diff --git a/js/ipc/WrapperAnswer.cpp b/js/ipc/WrapperAnswer.cpp index 067ac8c576..80cc5cba68 100644 --- a/js/ipc/WrapperAnswer.cpp +++ b/js/ipc/WrapperAnswer.cpp @@ -7,7 +7,9 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/ScriptSettings.h" #include "xpcprivate.h" +#include "jsfriendapi.h" #include "js/Class.h" +#include "js/Object.h" // JS::GetBuiltinClass #include "js/RegExp.h" #include "jsfriendapi.h" @@ -601,7 +603,7 @@ bool WrapperAnswer::RecvGetBuiltinClass(const ObjectId& objId, ReturnStatus* rs, LOG("%s.getBuiltinClass()", ReceiverObj(objId)); js::ESClass cls; - if (!js::GetBuiltinClass(cx, obj, &cls)) { + if (!JS::GetBuiltinClass(cx, obj, &cls)) { return fail(jsapi, rs); } diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp index bb6c76f1b4..8dc8dcb9a5 100644 --- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -7,6 +7,7 @@ #include "mozilla/Unused.h" #include "mozilla/dom/BindingUtils.h" #include "jsfriendapi.h" +#include "js/friend/DumpFunctions.h" // js::DumpBacktrace #include "js/CharacterEncoding.h" #include "js/RegExp.h" #include "js/RegExpFlags.h" diff --git a/js/moz.configure b/js/moz.configure index 4e0062a5ec..9cb1be6aaa 100644 --- a/js/moz.configure +++ b/js/moz.configure @@ -502,65 +502,45 @@ set_config('JS_HAS_TYPED_OBJECTS', depends_if('--enable-typed-objects')(lambda x set_define('JS_HAS_TYPED_OBJECTS', depends_if('--enable-typed-objects')(lambda x: True)) -# Support for WebAssembly bulk memory operations. -# ===================================================== - -@depends(milestone.is_nightly) -def default_wasm_bulk_memory(is_nightly): - return is_nightly - -js_option('--enable-wasm-bulk-memory', - default=default_wasm_bulk_memory, - help='{Enable|Disable} WebAssembly bulk memory operators') - -set_config('ENABLE_WASM_BULKMEM_OPS', depends_if('--enable-wasm-bulk-memory')(lambda x: True)) -set_define('ENABLE_WASM_BULKMEM_OPS', depends_if('--enable-wasm-bulk-memory')(lambda x: True)) - - # Support for WebAssembly reference types. # ===================================================== -@depends(milestone.is_nightly) -def default_wasm_reftypes(is_nightly): - return is_nightly - -js_option('--enable-wasm-reftypes', - default=default_wasm_reftypes, - help='{Enable|Disable} WebAssembly reference types') - -set_config('ENABLE_WASM_REFTYPES', depends_if('--enable-wasm-reftypes')(lambda x: True)) -set_define('ENABLE_WASM_REFTYPES', depends_if('--enable-wasm-reftypes')(lambda x: True)) - +js_option('--disable-wasm-reftypes', + help='Disable WebAssembly reference types') -# Support for WebAssembly I64/BigInt conversion -# =========================================================================== - -@depends(milestone.is_nightly) -def default_wasm_bigint(is_nightly): - return is_nightly - -js_option('--enable-wasm-bigint', - default=default_wasm_bigint, - help='{Enable|Disable} WebAssembly I64/BigInt conversion') +@depends('--disable-wasm-reftypes') +def enable_wasm_reftypes(value): + if value: + return True -set_config('ENABLE_WASM_BIGINT', depends_if('--enable-wasm-bigint')(lambda x: True)) -set_define('ENABLE_WASM_BIGINT', depends_if('--enable-wasm-bigint')(lambda x: True)) +set_config('ENABLE_WASM_REFTYPES', enable_wasm_reftypes) +set_define('ENABLE_WASM_REFTYPES', enable_wasm_reftypes) # Support for WebAssembly GC. # =========================== -@depends(milestone.is_nightly, '--enable-wasm-reftypes') -def default_wasm_gc(is_nightly, reftypes): - if reftypes and is_nightly: +@depends(milestone.is_nightly, '--enable-wasm-reftypes', '--enable-typed-objects') +def default_wasm_gc(is_nightly, reftypes, typed_objects): + if is_nightly and reftypes and typed_objects: return True js_option('--enable-wasm-gc', default=default_wasm_gc, help='{Enable|Disable} WebAssembly GC') -set_config('ENABLE_WASM_GC', depends_if('--enable-wasm-gc')(lambda x: True)) -set_define('ENABLE_WASM_GC', depends_if('--enable-wasm-gc')(lambda x: True)) +@depends('--enable-wasm-gc', '--enable-wasm-reftypes', '--enable-typed-objects') +def wasm_gc(value, reftypes, typed_objects): + if not value: + return + + if reftypes and typed_objects: + return True + + die('--enable-wasm-gc only possible with --enable-wasm-reftypes and --enable-typed-objects') + +set_config('ENABLE_WASM_GC', wasm_gc) +set_define('ENABLE_WASM_GC', wasm_gc) # Support for WebAssembly private ref types. diff --git a/js/public/AllocationLogging.h b/js/public/AllocationLogging.h new file mode 100644 index 0000000000..03a6851c35 --- /dev/null +++ b/js/public/AllocationLogging.h @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Embedder-supplied tracking of the allocation and deallocation of various + * non-garbage-collected objects in SpiderMonkey. + * + * This functionality is intended to track allocation of non-user-visible + * structures, for debugging the C++ of an embedding. It is not intended to + * give the end user visibility into allocations in JS. Instead see + * AllocationRecording.h for such functionality. + */ + +#ifndef js_AllocationLogging_h +#define js_AllocationLogging_h + +#include "mozilla/MemoryReporting.h" +#include "mozilla/PodOperations.h" + +#include // uint32_t + +#include "jstypes.h" // JS_PUBLIC_API + +namespace JS { + +using LogCtorDtor = void (*)(void*, const char*, uint32_t); + +/** + * Set global functions used to monitor classes to highlight leaks. + * + * For each C++ class that uses these mechanisms, the allocation of an instance + * will log the constructor call, and its subsequent deallocation will log the + * destructor call. If only the former occurs, the instance/allocation is + * leaked. With carefully-written logging functions, this can be used to debug + * the origin of the leaks. + */ +extern JS_PUBLIC_API void SetLogCtorDtorFunctions(LogCtorDtor ctor, + LogCtorDtor dtor); + +/** + * Log the allocation of |self|, having a type uniquely identified by the string + * |type|, with allocation size |sz|. + * + * You generally should use |JS_COUNT_CTOR| and |JS_COUNT_DTOR| instead of + * using this function directly. + */ +extern JS_PUBLIC_API void LogCtor(void* self, const char* type, uint32_t sz); + +/** + * Log the deallocation of |self|, having a type uniquely identified by the + * string |type|, with allocation size |sz|. + * + * You generally should use |JS_COUNT_CTOR| and |JS_COUNT_DTOR| instead of + * using this function directly. + */ +extern JS_PUBLIC_API void LogDtor(void* self, const char* type, uint32_t sz); + +/** + * Within each non-delegating constructor of a |Class|, use + * |JS_COUNT_CTOR(Class);| to log the allocation of |this|. (If you do this in + * delegating constructors, you might count a single allocation multiple times.) + */ +#define JS_COUNT_CTOR(Class) \ + (::JS::LogCtor(static_cast(this), #Class, sizeof(Class))) + +/** + * Within the destructor of a |Class|, use |JS_COUNT_DTOR(Class);| to log the + * deallocation of |this|. + */ +#define JS_COUNT_DTOR(Class) \ + (::JS::LogDtor(static_cast(this), #Class, sizeof(Class))) + +} // namespace JS + +#endif // js_AllocationLogging_h diff --git a/js/public/AllocationRecording.h b/js/public/AllocationRecording.h index b016c4f595..8e62ebb116 100644 --- a/js/public/AllocationRecording.h +++ b/js/public/AllocationRecording.h @@ -18,12 +18,10 @@ namespace JS { struct RecordAllocationInfo { RecordAllocationInfo(const char16_t* typeName, const char* className, const char16_t* descriptiveTypeName, - const char* scriptFilename, const char* coarseType, - uint64_t size, bool inNursery) + const char* coarseType, uint64_t size, bool inNursery) : typeName(typeName), className(className), descriptiveTypeName(descriptiveTypeName), - scriptFilename(scriptFilename), coarseType(coarseType), size(size), inNursery(inNursery) {} @@ -34,7 +32,6 @@ struct RecordAllocationInfo { const char16_t* typeName; const char* className; const char16_t* descriptiveTypeName; - const char* scriptFilename; // The coarseType points to a string literal, so does not need to be // duplicated. diff --git a/js/public/BigInt.h b/js/public/BigInt.h new file mode 100644 index 0000000000..a77901989d --- /dev/null +++ b/js/public/BigInt.h @@ -0,0 +1,138 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* BigInt. */ + +#ifndef js_BigInt_h +#define js_BigInt_h + +#include "mozilla/Range.h" // mozilla::Range + +#include // std::numeric_limits +#include // int64_t, uint64_t +#include // std::enable_if_t, std::{true,false}_type, std::is_{integral,signed,unsigned}_v +#include // std::declval + +#include "jstypes.h" // JS_PUBLIC_API +#include "js/RootingAPI.h" // JS::Handle +#include "js/Value.h" // JS::Value + +struct JS_PUBLIC_API JSContext; + +namespace JS { + +class JS_PUBLIC_API BigInt; + +namespace detail { + +extern JS_PUBLIC_API BigInt* BigIntFromInt64(JSContext* cx, int64_t num); +extern JS_PUBLIC_API BigInt* BigIntFromUint64(JSContext* cx, uint64_t num); +extern JS_PUBLIC_API BigInt* BigIntFromBool(JSContext* cx, bool b); + +template +struct NumberToBigIntConverter; + +template +struct NumberToBigIntConverter< + SignedIntT, + std::enable_if_t && + std::is_signed_v && + std::numeric_limits::digits <= 64>> { + static BigInt* convert(JSContext* cx, SignedIntT num) { + return BigIntFromInt64(cx, num); + } +}; + +template +struct NumberToBigIntConverter< + UnsignedIntT, + std::enable_if_t && + std::is_unsigned_v && + std::numeric_limits::digits <= 64>> { + static BigInt* convert(JSContext* cx, UnsignedIntT num) { + return BigIntFromUint64(cx, num); + } +}; + +template <> +struct NumberToBigIntConverter { + static BigInt* convert(JSContext* cx, bool b) { + return BigIntFromBool(cx, b); + } +}; + +} // namespace detail + +/** + * Create a BigInt from an integer value. All integral types not larger than 64 + * bits in size are supported. + */ +template +extern JS_PUBLIC_API BigInt* NumberToBigInt(JSContext* cx, NumericT val) { + return detail::NumberToBigIntConverter::convert(cx, val); +} + +/** + * Create a BigInt from a floating-point value. If the number isn't integral + * (that is, if it's NaN, an infinity, or contains a fractional component), + * this function returns null and throws an exception. + * + * Passing -0.0 will produce the bigint 0n. + */ +extern JS_PUBLIC_API BigInt* NumberToBigInt(JSContext* cx, double num); + +/** + * Create a BigInt by parsing a string using the ECMAScript StringToBigInt + * algorithm (https://tc39.es/ecma262/#sec-stringtobigint). Latin1 and two-byte + * character ranges are supported. It may be convenient to use + * JS::ConstLatin1Chars or JS::ConstTwoByteChars. + * + * (StringToBigInt performs parsing similar to that performed by the |Number| + * global function when passed a string, but it doesn't allow infinities, + * decimal points, or exponential notation, and neither algorithm allows numeric + * separators or an 'n' suffix character. This fast-and-loose description is + * offered purely as a convenience to the reader: see the specification + * algorithm for exact behavior.) + * + * If parsing fails, this function returns null and throws an exception. + */ +extern JS_PUBLIC_API BigInt* StringToBigInt( + JSContext* cx, mozilla::Range chars); + +extern JS_PUBLIC_API BigInt* StringToBigInt( + JSContext* cx, mozilla::Range chars); + +/** + * Create a BigInt by parsing a string consisting of an optional sign character + * followed by one or more alphanumeric ASCII digits in the provided radix. + * + * If the radix is not in the range [2, 36], or the string fails to parse, this + * function returns null and throws an exception. + */ +extern JS_PUBLIC_API BigInt* SimpleStringToBigInt( + JSContext* cx, mozilla::Span chars, unsigned radix); + +/** + * Convert a JS::Value to a BigInt using the ECMAScript ToBigInt algorithm + * (https://tc39.es/ecma262/#sec-tobigint). + * + * (Note in particular that this will throw if passed a value whose type is + * 'number'. To convert a number to a BigInt, use one of the overloads of + * JS::NumberToBigInt().) + */ +extern JS_PUBLIC_API BigInt* ToBigInt(JSContext* cx, Handle val); + +/** + * Convert the given BigInt, modulo 2**64, to a signed 64-bit integer. + */ +extern JS_PUBLIC_API int64_t ToBigInt64(BigInt* bi); + +/** + * Convert the given BigInt, modulo 2**64, to an unsigned 64-bit integer. + */ +extern JS_PUBLIC_API uint64_t ToBigUint64(BigInt* bi); + +} // namespace JS + +#endif /* js_BigInt_h */ diff --git a/js/public/BuildId.h b/js/public/BuildId.h index 2bc0415379..12bb51fbff 100644 --- a/js/public/BuildId.h +++ b/js/public/BuildId.h @@ -59,6 +59,25 @@ extern JS_PUBLIC_API void SetProcessBuildIdOp(BuildIdOp buildIdOp); extern MOZ_MUST_USE JS_PUBLIC_API bool GetOptimizedEncodingBuildId( BuildIdCharVector* buildId); +/** + * Script bytecode is dependent on the buildId and a few other things. + * + * This function produces a buildId that includes: + * + * * The buildId defined by the embedder-provided BuildIdOp set by + * JS::SetProcessBuildIdOp. + * * Additional bytes describing things like endianness, pointer size and + * other state XDR buffers depend on. + * + * Note: this value may depend on runtime preferences so isn't guaranteed to be + * stable across restarts. + * + * Embedders should use this function to tag transcoded bytecode. + * See Transcoding.h. + */ +extern MOZ_MUST_USE JS_PUBLIC_API bool GetScriptTranscodingBuildId( + BuildIdCharVector* buildId); + } // namespace JS #endif /* js_BuildId_h */ diff --git a/js/public/CharacterEncoding.h b/js/public/CharacterEncoding.h index 97eac8a644..a921d20b57 100644 --- a/js/public/CharacterEncoding.h +++ b/js/public/CharacterEncoding.h @@ -38,6 +38,20 @@ class Latin1Chars : public mozilla::Range { aLength) {} }; +/* + * Like Latin1Chars, but the chars are const. + */ +class ConstLatin1Chars : public mozilla::Range { + typedef mozilla::Range Base; + + public: + using CharT = Latin1Char; + + ConstLatin1Chars() = default; + ConstLatin1Chars(const Latin1Char* aChars, size_t aLength) + : Base(aChars, aLength) {} +}; + /* * A Latin1Chars, but with \0 termination for C compatibility. */ @@ -289,11 +303,12 @@ JS_PUBLIC_API size_t GetDeflatedUTF8StringLength(JSLinearString* s); * exhausted or too little space is available in |dst| to fit the scalar * value. Lone surrogates are converted to REPLACEMENT CHARACTER. Return * the number of bytes of |dst| that were filled. + * * Use |JS_EncodeStringToUTF8BufferPartial| if your string isn't already - * flat. + * linear. * - * Given |JSString* str = JS_FORGET_STRING_FLATNESS(src)|, - * if |JS_StringHasLatin1Chars(str)|, then |src| is always fully converted + * Given |JSString* str = JS_FORGET_STRING_LINEARNESS(src)|, + * if |JS::StringHasLatin1Chars(str)|, then |src| is always fully converted * if |dst.Length() >= JS_GetStringLength(str) * 2|. Otherwise |src| is * always fully converted if |dst.Length() >= JS_GetStringLength(str) * 3|. * diff --git a/js/public/Class.h b/js/public/Class.h index 48e6b54009..dd3c1da194 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -76,9 +76,9 @@ namespace JS { class ObjectOpResult { private: /** - * code_ is either one of the special codes OkCode or Uninitialized, or - * an error code. For now the error codes are private to the JS engine; - * they're defined in js/src/js.msg. + * code_ is either one of the special codes OkCode or Uninitialized, or an + * error code. For now the error codes are JS friend API and are defined in + * js/public/friend/ErrorNumbers.msg. * * code_ is uintptr_t (rather than uint32_t) for the convenience of the * JITs, which would otherwise have to deal with either padding or stack @@ -698,7 +698,7 @@ static const uint32_t JSCLASS_FOREGROUND_FINALIZE = // application. static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5; static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT = - JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 26; + JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 28; static constexpr uint32_t JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(uint32_t n) { return JSCLASS_IS_GLOBAL | diff --git a/js/public/CompilationAndEvaluation.h b/js/public/CompilationAndEvaluation.h index 4acd4a0237..685e55ce27 100644 --- a/js/public/CompilationAndEvaluation.h +++ b/js/public/CompilationAndEvaluation.h @@ -12,6 +12,7 @@ #include // size_t #include // FILE +#include "jsapi.h" // JSGetElementCallback #include "jstypes.h" // JS_PUBLIC_API #include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyCompileOptions @@ -162,6 +163,25 @@ extern JS_PUBLIC_API JSScript* Compile(JSContext* cx, const ReadOnlyCompileOptions& options, SourceText& srcBuf); +/** + * Compile the provided script using the given options, and register an encoder + * on is script source, such that all functions can be encoded as they are + * parsed. This strategy is used to avoid blocking the main thread in a + * non-interruptible way. + * + * See also JS::FinishIncrementalEncoding. + * + * Return the script on success, or return null on failure (usually with an + * error reported) + */ +extern JS_PUBLIC_API JSScript* CompileAndStartIncrementalEncoding( + JSContext* cx, const ReadOnlyCompileOptions& options, + SourceText& srcBuf); + +extern JS_PUBLIC_API JSScript* CompileAndStartIncrementalEncoding( + JSContext* cx, const ReadOnlyCompileOptions& options, + SourceText& srcBuf); + /** * Compile the UTF-8 contents of the given file into a script. It is an error * if the file contains invalid UTF-8. Return the script on success, or return @@ -179,19 +199,6 @@ extern JS_PUBLIC_API JSScript* CompileUtf8File( extern JS_PUBLIC_API JSScript* CompileUtf8Path( JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename); -extern JS_PUBLIC_API JSScript* CompileForNonSyntacticScope( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - -/** - * Compile the provided UTF-8 data into a script in a non-syntactic scope. It - * is an error if the data contains invalid UTF-8. Return the script on - * success, or return null on failure (usually with an error reported). - */ -extern JS_PUBLIC_API JSScript* CompileForNonSyntacticScope( - JSContext* cx, const ReadOnlyCompileOptions& options, - SourceText& srcBuf); - /** * Compile a function with envChain plus the global as its scope chain. * envChain must contain objects in the current compartment of cx. The actual @@ -241,6 +248,9 @@ extern JS_PUBLIC_API bool InitScriptSourceElement( extern JS_PUBLIC_API void ExposeScriptToDebugger(JSContext* cx, Handle script); +extern JS_PUBLIC_API void SetGetElementCallback(JSContext* cx, + JSGetElementCallback callback); + } /* namespace JS */ #endif /* js_CompilationAndEvaluation_h */ diff --git a/js/public/CompileOptions.h b/js/public/CompileOptions.h index 38720dd6fe..eac45dff91 100644 --- a/js/public/CompileOptions.h +++ b/js/public/CompileOptions.h @@ -60,6 +60,7 @@ #include "jstypes.h" // JS_PUBLIC_API #include "js/RootingAPI.h" // JS::PersistentRooted, JS::Rooted +#include "js/Value.h" struct JS_PUBLIC_API JSContext; class JS_PUBLIC_API JSObject; @@ -129,6 +130,12 @@ class JS_PUBLIC_API TransitiveCompileOptions { bool hideScriptFromDebugger = false; bool nonSyntacticScope = false; bool privateClassFields = false; + bool privateClassMethods = false; + + // True if off-thread parsing should use a parse GlobalObject in order to + // directly allocate to the GC from a helper thread. If false, transfer the + // CompilationStencil back to main thread before allocating GC objects. + bool useOffThreadParseGlobal = true; /** * |introductionType| is a statically allocated C string: one of "eval", @@ -161,7 +168,7 @@ class JS_PUBLIC_API TransitiveCompileOptions { const char* filename() const { return filename_; } const char* introducerFilename() const { return introducerFilename_; } const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; + virtual Value privateValue() const = 0; virtual JSString* elementAttributeName() const = 0; virtual JSScript* introductionScript() const = 0; @@ -232,17 +239,17 @@ class JS_PUBLIC_API ReadOnlyCompileOptions : public TransitiveCompileOptions { * anything else it entrains, will never be freed. */ class JS_PUBLIC_API OwningCompileOptions final : public ReadOnlyCompileOptions { - PersistentRooted elementRoot; PersistentRooted elementAttributeNameRoot; PersistentRooted introductionScriptRoot; PersistentRooted scriptOrModuleRoot; + PersistentRooted privateValueRoot; public: // A minimal constructor, for use with OwningCompileOptions::copy. explicit OwningCompileOptions(JSContext* cx); ~OwningCompileOptions(); - JSObject* element() const override { return elementRoot; } + Value privateValue() const override { return privateValueRoot; } JSString* elementAttributeName() const override { return elementAttributeNameRoot; } @@ -256,6 +263,24 @@ class JS_PUBLIC_API OwningCompileOptions final : public ReadOnlyCompileOptions { size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + OwningCompileOptions& setIsRunOnce(bool once) { + isRunOnce = once; + return *this; + } + + OwningCompileOptions& setForceStrictMode() { + forceStrictMode_ = true; + return *this; + } + + OwningCompileOptions& setModule() { + // ES6 10.2.1 Module code is always strict mode code. + setForceStrictMode(); + setIsRunOnce(true); + allowHTMLComments = false; + return *this; + } + private: void release(); @@ -273,10 +298,10 @@ class JS_PUBLIC_API OwningCompileOptions final : public ReadOnlyCompileOptions { class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final : public ReadOnlyCompileOptions { private: - Rooted elementRoot; Rooted elementAttributeNameRoot; Rooted introductionScriptRoot; Rooted scriptOrModuleRoot; + Rooted privateValueRoot; public: // Default options determined using the JSContext. @@ -286,23 +311,23 @@ class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final // options object. CompileOptions(JSContext* cx, const ReadOnlyCompileOptions& rhs) : ReadOnlyCompileOptions(), - elementRoot(cx), elementAttributeNameRoot(cx), introductionScriptRoot(cx), - scriptOrModuleRoot(cx) { + scriptOrModuleRoot(cx), + privateValueRoot(cx) { copyPODNonTransitiveOptions(rhs); copyPODTransitiveOptions(rhs); filename_ = rhs.filename(); introducerFilename_ = rhs.introducerFilename(); sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); + privateValueRoot = rhs.privateValue(); elementAttributeNameRoot = rhs.elementAttributeName(); introductionScriptRoot = rhs.introductionScript(); scriptOrModuleRoot = rhs.scriptOrModule(); } - JSObject* element() const override { return elementRoot; } + Value privateValue() const override { return privateValueRoot; } JSString* elementAttributeName() const override { return elementAttributeNameRoot; @@ -335,8 +360,8 @@ class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final return *this; } - CompileOptions& setElement(JSObject* e) { - elementRoot = e; + CompileOptions& setPrivateValue(const Value& v) { + privateValueRoot = v; return *this; } @@ -426,6 +451,14 @@ class MOZ_STACK_CLASS JS_PUBLIC_API CompileOptions final return *this; } + CompileOptions& setModule() { + // ES6 10.2.1 Module code is always strict mode code. + setForceStrictMode(); + setIsRunOnce(true); + allowHTMLComments = false; + return *this; + } + CompileOptions(const CompileOptions& rhs) = delete; CompileOptions& operator=(const CompileOptions& rhs) = delete; }; diff --git a/js/public/ContextOptions.h b/js/public/ContextOptions.h index ab3752a3e2..06eed5ccb7 100644 --- a/js/public/ContextOptions.h +++ b/js/public/ContextOptions.h @@ -26,17 +26,22 @@ class JS_PUBLIC_API ContextOptions { wasmGc_(false), wasmMultiValue_(false), testWasmAwaitTier2_(false), -#ifdef ENABLE_WASM_BIGINT - enableWasmBigInt_(true), -#endif throwOnAsmJSValidationFailure_(false), disableIon_(false), + disableEvalSecurityChecks_(false), asyncStack_(true), + asyncStackCaptureDebuggeeOnly_(false), sourcePragmas_(true), throwOnDebuggeeWouldRun_(true), dumpStackOnDebuggeeWouldRun_(false), strictMode_(false), - fuzzing_(false) { +#ifdef JS_ENABLE_SMOOSH + trackNotImplemented_(false), + trySmoosh_(false), +#endif + fuzzing_(false), + privateClassFields_(false), + privateClassMethods_(false) { } bool asmJS() const { return asmJS_; } @@ -93,14 +98,6 @@ class JS_PUBLIC_API ContextOptions { return *this; } -#ifdef ENABLE_WASM_BIGINT - bool isWasmBigIntEnabled() const { return enableWasmBigInt_; } - ContextOptions& setWasmBigIntEnabled(bool flag) { - enableWasmBigInt_ = flag; - return *this; - } -#endif - bool wasmGc() const { return wasmGc_; } // Defined out-of-line because it depends on a compile-time option ContextOptions& setWasmGc(bool flag); @@ -130,12 +127,40 @@ class JS_PUBLIC_API ContextOptions { return *this; } + bool privateClassFields() const { return privateClassFields_; } + ContextOptions& setPrivateClassFields(bool enabled) { + privateClassFields_ = enabled; + return *this; + } + + bool privateClassMethods() const { return privateClassMethods_; } + ContextOptions& setPrivateClassMethods(bool enabled) { + privateClassMethods_ = enabled; + return *this; + } + + // Override to allow disabling the eval restriction security checks for + // this context. + bool disableEvalSecurityChecks() const { return disableEvalSecurityChecks_; } + ContextOptions& setDisableEvalSecurityChecks() { + disableEvalSecurityChecks_ = true; + return *this; + } + bool asyncStack() const { return asyncStack_; } ContextOptions& setAsyncStack(bool flag) { asyncStack_ = flag; return *this; } + bool asyncStackCaptureDebuggeeOnly() const { + return asyncStackCaptureDebuggeeOnly_; + } + ContextOptions& setAsyncStackCaptureDebuggeeOnly(bool flag) { + asyncStackCaptureDebuggeeOnly_ = flag; + return *this; + } + // Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas. bool sourcePragmas() const { return sourcePragmas_; } ContextOptions& setSourcePragmas(bool flag) { @@ -167,17 +192,31 @@ class JS_PUBLIC_API ContextOptions { return *this; } +#ifdef JS_ENABLE_SMOOSH + // Track Number of Not Implemented Calls by writing to a file + bool trackNotImplemented() const { return trackNotImplemented_; } + ContextOptions& setTrackNotImplemented(bool flag) { + trackNotImplemented_ = flag; + return *this; + } + + // Try compiling SmooshMonkey frontend first, and fallback to C++ + // implementation when it fails. + bool trySmoosh() const { return trySmoosh_; } + ContextOptions& setTrySmoosh(bool flag) { + trySmoosh_ = flag; + return *this; + } + +#endif // JS_ENABLE_SMOOSH + bool fuzzing() const { return fuzzing_; } // Defined out-of-line because it depends on a compile-time option ContextOptions& setFuzzing(bool flag); void disableOptionsForSafeMode() { setAsmJS(false); - setWasm(false); setWasmBaseline(false); - setWasmIon(false); - setWasmGc(false); - setWasmMultiValue(false); } private: @@ -191,17 +230,22 @@ class JS_PUBLIC_API ContextOptions { bool wasmGc_ : 1; bool wasmMultiValue_ : 1; bool testWasmAwaitTier2_ : 1; -#ifdef ENABLE_WASM_BIGINT - bool enableWasmBigInt_ : 1; -#endif bool throwOnAsmJSValidationFailure_ : 1; bool disableIon_ : 1; + bool disableEvalSecurityChecks_ : 1; bool asyncStack_ : 1; + bool asyncStackCaptureDebuggeeOnly_ : 1; bool sourcePragmas_ : 1; bool throwOnDebuggeeWouldRun_ : 1; bool dumpStackOnDebuggeeWouldRun_ : 1; bool strictMode_ : 1; +#ifdef JS_ENABLE_SMOOSH + bool trackNotImplemented_ : 1; + bool trySmoosh_ : 1; +#endif bool fuzzing_ : 1; + bool privateClassFields_ : 1; + bool privateClassMethods_ : 1; }; JS_PUBLIC_API ContextOptions& ContextOptionsRef(JSContext* cx); diff --git a/js/public/ErrorReport.h b/js/public/ErrorReport.h index cd424d0572..198b9c56a6 100644 --- a/js/public/ErrorReport.h +++ b/js/public/ErrorReport.h @@ -27,6 +27,8 @@ #include "js/AllocPolicy.h" // js::SystemAllocPolicy #include "js/CharacterEncoding.h" // JS::ConstUTF8CharsZ +#include "js/Exception.h" // JS::ExceptionStack +#include "js/RootingAPI.h" // JS::HandleObject, JS::RootedObject #include "js/UniquePtr.h" // js::UniquePtr #include "js/Vector.h" // js::Vector @@ -37,8 +39,9 @@ class JS_PUBLIC_API JSString; * Possible exception types. These types are part of a JSErrorFormatString * structure. They define which error to throw in case of a runtime error. * - * JSEXN_WARN is used for warnings in js.msg files (for instance because we - * don't want to prepend 'Error:' to warning messages). This value can go away + * JSEXN_WARN is used for warnings, that are not strictly errors but are handled + * using the generalized error reporting mechanism. (One side effect of this + * type is to not prepend 'Error:' to warning messages.) This value can go away * if we ever decide to use an entirely separate mechanism for warnings. */ enum JSExnType { @@ -102,7 +105,7 @@ class JSErrorBase { // Zero-based column index in line. unsigned column; - // the error number, e.g. see js.msg. + // the error number, e.g. see js/public/friend/ErrorNumbers.msg. unsigned errorNumber; // Points to JSErrorFormatString::name. @@ -264,4 +267,94 @@ class JSErrorReport : public JSErrorBase { void freeLinebuf(); }; +namespace JS { + +struct MOZ_STACK_CLASS JS_PUBLIC_API ErrorReportBuilder { + explicit ErrorReportBuilder(JSContext* cx); + ~ErrorReportBuilder(); + + enum SniffingBehavior { WithSideEffects, NoSideEffects }; + + /** + * Generate a JSErrorReport from the provided thrown value. + * + * If the value is a (possibly wrapped) Error object, the JSErrorReport will + * be exactly initialized from the Error object's information, without + * observable side effects. (The Error object's JSErrorReport is reused, if + * it has one.) + * + * Otherwise various attempts are made to derive JSErrorReport information + * from |exnStack| and from the current execution state. This process is + * *definitely* inconsistent with any standard, and particulars of the + * behavior implemented here generally shouldn't be relied upon. + * + * If the value of |sniffingBehavior| is |WithSideEffects|, some of these + * attempts *may* invoke user-configurable behavior when the exception is an + * object: converting it to a string, detecting and getting its properties, + * accessing its prototype chain, and others are possible. Users *must* + * tolerate |ErrorReportBuilder::init| potentially having arbitrary effects. + * Any exceptions thrown by these operations will be caught and silently + * ignored, and "default" values will be substituted into the JSErrorReport. + * + * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts + * *will not* invoke any observable side effects. The JSErrorReport will + * simply contain fewer, less precise details. + * + * Unlike some functions involved in error handling, this function adheres + * to the usual JSAPI return value error behavior. + */ + bool init(JSContext* cx, const JS::ExceptionStack& exnStack, + SniffingBehavior sniffingBehavior); + + JSErrorReport* report() const { return reportp; } + + const JS::ConstUTF8CharsZ toStringResult() const { return toStringResult_; } + + private: + // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA + // but fills in an ErrorReport instead of reporting it. Uses varargs to + // make it simpler to call js::ExpandErrorArgumentsVA. + // + // Returns false if we fail to actually populate the ErrorReport + // for some reason (probably out of memory). + bool populateUncaughtExceptionReportUTF8(JSContext* cx, + JS::HandleObject stack, ...); + bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, + JS::HandleObject stack, + va_list ap); + + // Reports exceptions from add-on scopes to telemetry. + void ReportAddonExceptionToTelemetry(JSContext* cx); + + // We may have a provided JSErrorReport, so need a way to represent that. + JSErrorReport* reportp; + + // Or we may need to synthesize a JSErrorReport one of our own. + JSErrorReport ownedReport; + + // Root our exception value to keep a possibly borrowed |reportp| alive. + JS::RootedObject exnObject; + + // And for our filename. + JS::UniqueChars filename; + + // We may have a result of error.toString(). + // FIXME: We should not call error.toString(), since it could have side + // effect (see bug 633623). + JS::ConstUTF8CharsZ toStringResult_; + JS::UniqueChars toStringResultBytesStorage; +}; + +// Writes a full report to a file descriptor. Does nothing for JSErrorReports +// which are warnings, unless reportWarnings is set. +extern JS_PUBLIC_API void PrintError(JSContext* cx, FILE* file, + JSErrorReport* report, + bool reportWarnings); + +extern JS_PUBLIC_API void PrintError(JSContext* cx, FILE* file, + const JS::ErrorReportBuilder& builder, + bool reportWarnings); + +} // namespace JS + #endif /* js_ErrorReport_h */ diff --git a/js/public/Exception.h b/js/public/Exception.h new file mode 100644 index 0000000000..9cc94be657 --- /dev/null +++ b/js/public/Exception.h @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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_Exception_h +#define js_Exception_h + +#include "mozilla/Attributes.h" + +#include "jspubtd.h" +#include "js/RootingAPI.h" // JS::{Handle,Rooted} +#include "js/Value.h" // JS::Value, JS::Handle + +namespace JS { + +// This class encapsulates a (pending) exception and the corresponding optional +// SavedFrame stack object captured when the pending exception was set +// on the JSContext. This fuzzily correlates with a `throw` statement in JS, +// although arbitrary JSAPI consumers or VM code may also set pending exceptions +// via `JS_SetPendingException`. +// +// This is not the same stack as `e.stack` when `e` is an `Error` object. +// (That would be JS::ExceptionStackOrNull). +class MOZ_STACK_CLASS ExceptionStack { + Rooted exception_; + Rooted stack_; + + friend JS_PUBLIC_API bool GetPendingExceptionStack( + JSContext* cx, JS::ExceptionStack* exceptionStack); + + void init(HandleValue exception, HandleObject stack) { + exception_ = exception; + stack_ = stack; + } + + public: + explicit ExceptionStack(JSContext* cx) : exception_(cx), stack_(cx) {} + + ExceptionStack(JSContext* cx, HandleValue exception, HandleObject stack) + : exception_(cx, exception), stack_(cx, stack) {} + + HandleValue exception() const { return exception_; } + + // |stack| can be null. + HandleObject stack() const { return stack_; } +}; + +// Get the current pending exception value and stack. +// This function asserts that there is a pending exception. +// If this function returns false, then retrieving the current pending exception +// failed and might have been overwritten by a new exception. +extern JS_PUBLIC_API bool GetPendingExceptionStack( + JSContext* cx, JS::ExceptionStack* exceptionStack); + +// Similar to GetPendingExceptionStack, but also clears the current +// pending exception. +extern JS_PUBLIC_API bool StealPendingExceptionStack( + JSContext* cx, JS::ExceptionStack* exceptionStack); + +// Set both the exception value and its associated stack on the context as +// the current pending exception. +extern JS_PUBLIC_API void SetPendingExceptionStack( + JSContext* cx, const JS::ExceptionStack& exceptionStack); + +} // namespace JS + +#endif // js_Exception_h diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 53be9d6ddf..3fbddd40d2 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -321,7 +321,7 @@ typedef enum JSGCParamKey { /* * The current size of the nursery. * - * read-only. + * This parameter is read-only. */ JSGC_NURSERY_BYTES = 34, @@ -346,6 +346,37 @@ typedef enum JSGCParamKey { * Default: IncrementalWeakMarkEnabled */ JSGC_INCREMENTAL_WEAKMAP_ENABLED = 37, + + /** + * The chunk size in bytes for this system. + * + * This parameter is read-only. + */ + JSGC_CHUNK_BYTES = 38, + + /** + * The number of background threads to use for parallel GC work for each CPU + * core, expressed as an integer percentage. + * + * Pref: javascript.options.mem.gc_helper_thread_ratio + */ + JSGC_HELPER_THREAD_RATIO = 39, + + /** + * The maximum number of background threads to use for parallel GC work. + * + * Pref: javascript.options.mem.gc_max_helper_threads + */ + JSGC_MAX_HELPER_THREADS = 40, + + /** + * The number of background threads to use for parallel GC work. + * + * This parameter is read-only and is set based on the + * JSGC_HELPER_THREAD_RATIO and JSGC_MAX_HELPER_THREADS parameters. + */ + JSGC_HELPER_THREAD_COUNT = 41, + } JSGCParamKey; /* @@ -395,14 +426,14 @@ typedef void (*JSWeakPointerCompartmentCallback)(JSContext* cx, void* data); /* - * This is called to tell the embedding that the FinalizationRegistry object - * |registry| has cleanup work, and that then engine should be called back at an - * appropriate later time to perform this cleanup. + * This is called to tell the embedding that a FinalizationRegistry object has + * cleanup work, and that the engine should be called back at an appropriate + * later time to perform this cleanup, by calling the function |doCleanup|. * * This callback must not do anything that could cause GC. */ -using JSHostCleanupFinalizationRegistryCallback = void (*)(JSObject* registry, - void* data); +using JSHostCleanupFinalizationRegistryCallback = + void (*)(JSFunction* doCleanup, JSObject* incumbentGlobal, void* data); /** * Each external string has a pointer to JSExternalStringCallbacks. Embedders @@ -731,8 +762,6 @@ struct JS_PUBLIC_API GCDescription { mozilla::TimeStamp lastSliceStart(JSContext* cx) const; mozilla::TimeStamp lastSliceEnd(JSContext* cx) const; - char16_t* formatJSONTelemetry(JSContext* cx, uint64_t timestamp) const; - JS::UniqueChars sliceToJSONProfiler(JSContext* cx) const; JS::UniqueChars formatJSONProfiler(JSContext* cx) const; @@ -1084,12 +1113,6 @@ extern JS_PUBLIC_API JSString* JS_NewMaybeExternalString( JSContext* cx, const char16_t* chars, size_t length, const JSExternalStringCallbacks* callbacks, bool* allocatedExternal); -/** - * Return whether 'str' was created with JS_NewExternalString or - * JS_NewExternalStringWithClosure. - */ -extern JS_PUBLIC_API bool JS_IsExternalString(JSString* str); - /** * Return the 'callbacks' arg passed to JS_NewExternalString or * JS_NewMaybeExternalString. diff --git a/js/public/GCVector.h b/js/public/GCVector.h index e822dd0fb8..4bcb24f9e0 100644 --- a/js/public/GCVector.h +++ b/js/public/GCVector.h @@ -65,6 +65,7 @@ class GCVector { bool initCapacity(size_t cap) { return vector.initCapacity(cap); } MOZ_MUST_USE bool reserve(size_t req) { return vector.reserve(req); } void shrinkBy(size_t amount) { return vector.shrinkBy(amount); } + void shrinkTo(size_t newLen) { return vector.shrinkTo(newLen); } MOZ_MUST_USE bool growBy(size_t amount) { return vector.growBy(amount); } MOZ_MUST_USE bool resize(size_t newLen) { return vector.resize(newLen); } diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index a18c3a72ed..e7d2faee65 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -5,12 +5,17 @@ #ifndef js_HeapAPI_h #define js_HeapAPI_h +#include "mozilla/Atomics.h" + #include #include #include "jspubtd.h" #include "js/GCAnnotations.h" +#include "js/shadow/String.h" // JS::shadow::String +#include "js/shadow/Symbol.h" // JS::shadow::Symbol +#include "js/shadow/Zone.h" // JS::shadow::Zone #include "js/TraceKind.h" #include "js/Utility.h" @@ -29,6 +34,7 @@ JS_FRIEND_API bool CurrentThreadCanAccessZone(JS::Zone* zone); namespace gc { struct Cell; +class TenuredCell; const size_t ArenaShift = 12; const size_t ArenaSize = size_t(1) << ArenaShift; @@ -180,116 +186,6 @@ const uint32_t DefaultNurseryMaxBytes = 16 * js::gc::ChunkSize; /* Default maximum heap size in bytes to pass to JS_NewContext(). */ const uint32_t DefaultHeapMaxBytes = 32 * 1024 * 1024; -namespace shadow { - -struct Zone { - enum GCState : uint8_t { - NoGC, - MarkBlackOnly, - MarkBlackAndGray, - Sweep, - Finished, - Compact - }; - - protected: - JSRuntime* const runtime_; - JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. - uint32_t needsIncrementalBarrier_; - GCState gcState_; - - Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) - : runtime_(runtime), - barrierTracer_(barrierTracerArg), - needsIncrementalBarrier_(0), - gcState_(NoGC) {} - - public: - bool needsIncrementalBarrier() const { return needsIncrementalBarrier_; } - - JSTracer* barrierTracer() { - MOZ_ASSERT(needsIncrementalBarrier_); - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return barrierTracer_; - } - - JSRuntime* runtimeFromMainThread() const { - MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); - return runtime_; - } - - // Note: Unrestricted access to the zone's runtime from an arbitrary - // thread can easily lead to races. Use this method very carefully. - JSRuntime* runtimeFromAnyThread() const { return runtime_; } - - GCState gcState() const { return gcState_; } - bool wasGCStarted() const { return gcState_ != NoGC; } - bool isGCMarkingBlackOnly() const { return gcState_ == MarkBlackOnly; } - bool isGCMarkingBlackAndGray() const { return gcState_ == MarkBlackAndGray; } - bool isGCSweeping() const { return gcState_ == Sweep; } - bool isGCFinished() const { return gcState_ == Finished; } - bool isGCCompacting() const { return gcState_ == Compact; } - bool isGCMarking() const { - return isGCMarkingBlackOnly() || isGCMarkingBlackAndGray(); - } - bool isGCSweepingOrCompacting() const { - return gcState_ == Sweep || gcState_ == Compact; - } - - static MOZ_ALWAYS_INLINE JS::shadow::Zone* from(JS::Zone* zone) { - return reinterpret_cast(zone); - } -}; - -struct String { - static const uint32_t ATOM_BIT = js::Bit(3); - static const uint32_t LINEAR_BIT = js::Bit(4); - static const uint32_t INLINE_CHARS_BIT = js::Bit(6); - static const uint32_t LATIN1_CHARS_BIT = js::Bit(9); - static const uint32_t EXTERNAL_FLAGS = LINEAR_BIT | js::Bit(8); - static const uint32_t TYPE_FLAGS_MASK = js::BitMask(9) - js::BitMask(3); - static const uint32_t PERMANENT_ATOM_MASK = ATOM_BIT | js::Bit(8); - - uintptr_t flags_; -#if JS_BITS_PER_WORD == 32 - uint32_t length_; -#endif - - union { - const JS::Latin1Char* nonInlineCharsLatin1; - const char16_t* nonInlineCharsTwoByte; - JS::Latin1Char inlineStorageLatin1[1]; - char16_t inlineStorageTwoByte[1]; - }; - const JSExternalStringCallbacks* externalCallbacks; - - inline uint32_t flags() const { return uint32_t(flags_); } - inline uint32_t length() const { -#if JS_BITS_PER_WORD == 32 - return length_; -#else - return uint32_t(flags_ >> 32); -#endif - } - - static bool isPermanentAtom(const js::gc::Cell* cell) { - uint32_t flags = reinterpret_cast(cell)->flags(); - return (flags & PERMANENT_ATOM_MASK) == PERMANENT_ATOM_MASK; - } -}; - -struct Symbol { - void* _1; - uint32_t code_; - static const uint32_t WellKnownAPILimit = 0x80000000; - - static bool isWellKnownSymbol(const js::gc::Cell* cell) { - return reinterpret_cast(cell)->code_ < WellKnownAPILimit; - } -}; - -} /* namespace shadow */ - /** * A GC pointer, tagged with the trace kind. * @@ -380,7 +276,7 @@ class JS_FRIEND_API GCCellPtr { private: static uintptr_t checkedCast(void* p, JS::TraceKind traceKind) { - js::gc::Cell* cell = static_cast(p); + auto* cell = static_cast(p); MOZ_ASSERT((uintptr_t(p) & OutOfLineTraceKindMask) == 0); AssertGCThingHasType(cell, traceKind); // Note: the OutOfLineTraceKindMask bits are set on all out-of-line kinds @@ -436,19 +332,26 @@ inline bool operator!=(const JS::GCCellPtr& ptr1, const JS::GCCellPtr& ptr2) { namespace js { namespace gc { + +// Mark bitmaps are atomic because they can be written by gray unmarking on the +// main thread while read by sweeping on a background thread. The former does +// not affect the result of the latter. +using MarkBitmapWord = mozilla::Atomic; + namespace detail { -static MOZ_ALWAYS_INLINE uintptr_t* GetGCThingMarkBitmap(const uintptr_t addr) { +static MOZ_ALWAYS_INLINE MarkBitmapWord* GetGCThingMarkBitmap( + const uintptr_t addr) { // Note: the JIT pre-barrier trampolines inline this code. Update that // code too when making changes here! MOZ_ASSERT(addr); const uintptr_t bmap_addr = (addr & ~ChunkMask) | ChunkMarkBitmapOffset; - return reinterpret_cast(bmap_addr); + return reinterpret_cast(bmap_addr); } static MOZ_ALWAYS_INLINE void GetGCThingMarkWordAndMask(const uintptr_t addr, ColorBit colorBit, - uintptr_t** wordp, + MarkBitmapWord** wordp, uintptr_t* maskp) { // Note: the JIT pre-barrier trampolines inline this code. Update that // code too when making changes here! @@ -456,7 +359,7 @@ static MOZ_ALWAYS_INLINE void GetGCThingMarkWordAndMask(const uintptr_t addr, const size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellBytesPerMarkBit + static_cast(colorBit); MOZ_ASSERT(bit < js::gc::ChunkMarkBitmapBits); - uintptr_t* bitmap = GetGCThingMarkBitmap(addr); + MarkBitmapWord* bitmap = GetGCThingMarkBitmap(addr); const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT; *maskp = uintptr_t(1) << (bit % nbits); *wordp = &bitmap[bit / nbits]; @@ -473,14 +376,16 @@ static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const Cell* cell) { MOZ_ASSERT(cell); MOZ_ASSERT(!js::gc::IsInsideNursery(cell)); - uintptr_t *grayWord, grayMask; + MarkBitmapWord* grayWord; + uintptr_t grayMask; js::gc::detail::GetGCThingMarkWordAndMask( uintptr_t(cell), js::gc::ColorBit::GrayOrBlackBit, &grayWord, &grayMask); if (!(*grayWord & grayMask)) { return false; } - uintptr_t *blackWord, blackMask; + MarkBitmapWord* blackWord; + uintptr_t blackMask; js::gc::detail::GetGCThingMarkWordAndMask( uintptr_t(cell), js::gc::ColorBit::BlackBit, &blackWord, &blackMask); return !(*blackWord & blackMask); @@ -528,6 +433,12 @@ MOZ_ALWAYS_INLINE bool IsInsideNursery(const Cell* cell) { return location == ChunkLocation::Nursery; } +MOZ_ALWAYS_INLINE bool IsInsideNursery(const TenuredCell* cell) { + MOZ_ASSERT_IF(cell, + detail::GetCellLocation(cell) == ChunkLocation::TenuredHeap); + return false; +} + // Allow use before the compiler knows the derivation of JSObject, JSString, and // JS::BigInt. MOZ_ALWAYS_INLINE bool IsInsideNursery(const JSObject* obj) { diff --git a/js/public/Id.h b/js/public/Id.h index c8b5f78d4c..b9bd13e549 100644 --- a/js/public/Id.h +++ b/js/public/Id.h @@ -90,8 +90,13 @@ struct PropertyKey { return reinterpret_cast(asBits ^ JSID_TYPE_SYMBOL); } + js::gc::Cell* toGCThing() const { + MOZ_ASSERT(isGCThing()); + return reinterpret_cast(asBits & ~(size_t)JSID_TYPE_MASK); + } + GCCellPtr toGCCellPtr() const { - void* thing = (void*)(asBits & ~(size_t)JSID_TYPE_MASK); + js::gc::Cell* thing = toGCThing(); if (isString()) { return JS::GCCellPtr(thing, JS::TraceKind::String); } @@ -99,6 +104,8 @@ struct PropertyKey { return JS::GCCellPtr(thing, JS::TraceKind::Symbol); } + bool isPrivateName() const; + bool isWellKnownSymbol(JS::SymbolCode code) const; // This API can be used by embedders to convert pinned (aka interned) strings, @@ -222,6 +229,12 @@ struct GCPolicy { return !id.isGCThing() || js::gc::IsCellPointerValid(id.toGCCellPtr().asCell()); } + + static bool isTenured(jsid id) { + MOZ_ASSERT_IF(id.isGCThing(), + !js::gc::IsInsideNursery(id.toGCCellPtr().asCell())); + return true; + } }; #ifdef DEBUG @@ -301,6 +314,8 @@ class WrappedPtrOperations { JSString* toString() const { return id().toString(); } JS::Symbol* toSymbol() const { return id().toSymbol(); } + bool isPrivateName() const { return id().isPrivateName(); } + bool isWellKnownSymbol(JS::SymbolCode code) const { return id().isWellKnownSymbol(code); } diff --git a/js/public/MemoryMetrics.h b/js/public/MemoryMetrics.h index 27531905e7..66f31d2597 100644 --- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -17,6 +17,7 @@ #include "jspubtd.h" #include "js/AllocPolicy.h" +#include "js/GCAPI.h" #include "js/HashTable.h" #include "js/TracingAPI.h" #include "js/Utility.h" @@ -450,7 +451,8 @@ struct HelperThreadStats { MACRO(_, MallocHeap, stateData) \ MACRO(_, MallocHeap, parseTask) \ MACRO(_, MallocHeap, ionCompileTask) \ - MACRO(_, MallocHeap, wasmCompile) + MACRO(_, MallocHeap, wasmCompile) \ + MACRO(_, MallocHeap, contexts) HelperThreadStats() = default; @@ -843,9 +845,10 @@ struct RuntimeStats { mozilla::MallocSizeOf mallocSizeOf_; - virtual void initExtraRealmStats(JS::Handle realm, - RealmStats* rstats) = 0; - virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats) = 0; + virtual void initExtraRealmStats(JS::Realm* realm, RealmStats* rstats, + const JS::AutoRequireNoGC& nogc) = 0; + virtual void initExtraZoneStats(JS::Zone* zone, ZoneStats* zstats, + const JS::AutoRequireNoGC& nogc) = 0; #undef FOR_EACH_SIZE }; diff --git a/js/public/Modules.h b/js/public/Modules.h index b429a66cf2..c00f4610b9 100644 --- a/js/public/Modules.h +++ b/js/public/Modules.h @@ -79,8 +79,20 @@ GetModuleDynamicImportHook(JSRuntime* rt); extern JS_PUBLIC_API void SetModuleDynamicImportHook( JSRuntime* rt, ModuleDynamicImportHook func); +/** + * Passed to FinishDynamicModuleImport to indicate the result of the dynamic + * import operation. + */ +enum class DynamicImportStatus { Failed = 0, Ok }; + +/** + * This must be called after a dynamic import operation is complete. + * + * If |status| is Failed, any pending exception on the context will be used to + * complete the user's promise. + */ extern JS_PUBLIC_API bool FinishDynamicModuleImport( - JSContext* cx, Handle referencingPrivate, + JSContext* cx, DynamicImportStatus status, Handle referencingPrivate, Handle specifier, Handle promise); /** diff --git a/js/public/Object.h b/js/public/Object.h new file mode 100644 index 0000000000..86c4b35fae --- /dev/null +++ b/js/public/Object.h @@ -0,0 +1,117 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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_public_Object_h +#define js_public_Object_h + +#include "js/shadow/Object.h" // JS::shadow::Object + +#include "mozilla/Assertions.h" // MOZ_ASSERT + +#include // size_t +#include // uint32_t + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/Class.h" // js::ESClass, JSCLASS_RESERVED_SLOTS, JSCLASS_HAS_PRIVATE +#include "js/Realm.h" // JS::GetCompartmentForRealm +#include "js/RootingAPI.h" // JS::{,Mutable}Handle +#include "js/shadow/ObjectGroup.h" // JS::shadow::ObjectGroup + +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; + +namespace JS { + +class JS_PUBLIC_API Compartment; + +/** + * Determine the ECMAScript "class" -- Date, String, RegExp, and all the other + * builtin object types (described in ECMAScript in terms of an objecting having + * "an [[ArrayBufferData]] internal slot" or similar language for other kinds of + * object -- of the provided object. + * + * If this function is passed a wrapper that can be unwrapped, the determination + * is performed on that object. If the wrapper can't be unwrapped, and it's not + * a wrapper that prefers to treat this operation as a failure, this function + * will indicate that the object is |js::ESClass::Other|. + */ +extern JS_PUBLIC_API bool GetBuiltinClass(JSContext* cx, Handle obj, + js::ESClass* cls); + +/** Get the |JSClass| of an object. */ +inline const JSClass* GetClass(const JSObject* obj) { + return reinterpret_cast(obj)->group->clasp; +} + +/** + * Get the |JS::Compartment*| of an object. + * + * Note that the compartment of an object in this realm, that is a + * cross-compartment wrapper around an object from another realm, is the + * compartment of this realm. + */ +static MOZ_ALWAYS_INLINE Compartment* GetCompartment(JSObject* obj) { + Realm* realm = reinterpret_cast(obj)->group->realm; + return GetCompartmentForRealm(realm); +} + +/** + * Get the private value stored for an object whose class has a private. + * + * It is safe to call this function within |obj|'s finalize hook. + */ +inline void* GetPrivate(JSObject* obj) { + MOZ_ASSERT(GetClass(obj)->flags & JSCLASS_HAS_PRIVATE); + const auto* nobj = reinterpret_cast(obj); + void** addr = + reinterpret_cast(&nobj->fixedSlots()[nobj->numFixedSlots()]); + return *addr; +} + +/** + * Set the private value for |obj|. + * + * This function may called during the finalization of |obj|. + */ +extern JS_PUBLIC_API void SetPrivate(JSObject* obj, void* data); + +/** + * Get the value stored in a reserved slot in an object. + * + * If |obj| is known to be a proxy and you're willing to use friend APIs, + * |js::GetProxyReservedSlot| in "js/Proxy.h" is very slightly more efficient. + */ +inline const Value& GetReservedSlot(JSObject* obj, size_t slot) { + MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetClass(obj))); + return reinterpret_cast(obj)->slotRef(slot); +} + +namespace detail { + +extern JS_FRIEND_API void SetReservedSlotWithBarrier(JSObject* obj, size_t slot, + const Value& value); + +} // namespace detail + +/** + * Store a value in an object's reserved slot. + * + * This can be used with both native objects and proxies. However, if |obj| is + * known to be a proxy, |js::SetProxyReservedSlot| in "js/Proxy.h" is very + * slightly more efficient. + */ +inline void SetReservedSlot(JSObject* obj, size_t slot, const Value& value) { + MOZ_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetClass(obj))); + auto* sobj = reinterpret_cast(obj); + if (sobj->slotRef(slot).isGCThing() || value.isGCThing()) { + detail::SetReservedSlotWithBarrier(obj, slot, value); + } else { + sobj->slotRef(slot) = value; + } +} + +} // namespace JS + +#endif // js_public_Object_h diff --git a/js/public/OffThreadScriptCompilation.h b/js/public/OffThreadScriptCompilation.h index 85bcafcf32..0877f55388 100644 --- a/js/public/OffThreadScriptCompilation.h +++ b/js/public/OffThreadScriptCompilation.h @@ -18,7 +18,6 @@ #include "jstypes.h" // JS_PUBLIC_API -#include "js/BinASTFormat.h" // JS::BinASTFormat #include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions #include "js/GCVector.h" // JS::GCVector #include "js/Transcoding.h" // JS::TranscodeSource @@ -63,7 +62,7 @@ extern JS_PUBLIC_API bool CanCompileOffThread( extern JS_PUBLIC_API bool CompileOffThread( JSContext* cx, const ReadOnlyCompileOptions& options, SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); + void* callbackData, OffThreadToken** tokenOut = nullptr); // NOTE: Unlike for the normal sync compilation functions, this function NEVER // INFLATES TO UTF-16. Therefore, it is ALWAYS invoking experimental @@ -72,18 +71,32 @@ extern JS_PUBLIC_API bool CompileOffThread( extern JS_PUBLIC_API bool CompileOffThread( JSContext* cx, const ReadOnlyCompileOptions& options, SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); + void* callbackData, OffThreadToken** tokenOut = nullptr); +// Finish the off-thread parse/decode task and return the script. Return the +// script on success, or return null on failure (usually with an error reported) extern JS_PUBLIC_API JSScript* FinishOffThreadScript(JSContext* cx, OffThreadToken* token); +// Finish the off-thread parse/decode task and return the script, and register +// an encoder on its script source, such that all functions can be encoded as +// they are parsed. This strategy is used to avoid blocking the main thread in +// a non-interruptible way. +// +// See also JS::FinishIncrementalEncoding. +// +// Return the script on success, or return null on failure (usually with an +// error reported) +extern JS_PUBLIC_API JSScript* FinishOffThreadScriptAndStartIncrementalEncoding( + JSContext* cx, OffThreadToken* token); + extern JS_PUBLIC_API void CancelOffThreadScript(JSContext* cx, OffThreadToken* token); extern JS_PUBLIC_API bool CompileOffThreadModule( JSContext* cx, const ReadOnlyCompileOptions& options, SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); + void* callbackData, OffThreadToken** tokenOut = nullptr); // NOTE: Unlike for the normal sync compilation functions, this function NEVER // INFLATES TO UTF-16. Therefore, it is ALWAYS invoking experimental @@ -92,7 +105,7 @@ extern JS_PUBLIC_API bool CompileOffThreadModule( extern JS_PUBLIC_API bool CompileOffThreadModule( JSContext* cx, const ReadOnlyCompileOptions& options, SourceText& srcBuf, OffThreadCompileCallback callback, - void* callbackData); + void* callbackData, OffThreadToken** tokenOut = nullptr); extern JS_PUBLIC_API JSObject* FinishOffThreadModule(JSContext* cx, OffThreadToken* token); @@ -106,12 +119,14 @@ extern JS_PUBLIC_API bool CanDecodeOffThread( extern JS_PUBLIC_API bool DecodeOffThreadScript( JSContext* cx, const ReadOnlyCompileOptions& options, mozilla::Vector& buffer /* TranscodeBuffer& */, size_t cursor, - OffThreadCompileCallback callback, void* callbackData); + OffThreadCompileCallback callback, void* callbackData, + OffThreadToken** tokenOut = nullptr); extern JS_PUBLIC_API bool DecodeOffThreadScript( JSContext* cx, const ReadOnlyCompileOptions& options, const mozilla::Range& range /* TranscodeRange& */, - OffThreadCompileCallback callback, void* callbackData); + OffThreadCompileCallback callback, void* callbackData, + OffThreadToken** tokenOut = nullptr); extern JS_PUBLIC_API JSScript* FinishOffThreadScriptDecoder( JSContext* cx, OffThreadToken* token); @@ -131,20 +146,17 @@ extern JS_PUBLIC_API bool FinishMultiOffThreadScriptsDecoder( extern JS_PUBLIC_API void CancelMultiOffThreadScriptsDecoder( JSContext* cx, OffThreadToken* token); -// This returns false if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API bool CanDecodeBinASTOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -// This throws an exception if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API bool DecodeBinASTOffThread( - JSContext* cx, const ReadOnlyCompileOptions& options, const uint8_t* buf, - size_t length, JS::BinASTFormat format, OffThreadCompileCallback callback, - void* callbackData); - -// This throws an exception if built without JS_BUILD_BINAST. -extern JS_PUBLIC_API JSScript* FinishOffThreadBinASTDecode( - JSContext* cx, OffThreadToken* token); +// Tell off-thread compilation to/not to use the parse global. +// The default value is true. +// +// If set to false, off-thread compilation will compile to stencil, and +// instantiate the stencil on main-thread. +extern JS_PUBLIC_API void SetUseOffThreadParseGlobal(bool value); } // namespace JS +namespace js { +extern bool UseOffThreadParseGlobal(); +} // namespace js + #endif /* js_OffThreadScriptCompilation_h */ diff --git a/js/public/Promise.h b/js/public/Promise.h index 626d1e1988..e50ca18324 100644 --- a/js/public/Promise.h +++ b/js/public/Promise.h @@ -6,7 +6,6 @@ #define js_Promise_h #include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" #include "jspubtd.h" #include "js/RootingAPI.h" @@ -221,8 +220,7 @@ extern JS_PUBLIC_API void SetJobQueue(JSContext* cx, JobQueue* queue); */ class MOZ_RAII JS_PUBLIC_API AutoDebuggerJobQueueInterruption { public: - explicit AutoDebuggerJobQueueInterruption( - MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM); + explicit AutoDebuggerJobQueueInterruption(); ~AutoDebuggerJobQueueInterruption(); bool init(JSContext* cx); @@ -250,7 +248,6 @@ class MOZ_RAII JS_PUBLIC_API AutoDebuggerJobQueueInterruption { void runJobs(); private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER; JSContext* cx; js::UniquePtr saved; }; diff --git a/js/public/PropertySpec.h b/js/public/PropertySpec.h index c56bde049d..e79eae0c14 100644 --- a/js/public/PropertySpec.h +++ b/js/public/PropertySpec.h @@ -22,7 +22,7 @@ #include "js/Value.h" // JS::Value struct JS_PUBLIC_API JSContext; -struct JSJitInfo; +class JSJitInfo; /** * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will diff --git a/js/public/Proxy.h b/js/public/Proxy.h index fdc0bcdde0..8f6d7e5d9e 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -12,6 +12,8 @@ #include "js/Array.h" // JS::IsArrayAnswer #include "js/CallNonGenericMethod.h" #include "js/Class.h" +#include "js/Object.h" // JS::GetClass +#include "js/shadow/Object.h" // JS::shadow::Object namespace js { @@ -318,6 +320,10 @@ class JS_FRIEND_API BaseProxyHandler { HandleValue v, HandleValue receiver, ObjectOpResult& result) const; + // Use the ProxyExpando object for private fields, rather than taking the + // normal get/set/defineField paths. + virtual bool useProxyExpandoObjectForPrivateFields() const { return true; } + /* * [[Call]] and [[Construct]] are standard internal methods but according * to the spec, they are not present on every object. @@ -377,7 +383,7 @@ class JS_FRIEND_API BaseProxyHandler { extern JS_FRIEND_DATA const JSClass ProxyClass; inline bool IsProxy(const JSObject* obj) { - return GetObjectClass(obj)->isProxy(); + return JS::GetClass(obj)->isProxy(); } namespace detail { @@ -387,6 +393,8 @@ namespace detail { // // Every proxy has a ProxyValueArray that contains the following Values: // +// - The expando slot. This is used to hold private fields should they be +// stamped into a non-forwarding proxy type. // - The private slot. // - The reserved slots. The number of slots is determined by the proxy's Class. // @@ -395,8 +403,8 @@ namespace detail { // ProxyValueArray::fromReservedSlots or ProxyDataLayout::values. // // Storing a pointer to ProxyReservedSlots instead of ProxyValueArray has a -// number of advantages. In particular, it means js::GetReservedSlot and -// js::SetReservedSlot can be used with both proxies and native objects. This +// number of advantages. In particular, it means JS::GetReservedSlot and +// JS::SetReservedSlot can be used with both proxies and native objects. This // works because the ProxyReservedSlots* pointer is stored where native objects // store their dynamic slots pointer. @@ -420,10 +428,12 @@ struct ProxyReservedSlots { }; struct ProxyValueArray { + Value expandoSlot; Value privateSlot; ProxyReservedSlots reservedSlots; void init(size_t nreserved) { + expandoSlot = JS::ObjectOrNullValue(nullptr); privateSlot = JS::UndefinedValue(); reservedSlots.init(nreserved); } @@ -484,7 +494,7 @@ JS_FRIEND_API void SetValueInProxy(Value* slot, const Value& value); inline void SetProxyReservedSlotUnchecked(JSObject* obj, size_t n, const Value& extra) { - MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); + MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(JS::GetClass(obj))); Value* vp = &GetProxyDataLayout(obj)->reservedSlots->slots[n]; @@ -506,12 +516,16 @@ inline const Value& GetProxyPrivate(const JSObject* obj) { return detail::GetProxyDataLayout(obj)->values()->privateSlot; } +inline const Value& GetProxyExpando(const JSObject* obj) { + return detail::GetProxyDataLayout(obj)->values()->expandoSlot; +} + inline JSObject* GetProxyTargetObject(JSObject* obj) { return GetProxyPrivate(obj).toObjectOrNull(); } inline const Value& GetProxyReservedSlot(const JSObject* obj, size_t n) { - MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj))); + MOZ_ASSERT(n < JSCLASS_RESERVED_SLOTS(JS::GetClass(obj))); return detail::GetProxyDataLayout(obj)->reservedSlots->slots[n]; } @@ -707,7 +721,7 @@ constexpr unsigned CheckProxyFlags() { (offsetof(js::detail::ProxyValueArray, reservedSlots) / sizeof(Value)) + ((Flags >> JSCLASS_RESERVED_SLOTS_SHIFT) & JSCLASS_RESERVED_SLOTS_MASK) <= - shadow::Object::MAX_FIXED_SLOTS, + JS::shadow::Object::MAX_FIXED_SLOTS, "ProxyValueArray size must not exceed max JSObject size"); // Proxies must not have the JSCLASS_SKIP_NURSERY_FINALIZE flag set: they diff --git a/js/public/Realm.h b/js/public/Realm.h index 2014db76e4..cd9d30be2d 100644 --- a/js/public/Realm.h +++ b/js/public/Realm.h @@ -5,7 +5,10 @@ #ifndef js_Realm_h #define js_Realm_h +#include "js/shadow/Realm.h" // JS::shadow::Realm + #include "jspubtd.h" +#include "js/GCAPI.h" #include "js/GCPolicyAPI.h" #include "js/TypeDecls.h" // forward-declaration of JS::Realm @@ -36,23 +39,6 @@ struct GCPolicy : public NonGCPointerPolicy { // Realm Record". extern JS_PUBLIC_API Realm* GetCurrentRealmOrNull(JSContext* cx); -namespace shadow { - -class Realm { - protected: - JS::Compartment* compartment_; - - explicit Realm(JS::Compartment* comp) : compartment_(comp) {} - - public: - JS::Compartment* compartment() { return compartment_; } - static shadow::Realm* get(JS::Realm* realm) { - return reinterpret_cast(realm); - } -}; - -}; // namespace shadow - // Return the compartment that contains a given realm. inline JS::Compartment* GetCompartmentForRealm(Realm* realm) { return shadow::Realm::get(realm)->compartment(); @@ -82,8 +68,9 @@ typedef void (*DestroyRealmCallback)(JSFreeOp* fop, Realm* realm); extern JS_PUBLIC_API void SetDestroyRealmCallback( JSContext* cx, DestroyRealmCallback callback); -typedef void (*RealmNameCallback)(JSContext* cx, Handle realm, - char* buf, size_t bufsize); +using RealmNameCallback = void (*)(JSContext* cx, Realm* realm, char* buf, + size_t bufsize, + const JS::AutoRequireNoGC& nogc); // Set the callback SpiderMonkey calls to get the name of a realm, for // diagnostic output. @@ -92,7 +79,7 @@ extern JS_PUBLIC_API void SetRealmNameCallback(JSContext* cx, // Get the global object for the given realm. This only returns nullptr during // GC, between collecting the global object and destroying the Realm. -extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Handle realm); +extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Realm* realm); // Initialize standard JS class constructors, prototypes, and any top-level // functions and constants associated with the standard classes (e.g. isNaN diff --git a/js/public/RealmOptions.h b/js/public/RealmOptions.h index e26ee1e6ec..79ffa57407 100644 --- a/js/public/RealmOptions.h +++ b/js/public/RealmOptions.h @@ -127,15 +127,27 @@ class JS_PUBLIC_API RealmCreationOptions { return *this; } - bool cloneSingletons() const { return cloneSingletons_; } - RealmCreationOptions& setCloneSingletons(bool flag) { - cloneSingletons_ = flag; - return *this; - } - + // Determines whether 1) the global Atomic property is defined and atomic + // operations are supported, and 2) whether shared-memory operations are + // supported. bool getSharedMemoryAndAtomicsEnabled() const; RealmCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag); + // Determines (if getSharedMemoryAndAtomicsEnabled() is true) whether the + // global SharedArrayBuffer property is defined. If the property is not + // defined, shared array buffer functionality can only be invoked if the + // host/embedding specifically acts to expose it. + // + // This option defaults to true: embeddings unable to tolerate a global + // SharedAraryBuffer property must opt out of it. + bool defineSharedArrayBufferConstructor() const { + return defineSharedArrayBufferConstructor_; + } + RealmCreationOptions& setDefineSharedArrayBufferConstructor(bool flag) { + defineSharedArrayBufferConstructor_ = flag; + return *this; + } + bool getStreamsEnabled() const { return streams_; } RealmCreationOptions& setStreamsEnabled(bool flag) { streams_ = flag; @@ -192,12 +204,6 @@ class JS_PUBLIC_API RealmCreationOptions { return *this; } - bool getPrivateClassFieldsEnabled() const { return privateClassFields_; } - RealmCreationOptions& setPrivateClassFieldsEnabled(bool flag) { - privateClassFields_ = flag; - return *this; - } - // This flag doesn't affect JS engine behavior. It is used by Gecko to // mark whether content windows and workers are "Secure Context"s. See // https://w3c.github.io/webappsec-secure-contexts/ @@ -219,8 +225,8 @@ class JS_PUBLIC_API RealmCreationOptions { bool invisibleToDebugger_ = false; bool mergeable_ = false; bool preserveJitCode_ = false; - bool cloneSingletons_ = false; bool sharedMemoryAndAtomics_ = false; + bool defineSharedArrayBufferConstructor_ = true; bool streams_ = false; bool readableByteStreams_ = false; bool byobStreamReaders_ = false; @@ -229,7 +235,6 @@ class JS_PUBLIC_API RealmCreationOptions { bool toSource_ = false; bool propertyErrorMessageFix_ = false; bool iteratorHelpers_ = false; - bool privateClassFields_ = false; bool secureContext_ = false; }; @@ -284,12 +289,6 @@ class JS_PUBLIC_API RealmBehaviors { Mode mode_; }; - bool getSingletonsAsTemplates() const { return singletonsAsTemplates_; } - RealmBehaviors& setSingletonsAsValues() { - singletonsAsTemplates_ = false; - return *this; - } - // A Realm can stop being "live" in all the ways that matter before its global // is actually GCed. Consumers that tear down parts of a Realm or its global // before that point should set isNonLive accordingly. @@ -303,11 +302,6 @@ class JS_PUBLIC_API RealmBehaviors { bool discardSource_ = false; bool disableLazyParsing_ = false; bool clampAndJitterTime_ = true; - - // To XDR singletons, we need to ensure that all singletons are all used as - // templates, by making JSOP_OBJECT return a clone of the JSScript - // singleton, instead of returning the value which is baked in the JSScript. - bool singletonsAsTemplates_ = true; bool isNonLive_ = false; }; diff --git a/js/public/Result.h b/js/public/Result.h index f8195aca45..5db0560277 100644 --- a/js/public/Result.h +++ b/js/public/Result.h @@ -15,13 +15,13 @@ * can't fail, don't use Result. Otherwise: * * JS::Result<> - function can fail, doesn't return anything on success - * (defaults to `JS::Result`) - * JS::Result - like JS::Result<>, but fails only on OOM + * (defaults to `JS::Result`) + * JS::Result - like JS::Result<>, but fails only on OOM * * JS::Result - function can fail, returns Data on success - * JS::Result - returns Data, fails only on OOM + * JS::Result - returns Data, fails only on OOM * - * mozilla::GenericErrorResult - always fails + * mozilla::GenericErrorResult - always fails * * That last type is like a Result with no success type. It's used for * functions like `js::ReportNotFunction` that always return an error @@ -175,17 +175,81 @@ namespace JS { using mozilla::Ok; +template +struct UnusedZero; + /** * Type representing a JS error or exception. At the moment this only * "represents" an error in a rather abstract way. */ struct Error { - // Ensure sizeof(Error) > 1 so that Result can use pointer - // tagging. - int dummy; + // Since we claim UnusedZero::value and HasFreeLSB::value == + // true below, we must only use positive even enum values. + enum class ErrorKind : uintptr_t { Unspecified = 2, OOM = 4 }; + + const ErrorKind kind = ErrorKind::Unspecified; + + Error() = default; + + protected: + friend struct UnusedZero; + + constexpr MOZ_IMPLICIT Error(ErrorKind aKind) : kind(aKind) {} +}; + +struct OOM : Error { + constexpr OOM() : Error(ErrorKind::OOM) {} + + protected: + friend struct UnusedZero; + + using Error::Error; }; -struct OOM : public Error {}; +template +struct UnusedZero { + using StorageType = std::underlying_type_t; + + static constexpr bool value = true; + static constexpr StorageType nullValue = 0; + static constexpr StorageType GetDefaultValue() { + return T::ErrorKind::Unspecified; + } + + static constexpr void AssertValid(StorageType aValue) {} + static constexpr T Inspect(const StorageType& aValue) { + return static_cast(aValue); + } + static constexpr T Unwrap(StorageType aValue) { + return static_cast(aValue); + } + static constexpr StorageType Store(T aValue) { + return static_cast(aValue.kind); + } +}; + +} // namespace JS + +namespace mozilla::detail { + +template <> +struct UnusedZero : JS::UnusedZero {}; + +template <> +struct UnusedZero : JS::UnusedZero {}; + +template <> +struct HasFreeLSB { + static const bool value = true; +}; + +template <> +struct HasFreeLSB { + static const bool value = true; +}; +} // namespace mozilla::detail + +namespace JS { /** * `Result` is intended to be the return type of JSAPI calls and internal @@ -202,14 +266,14 @@ struct OOM : public Error {}; * return. JS `catch` blocks can't catch this kind of failure, * and JS `finally` blocks don't execute. */ -template +template using Result = mozilla::Result; static_assert(sizeof(Result<>) == sizeof(uintptr_t), "Result<> should be pointer-sized"); -static_assert(sizeof(Result) == sizeof(uintptr_t), - "Result should be pointer-sized"); +static_assert(sizeof(Result) == sizeof(uintptr_t), + "Result should be pointer-sized"); } // namespace JS diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index 18a5686fc9..b280d52ce2 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -8,12 +8,11 @@ #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/EnumeratedArray.h" -#include "mozilla/GuardObjects.h" #include "mozilla/LinkedList.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" #include +#include #include "jspubtd.h" @@ -21,6 +20,7 @@ #include "js/GCAnnotations.h" #include "js/GCPolicyAPI.h" #include "js/GCTypeMacros.h" // JS_FOR_EACH_PUBLIC_{,TAGGED_}GC_POINTER_TYPE +#include "js/HashTable.h" #include "js/HeapAPI.h" #include "js/ProfilingStack.h" #include "js/Realm.h" @@ -538,6 +538,22 @@ struct DefineComparisonOps> : std::true_type { } // namespace detail +// std::swap uses a stack temporary, which prevents classes like Heap +// from being declared MOZ_HEAP_CLASS. +template +void swap(TenuredHeap& aX, TenuredHeap& aY) { + T tmp = aX; + aX = aY; + aY = tmp; +} + +template +void swap(Heap& aX, Heap& aY) { + T tmp = aX; + aX = aY; + aY = tmp; +} + static MOZ_ALWAYS_INLINE bool ObjectIsMarkedGray( const JS::TenuredHeap& obj) { return ObjectIsMarkedGray(obj.unbarrieredGetPtr()); @@ -813,7 +829,8 @@ struct JS_PUBLIC_API MovableCellHasher { static bool ensureHash(const Lookup& l); static HashNumber hash(const Lookup& l); static bool match(const Key& k, const Lookup& l); - static void rekey(Key& k, const Key& newKey) { k = newKey; } + // The rekey hash policy method is not provided since you dont't need to + // rekey any more when using this policy. }; template @@ -833,7 +850,6 @@ struct JS_PUBLIC_API MovableCellHasher> { static bool match(const Key& k, const Lookup& l) { return MovableCellHasher::match(k.unbarrieredGet(), l); } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } }; } // namespace js @@ -856,43 +872,43 @@ struct FallibleHashMethods> { namespace js { -// The alignment must be set because the Rooted and PersistentRooted ptr fields -// may be accessed through reinterpret_cast*>, and -// the compiler may choose a different alignment for the ptr field when it -// knows the actual type stored in DispatchWrapper. -// -// It would make more sense to align only those specific fields of type -// DispatchWrapper, rather than DispatchWrapper itself, but that causes MSVC to -// fail when Rooted is used in an IsConvertible test. +struct VirtualTraceable { + virtual ~VirtualTraceable() = default; + virtual void trace(JSTracer* trc, const char* name) = 0; +}; + template -class alignas(8) DispatchWrapper { +struct RootedTraceable final : public VirtualTraceable { static_assert(JS::MapTypeToRootKind::kind == JS::RootKind::Traceable, - "DispatchWrapper is intended only for usage with a Traceable"); + "RootedTraceable is intended only for usage with a Traceable"); - using TraceFn = void (*)(JSTracer*, T*, const char*); - TraceFn tracer; - alignas(gc::CellAlignBytes) T storage; + T ptr; - public: template - MOZ_IMPLICIT DispatchWrapper(U&& initial) - : tracer(&JS::GCPolicy::trace), storage(std::forward(initial)) {} - - // Mimic a pointer type, so that we can drop into Rooted. - T* operator&() { return &storage; } - const T* operator&() const { return &storage; } - operator T&() { return storage; } - operator const T&() const { return storage; } - - // Trace the contained storage (of unknown type) using the trace function - // we set aside when we did know the type. - static void TraceWrapped(JSTracer* trc, T* thingp, const char* name) { - auto wrapper = reinterpret_cast( - uintptr_t(thingp) - offsetof(DispatchWrapper, storage)); - wrapper->tracer(trc, &wrapper->storage, name); + MOZ_IMPLICIT RootedTraceable(U&& initial) : ptr(std::forward(initial)) {} + + operator T&() { return ptr; } + operator const T&() const { return ptr; } + + void trace(JSTracer* trc, const char* name) override { + JS::GCPolicy::trace(trc, &ptr, name); } }; +template +struct RootedTraceableTraits { + static T* address(RootedTraceable& self) { return &self.ptr; } + static const T* address(const RootedTraceable& self) { return &self.ptr; } + static void trace(JSTracer* trc, VirtualTraceable* thingp, const char* name); +}; + +template +struct RootedGCThingTraits { + static T* address(T& self) { return &self; } + static const T* address(const T& self) { return &self; } + static void trace(JSTracer* trc, T* thingp, const char* name); +}; + } /* namespace js */ namespace JS { @@ -1020,18 +1036,16 @@ class JS_PUBLIC_API AutoGCRooter { namespace detail { -/* - * For pointer types, the TraceKind for tracing is based on the list it is - * in (selected via MapTypeToRootKind), so no additional storage is - * required here. Non-pointer types, however, share the same list, so the - * function to call for tracing is stored adjacent to the struct. Since C++ - * cannot templatize on storage class, this is implemented via the wrapper - * class DispatchWrapper. - */ template -using MaybeWrapped = +using RootedPtr = std::conditional_t::kind == JS::RootKind::Traceable, - js::DispatchWrapper, T>; + js::RootedTraceable, T>; + +template +using RootedPtrTraits = + std::conditional_t::kind == JS::RootKind::Traceable, + js::RootedTraceableTraits, + js::RootedGCThingTraits>; // Dummy types to make it easier to understand template overload preference // ordering. @@ -1051,6 +1065,9 @@ using OverloadSelector = PreferredOverload; */ template class MOZ_RAII Rooted : public js::RootedBase> { + using Ptr = detail::RootedPtr; + using PtrTraits = detail::RootedPtrTraits; + inline void registerWithRootLists(RootedListHeads& roots) { this->stack = &roots[JS::MapTypeToRootKind::kind]; this->prev = *stack; @@ -1125,8 +1142,14 @@ class MOZ_RAII Rooted : public js::RootedBase> { DECLARE_POINTER_CONSTREF_OPS(T); DECLARE_POINTER_ASSIGN_OPS(Rooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr); + + T& get() { return ptr; } + const T& get() const { return ptr; } + + T* address() { return PtrTraits::address(ptr); } + const T* address() const { return PtrTraits::address(ptr); } + + void trace(JSTracer* trc, const char* name); private: /* @@ -1137,7 +1160,7 @@ class MOZ_RAII Rooted : public js::RootedBase> { Rooted** stack; Rooted* prev; - detail::MaybeWrapped ptr; + Ptr ptr; Rooted(const Rooted&) = delete; } JS_HAZ_ROOTED; @@ -1308,6 +1331,8 @@ class PersistentRooted : public js::RootedBase>, private mozilla::LinkedListElement> { using ListBase = mozilla::LinkedListElement>; + using Ptr = detail::RootedPtr; + using PtrTraits = detail::RootedPtrTraits; friend class mozilla::LinkedList; friend class mozilla::LinkedListElement; @@ -1372,7 +1397,7 @@ class PersistentRooted const_cast(rhs).setNext(this); } - bool initialized() { return ListBase::isInList(); } + bool initialized() const { return ListBase::isInList(); } void init(RootingContext* cx) { init(cx, SafelyInitialized()); } void init(JSContext* cx) { init(RootingContext::get(cx)); } @@ -1397,19 +1422,15 @@ class PersistentRooted DECLARE_POINTER_CONSTREF_OPS(T); DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); - // These are the same as DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS, except - // they check that |this| is initialized in case the caller later stores - // something in |ptr|. + T& get() { return ptr; } + const T& get() const { return ptr; } + T* address() { MOZ_ASSERT(initialized()); - return &ptr; - } - T& get() { - MOZ_ASSERT(initialized()); - return ptr; + return PtrTraits::address(ptr); } + const T* address() const { return PtrTraits::address(ptr); } template void set(U&& value) { @@ -1417,8 +1438,10 @@ class PersistentRooted ptr = std::forward(value); } + void trace(JSTracer* trc, const char* name); + private: - detail::MaybeWrapped ptr; + Ptr ptr; } JS_HAZ_ROOTED; namespace detail { @@ -1502,25 +1525,7 @@ void CallTraceCallbackOnNonHeap(T* v, const TraceCallbacks& aCallbacks, } } /* namespace gc */ -} /* namespace js */ - -// mozilla::Swap uses a stack temporary, which prevents classes like Heap -// from being declared MOZ_HEAP_CLASS. -namespace mozilla { - -template -inline void Swap(JS::Heap& aX, JS::Heap& aY) { - T tmp = aX; - aX = aY; - aY = tmp; -} -template -inline void Swap(JS::TenuredHeap& aX, JS::TenuredHeap& aY) { - T tmp = aX; - aX = aY; - aY = tmp; -} +} /* namespace js */ -} /* namespace mozilla */ #endif /* js_RootingAPI_h */ diff --git a/js/public/ScalarType.h b/js/public/ScalarType.h new file mode 100644 index 0000000000..262a981f7c --- /dev/null +++ b/js/public/ScalarType.h @@ -0,0 +1,126 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* An enumeration of all possible element types in typed data. */ + +#ifndef js_ScalarType_h +#define js_ScalarType_h + +#include "mozilla/Assertions.h" // MOZ_CRASH + +#include // size_t + +namespace js { + +namespace Scalar { + +// Scalar types that can appear in typed arrays and typed objects. +// The enum values must be kept in sync with: +// * the JS_SCALARTYPEREPR constants +// * the TYPEDARRAY_KIND constants +// * the SCTAG_TYPED_ARRAY constants +// * JS_FOR_EACH_TYPEDARRAY +// * JS_FOR_PROTOTYPES_ +// * JS_FOR_EACH_UNIQUE_SCALAR_TYPE_REPR_CTYPE +// * JIT compilation +enum Type { + Int8 = 0, + Uint8, + Int16, + Uint16, + Int32, + Uint32, + Float32, + Float64, + + /** + * Special type that is a uint8_t, but assignments are clamped to [0, 256). + * Treat the raw data type as a uint8_t. + */ + Uint8Clamped, + + BigInt64, + BigUint64, + + /** + * Types that don't have their own TypedArray equivalent, for now. + */ + MaxTypedArrayViewType, + + Int64, +}; + +static inline size_t byteSize(Type atype) { + switch (atype) { + case Int8: + case Uint8: + case Uint8Clamped: + return 1; + case Int16: + case Uint16: + return 2; + case Int32: + case Uint32: + case Float32: + return 4; + case Int64: + case Float64: + case BigInt64: + case BigUint64: + return 8; + case MaxTypedArrayViewType: + break; + } + MOZ_CRASH("invalid scalar type"); +} + +static inline bool isSignedIntType(Type atype) { + switch (atype) { + case Int8: + case Int16: + case Int32: + case Int64: + case BigInt64: + return true; + case Uint8: + case Uint8Clamped: + case Uint16: + case Uint32: + case Float32: + case Float64: + case BigUint64: + return false; + case MaxTypedArrayViewType: + break; + } + MOZ_CRASH("invalid scalar type"); +} + +static inline bool isBigIntType(Type atype) { + switch (atype) { + case BigInt64: + case BigUint64: + return true; + case Int8: + case Int16: + case Int32: + case Int64: + case Uint8: + case Uint8Clamped: + case Uint16: + case Uint32: + case Float32: + case Float64: + return false; + case MaxTypedArrayViewType: + break; + } + MOZ_CRASH("invalid scalar type"); +} + +} // namespace Scalar + +} // namespace js + +#endif // js_ScalarType_h diff --git a/js/public/StableStringChars.h b/js/public/StableStringChars.h index 392c4927b0..9cdf89553b 100644 --- a/js/public/StableStringChars.h +++ b/js/public/StableStringChars.h @@ -20,8 +20,8 @@ #include "jstypes.h" // JS_FRIEND_API -#include "js/HeapAPI.h" // JS::shadow::String #include "js/RootingAPI.h" // JS::Handle, JS::Rooted +#include "js/String.h" // JS::GetStringLength #include "js/TypeDecls.h" // JSContext, JS::Latin1Char, JSString #include "js/Vector.h" // js::Vector @@ -29,18 +29,13 @@ class JSLinearString; namespace JS { -MOZ_ALWAYS_INLINE size_t GetStringLength(JSString* s) { - return reinterpret_cast(s)->length(); -} - /** - * This class provides safe access to a string's chars across a GC. Once - * we allocate strings and chars in the nursery (bug 903519), this class - * will have to make a copy of the string's chars if they are allocated - * in the nursery, so it's best to avoid using this class unless you really - * need it. It's usually more efficient to use the latin1Chars/twoByteChars - * JSString methods and often the code can be rewritten so that only indexes - * instead of char pointers are used in parts of the code that can GC. + * This class provides safe access to a string's chars across a GC. If we ever + * nursery allocate strings' out of line chars, this class will have to make a + * copy, so it's best to avoid using this class unless you really need it. It's + * usually more efficient to use the latin1Chars/twoByteChars JSString methods + * and often the code can be rewritten so that only indexes instead of char + * pointers are used in parts of the code that can GC. */ class MOZ_STACK_CLASS JS_FRIEND_API AutoStableStringChars final { /* diff --git a/js/public/Stream.h b/js/public/Stream.h index 17fd02a599..8cb5ccd2f0 100644 --- a/js/public/Stream.h +++ b/js/public/Stream.h @@ -21,6 +21,8 @@ #include "js/RootingAPI.h" #include "js/TypeDecls.h" +struct JSClass; + namespace JS { /** @@ -498,6 +500,37 @@ class JS_PUBLIC_API WritableStreamUnderlyingSink { virtual void finalize() = 0; }; +/** + * The signature of a function that, when passed an |AbortSignal| instance, will + * return the value of its "aborted" flag. + * + * This function will be called while |signal|'s realm has been entered. + */ +using AbortSignalIsAborted = bool (*)(JSObject* signal); + +/** + * Dictate all details of handling of |AbortSignal| objects for SpiderMonkey to + * use. This should only be performed once, for a single context associated + * with a |JSRuntime|. + * + * The |ReadableStream.prototype.pipeTo| function accepts a |signal| argument + * that may be used to abort the piping operation. This argument must be either + * |undefined| (in other words, the piping operation can't be aborted) or an + * |AbortSignal| instance. |AbortSignal| is defined by WebIDL and the DOM in + * the web embedding. Therefore, embedders must use this function to specify + * how such objects can be recognized and how to perform various essential + * actions upon them. + * + * The provided |isAborted| function will be called with an unwrapped + * |AbortSignal| instance, while that instance's realm has been entered. + * + * If this function isn't called, and a situation arises where an "is this an + * |AbortSignal|?" question must be asked, that question will simply be answered + * "no". + */ +extern JS_PUBLIC_API void InitAbortSignalHandling( + const JSClass* clasp, AbortSignalIsAborted isAborted, JSContext* cx); + } // namespace JS #endif // js_Stream_h diff --git a/js/public/String.h b/js/public/String.h new file mode 100644 index 0000000000..b7bacb8ffa --- /dev/null +++ b/js/public/String.h @@ -0,0 +1,231 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* JavaScript string operations. */ + +#ifndef js_String_h +#define js_String_h + +#include "js/shadow/String.h" // JS::shadow::String + +#include "mozilla/Assertions.h" // MOZ_ASSERT +#include "mozilla/Attributes.h" // MOZ_ALWAYS_INLINE, MOZ_MUST_USE +#include "mozilla/Likely.h" // MOZ_LIKELY + +#include // std::copy_n +#include // size_t +#include // uint32_t, uint64_t, INT32_MAX + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/TypeDecls.h" // JS::Latin1Char + +class JS_PUBLIC_API JSAtom; +class JSLinearString; +class JS_PUBLIC_API JSString; + +namespace JS { + +class JS_PUBLIC_API AutoRequireNoGC; + +/** + * Maximum length of a JS string. This is chosen so that the number of bytes + * allocated for a null-terminated TwoByte string still fits in int32_t. + */ +static constexpr uint32_t MaxStringLength = (1 << 30) - 2; + +static_assert((uint64_t(MaxStringLength) + 1) * sizeof(char16_t) <= INT32_MAX, + "size of null-terminated JSString char buffer must fit in " + "INT32_MAX"); + +/** Compute the length of a string. */ +MOZ_ALWAYS_INLINE size_t GetStringLength(JSString* s) { + return shadow::AsShadowString(s)->length(); +} + +/** Compute the length of a linear string. */ +MOZ_ALWAYS_INLINE size_t GetLinearStringLength(JSLinearString* s) { + return shadow::AsShadowString(s)->length(); +} + +/** Return true iff the given linear string uses Latin-1 storage. */ +MOZ_ALWAYS_INLINE bool LinearStringHasLatin1Chars(JSLinearString* s) { + return shadow::AsShadowString(s)->hasLatin1Chars(); +} + +/** Return true iff the given string uses Latin-1 storage. */ +MOZ_ALWAYS_INLINE bool StringHasLatin1Chars(JSString* s) { + return shadow::AsShadowString(s)->hasLatin1Chars(); +} + +/** + * Given a linear string known to use Latin-1 storage, return a pointer to that + * storage. This pointer remains valid only as long as no GC occurs. + */ +MOZ_ALWAYS_INLINE const Latin1Char* GetLatin1LinearStringChars( + const AutoRequireNoGC& nogc, JSLinearString* linear) { + return shadow::AsShadowString(linear)->latin1LinearChars(); +} + +/** + * Given a linear string known to use two-byte storage, return a pointer to that + * storage. This pointer remains valid only as long as no GC occurs. + */ +MOZ_ALWAYS_INLINE const char16_t* GetTwoByteLinearStringChars( + const AutoRequireNoGC& nogc, JSLinearString* linear) { + return shadow::AsShadowString(linear)->twoByteLinearChars(); +} + +/** + * Given an in-range index into the provided string, return the character at + * that index. + */ +MOZ_ALWAYS_INLINE char16_t GetLinearStringCharAt(JSLinearString* linear, + size_t index) { + shadow::String* s = shadow::AsShadowString(linear); + MOZ_ASSERT(index < s->length()); + + return s->hasLatin1Chars() ? s->latin1LinearChars()[index] + : s->twoByteLinearChars()[index]; +} + +/** + * Convert an atom to a linear string. All atoms are linear, so this + * operation is infallible. + */ +MOZ_ALWAYS_INLINE JSLinearString* AtomToLinearString(JSAtom* atom) { + return reinterpret_cast(atom); +} + +/** + * If the provided string uses externally-managed storage, return true and set + * |*callbacks| to the external-string callbacks used to create it and |*chars| + * to a pointer to its two-byte storage. (These pointers remain valid as long + * as the provided string is kept alive.) + */ +MOZ_ALWAYS_INLINE bool IsExternalString( + JSString* str, const JSExternalStringCallbacks** callbacks, + const char16_t** chars) { + shadow::String* s = shadow::AsShadowString(str); + + if (!s->isExternal()) { + return false; + } + + *callbacks = s->externalCallbacks; + *chars = s->nonInlineCharsTwoByte; + return true; +} + +namespace detail { + +extern JS_FRIEND_API JSLinearString* StringToLinearStringSlow(JSContext* cx, + JSString* str); + +} // namespace detail + +/** Convert a string to a linear string. */ +MOZ_ALWAYS_INLINE JSLinearString* StringToLinearString(JSContext* cx, + JSString* str) { + if (MOZ_LIKELY(shadow::AsShadowString(str)->isLinear())) { + return reinterpret_cast(str); + } + + return detail::StringToLinearStringSlow(cx, str); +} + +/** Copy characters in |s[start..start + len]| to |dest[0..len]|. */ +MOZ_ALWAYS_INLINE void CopyLinearStringChars(char16_t* dest, JSLinearString* s, + size_t len, size_t start = 0) { +#ifdef DEBUG + size_t stringLen = GetLinearStringLength(s); + MOZ_ASSERT(start <= stringLen); + MOZ_ASSERT(len <= stringLen - start); +#endif + + shadow::String* str = shadow::AsShadowString(s); + + if (str->hasLatin1Chars()) { + const Latin1Char* src = str->latin1LinearChars(); + for (size_t i = 0; i < len; i++) { + dest[i] = src[start + i]; + } + } else { + const char16_t* src = str->twoByteLinearChars(); + std::copy_n(src + start, len, dest); + } +} + +/** + * Copy characters in |s[start..start + len]| to |dest[0..len]|, lossily + * truncating 16-bit values to |char| if necessary. + */ +MOZ_ALWAYS_INLINE void LossyCopyLinearStringChars(char* dest, JSLinearString* s, + size_t len, + size_t start = 0) { +#ifdef DEBUG + size_t stringLen = GetLinearStringLength(s); + MOZ_ASSERT(start <= stringLen); + MOZ_ASSERT(len <= stringLen - start); +#endif + + shadow::String* str = shadow::AsShadowString(s); + + if (LinearStringHasLatin1Chars(s)) { + const Latin1Char* src = str->latin1LinearChars(); + for (size_t i = 0; i < len; i++) { + dest[i] = char(src[start + i]); + } + } else { + const char16_t* src = str->twoByteLinearChars(); + for (size_t i = 0; i < len; i++) { + dest[i] = char(src[start + i]); + } + } +} + +/** + * Copy characters in |s[start..start + len]| to |dest[0..len]|. + * + * This function is fallible. If you already have a linear string, use the + * infallible |JS::CopyLinearStringChars| above instead. + */ +inline MOZ_MUST_USE bool CopyStringChars(JSContext* cx, char16_t* dest, + JSString* s, size_t len, + size_t start = 0) { + JSLinearString* linear = StringToLinearString(cx, s); + if (!linear) { + return false; + } + + CopyLinearStringChars(dest, linear, len, start); + return true; +} + +/** + * Copy characters in |s[start..start + len]| to |dest[0..len]|, lossily + * truncating 16-bit values to |char| if necessary. + * + * This function is fallible. If you already have a linear string, use the + * infallible |JS::LossyCopyLinearStringChars| above instead. + */ +inline MOZ_MUST_USE bool LossyCopyStringChars(JSContext* cx, char* dest, + JSString* s, size_t len, + size_t start = 0) { + JSLinearString* linear = StringToLinearString(cx, s); + if (!linear) { + return false; + } + + LossyCopyLinearStringChars(dest, linear, len, start); + return true; +} + +} // namespace JS + +/** DO NOT USE, only present for Rust bindings as a temporary hack */ +[[deprecated]] extern JS_PUBLIC_API bool JS_DeprecatedStringHasLatin1Chars( + JSString* str); + +#endif // js_String_h diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index b08da4781c..df68824f76 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -8,12 +8,13 @@ #include "mozilla/Attributes.h" #include "mozilla/BufferList.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" #include +#include #include "jstypes.h" +#include "js/AllocPolicy.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" #include "js/Value.h" @@ -265,7 +266,8 @@ typedef bool (*WriteStructuredCloneOp)(JSContext* cx, * 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); +typedef void (*StructuredCloneErrorOp)(JSContext* cx, uint32_t errorid, + void* closure, const char* errorMessage); /** * This is called when JS_ReadStructuredClone receives a transferable object @@ -319,6 +321,19 @@ typedef bool (*CanTransferStructuredCloneOp)(JSContext* cx, bool* sameProcessScopeRequired, void* closure); +/** + * Called when a SharedArrayBuffer (including one owned by a Wasm memory object) + * has been processed in context `cx` by structured cloning. If `receiving` is + * true then the SAB has been received from a channel and a new SAB object has + * been created; if false then an existing SAB has been serialized onto a + * channel. + * + * If the callback returns false then the clone operation (read or write) will + * signal a failure. + */ +typedef bool (*SharedArrayBufferClonedOp)(JSContext* cx, bool receiving, + void* closure); + struct JSStructuredCloneCallbacks { ReadStructuredCloneOp read; WriteStructuredCloneOp write; @@ -327,6 +342,7 @@ struct JSStructuredCloneCallbacks { TransferStructuredCloneOp writeTransfer; FreeTransferStructuredCloneOp freeTransfer; CanTransferStructuredCloneOp canTransfer; + SharedArrayBufferClonedOp sabCloned; }; enum OwnTransferablePolicy { @@ -684,6 +700,8 @@ class JS_PUBLIC_API JSAutoStructuredCloneBuffer { #define JS_SCERR_DUP_TRANSFERABLE 2 #define JS_SCERR_UNSUPPORTED_TYPE 3 #define JS_SCERR_SHMEM_TRANSFERABLE 4 +#define JS_SCERR_TYPED_ARRAY_DETACHED 5 +#define JS_SCERR_WASM_NO_TRANSFER 6 JS_PUBLIC_API bool JS_ReadUint32Pair(JSStructuredCloneReader* r, uint32_t* p1, uint32_t* p2); diff --git a/js/public/Symbol.h b/js/public/Symbol.h index d40f0eeb1e..333db103e3 100644 --- a/js/public/Symbol.h +++ b/js/public/Symbol.h @@ -7,6 +7,8 @@ #ifndef js_Symbol_h #define js_Symbol_h +#include "js/shadow/Symbol.h" // JS::shadow::Symbol::WellKnownAPILimit + #include // size_t #include // uintptr_t, uint32_t @@ -71,9 +73,7 @@ enum class SymbolCode : uint32_t { JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc. #undef JS_DEFINE_SYMBOL_ENUM Limit, - WellKnownAPILimit = - 0x80000000, // matches JS::shadow::Symbol::WellKnownAPILimit for inline - // use + WellKnownAPILimit = JS::shadow::Symbol::WellKnownAPILimit, PrivateNameSymbol = 0xfffffffd, // created by the #PrivateName syntax. InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor() diff --git a/js/public/TracingAPI.h b/js/public/TracingAPI.h index bae3da2702..627616807d 100644 --- a/js/public/TracingAPI.h +++ b/js/public/TracingAPI.h @@ -5,9 +5,7 @@ #ifndef js_TracingAPI_h #define js_TracingAPI_h -#include "js/AllocPolicy.h" #include "js/GCTypeMacros.h" -#include "js/HashTable.h" #include "js/HeapAPI.h" #include "js/TraceKind.h" @@ -444,20 +442,6 @@ JS_DECLARE_UNSAFE_TRACE_ROOT(js::SavedFrame*) extern JS_PUBLIC_API void TraceChildren(JSTracer* trc, GCCellPtr thing); -using ZoneSet = - js::HashSet, js::SystemAllocPolicy>; -using CompartmentSet = - js::HashSet, - js::SystemAllocPolicy>; - -/** - * Trace every value within |compartments| that is wrapped by a - * cross-compartment wrapper from a compartment that is not an element of - * |compartments|. - */ -extern JS_PUBLIC_API void TraceIncomingCCWs( - JSTracer* trc, const JS::CompartmentSet& compartments); - } // namespace JS extern JS_PUBLIC_API void JS_GetTraceThingInfo(char* buf, size_t bufsize, diff --git a/js/public/Transcoding.h b/js/public/Transcoding.h index 2cbd889b40..c9dc422f16 100644 --- a/js/public/Transcoding.h +++ b/js/public/Transcoding.h @@ -56,6 +56,7 @@ enum TranscodeResult : uint8_t { TranscodeResult_Throw = 0x20 }; +// Encode JSScript into the buffer. extern JS_PUBLIC_API TranscodeResult EncodeScript(JSContext* cx, TranscodeBuffer& buffer, Handle script); @@ -63,6 +64,7 @@ extern JS_PUBLIC_API TranscodeResult EncodeScript(JSContext* cx, extern JS_PUBLIC_API TranscodeResult EncodeInterpretedFunction( JSContext* cx, TranscodeBuffer& buffer, Handle funobj); +// Decode JSScript from the buffer. extern JS_PUBLIC_API TranscodeResult DecodeScript(JSContext* cx, TranscodeBuffer& buffer, MutableHandle scriptp, size_t cursorIndex = 0); @@ -75,21 +77,27 @@ extern JS_PUBLIC_API TranscodeResult DecodeInterpretedFunction( JSContext* cx, TranscodeBuffer& buffer, MutableHandle funp, size_t cursorIndex = 0); -// Register an encoder on the given script source, such that all functions can -// be encoded as they are parsed. This strategy is used to avoid blocking the -// main thread in a non-interruptible way. +// Decode JSScript from the buffer, and register an encoder on its script +// source, such that all functions can be encoded as they are parsed. This +// strategy is used to avoid blocking the main thread in a non-interruptible +// way. // -// The |script| argument of |StartIncrementalEncoding| and -// |FinishIncrementalEncoding| should be the top-level script returned either as -// an out-param of any of the |Compile| functions, or the result of -// |FinishOffThreadScript|. +// See also JS::FinishIncrementalEncoding. +extern JS_PUBLIC_API TranscodeResult DecodeScriptAndStartIncrementalEncoding( + JSContext* cx, TranscodeBuffer& buffer, MutableHandle scriptp, + size_t cursorIndex = 0); + +// Finish incremental encoding started by one of: +// * JS::CompileAndStartIncrementalEncoding +// * JS::FinishOffThreadScriptAndStartIncrementalEncoding +// * JS::DecodeScriptAndStartIncrementalEncoding +// +// The |script| argument of |FinishIncrementalEncoding| should be the top-level +// script returned from one of the above. // // The |buffer| argument of |FinishIncrementalEncoding| is used for appending // the encoded bytecode into the buffer. If any of these functions failed, the // content of |buffer| would be undefined. -extern JS_PUBLIC_API bool StartIncrementalEncoding(JSContext* cx, - Handle script); - extern JS_PUBLIC_API bool FinishIncrementalEncoding(JSContext* cx, Handle script, TranscodeBuffer& buffer); diff --git a/js/public/TypeDecls.h b/js/public/TypeDecls.h index fe5a98871a..65063834c2 100644 --- a/js/public/TypeDecls.h +++ b/js/public/TypeDecls.h @@ -25,7 +25,7 @@ typedef uint8_t jsbytecode; class JS_PUBLIC_API JSAtom; struct JS_PUBLIC_API JSContext; -struct JS_PUBLIC_API JSClass; +struct JSClass; class JS_PUBLIC_API JSFunction; class JS_PUBLIC_API JSFreeOp; class JS_PUBLIC_API JSObject; diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index cc28dc3189..dd6a9dcc1a 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -11,12 +11,14 @@ #include "mozilla/HashFunctions.h" #include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" #include "mozilla/RangedPtr.h" #include "mozilla/Variant.h" +#include + #include "jspubtd.h" +#include "js/AllocPolicy.h" #include "js/GCAPI.h" #include "js/HashTable.h" #include "js/RootingAPI.h" @@ -160,23 +162,25 @@ // structure of the snapshot file, the analyses should be prepared for ubi::Node // graphs constructed from snapshots to be even more bizarre. -namespace JS { -namespace ubi { - -class Edge; -class EdgeRange; -class StackFrame; - -} // namespace ubi -} // namespace JS - namespace js { class BaseScript; } // namespace js namespace JS { + +using ZoneSet = + js::HashSet, js::SystemAllocPolicy>; + +using CompartmentSet = + js::HashSet, + js::SystemAllocPolicy>; + namespace ubi { +class Edge; +class EdgeRange; +class StackFrame; + using mozilla::Maybe; using mozilla::RangedPtr; using mozilla::Variant; diff --git a/js/public/UbiNodeCensus.h b/js/public/UbiNodeCensus.h index 32ceec5702..22af50907e 100644 --- a/js/public/UbiNodeCensus.h +++ b/js/public/UbiNodeCensus.h @@ -6,9 +6,9 @@ #define js_UbiNodeCensus_h #include "mozilla/Attributes.h" -#include "mozilla/Move.h" #include +#include #include "jsapi.h" diff --git a/js/public/UbiNodeDominatorTree.h b/js/public/UbiNodeDominatorTree.h index b69d7a21f0..9ba32589f1 100644 --- a/js/public/UbiNodeDominatorTree.h +++ b/js/public/UbiNodeDominatorTree.h @@ -8,9 +8,10 @@ #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" #include "mozilla/UniquePtr.h" +#include + #include "js/AllocPolicy.h" #include "js/UbiNode.h" #include "js/UbiNodePostOrder.h" diff --git a/js/public/UbiNodePostOrder.h b/js/public/UbiNodePostOrder.h index 3e9c528fd2..fa11a67d6f 100644 --- a/js/public/UbiNodePostOrder.h +++ b/js/public/UbiNodePostOrder.h @@ -7,7 +7,8 @@ #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" + +#include #include "js/AllocPolicy.h" #include "js/UbiNode.h" diff --git a/js/public/UbiNodeShortestPaths.h b/js/public/UbiNodeShortestPaths.h index 51880882b6..61bdb297cd 100644 --- a/js/public/UbiNodeShortestPaths.h +++ b/js/public/UbiNodeShortestPaths.h @@ -7,7 +7,8 @@ #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" + +#include #include "js/AllocPolicy.h" #include "js/UbiNodeBreadthFirst.h" diff --git a/js/public/Utility.h b/js/public/Utility.h index f3d34bef5e..1749eb1f89 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -9,17 +9,17 @@ #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/Compiler.h" -#include "mozilla/Move.h" #include "mozilla/TemplateLib.h" #include "mozilla/UniquePtr.h" #include #include #include +#include #include "jstypes.h" - #include "mozmemory.h" +#include "js/TypeDecls.h" /* The public JS engine namespace. */ namespace JS {} @@ -649,6 +649,7 @@ struct FreePolicy { typedef mozilla::UniquePtr UniqueChars; typedef mozilla::UniquePtr UniqueTwoByteChars; +typedef mozilla::UniquePtr UniqueLatin1Chars; } // namespace JS diff --git a/js/public/Value.h b/js/public/Value.h index aa0115c747..61f773abf0 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -117,21 +117,21 @@ static_assert(sizeof(JSValueTag) == sizeof(uint32_t), "compiler typed enum support is apparently buggy"); enum JSValueShiftedTag : uint64_t { + // See Bug 584653 for why we include 0xFFFFFFFF. JSVAL_SHIFTED_TAG_MAX_DOUBLE = - ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), + ((uint64_t(JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), + JSVAL_SHIFTED_TAG_INT32 = (uint64_t(JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_UNDEFINED = - (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = - (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), + (uint64_t(JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_NULL = (uint64_t(JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_BOOLEAN = (uint64_t(JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_MAGIC = (uint64_t(JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_STRING = (uint64_t(JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_SYMBOL = (uint64_t(JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), JSVAL_SHIFTED_TAG_PRIVATE_GCTHING = - (((uint64_t)JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BIGINT = (((uint64_t)JSVAL_TAG_BIGINT) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) + (uint64_t(JSVAL_TAG_PRIVATE_GCTHING) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_BIGINT = (uint64_t(JSVAL_TAG_BIGINT) << JSVAL_TAG_SHIFT), + JSVAL_SHIFTED_TAG_OBJECT = (uint64_t(JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) }; static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), @@ -148,6 +148,10 @@ constexpr JSValueTag ValueTypeToTag(JSValueType type) { return static_cast(JSVAL_TAG_CLEAR | type); } +constexpr bool ValueIsDouble(uint64_t bits) { + return uint32_t(bits >> JSVAL_TAG_SHIFT) <= uint32_t(JSVAL_TAG_CLEAR); +} + constexpr JSValueTag ValueUpperExclPrimitiveTag = JSVAL_TAG_OBJECT; constexpr JSValueTag ValueUpperInclNumberTag = JSVAL_TAG_INT32; constexpr JSValueTag ValueLowerInclGCThingTag = JSVAL_TAG_STRING; @@ -158,6 +162,10 @@ constexpr JSValueTag ValueTypeToTag(JSValueType type) { return static_cast(JSVAL_TAG_MAX_DOUBLE | type); } +constexpr bool ValueIsDouble(uint64_t bits) { + return bits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; +} + constexpr uint64_t ValueTagMask = 0xFFFF'8000'0000'0000; // This should only be used in toGCThing. See the 'Spectre mitigations' comment. @@ -252,6 +260,15 @@ enum JSWhyMagic { */ JS_WRITABLESTREAM_CLOSE_RECORD, + /** + * The ReadableStream pipe-to operation concludes with a "finalize" operation + * that accepts an optional |error| argument. In certain cases that optional + * |error| must be stored in a handler function, for use after a promise has + * settled. We represent the argument not being provided, in those cases, + * using this magic value. + */ + JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR, + JS_WHY_MAGIC_COUNT }; @@ -263,44 +280,67 @@ namespace JS { namespace detail { +// IEEE-754 bit pattern for double-precision positive infinity. +constexpr int InfinitySignBit = 0; +constexpr uint64_t InfinityBits = + mozilla::InfinityBits::value; + +// This is a quiet NaN on IEEE-754[2008] compatible platforms, including X86, +// ARM, SPARC and modern MIPS. +// +// Note: The default sign bit for a hardware sythesized NaN differs between X86 +// and ARM. Both values are considered compatible values on both +// platforms. constexpr int CanonicalizedNaNSignBit = 0; constexpr uint64_t CanonicalizedNaNSignificand = 0x8000000000000; +#if defined(__sparc__) +// Some architectures (not to name names) generate NaNs with bit patterns that +// are incompatible with JS::Value's bit pattern restrictions. Instead we must +// canonicalize all hardware values before storing in JS::Value. +# define JS_NONCANONICAL_HARDWARE_NAN +#endif + +#if defined(__mips__) && !defined(__mips_nan_2008) +// These builds may run on hardware that has differing polarity of the signaling +// NaN bit. While the kernel may handle the trap for us, it is a performance +// issue so instead we compute the NaN to use on startup. The runtime value must +// still meet `ValueIsDouble` requirements which are checked on startup. + +// In particular, we expect one of the following values on MIPS: +// - 0x7FF7FFFFFFFFFFFF Legacy +// - 0x7FF8000000000000 IEEE-754[2008] +# define JS_RUNTIME_CANONICAL_NAN +#endif + +#if defined(JS_RUNTIME_CANONICAL_NAN) +extern uint64_t CanonicalizedNaNBits; +#else constexpr uint64_t CanonicalizedNaNBits = mozilla::SpecificNaNBits::value; - -constexpr int InfinitySignBit = 0; -constexpr uint64_t InfinityBits = - mozilla::InfinityBits::value; - +#endif } // namespace detail -/** - * Returns a generic quiet NaN value, with all payload bits set to zero. - * - * Among other properties, this NaN's bit pattern conforms to JS::Value's - * bit pattern restrictions. - */ +// Return a quiet NaN that is compatible with JS::Value restrictions. static MOZ_ALWAYS_INLINE double GenericNaN() { - return mozilla::SpecificNaN(detail::CanonicalizedNaNSignBit, - detail::CanonicalizedNaNSignificand); +#if !defined(JS_RUNTIME_CANONICAL_NAN) + static_assert(detail::ValueIsDouble(detail::CanonicalizedNaNBits), + "Canonical NaN must be compatible with JS::Value"); +#endif + + return mozilla::BitwiseCast(detail::CanonicalizedNaNBits); } -static inline double CanonicalizeNaN(double d) { +// Convert an arbitrary double to one compatible with JS::Value representation +// by replacing any NaN value with a canonical one. +static MOZ_ALWAYS_INLINE double CanonicalizeNaN(double d) { if (MOZ_UNLIKELY(mozilla::IsNaN(d))) { return GenericNaN(); } return d; } -#if defined(__sparc__) -// Some architectures (not to name names) generate NaNs with bit -// patterns that don't conform to JS::Value's bit pattern -// restrictions. -# define JS_NONCANONICAL_HARDWARE_NAN -#endif - /** * [SMDOC] JS::Value type * @@ -575,14 +615,7 @@ class alignas(8) Value { return asBits_ == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32)); } - bool isDouble() const { -#if defined(JS_NUNBOX32) - return uint32_t(toTag()) <= uint32_t(JSVAL_TAG_CLEAR); -#elif defined(JS_PUNBOX64) - return (asBits_ | mozilla::FloatingPoint::kSignBit) <= - JSVAL_SHIFTED_TAG_MAX_DOUBLE; -#endif - } + bool isDouble() const { return detail::ValueIsDouble(asBits_); } bool isNumber() const { #if defined(JS_NUNBOX32) @@ -898,7 +931,7 @@ static inline Value CanonicalizedDoubleValue(double d) { return Value::fromDouble(CanonicalizeNaN(d)); } -static inline constexpr Value NaNValue() { +static inline Value NaNValue() { return Value::fromRawBits(detail::CanonicalizedNaNBits); } @@ -1190,7 +1223,8 @@ class MutableWrappedPtrOperations void setUndefined() { set(JS::UndefinedValue()); } void setInt32(int32_t i) { set(JS::Int32Value(i)); } void setDouble(double d) { set(JS::DoubleValue(d)); } - void setNaN() { setDouble(JS::GenericNaN()); } + void setNaN() { set(JS::NaNValue()); } + void setInfinity() { set(JS::InfinityValue()); } void setBoolean(bool b) { set(JS::BooleanValue(b)); } void setMagic(JSWhyMagic why) { set(JS::MagicValue(why)); } void setNumber(uint32_t ui) { set(JS::NumberValue(ui)); } @@ -1237,6 +1271,9 @@ class HeapBase } }; +MOZ_HAVE_NORETURN MOZ_COLD MOZ_NEVER_INLINE void ReportBadValueTypeAndCrash( + const JS::Value& val); + // If the Value is a GC pointer type, call |f| with the pointer cast to that // type and return the result wrapped in a Maybe, otherwise return None(). template @@ -1278,7 +1315,7 @@ auto MapGCThingTyped(const JS::Value& val, F&& f) { } } - MOZ_CRASH("no missing return"); + ReportBadValueTypeAndCrash(val); } // If the Value is a GC pointer type, call |f| with the pointer cast to that diff --git a/js/public/ValueArray.h b/js/public/ValueArray.h index 31aad60b0d..17c59e2106 100644 --- a/js/public/ValueArray.h +++ b/js/public/ValueArray.h @@ -9,7 +9,6 @@ #include "mozilla/Assertions.h" // MOZ_ASSERT #include "mozilla/Attributes.h" // MOZ_IMPLICIT, MOZ_RAII -#include "mozilla/GuardObjects.h" // MOZ_GUARD_OBJECT_NOTIFIER_{INIT,PARAM}, MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER #include // size_t diff --git a/js/public/Wrapper.h b/js/public/Wrapper.h index 707e419b7d..147a4c175d 100644 --- a/js/public/Wrapper.h +++ b/js/public/Wrapper.h @@ -105,6 +105,11 @@ class JS_FRIEND_API ForwardingProxyHandler : public BaseProxyHandler { MutableHandleValue vp) const override; virtual bool isCallable(JSObject* obj) const override; virtual bool isConstructor(JSObject* obj) const override; + + // Use the target object for private fields. + virtual bool useProxyExpandoObjectForPrivateFields() const override { + return false; + } }; /* diff --git a/js/public/experimental/CodeCoverage.h b/js/public/experimental/CodeCoverage.h new file mode 100644 index 0000000000..cca4f9707f --- /dev/null +++ b/js/public/experimental/CodeCoverage.h @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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_experimental_CodeCoverage_h +#define js_experimental_CodeCoverage_h + +#include "jstypes.h" // JS_FRIEND_API +#include "js/Utility.h" // JS::UniqueChars + +struct JS_PUBLIC_API JSContext; + +namespace js { + +/** + * Enable the collection of lcov code coverage metrics. + * Must be called before a runtime is created and before any calls to + * GetCodeCoverageSummary. + */ +extern JS_FRIEND_API void EnableCodeCoverage(); + +/** + * Generate lcov trace file content for the current realm, and allocate a new + * buffer and return the content in it, the size of the newly allocated content + * within the buffer would be set to the length out-param. The 'All' variant + * will collect data for all realms in the runtime. + * + * In case of out-of-memory, this function returns nullptr. The length + * out-param is undefined on failure. + */ +extern JS_FRIEND_API JS::UniqueChars GetCodeCoverageSummary(JSContext* cx, + size_t* length); +extern JS_FRIEND_API JS::UniqueChars GetCodeCoverageSummaryAll(JSContext* cx, + size_t* length); + +} // namespace js + +#endif // js_experimental_CodeCoverage_h diff --git a/js/public/experimental/JitInfo.h b/js/public/experimental/JitInfo.h new file mode 100644 index 0000000000..3a83fb5914 --- /dev/null +++ b/js/public/experimental/JitInfo.h @@ -0,0 +1,334 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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_experimental_JitInfo_h +#define js_experimental_JitInfo_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT + +#include // size_t +#include // uint16_t, uint32_t + +#include "js/CallArgs.h" // JS::CallArgs, JS::detail::CallArgsBase, JSNative +#include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted +#include "js/Value.h" // JS::Value, JSValueType + +namespace js { + +namespace jit { + +enum class InlinableNative : uint16_t; + +} // namespace jit + +} // namespace js + +/** + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitGetterOp. + */ +class JSJitGetterCallArgs : protected JS::MutableHandle { + public: + explicit JSJitGetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandle(args.rval()) {} + + explicit JSJitGetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandle(rooted) {} + + explicit JSJitGetterCallArgs(JS::MutableHandle handle) + : JS::MutableHandle(handle) {} + + JS::MutableHandle rval() { return *this; } +}; + +/** + * A class, expected to be passed by value, which represents the CallArgs for a + * JSJitSetterOp. + */ +class JSJitSetterCallArgs : protected JS::MutableHandle { + public: + explicit JSJitSetterCallArgs(const JS::CallArgs& args) + : JS::MutableHandle(args[0]) {} + + explicit JSJitSetterCallArgs(JS::Rooted* rooted) + : JS::MutableHandle(rooted) {} + + JS::MutableHandle operator[](unsigned i) { + MOZ_ASSERT(i == 0); + return *this; + } + + unsigned length() const { return 1; } + + // Add get() or maybe hasDefined() as needed +}; + +struct JSJitMethodCallArgsTraits; + +/** + * A class, expected to be passed by reference, which represents the CallArgs + * for a JSJitMethodOp. + */ +class JSJitMethodCallArgs + : protected JS::detail::CallArgsBase { + private: + using Base = JS::detail::CallArgsBase; + friend struct JSJitMethodCallArgsTraits; + + public: + explicit JSJitMethodCallArgs(const JS::CallArgs& args) { + argv_ = args.array(); + argc_ = args.length(); + } + + JS::MutableHandle rval() const { return Base::rval(); } + + unsigned length() const { return Base::length(); } + + JS::MutableHandle operator[](unsigned i) const { + return Base::operator[](i); + } + + bool hasDefined(unsigned i) const { return Base::hasDefined(i); } + + JSObject& callee() const { + // We can't use Base::callee() because that will try to poke at + // this->usedRval_, which we don't have. + return argv_[-2].toObject(); + } + + JS::Handle get(unsigned i) const { return Base::get(i); } + + bool requireAtLeast(JSContext* cx, const char* fnname, + unsigned required) const { + // Can just forward to Base, since it only needs the length and we + // forward that already. + return Base::requireAtLeast(cx, fnname, required); + } +}; + +struct JSJitMethodCallArgsTraits { + static constexpr size_t offsetOfArgv = offsetof(JSJitMethodCallArgs, argv_); + static constexpr size_t offsetOfArgc = offsetof(JSJitMethodCallArgs, argc_); +}; + +using JSJitGetterOp = bool (*)(JSContext*, JS::Handle, void*, + JSJitGetterCallArgs); +using JSJitSetterOp = bool (*)(JSContext*, JS::Handle, void*, + JSJitSetterCallArgs); +using JSJitMethodOp = bool (*)(JSContext*, JS::Handle, void*, + const JSJitMethodCallArgs&); + +/** + * This struct contains metadata passed from the DOM to the JS Engine for JIT + * optimizations on DOM property accessors. + * + * Eventually, this should be made available to general JSAPI users as *not* + * experimental and *not* a friend API, but we're not ready to do so yet. + */ +class JSJitInfo { + public: + enum OpType { + Getter, + Setter, + Method, + StaticMethod, + InlinableNative, + IgnoresReturnValueNative, + // Must be last + OpTypeCount + }; + + enum ArgType { + // Basic types + String = (1 << 0), + Integer = (1 << 1), // Only 32-bit or less + Double = (1 << 2), // Maybe we want to add Float sometime too + Boolean = (1 << 3), + Object = (1 << 4), + Null = (1 << 5), + + // And derived types + Numeric = Integer | Double, + // Should "Primitive" use the WebIDL definition, which + // excludes string and null, or the typical JS one that includes them? + Primitive = Numeric | Boolean | Null | String, + ObjectOrNull = Object | Null, + Any = ObjectOrNull | Primitive, + + // Our sentinel value. + ArgTypeListEnd = (1 << 31) + }; + + static_assert(Any & String, "Any must include String"); + static_assert(Any & Integer, "Any must include Integer"); + static_assert(Any & Double, "Any must include Double"); + static_assert(Any & Boolean, "Any must include Boolean"); + static_assert(Any & Object, "Any must include Object"); + static_assert(Any & Null, "Any must include Null"); + + /** + * An enum that describes what this getter/setter/method aliases. This + * determines what things can be hoisted past this call, and if this + * call is movable what it can be hoisted past. + */ + enum AliasSet { + /** + * Alias nothing: a constant value, getting it can't affect any other + * values, nothing can affect it. + */ + AliasNone, + + /** + * Alias things that can modify the DOM but nothing else. Doing the + * call can't affect the behavior of any other function. + */ + AliasDOMSets, + + /** + * Alias the world. Calling this can change arbitrary values anywhere + * in the system. Most things fall in this bucket. + */ + AliasEverything, + + /** Must be last. */ + AliasSetCount + }; + + bool needsOuterizedThisObject() const { + return type() != Getter && type() != Setter; + } + + bool isTypedMethodJitInfo() const { return isTypedMethod; } + + OpType type() const { return OpType(type_); } + + AliasSet aliasSet() const { return AliasSet(aliasSet_); } + + JSValueType returnType() const { return JSValueType(returnType_); } + + union { + JSJitGetterOp getter; + JSJitSetterOp setter; + JSJitMethodOp method; + /** A DOM static method, used for Promise wrappers */ + JSNative staticMethod; + JSNative ignoresReturnValueMethod; + }; + + static unsigned offsetOfIgnoresReturnValueNative() { + return offsetof(JSJitInfo, ignoresReturnValueMethod); + } + + union { + uint16_t protoID; + js::jit::InlinableNative inlinableNative; + }; + + union { + uint16_t depth; + + // Additional opcode for some InlinableNative functions. + uint16_t nativeOp; + }; + + // These fields are carefully packed to take up 4 bytes. If you need more + // bits for whatever reason, please see if you can steal bits from existing + // fields before adding more members to this structure. + static constexpr size_t OpTypeBits = 4; + static constexpr size_t AliasSetBits = 4; + static constexpr size_t ReturnTypeBits = 8; + static constexpr size_t SlotIndexBits = 10; + + /** The OpType that says what sort of function we are. */ + uint32_t type_ : OpTypeBits; + + /** + * The alias set for this op. This is a _minimal_ alias set; in + * particular for a method it does not include whatever argument + * conversions might do. That's covered by argTypes and runtime + * analysis of the actual argument types being passed in. + */ + uint32_t aliasSet_ : AliasSetBits; + + /** The return type tag. Might be JSVAL_TYPE_UNKNOWN. */ + uint32_t returnType_ : ReturnTypeBits; + + static_assert(OpTypeCount <= (1 << OpTypeBits), + "Not enough space for OpType"); + static_assert(AliasSetCount <= (1 << AliasSetBits), + "Not enough space for AliasSet"); + static_assert((sizeof(JSValueType) * 8) <= ReturnTypeBits, + "Not enough space for JSValueType"); + + /** Is op fallible? False in setters. */ + uint32_t isInfallible : 1; + + /** + * Is op movable? To be movable the op must + * not AliasEverything, but even that might + * not be enough (e.g. in cases when it can + * throw or is explicitly not movable). + */ + uint32_t isMovable : 1; + + /** + * Can op be dead-code eliminated? Again, this + * depends on whether the op can throw, in + * addition to the alias set. + */ + uint32_t isEliminatable : 1; + + // XXXbz should we have a JSValueType for the type of the member? + /** + * True if this is a getter that can always + * get the value from a slot of the "this" object. + */ + uint32_t isAlwaysInSlot : 1; + + /** + * True if this is a getter that can sometimes (if the slot doesn't contain + * UndefinedValue()) get the value from a slot of the "this" object. + */ + uint32_t isLazilyCachedInSlot : 1; + + /** True if this is an instance of JSTypedMethodJitInfo. */ + uint32_t isTypedMethod : 1; + + /** + * If isAlwaysInSlot or isSometimesInSlot is true, + * the index of the slot to get the value from. + * Otherwise 0. + */ + uint32_t slotIndex : SlotIndexBits; + + static constexpr size_t maxSlotIndex = (1 << SlotIndexBits) - 1; +}; + +static_assert(sizeof(JSJitInfo) == (sizeof(void*) + 2 * sizeof(uint32_t)), + "There are several thousand instances of JSJitInfo stored in " + "a binary. Please don't increase its space requirements without " + "verifying that there is no other way forward (better packing, " + "smaller datatypes for fields, subclassing, etc.)."); + +struct JSTypedMethodJitInfo { + // We use C-style inheritance here, rather than C++ style inheritance + // because not all compilers support brace-initialization for non-aggregate + // classes. Using C++ style inheritance and constructors instead of + // brace-initialization would also force the creation of static + // constructors (on some compilers) when JSJitInfo and JSTypedMethodJitInfo + // structures are declared. Since there can be several thousand of these + // structures present and we want to have roughly equivalent performance + // across a range of compilers, we do things manually. + JSJitInfo base; + + const JSJitInfo::ArgType* const argTypes; /* For a method, a list of sets of + types that the function + expects. This can be used, + for example, to figure out + when argument coercions can + have side-effects. */ +}; + +#endif // js_experimental_JitInfo_h diff --git a/js/public/experimental/TypedData.h b/js/public/experimental/TypedData.h new file mode 100644 index 0000000000..32be2df447 --- /dev/null +++ b/js/public/experimental/TypedData.h @@ -0,0 +1,398 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Typed array, ArrayBuffer, and DataView creation, predicate, and accessor + * functions. + */ + +#ifndef js_experimental_TypedData_h +#define js_experimental_TypedData_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_CRASH +#include "mozilla/Casting.h" // mozilla::AssertedCast + +#include // size_t +#include // {,u}int8_t, {,u}int16_t, {,u}int32_t + +#include "jstypes.h" // JS_FRIEND_API + +#include "js/Object.h" // JS::GetClass, JS::GetPrivate, JS::GetReservedSlot +#include "js/RootingAPI.h" // JS::Handle +#include "js/ScalarType.h" // js::Scalar::Type + +struct JSClass; +class JS_PUBLIC_API JSObject; + +namespace JS { + +class JS_PUBLIC_API AutoRequireNoGC; + +} // namespace JS + +/* + * Create a new typed array with nelements elements. + * + * These functions (except the WithBuffer variants) fill in the array with + * zeros. + */ + +extern JS_FRIEND_API JSObject* JS_NewInt8Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewUint8Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewUint8ClampedArray(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewInt16Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewUint16Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewInt32Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewUint32Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewFloat32Array(JSContext* cx, + uint32_t nelements); +extern JS_FRIEND_API JSObject* JS_NewFloat64Array(JSContext* cx, + uint32_t nelements); + +/* + * Create a new typed array and copy in values from the given object. The + * object is used as if it were an array; that is, the new array (if + * successfully created) will have length given by array.length, and its + * elements will be those specified by array[0], array[1], and so on, after + * conversion to the typed array element type. + */ + +extern JS_FRIEND_API JSObject* JS_NewInt8ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewUint8ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewUint8ClampedArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewInt16ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewUint16ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewInt32ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewUint32ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewFloat32ArrayFromArray( + JSContext* cx, JS::Handle array); +extern JS_FRIEND_API JSObject* JS_NewFloat64ArrayFromArray( + JSContext* cx, JS::Handle array); + +/* + * Create a new typed array using the given ArrayBuffer or + * SharedArrayBuffer for storage. The length value is optional; if -1 + * is passed, enough elements to use up the remainder of the byte + * array is used as the default value. + */ + +extern JS_FRIEND_API JSObject* JS_NewInt8ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewUint8ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewUint8ClampedArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewInt16ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewUint16ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewInt32ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewUint32ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewBigInt64ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewBigUint64ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewFloat32ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); +extern JS_FRIEND_API JSObject* JS_NewFloat64ArrayWithBuffer( + JSContext* cx, JS::Handle arrayBuffer, uint32_t byteOffset, + int32_t length); + +/** + * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return + * false if a security wrapper is encountered that denies the unwrapping. If + * this test or one of the JS_Is*Array tests succeeds, then it is safe to call + * the various accessor JSAPI calls defined below. + */ +extern JS_FRIEND_API bool JS_IsTypedArrayObject(JSObject* obj); + +/** + * Check whether obj supports JS_GetArrayBufferView* APIs. Note that this may + * return false if a security wrapper is encountered that denies the + * unwrapping. If this test or one of the more specific tests succeeds, then it + * is safe to call the various ArrayBufferView accessor JSAPI calls defined + * below. + */ +extern JS_FRIEND_API bool JS_IsArrayBufferViewObject(JSObject* obj); + +/* + * Test for specific typed array types (ArrayBufferView subtypes) + */ + +extern JS_FRIEND_API bool JS_IsInt8Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsUint8Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsUint8ClampedArray(JSObject* obj); +extern JS_FRIEND_API bool JS_IsInt16Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsUint16Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsInt32Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsUint32Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsFloat32Array(JSObject* obj); +extern JS_FRIEND_API bool JS_IsFloat64Array(JSObject* obj); + +/** + * Return the isShared flag of a typed array, which denotes whether + * the underlying buffer is a SharedArrayBuffer. + * + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow + * be known that it would pass such a test: it is a typed array or a wrapper of + * a typed array, and the unwrapping will succeed. + */ +extern JS_FRIEND_API bool JS_GetTypedArraySharedness(JSObject* obj); + +/* + * Test for specific typed array types (ArrayBufferView subtypes) and return + * the unwrapped object if so, else nullptr. Never throws. + */ + +namespace js { + +extern JS_FRIEND_API JSObject* UnwrapInt8Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapUint8Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapUint8ClampedArray(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapInt16Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapUint16Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapInt32Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapUint32Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapBigInt64Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapBigUint64Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapFloat32Array(JSObject* obj); +extern JS_FRIEND_API JSObject* UnwrapFloat64Array(JSObject* obj); + +extern JS_FRIEND_API JSObject* UnwrapArrayBufferView(JSObject* obj); + +extern JS_FRIEND_API JSObject* UnwrapReadableStream(JSObject* obj); + +namespace detail { + +extern JS_FRIEND_DATA const JSClass* const Int8ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Uint8ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Uint8ClampedArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Int16ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Uint16ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Int32ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Uint32ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const BigInt64ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const BigUint64ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Float32ArrayClassPtr; +extern JS_FRIEND_DATA const JSClass* const Float64ArrayClassPtr; + +const size_t TypedArrayLengthSlot = 1; + +} // namespace detail + +#define JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Type, type) \ + inline void Get##Type##ArrayLengthAndData( \ + JSObject* obj, uint32_t* length, bool* isSharedMemory, type** data) { \ + MOZ_ASSERT(JS::GetClass(obj) == detail::Type##ArrayClassPtr); \ + const JS::Value& lenSlot = \ + JS::GetReservedSlot(obj, detail::TypedArrayLengthSlot); \ + *length = mozilla::AssertedCast(lenSlot.toInt32()); \ + *isSharedMemory = JS_GetTypedArraySharedness(obj); \ + *data = static_cast(JS::GetPrivate(obj)); \ + } + +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int8, int8_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8, uint8_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float) +JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double) + +#undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR + +// This one isn't inlined because it's rather tricky (by dint of having to deal +// with a dozen-plus classes and varying slot layouts. +extern JS_FRIEND_API void GetArrayBufferViewLengthAndData(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + uint8_t** data); + +} // namespace js + +/* + * Unwrap Typed arrays all at once. Return nullptr without throwing if the + * object cannot be viewed as the correct typed array, or the typed array + * object on success, filling both outparameters. + */ +extern JS_FRIEND_API JSObject* JS_GetObjectAsInt8Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + int8_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsUint8Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + uint8_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsUint8ClampedArray( + JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsInt16Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + int16_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsUint16Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + uint16_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsInt32Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + int32_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsUint32Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + uint32_t** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsFloat32Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + float** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsFloat64Array(JSObject* obj, + uint32_t* length, + bool* isSharedMemory, + double** data); +extern JS_FRIEND_API JSObject* JS_GetObjectAsArrayBufferView( + JSObject* obj, uint32_t* length, bool* isSharedMemory, uint8_t** data); + +/* + * Get the type of elements in a typed array, or MaxTypedArrayViewType if a + * DataView. + * + * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow + * be known that it would pass such a test: it is an ArrayBufferView or a + * wrapper of an ArrayBufferView, and the unwrapping will succeed. + */ +extern JS_FRIEND_API js::Scalar::Type JS_GetArrayBufferViewType(JSObject* obj); + +/** + * Return the number of elements in a typed array. + * + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow + * be known that it would pass such a test: it is a typed array or a wrapper of + * a typed array, and the unwrapping will succeed. + */ +extern JS_FRIEND_API uint32_t JS_GetTypedArrayLength(JSObject* obj); + +/** + * Return the byte offset from the start of an ArrayBuffer to the start of a + * typed array view. + * + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow + * be known that it would pass such a test: it is a typed array or a wrapper of + * a typed array, and the unwrapping will succeed. + */ +extern JS_FRIEND_API uint32_t JS_GetTypedArrayByteOffset(JSObject* obj); + +/** + * Return the byte length of a typed array. + * + * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow + * be known that it would pass such a test: it is a typed array or a wrapper of + * a typed array, and the unwrapping will succeed. + */ +extern JS_FRIEND_API uint32_t JS_GetTypedArrayByteLength(JSObject* obj); + +/** + * More generic name for JS_GetTypedArrayByteLength to cover DataViews as well + */ +extern JS_FRIEND_API uint32_t JS_GetArrayBufferViewByteLength(JSObject* obj); + +/** + * More generic name for JS_GetTypedArrayByteOffset to cover DataViews as well + */ +extern JS_FRIEND_API uint32_t JS_GetArrayBufferViewByteOffset(JSObject* obj); + +/* + * Return a pointer to the start of the data referenced by a typed array. The + * data is still owned by the typed array, and should not be modified on + * another thread. Furthermore, the pointer can become invalid on GC (if the + * data is small and fits inside the array's GC header), so callers must take + * care not to hold on across anything that could GC. + * + * |obj| must have passed a JS_Is*Array test, or somehow be known that it would + * pass such a test: it is a typed array or a wrapper of a typed array, and the + * unwrapping will succeed. + * + * |*isSharedMemory| will be set to true if the typed array maps a + * SharedArrayBuffer, otherwise to false. + */ + +extern JS_FRIEND_API int8_t* JS_GetInt8ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); +extern JS_FRIEND_API uint8_t* JS_GetUint8ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); +extern JS_FRIEND_API uint8_t* JS_GetUint8ClampedArrayData( + JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&); +extern JS_FRIEND_API int16_t* JS_GetInt16ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); +extern JS_FRIEND_API uint16_t* JS_GetUint16ArrayData( + JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&); +extern JS_FRIEND_API int32_t* JS_GetInt32ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); +extern JS_FRIEND_API uint32_t* JS_GetUint32ArrayData( + JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&); +extern JS_FRIEND_API float* JS_GetFloat32ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); +extern JS_FRIEND_API double* JS_GetFloat64ArrayData(JSObject* obj, + bool* isSharedMemory, + const JS::AutoRequireNoGC&); + +/** + * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific + * versions when possible. + */ +extern JS_FRIEND_API void* JS_GetArrayBufferViewData( + JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&); + +/** + * Return the ArrayBuffer or SharedArrayBuffer underlying an ArrayBufferView. + * This may return a detached buffer. |obj| must be an object that would + * return true for JS_IsArrayBufferViewObject(). + */ +extern JS_FRIEND_API JSObject* JS_GetArrayBufferViewBuffer( + JSContext* cx, JS::Handle obj, bool* isSharedMemory); + +/** + * Create a new DataView using the given buffer for storage. The given buffer + * must be an ArrayBuffer or SharedArrayBuffer (or a cross-compartment wrapper + * of either type), and the offset and length must fit within the bounds of the + * buffer. Currently, nullptr will be returned and an exception will be thrown + * if these conditions do not hold, but do not depend on that behavior. + */ +JS_FRIEND_API JSObject* JS_NewDataView(JSContext* cx, + JS::Handle buffer, + uint32_t byteOffset, int32_t byteLength); + +#endif // js_experimental_TypedData_h diff --git a/js/public/friend/DOMProxy.h b/js/public/friend/DOMProxy.h new file mode 100644 index 0000000000..b5178d4582 --- /dev/null +++ b/js/public/friend/DOMProxy.h @@ -0,0 +1,88 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Specify information about DOMProxy proxies in the DOM, for use by ICs. + * + * Embedders who don't need to define particularly high-performance proxies that + * can have random properties added to them can ignore this header. + */ + +#ifndef js_friend_DOMProxy_h +#define js_friend_DOMProxy_h + +#include // size_t +#include // uint64_t + +#include "jstypes.h" // JS_FRIEND_API + +#include "js/Id.h" // JS::PropertyKey +#include "js/RootingAPI.h" // JS::Handle, JS::Heap +#include "js/Value.h" // JS::UndefinedValue, JS::Value + +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; + +namespace JS { + +/* + * The DOMProxyShadowsCheck function will be called to check if the property for + * id should be gotten from the prototype, or if there is an own property that + * shadows it. + * * If ShadowsViaDirectExpando is returned, then the slot at + * listBaseExpandoSlot contains an expando object which has the property in + * question. + * * If ShadowsViaIndirectExpando is returned, then the slot at + * listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration + * and the expando object in the ExpandoAndGeneration has the property in + * question. + * * If DoesntShadow is returned then the slot at listBaseExpandoSlot should + * either be undefined or point to an expando object that would contain the + * own property. + * * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot + * should contain a private pointer to a ExpandoAndGeneration, which contains + * a JS::Value that should either be undefined or point to an expando object, + * and a uint64 value. If that value changes then the IC for getting a + * property will be invalidated. + * * If Shadows is returned, that means the property is an own property of the + * proxy but doesn't live on the expando object. + */ + +struct ExpandoAndGeneration { + ExpandoAndGeneration() : expando(JS::UndefinedValue()), generation(0) {} + + void OwnerUnlinked() { ++generation; } + + static constexpr size_t offsetOfExpando() { + return offsetof(ExpandoAndGeneration, expando); + } + + static constexpr size_t offsetOfGeneration() { + return offsetof(ExpandoAndGeneration, generation); + } + + Heap expando; + uint64_t generation; +}; + +enum class DOMProxyShadowsResult { + ShadowCheckFailed, + Shadows, + DoesntShadow, + DoesntShadowUnique, + ShadowsViaDirectExpando, + ShadowsViaIndirectExpando +}; + +using DOMProxyShadowsCheck = DOMProxyShadowsResult (*)(JSContext*, + Handle, + Handle); + +extern JS_FRIEND_API void SetDOMProxyInformation( + const void* domProxyHandlerFamily, + DOMProxyShadowsCheck domProxyShadowsCheck); + +} // namespace JS + +#endif // js_friend_DOMProxy_h diff --git a/js/public/friend/DumpFunctions.h b/js/public/friend/DumpFunctions.h new file mode 100644 index 0000000000..6d73e117d6 --- /dev/null +++ b/js/public/friend/DumpFunctions.h @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Functions to print out values during debugging. */ + +#ifndef js_friend_DumpFunctions_h +#define js_friend_DumpFunctions_h + +#include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf + +#include // size_t +#include // FILE + +#include "jstypes.h" // JS_FRIEND_API + +#include "js/Utility.h" // JS::UniqueChars + +class JS_PUBLIC_API JSAtom; +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; +class JS_PUBLIC_API JSScript; +class JS_PUBLIC_API JSString; + +namespace JS { + +struct JS_PUBLIC_API PropertyKey; +class JS_PUBLIC_API Value; + +} // namespace JS + +namespace js { + +class InterpreterFrame; + +} // namespace js + +namespace JS { + +/** Exposed for DumpJSStack */ +extern JS_FRIEND_API JS::UniqueChars FormatStackDump(JSContext* cx, + bool showArgs, + bool showLocals, + bool showThisProps); + +} // namespace JS + +namespace js { + +/* + * These functions are FRIEND_API to help the debugger find them and to support + * temporarily hacking js::Dump* calls into other code. Note that there are + * overloads that do not require the FILE* parameter, which will default to + * stderr. + * + * These functions are no-ops unless built with DEBUG or JS_JITSPEW. + */ + +extern JS_FRIEND_API void DumpString(JSString* str, FILE* fp); + +extern JS_FRIEND_API void DumpAtom(JSAtom* atom, FILE* fp); + +extern JS_FRIEND_API void DumpObject(JSObject* obj, FILE* fp); + +extern JS_FRIEND_API void DumpChars(const char16_t* s, size_t n, FILE* fp); + +extern JS_FRIEND_API void DumpValue(const JS::Value& val, FILE* fp); + +extern JS_FRIEND_API void DumpId(JS::PropertyKey id, FILE* fp); + +extern JS_FRIEND_API bool DumpPC(JSContext* cx, FILE* fp); + +extern JS_FRIEND_API bool DumpScript(JSContext* cx, JSScript* scriptArg, + FILE* fp); + +// Versions for use directly in a debugger (default parameters are not handled +// well in gdb; built-in handles like stderr are not handled well in lldb.) +extern JS_FRIEND_API void DumpString(JSString* str); +extern JS_FRIEND_API void DumpAtom(JSAtom* atom); +extern JS_FRIEND_API void DumpObject(JSObject* obj); +extern JS_FRIEND_API void DumpChars(const char16_t* s, size_t n); +extern JS_FRIEND_API void DumpValue(const JS::Value& val); +extern JS_FRIEND_API void DumpId(JS::PropertyKey id); +extern JS_FRIEND_API void DumpInterpreterFrame( + JSContext* cx, InterpreterFrame* start = nullptr); +extern JS_FRIEND_API bool DumpPC(JSContext* cx); +extern JS_FRIEND_API bool DumpScript(JSContext* cx, JSScript* scriptArg); + +// DumpBacktrace(), unlike the other dump functions, always dumps a backtrace -- +// regardless of DEBUG or JS_JITSPEW. + +extern JS_FRIEND_API void DumpBacktrace(JSContext* cx, FILE* fp); + +extern JS_FRIEND_API void DumpBacktrace(JSContext* cx); + +enum DumpHeapNurseryBehaviour { + CollectNurseryBeforeDump, + IgnoreNurseryObjects +}; + +/** + * Dump the complete object graph of heap-allocated things. + * fp is the file for the dump output. + */ +extern JS_FRIEND_API void DumpHeap( + JSContext* cx, FILE* fp, DumpHeapNurseryBehaviour nurseryBehaviour, + mozilla::MallocSizeOf mallocSizeOf = nullptr); + +} // namespace js + +#endif // js_friend_DumpFunctions_h diff --git a/js/public/friend/ErrorMessages.h b/js/public/friend/ErrorMessages.h new file mode 100644 index 0000000000..6fb0547280 --- /dev/null +++ b/js/public/friend/ErrorMessages.h @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * SpiderMonkey internal error numbering and error-formatting functionality + * (also for warnings). + * + * This functionality is moderately stable. JSErrNum and js::GetErrorMessage + * are widely used inside SpiderMonkey, and Gecko uses them to produce errors + * identical to those SpiderMonkey itself would produce, in various situations. + * However, the set of error numbers is not stable, error number values are not + * stable, error types are not stable, etc. Use your own error reporting code + * if you can. + */ + +#ifndef js_friend_ErrorMessages_h +#define js_friend_ErrorMessages_h + +#include "jstypes.h" // JS_FRIEND_API + +struct JSErrorFormatString; + +enum JSErrNum { +#define MSG_DEF(name, count, exception, format) name, +#include "js/friend/ErrorNumbers.msg" +#undef MSG_DEF + JSErr_Limit +}; + +namespace js { + +/** + * A JSErrorCallback suitable for passing to |JS_ReportErrorNumberASCII| and + * similar functions in concert with one of the |JSErrNum| error numbers. + * + * This function is a function only of |errorNumber|: |userRef| and ambient + * state have no effect on its behavior. + */ +extern JS_FRIEND_API const JSErrorFormatString* GetErrorMessage( + void* userRef, unsigned errorNumber); + +} // namespace js + +#endif // js_friend_ErrorMessages_h diff --git a/js/src/js.msg b/js/public/friend/ErrorNumbers.msg similarity index 96% rename from js/src/js.msg rename to js/public/friend/ErrorNumbers.msg index 02a9bd7300..5cba2fcb95 100644 --- a/js/src/js.msg +++ b/js/public/friend/ErrorNumbers.msg @@ -2,6 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * SpiderMonkey error messages. + * + * These are largely for internal use, but they're exposed publicly as a + * "friend" interface for embedders that want to replicate SpiderMonkey's exact + * error message behavior in particular circumstances. All names, arities, + * types, and messages are subject to change or removal. However, the + * longer-lived the error message, the less likely it is to change. + */ + /* * This is the JavaScript error message file. * @@ -17,7 +27,7 @@ * is an integer literal specifying the total number of * replaceable arguments in the following format string. * - * is an enum JSExnType value, defined in jsapi.h. + * is an enum JSExnType value, defined in js/ErrorReport.h. * * is a string literal, optionally containing sequences * {X} where X is an integer representing the argument number that will @@ -70,7 +80,9 @@ MSG_DEF(JSMSG_SOURCE_ARRAY_TOO_LONG, 0, JSEXN_RANGEERR, "source array is too l MSG_DEF(JSMSG_REDECLARED_PREV, 2, JSEXN_NOTE, "Previously declared at line {0}, column {1}") MSG_DEF(JSMSG_REDECLARED_VAR, 2, JSEXN_SYNTAXERR, "redeclaration of {0} {1}") MSG_DEF(JSMSG_UNDECLARED_VAR, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") +MSG_DEF(JSMSG_UNDECLARED_PRIVATE, 0, JSEXN_TYPEERR, "Trying to read undeclared field") MSG_DEF(JSMSG_GETTER_ONLY, 1, JSEXN_TYPEERR, "setting getter-only property {0}") +MSG_DEF(JSMSG_PRIVATE_SETTER_ONLY, 0, JSEXN_TYPEERR, "getting private setter-only property") MSG_DEF(JSMSG_OVERWRITING_ACCESSOR, 1, JSEXN_TYPEERR, "can't overwrite accessor property {0}") MSG_DEF(JSMSG_INVALID_MAP_ITERABLE, 1, JSEXN_TYPEERR, "iterable for {0} should have array-like objects") MSG_DEF(JSMSG_NESTING_GENERATOR, 0, JSEXN_TYPEERR, "already executing generator") @@ -128,9 +140,9 @@ MSG_DEF(JSMSG_IN_NOT_OBJECT, 1, JSEXN_TYPEERR, "right-hand side of 'in MSG_DEF(JSMSG_IN_STRING, 2, JSEXN_TYPEERR, "cannot use 'in' operator to search for {0} in {1}") MSG_DEF(JSMSG_TOO_MANY_CON_SPREADARGS, 0, JSEXN_RANGEERR, "too many constructor arguments") MSG_DEF(JSMSG_TOO_MANY_FUN_SPREADARGS, 0, JSEXN_RANGEERR, "too many function arguments") -MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration `{0}' before initialization") -MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const `{0}'") -MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding `{0}': {1}") +MSG_DEF(JSMSG_UNINITIALIZED_LEXICAL, 1, JSEXN_REFERENCEERR, "can't access lexical declaration '{0}' before initialization") +MSG_DEF(JSMSG_BAD_CONST_ASSIGN, 1, JSEXN_TYPEERR, "invalid assignment to const '{0}'") +MSG_DEF(JSMSG_CANT_DECLARE_GLOBAL_BINDING, 2, JSEXN_TYPEERR, "cannot declare global binding '{0}': {1}") // Date MSG_DEF(JSMSG_INVALID_DATE, 0, JSEXN_RANGEERR, "invalid date") @@ -224,6 +236,7 @@ MSG_DEF(JSMSG_BAD_STRICT_ASSIGN_EVAL, 0, JSEXN_SYNTAXERR, "'eval' can't be defi MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement") MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'") MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods") +MSG_DEF(JSMSG_BAD_SUPERPRIVATE, 0, JSEXN_SYNTAXERR, "invalid access of private field on 'super'") MSG_DEF(JSMSG_BAD_SUPERCALL, 0, JSEXN_SYNTAXERR, "super() is only valid in derived class constructors") MSG_DEF(JSMSG_BAD_ARGUMENTS, 0, JSEXN_SYNTAXERR, "arguments is not valid in fields") MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing ] after element list") @@ -272,6 +285,8 @@ MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage a MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence") MSG_DEF(JSMSG_MISSING_PRIVATE_NAME, 0, JSEXN_SYNTAXERR, "'#' not followed by identifier") +MSG_DEF(JSMSG_PRIVATE_DELETE, 0, JSEXN_SYNTAXERR, "private fields can't be deleted") +MSG_DEF(JSMSG_MISSING_PRIVATE_DECL, 1, JSEXN_SYNTAXERR, "reference to undeclared private field or method {0}") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character") MSG_DEF(JSMSG_IMPORT_META_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "import.meta may only appear in a module") MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module") @@ -366,6 +381,7 @@ MSG_DEF(JSMSG_BAD_OPTIONAL_TEMPLATE, 0, JSEXN_SYNTAXERR, "tagged template cann MSG_DEF(JSMSG_ESCAPED_KEYWORD, 0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes") MSG_DEF(JSMSG_PRIVATE_FIELDS_NOT_SUPPORTED, 0, JSEXN_SYNTAXERR, "private fields are not currently supported") MSG_DEF(JSMSG_ILLEGAL_PRIVATE_FIELD, 0, JSEXN_SYNTAXERR, "private fields aren't valid in this context") +MSG_DEF(JSMSG_PRIVATE_FIELD_DOUBLE, 0, JSEXN_TYPEERR, "Initializing an object twice is an error with private fields") // UTF-8 source text encoding errors MSG_DEF(JSMSG_BAD_LEADING_UTF8_UNIT, 1, JSEXN_SYNTAXERR, "{0} byte doesn't begin a valid UTF-8 code point") @@ -393,7 +409,6 @@ MSG_DEF(JSMSG_WASM_BAD_IMP_MAX, 1, JSEXN_WASMLINKERROR, "imported {0} wit MSG_DEF(JSMSG_WASM_IMP_SHARED_REQD, 0, JSEXN_WASMLINKERROR, "imported unshared memory but shared required") MSG_DEF(JSMSG_WASM_IMP_SHARED_BANNED, 0, JSEXN_WASMLINKERROR, "imported shared memory but unshared required") MSG_DEF(JSMSG_WASM_BAD_FIT, 2, JSEXN_WASMLINKERROR, "{0} segment does not fit in {1}") -MSG_DEF(JSMSG_WASM_BAD_I64_LINK, 0, JSEXN_WASMLINKERROR, "cannot pass i64 to or from JS") MSG_DEF(JSMSG_WASM_NO_SHMEM_LINK, 0, JSEXN_WASMLINKERROR, "shared memory is disabled") MSG_DEF(JSMSG_WASM_BAD_GLOB_MUT_LINK, 0, JSEXN_WASMLINKERROR, "imported global mutability mismatch") MSG_DEF(JSMSG_WASM_BAD_GLOB_TYPE_LINK, 0, JSEXN_WASMLINKERROR, "imported global type mismatch") @@ -408,6 +423,8 @@ MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access") MSG_DEF(JSMSG_WASM_WAKE_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "too many woken agents") MSG_DEF(JSMSG_WASM_DEREF_NULL, 0, JSEXN_WASMRUNTIMEERROR, "dereferencing null pointer") +MSG_DEF(JSMSG_WASM_MEM_IMP_LIMIT, 0, JSEXN_WASMRUNTIMEERROR, "too many memory pages") +MSG_DEF(JSMSG_WASM_TABLE_IMP_LIMIT, 0, JSEXN_WASMRUNTIMEERROR, "too many table elements") MSG_DEF(JSMSG_WASM_BAD_RANGE , 2, JSEXN_RANGEERR, "bad {0} {1}") MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}") MSG_DEF(JSMSG_WASM_TABLE_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "table index out of bounds") @@ -417,20 +434,20 @@ MSG_DEF(JSMSG_WASM_BAD_MOD_ARG, 0, JSEXN_TYPEERR, "first argument mus MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG, 0, JSEXN_TYPEERR, "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object") MSG_DEF(JSMSG_WASM_BAD_DESC_ARG, 1, JSEXN_TYPEERR, "first argument must be a {0} descriptor") MSG_DEF(JSMSG_WASM_BAD_ELEMENT, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\"") -MSG_DEF(JSMSG_WASM_BAD_ELEMENT_GENERALIZED, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\" or \"anyref\"") +MSG_DEF(JSMSG_WASM_BAD_ELEMENT_GENERALIZED, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\" or \"externref\"") MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument must be an object") MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 1, JSEXN_TYPEERR, "import object field '{0}' is not an Object") MSG_DEF(JSMSG_WASM_BAD_FUNCREF_VALUE, 0, JSEXN_TYPEERR, "can only pass WebAssembly exported functions to funcref") -MSG_DEF(JSMSG_WASM_BAD_I64_TYPE, 0, JSEXN_TYPEERR, "cannot pass i64 to or from JS") +MSG_DEF(JSMSG_WASM_BAD_I64_TYPE, 0, JSEXN_TYPEERR, "cannot pass v128 to or from JS") MSG_DEF(JSMSG_WASM_BAD_GLOBAL_TYPE, 0, JSEXN_TYPEERR, "bad type for a WebAssembly.Global") MSG_DEF(JSMSG_WASM_NO_TRANSFER, 0, JSEXN_TYPEERR, "cannot transfer WebAssembly/asm.js ArrayBuffer") MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}") MSG_DEF(JSMSG_WASM_MISSING_MAXIMUM, 0, JSEXN_TYPEERR, "'shared' is true but maximum is not specified") MSG_DEF(JSMSG_WASM_GLOBAL_IMMUTABLE, 0, JSEXN_TYPEERR, "can't set value of immutable global") -MSG_DEF(JSMSG_WASM_NULL_REQUIRED, 0, JSEXN_TYPEERR, "nullref requires a null value") MSG_DEF(JSMSG_WASM_TYPEREF_FROM_JS, 0, JSEXN_TYPEERR, "conversion from JavaScript value to WebAssembly typed ref unimplemented") MSG_DEF(JSMSG_WASM_TYPEREF_TO_JS, 0, JSEXN_TYPEERR, "conversion from WebAssembly typed ref to JavaScript value unimplemented") MSG_DEF(JSMSG_WASM_WRONG_NUMBER_OF_VALUES, 2, JSEXN_TYPEERR, "wrong number of values returned by JavaScript to WebAssembly (expected {0}, got {1})") +MSG_DEF(JSMSG_WASM_NONSHARED_WAIT , 0, JSEXN_WASMRUNTIMEERROR, "atomic wait on non-shared memory") // Proxy MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") @@ -503,19 +520,19 @@ MSG_DEF(JSMSG_DEBUG_NOT_ON_STACK_OR_SUSPENDED, 1, JSEXN_ERR, "{0} is not on stac MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects") MSG_DEF(JSMSG_DEBUG_PROTO, 2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance") MSG_DEF(JSMSG_DEBUG_WRONG_OWNER, 1, JSEXN_TYPEERR, "{0} belongs to a different Debugger") -MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable `{0}' has been optimized out") +MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT, 1, JSEXN_ERR, "variable '{0}' has been optimized out") MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT_FUN, 0, JSEXN_ERR, "function is optimized out") MSG_DEF(JSMSG_DEBUG_FORCED_RETURN_DISALLOWED, 0, JSEXN_TYPEERR, "can't force return from a generator before the initial yield") MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook") MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment") MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY, 3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required") -MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee `{0}:{1}' would run") +MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN, 2, JSEXN_DEBUGGEEWOULDRUN, "debuggee '{0}:{1}' would run") MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined") MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true") MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so") MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'") MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property") -MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set `{0}' in an optimized-out environment") +MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set '{0}' in an optimized-out environment") MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger") MSG_DEF(JSMSG_DEBUG_CENSUS_BREAKDOWN, 1, JSEXN_TYPEERR, "unrecognized 'by' value in takeCensus breakdown: {0}") MSG_DEF(JSMSG_DEBUG_PROMISE_NOT_RESOLVED, 0, JSEXN_TYPEERR, "Promise hasn't been resolved") @@ -547,6 +564,9 @@ MSG_DEF(JSMSG_INVALID_DATETIME_OPTION, 2, JSEXN_TYPEERR, "can't set option {0} w MSG_DEF(JSMSG_INVALID_DATETIME_STYLE, 2, JSEXN_TYPEERR, "can't set option {0} in Date.{1}()") MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style") MSG_DEF(JSMSG_UNDEFINED_UNIT, 0, JSEXN_TYPEERR, "undefined unit in NumberFormat() with unit style") +MSG_DEF(JSMSG_UNDEFINED_DATE, 2, JSEXN_TYPEERR, "undefined {0}-date in DateTimeFormat.{1}()") +MSG_DEF(JSMSG_UNDEFINED_TYPE, 0, JSEXN_TYPEERR, "missing \"type\" option in DisplayNames()") +MSG_DEF(JSMSG_START_AFTER_END_DATE, 1, JSEXN_RANGEERR, "start-date after end-date in DateTimeFormat.{0}()") // RegExp MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") @@ -650,7 +670,6 @@ MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found f MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found") MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status") MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED, 0, JSEXN_TYPEERR, "error loading dynamically imported module") -MSG_DEF(JSMSG_BAD_MODULE_SPECIFIER, 1, JSEXN_TYPEERR, "error resolving module specifier '{0}'") // Promise MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.") @@ -735,9 +754,6 @@ MSG_DEF(JSMSG_BIGINT_INVALID_SYNTAX, 0, JSEXN_SYNTAXERR, "invalid BigInt syntax" MSG_DEF(JSMSG_BIGINT_NOT_SERIALIZABLE, 0, JSEXN_TYPEERR, "BigInt value can't be serialized in JSON") MSG_DEF(JSMSG_SC_BIGINT_DISABLED, 0, JSEXN_ERR, "BigInt not cloned - feature disabled in receiver") -// BinAST -MSG_DEF(JSMSG_BINAST, 1, JSEXN_SYNTAXERR, "BinAST Parsing Error: {0}") - // FinalizationRegistry MSG_DEF(JSMSG_NOT_A_FINALIZATION_REGISTRY, 1, JSEXN_TYPEERR, "{0} is not a FinalizationRegistry") MSG_DEF(JSMSG_NOT_A_FINALIZATION_ITERATOR, 1, JSEXN_TYPEERR, "{0} is not a FinalizationRegistryCleanupIterator") @@ -751,4 +767,7 @@ MSG_DEF(JSMSG_BAD_FINALIZATION_REGISTRY_OBJECT, 0, JSEXN_TYPEERR, "cann MSG_DEF(JSMSG_NOT_A_WEAK_REF, 1, JSEXN_TYPEERR, "{0} is not a WeakRef") MSG_DEF(JSMSG_BAD_WEAKREF_TARGET, 0, JSEXN_TYPEERR, "cannot use the given object as the target of a WeakRef") +// Iterator Helpers +MSG_DEF(JSMSG_NEGATIVE_LIMIT, 0, JSEXN_RANGEERR, "Iterator limits cannot be negative") + //clang-format on diff --git a/js/public/friend/JSMEnvironment.h b/js/public/friend/JSMEnvironment.h new file mode 100644 index 0000000000..4c40796732 --- /dev/null +++ b/js/public/friend/JSMEnvironment.h @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 provided for the JSM component loader in Gecko, that requires + * its own unique manner of global environment and currently requires assistance + * from SpiderMonkey to do so. + * + * Embedders who aren't Gecko can ignore this header. + */ + +#ifndef js_friend_JSMEnvironment_h +#define js_friend_JSMEnvironment_h + +#include "jstypes.h" // JS_FRIEND_API, JS_PUBLIC_API + +#include "js/GCVector.h" // JS::StackGCVector +#include "js/RootingAPI.h" // JS::Handle + +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; +class JS_PUBLIC_API JSScript; + +// A 'JSMEnvironment' refers to an environment chain constructed for JSM loading +// in a shared global. Internally it is a NonSyntacticVariablesObject with a +// corresponding extensible LexicalEnvironmentObject that is accessible by +// JS_ExtensibleLexicalEnvironment. The |this| value of that lexical environment +// is the NSVO itself. +// +// Normal global environment (ES6): JSM "global" environment: +// +// * - extensible lexical environment +// | (code runs in this environment; +// | `let/const` bindings go here) +// | +// * - JSMEnvironment (=== `this`) +// | (`var` bindings go here) +// | +// * - extensible lexical environment * - extensible lexical environment +// | (code runs in this environment; | (empty) +// | `let/const` bindings go here) | +// | | +// * - actual global (=== `this`) * - shared JSM global +// (var bindings go here; and (Object, Math, etc. live here) +// Object, Math, etc. live here) + +namespace JS { + +/** + * Allocate a new environment in the current compartment that is compatible with + * JSM shared loading. + */ +extern JS_FRIEND_API JSObject* NewJSMEnvironment(JSContext* cx); + +/** + * Execute the given script (copied into the current compartment if necessary) + * in the given JSMEnvironment. The script must have been compiled for + * hasNonSyntacticScope. The |jsmEnv| must have been previously allocated by + * |NewJSMEnvironment|. + * + * NOTE: The associated extensible lexical environment is reused. + */ +extern JS_FRIEND_API bool ExecuteInJSMEnvironment(JSContext* cx, + Handle script, + Handle jsmEnv); + +// Additionally, target objects may be specified as required by the Gecko +// subscript loader. These are wrapped in non-syntactic WithEnvironments and +// temporarily placed on the environment chain. +// +// See also: JS::CloneAndExecuteScript(...) +extern JS_FRIEND_API bool ExecuteInJSMEnvironment( + JSContext* cx, Handle script, Handle jsmEnv, + Handle> targetObj); + +// Used by native methods to determine the JSMEnvironment of caller if possible +// by looking at stack frames. Returns nullptr if top frame isn't a scripted +// caller in a JSM. +// +// NOTE: This may find NonSyntacticVariablesObject generated by other embedding +// such as a Gecko FrameScript. Caller can check the compartment if needed. +extern JS_FRIEND_API JSObject* GetJSMEnvironmentOfScriptedCaller(JSContext* cx); + +/** + * Determine if obj is a JSMEnvironment + * + * NOTE: This may return true for an NonSyntacticVariablesObject generated by + * other embedding such as a Gecko FrameScript. Caller can check compartment. + */ +extern JS_FRIEND_API bool IsJSMEnvironment(JSObject* obj); + +} // namespace JS + +#endif // js_friend_JSMEnvironment_h diff --git a/js/public/friend/StackLimits.h b/js/public/friend/StackLimits.h new file mode 100644 index 0000000000..61704bab19 --- /dev/null +++ b/js/public/friend/StackLimits.h @@ -0,0 +1,163 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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_friend_StackLimits_h +#define js_friend_StackLimits_h + +#include "mozilla/Attributes.h" // MOZ_ALWAYS_INLINE, MOZ_COLD +#include "mozilla/Likely.h" // MOZ_LIKELY + +#include // size_t +#include // uintptr_t + +#include "jstypes.h" // JS_FRIEND_API + +#include "js/HeapAPI.h" // JS::StackKind, JS::StackForTrustedScript, JS::StackForUntrustedScript +#include "js/RootingAPI.h" // JS::RootingContext +#include "js/Utility.h" // JS_STACK_OOM_POSSIBLY_FAIL_REPORT, JS_STACK_OOM_POSSIBLY_FAIL + +struct JS_PUBLIC_API JSContext; + +#ifndef JS_STACK_GROWTH_DIRECTION +# ifdef __hppa +# define JS_STACK_GROWTH_DIRECTION (1) +# else +# define JS_STACK_GROWTH_DIRECTION (-1) +# endif +#endif + +#if JS_STACK_GROWTH_DIRECTION > 0 +# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit))) +#else +# define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit))) +#endif + +namespace js { + +namespace detail { + +extern JS_FRIEND_API bool RunningWithTrustedPrincipals(JSContext* cx); + +MOZ_ALWAYS_INLINE uintptr_t GetNativeStackLimitHelper(JSContext* cx, + JS::StackKind kind, + int extraAllowance) { + uintptr_t limit = JS::RootingContext::get(cx)->nativeStackLimit[kind]; +#if JS_STACK_GROWTH_DIRECTION > 0 + limit += extraAllowance; +#else + limit -= extraAllowance; +#endif + return limit; +} + +} // namespace detail + +extern MOZ_COLD JS_FRIEND_API void ReportOverRecursed(JSContext* maybecx); + +MOZ_ALWAYS_INLINE uintptr_t GetNativeStackLimit(JSContext* cx) { + JS::StackKind kind = detail::RunningWithTrustedPrincipals(cx) + ? JS::StackForTrustedScript + : JS::StackForUntrustedScript; + return detail::GetNativeStackLimitHelper(cx, kind, 0); +} + +/* + * These functions return |false| if we are close to using up the C++ stack. + * They also report an overrecursion error, except for the DontReport variants. + * The CheckSystemRecursionLimit variant gives us a little extra space so we + * can ensure that crucial code is able to run. CheckRecursionLimitConservative + * allows less space than any other check, including a safety buffer (as in, it + * uses the untrusted limit and subtracts a little more from it). + */ + +MOZ_ALWAYS_INLINE bool CheckRecursionLimit(JSContext* cx, uintptr_t limit) { + int stackDummy; + + JS_STACK_OOM_POSSIBLY_FAIL_REPORT(); + + if (!JS_CHECK_STACK_SIZE(limit, &stackDummy)) { + ReportOverRecursed(cx); + return false; + } + + return true; +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitDontReport(uintptr_t limit) { + int stackDummy; + + JS_STACK_OOM_POSSIBLY_FAIL(); + + return JS_CHECK_STACK_SIZE(limit, &stackDummy); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimit(JSContext* cx) { + JS_STACK_OOM_POSSIBLY_FAIL_REPORT(); + + // GetNativeStackLimit(cx) is pretty slow because it has to do an uninlined + // call to RunningWithTrustedPrincipals to determine which stack limit to + // use. To work around this, check the untrusted limit first to avoid the + // overhead in most cases. + uintptr_t untrustedLimit = + detail::GetNativeStackLimitHelper(cx, JS::StackForUntrustedScript, 0); + if (MOZ_LIKELY(CheckRecursionLimitDontReport(untrustedLimit))) { + return true; + } + return CheckRecursionLimit(cx, GetNativeStackLimit(cx)); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitDontReport(JSContext* cx) { + return CheckRecursionLimitDontReport(GetNativeStackLimit(cx)); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitWithStackPointerDontReport( + JSContext* cx, void* sp) { + JS_STACK_OOM_POSSIBLY_FAIL(); + + return JS_CHECK_STACK_SIZE(GetNativeStackLimit(cx), sp); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitWithStackPointer(JSContext* cx, + void* sp) { + JS_STACK_OOM_POSSIBLY_FAIL_REPORT(); + + if (!JS_CHECK_STACK_SIZE(GetNativeStackLimit(cx), sp)) { + ReportOverRecursed(cx); + return false; + } + return true; +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitWithExtra(JSContext* cx, + size_t extra) { + char stackDummy; + char* sp = &stackDummy; +#if JS_STACK_GROWTH_DIRECTION > 0 + sp += extra; +#else + sp -= extra; +#endif + return CheckRecursionLimitWithStackPointer(cx, sp); +} + +MOZ_ALWAYS_INLINE bool CheckSystemRecursionLimit(JSContext* cx) { + return CheckRecursionLimit( + cx, detail::GetNativeStackLimitHelper(cx, JS::StackForSystemCode, 0)); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitConservative(JSContext* cx) { + return CheckRecursionLimit( + cx, detail::GetNativeStackLimitHelper(cx, JS::StackForUntrustedScript, + -1024 * int(sizeof(size_t)))); +} + +MOZ_ALWAYS_INLINE bool CheckRecursionLimitConservativeDontReport( + JSContext* cx) { + return CheckRecursionLimitDontReport(detail::GetNativeStackLimitHelper( + cx, JS::StackForUntrustedScript, -1024 * int(sizeof(size_t)))); +} + +} // namespace js + +#endif // js_friend_StackLimits_h diff --git a/js/public/friend/UsageStatistics.h b/js/public/friend/UsageStatistics.h new file mode 100644 index 0000000000..3ec321174a --- /dev/null +++ b/js/public/friend/UsageStatistics.h @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Telemetry and use counter functionality. */ + +#ifndef js_friend_UsageStatistics_h +#define js_friend_UsageStatistics_h + +#include // uint32_t + +#include "jstypes.h" // JS_FRIEND_API + +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; + +/* + * Telemetry reasons passed to the accumulate telemetry callback. + * + * It's OK for these enum values to change as they will be mapped to a fixed + * member of the mozilla::Telemetry::HistogramID enum by the callback. + */ +enum { + JS_TELEMETRY_GC_REASON, + JS_TELEMETRY_GC_IS_ZONE_GC, + JS_TELEMETRY_GC_MS, + JS_TELEMETRY_GC_BUDGET_OVERRUN, + JS_TELEMETRY_GC_ANIMATION_MS, + JS_TELEMETRY_GC_MAX_PAUSE_MS_2, + JS_TELEMETRY_GC_MARK_MS, + JS_TELEMETRY_GC_SWEEP_MS, + JS_TELEMETRY_GC_COMPACT_MS, + JS_TELEMETRY_GC_SLICE_MS, + JS_TELEMETRY_GC_SLOW_PHASE, + JS_TELEMETRY_GC_SLOW_TASK, + JS_TELEMETRY_GC_MMU_50, + JS_TELEMETRY_GC_RESET, + JS_TELEMETRY_GC_RESET_REASON, + JS_TELEMETRY_GC_NON_INCREMENTAL, + JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, + JS_TELEMETRY_GC_MINOR_REASON, + JS_TELEMETRY_GC_MINOR_REASON_LONG, + JS_TELEMETRY_GC_MINOR_US, + JS_TELEMETRY_GC_NURSERY_BYTES, + JS_TELEMETRY_GC_NURSERY_PROMOTION_RATE, + JS_TELEMETRY_END +}; + +using JSAccumulateTelemetryDataCallback = void (*)(int, uint32_t, const char*); + +extern JS_FRIEND_API void JS_SetAccumulateTelemetryCallback( + JSContext* cx, JSAccumulateTelemetryDataCallback callback); + +#endif // js_friend_UsageStatistics_h diff --git a/js/public/friend/WindowProxy.h b/js/public/friend/WindowProxy.h new file mode 100644 index 0000000000..b2e9c2e498 --- /dev/null +++ b/js/public/friend/WindowProxy.h @@ -0,0 +1,104 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Window and WindowProxy. + * + * For silly obscure reasons embedders are better off not knowing, the web wants + * every global object to exist as two linked components: a Window component + * that stores global variables and appears in environment chains but can't be + * directly referred to by any script, and a WindowProxy component that + * intermediates access to its Window that *can* be directly referred to by + * script. (Thus the global |window| and |globalThis| properties, |this| in + * global code, the value of |(function() { return this; })()| in non-strict + * mode code, and similar values are WindowProxy objects, not Windows.) + * + * Maintaining an invariant of never exposing a Window to script requires + * substituting in its WindowProxy in a variety of apparently arbitrary (but + * actually *very* carefully and nervously selected) places throughout the + * engine and indeed the universe. + * + * This header defines functions that let embeddings convert from a WindowProxy + * to its Window and vice versa. + * + * If you're not embedding SpiderMonkey in a web browser, you can almost + * certainly ignore this header. + */ + +#ifndef js_friend_WindowProxy_h +#define js_friend_WindowProxy_h + +#include "jstypes.h" // JS_FRIEND_API, JS_PUBLIC_API + +#include "js/Class.h" // JSCLASS_IS_GLOBAL +#include "js/Object.h" // JS::GetClass +#include "js/RootingAPI.h" // JS::Handle + +struct JSClass; +struct JS_PUBLIC_API JSContext; +class JS_PUBLIC_API JSObject; + +namespace js { + +/** + * Tell the JS engine which Class is used for WindowProxy objects. Used by the + * functions below. + */ +extern JS_FRIEND_API void SetWindowProxyClass(JSContext* cx, + const JSClass* clasp); + +/** + * Associates a WindowProxy with a Window (global object). `windowProxy` must + * have the Class set by SetWindowProxyClass. + */ +extern JS_FRIEND_API void SetWindowProxy(JSContext* cx, + JS::Handle global, + JS::Handle windowProxy); + +namespace detail { + +extern JS_FRIEND_API bool IsWindowSlow(JSObject* obj); + +extern JS_FRIEND_API JSObject* ToWindowProxyIfWindowSlow(JSObject* obj); + +} // namespace detail + +/** + * Returns true iff `obj` is a global object with an associated WindowProxy, + * see SetWindowProxy. + */ +inline bool IsWindow(JSObject* obj) { + if (JS::GetClass(obj)->flags & JSCLASS_IS_GLOBAL) { + return detail::IsWindowSlow(obj); + } + return false; +} + +/** + * Returns true iff `obj` has the WindowProxy Class (see SetWindowProxyClass). + */ +extern JS_FRIEND_API bool IsWindowProxy(JSObject* obj); + +/** + * If `obj` is a Window, get its associated WindowProxy (or a CCW or dead + * wrapper if the page was navigated away from), else return `obj`. This + * function is infallible and never returns nullptr. + */ +MOZ_ALWAYS_INLINE JSObject* ToWindowProxyIfWindow(JSObject* obj) { + if (JS::GetClass(obj)->flags & JSCLASS_IS_GLOBAL) { + return detail::ToWindowProxyIfWindowSlow(obj); + } + return obj; +} + +/** + * If `obj` is a WindowProxy, get its associated Window (the compartment's + * global), else return `obj`. This function is infallible and never returns + * nullptr. + */ +extern JS_FRIEND_API JSObject* ToWindowIfWindowProxy(JSObject* obj); + +} // namespace js + +#endif // js_friend_WindowProxy_h diff --git a/js/public/friend/XrayJitInfo.h b/js/public/friend/XrayJitInfo.h new file mode 100644 index 0000000000..41d9ad435c --- /dev/null +++ b/js/public/friend/XrayJitInfo.h @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * JIT info so SpiderMonkey can efficiently work with Gecko XrayWrapper + * instances. + * + * This header is completely irrelevant to non-Gecko embedders. + */ + +#ifndef js_friend_XrayJitInfo_h +#define js_friend_XrayJitInfo_h + +#include // size_t + +#include "jstypes.h" // JS_FRIEND_API, JS_PUBLIC_API + +class JS_PUBLIC_API JSObject; + +namespace js { + +class JS_FRIEND_API BaseProxyHandler; + +} // namespace js + +namespace JS { + +// Callbacks and other information for use by the JITs when optimizing accesses +// on xray wrappers. +struct XrayJitInfo { + // Test whether a proxy handler is a cross compartment xray with no + // security checks. + bool (*isCrossCompartmentXray)(const js::BaseProxyHandler* handler); + + // Test whether xrays in |obj|'s compartment have expandos of their own, + // instead of sharing them with Xrays from other compartments. + bool (*compartmentHasExclusiveExpandos)(JSObject* obj); + + // Proxy reserved slot used by xrays in sandboxes to store their holder + // object. + size_t xrayHolderSlot; + + // Reserved slot used by xray holders to store the xray's expando object. + size_t holderExpandoSlot; + + // Reserved slot used by xray expandos to store a custom prototype. + size_t expandoProtoSlot; +}; + +extern JS_FRIEND_API void SetXrayJitInfo(XrayJitInfo* info); + +} // namespace JS + +#endif // js_friend_XrayJitInfo_h diff --git a/js/public/shadow/Function.h b/js/public/shadow/Function.h new file mode 100644 index 0000000000..9e67dc6835 --- /dev/null +++ b/js/public/shadow/Function.h @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |JSFunction| innards. Do not use this directly! */ + +#ifndef js_shadow_Function_h +#define js_shadow_Function_h + +#include // uint16_t + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/CallArgs.h" // JSNative +#include "js/shadow/Object.h" // JS::shadow::Object + +class JS_PUBLIC_API JSFunction; +class JSJitInfo; + +namespace JS { + +namespace shadow { + +struct Function { + shadow::Object base; + uint16_t nargs; + uint16_t flags; + /* Used only for natives */ + JSNative native; + const JSJitInfo* jitinfo; + void* _1; +}; + +inline Function* AsShadowFunction(JSFunction* fun) { + return reinterpret_cast(fun); +} + +inline const Function* AsShadowFunction(const JSFunction* fun) { + return reinterpret_cast(fun); +} + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Function_h diff --git a/js/public/shadow/Object.h b/js/public/shadow/Object.h new file mode 100644 index 0000000000..1fee3d3209 --- /dev/null +++ b/js/public/shadow/Object.h @@ -0,0 +1,65 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Shadow definition of |JSObject| innards. (|js::NativeObject| is more + * accurate, but portions can sometimes be used in some non-native objects.) Do + * not use this directly! + */ + +#ifndef js_shadow_Object_h +#define js_shadow_Object_h + +#include // size_t + +#include "js/shadow/Shape.h" // JS::shadow::Shape +#include "js/Value.h" // JS::Value + +class JS_PUBLIC_API JSObject; + +namespace JS { + +class JS_PUBLIC_API Value; + +namespace shadow { + +struct ObjectGroup; + +/** + * This layout is shared by all native objects. For non-native objects, the + * group may always be accessed safely, and other members may be as well, + * depending on the object's specific layout. + */ +struct Object { + shadow::ObjectGroup* group; + shadow::Shape* shape; + Value* slots; + void* _1; + + static constexpr size_t MAX_FIXED_SLOTS = 16; + + size_t numFixedSlots() const { + return (shape->immutableFlags & shadow::Shape::FIXED_SLOTS_MASK) >> + shadow::Shape::FIXED_SLOTS_SHIFT; + } + + Value* fixedSlots() const { + auto address = reinterpret_cast(this); + return reinterpret_cast(address + sizeof(shadow::Object)); + } + + Value& slotRef(size_t slot) const { + size_t nfixed = numFixedSlots(); + if (slot < nfixed) { + return fixedSlots()[slot]; + } + return slots[slot - nfixed]; + } +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Object_h diff --git a/js/public/shadow/ObjectGroup.h b/js/public/shadow/ObjectGroup.h new file mode 100644 index 0000000000..746ffd72ca --- /dev/null +++ b/js/public/shadow/ObjectGroup.h @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |js::ObjectGroup| innards. Do not use this directly! */ + +#ifndef js_shadow_ObjectGroup_h +#define js_shadow_ObjectGroup_h + +#include "jstypes.h" // JS_PUBLIC_API + +struct JSClass; +class JS_PUBLIC_API JSObject; + +namespace JS { + +class JS_PUBLIC_API Realm; + +namespace shadow { + +struct ObjectGroup { + const JSClass* clasp; + JSObject* proto; + JS::Realm* realm; +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_ObjectGroup_h diff --git a/js/public/shadow/Realm.h b/js/public/shadow/Realm.h new file mode 100644 index 0000000000..86e38654b7 --- /dev/null +++ b/js/public/shadow/Realm.h @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |JS::Realm| innards. Do not use this directly! */ + +#ifndef js_shadow_Realm_h +#define js_shadow_Realm_h + +#include "jstypes.h" // JS_PUBLIC_API + +namespace JS { + +class JS_PUBLIC_API Compartment; +class JS_PUBLIC_API Realm; + +namespace shadow { + +class Realm { + protected: + JS::Compartment* compartment_; + + explicit Realm(JS::Compartment* comp) : compartment_(comp) {} + + public: + JS::Compartment* compartment() { return compartment_; } + static shadow::Realm* get(JS::Realm* realm) { + return reinterpret_cast(realm); + } +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Realm_h diff --git a/js/public/shadow/Shape.h b/js/public/shadow/Shape.h new file mode 100644 index 0000000000..6a72638778 --- /dev/null +++ b/js/public/shadow/Shape.h @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Shadow definition of |js::BaseShape| and |js::Shape| innards. Do not use + * this directly! + */ + +#ifndef js_shadow_Shape_h +#define js_shadow_Shape_h + +#include // uint32_t + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/Id.h" // JS::PropertyKey + +struct JSClass; +class JS_PUBLIC_API JSObject; + +namespace JS { + +namespace shadow { + +struct BaseShape { + const JSClass* clasp_; +}; + +class Shape { + public: + shadow::BaseShape* base; + JS::PropertyKey _1; + uint32_t immutableFlags; + + static constexpr uint32_t FIXED_SLOTS_SHIFT = 24; + static constexpr uint32_t FIXED_SLOTS_MASK = 0x1f << FIXED_SLOTS_SHIFT; +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Shape_h diff --git a/js/public/shadow/String.h b/js/public/shadow/String.h new file mode 100644 index 0000000000..6053934bc8 --- /dev/null +++ b/js/public/shadow/String.h @@ -0,0 +1,118 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |JSString| innards. Don't use this directly! */ + +#ifndef js_shadow_String_h +#define js_shadow_String_h + +#include // uint32_t, uintptr_t + +#include "jstypes.h" // JS_PUBLIC_API, js::Bit, js::BitMask, JS_BITS_PER_WORD + +#include "js/TypeDecls.h" // JS::Latin1Char + +class JS_PUBLIC_API JSAtom; +struct JSExternalStringCallbacks; +class JSLinearString; +class JS_PUBLIC_API JSString; + +namespace js { +namespace gc { +struct Cell; +} // namespace gc +} // namespace js + +namespace JS { + +namespace shadow { + +struct String { + static constexpr uint32_t ATOM_BIT = js::Bit(3); + static constexpr uint32_t LINEAR_BIT = js::Bit(4); + static constexpr uint32_t INLINE_CHARS_BIT = js::Bit(6); + static constexpr uint32_t LATIN1_CHARS_BIT = js::Bit(9); + static constexpr uint32_t EXTERNAL_FLAGS = LINEAR_BIT | js::Bit(8); + static constexpr uint32_t TYPE_FLAGS_MASK = js::BitMask(9) - js::BitMask(3); + static constexpr uint32_t PERMANENT_ATOM_MASK = ATOM_BIT | js::Bit(8); + + uintptr_t flags_; +#if JS_BITS_PER_WORD == 32 + uint32_t length_; +#endif + + union { + const JS::Latin1Char* nonInlineCharsLatin1; + const char16_t* nonInlineCharsTwoByte; + JS::Latin1Char inlineStorageLatin1[1]; + char16_t inlineStorageTwoByte[1]; + }; + const JSExternalStringCallbacks* externalCallbacks; + + uint32_t flags() const { return static_cast(flags_); } + uint32_t length() const { +#if JS_BITS_PER_WORD == 32 + return length_; +#else + return static_cast(flags_ >> 32); +#endif + } + + static bool isPermanentAtom(const js::gc::Cell* cell) { + uint32_t flags = reinterpret_cast(cell)->flags(); + return (flags & PERMANENT_ATOM_MASK) == PERMANENT_ATOM_MASK; + } + + bool isLinear() const { return flags() & LINEAR_BIT; } + bool hasLatin1Chars() const { return flags() & LATIN1_CHARS_BIT; } + + // For hot code, prefer other type queries. + bool isExternal() const { + return (flags() & TYPE_FLAGS_MASK) == EXTERNAL_FLAGS; + } + + const JS::Latin1Char* latin1LinearChars() const { + MOZ_ASSERT(isLinear()); + MOZ_ASSERT(hasLatin1Chars()); + return (flags() & String::INLINE_CHARS_BIT) ? inlineStorageLatin1 + : nonInlineCharsLatin1; + } + + const char16_t* twoByteLinearChars() const { + MOZ_ASSERT(isLinear()); + MOZ_ASSERT(!hasLatin1Chars()); + return (flags() & String::INLINE_CHARS_BIT) ? inlineStorageTwoByte + : nonInlineCharsTwoByte; + } +}; + +inline const String* AsShadowString(const JSString* str) { + return reinterpret_cast(str); +} + +inline String* AsShadowString(JSString* str) { + return reinterpret_cast(str); +} + +inline const String* AsShadowString(const JSLinearString* str) { + return reinterpret_cast(str); +} + +inline String* AsShadowString(JSLinearString* str) { + return reinterpret_cast(str); +} + +inline const String* AsShadowString(const JSAtom* str) { + return reinterpret_cast(str); +} + +inline String* AsShadowString(JSAtom* str) { + return reinterpret_cast(str); +} + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_String_h diff --git a/js/public/shadow/Symbol.h b/js/public/shadow/Symbol.h new file mode 100644 index 0000000000..5cef5a35c8 --- /dev/null +++ b/js/public/shadow/Symbol.h @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |JS::Symbol| innards. Do not use this directly! */ + +#ifndef js_shadow_Symbol_h +#define js_shadow_Symbol_h + +#include // uint32_t + +namespace js { +namespace gc { +struct Cell; +} // namespace gc +} // namespace js + +namespace JS { + +namespace shadow { + +struct Symbol { + void* _1; + uint32_t code_; + static constexpr uint32_t WellKnownAPILimit = 0x80000000; + + static bool isWellKnownSymbol(const js::gc::Cell* cell) { + return reinterpret_cast(cell)->code_ < WellKnownAPILimit; + } +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Symbol_h diff --git a/js/public/shadow/Zone.h b/js/public/shadow/Zone.h new file mode 100644 index 0000000000..2dd705ce2e --- /dev/null +++ b/js/public/shadow/Zone.h @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Shadow definition of |JS::Zone| innards. Do not use this directly! */ + +#ifndef js_shadow_Zone_h +#define js_shadow_Zone_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT + +#include // uint8_t, uint32_t + +#include "jspubtd.h" // js::CurrentThreadCanAccessRuntime + +struct JS_PUBLIC_API JSRuntime; +class JS_PUBLIC_API JSTracer; + +namespace JS { + +namespace shadow { + +struct Zone { + enum GCState : uint8_t { + NoGC, + MarkBlackOnly, + MarkBlackAndGray, + Sweep, + Finished, + Compact + }; + + protected: + JSRuntime* const runtime_; + JSTracer* const barrierTracer_; // A pointer to the JSRuntime's |gcMarker|. + uint32_t needsIncrementalBarrier_; + GCState gcState_; + + Zone(JSRuntime* runtime, JSTracer* barrierTracerArg) + : runtime_(runtime), + barrierTracer_(barrierTracerArg), + needsIncrementalBarrier_(0), + gcState_(NoGC) {} + + public: + bool needsIncrementalBarrier() const { return needsIncrementalBarrier_; } + + JSTracer* barrierTracer() { + MOZ_ASSERT(needsIncrementalBarrier_); + MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); + return barrierTracer_; + } + + JSRuntime* runtimeFromMainThread() const { + MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_)); + return runtime_; + } + + // Note: Unrestricted access to the zone's runtime from an arbitrary + // thread can easily lead to races. Use this method very carefully. + JSRuntime* runtimeFromAnyThread() const { return runtime_; } + + GCState gcState() const { return gcState_; } + bool wasGCStarted() const { return gcState_ != NoGC; } + bool isGCMarkingBlackOnly() const { return gcState_ == MarkBlackOnly; } + bool isGCMarkingBlackAndGray() const { return gcState_ == MarkBlackAndGray; } + bool isGCSweeping() const { return gcState_ == Sweep; } + bool isGCFinished() const { return gcState_ == Finished; } + bool isGCCompacting() const { return gcState_ == Compact; } + bool isGCMarking() const { + return isGCMarkingBlackOnly() || isGCMarkingBlackAndGray(); + } + bool isGCSweepingOrCompacting() const { + return gcState_ == Sweep || gcState_ == Compact; + } + + static shadow::Zone* from(JS::Zone* zone) { + return reinterpret_cast(zone); + } +}; + +} // namespace shadow + +} // namespace JS + +#endif // js_shadow_Zone_h diff --git a/js/rust/build.rs b/js/rust/build.rs index b185b1e65c..247a05abfa 100644 --- a/js/rust/build.rs +++ b/js/rust/build.rs @@ -163,7 +163,7 @@ const WHITELIST_TYPES: &'static [&'static str] = &[ "JS::RealmOptions", "JS::ContextOptions", "js::DOMCallbacks", - "js::DOMProxyShadowsResult", + "JS::DOMProxyShadowsResult", "js::ESClass", "JS::ForOfIterator", "JS::Handle", @@ -214,7 +214,7 @@ const WHITELIST_TYPES: &'static [&'static str] = &[ "jsid", "JS::Compartment", "JS::Latin1Char", - "JS::detail::MaybeWrapped", + "JS::detail::RootedPtr", "JS::MutableHandle", "JS::MutableHandleObject", "JS::MutableHandleValue", @@ -232,8 +232,8 @@ const WHITELIST_TYPES: &'static [&'static str] = &[ "JS::RootKind", "js::Scalar::Type", "JS::ServoSizes", - "js::shadow::Object", - "js::shadow::ObjectGroup", + "JS::shadow::Object", + "JS::shadow::ObjectGroup", "JS::SourceText", "js::StackFormat", "JSStructuredCloneCallbacks", @@ -282,7 +282,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ "JS::CompileFunctionUtf8", "JS::Construct", "JS::ContextOptionsRef", - "JS_CopyPropertiesFrom", + "JS_CopyOwnPropertiesAndPrivateFields", "JS::CurrentGlobalOrNull", "JS_DeletePropertyById", "js::detail::IsWindowSlow", @@ -324,6 +324,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ "JS_DefineProperty", "JS_DefinePropertyById", "JS_DefineUCProperty", + "JS_DeprecatedStringHasLatin1Chars", "JS::detail::InitWithFailureDiagnostic", "JS_DestroyContext", "JS::DisableIncrementalGC", @@ -350,7 +351,7 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ "JS_GetPropertyById", "js::GetPropertyKeys", "JS_GetPrototype", - "JS_GetReservedSlot", + "JS::GetReservedSlot", "JS::GetRealmErrorPrototype", "JS::GetRealmFunctionPrototype", "JS::GetRealmIteratorPrototype", @@ -395,7 +396,6 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ "JS_NewUint32Array", "JS_NewUint8Array", "JS_NewUint8ClampedArray", - "js::ObjectClassName", "JS::ObjectIsDate", "JS_ParseJSON", "JS_ReadBytes", @@ -437,7 +437,6 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ "js::StopDrainingJobQueue", "JS_StrictPropertyStub", "JS_StringEqualsAscii", - "JS_StringHasLatin1Chars", "JS_WrapObject", "JS_WrapValue", "JS_WriteBytes", diff --git a/js/rust/etc/wrapper.hpp b/js/rust/etc/wrapper.hpp index d08d9313d9..48dfd8b55c 100644 --- a/js/rust/etc/wrapper.hpp +++ b/js/rust/etc/wrapper.hpp @@ -13,25 +13,35 @@ typedef uint32_t HashNumber; #include "jsfriendapi.h" #include "js/Array.h" #include "js/ArrayBuffer.h" +#include "js/CallArgs.h" +#include "js/CallNonGenericMethod.h" #include "js/CompilationAndEvaluation.h" #include "js/CompileOptions.h" #include "js/ContextOptions.h" #include "js/Conversions.h" #include "js/Date.h" +#include "js/experimental/JitInfo.h" +#include "js/experimental/TypedData.h" #include "js/ForOfIterator.h" +#include "js/friend/WindowProxy.h" #include "js/Initialization.h" #include "js/MemoryMetrics.h" #include "js/PropertySpec.h" +#include "js/shadow/Object.h" +#include "js/shadow/ObjectGroup.h" +#include "js/shadow/Realm.h" +#include "js/shadow/Zone.h" #include "js/SourceText.h" +#include "js/String.h" #include "js/StructuredClone.h" #include "js/ValueArray.h" #include "js/Warnings.h" // Replacements for types that are too difficult for rust-bindgen. -///
+///
template -using replaces_MaybeWrapped = T; +using replaces_RootedPtr = T; ///
struct MutableHandleIdVector_Simple { diff --git a/js/rust/src/conversions.rs b/js/rust/src/conversions.rs index 00331f70e0..199ff376ab 100644 --- a/js/rust/src/conversions.rs +++ b/js/rust/src/conversions.rs @@ -561,7 +561,7 @@ impl FromJSValConvertible for f64 { /// Converts a `JSString`, encoded in "Latin1" (i.e. U+0000-U+00FF encoded as 0x00-0xFF) into a /// `String`. pub unsafe fn latin1_to_string(cx: *mut JSContext, s: *mut JSString) -> String { - assert!(JS_StringHasLatin1Chars(s)); + assert!(JS_DeprecatedStringHasLatin1Chars(s)); let mut length = 0; let chars = JS_GetLatin1StringCharsAndLength(cx, ptr::null(), s, &mut length); @@ -612,7 +612,7 @@ impl FromJSValConvertible for String { debug!("ToString failed"); return Err(()); } - if JS_StringHasLatin1Chars(jsstr) { + if JS_DeprecatedStringHasLatin1Chars(jsstr) { return Ok(latin1_to_string(cx, jsstr)).map(ConversionResult::Success); } diff --git a/js/rust/src/jsglue.cpp b/js/rust/src/jsglue.cpp index 7a9311d668..690ec71f95 100644 --- a/js/rust/src/jsglue.cpp +++ b/js/rust/src/jsglue.cpp @@ -17,6 +17,8 @@ #include "js/Proxy.h" #include "js/CharacterEncoding.h" #include "js/Class.h" +#include "js/experimental/JitInfo.h" +#include "js/experimental/TypedData.h" #include "js/MemoryMetrics.h" #include "js/Principals.h" #include "js/StructuredClone.h" diff --git a/js/rust/src/rust.rs b/js/rust/src/rust.rs index 8e70e82980..269c8c4517 100644 --- a/js/rust/src/rust.rs +++ b/js/rust/src/rust.rs @@ -1100,9 +1100,9 @@ pub static SIMPLE_GLOBAL_CLASS: JSClass = JSClass { }; #[inline] -unsafe fn get_object_group(obj: *mut JSObject) -> *mut js::shadow::ObjectGroup { +unsafe fn get_object_group(obj: *mut JSObject) -> *mut JS::shadow::ObjectGroup { assert!(!obj.is_null()); - let obj = obj as *mut js::shadow::Object; + let obj = obj as *mut JS::shadow::Object; (*obj).group } diff --git a/js/src/NamespaceImports.h b/js/src/NamespaceImports.h index e06d4ff755..c14c74e21c 100644 --- a/js/src/NamespaceImports.h +++ b/js/src/NamespaceImports.h @@ -72,6 +72,7 @@ using JS::Latin1CharsZ; using JS::TwoByteChars; using JS::TwoByteCharsZ; using JS::UniqueChars; +using JS::UniqueLatin1Chars; using JS::UniqueTwoByteChars; using JS::UTF8Chars; using JS::UTF8CharsZ; diff --git a/js/src/build.rs b/js/src/build.rs index cf37067144..9152f3f1a7 100644 --- a/js/src/build.rs +++ b/js/src/build.rs @@ -2,8 +2,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/. -extern crate num_cpus; extern crate glob; +extern crate num_cpus; use std::env; use std::path; @@ -34,28 +34,29 @@ fn main() { let python = env::var("PYTHON3").unwrap_or("python3".into()); let mut cmd = Command::new(&python); - cmd.args(&["./devtools/automation/autospider.py", - // Only build SpiderMonkey, don't run all the tests. - "--build-only", - // Disable Mozilla's jemalloc; Rust has its own jemalloc that we - // can swap in instead and everything using a single malloc is - // good. - "--no-jemalloc", - // Don't try to clobber the output directory. Without - // this option, the build will fail because the directory - // already exists but wasn't created by autospider. - "--dep", - "--objdir", &out_dir, - &variant]) - .env("NO_RUST_PANIC_HOOK", "1") - .env("SOURCE", &js_src) - .env("PWD", &js_src) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()); + cmd.args(&[ + "./devtools/automation/autospider.py", + // Only build SpiderMonkey, don't run all the tests. + "--build-only", + // Disable Mozilla's jemalloc; Rust has its own jemalloc that we + // can swap in instead and everything using a single malloc is + // good. + "--no-jemalloc", + // Don't try to clobber the output directory. Without + // this option, the build will fail because the directory + // already exists but wasn't created by autospider. + "--dep", + "--objdir", + &out_dir, + &variant, + ]) + .env("NO_RUST_PANIC_HOOK", "1") + .env("SOURCE", &js_src) + .env("PWD", &js_src) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()); println!("Running command: {:?}", cmd); - let result = cmd - .status() - .expect("Should spawn autospider OK"); + let result = cmd.status().expect("Should spawn autospider OK"); assert!(result.success(), "autospider should exit OK"); println!("cargo:rustc-link-search=native={}/js/src/build", out_dir); @@ -82,8 +83,7 @@ fn main() { /// Find if Spidermonkey built the Spidermonkey Rust library, and add it to the /// link if it was the case. fn maybe_add_spidermonkey_rust_lib() { - let out_dir = env::var("OUT_DIR") - .expect("cargo should invoke us with the OUT_DIR env var set"); + let out_dir = env::var("OUT_DIR").expect("cargo should invoke us with the OUT_DIR env var set"); let mut target_build_dir = path::PathBuf::from(out_dir); target_build_dir.push("../../"); @@ -91,17 +91,19 @@ fn maybe_add_spidermonkey_rust_lib() { let mut build_dir = target_build_dir.display().to_string(); build_dir.push_str("mozjs_sys-*/out/*/debug"); - let entries = match glob::glob(&build_dir){ - Err(_) => { return; } - Ok(entries) => entries + let entries = match glob::glob(&build_dir) { + Err(_) => { + return; + } + Ok(entries) => entries, }; for entry in entries { if let Ok(path) = entry { - let path = path.canonicalize() + let path = path + .canonicalize() .expect("Should canonicalize debug build path"); - let path = path.to_str() - .expect("Should be utf8"); + let path = path.to_str().expect("Should be utf8"); println!("cargo:rustc-link-search=native={}", path); println!("cargo:rustc-link-lib=static=jsrust"); return; diff --git a/js/src/builtin/.eslintrc.js b/js/src/builtin/.eslintrc.js index 9071d0c5d5..29a2d3b83f 100644 --- a/js/src/builtin/.eslintrc.js +++ b/js/src/builtin/.eslintrc.js @@ -5,6 +5,11 @@ module.exports = { "spidermonkey-js" ], + "overrides": [{ + "files": ["*.js"], + "processor": "spidermonkey-js/processor", + }], + "rules": { // We should fix those at some point, but we use this to detect NaNs. "no-self-compare": "off", diff --git a/js/src/builtin/Array.cpp b/js/src/builtin/Array.cpp index ed66a74bb9..20b41424c7 100644 --- a/js/src/builtin/Array.cpp +++ b/js/src/builtin/Array.cpp @@ -23,6 +23,8 @@ #include "jit/InlinableNatives.h" #include "js/Class.h" #include "js/Conversions.h" +#include "js/experimental/JitInfo.h" // JSJitGetterOp, JSJitInfo +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit #include "js/PropertySpec.h" #include "util/Poison.h" #include "util/StringBuffer.h" @@ -294,7 +296,8 @@ bool ToId(JSContext* cx, uint64_t index, MutableHandleId id) { } Value tmp = DoubleValue(index); - return ValueToId(cx, HandleValue::fromMarkedLocation(&tmp), id); + return PrimitiveValueToId(cx, HandleValue::fromMarkedLocation(&tmp), + id); } /* @@ -544,8 +547,7 @@ static bool DeleteArrayElement(JSContext* cx, HandleObject obj, uint64_t index, if (idx + 1 == aobj->getDenseInitializedLength()) { aobj->setDenseInitializedLengthMaybeNonExtensible(cx, idx); } else { - aobj->markDenseElementsNotPacked(cx); - aobj->setDenseElement(idx, MagicValue(JS_ELEMENTS_HOLE)); + aobj->setDenseElementHole(cx, idx); } if (!SuppressDeletedElement(cx, obj, idx)) { return false; @@ -668,38 +670,6 @@ struct ReverseIndexComparator { } }; -static bool MaybeInIteration(HandleObject obj, JSContext* cx) { - /* - * Don't optimize if the array might be in the midst of iteration. We - * rely on this to be able to safely move dense array elements around with - * just a memmove (see NativeObject::moveDenseArrayElements), without worrying - * about updating any in-progress enumerators for properties implicitly - * deleted if a hole is moved from one location to another location not yet - * visited. See bug 690622. - * - * Note that it's fine to optimize if |obj| is on the prototype of another - * object: SuppressDeletedProperty only suppresses properties deleted from - * the iterated object itself. - */ - - if (MOZ_LIKELY(!ObjectRealm::get(obj).objectMaybeInIteration(obj))) { - return false; - } - - ObjectGroup* group = JSObject::getGroup(cx, obj); - if (MOZ_UNLIKELY(!group)) { - cx->recoverFromOutOfMemory(); - return true; - } - - AutoSweepObjectGroup sweep(group); - if (MOZ_UNLIKELY(group->hasAllFlags(sweep, OBJECT_FLAG_ITERATED))) { - return true; - } - - return false; -} - /* ES6 draft rev 34 (2015 Feb 20) 9.4.2.4 ArraySetLength */ bool js::ArraySetLength(JSContext* cx, Handle arr, HandleId id, unsigned attrs, HandleValue value, @@ -802,7 +772,7 @@ bool js::ArraySetLength(JSContext* cx, Handle arr, HandleId id, // would be too costly. // This optimization is also invalid when there are sealed // (non-configurable) elements. - if (!arr->isIndexed() && !MaybeInIteration(arr, cx) && + if (!arr->isIndexed() && !arr->denseElementsMaybeInIteration() && !arr->denseElementsAreSealed()) { if (!arr->maybeCopyElementsForWrite(cx)) { return false; @@ -1075,14 +1045,8 @@ static bool IsArrayConstructor(const Value& v) { return v.isObject() && IsArrayConstructor(&v.toObject()); } -bool js::IsCrossRealmArrayConstructor(JSContext* cx, const Value& v, +bool js::IsCrossRealmArrayConstructor(JSContext* cx, JSObject* obj, bool* result) { - if (!v.isObject()) { - *result = false; - return true; - } - - JSObject* obj = &v.toObject(); if (obj->is()) { obj = CheckedUnwrapDynamic(obj, cx); if (!obj) { @@ -1637,25 +1601,33 @@ static DenseElementResult ArrayReverseDenseKernel(JSContext* cx, } } - if (!MaybeInIteration(obj, cx) && !cx->zone()->needsIncrementalBarrier()) { + if (!obj->denseElementsMaybeInIteration() && + !cx->zone()->needsIncrementalBarrier()) { obj->reverseDenseElementsNoPreBarrier(length); return DenseElementResult::Success; } + auto setElementMaybeHole = [](JSContext* cx, HandleNativeObject obj, + uint32_t index, const Value& val) { + if (MOZ_LIKELY(!val.isMagic(JS_ELEMENTS_HOLE))) { + obj->setDenseElement(index, val); + return true; + } + + obj->setDenseElementHole(cx, index); + return SuppressDeletedProperty(cx, obj, INT_TO_JSID(index)); + }; + RootedValue origlo(cx), orighi(cx); uint32_t lo = 0, hi = length - 1; for (; lo < hi; lo++, hi--) { origlo = obj->getDenseElement(lo); orighi = obj->getDenseElement(hi); - obj->setDenseElement(lo, orighi); - if (orighi.isMagic(JS_ELEMENTS_HOLE) && - !SuppressDeletedProperty(cx, obj, INT_TO_JSID(lo))) { + if (!setElementMaybeHole(cx, obj, lo, orighi)) { return DenseElementResult::Failure; } - obj->setDenseElement(hi, origlo); - if (origlo.isMagic(JS_ELEMENTS_HOLE) && - !SuppressDeletedProperty(cx, obj, INT_TO_JSID(hi))) { + if (!setElementMaybeHole(cx, obj, hi, origlo)) { return DenseElementResult::Failure; } } @@ -2490,17 +2462,19 @@ bool js::array_pop(JSContext* cx, unsigned argc, Value* vp) { return SetLengthProperty(cx, obj, index); } -void js::ArrayShiftMoveElements(NativeObject* obj) { +void js::ArrayShiftMoveElements(ArrayObject* arr) { AutoUnsafeCallWithABI unsafe; - MOZ_ASSERT(obj->isExtensible()); - MOZ_ASSERT_IF(obj->is(), - obj->as().lengthIsWritable()); + MOZ_ASSERT(arr->isExtensible()); + MOZ_ASSERT(arr->lengthIsWritable()); + MOZ_ASSERT_IF(jit::JitOptions.warpBuilder, IsPackedArray(arr)); + MOZ_ASSERT(!arr->denseElementsAreCopyOnWrite()); + MOZ_ASSERT(!arr->denseElementsHaveMaybeInIterationFlag()); - size_t initlen = obj->getDenseInitializedLength(); + size_t initlen = arr->getDenseInitializedLength(); MOZ_ASSERT(initlen > 0); - if (!obj->tryShiftDenseElements(1)) { - obj->moveDenseElementsNoPreBarrier(0, 1, initlen - 1); + if (!arr->tryShiftDenseElements(1)) { + arr->moveDenseElements(0, 1, initlen - 1); } } @@ -2535,35 +2509,35 @@ static DenseElementResult ArrayShiftDenseKernel(JSContext* cx, HandleObject obj, return DenseElementResult::Incomplete; } - if (MaybeInIteration(obj, cx)) { + HandleNativeObject nobj = obj.as(); + if (nobj->denseElementsMaybeInIteration()) { return DenseElementResult::Incomplete; } - if (!obj->as().isExtensible()) { + if (!nobj->isExtensible()) { return DenseElementResult::Incomplete; } - size_t initlen = obj->as().getDenseInitializedLength(); + size_t initlen = nobj->getDenseInitializedLength(); if (initlen == 0) { return DenseElementResult::Incomplete; } - rval.set(obj->as().getDenseElement(0)); + rval.set(nobj->getDenseElement(0)); if (rval.isMagic(JS_ELEMENTS_HOLE)) { rval.setUndefined(); } - if (obj->as().tryShiftDenseElements(1)) { + if (nobj->tryShiftDenseElements(1)) { return DenseElementResult::Success; } - DenseElementResult result = - MoveDenseElements(cx, &obj->as(), 0, 1, initlen - 1); + DenseElementResult result = MoveDenseElements(cx, nobj, 0, 1, initlen - 1); if (result != DenseElementResult::Success) { return result; } - SetInitializedLength(cx, obj.as(), initlen - 1); + SetInitializedLength(cx, nobj, initlen - 1); return DenseElementResult::Success; } @@ -2683,10 +2657,10 @@ static bool array_unshift(JSContext* cx, unsigned argc, Value* vp) { if (ObjectMayHaveExtraIndexedProperties(obj)) { break; } - if (MaybeInIteration(obj, cx)) { + NativeObject* nobj = &obj->as(); + if (nobj->denseElementsMaybeInIteration()) { break; } - NativeObject* nobj = &obj->as(); if (!nobj->isExtensible()) { break; } @@ -2818,7 +2792,7 @@ static bool CanOptimizeForDenseStorage(HandleObject arr, uint64_t endIndex, } /* Also pick the slow path if the object is being iterated over. */ - if (MaybeInIteration(arr, cx)) { + if (arr->as().denseElementsMaybeInIteration()) { return false; } @@ -2855,7 +2829,7 @@ static ArrayObject* CopyDenseArrayElements(JSContext* cx, narr->setLength(cx, count); if (newlength > 0) { - narr->initDenseElements(obj, begin, newlength); + narr->initDenseElements(cx, obj, begin, newlength); } return narr; @@ -3129,43 +3103,47 @@ static bool array_splice_impl(JSContext* cx, unsigned argc, Value* vp, /* Step 16. */ - /* - * Optimize only if the array is already dense and we can extend it to - * its new length. It would be wrong to extend the elements here for a - * number of reasons. - * - * First, this could cause us to fall into the fast-path below. This - * would cause elements to be moved into places past the non-writable - * length. And when the dense initialized length is updated, that'll - * cause the |in| operator to think that those elements actually exist, - * even though, properly, setting them must fail. - * - * Second, extending the elements here will trigger assertions inside - * ensureDenseElements that the elements aren't being extended past the - * length of a non-writable array. This is because extending elements - * will extend capacity -- which might extend them past a non-writable - * length, violating the |capacity <= length| invariant for such - * arrays. And that would make the various JITted fast-path method - * implementations of [].push, [].unshift, and so on wrong. - * - * If the array length is non-writable, this method *will* throw. For - * simplicity, have the slow-path code do it. (Also note that the slow - * path may validly *not* throw -- if all the elements being moved are - * holes.) - */ - if (obj->is() && !ObjectMayHaveExtraIndexedProperties(obj) && - len <= UINT32_MAX) { + // Fast path for when we can simply extend and move the dense elements. + auto extendElements = [len, itemCount, deleteCount](JSContext* cx, + HandleObject obj) { + if (!obj->is()) { + return DenseElementResult::Incomplete; + } + if (len > UINT32_MAX) { + return DenseElementResult::Incomplete; + } + + // Ensure there are no getters/setters or other extra indexed properties. + if (ObjectMayHaveExtraIndexedProperties(obj)) { + return DenseElementResult::Incomplete; + } + + // Watch out for arrays with non-writable length or non-extensible arrays. + // In these cases `splice` may have to throw an exception so we let the + // slow path handle it. We also have to ensure we maintain the + // |capacity <= initializedLength| invariant for such objects. See + // NativeObject::shrinkCapacityToInitializedLength. HandleArrayObject arr = obj.as(); - if (arr->lengthIsWritable() && arr->isExtensible()) { - DenseElementResult result = arr->ensureDenseElements( - cx, uint32_t(len), itemCount - deleteCount); - if (result == DenseElementResult::Failure) { - return false; - } + if (!arr->lengthIsWritable() || !arr->isExtensible()) { + return DenseElementResult::Incomplete; } - } - if (CanOptimizeForDenseStorage(obj, finalLength, cx)) { + // Also use the slow path if there might be an active for-in iterator so + // that we don't have to worry about suppressing deleted properties. + if (arr->denseElementsMaybeInIteration()) { + return DenseElementResult::Incomplete; + } + + return arr->ensureDenseElements(cx, uint32_t(len), + itemCount - deleteCount); + }; + + DenseElementResult res = extendElements(cx, obj); + if (res == DenseElementResult::Failure) { + return false; + } + if (res == DenseElementResult::Success) { + MOZ_ASSERT(finalLength <= UINT32_MAX); MOZ_ASSERT((actualStart + actualDeleteCount) <= len && len <= UINT32_MAX, "start and deleteCount are uint32 array indices"); MOZ_ASSERT(actualStart + itemCount <= UINT32_MAX, @@ -3186,6 +3164,8 @@ static bool array_splice_impl(JSContext* cx, unsigned argc, Value* vp, /* Steps 16.a-b. */ SetInitializedLength(cx, obj.as(), finalLength); } else { + MOZ_ASSERT(res == DenseElementResult::Incomplete); + RootedValue fromValue(cx); for (uint64_t k = len - actualDeleteCount; k > actualStart; k--) { if (!CheckForInterrupt(cx)) { @@ -3626,7 +3606,7 @@ static bool ArraySliceDenseKernel(JSContext* cx, ArrayObject* arr, if (!result->ensureElements(cx, newlength)) { return false; } - result->initDenseElements(arr, begin, newlength); + result->initDenseElements(cx, arr, begin, newlength); } } @@ -3638,6 +3618,8 @@ static bool ArraySliceDenseKernel(JSContext* cx, ArrayObject* arr, JSObject* js::ArraySliceDense(JSContext* cx, HandleObject obj, int32_t begin, int32_t end, HandleObject result) { + MOZ_ASSERT_IF(jit::JitOptions.warpBuilder, IsPackedArray(obj)); + if (result && IsArraySpecies(cx, obj)) { if (!ArraySliceDenseKernel(cx, &obj->as(), begin, end, &result->as())) { @@ -3859,14 +3841,15 @@ bool js::array_construct(JSContext* cx, unsigned argc, Value* vp) { return ArrayConstructorImpl(cx, args, /* isConstructor = */ false); } -ArrayObject* js::ArrayConstructorOneArg(JSContext* cx, HandleObjectGroup group, +ArrayObject* js::ArrayConstructorOneArg(JSContext* cx, + HandleArrayObject templateObject, int32_t lengthInt) { - // Ion can call this with a group from a different realm when calling - // another realm's Array constructor. + // JIT code can call this with a template object from a different realm when + // calling another realm's Array constructor. Maybe ar; - if (cx->realm() != group->realm()) { - MOZ_ASSERT(cx->compartment() == group->compartment()); - ar.emplace(cx, group); + if (cx->realm() != templateObject->realm()) { + MOZ_ASSERT(cx->compartment() == templateObject->compartment()); + ar.emplace(cx, templateObject); } if (lengthInt < 0) { @@ -3876,6 +3859,7 @@ ArrayObject* js::ArrayConstructorOneArg(JSContext* cx, HandleObjectGroup group, } uint32_t length = uint32_t(lengthInt); + RootedObjectGroup group(cx, templateObject->group()); ArrayObject* res = NewPartlyAllocatedArrayTryUseGroup(cx, group, length); MOZ_ASSERT_IF(res, res->realm() == group->realm()); return res; diff --git a/js/src/builtin/Array.h b/js/src/builtin/Array.h index 26947fcfed..01a0c6eb4c 100644 --- a/js/src/builtin/Array.h +++ b/js/src/builtin/Array.h @@ -143,7 +143,7 @@ extern bool array_pop(JSContext* cx, unsigned argc, js::Value* vp); extern bool array_join(JSContext* cx, unsigned argc, js::Value* vp); -extern void ArrayShiftMoveElements(NativeObject* obj); +extern void ArrayShiftMoveElements(ArrayObject* arr); extern bool array_shift(JSContext* cx, unsigned argc, js::Value* vp); @@ -162,7 +162,7 @@ extern JSObject* ArraySliceDense(JSContext* cx, HandleObject obj, int32_t begin, extern bool NewbornArrayPush(JSContext* cx, HandleObject obj, const Value& v); extern ArrayObject* ArrayConstructorOneArg(JSContext* cx, - HandleObjectGroup group, + HandleArrayObject templateObject, int32_t lengthInt); #ifdef DEBUG @@ -177,7 +177,7 @@ extern bool array_construct(JSContext* cx, unsigned argc, Value* vp); extern JSString* ArrayToSource(JSContext* cx, HandleObject obj); -extern bool IsCrossRealmArrayConstructor(JSContext* cx, const Value& v, +extern bool IsCrossRealmArrayConstructor(JSContext* cx, JSObject* obj, bool* result); extern bool ObjectMayHaveExtraIndexedProperties(JSObject* obj); diff --git a/js/src/builtin/AsyncIteration.js b/js/src/builtin/AsyncIteration.js index df0b911701..041a0ba867 100644 --- a/js/src/builtin/AsyncIteration.js +++ b/js/src/builtin/AsyncIteration.js @@ -23,3 +23,506 @@ function AsyncGeneratorReturn(val) { "ThisArgument must be a generator object for async generators"); return resumeGenerator(this, val, "return"); } + +/* ECMA262 7.4.7 AsyncIteratorClose */ +async function AsyncIteratorClose(iteratorRecord, value) { + // Step 3. + const iterator = iteratorRecord.iterator; + // Step 4. + const returnMethod = iterator.return; + // Step 5. + if (returnMethod !== undefined && returnMethod !== null) { + const result = await callContentFunction(returnMethod, iterator); + // Step 8. + if (!IsObject(result)) { + ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, result)); + } + } + // Step 5b & 9. + return value; +} + +/* Iterator Helpers proposal 1.1.1 */ +function GetAsyncIteratorDirectWrapper(obj) { + // Step 1. + if (!IsObject(obj)) { + ThrowTypeError(JSMSG_OBJECT_REQUIRED, obj); + } + + // Step 2. + const nextMethod = obj.next; + // Step 3. + if (!IsCallable(nextMethod)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, nextMethod); + } + + // Steps 4-5. + return { + // Use a named function expression instead of a method definition, so + // we don't create an inferred name for this function at runtime. + [std_asyncIterator]: function AsyncIteratorMethod() { + return this; + }, + next(value) { + return callContentFunction(nextMethod, obj, value); + }, + async return(value) { + const returnMethod = obj.return; + if (returnMethod !== undefined && returnMethod !== null) { + return callContentFunction(returnMethod, obj, value); + } + return {done: true, value}; + }, + }; +} + +/* AsyncIteratorHelper object prototype methods. */ +function AsyncIteratorHelperNext(value) { + let O; + if (!IsObject(this) || (O = GuardToAsyncIteratorHelper(this)) === null) { + return callFunction(CallAsyncIteratorHelperMethodIfWrapped, this, + value, "AsyncIteratorHelperNext"); + } + const generator = UnsafeGetReservedSlot(O, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT); + return callFunction(IntrinsicAsyncGeneratorNext, generator, value); +} + +function AsyncIteratorHelperReturn(value) { + let O; + if (!IsObject(this) || (O = GuardToAsyncIteratorHelper(this)) === null) { + return callFunction(CallAsyncIteratorHelperMethodIfWrapped, this, + value, "AsyncIteratorHelperReturn"); + } + const generator = UnsafeGetReservedSlot(O, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT); + return callFunction(IntrinsicAsyncGeneratorReturn, generator, value); +} + +function AsyncIteratorHelperThrow(value) { + let O; + if (!IsObject(this) || (O = GuardToAsyncIteratorHelper(this)) === null) { + return callFunction(CallAsyncIteratorHelperMethodIfWrapped, this, + value, "AsyncIteratorHelperThrow"); + } + const generator = UnsafeGetReservedSlot(O, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT); + return callFunction(IntrinsicAsyncGeneratorThrow, generator, value); +} + +// AsyncIterator lazy Iterator Helper methods +// Iterator Helpers proposal 2.1.6.2-2.1.6.7 +// +// The AsyncIterator lazy methods are structured closely to how the Iterator +// lazy methods are. See builtin/Iterator.js for the reasoning. + +/* Iterator Helpers proposal 2.1.6.2 Prelude */ +function AsyncIteratorMap(mapper) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(mapper)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper)); + } + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorMapGenerator(iterated, mapper); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.2 Body */ +async function* AsyncIteratorMapGenerator(iterated, mapper) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = await IteratorNext(iterated, lastValue); + !next.done; + next = await IteratorNext(iterated, lastValue)) { + // Step c. + const value = next.value; + + // Steps d-i. + needClose = true; + lastValue = yield callContentFunction(mapper, undefined, value); + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.6.3 Prelude */ +function AsyncIteratorFilter(filterer) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(filterer)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, filterer)); + } + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorFilterGenerator(iterated, filterer); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.3 Body */ +async function* AsyncIteratorFilterGenerator(iterated, filterer) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = await IteratorNext(iterated, lastValue); + !next.done; + next = await IteratorNext(iterated, lastValue)) { + // Step c. + const value = next.value; + + // Steps d-h. + needClose = true; + if (await callContentFunction(filterer, undefined, value)) { + lastValue = yield value; + } + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.6.4 Prelude */ +function AsyncIteratorTake(limit) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + const remaining = ToInteger(limit); + // Step 3. + if (remaining < 0) { + ThrowRangeError(JSMSG_NEGATIVE_LIMIT); + } + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorTakeGenerator(iterated, remaining); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.4 Body */ +async function* AsyncIteratorTakeGenerator(iterated, remaining) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (; remaining > 0; remaining--) { + const next = await IteratorNext(iterated, lastValue); + if (next.done) { + return undefined; + } + + const value = next.value; + + needClose = true; + lastValue = yield value; + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated, undefined); + } + } + + return AsyncIteratorClose(iterated, undefined); +} + +/* Iterator Helpers proposal 2.1.6.5 Prelude */ +function AsyncIteratorDrop(limit) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + const remaining = ToInteger(limit); + // Step 3. + if (remaining < 0) { + ThrowRangeError(JSMSG_NEGATIVE_LIMIT); + } + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorDropGenerator(iterated, remaining); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.5 Body */ +async function* AsyncIteratorDropGenerator(iterated, remaining) { + let needClose = true; + try { + yield; + needClose = false; + + // Step 1. + for (; remaining > 0; remaining--) { + const next = await IteratorNext(iterated); + if (next.done) { + return; + } + } + + // Step 2. + let lastValue; + // Step 3. + for (let next = await IteratorNext(iterated, lastValue); + !next.done; + next = await IteratorNext(iterated, lastValue)) { + // Steps c-d. + const value = next.value; + + needClose = true; + lastValue = yield value; + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.6.6 Prelude */ +function AsyncIteratorAsIndexedPairs() { + // Step 1. + const iterated = GetIteratorDirect(this); + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorAsIndexedPairsGenerator(iterated); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.6 Body */ +async function* AsyncIteratorAsIndexedPairsGenerator(iterated) { + let needClose = true; + try { + yield; + needClose = false; + + // Step 2. + let lastValue; + // Step 3. + for (let next = await IteratorNext(iterated, lastValue), index = 0; + !next.done; + next = await IteratorNext(iterated, lastValue), index++) { + // Steps c-g. + const value = next.value; + + needClose = true; + lastValue = yield [index, value]; + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.6.7 Prelude */ +function AsyncIteratorFlatMap(mapper) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(mapper)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper)); + } + + const iteratorHelper = NewAsyncIteratorHelper(); + const generator = AsyncIteratorFlatMapGenerator(iterated, mapper); + callFunction(IntrinsicAsyncGeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ASYNC_ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.6.7 Body */ +async function* AsyncIteratorFlatMapGenerator(iterated, mapper) { + let needClose = true; + try { + yield; + needClose = false; + + // Step 1. + for (let next = await IteratorNext(iterated); + !next.done; + next = await IteratorNext(iterated)) { + // Step c. + const value = next.value; + + needClose = true; + // Step d. + const mapped = await callContentFunction(mapper, undefined, value); + // Steps f-k. + for await (const innerValue of allowContentIter(mapped)) { + yield innerValue; + } + needClose = false; + } + } finally { + if (needClose) { + AsyncIteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.6.8 */ +async function AsyncIteratorReduce(reducer/*, initialValue*/) { + // Step 1. + const iterated = GetAsyncIteratorDirectWrapper(this); + + // Step 2. + if (!IsCallable(reducer)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, reducer)); + } + + // Step 3. + let accumulator; + if (arguments.length === 1) { + // Step a. + const next = await callContentFunction(iterated.next, iterated); + if (!IsObject(next)) { + ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, next)); + } + // Step b. + if (next.done) { + ThrowTypeError(JSMSG_EMPTY_ITERATOR_REDUCE); + } + // Step c. + accumulator = next.value; + } else { + // Step 4. + accumulator = arguments[1]; + } + + // Step 5. + for await (const value of allowContentIter(iterated)) { + // Steps d-h. + accumulator = await callContentFunction(reducer, undefined, accumulator, value); + } + // Step 5b. + return accumulator; +} + +/* Iterator Helpers proposal 2.1.6.9 */ +async function AsyncIteratorToArray() { + // Step 1. + const iterated = {[std_asyncIterator]: () => this}; + // Step 2. + const items = []; + let index = 0; + // Step 3. + for await (const value of allowContentIter(iterated)) { + // Step d. + _DefineDataProperty(items, index++, value); + } + // Step 3b. + return items; +} + +/* Iterator Helpers proposal 2.1.6.10 */ +async function AsyncIteratorForEach(fn) { + // Step 1. + const iterated = GetAsyncIteratorDirectWrapper(this); + + // Step 2. + if (!IsCallable(fn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, fn)); + } + + // Step 3. + for await (const value of allowContentIter(iterated)) { + // Steps d-g. + await callContentFunction(fn, undefined, value); + } +} + +/* Iterator Helpers proposal 2.1.6.11 */ +async function AsyncIteratorSome(fn) { + // Step 1. + const iterated = GetAsyncIteratorDirectWrapper(this); + + // Step 2. + if (!IsCallable(fn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, fn)); + } + + // Step 3. + for await (const value of allowContentIter(iterated)) { + // Steps d-h. + if (await callContentFunction(fn, undefined, value)) { + return true; + } + } + // Step 3b. + return false; +} + +/* Iterator Helpers proposal 2.1.6.12 */ +async function AsyncIteratorEvery(fn) { + // Step 1. + const iterated = GetAsyncIteratorDirectWrapper(this); + + // Step 2. + if (!IsCallable(fn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, fn)); + } + + // Step 3. + for await (const value of allowContentIter(iterated)) { + // Steps d-h. + if (!await callContentFunction(fn, undefined, value)) { + return false; + } + } + // Step 3b. + return true; +} + +/* Iterator Helpers proposal 2.1.6.13 */ +async function AsyncIteratorFind(fn) { + // Step 1. + const iterated = GetAsyncIteratorDirectWrapper(this); + + // Step 2. + if (!IsCallable(fn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, fn)); + } + + // Step 3. + for await (const value of allowContentIter(iterated)) { + // Steps d-h. + if (await callContentFunction(fn, undefined, value)) { + return value; + } + } +} diff --git a/js/src/builtin/AtomicsObject.cpp b/js/src/builtin/AtomicsObject.cpp index b610ad6637..4f2eb294f7 100644 --- a/js/src/builtin/AtomicsObject.cpp +++ b/js/src/builtin/AtomicsObject.cpp @@ -163,7 +163,8 @@ struct ArrayOps { template <> JS::Result<> ArrayOps::storeResult(JSContext* cx, uint32_t v, MutableHandleValue result) { - result.setNumber(v); + // Always double typed so that the JITs can assume the types are stable. + result.setDouble(v); return Ok(); } diff --git a/js/src/builtin/BigInt.cpp b/js/src/builtin/BigInt.cpp index 7b0f5aca5e..4e3f22fc9d 100644 --- a/js/src/builtin/BigInt.cpp +++ b/js/src/builtin/BigInt.cpp @@ -205,16 +205,15 @@ const ClassSpec BigIntObject::classSpec_ = { BigIntObject::methods, BigIntObject::properties}; -// The class is named "Object" as a workaround for bug 1277801. const JSClass BigIntObject::class_ = { - "Object", + "BigInt", JSCLASS_HAS_CACHED_PROTO(JSProto_BigInt) | JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS), JS_NULL_CLASS_OPS, &BigIntObject::classSpec_}; const JSClass BigIntObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_BigInt), JS_NULL_CLASS_OPS, - &BigIntObject::classSpec_}; + "BigInt.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_BigInt), + JS_NULL_CLASS_OPS, &BigIntObject::classSpec_}; const JSPropertySpec BigIntObject::properties[] = { // BigInt proposal section 5.3.5 diff --git a/js/src/builtin/DataViewObject.cpp b/js/src/builtin/DataViewObject.cpp index 6133cfc067..305b7a2ffd 100644 --- a/js/src/builtin/DataViewObject.cpp +++ b/js/src/builtin/DataViewObject.cpp @@ -20,6 +20,7 @@ #include "jit/AtomicOperations.h" #include "jit/InlinableNatives.h" #include "js/Conversions.h" +#include "js/experimental/TypedData.h" // JS_NewDataView #include "js/PropertySpec.h" #include "js/Wrapper.h" #include "util/Windows.h" @@ -247,21 +248,13 @@ bool DataViewObject::construct(JSContext* cx, unsigned argc, Value* vp) { } template -/* static */ -SharedMem DataViewObject::getDataPointer(JSContext* cx, - Handle obj, - uint64_t offset, +SharedMem DataViewObject::getDataPointer(uint64_t offset, bool* isSharedMemory) { - const size_t TypeSize = sizeof(NativeType); - if (offset > UINT32_MAX - TypeSize || offset + TypeSize > obj->byteLength()) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, - JSMSG_OFFSET_OUT_OF_DATAVIEW); - return SharedMem::unshared(nullptr); - } + MOZ_ASSERT(offsetIsInBounds(offset)); MOZ_ASSERT(offset < UINT32_MAX); - *isSharedMemory = obj->isSharedMemory(); - return obj->dataPointerEither().cast() + uint32_t(offset); + *isSharedMemory = this->isSharedMemory(); + return dataPointerEither().cast() + uint32_t(offset); } template @@ -319,45 +312,61 @@ struct DataViewIO { } }; +template +NativeType DataViewObject::read(uint64_t offset, bool isLittleEndian) { + bool isSharedMemory; + SharedMem data = + getDataPointer(offset, &isSharedMemory); + MOZ_ASSERT(data); + + NativeType val = 0; + if (isSharedMemory) { + DataViewIO>::fromBuffer(&val, data, + isLittleEndian); + } else { + DataViewIO::fromBuffer(&val, data.unwrapUnshared(), + isLittleEndian); + } + + return val; +} + +template uint32_t DataViewObject::read(uint64_t offset, bool isLittleEndian); + +// https://tc39.github.io/ecma262/#sec-getviewvalue +// GetViewValue ( view, requestIndex, isLittleEndian, type ) template /* static */ bool DataViewObject::read(JSContext* cx, Handle obj, const CallArgs& args, NativeType* val) { - // Steps 1-2. done by the caller - // Step 3. unnecessary assert + // Step 1. done by the caller + // Step 2. unnecessary assert - // Step 4. + // Step 3. uint64_t getIndex; if (!ToIndex(cx, args.get(0), &getIndex)) { return false; } - // Step 5. + // Step 4. bool isLittleEndian = args.length() >= 2 && ToBoolean(args[1]); - // Steps 6-7. + // Steps 5-6. if (obj->hasDetachedBuffer()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED); return false; } - // Steps 8-12. - bool isSharedMemory; - SharedMem data = DataViewObject::getDataPointer( - cx, obj, getIndex, &isSharedMemory); - if (!data) { + // Steps 7-10. + if (!obj->offsetIsInBounds(getIndex)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_OFFSET_OUT_OF_DATAVIEW); return false; } - // Step 13. - if (isSharedMemory) { - DataViewIO>::fromBuffer(val, data, - isLittleEndian); - } else { - DataViewIO::fromBuffer(val, data.unwrapUnshared(), - isLittleEndian); - } + // Steps 11-12. + *val = obj->read(getIndex, isLittleEndian); return true; } @@ -425,16 +434,16 @@ template /* static */ bool DataViewObject::write(JSContext* cx, Handle obj, const CallArgs& args) { - // Steps 1-2. done by the caller - // Step 3. unnecessary assert + // Step 1. done by the caller + // Step 2. unnecessary assert - // Step 4. + // Step 3. uint64_t getIndex; if (!ToIndex(cx, args.get(0), &getIndex)) { return false; } - // Step 5. Extended by the BigInt proposal to call either ToBigInt or ToNumber + // Steps 4-5. Call ToBigInt(value) or ToNumber(value) depending on the type. NativeType value; if (!WebIDLCast(cx, args.get(1), &value)) { return false; @@ -457,15 +466,19 @@ bool DataViewObject::write(JSContext* cx, Handle obj, return false; } - // Steps 9-13. - bool isSharedMemory; - SharedMem data = DataViewObject::getDataPointer( - cx, obj, getIndex, &isSharedMemory); - if (!data) { + // Steps 9-12. + if (!obj->offsetIsInBounds(getIndex)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_OFFSET_OUT_OF_DATAVIEW); return false; } - // Step 14. + // Steps 13-14. + bool isSharedMemory; + SharedMem data = + obj->getDataPointer(getIndex, &isSharedMemory); + MOZ_ASSERT(data); + if (isSharedMemory) { DataViewIO>::toBuffer(data, &value, isLittleEndian); @@ -956,7 +969,7 @@ const JSClass DataViewObject::class_ = { &DataViewObjectClassOps, &DataViewObject::classSpec_}; const JSClass DataViewObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_DataView), + "DataView.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_DataView), JS_NULL_CLASS_OPS, &DataViewObject::classSpec_}; const JSFunctionSpec DataViewObject::methods[] = { diff --git a/js/src/builtin/DataViewObject.h b/js/src/builtin/DataViewObject.h index 337b8c8812..ad3f0db879 100644 --- a/js/src/builtin/DataViewObject.h +++ b/js/src/builtin/DataViewObject.h @@ -32,10 +32,7 @@ class DataViewObject : public ArrayBufferViewObject { } template - static SharedMem getDataPointer(JSContext* cx, - Handle obj, - uint64_t offset, - bool* isSharedMemory); + SharedMem getDataPointer(uint64_t offset, bool* isSharedMemory); static bool bufferGetterImpl(JSContext* cx, const CallArgs& args); static bool bufferGetter(JSContext* cx, unsigned argc, Value* vp); @@ -79,6 +76,15 @@ class DataViewObject : public ArrayBufferViewObject { uint32_t byteLength() const { return byteLengthValue(this).toInt32(); } + template + bool offsetIsInBounds(uint64_t offset) const { + return offsetIsInBounds(sizeof(NativeType), offset); + } + bool offsetIsInBounds(uint32_t byteSize, uint64_t offset) const { + MOZ_ASSERT(byteSize <= 8); + return offset <= UINT32_MAX - byteSize && offset + byteSize <= byteLength(); + } + static bool isOriginalByteOffsetGetter(Native native) { return native == byteOffsetGetter; } @@ -149,6 +155,9 @@ class DataViewObject : public ArrayBufferViewObject { static bool setFloat64Impl(JSContext* cx, const CallArgs& args); static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp); + template + NativeType read(uint64_t offset, bool isLittleEndian); + template static bool read(JSContext* cx, Handle obj, const CallArgs& args, NativeType* val); diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index a5fcc6a6b9..628424f5db 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -11,6 +11,8 @@ #include "frontend/BytecodeCompilation.h" #include "frontend/CompilationInfo.h" #include "gc/HashUtil.h" +#include "js/friend/JSMEnvironment.h" // JS::NewJSMEnvironment, JS::ExecuteInJSMEnvironment, JS::GetJSMEnvironmentOfScriptedCaller, JS::IsJSMEnvironment +#include "js/friend/WindowProxy.h" // js::IsWindowProxy #include "js/SourceText.h" #include "js/StableStringChars.h" #include "vm/GlobalObject.h" @@ -327,23 +329,13 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, return false; } - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - frontend::CompilationInfo compilationInfo(cx, allocScope, options, - enclosing, env); - if (!compilationInfo.init(cx)) { - return false; - } - uint32_t len = srcBuf.length(); - SourceExtent extent = SourceExtent::makeGlobalExtent(len); - frontend::EvalSharedContext evalsc(cx, compilationInfo, enclosing, - compilationInfo.directives, extent); - RootedScript compiled( - cx, frontend::CompileEvalScript(compilationInfo, evalsc, srcBuf)); - if (!compiled) { + JSScript* script = + frontend::CompileEvalScript(cx, options, srcBuf, enclosing, env); + if (!script) { return false; } - esg.setNewScript(compiled); + esg.setNewScript(script); } // If this is a direct eval we need to use the caller's newTarget. @@ -434,24 +426,13 @@ bool js::DirectEvalStringFromIon(JSContext* cx, HandleObject env, return false; } - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - frontend::CompilationInfo compilationInfo(cx, allocScope, options, - enclosing, env); - if (!compilationInfo.init(cx)) { - return false; - } - - uint32_t len = srcBuf.length(); - SourceExtent extent = SourceExtent::makeGlobalExtent(len); - frontend::EvalSharedContext evalsc(cx, compilationInfo, enclosing, - compilationInfo.directives, extent); - JSScript* compiled = - frontend::CompileEvalScript(compilationInfo, evalsc, srcBuf); - if (!compiled) { + JSScript* script = + frontend::CompileEvalScript(cx, options, srcBuf, enclosing, env); + if (!script) { return false; } - esg.setNewScript(compiled); + esg.setNewScript(script); } return ExecuteKernel(cx, esg.script(), env, newTargetValue, @@ -547,7 +528,7 @@ JS_FRIEND_API bool js::ExecuteInFrameScriptEnvironment( return true; } -JS_FRIEND_API JSObject* js::NewJSMEnvironment(JSContext* cx) { +JS_FRIEND_API JSObject* JS::NewJSMEnvironment(JSContext* cx) { RootedObject varEnv(cx, NonSyntacticVariablesObject::create(cx)); if (!varEnv) { return nullptr; @@ -563,14 +544,14 @@ JS_FRIEND_API JSObject* js::NewJSMEnvironment(JSContext* cx) { return varEnv; } -JS_FRIEND_API bool js::ExecuteInJSMEnvironment(JSContext* cx, +JS_FRIEND_API bool JS::ExecuteInJSMEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject varEnv) { RootedObjectVector emptyChain(cx); return ExecuteInJSMEnvironment(cx, scriptArg, varEnv, emptyChain); } -JS_FRIEND_API bool js::ExecuteInJSMEnvironment(JSContext* cx, +JS_FRIEND_API bool JS::ExecuteInJSMEnvironment(JSContext* cx, HandleScript scriptArg, HandleObject varEnv, HandleObjectVector targetObj) { @@ -615,7 +596,7 @@ JS_FRIEND_API bool js::ExecuteInJSMEnvironment(JSContext* cx, return ExecuteInExtensibleLexicalEnvironment(cx, scriptArg, env); } -JS_FRIEND_API JSObject* js::GetJSMEnvironmentOfScriptedCaller(JSContext* cx) { +JS_FRIEND_API JSObject* JS::GetJSMEnvironmentOfScriptedCaller(JSContext* cx) { FrameIter iter(cx); if (iter.done()) { return nullptr; @@ -633,7 +614,7 @@ JS_FRIEND_API JSObject* js::GetJSMEnvironmentOfScriptedCaller(JSContext* cx) { return env; } -JS_FRIEND_API bool js::IsJSMEnvironment(JSObject* obj) { +JS_FRIEND_API bool JS::IsJSMEnvironment(JSObject* obj) { // NOTE: This also returns true if the NonSyntacticVariablesObject was // created for reasons other than the JSM loader. return obj->is(); diff --git a/js/src/builtin/FinalizationRegistryObject.cpp b/js/src/builtin/FinalizationRegistryObject.cpp index 478f854c87..140ba595fa 100644 --- a/js/src/builtin/FinalizationRegistryObject.cpp +++ b/js/src/builtin/FinalizationRegistryObject.cpp @@ -21,68 +21,32 @@ using namespace js; // FinalizationRecordObject const JSClass FinalizationRecordObject::class_ = { - "FinalizationRecord", JSCLASS_HAS_RESERVED_SLOTS(SlotCount), &classOps_, - JS_NULL_CLASS_SPEC}; - -const JSClassOps FinalizationRecordObject::classOps_ = { - nullptr, // addProperty - nullptr, // delProperty - nullptr, // enumerate - nullptr, // newEnumerate - nullptr, // resolve - nullptr, // mayResolve - nullptr, // finalize - nullptr, // call - nullptr, // hasInstance - nullptr, // construct - FinalizationRecordObject::trace, // trace -}; + "FinalizationRecord", JSCLASS_HAS_RESERVED_SLOTS(SlotCount)}; /* static */ FinalizationRecordObject* FinalizationRecordObject::create( - JSContext* cx, HandleFinalizationRegistryObject registry, - HandleValue heldValue) { - MOZ_ASSERT(registry); + JSContext* cx, HandleFinalizationQueueObject queue, HandleValue heldValue) { + MOZ_ASSERT(queue); auto record = NewObjectWithGivenProto(cx, nullptr); if (!record) { return nullptr; } - MOZ_ASSERT(registry->compartment() == record->compartment()); + MOZ_ASSERT(queue->compartment() == record->compartment()); - record->initReservedSlot(WeakRegistrySlot, PrivateValue(registry)); + record->initReservedSlot(QueueSlot, ObjectValue(*queue)); record->initReservedSlot(HeldValueSlot, heldValue); return record; } -FinalizationRegistryObject* FinalizationRecordObject::registryDuringGC( - gc::GCRuntime* gc) const { - FinalizationRegistryObject* registry = registryUnbarriered(); - - // Perform a manual read barrier. This is the only place where the GC itself - // needs to perform a read barrier so we must work around our assertions that - // this doesn't happen. - if (registry->zone()->isGCMarking()) { - FinalizationRegistryObject* tmp = registry; - TraceManuallyBarrieredEdge(&gc->marker, &tmp, - "FinalizationRegistry read barrier"); - MOZ_ASSERT(tmp == registry); - } else if (registry->isMarkedGray()) { - gc::UnmarkGrayGCThingUnchecked(gc->rt, JS::GCCellPtr(registry)); - } - - return registry; -} - -FinalizationRegistryObject* FinalizationRecordObject::registryUnbarriered() - const { - Value value = getReservedSlot(WeakRegistrySlot); +FinalizationQueueObject* FinalizationRecordObject::queue() const { + Value value = getReservedSlot(QueueSlot); if (value.isUndefined()) { return nullptr; } - return static_cast(value.toPrivate()); + return &value.toObject().as(); } Value FinalizationRecordObject::heldValue() const { @@ -90,47 +54,16 @@ Value FinalizationRecordObject::heldValue() const { } bool FinalizationRecordObject::isActive() const { - MOZ_ASSERT_IF(!registryUnbarriered(), heldValue().isUndefined()); - return registryUnbarriered(); + MOZ_ASSERT_IF(!queue(), heldValue().isUndefined()); + return queue(); } void FinalizationRecordObject::clear() { - MOZ_ASSERT(registryUnbarriered()); - setReservedSlot(WeakRegistrySlot, UndefinedValue()); + MOZ_ASSERT(queue()); + setReservedSlot(QueueSlot, UndefinedValue()); setReservedSlot(HeldValueSlot, UndefinedValue()); } -bool FinalizationRecordObject::sweep() { - FinalizationRegistryObject* obj = registryUnbarriered(); - MOZ_ASSERT(obj); - - if (IsAboutToBeFinalizedUnbarriered(&obj)) { - clear(); - return false; - } - - return true; -} - -/* static */ -void FinalizationRecordObject::trace(JSTracer* trc, JSObject* obj) { - if (!trc->traceWeakEdges()) { - return; - } - - auto record = &obj->as(); - FinalizationRegistryObject* registry = record->registryUnbarriered(); - if (!registry) { - return; - } - - TraceManuallyBarrieredEdge(trc, ®istry, - "FinalizationRecordObject weak registry"); - if (registry != record->registryUnbarriered()) { - record->setReservedSlot(WeakRegistrySlot, PrivateValue(registry)); - } -} - /////////////////////////////////////////////////////////////////////////// // FinalizationRegistrationsObject @@ -150,7 +83,7 @@ const JSClassOps FinalizationRegistrationsObject::classOps_ = { nullptr, // call nullptr, // hasInstance nullptr, // construct - nullptr, // trace + FinalizationRegistrationsObject::trace, // trace }; /* static */ @@ -173,10 +106,23 @@ FinalizationRegistrationsObject* FinalizationRegistrationsObject::create( return object; } +/* static */ +void FinalizationRegistrationsObject::trace(JSTracer* trc, JSObject* obj) { + if (!trc->traceWeakEdges()) { + return; + } + + auto* self = &obj->as(); + if (WeakFinalizationRecordVector* records = self->records()) { + TraceRange(trc, records->length(), records->begin(), + "FinalizationRegistrationsObject records"); + } +} + /* static */ void FinalizationRegistrationsObject::finalize(JSFreeOp* fop, JSObject* obj) { - auto rv = &obj->as(); - fop->delete_(obj, rv->records(), MemoryUse::FinalizationRecordVector); + auto* self = &obj->as(); + fop->delete_(obj, self->records(), MemoryUse::FinalizationRecordVector); } inline WeakFinalizationRecordVector* @@ -234,7 +180,7 @@ const JSClass FinalizationRegistryObject::class_ = { &classOps_, &classSpec_}; const JSClass FinalizationRegistryObject::protoClass_ = { - "FinalizationRegistryPrototype", + "FinalizationRegistry.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_FinalizationRegistry), JS_NULL_CLASS_OPS, &classSpec_}; @@ -278,57 +224,46 @@ bool FinalizationRegistryObject::construct(JSContext* cx, unsigned argc, return false; } - RootedObject cleanupCallback( - cx, ValueToCallable(cx, args.get(0), 1, NO_CONSTRUCT)); - if (!cleanupCallback) { - return false; - } - RootedObject proto(cx); if (!GetPrototypeFromBuiltinConstructor( cx, args, JSProto_FinalizationRegistry, &proto)) { return false; } - Rooted> registrations( - cx, cx->make_unique(cx)); - if (!registrations) { + RootedObject cleanupCallback( + cx, ValueToCallable(cx, args.get(0), 1, NO_CONSTRUCT)); + if (!cleanupCallback) { return false; } - Rooted> activeRecords( - cx, cx->make_unique(cx->zone())); - if (!activeRecords) { + Rooted> registrations( + cx, cx->make_unique(cx)); + if (!registrations) { return false; } - Rooted> recordsToBeCleanedUp( - cx, cx->make_unique(cx->zone())); - if (!recordsToBeCleanedUp) { + RootedFinalizationQueueObject queue( + cx, FinalizationQueueObject::create(cx, cleanupCallback)); + if (!queue) { return false; } - FinalizationRegistryObject* registry = - NewObjectWithClassProto(cx, proto); + RootedFinalizationRegistryObject registry( + cx, NewObjectWithClassProto(cx, proto)); if (!registry) { return false; } - registry->initReservedSlot(CleanupCallbackSlot, - ObjectValue(*cleanupCallback)); + registry->initReservedSlot(QueueSlot, ObjectValue(*queue)); InitReservedSlot(registry, RegistrationsSlot, registrations.release(), MemoryUse::FinalizationRegistryRegistrations); - InitReservedSlot(registry, ActiveRecords, activeRecords.release(), - MemoryUse::FinalizationRegistryRecordSet); - InitReservedSlot(registry, RecordsToBeCleanedUpSlot, - recordsToBeCleanedUp.release(), - MemoryUse::FinalizationRegistryRecordVector); - registry->initReservedSlot(IsQueuedForCleanupSlot, BooleanValue(false)); if (!cx->runtime()->gc.addFinalizationRegistry(cx, registry)) { return false; } + queue->setHasRegistry(true); + args.rval().setObject(*registry); return true; } @@ -343,20 +278,9 @@ void FinalizationRegistryObject::trace(JSTracer* trc, JSObject* obj) { if (ObjectWeakMap* registrations = registry->registrations()) { registrations->trace(trc); } - - // The active record set is weakly held and is not traced. - - if (FinalizationRecordVector* records = registry->recordsToBeCleanedUp()) { - records->trace(trc); - } } void FinalizationRegistryObject::sweep() { - // Sweep the set of active records. These may die if CCWs to record objects - // get nuked. - MOZ_ASSERT(activeRecords()); - activeRecords()->sweep(); - // Sweep the contents of the registrations weak map's values. MOZ_ASSERT(registrations()); for (ObjectValueWeakMap::Enum e(registrations()->valueMap()); !e.empty(); @@ -374,37 +298,20 @@ void FinalizationRegistryObject::sweep() { void FinalizationRegistryObject::finalize(JSFreeOp* fop, JSObject* obj) { auto registry = &obj->as(); - // Clear the weak pointer to the registry in all remaining records. - - // FinalizationRegistries are foreground finalized whereas record objects are - // background finalized, so record objects are guaranteed to still be - // accessible at this point. - MOZ_ASSERT(registry->getClass()->flags & JSCLASS_FOREGROUND_FINALIZE); - - FinalizationRecordSet* allRecords = registry->activeRecords(); - for (auto r = allRecords->all(); !r.empty(); r.popFront()) { - auto record = &r.front()->as(); - MOZ_ASSERT(!(record->getClass()->flags & JSCLASS_FOREGROUND_FINALIZE)); - MOZ_ASSERT(record->zone() == registry->zone()); - if (record->isActive()) { - record->clear(); - } - } + // The queue's flag should have been updated by + // GCRuntime::sweepFinalizationRegistries. + MOZ_ASSERT_IF(registry->queue(), !registry->queue()->hasRegistry()); fop->delete_(obj, registry->registrations(), MemoryUse::FinalizationRegistryRegistrations); - fop->delete_(obj, registry->activeRecords(), - MemoryUse::FinalizationRegistryRecordSet); - fop->delete_(obj, registry->recordsToBeCleanedUp(), - MemoryUse::FinalizationRegistryRecordVector); } -inline JSObject* FinalizationRegistryObject::cleanupCallback() const { - Value value = getReservedSlot(CleanupCallbackSlot); +FinalizationQueueObject* FinalizationRegistryObject::queue() const { + Value value = getReservedSlot(QueueSlot); if (value.isUndefined()) { return nullptr; } - return &value.toObject(); + return &value.toObject().as(); } ObjectWeakMap* FinalizationRegistryObject::registrations() const { @@ -415,40 +322,6 @@ ObjectWeakMap* FinalizationRegistryObject::registrations() const { return static_cast(value.toPrivate()); } -FinalizationRecordSet* FinalizationRegistryObject::activeRecords() const { - Value value = getReservedSlot(ActiveRecords); - if (value.isUndefined()) { - return nullptr; - } - return static_cast(value.toPrivate()); -} - -FinalizationRecordVector* FinalizationRegistryObject::recordsToBeCleanedUp() - const { - Value value = getReservedSlot(RecordsToBeCleanedUpSlot); - if (value.isUndefined()) { - return nullptr; - } - return static_cast(value.toPrivate()); -} - -bool FinalizationRegistryObject::isQueuedForCleanup() const { - return getReservedSlot(IsQueuedForCleanupSlot).toBoolean(); -} - -void FinalizationRegistryObject::queueRecordToBeCleanedUp( - FinalizationRecordObject* record) { - AutoEnterOOMUnsafeRegion oomUnsafe; - if (!recordsToBeCleanedUp()->append(record)) { - oomUnsafe.crash("FinalizationRegistryObject::queueRecordsToBeCleanedUp"); - } -} - -void FinalizationRegistryObject::setQueuedForCleanup(bool value) { - MOZ_ASSERT(value != isQueuedForCleanup()); - setReservedSlot(IsQueuedForCleanupSlot, BooleanValue(value)); -} - // FinalizationRegistry.prototype.register(target, heldValue [, unregisterToken // ]) // https://tc39.es/proposal-weakrefs/#sec-finalization-registry.prototype.register @@ -507,21 +380,13 @@ bool FinalizationRegistryObject::register_(JSContext* cx, unsigned argc, } // Create the finalization record representing this target and heldValue. + Rooted queue(cx, registry->queue()); Rooted record( - cx, FinalizationRecordObject::create(cx, registry, heldValue)); + cx, FinalizationRecordObject::create(cx, queue, heldValue)); if (!record) { return false; } - // Add the record to the list of records with live targets. - if (!registry->activeRecords()->put(record)) { - ReportOutOfMemory(cx); - return false; - } - - auto recordsGuard = mozilla::MakeScopeExit( - [&] { registry->activeRecords()->remove(record); }); - // Add the record to the registrations if an unregister token was supplied. if (unregisterToken && !addRegistration(cx, registry, unregisterToken, record)) { @@ -566,7 +431,6 @@ bool FinalizationRegistryObject::register_(JSContext* cx, unsigned argc, return false; } - recordsGuard.release(); registrationsGuard.release(); args.rval().setUndefined(); return true; @@ -678,22 +542,15 @@ bool FinalizationRegistryObject::unregister(JSContext* cx, unsigned argc, // i. Remove cell from finalizationRegistry.[[Cells]]. // ii. Set removed to true. - FinalizationRecordSet* activeRecords = registry->activeRecords(); RootedObject obj(cx, registry->registrations()->lookup(unregisterToken)); if (obj) { auto* records = obj->as().records(); MOZ_ASSERT(records); MOZ_ASSERT(!records->empty()); for (FinalizationRecordObject* record : *records) { - if (record->isActive()) { - // Clear the fields of this record; it will be removed from the target's - // list when it is next swept. - activeRecords->remove(record); - record->clear(); + if (unregisterRecord(record)) { removed = true; } - - MOZ_ASSERT(!activeRecords->has(record)); } registry->registrations()->remove(unregisterToken); } @@ -703,6 +560,19 @@ bool FinalizationRegistryObject::unregister(JSContext* cx, unsigned argc, return true; } +/* static */ +bool FinalizationRegistryObject::unregisterRecord( + FinalizationRecordObject* record) { + if (!record->isActive()) { + return false; + } + + // Clear the fields of this record; it will be removed from the target's + // list when it is next swept. + record->clear(); + return true; +} + // FinalizationRegistry.prototype.cleanupSome ( [ callback ] ) // https://tc39.es/proposal-weakrefs/#sec-finalization-registry.prototype.cleanupSome bool FinalizationRegistryObject::cleanupSome(JSContext* cx, unsigned argc, @@ -732,7 +602,9 @@ bool FinalizationRegistryObject::cleanupSome(JSContext* cx, unsigned argc, } } - if (!cleanupQueuedRecords(cx, registry, cleanupCallback)) { + RootedFinalizationQueueObject queue(cx, registry->queue()); + if (!FinalizationQueueObject::cleanupQueuedRecords(cx, queue, + cleanupCallback)) { return false; } @@ -740,13 +612,184 @@ bool FinalizationRegistryObject::cleanupSome(JSContext* cx, unsigned argc, return true; } +/////////////////////////////////////////////////////////////////////////// +// FinalizationQueueObject + +// Bug 1600300: FinalizationQueueObject is foreground finalized so that +// HeapPtr destructors never see referents with released arenas. When this is +// fixed we may be able to make this background finalized again. +const JSClass FinalizationQueueObject::class_ = { + "FinalizationQueue", + JSCLASS_HAS_RESERVED_SLOTS(SlotCount) | JSCLASS_FOREGROUND_FINALIZE, + &classOps_}; + +const JSClassOps FinalizationQueueObject::classOps_ = { + nullptr, // addProperty + nullptr, // delProperty + nullptr, // enumerate + nullptr, // newEnumerate + nullptr, // resolve + nullptr, // mayResolve + FinalizationQueueObject::finalize, // finalize + nullptr, // call + nullptr, // hasInstance + nullptr, // construct + FinalizationQueueObject::trace, // trace +}; + +/* static */ +FinalizationQueueObject* FinalizationQueueObject::create( + JSContext* cx, HandleObject cleanupCallback) { + MOZ_ASSERT(cleanupCallback); + + Rooted> recordsToBeCleanedUp( + cx, cx->make_unique(cx->zone())); + if (!recordsToBeCleanedUp) { + return nullptr; + } + + HandlePropertyName funName = cx->names().empty; + RootedFunction doCleanupFunction( + cx, NewNativeFunction(cx, doCleanup, 0, funName, + gc::AllocKind::FUNCTION_EXTENDED)); + if (!doCleanupFunction) { + return nullptr; + } + + // It's problematic storing a CCW to a global in another compartment because + // you don't know how far to unwrap it to get the original object + // back. Instead store a CCW to a plain object in the same compartment as the + // global (this uses Object.prototype). + RootedObject incumbentObject(cx); + if (!GetObjectFromIncumbentGlobal(cx, &incumbentObject)) { + return nullptr; + } + + FinalizationQueueObject* queue = + NewObjectWithGivenProto(cx, nullptr); + if (!queue) { + return nullptr; + } + + queue->initReservedSlot(CleanupCallbackSlot, ObjectValue(*cleanupCallback)); + queue->initReservedSlot(IncumbentObjectSlot, ObjectValue(*incumbentObject)); + InitReservedSlot(queue, RecordsToBeCleanedUpSlot, + recordsToBeCleanedUp.release(), + MemoryUse::FinalizationRegistryRecordVector); + queue->initReservedSlot(IsQueuedForCleanupSlot, BooleanValue(false)); + queue->initReservedSlot(DoCleanupFunctionSlot, + ObjectValue(*doCleanupFunction)); + queue->initReservedSlot(HasRegistrySlot, BooleanValue(false)); + + doCleanupFunction->setExtendedSlot(DoCleanupFunction_QueueSlot, + ObjectValue(*queue)); + + return queue; +} + +/* static */ +void FinalizationQueueObject::trace(JSTracer* trc, JSObject* obj) { + auto queue = &obj->as(); + + if (FinalizationRecordVector* records = queue->recordsToBeCleanedUp()) { + records->trace(trc); + } +} + +/* static */ +void FinalizationQueueObject::finalize(JSFreeOp* fop, JSObject* obj) { + auto queue = &obj->as(); + + fop->delete_(obj, queue->recordsToBeCleanedUp(), + MemoryUse::FinalizationRegistryRecordVector); +} + +void FinalizationQueueObject::setHasRegistry(bool newValue) { + MOZ_ASSERT(hasRegistry() != newValue); + + // Suppress our assertions about touching grey things. It's OK for us to set a + // boolean slot even if this object is gray. + AutoTouchingGrayThings atgt; + + setReservedSlot(HasRegistrySlot, BooleanValue(newValue)); +} + +bool FinalizationQueueObject::hasRegistry() const { + return getReservedSlot(HasRegistrySlot).toBoolean(); +} + +inline JSObject* FinalizationQueueObject::cleanupCallback() const { + Value value = getReservedSlot(CleanupCallbackSlot); + if (value.isUndefined()) { + return nullptr; + } + return &value.toObject(); +} + +JSObject* FinalizationQueueObject::incumbentObject() const { + Value value = getReservedSlot(IncumbentObjectSlot); + if (value.isUndefined()) { + return nullptr; + } + return &value.toObject(); +} + +FinalizationRecordVector* FinalizationQueueObject::recordsToBeCleanedUp() + const { + Value value = getReservedSlot(RecordsToBeCleanedUpSlot); + if (value.isUndefined()) { + return nullptr; + } + return static_cast(value.toPrivate()); +} + +bool FinalizationQueueObject::isQueuedForCleanup() const { + return getReservedSlot(IsQueuedForCleanupSlot).toBoolean(); +} + +JSFunction* FinalizationQueueObject::doCleanupFunction() const { + Value value = getReservedSlot(DoCleanupFunctionSlot); + if (value.isUndefined()) { + return nullptr; + } + return &value.toObject().as(); +} + +void FinalizationQueueObject::queueRecordToBeCleanedUp( + FinalizationRecordObject* record) { + AutoEnterOOMUnsafeRegion oomUnsafe; + if (!recordsToBeCleanedUp()->append(record)) { + oomUnsafe.crash("FinalizationQueueObject::queueRecordsToBeCleanedUp"); + } +} + +void FinalizationQueueObject::setQueuedForCleanup(bool value) { + MOZ_ASSERT(value != isQueuedForCleanup()); + setReservedSlot(IsQueuedForCleanupSlot, BooleanValue(value)); +} + +/* static */ +bool FinalizationQueueObject::doCleanup(JSContext* cx, unsigned argc, + Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + RootedFunction callee(cx, &args.callee().as()); + + Value value = callee->getExtendedSlot(DoCleanupFunction_QueueSlot); + RootedFinalizationQueueObject queue( + cx, &value.toObject().as()); + + queue->setQueuedForCleanup(false); + return cleanupQueuedRecords(cx, queue); +} + // CleanupFinalizationRegistry ( finalizationRegistry [ , callback ] ) // https://tc39.es/proposal-weakrefs/#sec-cleanup-finalization-registry /* static */ -bool FinalizationRegistryObject::cleanupQueuedRecords( - JSContext* cx, HandleFinalizationRegistryObject registry, +bool FinalizationQueueObject::cleanupQueuedRecords( + JSContext* cx, HandleFinalizationQueueObject queue, HandleObject callbackArg) { - MOZ_ASSERT(cx->compartment() == registry->compartment()); + MOZ_ASSERT(cx->compartment() == queue->compartment()); // 2. If callback is undefined, set callback to // finalizationRegistry.[[CleanupCallback]]. @@ -754,7 +797,7 @@ bool FinalizationRegistryObject::cleanupQueuedRecords( if (callbackArg) { callback.setObject(*callbackArg); } else { - JSObject* cleanupCallback = registry->cleanupCallback(); + JSObject* cleanupCallback = queue->cleanupCallback(); MOZ_ASSERT(cleanupCallback); callback.setObject(*cleanupCallback); } @@ -768,8 +811,7 @@ bool FinalizationRegistryObject::cleanupQueuedRecords( RootedValue heldValue(cx); RootedValue rval(cx); - FinalizationRecordVector* records = registry->recordsToBeCleanedUp(); - FinalizationRecordSet* activeRecords = registry->activeRecords(); + FinalizationRecordVector* records = queue->recordsToBeCleanedUp(); while (!records->empty()) { FinalizationRecordObject* record = records->popCopy(); @@ -780,7 +822,6 @@ bool FinalizationRegistryObject::cleanupQueuedRecords( heldValue.set(record->heldValue()); - activeRecords->remove(record); record->clear(); if (!Call(cx, callback, UndefinedHandleValue, heldValue, &rval)) { diff --git a/js/src/builtin/FinalizationRegistryObject.h b/js/src/builtin/FinalizationRegistryObject.h index 2c06c3788b..c384964908 100644 --- a/js/src/builtin/FinalizationRegistryObject.h +++ b/js/src/builtin/FinalizationRegistryObject.h @@ -10,45 +10,56 @@ * * To arrange this, the following data structures are used: * - * +-------------------------------------+---------------------------------+ - * | FinalizationRegistry compartment | Target zone / compartment | - * | | | - * | +----------------------+ | +------------------+ | - * | +---->+ FinalizationRegistry | | | Zone | | - * | | +---------+------------+ | +---------+--------+ | - * | | | | | | - * | | v | v | - * | | +------------+--------------+ | +------------+------------+ | - * | | | Registrations | | | FinalizationRecordMap | | - * | | | weak map | | | map | | - * | | +---------------------------+ | +-------------------------+ | - * | | | Unregister : Records | | | Target : Finalization-| | - * | | | token : object | | | object : RecordVector | | - * | | +--------------------+------+ | +----+-------------+------+ | - * | | | | | | | - * | | v | v | | - * | | +--------------------+------+ | +----+-----+ | | - * | | | Finalization- | | | Target | | | - * | | | RegistrationsObject | | | JSObject | | | - * | | +-------------+-------------+ | +----------+ | | - * | | | RecordVector | | | | - * | | +-------------+-------------+ | | | - * | | | | | | - * | | * v | | | - * | | +-------------+-------------+ * | | | - * | | | FinalizationRecordObject +<-------------------------+ | - * | | +---------------------------+ | | - * | +--+ Registry | | | - * | +---------------------------+ | | - * | | Held value | | | - * | +---------------------------+ | | - * | | | - * +-------------------------------------+---------------------------------+ + * +---------------------------------------+-------------------------------+ + * | FinalizationRegistry compartment | Target zone / compartment | + * | | | + * | +----------------------+ | +------------------+ | + * | +-----+ FinalizationRegistry | | | Zone | | + * | | +----------+-----------+ | +---------+--------+ | + * | | | | | | + * | | v | v | + * | | +-------------+-------------+ | +------------+------------+ | + * | | | Registrations | | | FinalizationRecordMap | | + * | | | weak map | | | map | | + * | | +---------------------------+ | +-------------------------+ | + * | | | Unregister : Records | | | Target : Finalization | | + * | | | token : object | | | object : RecordVector | | + * | | +--------------------+------+ | +----+-------------+------+ | + * | | | | | | | + * | | v | v | | + * | | +--------------------+------+ | +----+-----+ | | + * | | | Finalization | | | Target | | | + * | | | RegistrationsObject | | | JSObject | | | + * | | +---------------------------+ | +----------+ | | + * | | | RecordVector | | | | + * | | +-------------+-------------+ | | | + * | | | | | | + * | | * v | | | + * | | +-------------+-------------+ * | | | + * | | | FinalizationRecordObject +<--------------------------+ | + * | | +---------------------------+ | | + * | | | Queue +--+ | | + * | | +---------------------------+ | | | + * | | | Held value | | | | + * | | +---------------------------+ | | | + * | | | | | + * | +--------------+ +--------------+ | | + * | | | | | + * | v v | | + * | +----------+---+----------+ | | + * | | FinalizationQueueObject | | | + * | +-------------------------+ | | + * | | | + * +---------------------------------------+-------------------------------+ + * + * A FinalizationRegistry consists of two parts: the FinalizationRegistry that + * consumers see and a FinalizationQueue used internally to queue and call the + * cleanup callbacks. * * Registering a target with a FinalizationRegistry creates a FinalizationRecord - * containing the registry and the heldValue. This is added to a vector of - * records associated with the target, implemented as a map on the target's - * Zone. All finalization records are treated as GC roots. + * containing a pointer to the queue and the heldValue. This is added to a + * vector of records associated with the target, implemented as a map on the + * target's Zone. All finalization records are treated as GC roots. * * When a target is registered an unregister token may be supplied. If so, this * is also recorded by the registry and is stored in a weak map of @@ -56,20 +67,18 @@ * objects. It's necessary to have another JSObject here because our weak map * implementation only supports JS types as values. * - * After a target object has been registered with a finalization registry it is - * expected that its callback will be called for that object even if the - * finalization registry itself is no longer reachable from JS. Thus the values - * of each zone's finalization record map are treated as roots and marked at the - * start of GC. - * - * The finalization record maps are also swept during GC to check for any - * targets that are dying. For such targets the associated record list is - * processed and for each record the heldValue is queued on finalization - * registry. At a later time this causes the client's callback to be run. - * * When targets are unregistered, the registration is looked up in the weakmap - * and the corresponding records are cleared. These are removed from the zone's - * record map when it is next swept. + * and the corresponding records are cleared. + + * The finalization record maps are swept during GC to check for records that + * have been cleared by unregistration, for FinalizationRecords that are dead + * and for nuked CCWs. In all cases the record is removed and the cleanup + * callback is not run. + * + * Following this the targets are checked to see if they are dying. For such + * targets the associated record list is processed and for each record the + * heldValue is queued on the FinalizationQueue. At a later time this causes the + * client's cleanup callback to be run. */ #ifndef builtin_FinalizationRegistryObject_h @@ -82,15 +91,16 @@ namespace js { class FinalizationRegistryObject; -class FinalizationIteratorObject; class FinalizationRecordObject; +class FinalizationQueueObject; class ObjectWeakMap; using HandleFinalizationRegistryObject = Handle; using HandleFinalizationRecordObject = Handle; +using HandleFinalizationQueueObject = Handle; using RootedFinalizationRegistryObject = Rooted; -using RootedFinalizationIteratorObject = Rooted; using RootedFinalizationRecordObject = Rooted; +using RootedFinalizationQueueObject = Rooted; // A finalization record: a pair of finalization registry and held value. // @@ -101,32 +111,21 @@ using RootedFinalizationRecordObject = Rooted; // inactive. This happens when: // - the heldValue is passed to the registry's cleanup callback // - the registry's unregister method removes the registration -// - the FinalizationRegistry dies class FinalizationRecordObject : public NativeObject { - enum { WeakRegistrySlot = 0, HeldValueSlot, SlotCount }; + enum { QueueSlot = 0, HeldValueSlot, SlotCount }; public: static const JSClass class_; - // The registry can be a CCW to a FinalizationRegistryObject. - static FinalizationRecordObject* create( - JSContext* cx, HandleFinalizationRegistryObject registry, - HandleValue heldValue); - - // Read weak registry pointer and perform read barrier during GC. - FinalizationRegistryObject* registryDuringGC(gc::GCRuntime* gc) const; + static FinalizationRecordObject* create(JSContext* cx, + HandleFinalizationQueueObject queue, + HandleValue heldValue); + FinalizationQueueObject* queue() const; Value heldValue() const; bool isActive() const; - void clear(); - bool sweep(); - private: - static const JSClassOps classOps_; - - static void trace(JSTracer* trc, JSObject* obj); - - FinalizationRegistryObject* registryUnbarriered() const; + void clear(); }; // A vector of weakly-held FinalizationRecordObjects. @@ -168,35 +167,21 @@ class FinalizationRegistrationsObject : public NativeObject { using FinalizationRecordVector = GCVector, 1, js::ZoneAllocPolicy>; -using FinalizationRecordSet = - GCHashSet, ZoneAllocPolicy>; - -// The FinalizationRegistry object itself. +// The JS FinalizationRegistry object itself. class FinalizationRegistryObject : public NativeObject { - enum { - CleanupCallbackSlot = 0, - RegistrationsSlot, - ActiveRecords, - RecordsToBeCleanedUpSlot, - IsQueuedForCleanupSlot, - SlotCount - }; + enum { QueueSlot = 0, RegistrationsSlot, SlotCount }; public: static const JSClass class_; static const JSClass protoClass_; - JSObject* cleanupCallback() const; + FinalizationQueueObject* queue() const; ObjectWeakMap* registrations() const; - FinalizationRecordSet* activeRecords() const; - FinalizationRecordVector* recordsToBeCleanedUp() const; - bool isQueuedForCleanup() const; - - void queueRecordToBeCleanedUp(FinalizationRecordObject* record); - void setQueuedForCleanup(bool value); void sweep(); + static bool unregisterRecord(FinalizationRecordObject* record); + static bool cleanupQueuedRecords(JSContext* cx, HandleFinalizationRegistryObject registry, HandleObject callback = nullptr); @@ -226,29 +211,52 @@ class FinalizationRegistryObject : public NativeObject { static void finalize(JSFreeOp* fop, JSObject* obj); }; -// An iterator over a finalization registry's queued held values. In the spec -// this is called FinalizationRegistryCleanupIterator. -class FinalizationIteratorObject : public NativeObject { - enum { FinalizationRegistrySlot = 0, IndexSlot, SlotCount }; +// Contains information about the cleanup callback and the records queued to +// be cleaned up. This is not exposed to content JS. +class FinalizationQueueObject : public NativeObject { + enum { + CleanupCallbackSlot = 0, + IncumbentObjectSlot, + RecordsToBeCleanedUpSlot, + IsQueuedForCleanupSlot, + DoCleanupFunctionSlot, + HasRegistrySlot, + SlotCount + }; + + enum DoCleanupFunctionSlots { + DoCleanupFunction_QueueSlot = 0, + }; public: static const JSClass class_; - static FinalizationIteratorObject* create( - JSContext* cx, HandleFinalizationRegistryObject registry); + JSObject* cleanupCallback() const; + JSObject* incumbentObject() const; + FinalizationRecordVector* recordsToBeCleanedUp() const; + bool isQueuedForCleanup() const; + JSFunction* doCleanupFunction() const; + bool hasRegistry() const; - FinalizationRegistryObject* finalizationRegistry() const; - size_t index() const; + void queueRecordToBeCleanedUp(FinalizationRecordObject* record); + void setQueuedForCleanup(bool value); + + void setHasRegistry(bool newValue); - void setIndex(size_t index); - void clearFinalizationRegistry(); + static FinalizationQueueObject* create(JSContext* cx, + HandleObject cleanupCallback); + + static bool cleanupQueuedRecords(JSContext* cx, + HandleFinalizationQueueObject registry, + HandleObject callback = nullptr); private: - friend class GlobalObject; - static const JSFunctionSpec methods_[]; - static const JSPropertySpec properties_[]; + static const JSClassOps classOps_; - static bool next(JSContext* cx, unsigned argc, Value* vp); + static bool doCleanup(JSContext* cx, unsigned argc, Value* vp); + + static void trace(JSTracer* trc, JSObject* obj); + static void finalize(JSFreeOp* fop, JSObject* obj); }; } // namespace js diff --git a/js/src/builtin/Iterator.js b/js/src/builtin/Iterator.js index c03d613e0c..2fa9bef38e 100644 --- a/js/src/builtin/Iterator.js +++ b/js/src/builtin/Iterator.js @@ -6,6 +6,20 @@ function IteratorIdentity() { return this; } +/* ECMA262 7.2.7 */ +function IteratorNext(iteratorRecord, value) { + // Steps 1-2. + const result = (arguments.length < 2 + ? callContentFunction(iteratorRecord.nextMethod, iteratorRecord.iterator) + : callContentFunction(iteratorRecord.nextMethod, iteratorRecord.iterator, value)); + // Step 3. + if (!IsObject(result)) { + ThrowTypeError(JSMSG_OBJECT_REQUIRED, result); + } + // Step 4. + return result; +} + /* ECMA262 7.4.6 */ function IteratorClose(iteratorRecord, value) { // Step 3. @@ -138,8 +152,14 @@ function IteratorFrom(O) { function WrapForValidIteratorNext(value) { // Step 1-2. let O; - if (!IsObject(this) || (O = GuardToWrapForValidIterator(this)) === null) - ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, O)); + if (!IsObject(this) || (O = GuardToWrapForValidIterator(this)) === null) { + if (arguments.length === 0) { + return callFunction(CallWrapForValidIteratorMethodIfWrapped, this, + "WrapForValidIteratorNext"); + } + return callFunction(CallWrapForValidIteratorMethodIfWrapped, this, + value, "WrapForValidIteratorNext"); + } const iterated = UnsafeGetReservedSlot(O, ITERATED_SLOT); // Step 3. let result; @@ -158,8 +178,10 @@ function WrapForValidIteratorNext(value) { function WrapForValidIteratorReturn(value) { // Step 1-2. let O; - if (!IsObject(this) || (O = GuardToWrapForValidIterator(this)) === null) - ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, O)); + if (!IsObject(this) || (O = GuardToWrapForValidIterator(this)) === null) { + return callFunction(CallWrapForValidIteratorMethodIfWrapped, this, + value, "WrapForValidIteratorReturn"); + } const iterated = UnsafeGetReservedSlot(O, ITERATED_SLOT); // Step 3. @@ -184,7 +206,8 @@ function WrapForValidIteratorThrow(value) { // Step 1-2. let O; if (!IsObject(this) || (O = GuardToWrapForValidIterator(this)) === null) { - ThrowTypeError(JSMSG_OBJECT_REQUIRED, DecompileArg(0, O)); + return callFunction(CallWrapForValidIteratorMethodIfWrapped, this, + value, "WrapForValidIteratorThrow"); } const iterated = UnsafeGetReservedSlot(O, ITERATED_SLOT); // Step 3. @@ -199,6 +222,343 @@ function WrapForValidIteratorThrow(value) { return callContentFunction(throwMethod, iterator, value); } +/* Iterator Helper object prototype methods. */ +function IteratorHelperNext(value) { + let O; + if (!IsObject(this) || (O = GuardToIteratorHelper(this)) === null) { + return callFunction(CallIteratorHelperMethodIfWrapped, this, + value, "IteratorHelperNext"); + } + const generator = UnsafeGetReservedSlot(O, ITERATOR_HELPER_GENERATOR_SLOT); + return callContentFunction(GeneratorNext, generator, value); +} + +function IteratorHelperReturn(value) { + let O; + if (!IsObject(this) || (O = GuardToIteratorHelper(this)) === null) { + return callFunction(CallIteratorHelperMethodIfWrapped, this, + value, "IteratorHelperReturn"); + } + const generator = UnsafeGetReservedSlot(O, ITERATOR_HELPER_GENERATOR_SLOT); + return callContentFunction(GeneratorReturn, generator, value); +} + +function IteratorHelperThrow(value) { + let O; + if (!IsObject(this) || (O = GuardToIteratorHelper(this)) === null) { + return callFunction(CallIteratorHelperMethodIfWrapped, this, + value, "IteratorHelperThrow"); + } + const generator = UnsafeGetReservedSlot(O, ITERATOR_HELPER_GENERATOR_SLOT); + return callContentFunction(GeneratorThrow, generator, value); +} + +// Lazy %Iterator.prototype% methods +// Iterator Helpers proposal 2.1.5.2-2.1.5.7 +// +// In order to match the semantics of the built-in generator objects used in +// the proposal, we use a reserved slot on the IteratorHelper objects to store +// a regular generator that is called from the %IteratorHelper.prototype% +// methods. +// +// Each of the lazy methods is divided into a prelude and a body, with the +// eager prelude steps being contained in the corresponding IteratorX method +// and the lazy body steps inside the IteratorXGenerator generator functions. +// +// Each prelude method initializes and returns a new IteratorHelper object. +// As part of this initialization process, the appropriate generator function +// is called, followed by GeneratorNext being called on returned generator +// instance in order to move it to it's first yield point. This is done so that +// if the return or throw methods are called on the IteratorHelper before next +// has been called, we can catch them in the try and use the finally block to +// close the source iterator. +// +// The needClose flag is used to track when the source iterator should be closed +// following an exception being thrown within the generator, corresponding to +// whether or not the abrupt completions in the spec are being passed back to +// the caller (when needClose is false) or handled with IfAbruptCloseIterator +// (when needClose is true). + +/* Iterator Helpers proposal 2.1.5.2 Prelude */ +function IteratorMap(mapper) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(mapper)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper)); + } + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorMapGenerator(iterated, mapper); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.2 Body */ +function* IteratorMapGenerator(iterated, mapper) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = IteratorStep(iterated, lastValue); + next; + next = IteratorStep(iterated, lastValue)) { + // Step c. + const value = next.value; + + // Steps d-g. + needClose = true; + lastValue = yield callContentFunction(mapper, undefined, value); + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.5.3 Prelude */ +function IteratorFilter(filterer) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(filterer)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, filterer)); + } + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorFilterGenerator(iterated, filterer); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.3 Body */ +function* IteratorFilterGenerator(iterated, filterer) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = IteratorStep(iterated, lastValue); + next; + next = IteratorStep(iterated, lastValue)) { + // Step c. + const value = next.value; + + // Steps d-g. + needClose = true; + if (callContentFunction(filterer, undefined, value)) { + lastValue = yield value; + } + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.5.4 Prelude */ +function IteratorTake(limit) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + const remaining = ToInteger(limit); + // Step 3. + if (remaining < 0) { + ThrowRangeError(JSMSG_NEGATIVE_LIMIT); + } + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorTakeGenerator(iterated, remaining); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.4 Body */ +function* IteratorTakeGenerator(iterated, remaining) { + // Step 1. + let lastValue; + // Step 2. + let needClose = true; + try { + yield; + needClose = false; + + for (; remaining > 0; remaining--) { + const next = IteratorStep(iterated, lastValue); + if (!next) { + return; + } + + const value = next.value; + needClose = true; + lastValue = yield value; + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } + + IteratorClose(iterated); +} + +/* Iterator Helpers proposal 2.1.5.5 Prelude */ +function IteratorDrop(limit) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + const remaining = ToInteger(limit); + // Step 3. + if (remaining < 0) { + ThrowRangeError(JSMSG_NEGATIVE_LIMIT); + } + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorDropGenerator(iterated, remaining); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.5 Body */ +function* IteratorDropGenerator(iterated, remaining) { + let needClose = true; + try { + yield; + needClose = false; + + // Step 1. + for (; remaining > 0; remaining--) { + if (!IteratorStep(iterated)) { + return; + } + } + + // Step 2. + let lastValue; + // Step 3. + for (let next = IteratorStep(iterated, lastValue); + next; + next = IteratorStep(iterated, lastValue)) { + // Steps c-d. + const value = next.value; + + needClose = true; + lastValue = yield value; + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.5.6 Prelude */ +function IteratorAsIndexedPairs() { + // Step 1. + const iterated = GetIteratorDirect(this); + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorAsIndexedPairsGenerator(iterated); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.6 Body */ +function* IteratorAsIndexedPairsGenerator(iterated) { + // Step 2. + let lastValue; + // Step 3. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = IteratorStep(iterated, lastValue), index = 0; + next; + next = IteratorStep(iterated, lastValue), index++) { + // Steps c-d. + const value = next.value; + + needClose = true; + lastValue = yield [index, value]; + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } +} + +/* Iterator Helpers proposal 2.1.5.7 Prelude */ +function IteratorFlatMap(mapper) { + // Step 1. + const iterated = GetIteratorDirect(this); + + // Step 2. + if (!IsCallable(mapper)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapper)); + } + + const iteratorHelper = NewIteratorHelper(); + const generator = IteratorFlatMapGenerator(iterated, mapper); + callContentFunction(GeneratorNext, generator); + UnsafeSetReservedSlot(iteratorHelper, ITERATOR_HELPER_GENERATOR_SLOT, generator); + return iteratorHelper; +} + +/* Iterator Helpers proposal 2.1.5.7 Body */ +function* IteratorFlatMapGenerator(iterated, mapper) { + // Step 1. + let needClose = true; + try { + yield; + needClose = false; + + for (let next = IteratorStep(iterated); + next; + next = IteratorStep(iterated)) { + // Step c. + const value = next.value; + + needClose = true; + // Step d. + const mapped = callContentFunction(mapper, undefined, value); + // Steps f-i. + for (const innerValue of allowContentIter(mapped)) { + yield innerValue; + } + needClose = false; + } + } finally { + if (needClose) { + IteratorClose(iterated); + } + } +} + /* Iterator Helpers proposal 2.1.5.8 */ function IteratorReduce(reducer/*, initialValue*/) { // Step 1. diff --git a/js/src/builtin/JSON.cpp b/js/src/builtin/JSON.cpp index 12e1b3d287..aa526e160e 100644 --- a/js/src/builtin/JSON.cpp +++ b/js/src/builtin/JSON.cpp @@ -16,6 +16,8 @@ #include "builtin/Array.h" #include "builtin/BigInt.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit +#include "js/Object.h" // JS::GetBuiltinClass #include "js/PropertySpec.h" #include "js/StableStringChars.h" #include "util/StringBuffer.h" @@ -339,7 +341,7 @@ static bool PreprocessValue(JSContext* cx, HandleObject holder, KeyType key, RootedObject obj(cx, &vp.get().toObject()); ESClass cls; - if (!GetBuiltinClass(cx, obj, &cls)) { + if (!JS::GetBuiltinClass(cx, obj, &cls)) { return false; } @@ -768,7 +770,12 @@ bool js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, } /* Step 4b(iii)(5)(c-g). */ - if (!item.isNumber() && !item.isString()) { + RootedId id(cx); + if (item.isNumber() || item.isString()) { + if (!PrimitiveValueToId(cx, item, &id)) { + return false; + } + } else { ESClass cls; if (!GetClassOfValue(cx, item, &cls)) { return false; @@ -777,11 +784,13 @@ bool js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, if (cls != ESClass::String && cls != ESClass::Number) { continue; } - } - RootedId id(cx); - if (!ValueToId(cx, item, &id)) { - return false; + JSAtom* atom = ToAtom(cx, item); + if (!atom) { + return false; + } + + id.set(AtomToId(atom)); } /* Step 4b(iii)(5)(g). */ @@ -803,7 +812,7 @@ bool js::Stringify(JSContext* cx, MutableHandleValue vp, JSObject* replacer_, RootedObject spaceObj(cx, &space.toObject()); ESClass cls; - if (!GetBuiltinClass(cx, spaceObj, &cls)) { + if (!JS::GetBuiltinClass(cx, spaceObj, &cls)) { return false; } diff --git a/js/src/builtin/Map.js b/js/src/builtin/Map.js index dadf7c2932..4a50d0bd06 100644 --- a/js/src/builtin/Map.js +++ b/js/src/builtin/Map.js @@ -40,7 +40,7 @@ function MapForEach(callbackfn, thisArg = undefined) { ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Steps 5-8. - var entries = callFunction(std_Map_iterator, M); + var entries = callFunction(std_Map_entries, M); // Inlined: MapIteratorNext var mapIterationResultPair = iteratorTemp.mapIterationResultPair; @@ -63,13 +63,6 @@ function MapForEach(callbackfn, thisArg = undefined) { } } -// Uncloned functions with `$` prefix are allocated as extended function -// to store the original name in `_SetCanonicalName`. -function $MapEntries() { - return callFunction(std_Map_iterator, this); -} -_SetCanonicalName($MapEntries, "entries"); - var iteratorTemp = { mapIterationResultPair: null }; function MapIteratorNext() { @@ -123,6 +116,8 @@ function MapIteratorNext() { } // ES6 final draft 23.1.2.2. +// Uncloned functions with `$` prefix are allocated as extended function +// to store the original name in `_SetCanonicalName`. function $MapSpecies() { // Step 1. return this; diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 7910f1b8b6..eb2de1cc55 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -304,8 +304,11 @@ static void DestroyRange(JSObject* iterator, Range* range) { } } -bool MapIteratorObject::next(Handle mapIterator, - HandleArrayObject resultPairObj, JSContext* cx) { +bool MapIteratorObject::next(MapIteratorObject* mapIterator, + ArrayObject* resultPairObj) { + // IC code calls this directly. + AutoUnsafeCallWithABI unsafe; + // Check invariants for inlined _GetNextMapEntryForIterator. // The array should be tenured, so that post-barrier can be done simply. @@ -327,18 +330,20 @@ bool MapIteratorObject::next(Handle mapIterator, return true; } + // Note: we don't need to call setDenseElementWithType because + // MapIteratorObject::createResultPair gave the elements unknown-types. switch (mapIterator->kind()) { case MapObject::Keys: - resultPairObj->setDenseElementWithType(cx, 0, range->front().key.get()); + resultPairObj->setDenseElement(0, range->front().key.get()); break; case MapObject::Values: - resultPairObj->setDenseElementWithType(cx, 1, range->front().value); + resultPairObj->setDenseElement(1, range->front().value); break; case MapObject::Entries: { - resultPairObj->setDenseElementWithType(cx, 0, range->front().key.get()); - resultPairObj->setDenseElementWithType(cx, 1, range->front().value); + resultPairObj->setDenseElement(0, range->front().key.get()); + resultPairObj->setDenseElement(1, range->front().value); break; } } @@ -395,7 +400,7 @@ const ClassSpec MapObject::classSpec_ = { MapObject::staticProperties, MapObject::methods, MapObject::properties, -}; + MapObject::finishInit}; const JSClass MapObject::class_ = { "Map", @@ -405,26 +410,52 @@ const JSClass MapObject::class_ = { &MapObject::classOps_, &MapObject::classSpec_}; const JSClass MapObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_Map), JS_NULL_CLASS_OPS, + "Map.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_Map), JS_NULL_CLASS_OPS, &MapObject::classSpec_}; const JSPropertySpec MapObject::properties[] = { JS_PSG("size", size, 0), JS_STRING_SYM_PS(toStringTag, "Map", JSPROP_READONLY), JS_PS_END}; +// clang-format off const JSFunctionSpec MapObject::methods[] = { - JS_FN("get", get, 1, 0), JS_FN("has", has, 1, 0), JS_FN("set", set, 2, 0), - JS_FN("delete", delete_, 1, 0), JS_FN("keys", keys, 0, 0), - JS_FN("values", values, 0, 0), JS_FN("clear", clear, 0, 0), + JS_FN("get", get, 1, 0), + JS_FN("has", has, 1, 0), + JS_FN("set", set, 2, 0), + JS_FN("delete", delete_, 1, 0), + JS_FN("keys", keys, 0, 0), + JS_FN("values", values, 0, 0), + JS_FN("clear", clear, 0, 0), JS_SELF_HOSTED_FN("forEach", "MapForEach", 2, 0), - // MapEntries only exists to preseve the equal identity of - // entries and @@iterator. - JS_SELF_HOSTED_FN("entries", "$MapEntries", 0, 0), - JS_SELF_HOSTED_SYM_FN(iterator, "$MapEntries", 0, 0), JS_FS_END}; + JS_FN("entries", entries, 0, 0), + // @@iterator is re-defined in finishInit so that it has the + // same identity as |entries|. + JS_SYM_FN(iterator, entries, 0, 0), + JS_FS_END +}; +// clang-format on const JSPropertySpec MapObject::staticProperties[] = { JS_SELF_HOSTED_SYM_GET(species, "$MapSpecies", 0), JS_PS_END}; +/* static */ bool MapObject::finishInit(JSContext* cx, HandleObject ctor, + HandleObject proto) { + HandleNativeObject nativeProto = proto.as(); + + RootedValue entriesFn(cx); + RootedId entriesId(cx, NameToId(cx->names().entries)); + if (!NativeGetProperty(cx, nativeProto, entriesId, &entriesFn)) { + return false; + } + + // 23.1.3.12 Map.prototype[@@iterator]() + // The initial value of the @@iterator property is the same function object + // as the initial value of the "entries" property. + RootedId iteratorId( + cx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(cx, JS::SymbolCode::iterator))); + return NativeDefineDataProperty(cx, nativeProto, iteratorId, entriesFn, 0); +} + template static void TraceKey(Range& r, const HashableValue& key, JSTracer* trc) { HashableValue newKey = key.trace(trc); @@ -435,6 +466,9 @@ static void TraceKey(Range& r, const HashableValue& key, JSTracer* trc) { // other types the hash function only uses the bits of the Value. r.rekeyFront(newKey); } + + // Clear newKey to avoid the barrier in ~PreBarriered. + newKey.unbarrieredClear(); } void MapObject::trace(JSTracer* trc, JSObject* obj) { @@ -513,7 +547,7 @@ class js::OrderedHashTableRef : public gc::BufferableRef { }; template -inline static MOZ_MUST_USE bool WriteBarrierPostImpl(ObjectT* obj, +inline static MOZ_MUST_USE bool PostWriteBarrierImpl(ObjectT* obj, const Value& keyValue) { if (MOZ_LIKELY(!keyValue.isObject() && !keyValue.isBigInt())) { MOZ_ASSERT_IF(keyValue.isGCThing(), !IsInsideNursery(keyValue.toGCThing())); @@ -542,14 +576,14 @@ inline static MOZ_MUST_USE bool WriteBarrierPostImpl(ObjectT* obj, return keys->append(keyValue); } -inline static MOZ_MUST_USE bool WriteBarrierPost(MapObject* map, +inline static MOZ_MUST_USE bool PostWriteBarrier(MapObject* map, const Value& key) { - return WriteBarrierPostImpl(map, key); + return PostWriteBarrierImpl(map, key); } -inline static MOZ_MUST_USE bool WriteBarrierPost(SetObject* set, +inline static MOZ_MUST_USE bool PostWriteBarrier(SetObject* set, const Value& key) { - return WriteBarrierPostImpl(set, key); + return PostWriteBarrierImpl(set, key); } bool MapObject::getKeysAndValuesInterleaved( @@ -581,7 +615,7 @@ bool MapObject::set(JSContext* cx, HandleObject obj, HandleValue k, return false; } - if (!WriteBarrierPost(&obj->as(), key.value()) || + if (!PostWriteBarrier(&obj->as(), key.value()) || !map->put(key, v)) { ReportOutOfMemory(cx); return false; @@ -780,7 +814,7 @@ bool MapObject::set_impl(JSContext* cx, const CallArgs& args) { ValueMap& map = extract(args); ARG0_KEY(cx, args, key); - if (!WriteBarrierPost(&args.thisv().toObject().as(), + if (!PostWriteBarrier(&args.thisv().toObject().as(), key.value()) || !map.put(key, args.get(1))) { ReportOutOfMemory(cx); @@ -1071,8 +1105,11 @@ size_t SetIteratorObject::objectMoved(JSObject* obj, JSObject* old) { return sizeof(ValueSet::Range); } -bool SetIteratorObject::next(Handle setIterator, - HandleArrayObject resultObj, JSContext* cx) { +bool SetIteratorObject::next(SetIteratorObject* setIterator, + ArrayObject* resultObj) { + // IC code calls this directly. + AutoUnsafeCallWithABI unsafe; + // Check invariants for inlined _GetNextSetEntryForIterator. // The array should be tenured, so that post-barrier can be done simply. @@ -1094,7 +1131,9 @@ bool SetIteratorObject::next(Handle setIterator, return true; } - resultObj->setDenseElementWithType(cx, 0, range->front().get()); + // Note: we don't need to call setDenseElementWithType because + // SetIteratorObject::createResult gave the elements unknown-types. + resultObj->setDenseElement(0, range->front().get()); range->popFront(); return false; } @@ -1147,7 +1186,7 @@ const ClassSpec SetObject::classSpec_ = { SetObject::staticProperties, SetObject::methods, SetObject::properties, -}; + SetObject::finishInit}; const JSClass SetObject::class_ = { "Set", @@ -1159,27 +1198,58 @@ const JSClass SetObject::class_ = { }; const JSClass SetObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_Set), JS_NULL_CLASS_OPS, + "Set.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_Set), JS_NULL_CLASS_OPS, &SetObject::classSpec_}; const JSPropertySpec SetObject::properties[] = { JS_PSG("size", size, 0), JS_STRING_SYM_PS(toStringTag, "Set", JSPROP_READONLY), JS_PS_END}; +// clang-format off const JSFunctionSpec SetObject::methods[] = { - JS_FN("has", has, 1, 0), JS_FN("add", add, 1, 0), - JS_FN("delete", delete_, 1, 0), JS_FN("entries", entries, 0, 0), + JS_FN("has", has, 1, 0), + JS_FN("add", add, 1, 0), + JS_FN("delete", delete_, 1, 0), + JS_FN("entries", entries, 0, 0), JS_FN("clear", clear, 0, 0), JS_SELF_HOSTED_FN("forEach", "SetForEach", 2, 0), - // SetValues only exists to preseve the equal identity of - // values, keys and @@iterator. - JS_SELF_HOSTED_FN("values", "$SetValues", 0, 0), - JS_SELF_HOSTED_FN("keys", "$SetValues", 0, 0), - JS_SELF_HOSTED_SYM_FN(iterator, "$SetValues", 0, 0), JS_FS_END}; + JS_FN("values", values, 0, 0), + // @@iterator and |keys| re-defined in finishInit so that they have the + // same identity as |values|. + JS_FN("keys", values, 0, 0), + JS_SYM_FN(iterator, values, 0, 0), + JS_FS_END +}; +// clang-format on const JSPropertySpec SetObject::staticProperties[] = { JS_SELF_HOSTED_SYM_GET(species, "$SetSpecies", 0), JS_PS_END}; +/* static */ bool SetObject::finishInit(JSContext* cx, HandleObject ctor, + HandleObject proto) { + HandleNativeObject nativeProto = proto.as(); + + RootedValue valuesFn(cx); + RootedId valuesId(cx, NameToId(cx->names().values)); + if (!NativeGetProperty(cx, nativeProto, valuesId, &valuesFn)) { + return false; + } + + // 23.2.3.8 Set.prototype.keys() + // The initial value of the "keys" property is the same function object + // as the initial value of the "values" property. + RootedId keysId(cx, NameToId(cx->names().keys)); + if (!NativeDefineDataProperty(cx, nativeProto, keysId, valuesFn, 0)) { + return false; + } + + // 23.2.3.11 Set.prototype[@@iterator]() + // See above. + RootedId iteratorId( + cx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(cx, JS::SymbolCode::iterator))); + return NativeDefineDataProperty(cx, nativeProto, iteratorId, valuesFn, 0); +} + bool SetObject::keys(JSContext* cx, HandleObject obj, JS::MutableHandle> keys) { ValueSet* set = obj->as().getData(); @@ -1207,7 +1277,7 @@ bool SetObject::add(JSContext* cx, HandleObject obj, HandleValue k) { return false; } - if (!WriteBarrierPost(&obj->as(), key.value()) || !set->put(key)) { + if (!PostWriteBarrier(&obj->as(), key.value()) || !set->put(key)) { ReportOutOfMemory(cx); return false; } @@ -1320,7 +1390,7 @@ bool SetObject::construct(JSContext* cx, unsigned argc, Value* vp) { if (!key.setValue(cx, keyVal)) { return false; } - if (!WriteBarrierPost(obj, key.value()) || !set->put(key)) { + if (!PostWriteBarrier(obj, key.value()) || !set->put(key)) { ReportOutOfMemory(cx); return false; } @@ -1418,7 +1488,7 @@ bool SetObject::add_impl(JSContext* cx, const CallArgs& args) { ValueSet& set = extract(args); ARG0_KEY(cx, args, key); - if (!WriteBarrierPost(&args.thisv().toObject().as(), + if (!PostWriteBarrier(&args.thisv().toObject().as(), key.value()) || !set.put(key)) { ReportOutOfMemory(cx); diff --git a/js/src/builtin/MapObject.h b/js/src/builtin/MapObject.h index bdc8ec5140..a6f663ac9a 100644 --- a/js/src/builtin/MapObject.h +++ b/js/src/builtin/MapObject.h @@ -54,6 +54,9 @@ class HashableValue { Value get() const { return value.get(); } void trace(JSTracer* trc) { TraceEdge(trc, &value, "HashableValue"); } + + // Clear the value without invoking the pre-barrier. + void unbarrieredClear() { value.unbarrieredSet(UndefinedValue()); } }; template @@ -145,6 +148,9 @@ class MapObject : public NativeObject { static const JSPropertySpec properties[]; static const JSFunctionSpec methods[]; static const JSPropertySpec staticProperties[]; + + static bool finishInit(JSContext* cx, HandleObject ctor, HandleObject proto); + ValueMap* getData() { return static_cast(getPrivate()); } static ValueMap& extract(HandleObject o); static ValueMap& extract(const CallArgs& args); @@ -205,8 +211,8 @@ class MapIteratorObject : public NativeObject { initFixedSlot(KindSlot, JS::Int32Value(int32_t(kind))); } - static MOZ_MUST_USE bool next(Handle mapIterator, - HandleArrayObject resultPairObj, JSContext* cx); + static MOZ_MUST_USE bool next(MapIteratorObject* mapIterator, + ArrayObject* resultPairObj); static JSObject* createResultPair(JSContext* cx); @@ -266,6 +272,8 @@ class SetObject : public NativeObject { static const JSFunctionSpec methods[]; static const JSPropertySpec staticProperties[]; + static bool finishInit(JSContext* cx, HandleObject ctor, HandleObject proto); + ValueSet* getData() { return static_cast(getPrivate()); } static ValueSet& extract(HandleObject o); static ValueSet& extract(const CallArgs& args); @@ -324,8 +332,8 @@ class SetIteratorObject : public NativeObject { initFixedSlot(KindSlot, JS::Int32Value(int32_t(kind))); } - static MOZ_MUST_USE bool next(Handle setIterator, - HandleArrayObject resultObj, JSContext* cx); + static MOZ_MUST_USE bool next(SetIteratorObject* setIterator, + ArrayObject* resultObj); static JSObject* createResult(JSContext* cx); diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js index 7abc42d83d..f28ba83448 100644 --- a/js/src/builtin/Module.js +++ b/js/src/builtin/Module.js @@ -11,7 +11,8 @@ function CallModuleResolveHook(module, specifier, expectedMinimumStatus) return requestedModule; } -// 15.2.1.16.2 GetExportedNames(exportStarSet) +// https://tc39.es/ecma262/#sec-getexportednames +// ES2020 15.2.1.17.2 GetExportedNames function ModuleGetExportedNames(exportStarSet = []) { if (!IsObject(this) || !IsModule(this)) { @@ -19,40 +20,40 @@ function ModuleGetExportedNames(exportStarSet = []) "ModuleGetExportedNames"); } - // Step 1 + // Step 3 let module = this; - // Step 2 + // Step 4 if (callFunction(ArrayIncludes, exportStarSet, module)) return []; - // Step 3 + // Step 5 _DefineDataProperty(exportStarSet, exportStarSet.length, module); - // Step 4 + // Step 6 let exportedNames = []; let namesCount = 0; - // Step 5 + // Step 7 let localExportEntries = module.localExportEntries; for (let i = 0; i < localExportEntries.length; i++) { let e = localExportEntries[i]; _DefineDataProperty(exportedNames, namesCount++, e.exportName); } - // Step 6 + // Step 8 let indirectExportEntries = module.indirectExportEntries; for (let i = 0; i < indirectExportEntries.length; i++) { let e = indirectExportEntries[i]; _DefineDataProperty(exportedNames, namesCount++, e.exportName); } - // Step 7 + // Step 9 let starExportEntries = module.starExportEntries; for (let i = 0; i < starExportEntries.length; i++) { let e = starExportEntries[i]; let requestedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATUS_UNINSTANTIATED); + MODULE_STATUS_UNLINKED); let starNames = callFunction(requestedModule.getExportedNames, requestedModule, exportStarSet); for (let j = 0; j < starNames.length; j++) { @@ -67,21 +68,22 @@ function ModuleGetExportedNames(exportStarSet = []) function ModuleSetStatus(module, newStatus) { - assert(newStatus >= MODULE_STATUS_UNINSTANTIATED && + assert(newStatus >= MODULE_STATUS_UNLINKED && newStatus <= MODULE_STATUS_EVALUATED_ERROR, "Bad new module status in ModuleSetStatus"); // Note that under OOM conditions we can fail the module instantiation // process even after modules have been marked as instantiated. - assert((module.status <= MODULE_STATUS_INSTANTIATED && - newStatus === MODULE_STATUS_UNINSTANTIATED) || + assert((module.status <= MODULE_STATUS_LINKED && + newStatus === MODULE_STATUS_UNLINKED) || newStatus > module.status, "New module status inconsistent with current status"); UnsafeSetReservedSlot(module, MODULE_OBJECT_STATUS_SLOT, newStatus); } -// 15.2.1.16.3 ResolveExport(exportName, resolveSet) +// https://tc39.es/ecma262/#sec-getexportednames +// ES2020 15.2.1.17.3 ResolveExport // // Returns an object describing the location of the resolved export or // indicating a failure. @@ -103,10 +105,10 @@ function ModuleResolveExport(exportName, resolveSet = []) "ModuleResolveExport"); } - // Step 1 + // Step 3 let module = this; - // Step 2 + // Step 4 for (let i = 0; i < resolveSet.length; i++) { let r = resolveSet[i]; if (r.module === module && r.exportName === exportName) { @@ -115,10 +117,10 @@ function ModuleResolveExport(exportName, resolveSet = []) } } - // Step 3 + // Step 5 _DefineDataProperty(resolveSet, resolveSet.length, {module, exportName}); - // Step 4 + // Step 6 let localExportEntries = module.localExportEntries; for (let i = 0; i < localExportEntries.length; i++) { let e = localExportEntries[i]; @@ -126,33 +128,36 @@ function ModuleResolveExport(exportName, resolveSet = []) return {module, bindingName: e.localName}; } - // Step 5 + // Step 7 let indirectExportEntries = module.indirectExportEntries; for (let i = 0; i < indirectExportEntries.length; i++) { let e = indirectExportEntries[i]; if (exportName === e.exportName) { let importedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATUS_UNINSTANTIATED); + MODULE_STATUS_UNLINKED); + if (e.importName === "*") { + return {module: importedModule, bindingName: "*namespace*"}; + } return callFunction(importedModule.resolveExport, importedModule, e.importName, resolveSet); } } - // Step 6 + // Step 8 if (exportName === "default") { // A default export cannot be provided by an export *. return null; } - // Step 7 + // Step 9 let starResolution = null; - // Step 8 + // Step 10 let starExportEntries = module.starExportEntries; for (let i = 0; i < starExportEntries.length; i++) { let e = starExportEntries[i]; let importedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATUS_UNINSTANTIATED); + MODULE_STATUS_UNLINKED); let resolution = callFunction(importedModule.resolveExport, importedModule, exportName, resolveSet); if (resolution === "ambiguous") @@ -170,7 +175,7 @@ function ModuleResolveExport(exportName, resolveSet = []) } } - // Step 9 + // Step 11 return starResolution; } @@ -181,14 +186,15 @@ function IsResolvedBinding(resolution) return typeof resolution === "object" && resolution !== null; } -// 15.2.1.18 GetModuleNamespace(module) +// https://tc39.es/ecma262/#sec-getmodulenamespace +// ES2020 15.2.1.21 GetModuleNamespace function GetModuleNamespace(module) { // Step 1 assert(IsObject(module) && IsModule(module), "GetModuleNamespace called with non-module"); // Step 2 - assert(module.status !== MODULE_STATUS_UNINSTANTIATED, + assert(module.status !== MODULE_STATUS_UNLINKED, "Bad module state in GetModuleNamespace"); // Step 3 @@ -211,31 +217,44 @@ function GetModuleNamespace(module) return namespace; } -// 9.4.6.13 ModuleNamespaceCreate(module, exports) +// https://tc39.es/ecma262/#sec-modulenamespacecreate +// ES2020 9.4.6.11 ModuleNamespaceCreate function ModuleNamespaceCreate(module, exports) { callFunction(ArraySort, exports); let ns = NewModuleNamespace(module, exports); - // Pre-compute all bindings now rather than calling ResolveExport() on every - // access. + // Pre-compute all binding mappings now instead of on each access. + // See: ES2020 9.4.6.7 Module Namespace Exotic Object [[Get]] for (let i = 0; i < exports.length; i++) { let name = exports[i]; let binding = callFunction(module.resolveExport, module, name); assert(IsResolvedBinding(binding), "Failed to resolve binding"); - AddModuleNamespaceBinding(ns, name, binding.module, binding.bindingName); + // ES2020 9.4.6.7 Module Namespace Exotic Object [[Get]], Step 10. + if (binding.bindingName === "*namespace*") { + let namespace = GetModuleNamespace(binding.module); + + // The spec uses an immutable binding here but we have already + // generated bytecode for an indirect binding. Instead, use an + // indirect binding to "*namespace*" slot of the target environment. + EnsureModuleEnvironmentNamespace(binding.module, namespace); + AddModuleNamespaceBinding(ns, name, binding.module, binding.bindingName); + } else { + AddModuleNamespaceBinding(ns, name, binding.module, binding.bindingName); + } } return ns; } + function GetModuleEnvironment(module) { assert(IsObject(module) && IsModule(module), "Non-module passed to GetModuleEnvironment"); - assert(module.status >= MODULE_STATUS_INSTANTIATING, - "Attempt to access module environement before instantation"); + assert(module.status >= MODULE_STATUS_LINKING, + "Attempt to access module environement before linking"); let env = UnsafeGetReservedSlot(module, MODULE_OBJECT_ENVIRONMENT_SLOT); assert(IsObject(env) && IsModuleEnvironment(env), @@ -265,10 +284,10 @@ function ArrayContains(array, value) function HandleModuleInstantiationFailure(module) { - // Reset the module to the "uninstantiated" state. Don't reset the + // Reset the module to the "unlinked" state. Don't reset the // environment slot as the environment object will be required by any // possible future instantiation attempt. - ModuleSetStatus(module, MODULE_STATUS_UNINSTANTIATED); + ModuleSetStatus(module, MODULE_STATUS_UNLINKED); UnsafeSetReservedSlot(module, MODULE_OBJECT_DFS_INDEX_SLOT, undefined); UnsafeSetReservedSlot(module, MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT, undefined); } @@ -283,7 +302,7 @@ function ModuleInstantiate() let module = this; // Step 2 - if (module.status === MODULE_STATUS_INSTANTIATING || + if (module.status === MODULE_STATUS_LINKING || module.status === MODULE_STATUS_EVALUATING) { ThrowInternalError(JSMSG_BAD_MODULE_STATUS); @@ -294,92 +313,104 @@ function ModuleInstantiate() // Steps 4-5 try { - InnerModuleInstantiation(module, stack, 0); + InnerModuleLinking(module, stack, 0); } catch (error) { for (let i = 0; i < stack.length; i++) { let m = stack[i]; - if (m.status === MODULE_STATUS_INSTANTIATING) { + if (m.status === MODULE_STATUS_LINKING) { HandleModuleInstantiationFailure(m); } } // Handle OOM when appending to the stack or over-recursion errors. - if (stack.length === 0 && module.status === MODULE_STATUS_INSTANTIATING) { + if (stack.length === 0 && module.status === MODULE_STATUS_LINKING) { HandleModuleInstantiationFailure(module); } - assert(module.status !== MODULE_STATUS_INSTANTIATING, - "Expected uninstantiated status after failed instantiation"); + assert(module.status !== MODULE_STATUS_LINKING, + "Expected unlinked status after failed linking"); throw error; } // Step 6 - assert(module.status === MODULE_STATUS_INSTANTIATED || + assert(module.status === MODULE_STATUS_LINKED || module.status === MODULE_STATUS_EVALUATED || module.status === MODULE_STATUS_EVALUATED_ERROR, - "Bad module status after successful instantiation"); + "Bad module status after successful linking"); // Step 7 assert(stack.length === 0, - "Stack should be empty after successful instantiation"); + "Stack should be empty after successful linking"); // Step 8 return undefined; } -// 15.2.1.16.4.1 InnerModuleInstantiation(module, stack, index) -function InnerModuleInstantiation(module, stack, index) +// https://tc39.es/ecma262/#sec-InnerModuleLinking +// ES2020 15.2.1.16.1.1 InnerModuleLinking +function InnerModuleLinking(module, stack, index) { // Step 1 - // TODO: Support module records other than source text module records. + // TODO: Support module records other than Cyclic Module Records. + // 1. If module is not a Cyclic Module Record, then + // a. Perform ? module.Link(). + // b. Return index. // Step 2 - if (module.status === MODULE_STATUS_INSTANTIATING || - module.status === MODULE_STATUS_INSTANTIATED || + if (module.status === MODULE_STATUS_LINKING || + module.status === MODULE_STATUS_LINKED || module.status === MODULE_STATUS_EVALUATED || module.status === MODULE_STATUS_EVALUATED_ERROR) { return index; } - // Step 3 - if (module.status !== MODULE_STATUS_UNINSTANTIATED) + // Step 3. Assert: module.[[Status]] is unlinked. + if (module.status !== MODULE_STATUS_UNLINKED) ThrowInternalError(JSMSG_BAD_MODULE_STATUS); - // Steps 4 - ModuleSetStatus(module, MODULE_STATUS_INSTANTIATING); + // Step 4. Set module.[[Status]] to linking. + ModuleSetStatus(module, MODULE_STATUS_LINKING); - // Step 5-7 + // Step 5. Set module.[[DFSIndex]] to index. UnsafeSetReservedSlot(module, MODULE_OBJECT_DFS_INDEX_SLOT, index); + // Step 6. Set module.[[DFSAncestorIndex]] to index. UnsafeSetReservedSlot(module, MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT, index); + // Step 7. Set index to index + 1. index++; - // Step 8 + // Step 8. Append module to stack. _DefineDataProperty(stack, stack.length, module); - // Step 9 + // Step 9. For each String required that is an element of module.[[RequestedModules]], do let requestedModules = module.requestedModules; for (let i = 0; i < requestedModules.length; i++) { + // Step 9.a let required = requestedModules[i].moduleSpecifier; - let requiredModule = CallModuleResolveHook(module, required, MODULE_STATUS_UNINSTANTIATED); + let requiredModule = CallModuleResolveHook(module, required, MODULE_STATUS_UNLINKED); - index = InnerModuleInstantiation(requiredModule, stack, index); + // Step 9.b + index = InnerModuleLinking(requiredModule, stack, index); - assert(requiredModule.status === MODULE_STATUS_INSTANTIATING || - requiredModule.status === MODULE_STATUS_INSTANTIATED || + // TODO: Check if requiredModule is a Cyclic Module Record + // Step 9.c.i + assert(requiredModule.status === MODULE_STATUS_LINKING || + requiredModule.status === MODULE_STATUS_LINKED || requiredModule.status === MODULE_STATUS_EVALUATED || requiredModule.status === MODULE_STATUS_EVALUATED_ERROR, - "Bad required module status after InnerModuleInstantiation"); + "Bad required module status after InnerModuleLinking"); - assert((requiredModule.status === MODULE_STATUS_INSTANTIATING) === + // Step 9.c.ii + assert((requiredModule.status === MODULE_STATUS_LINKING) === ArrayContains(stack, requiredModule), "Required module should be in the stack iff it is currently being instantiated"); assert(typeof requiredModule.dfsIndex === "number", "Bad dfsIndex"); assert(typeof requiredModule.dfsAncestorIndex === "number", "Bad dfsAncestorIndex"); - if (requiredModule.status === MODULE_STATUS_INSTANTIATING) { + // Step 9.c.iii + if (requiredModule.status === MODULE_STATUS_LINKING) { UnsafeSetReservedSlot(module, MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT, std_Math_min(module.dfsAncestorIndex, requiredModule.dfsAncestorIndex)); @@ -387,11 +418,12 @@ function InnerModuleInstantiation(module, stack, index) } // Step 10 - ModuleDeclarationEnvironmentSetup(module); + callFunction(InitializeEnvironment, module); - // Steps 11-12 + // Step 11 assert(CountArrayValues(stack, module) === 1, "Current module should appear exactly once in the stack"); + // Step 12 assert(module.dfsAncestorIndex <= module.dfsIndex, "Bad DFS ancestor index"); @@ -399,19 +431,26 @@ function InnerModuleInstantiation(module, stack, index) if (module.dfsAncestorIndex === module.dfsIndex) { let requiredModule; do { + // 13.b.i-ii requiredModule = callFunction(std_Array_pop, stack); - ModuleSetStatus(requiredModule, MODULE_STATUS_INSTANTIATED); + // TODO: 13.b.ii. Assert: requiredModule is a Cyclic Module Record. + // Step 13.b.iv + ModuleSetStatus(requiredModule, MODULE_STATUS_LINKED); } while (requiredModule !== module); } - // Step 15 + // Step 14 return index; } -// 15.2.1.16.4.2 ModuleDeclarationEnvironmentSetup(module) -function ModuleDeclarationEnvironmentSetup(module) +// https://tc39.es/ecma262/#sec-source-text-module-record-initialize-environment +// ES2020 15.2.1.17.4 InitializeEnvironment +function InitializeEnvironment() { // Step 1 + let module = this; + + // Step 2-3 let indirectExportEntries = module.indirectExportEntries; for (let i = 0; i < indirectExportEntries.length; i++) { let e = indirectExportEntries[i]; @@ -422,16 +461,20 @@ function ModuleDeclarationEnvironmentSetup(module) } } - // Steps 5-6 + // Omitting steps 4-5, for practical purposes it is impossible for a realm to be + // undefined at this point. + + // Step 6-8 // Note that we have already created the environment by this point. let env = GetModuleEnvironment(module); - // Step 8 + // Step 9 let importEntries = module.importEntries; for (let i = 0; i < importEntries.length; i++) { let imp = importEntries[i]; let importedModule = CallModuleResolveHook(module, imp.moduleRequest, - MODULE_STATUS_INSTANTIATING); + MODULE_STATUS_LINKING); + // Step 9.c-9.d if (imp.importName === "*") { let namespace = GetModuleNamespace(importedModule); CreateNamespaceBinding(env, imp.localName, namespace); @@ -443,16 +486,38 @@ function ModuleDeclarationEnvironmentSetup(module) imp.lineNumber, imp.columnNumber); } - CreateImportBinding(env, imp.localName, resolution.module, resolution.bindingName); + if (resolution.bindingName === "*namespace*") { + let namespace = GetModuleNamespace(resolution.module); + + // This should be CreateNamespaceBinding, but we have already + // generated bytecode assuming an indirect binding. Instead, + // ensure a special "*namespace*"" binding exists on the target + // module's environment. We then generate an indirect binding to + // this synthetic binding. + EnsureModuleEnvironmentNamespace(resolution.module, namespace); + CreateImportBinding(env, imp.localName, resolution.module, + resolution.bindingName); + } else { + CreateImportBinding(env, imp.localName, resolution.module, + resolution.bindingName); + } } } + // Steps 10-26 + // Some of these do not need to happen for practical purposes. For steps 21-23, the bindings + // that can be handled in a similar way to regulars scripts are done separately. Function + // Declarations are special due to hoisting and are handled within this function. + // See ModuleScope and ModuleEnvironmentObject for further details. + + // Step 24.a.iii is handled here. + // In order to have the functions correctly hoisted we need to do this separately. InstantiateModuleFunctionDeclarations(module); } function ThrowResolutionError(module, resolution, kind, name, line, column) { - assert(module.status === MODULE_STATUS_INSTANTIATING, + assert(module.status === MODULE_STATUS_LINKING, "Unexpected module status in ThrowResolutionError"); assert(kind === "import" || kind === "indirectExport", @@ -502,27 +567,28 @@ function RecordModuleEvaluationError(module, error) UnsafeSetReservedSlot(module, MODULE_OBJECT_EVALUATION_ERROR_SLOT, error); } -// 15.2.1.16.5 ModuleEvaluate() +// https://tc39.es/ecma262/#sec-moduleevaluation +// ES2020 15.2.1.16.2 ModuleEvaluate function ModuleEvaluate() { if (!IsObject(this) || !IsModule(this)) return callFunction(CallModuleMethodIfWrapped, this, "ModuleEvaluate"); - // Step 1 + // Step 2 let module = this; - // Step 2 - if (module.status !== MODULE_STATUS_INSTANTIATED && + // Step 3 + if (module.status !== MODULE_STATUS_LINKED && module.status !== MODULE_STATUS_EVALUATED && module.status !== MODULE_STATUS_EVALUATED_ERROR) { ThrowInternalError(JSMSG_BAD_MODULE_STATUS); } - // Step 3 + // Step 4 let stack = []; - // Steps 4-5 + // Steps 5-6 try { InnerModuleEvaluation(module, stack, 0); } catch (error) { @@ -543,19 +609,22 @@ function ModuleEvaluate() throw error; } + // Steps 7-8 assert(module.status === MODULE_STATUS_EVALUATED, "Bad module status after successful evaluation"); assert(stack.length === 0, "Stack should be empty after successful evaluation"); + // Step 9 return undefined; } -// 15.2.1.16.5.1 InnerModuleEvaluation(module, stack, index) +// https://tc39.es/ecma262/#sec-innermoduleevaluation +// ES2020 15.2.1.16.2.1 InnerModuleEvaluation function InnerModuleEvaluation(module, stack, index) { // Step 1 - // TODO: Support module records other than source text module records. + // TODO: Support module records other than Cyclic Module Records. // Step 2 if (module.status === MODULE_STATUS_EVALUATED_ERROR) @@ -569,7 +638,7 @@ function InnerModuleEvaluation(module, stack, index) return index; // Step 4 - assert(module.status === MODULE_STATUS_INSTANTIATED, + assert(module.status === MODULE_STATUS_LINKED, "Bad module status in InnerModuleEvaluation"); // Step 5 @@ -588,7 +657,7 @@ function InnerModuleEvaluation(module, stack, index) for (let i = 0; i < requestedModules.length; i++) { let required = requestedModules[i].moduleSpecifier; let requiredModule = - CallModuleResolveHook(module, required, MODULE_STATUS_INSTANTIATED); + CallModuleResolveHook(module, required, MODULE_STATUS_LINKED); index = InnerModuleEvaluation(requiredModule, stack, index); diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 01b3f1b3d4..fa9d367208 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -24,15 +24,17 @@ #include "vm/PlainObject.h" // js::PlainObject #include "vm/PromiseObject.h" // js::PromiseObject #include "vm/SelfHosting.h" +#include "vm/SharedStencil.h" // js::GCThingIndex #include "vm/JSObject-inl.h" #include "vm/JSScript-inl.h" +#include "vm/NativeObject-inl.h" using namespace js; -static_assert(MODULE_STATUS_UNINSTANTIATED < MODULE_STATUS_INSTANTIATING && - MODULE_STATUS_INSTANTIATING < MODULE_STATUS_INSTANTIATED && - MODULE_STATUS_INSTANTIATED < MODULE_STATUS_EVALUATED && +static_assert(MODULE_STATUS_UNLINKED < MODULE_STATUS_LINKING && + MODULE_STATUS_LINKING < MODULE_STATUS_LINKED && + MODULE_STATUS_LINKED < MODULE_STATUS_EVALUATED && MODULE_STATUS_EVALUATED < MODULE_STATUS_EVALUATED_ERROR, "Module statuses are ordered incorrectly"); @@ -687,16 +689,6 @@ void ModuleNamespaceObject::ProxyHandler::finalize(JSFreeOp* fop, } } -/////////////////////////////////////////////////////////////////////////// -// FunctionDeclaration - -FunctionDeclaration::FunctionDeclaration(HandleAtom name, uint32_t funIndex) - : name(name), funIndex(funIndex) {} - -void FunctionDeclaration::trace(JSTracer* trc) { - TraceEdge(trc, &name, "FunctionDeclaration name"); -} - /////////////////////////////////////////////////////////////////////////// // ModuleObject @@ -760,7 +752,8 @@ ModuleObject* ModuleObject::create(JSContext* cx) { InitReservedSlot(self, ImportBindingsSlot, bindings, MemoryUse::ModuleBindingMap); - FunctionDeclarationVector* funDecls = cx->new_(); + frontend::FunctionDeclarationVector* funDecls = + cx->new_(); if (!funDecls) { return nullptr; } @@ -776,7 +769,8 @@ void ModuleObject::finalize(JSFreeOp* fop, JSObject* obj) { if (self->hasImportBindings()) { fop->delete_(obj, &self->importBindings(), MemoryUse::ModuleBindingMap); } - if (FunctionDeclarationVector* funDecls = self->functionDeclarations()) { + if (frontend::FunctionDeclarationVector* funDecls = + self->functionDeclarations()) { // Not tracked as these may move between zones on merge. fop->deleteUntracked(funDecls); } @@ -793,7 +787,7 @@ ModuleEnvironmentObject* ModuleObject::environment() const { // According to the spec the environment record is created during // instantiation, but we create it earlier than that. - if (status() < MODULE_STATUS_INSTANTIATED) { + if (status() < MODULE_STATUS_LINKED) { return nullptr; } @@ -824,13 +818,18 @@ ScriptSourceObject* ModuleObject::scriptSourceObject() const { .as(); } -FunctionDeclarationVector* ModuleObject::functionDeclarations() { +frontend::FunctionDeclarationVector* ModuleObject::functionDeclarations() { Value value = getReservedSlot(FunctionDeclarationsSlot); if (value.isUndefined()) { return nullptr; } - return static_cast(value.toPrivate()); + return static_cast(value.toPrivate()); +} + +void ModuleObject::initFunctionDeclarations( + frontend::FunctionDeclarationVector&& decls) { + *functionDeclarations() = std::move(decls); } void ModuleObject::initScriptSlots(HandleScript script) { @@ -846,7 +845,7 @@ void ModuleObject::setInitialEnvironment( } void ModuleObject::initStatusSlot() { - initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED)); + initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNLINKED)); } void ModuleObject::initImportExportData(HandleArrayObject requestedModules, @@ -947,7 +946,7 @@ JSScript* ModuleObject::script() const { } static inline void AssertValidModuleStatus(ModuleStatus status) { - MOZ_ASSERT(status >= MODULE_STATUS_UNINSTANTIATED && + MOZ_ASSERT(status >= MODULE_STATUS_UNLINKED && status <= MODULE_STATUS_EVALUATED_ERROR); } @@ -993,35 +992,19 @@ void ModuleObject::trace(JSTracer* trc, JSObject* obj) { if (module.hasImportBindings()) { module.importBindings().trace(trc); } - - if (FunctionDeclarationVector* funDecls = module.functionDeclarations()) { - funDecls->trace(trc); - } -} - -bool ModuleObject::noteFunctionDeclaration(JSContext* cx, HandleAtom name, - uint32_t funIndex) { - FunctionDeclarationVector* funDecls = functionDeclarations(); - if (!funDecls->emplaceBack(name, funIndex)) { - ReportOutOfMemory(cx); - return false; - } - - return true; } /* static */ bool ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self) { #ifdef DEBUG - MOZ_ASSERT(self->status() == MODULE_STATUS_INSTANTIATING); + MOZ_ASSERT(self->status() == MODULE_STATUS_LINKING); if (!AssertFrozen(cx, self)) { return false; } #endif - // |self| initially manages this vector. - FunctionDeclarationVector* funDecls = self->functionDeclarations(); + frontend::FunctionDeclarationVector* funDecls = self->functionDeclarations(); if (!funDecls) { JS_ReportErrorASCII( cx, "Module function declarations have already been instantiated"); @@ -1032,16 +1015,18 @@ bool ModuleObject::instantiateFunctionDeclarations(JSContext* cx, RootedObject obj(cx); RootedValue value(cx); RootedFunction fun(cx); - for (const auto& funDecl : *funDecls) { - uint32_t funIndex = funDecl.funIndex; + RootedPropertyName name(cx); + + for (GCThingIndex funIndex : *funDecls) { fun.set(self->script()->getFunction(funIndex)); obj = Lambda(cx, fun, env); if (!obj) { return false; } + name = fun->explicitName()->asPropertyName(); value = ObjectValue(*obj); - if (!SetProperty(cx, env, funDecl.name->asPropertyName(), value)) { + if (!SetProperty(cx, env, name, value)) { return false; } } @@ -1211,49 +1196,69 @@ ModuleBuilder::ModuleBuilder(JSContext* cx, const frontend::EitherParser& eitherParser) : cx_(cx), eitherParser_(eitherParser), - requestedModuleSpecifiers_(cx, AtomSet(cx)), - requestedModules_(cx, RequestedModuleVector(cx)), - importEntries_(cx, ImportEntryMap(cx)), - exportEntries_(cx, ExportEntryVector(cx)), - exportNames_(cx, AtomSet(cx)), - localExportEntries_(cx, ExportEntryVector(cx)), - indirectExportEntries_(cx, ExportEntryVector(cx)), - starExportEntries_(cx, ExportEntryVector(cx)) {} - -bool ModuleBuilder::buildTables() { - for (const auto& e : exportEntries_) { - RootedExportEntryObject exp(cx_, e); - if (!exp->moduleRequest()) { - RootedImportEntryObject importEntry(cx_, - importEntryFor(exp->localName())); + requestedModuleSpecifiers_(cx), + importEntries_(cx), + exportEntries_(cx), + exportNames_(cx) {} + +bool ModuleBuilder::noteFunctionDeclaration(JSContext* cx, uint32_t funIndex) { + if (!functionDecls_.emplaceBack(funIndex)) { + js::ReportOutOfMemory(cx); + return false; + } + return true; +} + +bool ModuleBuilder::buildTables(frontend::StencilModuleMetadata& metadata) { + // https://tc39.es/ecma262/#sec-parsemodule + // 15.2.1.17.1 ParseModule, Steps 4-11. + + // Step 4. + metadata.requestedModules = std::move(requestedModules_); + + // Step 5. + if (!metadata.importEntries.reserve(importEntries_.count())) { + js::ReportOutOfMemory(cx_); + return false; + } + for (auto r = importEntries_.all(); !r.empty(); r.popFront()) { + frontend::StencilModuleEntry& entry = r.front().value(); + metadata.importEntries.infallibleAppend(entry); + } + + // Steps 6-11. + for (const frontend::StencilModuleEntry& exp : exportEntries_) { + if (!exp.specifier) { + frontend::StencilModuleEntry* importEntry = importEntryFor(exp.localName); if (!importEntry) { - if (!localExportEntries_.append(exp)) { + if (!metadata.localExportEntries.append(exp)) { + js::ReportOutOfMemory(cx_); return false; } } else { - if (importEntry->importName() == cx_->names().star) { - if (!localExportEntries_.append(exp)) { + if (importEntry->importName == cx_->parserNames().star) { + if (!metadata.localExportEntries.append(exp)) { + js::ReportOutOfMemory(cx_); return false; } } else { - RootedAtom exportName(cx_, exp->exportName()); - RootedAtom moduleRequest(cx_, importEntry->moduleRequest()); - RootedAtom importName(cx_, importEntry->importName()); - RootedExportEntryObject exportEntry(cx_); - exportEntry = ExportEntryObject::create( - cx_, exportName, moduleRequest, importName, nullptr, - exp->lineNumber(), exp->columnNumber()); - if (!exportEntry || !indirectExportEntries_.append(exportEntry)) { + auto entry = frontend::StencilModuleEntry::exportFromEntry( + importEntry->specifier, importEntry->importName, exp.exportName, + exp.lineno, exp.column); + if (!metadata.indirectExportEntries.append(entry)) { + js::ReportOutOfMemory(cx_); return false; } } } - } else if (exp->importName() == cx_->names().star) { - if (!starExportEntries_.append(exp)) { + } else if (exp.importName == cx_->parserNames().star && !exp.exportName) { + if (!metadata.starExportEntries.append(exp)) { + js::ReportOutOfMemory(cx_); return false; } } else { - if (!indirectExportEntries_.append(exp)) { + if (!metadata.indirectExportEntries.append(exp)) { + js::ReportOutOfMemory(cx_); return false; } } @@ -1262,39 +1267,145 @@ bool ModuleBuilder::buildTables() { return true; } -bool ModuleBuilder::initModule(JS::Handle module) { - RootedArrayObject requestedModules(cx_, - js::CreateArray(cx_, requestedModules_)); - if (!requestedModules) { +void ModuleBuilder::finishFunctionDecls( + frontend::StencilModuleMetadata& metadata) { + metadata.functionDecls = std::move(functionDecls_); +} + +enum class ModuleArrayType { + ImportEntryObject, + ExportEntryObject, + RequestedModuleObject, +}; + +static ArrayObject* ModuleBuilderInitArray( + JSContext* cx, frontend::CompilationInfo& compilationInfo, + ModuleArrayType arrayType, + const frontend::StencilModuleMetadata::EntryVector& vector) { + RootedArrayObject resultArray( + cx, NewDenseFullyAllocatedArray(cx, vector.length())); + if (!resultArray) { + return nullptr; + } + + resultArray->ensureDenseInitializedLength(cx, 0, vector.length()); + + RootedAtom specifier(cx); + RootedAtom localName(cx); + RootedAtom importName(cx); + RootedAtom exportName(cx); + RootedObject req(cx); + + for (uint32_t i = 0; i < vector.length(); ++i) { + const frontend::StencilModuleEntry& entry = vector[i]; + + if (entry.specifier) { + specifier = compilationInfo.liftParserAtomToJSAtom(cx, entry.specifier); + if (!specifier) { + return nullptr; + } + } + + if (entry.localName) { + localName = compilationInfo.liftParserAtomToJSAtom(cx, entry.localName); + if (!localName) { + return nullptr; + } + } + + if (entry.importName) { + importName = compilationInfo.liftParserAtomToJSAtom(cx, entry.importName); + if (!importName) { + return nullptr; + } + } + + if (entry.exportName) { + exportName = compilationInfo.liftParserAtomToJSAtom(cx, entry.exportName); + if (!exportName) { + return nullptr; + } + } + + switch (arrayType) { + case ModuleArrayType::ImportEntryObject: + MOZ_ASSERT(localName && importName); + req = ImportEntryObject::create(cx, specifier, importName, localName, + entry.lineno, entry.column); + break; + case ModuleArrayType::ExportEntryObject: + MOZ_ASSERT(localName || importName || exportName); + req = ExportEntryObject::create(cx, exportName, specifier, importName, + localName, entry.lineno, entry.column); + break; + case ModuleArrayType::RequestedModuleObject: + req = RequestedModuleObject::create(cx, specifier, entry.lineno, + entry.column); + // TODO: Make this consistent with other object types. + if (req && !FreezeObject(cx, req)) { + return nullptr; + } + break; + } + if (!req) { + return nullptr; + } + resultArray->initDenseElement(i, ObjectValue(*req)); + } + + return resultArray; +} + +// Use StencilModuleMetadata data to fill in ModuleObject +bool frontend::StencilModuleMetadata::initModule( + JSContext* cx, frontend::CompilationInfo& compilationInfo, + JS::Handle module) { + RootedArrayObject requestedModulesObject( + cx, ModuleBuilderInitArray(cx, compilationInfo, + ModuleArrayType::RequestedModuleObject, + requestedModules)); + if (!requestedModulesObject) { return false; } - RootedArrayObject importEntries(cx_, createArrayFromHashMap(importEntries_)); - if (!importEntries) { + RootedArrayObject importEntriesObject( + cx, ModuleBuilderInitArray(cx, compilationInfo, + ModuleArrayType::ImportEntryObject, + importEntries)); + if (!importEntriesObject) { return false; } - RootedArrayObject localExportEntries( - cx_, js::CreateArray(cx_, localExportEntries_)); - if (!localExportEntries) { + RootedArrayObject localExportEntriesObject( + cx, ModuleBuilderInitArray(cx, compilationInfo, + ModuleArrayType::ExportEntryObject, + localExportEntries)); + if (!localExportEntriesObject) { return false; } - RootedArrayObject indirectExportEntries( - cx_, js::CreateArray(cx_, indirectExportEntries_)); - if (!indirectExportEntries) { + RootedArrayObject indirectExportEntriesObject( + cx, ModuleBuilderInitArray(cx, compilationInfo, + ModuleArrayType::ExportEntryObject, + indirectExportEntries)); + if (!indirectExportEntriesObject) { return false; } - RootedArrayObject starExportEntries(cx_, - js::CreateArray(cx_, starExportEntries_)); - if (!starExportEntries) { + RootedArrayObject starExportEntriesObject( + cx, ModuleBuilderInitArray(cx, compilationInfo, + ModuleArrayType::ExportEntryObject, + starExportEntries)); + if (!starExportEntriesObject) { return false; } - module->initImportExportData(requestedModules, importEntries, - localExportEntries, indirectExportEntries, - starExportEntries); + // Transfer the vector of declarations to the ModuleObject. + module->initFunctionDeclarations(std::move(functionDecls)); + + module->initImportExportData( + requestedModulesObject, importEntriesObject, localExportEntriesObject, + indirectExportEntriesObject, starExportEntriesObject); return true; } @@ -1310,33 +1421,29 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) { NameNode* moduleSpec = &importNode->right()->as(); MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr)); - RootedAtom module(cx_, moduleSpec->atom()); + const ParserAtom* module = moduleSpec->atom(); if (!maybeAppendRequestedModule(module, moduleSpec)) { return false; } - RootedAtom importName(cx_); - RootedAtom localName(cx_); for (ParseNode* item : specList->contents()) { BinaryNode* spec = &item->as(); MOZ_ASSERT(spec->isKind(ParseNodeKind::ImportSpec)); NameNode* importNameNode = &spec->left()->as(); - NameNode* localNameNode = &spec->right()->as(); - importName = importNameNode->atom(); - localName = localNameNode->atom(); + const ParserAtom* importName = importNameNode->atom(); + const ParserAtom* localName = localNameNode->atom(); uint32_t line; uint32_t column; eitherParser_.computeLineAndColumn(importNameNode->pn_pos.begin, &line, &column); - RootedImportEntryObject importEntry(cx_); - importEntry = ImportEntryObject::create(cx_, module, importName, localName, - line, column); - if (!importEntry || !appendImportEntryObject(importEntry)) { + auto entry = frontend::StencilModuleEntry::importEntry( + module, localName, importName, line, column); + if (!importEntries_.put(localName, entry)) { return false; } } @@ -1344,12 +1451,6 @@ bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) { return true; } -bool ModuleBuilder::appendImportEntryObject( - HandleImportEntryObject importEntry) { - MOZ_ASSERT(importEntry->localName()); - return importEntries_.put(importEntry->localName(), importEntry); -} - bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { using namespace js::frontend; @@ -1362,24 +1463,24 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { if (isDefault && exportNode->as().right()) { // This is an export default containing an expression. - HandlePropertyName localName = cx_->names().default_; - HandlePropertyName exportName = cx_->names().default_; + const ParserAtom* localName = cx_->parserNames().default_; + const ParserAtom* exportName = cx_->parserNames().default_; return appendExportEntry(exportName, localName); } switch (kid->getKind()) { case ParseNodeKind::ExportSpecList: { MOZ_ASSERT(!isDefault); - RootedAtom localName(cx_); - RootedAtom exportName(cx_); for (ParseNode* item : kid->as().contents()) { BinaryNode* spec = &item->as(); MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportSpec)); NameNode* localNameNode = &spec->left()->as(); NameNode* exportNameNode = &spec->right()->as(); - localName = localNameNode->atom(); - exportName = exportNameNode->atom(); + + const ParserAtom* localName = localNameNode->atom(); + const ParserAtom* exportName = exportNameNode->atom(); + if (!appendExportEntry(exportName, localName, spec)) { return false; } @@ -1390,9 +1491,10 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { case ParseNodeKind::ClassDecl: { const ClassNode& cls = kid->as(); MOZ_ASSERT(cls.names()); - RootedAtom localName(cx_, cls.names()->innerBinding()->atom()); - RootedAtom exportName( - cx_, isDefault ? cx_->names().default_ : localName.get()); + const frontend::ParserAtom* localName = + cls.names()->innerBinding()->atom(); + const frontend::ParserAtom* exportName = + isDefault ? cx_->parserNames().default_ : localName; if (!appendExportEntry(exportName, localName)) { return false; } @@ -1402,8 +1504,6 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { case ParseNodeKind::VarStmt: case ParseNodeKind::ConstDecl: case ParseNodeKind::LetDecl: { - RootedAtom localName(cx_); - RootedAtom exportName(cx_); for (ParseNode* binding : kid->as().contents()) { if (binding->isKind(ParseNodeKind::AssignExpr)) { binding = binding->as().left(); @@ -1412,8 +1512,10 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { } if (binding->isKind(ParseNodeKind::Name)) { - localName = binding->as().atom(); - exportName = isDefault ? cx_->names().default_ : localName.get(); + const frontend::ParserAtom* localName = + binding->as().atom(); + const frontend::ParserAtom* exportName = + isDefault ? cx_->parserNames().default_ : localName; if (!appendExportEntry(exportName, localName)) { return false; } @@ -1434,10 +1536,9 @@ bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) { case ParseNodeKind::Function: { FunctionBox* box = kid->as().funbox(); MOZ_ASSERT(!box->isArrow()); - RootedAtom localName(cx_, box->explicitName()); - RootedAtom exportName( - cx_, isDefault ? cx_->names().default_ : localName.get()); - MOZ_ASSERT_IF(isDefault, localName); + const frontend::ParserAtom* localName = box->explicitName(); + const frontend::ParserAtom* exportName = + isDefault ? cx_->parserNames().default_ : localName; if (!appendExportEntry(exportName, localName)) { return false; } @@ -1455,7 +1556,7 @@ bool ModuleBuilder::processExportBinding(frontend::ParseNode* binding) { using namespace js::frontend; if (binding->isKind(ParseNodeKind::Name)) { - RootedAtom name(cx_, binding->as().atom()); + const frontend::ParserAtom* name = binding->as().atom(); return appendExportEntry(name, name); } @@ -1536,27 +1637,28 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) { NameNode* moduleSpec = &exportNode->right()->as(); MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr)); - RootedAtom module(cx_, moduleSpec->atom()); + const frontend::ParserAtom* module = moduleSpec->atom(); + if (!maybeAppendRequestedModule(module, moduleSpec)) { return false; } - RootedAtom bindingName(cx_); - RootedAtom exportName(cx_); for (ParseNode* spec : specList->contents()) { if (spec->isKind(ParseNodeKind::ExportSpec)) { NameNode* localNameNode = &spec->as().left()->as(); NameNode* exportNameNode = &spec->as().right()->as(); - bindingName = localNameNode->atom(); - exportName = exportNameNode->atom(); + + const frontend::ParserAtom* bindingName = localNameNode->atom(); + const frontend::ParserAtom* exportName = exportNameNode->atom(); + if (!appendExportFromEntry(exportName, module, bindingName, localNameNode)) { return false; } } else { MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt)); - exportName = cx_->names().star; + const frontend::ParserAtom* exportName = cx_->parserNames().star; if (!appendExportFromEntry(nullptr, module, exportName, spec)) { return false; } @@ -1566,23 +1668,24 @@ bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) { return true; } -ImportEntryObject* ModuleBuilder::importEntryFor(JSAtom* localName) const { +frontend::StencilModuleEntry* ModuleBuilder::importEntryFor( + const frontend::ParserAtom* localName) const { MOZ_ASSERT(localName); auto ptr = importEntries_.lookup(localName); if (!ptr) { return nullptr; } - return ptr->value(); + return &ptr->value(); } -bool ModuleBuilder::hasExportedName(JSAtom* name) const { +bool ModuleBuilder::hasExportedName(const frontend::ParserAtom* name) const { MOZ_ASSERT(name); return exportNames_.has(name); } -bool ModuleBuilder::appendExportEntry(HandleAtom exportName, - HandleAtom localName, +bool ModuleBuilder::appendExportEntry(const frontend::ParserAtom* exportName, + const frontend::ParserAtom* localName, frontend::ParseNode* node) { uint32_t line = 0; uint32_t column = 0; @@ -1590,38 +1693,40 @@ bool ModuleBuilder::appendExportEntry(HandleAtom exportName, eitherParser_.computeLineAndColumn(node->pn_pos.begin, &line, &column); } - Rooted exportEntry(cx_); - exportEntry = ExportEntryObject::create(cx_, exportName, nullptr, nullptr, - localName, line, column); - return exportEntry && appendExportEntryObject(exportEntry); + auto entry = frontend::StencilModuleEntry::exportAsEntry( + localName, exportName, line, column); + if (!exportEntries_.append(entry)) { + return false; + } + + if (exportName) { + if (!exportNames_.put(exportName)) { + return false; + } + } + + return true; } -bool ModuleBuilder::appendExportFromEntry(HandleAtom exportName, - HandleAtom moduleRequest, - HandleAtom importName, - frontend::ParseNode* node) { +bool ModuleBuilder::appendExportFromEntry( + const frontend::ParserAtom* exportName, + const frontend::ParserAtom* moduleRequest, + const frontend::ParserAtom* importName, frontend::ParseNode* node) { uint32_t line; uint32_t column; eitherParser_.computeLineAndColumn(node->pn_pos.begin, &line, &column); - Rooted exportEntry(cx_); - exportEntry = ExportEntryObject::create(cx_, exportName, moduleRequest, - importName, nullptr, line, column); - return exportEntry && appendExportEntryObject(exportEntry); -} - -bool ModuleBuilder::appendExportEntryObject( - HandleExportEntryObject exportEntry) { - if (!exportEntries_.append(exportEntry)) { + auto entry = frontend::StencilModuleEntry::exportFromEntry( + moduleRequest, importName, exportName, line, column); + if (!exportEntries_.append(entry)) { return false; } - JSAtom* exportName = exportEntry->exportName(); return !exportName || exportNames_.put(exportName); } -bool ModuleBuilder::maybeAppendRequestedModule(HandleAtom specifier, - frontend::ParseNode* node) { +bool ModuleBuilder::maybeAppendRequestedModule( + const frontend::ParserAtom* specifier, frontend::ParseNode* node) { if (requestedModuleSpecifiers_.has(specifier)) { return true; } @@ -1630,15 +1735,14 @@ bool ModuleBuilder::maybeAppendRequestedModule(HandleAtom specifier, uint32_t column; eitherParser_.computeLineAndColumn(node->pn_pos.begin, &line, &column); - JSContext* cx = cx_; - RootedRequestedModuleObject req( - cx, RequestedModuleObject::create(cx, specifier, line, column)); - if (!req) { + auto entry = + frontend::StencilModuleEntry::moduleRequest(specifier, line, column); + if (!requestedModules_.append(entry)) { + js::ReportOutOfMemory(cx_); return false; } - return FreezeObject(cx, req) && requestedModules_.append(req) && - requestedModuleSpecifiers_.put(specifier); + return requestedModuleSpecifiers_.put(specifier); } template @@ -1658,25 +1762,6 @@ ArrayObject* js::CreateArray(JSContext* cx, return array; } -template -ArrayObject* ModuleBuilder::createArrayFromHashMap( - const JS::Rooted>& map) { - uint32_t length = map.count(); - RootedArrayObject array(cx_, NewDenseFullyAllocatedArray(cx_, length)); - if (!array) { - return nullptr; - } - - array->setDenseInitializedLength(length); - - uint32_t i = 0; - for (auto r = map.all(); !r.empty(); r.popFront()) { - array->initDenseElement(i++, ObjectValue(*r.front().value())); - } - - return array; -} - JSObject* js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg) { HandleModuleObject module = moduleArg.as(); @@ -1785,15 +1870,19 @@ JSObject* js::StartDynamicModuleImport(JSContext* cx, HandleScript script, } bool js::FinishDynamicModuleImport(JSContext* cx, + JS::DynamicImportStatus status, HandleValue referencingPrivate, HandleString specifier, HandleObject promiseArg) { + MOZ_ASSERT_IF(cx->isExceptionPending(), + status == JS::DynamicImportStatus::Failed); + Handle promise = promiseArg.as(); auto releasePrivate = mozilla::MakeScopeExit( [&] { cx->runtime()->releaseScriptPrivate(referencingPrivate); }); - if (cx->isExceptionPending()) { + if (status == JS::DynamicImportStatus::Failed) { return RejectPromiseWithPendingError(cx, promise); } @@ -1961,7 +2050,7 @@ XDRResult js::XDRModuleObject(XDRState* xdr, // funcDecls points to data traced by the ModuleObject, // but is itself heap-allocated so we don't need to // worry about rooting it again here. - FunctionDeclarationVector* funcDecls; + frontend::FunctionDeclarationVector* funcDecls; uint32_t requestedModulesLength = 0; uint32_t importEntriesLength = 0; @@ -2075,22 +2164,17 @@ XDRResult js::XDRModuleObject(XDRState* xdr, MOZ_TRY(XDRExportEntries(xdr, &starExportEntries)); /* FunctionDeclarations slot */ - RootedAtom funcName(cx); uint32_t funIndex = 0; MOZ_TRY(xdr->codeUint32(&funcDeclLength)); for (uint32_t i = 0; i < funcDeclLength; i++) { if (mode == XDR_ENCODE) { - FunctionDeclaration fd = (*funcDecls)[i]; - funcName = fd.name; - funIndex = fd.funIndex; + funIndex = (*funcDecls)[i]; } - MOZ_TRY(XDRAtom(xdr, &funcName)); MOZ_TRY(xdr->codeUint32(&funIndex)); if (mode == XDR_DECODE) { - FunctionDeclaration funcDecl(funcName, funIndex); - if (!module->functionDeclarations()->append(funcDecl)) { + if (!module->functionDeclarations()->append(funIndex)) { ReportOutOfMemory(cx); return xdr->fail(JS::TranscodeResult_Throw); } diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index a1095cf692..ea551b9026 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -10,9 +10,11 @@ #include "jsapi.h" #include "builtin/SelfHostingDefines.h" +#include "frontend/Stencil.h" #include "gc/ZoneAllocator.h" #include "js/GCVector.h" #include "js/Id.h" +#include "js/Modules.h" #include "js/UniquePtr.h" #include "vm/JSAtom.h" #include "vm/NativeObject.h" @@ -222,19 +224,6 @@ class ModuleNamespaceObject : public ProxyObject { using RootedModuleNamespaceObject = Rooted; using HandleModuleNamespaceObject = Handle; -struct FunctionDeclaration { - FunctionDeclaration(HandleAtom name, uint32_t funIndex); - void trace(JSTracer* trc); - - const HeapPtr name; - const uint32_t funIndex; -}; - -// A vector of function bindings to be instantiated. This can be created in a -// helper thread zone and so can't use ZoneAllocPolicy. -using FunctionDeclarationVector = - GCVector; - // Possible values for ModuleStatus are defined in SelfHostingDefines.h. using ModuleStatus = int32_t; @@ -321,10 +310,6 @@ class ModuleObject : public NativeObject { void setMetaObject(JSObject* obj); - // For BytecodeEmitter. - bool noteFunctionDeclaration(JSContext* cx, HandleAtom name, - uint32_t funIndex); - // For intrinsic_InstantiateModuleFunctionDeclarations. static bool instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self); @@ -340,7 +325,8 @@ class ModuleObject : public NativeObject { static bool createEnvironment(JSContext* cx, HandleModuleObject self); - FunctionDeclarationVector* functionDeclarations(); + frontend::FunctionDeclarationVector* functionDeclarations(); + void initFunctionDeclarations(frontend::FunctionDeclarationVector&& decls); private: static const JSClassOps classOps_; @@ -359,7 +345,8 @@ JSObject* CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, JSObject* StartDynamicModuleImport(JSContext* cx, HandleScript script, HandleValue specifier); -bool FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, +bool FinishDynamicModuleImport(JSContext* cx, JS::DynamicImportStatus status, + HandleValue referencingPrivate, HandleString specifier, HandleObject promise); template diff --git a/js/src/builtin/Number.js b/js/src/builtin/Number.js index ef1b37b08e..dc81820389 100644 --- a/js/src/builtin/Number.js +++ b/js/src/builtin/Number.js @@ -13,8 +13,8 @@ var numberFormatCache = new Record(); * Spec: ECMAScript Internationalization API Specification, 13.2.1. */ function Number_toLocaleString() { - // Steps 1-2. Note that valueOf enforces "this Number value" restrictions. - var x = callFunction(std_Number_valueOf, this); + // Steps 1-2. + var x = callFunction(ThisNumberValueForToLocaleString, this); // Steps 2-3. var locales = arguments.length > 0 ? arguments[0] : undefined; diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 26b03beece..c1a11e0ad3 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "builtin/Object.h" +#include "js/Object.h" // JS::GetBuiltinClass #include "mozilla/MaybeOneOf.h" #include "mozilla/Range.h" @@ -15,6 +16,7 @@ #include "builtin/SelfHostingDefines.h" #include "frontend/BytecodeCompiler.h" #include "jit/InlinableNatives.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit #include "js/PropertySpec.h" #include "js/UniquePtr.h" #include "util/StringBuffer.h" @@ -81,7 +83,8 @@ bool js::obj_propertyIsEnumerable(JSContext* cx, unsigned argc, Value* vp) { /* Steps 1-2. */ jsid id; - if (args.thisv().isObject() && ValueToId(cx, idValue, &id)) { + if (args.thisv().isObject() && idValue.isPrimitive() && + PrimitiveValueToId(cx, idValue, &id)) { JSObject* obj = &args.thisv().toObject(); /* Step 3. */ @@ -502,7 +505,7 @@ static bool GetBuiltinTagSlow(JSContext* cx, HandleObject obj, // Steps 6-13. ESClass cls; - if (!GetBuiltinClass(cx, obj, &cls)) { + if (!JS::GetBuiltinClass(cx, obj, &cls)) { return false; } @@ -599,26 +602,77 @@ static MOZ_ALWAYS_INLINE JSString* GetBuiltinTagFast(JSObject* obj, return nullptr; } +// For primitive values we try to avoid allocating the object if we can +// determine that the prototype it would use does not define Symbol.toStringTag. +static JSAtom* MaybeObjectToStringPrimitive(JSContext* cx, const Value& v) { + JSProtoKey protoKey = js::PrimitiveToProtoKey(cx, v); + + // If prototype doesn't exist yet, just fall through. + JSObject* proto = cx->global()->maybeGetPrototype(protoKey); + if (!proto) { + return nullptr; + } + + // If determining this may have side-effects, we must instead create the + // object normally since it is the receiver while looking up + // Symbol.toStringTag. + if (MaybeHasInterestingSymbolProperty( + cx, proto, cx->wellKnownSymbols().toStringTag, nullptr)) { + return nullptr; + } + + // Return the direct result. + switch (protoKey) { + case JSProto_String: + return cx->names().objectString; + case JSProto_Number: + return cx->names().objectNumber; + case JSProto_Boolean: + return cx->names().objectBoolean; + case JSProto_Symbol: + return cx->names().objectSymbol; + case JSProto_BigInt: + return cx->names().objectBigInt; + default: + break; + } + + return nullptr; +} + // ES6 19.1.3.6 bool js::obj_toString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); + RootedObject obj(cx); - // Step 1. - if (args.thisv().isUndefined()) { - args.rval().setString(cx->names().objectUndefined); - return true; - } + if (args.thisv().isPrimitive()) { + // Step 1. + if (args.thisv().isUndefined()) { + args.rval().setString(cx->names().objectUndefined); + return true; + } - // Step 2. - if (args.thisv().isNull()) { - args.rval().setString(cx->names().objectNull); - return true; - } + // Step 2. + if (args.thisv().isNull()) { + args.rval().setString(cx->names().objectNull); + return true; + } - // Step 3. - RootedObject obj(cx, ToObject(cx, args.thisv())); - if (!obj) { - return false; + // Try fast-path for primitives. This is unusual but we encounter code like + // this in the wild. + JSAtom* result = MaybeObjectToStringPrimitive(cx, args.thisv()); + if (result) { + args.rval().setString(result); + return true; + } + + // Step 3. + obj = ToObject(cx, args.thisv()); + if (!obj) { + return false; + } + } else { + obj = &args.thisv().toObject(); } RootedString builtinTag(cx); @@ -646,7 +700,9 @@ bool js::obj_toString(JSContext* cx, unsigned argc, Value* vp) { } // Step 14. - // Currently omitted for non-standard fallback. + if (!builtinTag) { + builtinTag = cx->names().objectObject; + } // Step 15. RootedValue tag(cx); @@ -657,21 +713,6 @@ bool js::obj_toString(JSContext* cx, unsigned argc, Value* vp) { // Step 16. if (!tag.isString()) { - // Non-standard (bug 1277801): Use ClassName as a fallback in the interim - if (!builtinTag) { - const char* className = GetObjectClassName(cx, obj); - StringBuffer sb(cx); - if (!sb.append("[object ") || !sb.append(className, strlen(className)) || - !sb.append(']')) { - return false; - } - - builtinTag = sb.finishAtom(); - if (!builtinTag) { - return false; - } - } - args.rval().setString(builtinTag); return true; } @@ -1924,7 +1965,8 @@ static const JSFunctionSpec object_methods[] = { JS_SELF_HOSTED_FN(js_toLocaleString_str, "Object_toLocaleString", 0, 0), JS_SELF_HOSTED_FN(js_valueOf_str, "Object_valueOf", 0, 0), JS_SELF_HOSTED_FN(js_hasOwnProperty_str, "Object_hasOwnProperty", 1, 0), - JS_FN(js_isPrototypeOf_str, obj_isPrototypeOf, 1, 0), + JS_INLINABLE_FN(js_isPrototypeOf_str, obj_isPrototypeOf, 1, 0, + ObjectIsPrototypeOf), JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1, 0), JS_SELF_HOSTED_FN(js_defineGetter_str, "ObjectDefineGetter", 2, 0), JS_SELF_HOSTED_FN(js_defineSetter_str, "ObjectDefineSetter", 2, 0), diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 13cad504dd..dc281bf04a 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -13,6 +13,7 @@ #include "jsfriendapi.h" #include "js/Debug.h" +#include "js/experimental/JitInfo.h" // JSJitGetterOp, JSJitInfo #include "js/ForOfIterator.h" // JS::ForOfIterator #include "js/PropertySpec.h" #include "vm/ArrayObject.h" @@ -384,10 +385,6 @@ namespace { mozilla::Atomic gIDGenerator(0); } // namespace -static MOZ_ALWAYS_INLINE bool ShouldCaptureDebugInfo(JSContext* cx) { - return cx->options().asyncStack() || cx->realm()->isDebuggee(); -} - class PromiseDebugInfo : public NativeObject { private: enum Slots { @@ -467,8 +464,17 @@ class PromiseDebugInfo : public NativeObject { return getFixedSlot(Slot_ResolutionSite).toObjectOrNull(); } - static void setResolutionInfo(JSContext* cx, Handle promise) { - if (!ShouldCaptureDebugInfo(cx)) { + // The |unwrappedRejectionStack| parameter should only be set on promise + // rejections and should be the stack of the exception that caused the promise + // to be rejected. If the |unwrappedRejectionStack| is null, the current stack + // will be used instead. This is also the default behavior for fulfilled + // promises. + static void setResolutionInfo(JSContext* cx, Handle promise, + HandleSavedFrame unwrappedRejectionStack) { + MOZ_ASSERT_IF(unwrappedRejectionStack, + promise->state() == JS::PromiseState::Rejected); + + if (!JS::IsAsyncStackCaptureEnabledForRealm(cx)) { return; } @@ -506,11 +512,20 @@ class PromiseDebugInfo : public NativeObject { return; } - RootedObject stack(cx); - if (!JS::CaptureCurrentStack(cx, &stack, - JS::StackCapture(JS::AllFrames()))) { - cx->clearPendingException(); - return; + RootedObject stack(cx, unwrappedRejectionStack); + if (stack) { + // The exception stack is always unwrapped so it might be in + // a different compartment. + if (!cx->compartment()->wrap(cx, &stack)) { + cx->clearPendingException(); + return; + } + } else { + if (!JS::CaptureCurrentStack(cx, &stack, + JS::StackCapture(JS::AllFrames()))) { + cx->clearPendingException(); + return; + } } debugInfo->setFixedSlot(Slot_ResolutionSite, ObjectOrNullValue(stack)); @@ -555,23 +570,24 @@ JSObject* PromiseObject::resolutionSite() { } /** - * Wrapper for GetAndClearException that handles cases where no exception is - * pending, but an error occurred. This can be the case if an OOM was - * encountered while throwing the error. + * Wrapper for GetAndClearExceptionAndStack that handles cases where + * no exception is pending, but an error occurred. + * This can be the case if an OOM was encountered while throwing the error. */ -static bool MaybeGetAndClearException(JSContext* cx, MutableHandleValue rval) { +static bool MaybeGetAndClearExceptionAndStack(JSContext* cx, + MutableHandleValue rval, + MutableHandleSavedFrame stack) { if (!cx->isExceptionPending()) { return false; } - return GetAndClearException(cx, rval); + return GetAndClearExceptionAndStack(cx, rval, stack); } -static MOZ_MUST_USE bool RunRejectFunction(JSContext* cx, - HandleObject onRejectedFunc, - HandleValue result, - HandleObject promiseObj, - UnhandledRejectionBehavior behavior); +static MOZ_MUST_USE bool RunRejectFunction( + JSContext* cx, HandleObject onRejectedFunc, HandleValue result, + HandleObject promiseObj, HandleSavedFrame unwrappedRejectionStack, + UnhandledRejectionBehavior behavior); // ES2016, 25.4.1.1.1, Steps 1.a-b. // Extracting all of this internal spec algorithm into a helper function would @@ -581,11 +597,12 @@ static bool AbruptRejectPromise(JSContext* cx, CallArgs& args, HandleObject promiseObj, HandleObject reject) { // Step 1.a. RootedValue reason(cx); - if (!MaybeGetAndClearException(cx, &reason)) { + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &reason, &stack)) { return false; } - if (!RunRejectFunction(cx, reject, reason, promiseObj, + if (!RunRejectFunction(cx, reject, reason, promiseObj, stack, UnhandledRejectionBehavior::Report)) { return false; } @@ -894,14 +911,14 @@ static bool IsSettledMaybeWrappedPromise(JSObject* promise) { } // ES2016, 25.4.1.7. -static MOZ_MUST_USE bool RejectMaybeWrappedPromise(JSContext* cx, - HandleObject promiseObj, - HandleValue reason); +static MOZ_MUST_USE bool RejectMaybeWrappedPromise( + JSContext* cx, HandleObject promiseObj, HandleValue reason, + HandleSavedFrame unwrappedRejectionStack); // ES2016, 25.4.1.7. -static MOZ_MUST_USE bool RejectPromiseInternal(JSContext* cx, - Handle promise, - HandleValue reason); +static MOZ_MUST_USE bool RejectPromiseInternal( + JSContext* cx, Handle promise, HandleValue reason, + HandleSavedFrame unwrappedRejectionStack = nullptr); // ES2016, 25.4.1.3.1. static bool RejectPromiseFunction(JSContext* cx, unsigned argc, Value* vp) { @@ -939,7 +956,7 @@ static bool RejectPromiseFunction(JSContext* cx, unsigned argc, Value* vp) { } // Step 6. - if (!RejectMaybeWrappedPromise(cx, promise, reasonVal)) { + if (!RejectMaybeWrappedPromise(cx, promise, reasonVal, nullptr)) { return false; } args.rval().setUndefined(); @@ -981,12 +998,13 @@ static MOZ_MUST_USE bool ResolvePromiseInternal(JSContext* cx, JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF); RootedValue selfResolutionError(cx); - if (!MaybeGetAndClearException(cx, &selfResolutionError)) { + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &selfResolutionError, &stack)) { return false; } // Step 6.b. - return RejectMaybeWrappedPromise(cx, promise, selfResolutionError); + return RejectMaybeWrappedPromise(cx, promise, selfResolutionError, stack); } // Step 8. @@ -995,8 +1013,9 @@ static MOZ_MUST_USE bool ResolvePromiseInternal(JSContext* cx, GetProperty(cx, resolution, resolution, cx->names().then, &thenVal); RootedValue error(cx); + RootedSavedFrame errorStack(cx); if (!status) { - if (!MaybeGetAndClearException(cx, &error)) { + if (!MaybeGetAndClearExceptionAndStack(cx, &error, &errorStack)) { return false; } } @@ -1012,7 +1031,7 @@ static MOZ_MUST_USE bool ResolvePromiseInternal(JSContext* cx, // Step 9. if (!status) { - return RejectMaybeWrappedPromise(cx, promise, error); + return RejectMaybeWrappedPromise(cx, promise, error, errorStack); } // Step 10 (implicit). @@ -1243,14 +1262,20 @@ static MOZ_MUST_USE bool TriggerPromiseReactions(JSContext* cx, HandleValue valueOrReason); // ES2016, Commoned-out implementation of 25.4.1.4. and 25.4.1.7. -static MOZ_MUST_USE bool ResolvePromise(JSContext* cx, - Handle promise, - HandleValue valueOrReason, - JS::PromiseState state) { +// +// This method takes an additional optional |unwrappedRejectionStack| parameter, +// which is only used for debugging purposes. +// It allows callers to to pass in the stack of some exception which +// triggered the rejection of the promise. +static MOZ_MUST_USE bool ResolvePromise( + JSContext* cx, Handle promise, HandleValue valueOrReason, + JS::PromiseState state, + HandleSavedFrame unwrappedRejectionStack = nullptr) { // Step 1. MOZ_ASSERT(promise->state() == JS::PromiseState::Pending); MOZ_ASSERT(state == JS::PromiseState::Fulfilled || state == JS::PromiseState::Rejected); + MOZ_ASSERT_IF(unwrappedRejectionStack, state == JS::PromiseState::Rejected); // Step 2. // We only have one list of reactions for both resolution types. So @@ -1277,7 +1302,7 @@ static MOZ_MUST_USE bool ResolvePromise(JSContext* cx, // Now that everything else is done, do the things the debugger needs. // Step 7 of RejectPromise implemented in onSettled. - PromiseObject::onSettled(cx, promise); + PromiseObject::onSettled(cx, promise, unwrappedRejectionStack); // Step 7 of FulfillPromise. // Step 8 of RejectPromise. @@ -1285,10 +1310,11 @@ static MOZ_MUST_USE bool ResolvePromise(JSContext* cx, } // ES2016, 25.4.1.7. -static MOZ_MUST_USE bool RejectPromiseInternal(JSContext* cx, - Handle promise, - HandleValue reason) { - return ResolvePromise(cx, promise, reason, JS::PromiseState::Rejected); +static MOZ_MUST_USE bool RejectPromiseInternal( + JSContext* cx, Handle promise, HandleValue reason, + HandleSavedFrame unwrappedRejectionStack) { + return ResolvePromise(cx, promise, reason, JS::PromiseState::Rejected, + unwrappedRejectionStack); } // ES2016, 25.4.1.4. @@ -1482,9 +1508,9 @@ static bool GetCapabilitiesExecutor(JSContext* cx, unsigned argc, Value* vp) { } // ES2016, 25.4.1.7. -static MOZ_MUST_USE bool RejectMaybeWrappedPromise(JSContext* cx, - HandleObject promiseObj, - HandleValue reason_) { +static MOZ_MUST_USE bool RejectMaybeWrappedPromise( + JSContext* cx, HandleObject promiseObj, HandleValue reason_, + HandleSavedFrame unwrappedRejectionStack) { Rooted promise(cx); RootedValue reason(cx, reason_); @@ -1530,7 +1556,8 @@ static MOZ_MUST_USE bool RejectMaybeWrappedPromise(JSContext* cx, } } - return ResolvePromise(cx, promise, reason, JS::PromiseState::Rejected); + return ResolvePromise(cx, promise, reason, JS::PromiseState::Rejected, + unwrappedRejectionStack); } // Apply f to a mutable handle on each member of a collection of reactions, like @@ -1614,6 +1641,7 @@ static MOZ_MUST_USE bool DefaultResolvingPromiseReactionJob( // Run{Fulfill,Reject}Function for consistency with PromiseReactionJob. ResolutionMode resolutionMode = ResolveMode; RootedValue handlerResult(cx, UndefinedValue()); + RootedSavedFrame unwrappedRejectionStack(cx); if (promiseToResolve->state() == JS::PromiseState::Pending) { RootedValue argument(cx, reaction->handlerArg()); @@ -1627,7 +1655,8 @@ static MOZ_MUST_USE bool DefaultResolvingPromiseReactionJob( if (!ok) { resolutionMode = RejectMode; - if (!MaybeGetAndClearException(cx, &handlerResult)) { + if (!MaybeGetAndClearExceptionAndStack(cx, &handlerResult, + &unwrappedRejectionStack)) { return false; } } @@ -1646,6 +1675,7 @@ static MOZ_MUST_USE bool DefaultResolvingPromiseReactionJob( callee = reaction->getFixedSlot(ReactionRecordSlot_Reject).toObjectOrNull(); return RunRejectFunction(cx, callee, handlerResult, promiseObj, + unwrappedRejectionStack, reaction->unhandledRejectionBehavior()); } @@ -1835,6 +1865,8 @@ static bool PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp) { RootedValue handlerResult(cx); ResolutionMode resolutionMode = ResolveMode; + RootedSavedFrame unwrappedRejectionStack(cx); + // Steps 4-6. if (handlerVal.isInt32()) { int32_t handlerNum = handlerVal.toInt32(); @@ -1868,7 +1900,8 @@ static bool PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp) { // Step 6. if (!Call(cx, handlerVal, UndefinedHandleValue, argument, &handlerResult)) { resolutionMode = RejectMode; - if (!MaybeGetAndClearException(cx, &handlerResult)) { + if (!MaybeGetAndClearExceptionAndStack(cx, &handlerResult, + &unwrappedRejectionStack)) { return false; } } @@ -1887,6 +1920,7 @@ static bool PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp) { callee = reaction->getFixedSlot(ReactionRecordSlot_Reject).toObjectOrNull(); return RunRejectFunction(cx, callee, handlerResult, promiseObj, + unwrappedRejectionStack, reaction->unhandledRejectionBehavior()); } @@ -1939,7 +1973,9 @@ static bool PromiseResolveThenableJob(JSContext* cx, unsigned argc, Value* vp) { } // Steps 3-4. - if (!MaybeGetAndClearException(cx, &rval)) { + // Can't pass stack to a JS function. + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &rval, &stack)) { return false; } @@ -1988,7 +2024,8 @@ static bool PromiseResolveBuiltinThenableJob(JSContext* cx, unsigned argc, // Steps 3-4. RootedValue exception(cx); - if (!MaybeGetAndClearException(cx, &exception)) { + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &exception, &stack)) { return false; } @@ -2001,7 +2038,8 @@ static bool PromiseResolveBuiltinThenableJob(JSContext* cx, unsigned argc, return true; } - return RejectPromiseInternal(cx, promise.as(), exception); + return RejectPromiseInternal(cx, promise.as(), exception, + stack); } /** @@ -2212,7 +2250,7 @@ CreatePromiseObjectInternal(JSContext* cx, HandleObject proto /* = nullptr */, // Step 7. // Implicit, the handled flag is unset by default. - if (MOZ_LIKELY(!ShouldCaptureDebugInfo(cx))) { + if (MOZ_LIKELY(!JS::IsAsyncStackCaptureEnabledForRealm(cx))) { return promise; } @@ -2408,7 +2446,9 @@ PromiseObject* PromiseObject::create(JSContext* cx, HandleObject executor, // Step 10. if (!success) { RootedValue exceptionVal(cx); - if (!MaybeGetAndClearException(cx, &exceptionVal)) { + // Can't pass stack to a JS function. + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &exceptionVal, &stack)) { return nullptr; } @@ -2789,7 +2829,8 @@ static MOZ_MUST_USE bool RunFulfillFunction(JSContext* cx, static MOZ_MUST_USE bool RunRejectFunction( JSContext* cx, HandleObject onRejectedFunc, HandleValue result, - HandleObject promiseObj, UnhandledRejectionBehavior behavior) { + HandleObject promiseObj, HandleSavedFrame unwrappedRejectionStack, + UnhandledRejectionBehavior behavior) { cx->check(onRejectedFunc); cx->check(result); cx->check(promiseObj); @@ -2816,7 +2857,8 @@ static MOZ_MUST_USE bool RunRejectFunction( return true; } - return RejectPromiseInternal(cx, temporaryPromise, result); + return RejectPromiseInternal(cx, temporaryPromise, result, + unwrappedRejectionStack); } // Reject the promise only if it's still pending. @@ -2827,7 +2869,7 @@ static MOZ_MUST_USE bool RunRejectFunction( // If the promise has a default rejection function, perform its steps. if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS)) { - return RejectPromiseInternal(cx, promise, result); + return RejectPromiseInternal(cx, promise, result, unwrappedRejectionStack); } // Otherwise we're done. @@ -3793,11 +3835,12 @@ static bool PromiseAnyRejectElementFunction(JSContext* cx, unsigned argc, ThrowAggregateError(cx, errors, promiseObj); RootedValue reason(cx); - if (!MaybeGetAndClearException(cx, &reason)) { + RootedSavedFrame stack(cx); + if (!MaybeGetAndClearExceptionAndStack(cx, &reason, &stack)) { return false; } - if (!RunRejectFunction(cx, rejectFun, reason, promiseObj, + if (!RunRejectFunction(cx, rejectFun, reason, promiseObj, stack, UnhandledRejectionBehavior::Report)) { return false; } @@ -3930,16 +3973,20 @@ static MOZ_MUST_USE JSObject* CommonStaticResolveRejectImpl( return nullptr; } - // PromiseResolve, step 4: - // Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »). - // Promise.reject, step 4: - // Perform ? Call(promiseCapability.[[Reject]], undefined, « r »). HandleObject promise = capability.promise(); - if (!(mode == ResolveMode - ? RunFulfillFunction(cx, capability.resolve(), argVal, promise) - : RunRejectFunction(cx, capability.reject(), argVal, promise, - UnhandledRejectionBehavior::Report))) { - return nullptr; + if (mode == ResolveMode) { + // PromiseResolve, step 4: + // Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »). + if (!RunFulfillFunction(cx, capability.resolve(), argVal, promise)) { + return nullptr; + } + } else { + // Promise.reject, step 4: + // Perform ? Call(promiseCapability.[[Reject]], undefined, « r »). + if (!RunRejectFunction(cx, capability.reject(), argVal, promise, nullptr, + UnhandledRejectionBehavior::Report)) { + return nullptr; + } } // Step 5: Return promiseCapability.[[Promise]]. @@ -5113,8 +5160,6 @@ static MOZ_ALWAYS_INLINE bool IsPromiseThenOrCatchRetValImplicitlyUsed( // used explicitly in the script, the stack info is observable in devtools // and profilers. We shouldn't apply the optimization not to allocate the // returned Promise object if the it's implicitly used by them. - // - // FIXME: Once bug 1280819 gets fixed, we can use ShouldCaptureDebugInfo. if (!cx->options().asyncStack()) { return false; } @@ -5607,8 +5652,9 @@ bool PromiseObject::reject(JSContext* cx, Handle promise, } /* static */ -void PromiseObject::onSettled(JSContext* cx, Handle promise) { - PromiseDebugInfo::setResolutionInfo(cx, promise); +void PromiseObject::onSettled(JSContext* cx, Handle promise, + HandleSavedFrame unwrappedRejectionStack) { + PromiseDebugInfo::setResolutionInfo(cx, promise, unwrappedRejectionStack); if (promise->state() == JS::PromiseState::Rejected && promise->isUnhandled()) { @@ -5755,11 +5801,8 @@ MOZ_MUST_USE bool js::TrySkipAwait(JSContext* cx, HandleValue val, return true; } -JS::AutoDebuggerJobQueueInterruption::AutoDebuggerJobQueueInterruption( - MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL) - : cx(nullptr) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; -} +JS::AutoDebuggerJobQueueInterruption::AutoDebuggerJobQueueInterruption() + : cx(nullptr) {} JS::AutoDebuggerJobQueueInterruption::~AutoDebuggerJobQueueInterruption() { MOZ_ASSERT_IF(initialized(), cx->jobQueue->empty()); @@ -5831,5 +5874,5 @@ const JSClass PromiseObject::class_ = { JS_NULL_CLASS_OPS, &PromiseObjectClassSpec}; const JSClass PromiseObject::protoClass_ = { - "PromiseProto", JSCLASS_HAS_CACHED_PROTO(JSProto_Promise), + "Promise.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_Promise), JS_NULL_CLASS_OPS, &PromiseObjectClassSpec}; diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index 08185c7fbb..ef27949d8e 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -6,9 +6,9 @@ #include "mozilla/DebugOnly.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" #include +#include #include "jspubtd.h" @@ -19,6 +19,7 @@ #include "frontend/ParseNode.h" #include "frontend/Parser.h" #include "js/CharacterEncoding.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit #include "js/StableStringChars.h" #include "vm/BigIntType.h" #include "vm/FunctionFlags.h" // js::FunctionFlags @@ -2470,7 +2471,13 @@ bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) { case ParseNodeKind::ContinueStmt: { LoopControlStatement* node = &pn->as(); RootedValue label(cx); - RootedAtom pnAtom(cx, node->label()); + RootedAtom pnAtom(cx); + if (node->label()) { + pnAtom.set(parser->liftParserAtomToJSAtom(node->label())); + if (!pnAtom) { + return false; + } + } return optIdentifier(pnAtom, nullptr, &label) && (node->isKind(ParseNodeKind::BreakStmt) ? builder.breakStatement(label, &node->pn_pos, dst) @@ -2483,7 +2490,10 @@ bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) { MOZ_ASSERT(labelNode->pn_pos.encloses(stmtNode->pn_pos)); RootedValue label(cx), stmt(cx); - RootedAtom pnAtom(cx, labelNode->label()); + RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(labelNode->label())); + if (!pnAtom.get()) { + return false; + } return identifier(pnAtom, nullptr, &label) && statement(stmtNode, &stmt) && builder.labeledStatement(label, stmt, &labelNode->pn_pos, dst); @@ -2916,7 +2926,10 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { RootedValue expr(cx); RootedValue propname(cx); - RootedAtom pnAtom(cx, prop->key().atom()); + RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(prop->key().atom())); + if (!pnAtom.get()) { + return false; + } if (isSuper) { if (!builder.super(&prop->expression().pn_pos, &expr)) { @@ -2974,8 +2987,11 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { NameNode* rawItem = &item->as(); MOZ_ASSERT(callSiteObj->pn_pos.encloses(rawItem->pn_pos)); - RootedValue expr(cx); - expr.setString(rawItem->atom()); + JSAtom* exprAtom = parser->liftParserAtomToJSAtom(rawItem->atom()); + if (!exprAtom) { + return false; + } + RootedValue expr(cx, StringValue(exprAtom)); raw.infallibleAppend(expr); } @@ -2993,7 +3009,12 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { expr.setUndefined(); } else { MOZ_ASSERT(cookedItem->isKind(ParseNodeKind::TemplateStringExpr)); - expr.setString(cookedItem->as().atom()); + JSAtom* exprAtom = + parser->liftParserAtomToJSAtom(cookedItem->as().atom()); + if (!exprAtom) { + return false; + } + expr.setString(exprAtom); } cooked.infallibleAppend(expr); } @@ -3032,6 +3053,9 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { } case ParseNodeKind::ComputedName: { + if (pn->as().isSyntheticComputedName()) { + return literal(pn->as().kid(), dst); + } RootedValue name(cx); return expression(pn->as().kid(), &name) && builder.computedName(name, &pn->pn_pos, dst); @@ -3057,6 +3081,7 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { return builder.objectExpression(elts, &obj->pn_pos, dst); } + case ParseNodeKind::PrivateName: case ParseNodeKind::Name: return identifier(&pn->as(), dst); @@ -3183,7 +3208,8 @@ bool ASTSerializer::propertyName(ParseNode* key, MutableHandleValue dst) { if (key->isKind(ParseNodeKind::ComputedName)) { return expression(key, dst); } - if (key->isKind(ParseNodeKind::ObjectPropertyName)) { + if (key->isKind(ParseNodeKind::ObjectPropertyName) || + key->isKind(ParseNodeKind::PrivateName)) { return identifier(&key->as(), dst); } @@ -3245,13 +3271,19 @@ bool ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst) { RootedValue val(cx); switch (pn->getKind()) { case ParseNodeKind::TemplateStringExpr: - case ParseNodeKind::StringExpr: - val.setString(pn->as().atom()); + case ParseNodeKind::StringExpr: { + JSAtom* exprAtom = + parser->liftParserAtomToJSAtom(pn->as().atom()); + if (!exprAtom) { + return false; + } + val.setString(exprAtom); break; + } case ParseNodeKind::RegExpExpr: { - RegExpObject* re = - pn->as().create(cx, parser->getCompilationInfo()); + RegExpObject* re = pn->as().create( + cx, parser->getCompilationInfo().stencil); if (!re) { return false; } @@ -3410,7 +3442,10 @@ bool ASTSerializer::identifier(HandleAtom atom, TokenPos* pos, bool ASTSerializer::identifier(NameNode* id, MutableHandleValue dst) { LOCAL_ASSERT(id->atom()); - RootedAtom pnAtom(cx, id->atom()); + RootedAtom pnAtom(cx, parser->liftParserAtomToJSAtom(id->atom())); + if (!pnAtom.get()) { + return false; + } return identifier(pnAtom, &id->pn_pos, dst); } @@ -3425,7 +3460,13 @@ bool ASTSerializer::function(FunctionNode* funNode, ASTType type, bool isExpression = funbox->hasExprBody(); RootedValue id(cx); - RootedAtom funcAtom(cx, funbox->explicitName()); + RootedAtom funcAtom(cx); + if (funbox->explicitName()) { + funcAtom.set(parser->liftParserAtomToJSAtom(funbox->explicitName())); + if (!funcAtom) { + return false; + } + } if (!optIdentifier(funcAtom, nullptr, &id)) { return false; } @@ -3725,15 +3766,24 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) { options.allowHTMLComments = target == ParseGoal::Script; mozilla::Range chars = linearChars.twoByteRange(); - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options); - if (!compilationInfo.init(cx)) { - return false; + Rooted compilationInfo(cx, CompilationInfo(cx, options)); + if (target == ParseGoal::Script) { + if (!compilationInfo.get().input.initForGlobal(cx)) { + return false; + } + } else { + if (!compilationInfo.get().input.initForModule(cx)) { + return false; + } } + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + frontend::CompilationState compilationState(cx, allocScope, options); + Parser parser( cx, options, chars.begin().get(), chars.length(), - /* foldConstants = */ false, compilationInfo, nullptr, nullptr); + /* foldConstants = */ false, compilationInfo.get(), compilationState, + nullptr, nullptr); if (!parser.checkOptions()) { return false; } @@ -3751,18 +3801,12 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) { return false; } - Rooted module(cx, ModuleObject::create(cx)); - if (!module) { - return false; - } - ModuleBuilder builder(cx, &parser); uint32_t len = chars.length(); - SourceExtent extent = SourceExtent::makeGlobalExtent(len, options); - ModuleSharedContext modulesc(cx, module, compilationInfo, - &cx->global()->emptyGlobalScope(), builder, - extent); + SourceExtent extent = + SourceExtent::makeGlobalExtent(len, options.lineno, options.column); + ModuleSharedContext modulesc(cx, compilationInfo.get(), builder, extent); pn = parser.moduleBody(&modulesc); if (!pn) { return false; diff --git a/js/src/builtin/SelfHostingDefines.h b/js/src/builtin/SelfHostingDefines.h index 64989ae281..7e760ceac3 100644 --- a/js/src/builtin/SelfHostingDefines.h +++ b/js/src/builtin/SelfHostingDefines.h @@ -21,7 +21,7 @@ // NB: keep this in sync with the copy in vm/ArgumentsObject.h. #define MAX_ARGS_LENGTH (500 * 1000) -// NB: keep this in sync with js::MaxStringLength in jsfriendapi.h. +// NB: keep this in sync with JS::MaxStringLength in js/public/String.h. #define MAX_STRING_LENGTH ((1 << 30) - 2) // Spread non-empty argument list of up to 15 elements. @@ -69,10 +69,6 @@ // name for self-hosted builtins is stored. #define LAZY_FUNCTION_NAME_SLOT 0 -// Stores the length for bound functions, so the .length property doesn't need -// to be resolved eagerly. -#define BOUND_FUN_LENGTH_SLOT 1 - #define ITERATOR_SLOT_TARGET 0 // Used for collection iterators. #define ITERATOR_SLOT_RANGE 1 @@ -109,11 +105,18 @@ #define MODULE_OBJECT_DFS_INDEX_SLOT 14 #define MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT 15 -#define MODULE_STATUS_UNINSTANTIATED 0 -#define MODULE_STATUS_INSTANTIATING 1 -#define MODULE_STATUS_INSTANTIATED 2 +// rev b012019fea18f29737a67c36911340a3e25bfc63 +// 15.2.1.16 Cyclic Module Records +// Value types of [[Status]] in a Cyclic Module Record +#define MODULE_STATUS_UNLINKED 0 +#define MODULE_STATUS_LINKING 1 +#define MODULE_STATUS_LINKED 2 #define MODULE_STATUS_EVALUATING 3 #define MODULE_STATUS_EVALUATED 4 + +// rev b012019fea18f29737a67c36911340a3e25bfc63 +// 15.2.1.16 Cyclic Module Records +// Value types of [[EvaluationError]] in a Cyclic Module Record #define MODULE_STATUS_EVALUATED_ERROR 5 #define INTL_INTERNALS_OBJECT_SLOT 0 @@ -134,4 +137,8 @@ #define ITERATED_SLOT 0 +#define ITERATOR_HELPER_GENERATOR_SLOT 0 + +#define ASYNC_ITERATOR_HELPER_GENERATOR_SLOT 0 + #endif diff --git a/js/src/builtin/Set.js b/js/src/builtin/Set.js index cca97cc49c..9ca9ec803c 100644 --- a/js/src/builtin/Set.js +++ b/js/src/builtin/Set.js @@ -34,7 +34,7 @@ function SetForEach(callbackfn, thisArg = undefined) { ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Steps 5-8. - var values = callFunction(std_Set_iterator, S); + var values = callFunction(std_Set_values, S); // Inlined: SetIteratorNext var setIterationResult = setIteratorTemp.setIterationResult; @@ -53,14 +53,9 @@ function SetForEach(callbackfn, thisArg = undefined) { } } +// ES6 final draft 23.2.2.2. // Uncloned functions with `$` prefix are allocated as extended function // to store the original name in `_SetCanonicalName`. -function $SetValues() { - return callFunction(std_Set_iterator, this); -} -_SetCanonicalName($SetValues, "values"); - -// ES6 final draft 23.2.2.2. function $SetSpecies() { // Step 1. return this; diff --git a/js/src/builtin/Stream.cpp b/js/src/builtin/Stream.cpp index a61573bdea..a8b77831e9 100644 --- a/js/src/builtin/Stream.cpp +++ b/js/src/builtin/Stream.cpp @@ -18,6 +18,7 @@ #include "builtin/streams/ReadableStreamInternals.h" // js::ReadableStream{AddReadOrReadIntoRequest,CloseInternal,CreateReadResult,ErrorInternal,FulfillReadOrReadIntoRequest,GetNumReadRequests,HasDefaultReader} #include "builtin/streams/ReadableStreamReader.h" // js::ReadableStream{,Default}Reader, js::CreateReadableStreamDefaultReader, js::ReadableStreamReaderGeneric{Cancel,Initialize,Release}, js::ReadableStreamDefaultReaderRead #include "js/ArrayBuffer.h" // JS::NewArrayBuffer +#include "js/experimental/TypedData.h" // JS_GetArrayBufferViewData, JS_NewUint8Array{,WithBuffer} #include "js/PropertySpec.h" #include "vm/Interpreter.h" #include "vm/JSContext.h" diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index 75f3c0786b..05a46b4b96 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -30,6 +30,7 @@ #include "builtin/RegExp.h" #include "jit/InlinableNatives.h" #include "js/Conversions.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit #if !JS_HAS_INTL_API # include "js/LocaleSensitive.h" #endif @@ -3578,8 +3579,8 @@ static const JSFunctionSpec string_methods[] = { JS_FN(js_toSource_str, str_toSource, 0, 0), /* Java-like methods. */ - JS_FN(js_toString_str, str_toString, 0, 0), - JS_FN(js_valueOf_str, str_toString, 0, 0), + JS_INLINABLE_FN(js_toString_str, str_toString, 0, 0, StringToString), + JS_INLINABLE_FN(js_valueOf_str, str_toString, 0, 0, StringValueOf), JS_INLINABLE_FN("toLowerCase", str_toLowerCase, 0, 0, StringToLowerCase), JS_INLINABLE_FN("toUpperCase", str_toUpperCase, 0, 0, StringToUpperCase), JS_INLINABLE_FN("charAt", str_charAt, 1, 0, StringCharAt), diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index cadbb592ec..216fdbd12b 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -8,10 +8,10 @@ #include "mozilla/Casting.h" #include "mozilla/FloatingPoint.h" #include "mozilla/Maybe.h" -#include "mozilla/Move.h" #include "mozilla/Span.h" #include "mozilla/Sprintf.h" #include "mozilla/TextUtils.h" +#include "mozilla/ThreadLocal.h" #include "mozilla/Tuple.h" #include "mozilla/Unused.h" @@ -20,6 +20,8 @@ #include #include #include +#include +#include #if defined(XP_UNIX) && !defined(XP_DARWIN) # include @@ -30,6 +32,10 @@ #include "jsapi.h" #include "jsfriendapi.h" +#ifdef JS_HAS_INTL_API +# include "builtin/intl/CommonFunctions.h" +#endif +#include "builtin/ModuleObject.h" #include "builtin/Promise.h" #include "builtin/SelfHostingDefines.h" #ifdef DEBUG @@ -38,9 +44,11 @@ #include "gc/Allocator.h" #include "gc/Zone.h" #include "jit/BaselineJIT.h" +#include "jit/Disassemble.h" #include "jit/InlinableNatives.h" #include "jit/Ion.h" #include "jit/JitRealm.h" +#include "jit/TrialInlining.h" #include "js/Array.h" // JS::NewArrayObject #include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,GetArrayBufferLengthAndData,NewArrayBufferWithContents} #include "js/CharacterEncoding.h" @@ -48,12 +56,18 @@ #include "js/CompileOptions.h" #include "js/Date.h" #include "js/Debug.h" +#include "js/experimental/CodeCoverage.h" // js::GetCodeCoverageSummary +#include "js/experimental/TypedData.h" // JS_GetObjectAsUint8Array +#include "js/friend/DumpFunctions.h" // js::Dump{Backtrace,Heap,Object}, JS::FormatStackDump, js::IgnoreNurseryObjects +#include "js/friend/WindowProxy.h" // js::ToWindowProxyIfWindow #include "js/HashTable.h" #include "js/LocaleSensitive.h" +#include "js/OffThreadScriptCompilation.h" // js::UseOffThreadParseGlobal #include "js/PropertySpec.h" #include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags #include "js/SourceText.h" #include "js/StableStringChars.h" +#include "js/String.h" // JS::GetLinearStringLength, JS::StringToLinearString #include "js/StructuredClone.h" #include "js/UbiNode.h" #include "js/UbiNodeBreadthFirst.h" @@ -62,12 +76,20 @@ #include "js/Vector.h" #include "js/Wrapper.h" #include "threading/CpuCount.h" +#ifdef JS_HAS_INTL_API +# include "unicode/ucal.h" +# include "unicode/uchar.h" +# include "unicode/uloc.h" +# include "unicode/utypes.h" +# include "unicode/uversion.h" +#endif #include "util/StringBuffer.h" #include "util/Text.h" #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" #include "vm/ErrorObject.h" #include "vm/GlobalObject.h" +#include "vm/HelperThreadState.h" #include "vm/Interpreter.h" #include "vm/Iteration.h" #include "vm/JSContext.h" @@ -138,6 +160,36 @@ static bool EnvVarAsInt(const char* name, int* valueOut) { } #endif +static bool GetRealmConfiguration(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + RootedObject info(cx, JS_NewPlainObject(cx)); + if (!info) { + return false; + } + + bool privateFields = cx->options().privateClassFields(); + if (!JS_SetProperty(cx, info, "privateFields", + privateFields ? TrueHandleValue : FalseHandleValue)) { + return false; + } + bool privateMethods = cx->options().privateClassMethods(); + if (!JS_SetProperty(cx, info, "privateMethods", + privateFields && privateMethods ? TrueHandleValue + : FalseHandleValue)) { + return false; + } + + bool offThreadParseGlobal = js::UseOffThreadParseGlobal(); + if (!JS_SetProperty( + cx, info, "offThreadParseGlobal", + offThreadParseGlobal ? TrueHandleValue : FalseHandleValue)) { + return false; + } + + args.rval().setObject(*info); + return true; +} + static bool GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject info(cx, JS_NewPlainObject(cx)); @@ -188,6 +240,15 @@ static bool GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) { return false; } +#ifdef EARLY_BETA_OR_EARLIER + value = BooleanValue(true); +#else + value = BooleanValue(false); +#endif + if (!JS_SetProperty(cx, info, "early_beta_or_earlier", value)) { + return false; + } + #ifdef MOZ_CODE_COVERAGE value = BooleanValue(true); #else @@ -422,15 +483,6 @@ static bool GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) { return false; } -#if defined(JS_BUILD_BINAST) - value = BooleanValue(true); -#else - value = BooleanValue(false); -#endif - if (!JS_SetProperty(cx, info, "binast", value)) { - return false; - } - value.setInt32(sizeof(void*)); if (!JS_SetProperty(cx, info, "pointer-byte-size", value)) { return false; @@ -452,6 +504,27 @@ static bool IsTypeInferenceEnabled(JSContext* cx, unsigned argc, Value* vp) { return true; } +static bool TrialInline(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + args.rval().setUndefined(); + + if (!jit::JitOptions.warpBuilder) { + return true; + } + + FrameIter iter(cx); + if (iter.done() || !iter.isBaseline()) { + return true; + } + + jit::BaselineFrame* frame = iter.abstractFramePtr().asBaselineFrame(); + if (!jit::CanIonCompileScript(cx, frame->script())) { + return true; + } + + return jit::DoTrialInlining(cx, frame); +} + static bool ReturnStringCopy(JSContext* cx, CallArgs& args, const char* message) { JSString* str = JS_NewStringCopyZ(cx, message); @@ -463,6 +536,13 @@ static bool ReturnStringCopy(JSContext* cx, CallArgs& args, return true; } +static bool MaybeGC(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + JS_MaybeGC(cx); + args.rval().setUndefined(); + return true; +} + static bool GC(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -576,7 +656,11 @@ static bool MinorGC(JSContext* cx, unsigned argc, Value* vp) { _("pretenureGroupThreshold", JSGC_PRETENURE_GROUP_THRESHOLD, true) \ _("zoneAllocDelayKB", JSGC_ZONE_ALLOC_DELAY_KB, true) \ _("mallocThresholdBase", JSGC_MALLOC_THRESHOLD_BASE, true) \ - _("mallocGrowthFactor", JSGC_MALLOC_GROWTH_FACTOR, true) + _("mallocGrowthFactor", JSGC_MALLOC_GROWTH_FACTOR, true) \ + _("chunkBytes", JSGC_CHUNK_BYTES, false) \ + _("helperThreadRatio", JSGC_HELPER_THREAD_RATIO, true) \ + _("maxHelperThreads", JSGC_MAX_HELPER_THREADS, true) \ + _("helperThreadCount", JSGC_HELPER_THREAD_COUNT, false) static const struct ParamInfo { const char* name; @@ -709,7 +793,8 @@ static bool IsProxy(JSContext* cx, unsigned argc, Value* vp) { static bool WasmIsSupported(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - args.rval().setBoolean(wasm::HasSupport(cx)); + args.rval().setBoolean(wasm::HasSupport(cx) && + wasm::AnyCompilerAvailable(cx)); return true; } @@ -753,23 +838,6 @@ static bool WasmThreadsSupported(JSContext* cx, unsigned argc, Value* vp) { return true; } -static bool WasmBulkMemSupported(JSContext* cx, unsigned argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); -#ifdef ENABLE_WASM_BULKMEM_OPS - bool isSupported = true; -# ifdef ENABLE_WASM_CRANELIFT - if (cx->options().wasmCranelift()) { - isSupported = false; - } -# endif -#else - bool isSupported = - cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled(); -#endif - args.rval().setBoolean(isSupported); - return true; -} - static bool WasmReftypesEnabled(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setBoolean(wasm::ReftypesAvailable(cx)); @@ -788,12 +856,6 @@ static bool WasmMultiValueEnabled(JSContext* cx, unsigned argc, Value* vp) { return true; } -static bool WasmBigIntEnabled(JSContext* cx, unsigned argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - args.rval().setBoolean(wasm::I64BigIntConversionAvailable(cx)); - return true; -} - static bool WasmCompilersPresent(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -832,30 +894,32 @@ static bool WasmCompileMode(JSContext* cx, unsigned argc, Value* vp) { bool baseline = wasm::BaselineAvailable(cx); bool ion = wasm::IonAvailable(cx); bool cranelift = wasm::CraneliftAvailable(cx); + bool none = !baseline && !ion && !cranelift; + bool tiered = baseline && (ion || cranelift); MOZ_ASSERT(!(ion && cranelift)); - JSString* result; - if (!wasm::HasSupport(cx)) { - result = JS_NewStringCopyZ(cx, "none"); - } else if (baseline && ion) { - result = JS_NewStringCopyZ(cx, "baseline+ion"); - } else if (baseline && cranelift) { - result = JS_NewStringCopyZ(cx, "baseline+cranelift"); - } else if (baseline) { - result = JS_NewStringCopyZ(cx, "baseline"); - } else if (cranelift) { - result = JS_NewStringCopyZ(cx, "cranelift"); - } else { - result = JS_NewStringCopyZ(cx, "ion"); + JSStringBuilder result(cx); + if (none && !result.append("none", 4)) { + return false; } - - if (!result) { + if (baseline && !result.append("baseline", 8)) { return false; } - - args.rval().setString(result); - return true; + if (tiered && !result.append("+", 1)) { + return false; + } + if (ion && !result.append("ion", 3)) { + return false; + } + if (cranelift && !result.append("cranelift", 9)) { + return false; + } + if (JSString* str = result.finishString()) { + args.rval().setString(str); + return true; + } + return false; } static bool WasmCraneliftDisabledByFeatures(JSContext* cx, unsigned argc, @@ -970,6 +1034,159 @@ static bool WasmExtractCode(JSContext* cx, unsigned argc, Value* vp) { return true; } +struct DisasmBuffer { + JSStringBuilder builder; + bool oom; + explicit DisasmBuffer(JSContext* cx) : builder(cx), oom(false) {} +}; + +MOZ_THREAD_LOCAL(DisasmBuffer*) disasmBuf; + +static void captureDisasmText(const char* text) { + DisasmBuffer* buf = disasmBuf.get(); + if (!buf->builder.append(text, strlen(text)) || !buf->builder.append('\n')) { + buf->oom = true; + } +} + +static bool DisassembleNative(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + args.rval().setUndefined(); + + if (args.length() < 1) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_MORE_ARGS_NEEDED, "disnative", "1", "", + "0"); + return false; + } + + if (!args[0].isObject() || !args[0].toObject().is()) { + JS_ReportErrorASCII(cx, "The first argument must be a function."); + return false; + } + + Sprinter sprinter(cx); + if (!sprinter.init()) { + return false; + } + + RootedFunction fun(cx, &args[0].toObject().as()); + + uint8_t* jit_begin = nullptr; + uint8_t* jit_end = nullptr; + + if (fun->isAsmJSNative() || fun->isWasmWithJitEntry()) { + if (fun->isAsmJSNative() && !sprinter.jsprintf("; backend=asmjs\n")) { + return false; + } + if (!sprinter.jsprintf("; backend=wasm\n")) { + return false; + } + + const Value& v2 = + fun->getExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT); + + WasmInstanceObject* instobj = &v2.toObject().as(); + js::wasm::Instance& inst = instobj->instance(); + const js::wasm::Code& code = inst.code(); + js::wasm::Tier tier = code.bestTier(); + + const js::wasm::MetadataTier& meta = inst.metadata(tier); + + const js::wasm::CodeSegment& segment = code.segment(tier); + const uint32_t funcIndex = code.getFuncIndex(&*fun); + const js::wasm::FuncExport& func = meta.lookupFuncExport(funcIndex); + const js::wasm::CodeRange& codeRange = meta.codeRange(func); + + jit_begin = segment.base() + codeRange.begin(); + jit_end = segment.base() + codeRange.end(); + } else if (fun->hasJitScript()) { + JSScript* script = fun->nonLazyScript(); + if (script == nullptr) { + return false; + } + + js::jit::IonScript* ion = + script->hasIonScript() ? script->ionScript() : nullptr; + js::jit::BaselineScript* baseline = + script->hasBaselineScript() ? script->baselineScript() : nullptr; + if (ion && ion->method()) { + if (!sprinter.jsprintf("; backend=ion\n")) { + return false; + } + + jit_begin = ion->method()->raw(); + jit_end = ion->method()->rawEnd(); + } else if (baseline) { + if (!sprinter.jsprintf("; backend=baseline\n")) { + return false; + } + + jit_begin = baseline->method()->raw(); + jit_end = baseline->method()->rawEnd(); + } + } else { + return false; + } + + if (jit_begin == nullptr || jit_end == nullptr) { + return false; + } + + DisasmBuffer buf(cx); + disasmBuf.set(&buf); + auto onFinish = mozilla::MakeScopeExit([&] { disasmBuf.set(nullptr); }); + + jit::Disassemble(jit_begin, jit_end - jit_begin, &captureDisasmText); + + if (buf.oom) { + ReportOutOfMemory(cx); + return false; + } + JSString* sresult = buf.builder.finishString(); + if (!sresult) { + ReportOutOfMemory(cx); + return false; + } + sprinter.putString(sresult); + + if (args.length() > 1 && args[1].isString()) { + RootedString str(cx, args[1].toString()); + JS::UniqueChars fileNameBytes = JS_EncodeStringToUTF8(cx, str); + + const char* fileName = fileNameBytes.get(); + if (!fileName) { + ReportOutOfMemory(cx); + return false; + } + + FILE* f = fopen(fileName, "w"); + if (!f) { + JS_ReportErrorASCII(cx, "Could not open file for writing."); + return false; + } + + uintptr_t expected_length = reinterpret_cast(jit_end) - + reinterpret_cast(jit_begin); + if (expected_length != fwrite(jit_begin, jit_end - jit_begin, 1, f)) { + JS_ReportErrorASCII(cx, "Did not write all function bytes to the file."); + fclose(f); + return false; + } + fclose(f); + } + + JSString* str = JS_NewStringCopyZ(cx, sprinter.string()); + if (!str) { + return false; + } + + args[0].setUndefined(); + args.rval().setString(str); + + return true; +} + static bool WasmDisassemble(JSContext* cx, unsigned argc, Value* vp) { if (!cx->options().wasm()) { JS_ReportErrorASCII(cx, "wasm support unavailable"); @@ -1008,10 +1225,27 @@ static bool WasmDisassemble(JSContext* cx, unsigned argc, Value* vp) { return false; } + if (args.length() > 2 && args[2].isBoolean() && args[2].toBoolean()) { + DisasmBuffer buf(cx); + disasmBuf.set(&buf); + auto onFinish = mozilla::MakeScopeExit([&] { disasmBuf.set(nullptr); }); + instance.disassembleExport(cx, funcIndex, tier, captureDisasmText); + if (buf.oom) { + ReportOutOfMemory(cx); + return false; + } + JSString* sresult = buf.builder.finishString(); + if (!sresult) { + ReportOutOfMemory(cx); + return false; + } + args.rval().setString(sresult); + return true; + } + instance.disassembleExport(cx, funcIndex, tier, [](const char* text) { fprintf(stderr, "%s\n", text); }); - return true; } @@ -1414,14 +1648,14 @@ static bool FinishGC(JSContext* cx, unsigned argc, Value* vp) { static bool GCSlice(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() > 1) { + if (args.length() > 2) { RootedObject callee(cx, &args.callee()); ReportUsageErrorASCII(cx, callee, "Wrong number of arguments"); return false; } auto budget = SliceBudget::unlimited(); - if (args.length() == 1) { + if (args.length() >= 1) { uint32_t work = 0; if (!ToUint32(cx, args[0], &work)) { return false; @@ -1429,11 +1663,21 @@ static bool GCSlice(JSContext* cx, unsigned argc, Value* vp) { budget = SliceBudget(WorkBudget(work)); } + bool dontStart = false; + if (args.get(1).isObject()) { + RootedObject options(cx, &args[1].toObject()); + RootedValue v(cx); + if (!JS_GetProperty(cx, options, "dontStart", &v)) { + return false; + } + dontStart = ToBoolean(v); + } + JSRuntime* rt = cx->runtime(); - if (!rt->gc.isIncrementalGCInProgress()) { - rt->gc.startDebugGC(GC_NORMAL, budget); - } else { + if (rt->gc.isIncrementalGCInProgress()) { rt->gc.debugGCSlice(budget); + } else if (!dontStart) { + rt->gc.startDebugGC(GC_NORMAL, budget); } args.rval().setUndefined(); @@ -1756,70 +2000,95 @@ struct TestExternalString : public JSExternalStringCallbacks { static constexpr TestExternalString TestExternalStringCallbacks; -static bool NewExternalString(JSContext* cx, unsigned argc, Value* vp) { +static bool NewString(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() != 1 || !args[0].isString()) { - JS_ReportErrorASCII(cx, - "newExternalString takes exactly one string argument."); + RootedString src(cx, ToString(cx, args.get(0))); + if (!src) { return false; } - RootedString str(cx, args[0].toString()); - size_t len = str->length(); + gc::InitialHeap heap = gc::DefaultHeap; + bool wantTwoByte = false; + bool forceExternal = false; + bool maybeExternal = false; - auto buf = cx->make_pod_array(len); - if (!buf) { - return false; - } - - if (!JS_CopyStringChars(cx, mozilla::Range(buf.get(), len), str)) { - return false; - } + if (args.get(1).isObject()) { + RootedObject options(cx, &args[1].toObject()); + RootedValue v(cx); + bool requestTenured = false; + struct Setting { + const char* name; + bool* value; + }; + for (auto [name, setting] : + {Setting{"tenured", &requestTenured}, Setting{"twoByte", &wantTwoByte}, + Setting{"external", &forceExternal}, + Setting{"maybeExternal", &maybeExternal}}) { + if (!JS_GetProperty(cx, options, name, &v)) { + return false; + } + *setting = ToBoolean(v); // false if not given (or otherwise undefined) + } - JSString* res = - JS_NewExternalString(cx, buf.get(), len, &TestExternalStringCallbacks); - if (!res) { - return false; + heap = requestTenured ? gc::TenuredHeap : gc::DefaultHeap; + if (forceExternal || maybeExternal) { + wantTwoByte = true; + } } - mozilla::Unused << buf.release(); - args.rval().setString(res); - return true; -} - -static bool NewMaybeExternalString(JSContext* cx, unsigned argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - - if (args.length() != 1 || !args[0].isString()) { - JS_ReportErrorASCII( - cx, "newMaybeExternalString takes exactly one string argument."); - return false; - } + auto len = src->length(); + RootedString dest(cx); - RootedString str(cx, args[0].toString()); - size_t len = str->length(); + if (forceExternal || maybeExternal) { + auto buf = cx->make_pod_array(len); + if (!buf) { + return false; + } - auto buf = cx->make_pod_array(len); - if (!buf) { - return false; - } + if (!JS_CopyStringChars(cx, mozilla::Range(buf.get(), len), + src)) { + return false; + } - if (!JS_CopyStringChars(cx, mozilla::Range(buf.get(), len), str)) { - return false; + bool isExternal = true; + if (forceExternal) { + dest = JSExternalString::new_(cx, buf.get(), len, + &TestExternalStringCallbacks); + } else { + dest = NewMaybeExternalString( + cx, buf.get(), len, &TestExternalStringCallbacks, &isExternal, heap); + } + if (dest && isExternal) { + mozilla::Unused << buf.release(); // Ownership was transferred. + } + } else { + AutoStableStringChars stable(cx); + if (!wantTwoByte && src->hasLatin1Chars()) { + if (!stable.init(cx, src)) { + return false; + } + } else { + if (!stable.initTwoByte(cx, src)) { + return false; + } + } + if (wantTwoByte) { + dest = NewStringCopyNDontDeflate(cx, stable.twoByteChars(), len, + heap); + } else if (stable.isLatin1()) { + dest = NewStringCopyN(cx, stable.latin1Chars(), len, heap); + } else { + // Normal behavior: auto-deflate to latin1 if possible. + dest = NewStringCopyN(cx, stable.twoByteChars(), len, heap); + } } - bool allocatedExternal; - JSString* res = JS_NewMaybeExternalString( - cx, buf.get(), len, &TestExternalStringCallbacks, &allocatedExternal); - if (!res) { + if (!dest) { return false; } - if (allocatedExternal) { - mozilla::Unused << buf.release(); - } - args.rval().setString(res); + args.rval().setString(dest); return true; } @@ -3942,29 +4211,20 @@ static bool FindPath(JSContext* cx, unsigned argc, Value* vp) { static bool ShortestPaths(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (!args.requireAtLeast(cx, "shortestPaths", 3)) { + if (!args.requireAtLeast(cx, "shortestPaths", 1)) { return false; } - // We don't ToString non-objects given as 'start' or 'target', because this - // test is all about object identity, and ToString doesn't preserve that. - // Non-GCThing endpoints don't make much sense. - if (!args[0].isObject() && !args[0].isString() && !args[0].isSymbol()) { + if (!args[0].isObject() || !args[0].toObject().is()) { ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], - nullptr, "not an object, string, or symbol"); - return false; - } - - if (!args[1].isObject() || !args[1].toObject().is()) { - ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], nullptr, "not an array object"); return false; } - RootedArrayObject objs(cx, &args[1].toObject().as()); + RootedArrayObject objs(cx, &args[0].toObject().as()); size_t length = objs->getDenseInitializedLength(); if (length == 0) { - ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], + ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr, "not a dense array object with one or more elements"); return false; @@ -3979,14 +4239,46 @@ static bool ShortestPaths(JSContext* cx, unsigned argc, Value* vp) { } } - int32_t maxNumPaths; - if (!JS::ToInt32(cx, args[2], &maxNumPaths)) { - return false; - } - if (maxNumPaths <= 0) { - ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[2], - nullptr, "not greater than 0"); - return false; + RootedValue start(cx, NullValue()); + int32_t maxNumPaths = 3; + + if (!args.get(1).isUndefined()) { + if (!args[1].isObject()) { + ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], + nullptr, "not an options object"); + return false; + } + + RootedObject options(cx, &args[1].toObject()); + bool exists; + if (!JS_HasProperty(cx, options, "start", &exists)) { + return false; + } + if (exists) { + if (!JS_GetProperty(cx, options, "start", &start)) { + return false; + } + + // Non-GCThing endpoints don't make much sense. + if (!start.isGCThing()) { + ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, start, + nullptr, "not a GC thing"); + return false; + } + } + + RootedValue v(cx, Int32Value(maxNumPaths)); + if (!JS_GetProperty(cx, options, "maxNumPaths", &v)) { + return false; + } + if (!JS::ToInt32(cx, v, &maxNumPaths)) { + return false; + } + if (maxNumPaths <= 0) { + ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, v, + nullptr, "not greater than 0"); + return false; + } } // We accumulate the results into a GC-stable form, due to the fact that the @@ -3997,7 +4289,21 @@ static bool ShortestPaths(JSContext* cx, unsigned argc, Value* vp) { Vector>> names(cx); { - JS::AutoCheckCannotGC noGC(cx); + mozilla::Maybe maybeNoGC; + mozilla::Maybe maybeRoot; + + JS::ubi::RootList rootList(cx, maybeNoGC, true); + if (start.isNull()) { + if (!rootList.init()) { + ReportOutOfMemory(cx); + return false; + } + maybeRoot.emplace(&rootList); + } else { + maybeNoGC.emplace(cx); + maybeRoot.emplace(start); + } + JS::AutoCheckCannotGC& noGC = maybeNoGC.ref(); JS::ubi::NodeSet targets; @@ -4010,7 +4316,7 @@ static bool ShortestPaths(JSContext* cx, unsigned argc, Value* vp) { } } - JS::ubi::Node root(args[0]); + JS::ubi::Node& root = maybeRoot.ref(); auto maybeShortestPaths = JS::ubi::ShortestPaths::Create( cx, noGC, maxNumPaths, root, std::move(targets)); if (maybeShortestPaths.isNothing()) { @@ -4149,13 +4455,14 @@ static bool EvalReturningScope(JSContext* cx, unsigned argc, Value* vp) { JS::CompileOptions options(cx); options.setFileAndLine(filename.get(), lineno); options.setNoScriptRval(true); + options.setNonSyntacticScope(true); JS::SourceText srcBuf; if (!srcBuf.init(cx, src, srclen, SourceOwnership::Borrowed)) { return false; } - RootedScript script(cx, JS::CompileForNonSyntacticScope(cx, options, srcBuf)); + RootedScript script(cx, JS::Compile(cx, options, srcBuf)); if (!script) { return false; } @@ -4375,6 +4682,34 @@ static bool DumpStringRepresentation(JSContext* cx, unsigned argc, Value* vp) { args.rval().setUndefined(); return true; } + +static bool GetStringRepresentation(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + RootedString str(cx, ToString(cx, args.get(0))); + if (!str) { + return false; + } + + Sprinter out(cx, true); + if (!out.init()) { + return false; + } + str->dumpRepresentation(out, 0); + + if (out.hadOutOfMemory()) { + return false; + } + + JSString* rep = JS_NewStringCopyN(cx, out.string(), out.getOffset()); + if (!rep) { + return false; + } + + args.rval().setString(rep); + return true; +} + #endif static bool SetLazyParsingDisabled(JSContext* cx, unsigned argc, Value* vp) { @@ -4786,6 +5121,10 @@ static bool GetModuleEnvironmentNames(JSContext* cx, unsigned argc, Value* vp) { return false; } + // The "*namespace*" binding is a detail of current implementation so hide + // it to give stable results in tests. + ids.eraseIfEqual(NameToId(cx->names().starNamespaceStar)); + uint32_t length = ids.length(); RootedArrayObject array(cx, NewDenseFullyAllocatedArray(cx, length)); if (!array) { @@ -5466,11 +5805,12 @@ JSScript* js::TestingFunctionArgumentToScript( JSContext* cx, HandleValue v, JSFunction** funp /* = nullptr */) { if (v.isString()) { // To convert a string to a script, compile it. Parse it as an ES6 Program. - RootedLinearString linearStr(cx, StringToLinearString(cx, v.toString())); + RootedLinearString linearStr(cx, + JS::StringToLinearString(cx, v.toString())); if (!linearStr) { return nullptr; } - size_t len = GetLinearStringLength(linearStr); + size_t len = JS::GetLinearStringLength(linearStr); AutoStableStringChars linearChars(cx); if (!linearChars.initTwoByte(cx, linearStr)) { return nullptr; @@ -5620,23 +5960,75 @@ static bool ClearKeptObjects(JSContext* cx, unsigned argc, Value* vp) { return true; } -static bool NewPrivateName(JSContext* cx, unsigned argc, Value* vp) { +static bool NumberToDouble(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - if (!args.requireAtLeast(cx, "newPrivateName", 1)) { + if (!args.requireAtLeast(cx, "numberToDouble", 1)) { return false; } - RootedString desc(cx, ToString(cx, args[0])); - if (!desc) { + if (!args[0].isNumber()) { + RootedObject callee(cx, &args.callee()); + ReportUsageErrorASCII(cx, callee, "argument must be a number"); return false; } - auto* sym = JS::Symbol::new_(cx, JS::SymbolCode::PrivateNameSymbol, desc); - if (!sym) { + args.rval().setDouble(args[0].toNumber()); + return true; +} + +static bool GetICUOptions(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + + RootedObject info(cx, JS_NewPlainObject(cx)); + if (!info) { return false; } - args.rval().setSymbol(sym); +#ifdef JS_HAS_INTL_API + RootedString str(cx); + + str = NewStringCopyZ(cx, U_ICU_VERSION); + if (!str || !JS_DefineProperty(cx, info, "version", str, JSPROP_ENUMERATE)) { + return false; + } + + str = NewStringCopyZ(cx, U_UNICODE_VERSION); + if (!str || !JS_DefineProperty(cx, info, "unicode", str, JSPROP_ENUMERATE)) { + return false; + } + + str = NewStringCopyZ(cx, uloc_getDefault()); + if (!str || !JS_DefineProperty(cx, info, "locale", str, JSPROP_ENUMERATE)) { + return false; + } + + UErrorCode status = U_ZERO_ERROR; + const char* tzdataVersion = ucal_getTZDataVersion(&status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + str = NewStringCopyZ(cx, tzdataVersion); + if (!str || !JS_DefineProperty(cx, info, "tzdata", str, JSPROP_ENUMERATE)) { + return false; + } + + str = intl::CallICU(cx, ucal_getDefaultTimeZone); + if (!str || !JS_DefineProperty(cx, info, "timezone", str, JSPROP_ENUMERATE)) { + return false; + } + +# ifndef U_HIDE_DRAFT_API + str = intl::CallICU(cx, ucal_getHostTimeZone); + if (!str || + !JS_DefineProperty(cx, info, "host-timezone", str, JSPROP_ENUMERATE)) { + return false; + } +# endif +#endif + + args.rval().setObject(*info); return true; } @@ -5735,10 +6127,18 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { " Run a minor collector on the Nursery. When aboutToOverflow is true, marks\n" " the store buffer as about-to-overflow before collecting."), + JS_FN_HELP("maybegc", ::MaybeGC, 0, 0, +"maybegc()", +" Hint to the engine that now is an ok time to run the garbage collector.\n"), + JS_FN_HELP("gcparam", GCParameter, 2, 0, "gcparam(name [, value])", " Wrapper for JS_[GS]etGCParameter. The name is one of:" GC_PARAMETER_ARGS_LIST), + JS_FN_HELP("disnative", DisassembleNative, 2, 0, +"disnative(fun,[path])", +" Disassemble a function into its native code. Optionally write the native code bytes to a file on disk.\n"), + JS_FN_HELP("relazifyFunctions", RelazifyFunctions, 0, 0, "relazifyFunctions(...)", " Perform a GC and allow relazification of functions. Accepts the same\n" @@ -5749,6 +6149,11 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { " Return an object describing some of the configuration options SpiderMonkey\n" " was built with."), + JS_FN_HELP("getRealmConfiguration", GetRealmConfiguration, 0, 0, +"getRealmConfiguration()", +" Return an object describing some of the runtime options SpiderMonkey\n" +" is running with."), + JS_FN_HELP("isLcovEnabled", ::IsLCovEnabled, 0, 0, "isLcovEnabled()", " Return true if JS LCov support is enabled."), @@ -5757,6 +6162,10 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { "isTypeInferenceEnabled()", " Return true if Type Inference is enabled."), + JS_FN_HELP("trialInline", TrialInline, 0, 0, +"trialInline()", +" Perform trial-inlining for the caller's frame if it's a BaselineFrame."), + JS_FN_HELP("hasChild", HasChild, 0, 0, "hasChild(parent, child)", " Return true if |child| is a child of |parent|, as determined by a call to\n" @@ -5816,13 +6225,21 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = { " Set the filename validation callback to a callback that accepts only\n" " filenames starting with 'safe' or (only in system realms) 'system'."), - JS_FN_HELP("newExternalString", NewExternalString, 1, 0, -"newExternalString(str)", -" Copies str's chars and returns a new external string."), - - JS_FN_HELP("newMaybeExternalString", NewMaybeExternalString, 1, 0, -"newMaybeExternalString(str)", -" Like newExternalString but uses the JS_NewMaybeExternalString API."), + JS_FN_HELP("newString", NewString, 2, 0, +"newString(str[, options])", +" Copies str's chars and returns a new string. Valid options:\n" +" \n" +" - tenured: allocate directly into the tenured heap.\n" +" \n" +" - twoByte: create a \"two byte\" string, not a latin1 string, regardless of the\n" +" input string's characters. Latin1 will be used by default if possible\n" +" (again regardless of the input string.)\n" +" \n" +" - external: create an external string. External strings are always twoByte and\n" +" tenured.\n" +" \n" +" - maybeExternal: create an external string, unless the data fits within an\n" +" inline string. Inline strings may be nursery-allocated."), JS_FN_HELP("ensureLinearString", EnsureLinearString, 1, 0, "ensureLinearString(str)", @@ -5997,15 +6414,19 @@ gc::ZealModeHelpText), " Start an incremental GC and run a slice that processes about n objects.\n" " If 'shrinking' is passesd as the optional second argument, perform a\n" " shrinking GC rather than a normal GC. If no zones have been selected with\n" -" schedulegc(), a full GC will be performed."), +" schedulezone(), a full GC will be performed."), JS_FN_HELP("finishgc", FinishGC, 0, 0, "finishgc()", " Finish an in-progress incremental GC, if none is running then do nothing."), JS_FN_HELP("gcslice", GCSlice, 1, 0, -"gcslice([n])", -" Start or continue an an incremental GC, running a slice that processes about n objects."), +"gcslice([n [, options]])", +" Start or continue an an incremental GC, running a slice that processes\n" +" about n objects. Takes an optional options object, which may contain the\n" +" following properties:\n" +" dontStart: do not start a new incremental GC if one is not already\n" +" running"), JS_FN_HELP("abortgc", AbortGC, 1, 0, "abortgc()", @@ -6102,11 +6523,6 @@ gc::ZealModeHelpText), JS_FN_HELP("wasmThreadsSupported", WasmThreadsSupported, 0, 0, "wasmThreadsSupported()", " Returns a boolean indicating whether the WebAssembly threads proposal is\n" -" supported on the current device."), - - JS_FN_HELP("wasmBulkMemSupported", WasmBulkMemSupported, 0, 0, -"wasmBulkMemSupported()", -" Returns a boolean indicating whether the WebAssembly bulk memory proposal is\n" " supported on the current device."), JS_FN_HELP("wasmCompilersPresent", WasmCompilersPresent, 0, 0, @@ -6143,10 +6559,11 @@ gc::ZealModeHelpText), " until background compilation is complete."), JS_FN_HELP("wasmDis", WasmDisassemble, 1, 0, -"wasmDis(function[, tier])", +"wasmDis(function[, tier [, asString]])", " Disassembles generated machine code from an exported WebAssembly function.\n" " The tier is a string, 'stable', 'best', 'baseline', or 'ion'; the default is\n" -" 'stable'."), +" 'stable'. If `asString` is present and is the value `true` then the output\n" +" is returned as a string; otherwise it is printed on stderr."), JS_FN_HELP("wasmHasTier2CompilationCompleted", WasmHasTier2CompilationCompleted, 1, 0, "wasmHasTier2CompilationCompleted(module)", @@ -6170,10 +6587,6 @@ gc::ZealModeHelpText), "wasmMultiValueEnabled()", " Returns a boolean indicating whether the WebAssembly multi-value proposal is enabled."), - JS_FN_HELP("wasmBigIntEnabled", WasmBigIntEnabled, 1, 0, -"wasmBigIntEnabled()", -" Returns a boolean indicating whether the WebAssembly I64 to BigInt proposal is enabled."), - JS_FN_HELP("isLazyFunction", IsLazyFunction, 1, 0, "isLazyFunction(fun)", " True if fun is a lazy JSFunction."), @@ -6298,11 +6711,15 @@ gc::ZealModeHelpText), " the last array element is implicitly |target|.\n"), JS_FN_HELP("shortestPaths", ShortestPaths, 3, 0, -"shortestPaths(start, targets, maxNumPaths)", +"shortestPaths(targets, options)", " Return an array of arrays of shortest retaining paths. There is an array of\n" -" shortest retaining paths for each object in |targets|. The maximum number of\n" -" paths in each of those arrays is bounded by |maxNumPaths|. Each element in a\n" -" path is of the form |{ predecessor, edge }|."), +" shortest retaining paths for each object in |targets|. Each element in a path\n" +" is of the form |{ predecessor, edge }|. |options| may contain:\n" +" \n" +" maxNumPaths: The maximum number of paths returned in each of those arrays\n" +" (default 3).\n" +" start: The object to start all paths from. If not given, then\n" +" the starting point will be the set of GC roots."), #if defined(DEBUG) || defined(JS_JITSPEW) JS_FN_HELP("dumpObject", DumpObject, 1, 0, @@ -6350,7 +6767,7 @@ gc::ZealModeHelpText), JS_FN_HELP("getBacktrace", GetBacktrace, 1, 0, "getBacktrace([options])", " Return the current stack as a string. Takes an optional options object,\n" -" which may contain any or all of the boolean properties\n" +" which may contain any or all of the boolean properties:\n" " options.args - show arguments to each function\n" " options.locals - show local variables in each frame\n" " options.thisprops - show the properties of the 'this' object of each frame\n"), @@ -6376,6 +6793,11 @@ gc::ZealModeHelpText), JS_FN_HELP("dumpStringRepresentation", DumpStringRepresentation, 1, 0, "dumpStringRepresentation(str)", " Print a human-readable description of how the string |str| is represented.\n"), + + JS_FN_HELP("stringRepresentation", GetStringRepresentation, 1, 0, +"stringRepresentation(str)", +" Return a human-readable description of how the string |str| is represented.\n"), + #endif JS_FN_HELP("setLazyParsingDisabled", SetLazyParsingDisabled, 1, 0, @@ -6560,9 +6982,20 @@ gc::ZealModeHelpText), "sequence of ECMAScript execution completes. This is used for testing\n" "WeakRefs.\n"), - JS_FN_HELP("newPrivateName", NewPrivateName, 1, 0, -"newPrivateName(desc)", -"Create a new PrivateName symbol."), + + JS_FN_HELP("numberToDouble", NumberToDouble, 1, 0, +"numberToDouble(number)", +" Return the input number as double-typed number."), + +JS_FN_HELP("getICUOptions", GetICUOptions, 0, 0, +"getICUOptions()", +" Return an object describing the following ICU options.\n\n" +" version: a string containing the ICU version number, e.g. '67.1'\n" +" unicode: a string containing the Unicode version number, e.g. '13.0'\n" +" locale: the ICU default locale, e.g. 'en_US'\n" +" tzdata: a string containing the tzdata version number, e.g. '2020a'\n" +" timezone: the ICU default time zone, e.g. 'America/Los_Angeles'\n" +" host-timezone: the host time zone, e.g. 'America/Los_Angeles'"), JS_FS_HELP_END }; @@ -6622,6 +7055,8 @@ static const JSFunctionSpecWithHelp PCCountProfilingTestingFunctions[] = { }; // clang-format on +bool js::InitTestingFunctions() { return disasmBuf.init(); } + bool js::DefineTestingFunctions(JSContext* cx, HandleObject obj, bool fuzzingSafe_, bool disableOOMFunctions_) { fuzzingSafe = fuzzingSafe_; diff --git a/js/src/builtin/TestingFunctions.h b/js/src/builtin/TestingFunctions.h index bceea3f857..b5d6bc0ba0 100644 --- a/js/src/builtin/TestingFunctions.h +++ b/js/src/builtin/TestingFunctions.h @@ -9,6 +9,8 @@ namespace js { +MOZ_MUST_USE bool InitTestingFunctions(); + MOZ_MUST_USE bool DefineTestingFunctions(JSContext* cx, HandleObject obj, bool fuzzingSafe, bool disableOOMFunctions); diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 65f712c318..ab7cac3d70 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -12,6 +12,7 @@ #include "gc/Marking.h" #include "js/CharacterEncoding.h" #include "js/PropertySpec.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "js/Vector.h" #include "util/StringBuffer.h" #include "vm/GlobalObject.h" @@ -23,6 +24,7 @@ #include "vm/StringType.h" #include "vm/TypedArrayObject.h" +#include "gc/Marking-inl.h" #include "gc/Nursery-inl.h" #include "gc/StoreBuffer-inl.h" #include "vm/JSAtom-inl.h" @@ -1719,8 +1721,9 @@ void OutlineTypedObject::obj_trace(JSTracer* trc, JSObject* object) { // Update the data pointer if the owner moved and the owner's data is // inline with it. - if (owner != oldOwner && (owner->is() || - owner->as().hasInlineData())) { + if (owner != oldOwner && + (IsInlineTypedObjectClass(gc::MaybeForwardedObjectClass(owner)) || + gc::MaybeForwardedObjectAs(owner).hasInlineData())) { newData += reinterpret_cast(owner) - reinterpret_cast(oldOwner); typedObj.setData(newData); @@ -1736,6 +1739,11 @@ void OutlineTypedObject::obj_trace(JSTracer* trc, JSObject* object) { return; } + if (descr.hasTraceList()) { + gc::VisitTraceList(trc, object, descr.traceList(), newData); + return; + } + descr.traceInstance(trc, newData); } @@ -2191,7 +2199,14 @@ void InlineTypedObject::obj_trace(JSTracer* trc, JSObject* object) { return; } - typedObj.typeDescr().traceInstance(trc, typedObj.inlineTypedMem()); + TypeDescr& descr = typedObj.typeDescr(); + if (descr.hasTraceList()) { + gc::VisitTraceList(trc, object, typedObj.typeDescr().traceList(), + typedObj.inlineTypedMem()); + return; + } + + descr.traceInstance(trc, typedObj.inlineTypedMem()); } /* static */ @@ -2322,7 +2337,7 @@ bool TypedObject::construct(JSContext* cx, unsigned int argc, Value* vp) { return false; } -/* static */ JS::Result TypedObject::create( +/* static */ JS::Result TypedObject::create( JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap, js::HandleShape shape, js::HandleObjectGroup group) { debugCheckNewObject(group, shape, kind, heap); @@ -2694,7 +2709,8 @@ JS_FOR_EACH_REFERENCE_TYPE_REPR(JS_LOAD_REFERENCE_CLASS_IMPL) // Walking memory template -static void visitReferences(TypeDescr& descr, uint8_t* mem, V& visitor) { +static void VisitReferences(TypeDescr& descr, uint8_t* base, V& visitor, + size_t offset) { if (descr.transparent()) { return; } @@ -2704,15 +2720,15 @@ static void visitReferences(TypeDescr& descr, uint8_t* mem, V& visitor) { return; case type::Reference: - visitor.visitReference(descr.as(), mem); + visitor.visitReference(descr.as(), base, offset); return; case type::Array: { ArrayTypeDescr& arrayDescr = descr.as(); TypeDescr& elementDescr = arrayDescr.elementType(); for (uint32_t i = 0; i < arrayDescr.length(); i++) { - visitReferences(elementDescr, mem, visitor); - mem += elementDescr.size(); + VisitReferences(elementDescr, base, visitor, offset); + offset += elementDescr.size(); } return; } @@ -2721,8 +2737,8 @@ static void visitReferences(TypeDescr& descr, uint8_t* mem, V& visitor) { StructTypeDescr& structDescr = descr.as(); for (size_t i = 0; i < structDescr.fieldCount(); i++) { TypeDescr& descr = structDescr.fieldDescr(i); - size_t offset = structDescr.fieldOffset(i); - visitReferences(descr, mem + offset, visitor); + VisitReferences(descr, base, visitor, + offset + structDescr.fieldOffset(i)); } return; } @@ -2742,29 +2758,32 @@ class MemoryInitVisitor { public: explicit MemoryInitVisitor(const JSRuntime* rt) : rt_(rt) {} - void visitReference(ReferenceTypeDescr& descr, uint8_t* mem); + void visitReference(ReferenceTypeDescr& descr, uint8_t* base, size_t offset); }; } // namespace -void MemoryInitVisitor::visitReference(ReferenceTypeDescr& descr, - uint8_t* mem) { +void MemoryInitVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* base, + size_t offset) { switch (descr.type()) { case ReferenceType::TYPE_ANY: { - js::GCPtrValue* heapValue = reinterpret_cast(mem); + js::GCPtrValue* heapValue = + reinterpret_cast(base + offset); heapValue->init(UndefinedValue()); return; } case ReferenceType::TYPE_WASM_ANYREF: case ReferenceType::TYPE_OBJECT: { - js::GCPtrObject* objectPtr = reinterpret_cast(mem); + js::GCPtrObject* objectPtr = + reinterpret_cast(base + offset); objectPtr->init(nullptr); return; } case ReferenceType::TYPE_STRING: { - js::GCPtrString* stringPtr = reinterpret_cast(mem); + js::GCPtrString* stringPtr = + reinterpret_cast(base + offset); stringPtr->init(rt_->emptyString); return; } @@ -2779,7 +2798,7 @@ void TypeDescr::initInstance(const JSRuntime* rt, uint8_t* mem) { // Initialize the instance memset(mem, 0, size()); if (opaque()) { - visitReferences(*this, mem, visitor); + VisitReferences(*this, mem, visitor, 0); } } @@ -2794,16 +2813,16 @@ class MemoryTracingVisitor { public: explicit MemoryTracingVisitor(JSTracer* trace) : trace_(trace) {} - void visitReference(ReferenceTypeDescr& descr, uint8_t* mem); + void visitReference(ReferenceTypeDescr& descr, uint8_t* base, size_t offset); }; } // namespace void MemoryTracingVisitor::visitReference(ReferenceTypeDescr& descr, - uint8_t* mem) { + uint8_t* base, size_t offset) { switch (descr.type()) { case ReferenceType::TYPE_ANY: { - GCPtrValue* heapValue = reinterpret_cast(mem); + GCPtrValue* heapValue = reinterpret_cast(base + offset); TraceEdge(trace_, heapValue, "reference-val"); return; } @@ -2812,13 +2831,15 @@ void MemoryTracingVisitor::visitReference(ReferenceTypeDescr& descr, // TODO/AnyRef-boxing: With boxed immediates and strings the tracing code // will be more complicated. For now, tracing as an object is fine. case ReferenceType::TYPE_OBJECT: { - GCPtrObject* objectPtr = reinterpret_cast(mem); + GCPtrObject* objectPtr = + reinterpret_cast(base + offset); TraceNullableEdge(trace_, objectPtr, "reference-obj"); return; } case ReferenceType::TYPE_STRING: { - GCPtrString* stringPtr = reinterpret_cast(mem); + GCPtrString* stringPtr = + reinterpret_cast(base + offset); TraceNullableEdge(trace_, stringPtr, "reference-str"); return; } @@ -2830,24 +2851,29 @@ void MemoryTracingVisitor::visitReference(ReferenceTypeDescr& descr, void TypeDescr::traceInstance(JSTracer* trace, uint8_t* mem) { MemoryTracingVisitor visitor(trace); - visitReferences(*this, mem, visitor); + VisitReferences(*this, mem, visitor, 0); } namespace { struct TraceListVisitor { - typedef Vector VectorType; - VectorType stringOffsets, objectOffsets, valueOffsets; + using OffsetVector = Vector; + OffsetVector stringOffsets; + OffsetVector objectOffsets; + OffsetVector valueOffsets; - void visitReference(ReferenceTypeDescr& descr, uint8_t* mem); + void visitReference(ReferenceTypeDescr& descr, uint8_t* base, size_t offset); bool fillList(Vector& entries); }; } // namespace -void TraceListVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem) { - VectorType* offsets; +void TraceListVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* base, + size_t offset) { + MOZ_ASSERT(!base); + + OffsetVector* offsets; // TODO/AnyRef-boxing: Once a WasmAnyRef is no longer just a JSObject* // we must revisit this structure. switch (descr.type()) { @@ -2868,7 +2894,9 @@ void TraceListVisitor::visitReference(ReferenceTypeDescr& descr, uint8_t* mem) { } AutoEnterOOMUnsafeRegion oomUnsafe; - if (!offsets->append((uintptr_t)mem)) { + + MOZ_ASSERT(offset <= UINT32_MAX); + if (!offsets->append(offset)) { oomUnsafe.crash("TraceListVisitor::visitReference"); } } @@ -2891,7 +2919,7 @@ static bool CreateTraceList(JSContext* cx, HandleTypeDescr descr) { } TraceListVisitor visitor; - visitReferences(*descr, nullptr, visitor); + VisitReferences(*descr, nullptr, visitor, 0); Vector entries(cx); if (!visitor.fillList(entries)) { diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index 772efa170e..8b54735028 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -11,6 +11,8 @@ #include "gc/Allocator.h" #include "gc/WeakMap.h" #include "js/Conversions.h" +#include "js/experimental/JitInfo.h" // JSJitInfo +#include "js/ScalarType.h" // js::Scalar::Type #include "vm/ArrayBufferObject.h" #include "vm/JSObject.h" @@ -175,11 +177,11 @@ class TypeDescr : public NativeObject { MOZ_MUST_USE bool hasProperty(const JSAtomState& names, jsid id); // Type descriptors may contain a list of their references for use during - // scanning. Marking code is optimized to use this list to mark inline - // typed objects, rather than the slower trace hook. This list is only - // specified when (a) the descriptor is short enough that it can fit in an - // InlineTypedObject, and (b) the descriptor contains at least one - // reference. Otherwise its value is undefined. + // scanning. Typed object trace hooks can use this to call an optimized + // marking path that doesn't need to dispatch on the tracer kind for each + // edge. This list is only specified when (a) the descriptor is short enough + // that it can fit in an InlineTypedObject, and (b) the descriptor contains at + // least one reference. Otherwise its value is undefined. // // The list is three consecutive arrays of uint32_t offsets, preceded by a // header consisting of the length of each array. The arrays store offsets of @@ -597,11 +599,11 @@ class TypedObject : public JSObject { TypeDescr& typeDescr() const { return group()->typeDescr(); } - static JS::Result create(JSContext* cx, - js::gc::AllocKind kind, - js::gc::InitialHeap heap, - js::HandleShape shape, - js::HandleObjectGroup group); + static JS::Result create(JSContext* cx, + js::gc::AllocKind kind, + js::gc::InitialHeap heap, + js::HandleShape shape, + js::HandleObjectGroup group); uint32_t offset() const; uint32_t length() const; @@ -631,9 +633,7 @@ class TypedObject : public JSObject { // callee here is the type descriptor. static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp); - Shape** addressOfShapeFromGC() { - return shape_.unsafeUnbarrieredForTracing(); - } + Shape** addressOfShapeFromGC() { return shape_.unbarrieredAddress(); } }; using HandleTypedObject = Handle; @@ -746,8 +746,6 @@ class InlineTypedObject : public TypedObject { return inlineTypedMem(); } - uint8_t* inlineTypedMemForGC() const { return inlineTypedMem(); } - static void obj_trace(JSTracer* trace, JSObject* object); static size_t obj_moved(JSObject* dst, JSObject* src); @@ -1032,14 +1030,12 @@ inline bool JSObject::is() const { template <> inline bool JSObject::is() const { - return getClass() == &js::OutlineTransparentTypedObject::class_ || - getClass() == &js::OutlineOpaqueTypedObject::class_; + return js::IsOutlineTypedObjectClass(getClass()); } template <> inline bool JSObject::is() const { - return getClass() == &js::InlineTransparentTypedObject::class_ || - getClass() == &js::InlineOpaqueTypedObject::class_; + return js::IsInlineTypedObjectClass(getClass()); } #endif /* builtin_TypedObject_h */ diff --git a/js/src/builtin/Utilities.js b/js/src/builtin/Utilities.js index 940ba4c284..d60c4c949b 100644 --- a/js/src/builtin/Utilities.js +++ b/js/src/builtin/Utilities.js @@ -103,19 +103,6 @@ function IsPropertyKey(argument) { #define TO_PROPERTY_KEY(name) \ (typeof name !== "string" && typeof name !== "number" && typeof name !== "symbol" ? ToPropertyKey(name) : name) -var _builtinCtorsCache = {__proto__: null}; - -function GetBuiltinConstructor(builtinName) { - var ctor = _builtinCtorsCache[builtinName] || - (_builtinCtorsCache[builtinName] = GetBuiltinConstructorImpl(builtinName)); - assert(ctor, `No builtin with name "${builtinName}" found`); - return ctor; -} - -function GetBuiltinPrototype(builtinName) { - return (_builtinCtorsCache[builtinName] || GetBuiltinConstructor(builtinName)).prototype; -} - // ES 2016 draft Mar 25, 2016 7.3.20. function SpeciesConstructor(obj, defaultConstructor) { // Step 1. diff --git a/js/src/builtin/WeakMapObject.cpp b/js/src/builtin/WeakMapObject.cpp index 59d7b94730..5e19548a19 100644 --- a/js/src/builtin/WeakMapObject.cpp +++ b/js/src/builtin/WeakMapObject.cpp @@ -288,8 +288,8 @@ const JSClass WeakMapObject::class_ = { &WeakCollectionObject::classOps_, &WeakMapObject::classSpec_}; const JSClass WeakMapObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap), JS_NULL_CLASS_OPS, - &WeakMapObject::classSpec_}; + "WeakMap.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap), + JS_NULL_CLASS_OPS, &WeakMapObject::classSpec_}; const JSPropertySpec WeakMapObject::properties[] = { JS_STRING_SYM_PS(toStringTag, "WeakMap", JSPROP_READONLY), JS_PS_END}; diff --git a/js/src/builtin/WeakRefObject.cpp b/js/src/builtin/WeakRefObject.cpp index 0565542922..4128e7f430 100644 --- a/js/src/builtin/WeakRefObject.cpp +++ b/js/src/builtin/WeakRefObject.cpp @@ -4,6 +4,8 @@ #include "builtin/WeakRefObject.h" +#include "mozilla/Maybe.h" + #include "jsapi.h" #include "vm/GlobalObject.h" #include "vm/JSContext.h" @@ -72,19 +74,21 @@ bool WeakRefObject::construct(JSContext* cx, unsigned argc, Value* vp) { // 4. Perfom ! KeepDuringJob(target). if (!target->zone()->keepDuringJob(target)) { + ReportOutOfMemory(cx); return false; }; - // 5. Set weakRef.[[Target]] to target. - weakRef->setPrivateGCThing(target); - // Add an entry to the per-zone maps from target JS object to a list of weak // ref objects. gc::GCRuntime* gc = &cx->runtime()->gc; if (!gc->registerWeakRef(target, wrappedWeakRef)) { + ReportOutOfMemory(cx); return false; }; + // 5. Set weakRef.[[Target]] to target. + weakRef->setPrivateGCThing(target); + // 6. Return weakRef. args.rval().setObject(*weakRef); return true; @@ -116,17 +120,11 @@ void WeakRefObject::trace(JSTracer* trc, JSObject* obj) { /* static */ void WeakRefObject::finalize(JSFreeOp* fop, JSObject* obj) { - JSContext* cx = fop->runtime()->mainContextFromOwnThread(); - WeakRefObject* weakRef = &obj->as(); - JSObject* target = weakRef->target(); - if (!target) { - return; - } - - gc::GCRuntime* gc = &fop->runtime()->gc; - // TODO Bug 1602625: test unregisterWeakRef - // not tested, weakRef->target() has been swept. - gc->unregisterWeakRef(cx, target, weakRef); + // The target is cleared when the target's zone is swept and that always + // happens before this object is finalized because of the CCW from the target + // zone to this object. If the CCW is nuked, the target is cleared in + // NotifyGCNukeWrapper(). + MOZ_ASSERT(!obj->as().target()); } const JSClassOps WeakRefObject::classOps_ = { @@ -162,7 +160,7 @@ const JSClass WeakRefObject::class_ = { const JSClass WeakRefObject::protoClass_ = { // https://tc39.es/proposal-weakrefs/#sec-weak-ref.prototype // https://tc39.es/proposal-weakrefs/#sec-properties-of-the-weak-ref-prototype-object - "WeakRefPrototype", JSCLASS_HAS_CACHED_PROTO(JSProto_WeakRef), + "WeakRef.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_WeakRef), JS_NULL_CLASS_OPS, &classSpec_}; const JSPropertySpec WeakRefObject::properties[] = { @@ -191,6 +189,9 @@ bool WeakRefObject::deref(JSContext* cx, unsigned argc, Value* vp) { Rooted weakRef(cx, &args.thisv().toObject().as()); + // We need to perform a read barrier, which may clear the target. + readBarrier(cx, weakRef); + // 4. Let target be the value of weakRef.[[Target]]. // 5. If target is not empty, // a. Perform ! KeepDuringJob(target). @@ -206,9 +207,6 @@ bool WeakRefObject::deref(JSContext* cx, unsigned argc, Value* vp) { return false; } - // We need to perform a read barrier on the object. - JSObject::readBarrier(target); - // Target should be wrapped into the current realm before returning it. RootedObject wrappedTarget(cx, target); if (!JS_WrapObject(cx, &wrappedTarget)) { @@ -219,12 +217,30 @@ bool WeakRefObject::deref(JSContext* cx, unsigned argc, Value* vp) { return true; } -inline JSObject* WeakRefObject::target() { - return static_cast(getPrivate()); -} - void WeakRefObject::setTarget(JSObject* target) { setPrivate(target); } +/* static */ +void WeakRefObject::readBarrier(JSContext* cx, Handle self) { + RootedObject obj(cx, self->target()); + if (!obj) { + return; + } + + if (obj->getClass()->isDOMClass()) { + // We preserved the target when the WeakRef was created. If it has since + // been released then the DOM object it wraps has been collected, so clear + // the target. + MOZ_ASSERT(cx->runtime()->hasReleasedWrapperCallback); + bool wasReleased = cx->runtime()->hasReleasedWrapperCallback(obj); + if (wasReleased) { + self->setTarget(nullptr); + return; + } + } + + gc::ReadBarrier(obj.get()); +} + namespace gc { bool GCRuntime::registerWeakRef(HandleObject target, HandleObject weakRef) { @@ -242,16 +258,26 @@ bool GCRuntime::registerWeakRef(HandleObject target, HandleObject weakRef) { return refs.emplaceBack(weakRef); } -bool GCRuntime::unregisterWeakRef(JSContext* cx, JSObject* target, - WeakRefObject* weakRef) { +bool GCRuntime::unregisterWeakRefWrapper(JSObject* wrapper) { + WeakRefObject* weakRef = + &UncheckedUnwrapWithoutExpose(wrapper)->as(); + + JSObject* target = weakRef->target(); + MOZ_ASSERT(target); + + bool removed = false; auto& map = target->zone()->weakRefMap(); - auto ptr = map.lookup(target); - if (!ptr) { - return false; + if (auto ptr = map.lookup(target)) { + ptr->value().eraseIf([wrapper, &removed](JSObject* obj) { + bool remove = obj == wrapper; + if (remove) { + removed = true; + } + return remove; + }); } - ptr->value().eraseIfEqual(weakRef); - return true; + return removed; } void GCRuntime::traceKeptObjects(JSTracer* trc) { @@ -262,28 +288,30 @@ void GCRuntime::traceKeptObjects(JSTracer* trc) { } // namespace gc -void WeakRefMap::sweep() { - for (typename Base::Enum e(*this); !e.empty(); e.popFront()) { +void WeakRefMap::sweep(gc::StoreBuffer* sbToLock) { + mozilla::Maybe e; + for (e.emplace(*this); !e->empty(); e->popFront()) { // If target is dying, clear the target field of all weakRefs, and remove // the entry from the map. - if (JS::GCPolicy::needsSweep(&e.front().mutableKey())) { - for (JSObject* obj : e.front().value()) { + if (JS::GCPolicy::needsSweep(&e->front().mutableKey())) { + for (JSObject* obj : e->front().value()) { + MOZ_ASSERT(!JS_IsDeadWrapper(obj)); obj = UncheckedUnwrapWithoutExpose(obj); - if (!obj->is()) { - MOZ_ASSERT(JS_IsDeadWrapper(obj)); - continue; - } WeakRefObject* weakRef = &obj->as(); weakRef->setTarget(nullptr); } - e.front().value().clear(); - e.removeFront(); + e->removeFront(); } else { // Update the target field after compacting. - e.front().value().sweep(e.front().mutableKey()); + e->front().value().sweep(e->front().mutableKey()); } } + + // Take store buffer lock while the Enum's destructor is called as this can + // rehash/resize the table and access the store buffer. + gc::AutoLockStoreBuffer lock(sbToLock); + e.reset(); } // Like GCVector::sweep, but this method will also update the target in every @@ -294,10 +322,7 @@ void WeakRefHeapPtrVector::sweep(HeapPtrObject& target) { while (src != end()) { bool needsSweep = JS::GCPolicy::needsSweep(src); JSObject* obj = UncheckedUnwrapWithoutExpose(*src); - if (!obj->is()) { - MOZ_ASSERT(JS_IsDeadWrapper(obj)); - continue; - } + MOZ_ASSERT(!JS_IsDeadWrapper(obj)); WeakRefObject* weakRef = &obj->as(); diff --git a/js/src/builtin/WeakRefObject.h b/js/src/builtin/WeakRefObject.h index 0a78d4f37d..1613cb55af 100644 --- a/js/src/builtin/WeakRefObject.h +++ b/js/src/builtin/WeakRefObject.h @@ -14,7 +14,8 @@ class WeakRefObject : public NativeObject { static const JSClass class_; static const JSClass protoClass_; - JSObject* target(); + JSObject* target() { return static_cast(getPrivate()); } + void setTarget(JSObject* target); private: @@ -30,6 +31,7 @@ class WeakRefObject : public NativeObject { static bool preserveDOMWrapper(JSContext* cx, HandleObject obj); static bool deref(JSContext* cx, unsigned argc, Value* vp); + static void readBarrier(JSContext* cx, Handle self); }; } // namespace js diff --git a/js/src/builtin/WeakSetObject.cpp b/js/src/builtin/WeakSetObject.cpp index c31e939e7f..08d282edca 100644 --- a/js/src/builtin/WeakSetObject.cpp +++ b/js/src/builtin/WeakSetObject.cpp @@ -144,8 +144,8 @@ const JSClass WeakSetObject::class_ = { &WeakCollectionObject::classOps_, &WeakSetObject::classSpec_}; const JSClass WeakSetObject::protoClass_ = { - js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_WeakSet), JS_NULL_CLASS_OPS, - &WeakSetObject::classSpec_}; + "WeakSet.prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_WeakSet), + JS_NULL_CLASS_OPS, &WeakSetObject::classSpec_}; const JSPropertySpec WeakSetObject::properties[] = { JS_STRING_SYM_PS(toStringTag, "WeakSet", JSPROP_READONLY), JS_PS_END}; diff --git a/js/src/builtin/intl/Collator.cpp b/js/src/builtin/intl/Collator.cpp index 9185ad673a..6b0c8525d4 100644 --- a/js/src/builtin/intl/Collator.cpp +++ b/js/src/builtin/intl/Collator.cpp @@ -57,7 +57,7 @@ const JSClassOps CollatorObject::classOps_ = { }; const JSClass CollatorObject::class_ = { - js_Object_str, + "Intl.Collator", JSCLASS_HAS_RESERVED_SLOTS(CollatorObject::SLOT_COUNT) | JSCLASS_HAS_CACHED_PROTO(JSProto_Collator) | JSCLASS_FOREGROUND_FINALIZE, diff --git a/js/src/builtin/intl/Collator.h b/js/src/builtin/intl/Collator.h index 1d46d1c5e8..26967f76d0 100644 --- a/js/src/builtin/intl/Collator.h +++ b/js/src/builtin/intl/Collator.h @@ -32,7 +32,7 @@ class CollatorObject : public NativeObject { "INTERNALS_SLOT must match self-hosting define for internals " "object slot"); - // Estimated memory use for UCollator. + // Estimated memory use for UCollator (see IcuMemoryUsage). static constexpr size_t EstimatedMemoryUse = 1128; UCollator* getCollator() const { diff --git a/js/src/builtin/intl/CommonFunctions.cpp b/js/src/builtin/intl/CommonFunctions.cpp index f5587e76e2..a3260f0dbe 100644 --- a/js/src/builtin/intl/CommonFunctions.cpp +++ b/js/src/builtin/intl/CommonFunctions.cpp @@ -7,6 +7,7 @@ #include "builtin/intl/CommonFunctions.h" #include "mozilla/Assertions.h" +#include "mozilla/Casting.h" #include "mozilla/TextUtils.h" #include @@ -17,6 +18,7 @@ #include "gc/Zone.h" #include "gc/ZoneAllocator.h" #include "js/Value.h" +#include "unicode/uformattedvalue.h" #include "vm/JSContext.h" #include "vm/JSObject.h" #include "vm/SelfHosting.h" @@ -135,3 +137,17 @@ void js::intl::RemoveICUCellMemory(JSFreeOp* fop, JSObject* obj, size_t nbytes) { fop->removeCellMemory(obj, nbytes, MemoryUse::ICUObject); } + +JSString* js::intl::FormattedValueToString( + JSContext* cx, const UFormattedValue* formattedValue) { + UErrorCode status = U_ZERO_ERROR; + int32_t strLength; + const char16_t* str = ufmtval_getString(formattedValue, &strLength, &status); + if (U_FAILURE(status)) { + ReportInternalError(cx); + return nullptr; + } + + return NewStringCopyN(cx, str, + mozilla::AssertedCast(strLength)); +} diff --git a/js/src/builtin/intl/CommonFunctions.h b/js/src/builtin/intl/CommonFunctions.h index b69ced5da7..05de00f22e 100644 --- a/js/src/builtin/intl/CommonFunctions.h +++ b/js/src/builtin/intl/CommonFunctions.h @@ -17,6 +17,8 @@ #include "unicode/utypes.h" #include "vm/StringType.h" +struct UFormattedValue; + namespace js { namespace intl { @@ -155,6 +157,9 @@ void AddICUCellMemory(JSObject* obj, size_t nbytes); void RemoveICUCellMemory(JSFreeOp* fop, JSObject* obj, size_t nbytes); +JSString* FormattedValueToString(JSContext* cx, + const UFormattedValue* formattedValue); + } // namespace intl } // namespace js diff --git a/js/src/builtin/intl/DateTimeFormat.cpp b/js/src/builtin/intl/DateTimeFormat.cpp index 9974ef990b..a8f59b5b52 100644 --- a/js/src/builtin/intl/DateTimeFormat.cpp +++ b/js/src/builtin/intl/DateTimeFormat.cpp @@ -21,10 +21,12 @@ #include "gc/FreeOp.h" #include "js/CharacterEncoding.h" #include "js/Date.h" +#include "js/GCAPI.h" #include "js/PropertySpec.h" #include "js/StableStringChars.h" #include "unicode/ucal.h" #include "unicode/udat.h" +#include "unicode/udateintervalformat.h" #include "unicode/udatpg.h" #include "unicode/uenum.h" #include "unicode/ufieldpositer.h" @@ -67,7 +69,7 @@ const JSClassOps DateTimeFormatObject::classOps_ = { }; const JSClass DateTimeFormatObject::class_ = { - js_Object_str, + "Intl.DateTimeFormat", JSCLASS_HAS_RESERVED_SLOTS(DateTimeFormatObject::SLOT_COUNT) | JSCLASS_HAS_CACHED_PROTO(JSProto_DateTimeFormat) | JSCLASS_FOREGROUND_FINALIZE, @@ -91,7 +93,15 @@ static const JSFunctionSpec dateTimeFormat_methods[] = { 0, 0), JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 1, 0), - JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0), JS_FS_END}; +#ifdef NIGHTLY_BUILD +# ifndef U_HIDE_DRAFT_API + JS_SELF_HOSTED_FN("formatRange", "Intl_DateTimeFormat_formatRange", 2, 0), + JS_SELF_HOSTED_FN("formatRangeToParts", + "Intl_DateTimeFormat_formatRangeToParts", 2, 0), +# endif +#endif + JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0), + JS_FS_END}; static const JSPropertySpec dateTimeFormat_properties[] = { JS_SELF_HOSTED_GET("format", "$Intl_DateTimeFormat_format_get", 0), @@ -178,12 +188,23 @@ bool js::intl_DateTimeFormat(JSContext* cx, unsigned argc, Value* vp) { void js::DateTimeFormatObject::finalize(JSFreeOp* fop, JSObject* obj) { MOZ_ASSERT(fop->onMainThread()); - if (UDateFormat* df = obj->as().getDateFormat()) { - intl::RemoveICUCellMemory(fop, obj, - DateTimeFormatObject::EstimatedMemoryUse); + auto* dateTimeFormat = &obj->as(); + UDateFormat* df = dateTimeFormat->getDateFormat(); + UDateIntervalFormat* dif = dateTimeFormat->getDateIntervalFormat(); + + if (df) { + intl::RemoveICUCellMemory( + fop, obj, DateTimeFormatObject::UDateFormatEstimatedMemoryUse); udat_close(df); } + + if (dif) { + intl::RemoveICUCellMemory( + fop, obj, DateTimeFormatObject::UDateIntervalFormatEstimatedMemoryUse); + + udtitvfmt_close(dif); + } } bool js::AddMozDateTimeFormatConstructor(JSContext* cx, @@ -594,9 +615,10 @@ static HourCycle HourCycleFromOption(JSLinearString* str) { /** * Return the hour cycle used in the input pattern or Nothing if none was found. */ +template static mozilla::Maybe HourCycleFromPattern( - mozilla::Span pattern) { - PatternIterator iter(pattern); + mozilla::Span pattern) { + PatternIterator iter(pattern); while (const auto* ptr = iter.next()) { switch (*ptr) { case 'K': @@ -613,15 +635,16 @@ static mozilla::Maybe HourCycleFromPattern( } /** - * Replaces all hour pattern characters in |pattern| to use the matching hour - * representation for |hourCycle|. + * Replaces all hour pattern characters in |patternOrSkeleton| to use the + * matching hour representation for |hourCycle|. */ -static void ReplaceHourSymbol(mozilla::Span pattern, HourCycle hc) { +static void ReplaceHourSymbol(mozilla::Span patternOrSkeleton, + HourCycle hc) { char16_t replacement = HourSymbol(hc); - PatternIterator iter(pattern); + PatternIterator iter(patternOrSkeleton); while (auto* ptr = iter.next()) { char16_t ch = *ptr; - if (ch == 'K' || ch == 'h' || ch == 'H' || ch == 'k') { + if (ch == 'K' || ch == 'h' || ch == 'H' || ch == 'k' || ch == 'j') { *ptr = replacement; } } @@ -862,7 +885,7 @@ bool js::intl_patternForStyle(JSContext* cx, unsigned argc, Value* vp) { // the hour cycle used in the resolved pattern, find an equivalent pattern // with the correct hour cycle. if (timeStyle != UDAT_NONE && (hour12 || hourCycle)) { - if (auto hcPattern = HourCycleFromPattern(pattern)) { + if (auto hcPattern = HourCycleFromPattern(pattern)) { bool wantHour12 = hour12 ? hour12.value() : IsHour12(hourCycle.value()); if (wantHour12 != IsHour12(hcPattern.value())) { if (!FindPatternWithHourCycle(cx, locale.get(), pattern, wantHour12)) { @@ -886,25 +909,40 @@ bool js::intl_patternForStyle(JSContext* cx, unsigned argc, Value* vp) { return true; } -/** - * Returns a new UDateFormat with the locale and date-time formatting options - * of the given DateTimeFormat. - */ -static UDateFormat* NewUDateFormat( - JSContext* cx, Handle dateTimeFormat) { - RootedValue value(cx); +bool js::intl_skeletonForPattern(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 1); + MOZ_ASSERT(args[0].isString()); - RootedObject internals(cx, intl::GetInternalsObject(cx, dateTimeFormat)); - if (!internals) { - return nullptr; + AutoStableStringChars pattern(cx); + if (!pattern.initTwoByte(cx, args[0].toString())) { + return false; } + mozilla::Range patternChars = pattern.twoByteRange(); + + JSString* skeleton = CallICU( + cx, [&patternChars](char16_t* chars, int32_t size, UErrorCode* status) { + return udatpg_getSkeleton(nullptr, patternChars.begin().get(), + patternChars.length(), chars, size, status); + }); + if (!skeleton) { + return false; + } + + args.rval().setString(skeleton); + return true; +} +static UniqueChars DateTimeFormatLocale( + JSContext* cx, HandleObject internals, + mozilla::Maybe hourCycle = mozilla::Nothing()) { + RootedValue value(cx); if (!GetProperty(cx, internals, internals, cx->names().locale, &value)) { return nullptr; } - // ICU expects calendar and numberingSystem as Unicode locale extensions on - // locale. + // ICU expects calendar, numberingSystem, and hourCycle as Unicode locale + // extensions on locale. intl::LanguageTag tag(cx); { @@ -951,6 +989,28 @@ static UDateFormat* NewUDateFormat( } } + if (hourCycle) { + JSAtom* hourCycleStr; + switch (*hourCycle) { + case HourCycle::H11: + hourCycleStr = cx->names().h11; + break; + case HourCycle::H12: + hourCycleStr = cx->names().h12; + break; + case HourCycle::H23: + hourCycleStr = cx->names().h23; + break; + case HourCycle::H24: + hourCycleStr = cx->names().h24; + break; + } + + if (!keywords.emplaceBack("hc", hourCycleStr)) { + return nullptr; + } + } + // |ApplyUnicodeExtensionToTag| applies the new keywords to the front of // the Unicode extension subtag. We're then relying on ICU to follow RFC // 6067, which states that any trailing keywords using the same key @@ -959,7 +1019,23 @@ static UDateFormat* NewUDateFormat( return nullptr; } - UniqueChars locale = tag.toStringZ(cx); + return tag.toStringZ(cx); +} + +/** + * Returns a new UDateFormat with the locale and date-time formatting options + * of the given DateTimeFormat. + */ +static UDateFormat* NewUDateFormat( + JSContext* cx, Handle dateTimeFormat) { + RootedValue value(cx); + + RootedObject internals(cx, intl::GetInternalsObject(cx, dateTimeFormat)); + if (!internals) { + return nullptr; + } + + UniqueChars locale = DateTimeFormatLocale(cx, internals); if (!locale) { return nullptr; } @@ -1006,8 +1082,8 @@ static UDateFormat* NewUDateFormat( return df; } -static bool intl_FormatDateTime(JSContext* cx, UDateFormat* df, ClippedTime x, - MutableHandleValue result) { +static bool intl_FormatDateTime(JSContext* cx, const UDateFormat* df, + ClippedTime x, MutableHandleValue result) { MOZ_ASSERT(x.isValid()); JSString* str = @@ -1129,8 +1205,8 @@ static FieldType GetFieldTypeForFormatField(UDateFormatField fieldName) { return nullptr; } -static bool intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, - ClippedTime x, +static bool intl_FormatToPartsDateTime(JSContext* cx, const UDateFormat* df, + ClippedTime x, FieldType source, MutableHandleValue result) { MOZ_ASSERT(x.isValid()); @@ -1191,6 +1267,13 @@ static bool intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, return false; } + if (source) { + val = StringValue(cx->names().*source); + if (!DefineDataProperty(cx, singlePart, cx->names().source, val)) { + return false; + } + } + if (!NewbornArrayPush(cx, partsArray, ObjectValue(*singlePart))) { return false; } @@ -1273,10 +1356,530 @@ bool js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp) { dateTimeFormat->setDateFormat(df); intl::AddICUCellMemory(dateTimeFormat, - DateTimeFormatObject::EstimatedMemoryUse); + DateTimeFormatObject::UDateFormatEstimatedMemoryUse); } // Use the UDateFormat to actually format the time stamp. - return formatToParts ? intl_FormatToPartsDateTime(cx, df, x, args.rval()) - : intl_FormatDateTime(cx, df, x, args.rval()); + FieldType source = nullptr; + return formatToParts + ? intl_FormatToPartsDateTime(cx, df, x, source, args.rval()) + : intl_FormatDateTime(cx, df, x, args.rval()); +} + +#ifndef U_HIDE_DRAFT_API +/** + * Returns a new UDateIntervalFormat with the locale and date-time formatting + * options of the given DateTimeFormat. + */ +static UDateIntervalFormat* NewUDateIntervalFormat( + JSContext* cx, Handle dateTimeFormat) { + RootedValue value(cx); + + RootedObject internals(cx, intl::GetInternalsObject(cx, dateTimeFormat)); + if (!internals) { + return nullptr; + } + + if (!GetProperty(cx, internals, internals, cx->names().pattern, &value)) { + return nullptr; + } + + // Determine the hour cycle used in the resolved pattern. This is needed to + // workaround and + // . + mozilla::Maybe hcPattern; + { + JSLinearString* pattern = value.toString()->ensureLinear(cx); + if (!pattern) { + return nullptr; + } + + JS::AutoCheckCannotGC nogc; + if (pattern->hasLatin1Chars()) { + hcPattern = HourCycleFromPattern(pattern->latin1Range(nogc)); + } else { + hcPattern = HourCycleFromPattern(pattern->twoByteRange(nogc)); + } + } + + UniqueChars locale = DateTimeFormatLocale(cx, internals, hcPattern); + if (!locale) { + return nullptr; + } + + if (!GetProperty(cx, internals, internals, cx->names().timeZone, &value)) { + return nullptr; + } + + AutoStableStringChars timeZone(cx); + if (!timeZone.initTwoByte(cx, value.toString())) { + return nullptr; + } + mozilla::Span timeZoneChars = timeZone.twoByteRange(); + + if (!GetProperty(cx, internals, internals, cx->names().skeleton, &value)) { + return nullptr; + } + + AutoStableStringChars skeleton(cx); + if (!skeleton.initTwoByte(cx, value.toString())) { + return nullptr; + } + mozilla::Span skeletonChars = skeleton.twoByteRange(); + + Vector newSkeleton(cx); + if (hcPattern) { + if (!newSkeleton.append(skeletonChars.data(), skeletonChars.size())) { + return nullptr; + } + + ReplaceHourSymbol(newSkeleton, *hcPattern); + skeletonChars = newSkeleton; + } + + UErrorCode status = U_ZERO_ERROR; + UDateIntervalFormat* dif = udtitvfmt_open( + IcuLocale(locale.get()), skeletonChars.data(), skeletonChars.size(), + timeZoneChars.data(), timeZoneChars.size(), &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return nullptr; + } + + return dif; +} + +static UCalendar* CreateCalendar(JSContext* cx, const UCalendar* cal, + ClippedTime t) { + UErrorCode status = U_ZERO_ERROR; + UCalendar* clone = ucal_clone(cal, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return nullptr; + } + ScopedICUObject toClose(clone); + + ucal_setMillis(clone, t.toDouble(), &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return nullptr; + } + return toClose.forget(); +} + +/** + * PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + */ +static const UFormattedValue* PartitionDateTimeRangePattern( + JSContext* cx, const UDateFormat* df, const UDateIntervalFormat* dif, + UFormattedDateInterval* formatted, ClippedTime x, ClippedTime y) { + MOZ_ASSERT(x.isValid()); + MOZ_ASSERT(y.isValid()); + MOZ_ASSERT(x.toDouble() <= y.toDouble()); + + // We can't access the calendar used by UDateIntervalFormat to change it to a + // proleptic Gregorian calendar. Instead we need to call a different formatter + // function which accepts UCalendar instead of UDate. + // But creating new UCalendar objects for each call is slow, so when we can + // ensure that the input dates are later than the Gregorian change date, + // directly call the formatter functions taking UDate. + + // The Gregorian change date "1582-10-15T00:00:00.000Z". + constexpr double GregorianChangeDate = -12219292800000.0; + + // Add a full day to account for time zone offsets. + constexpr double GregorianChangeDatePlusOneDay = + GregorianChangeDate + msPerDay; + + UErrorCode status = U_ZERO_ERROR; + if (x.toDouble() < GregorianChangeDatePlusOneDay) { + // Create calendar objects for the start and end date by cloning the date + // formatter calendar. The date formatter calendar already has the correct + // time zone set and was changed to use a proleptic Gregorian calendar. + const UCalendar* cal = udat_getCalendar(df); + + UCalendar* startCal = CreateCalendar(cx, cal, x); + if (!startCal) { + return nullptr; + } + ScopedICUObject toCloseStart(startCal); + + UCalendar* endCal = CreateCalendar(cx, cal, y); + if (!endCal) { + return nullptr; + } + ScopedICUObject toCloseEnd(endCal); + + udtitvfmt_formatCalendarToResult(dif, startCal, endCal, formatted, &status); + } else { + // The common fast path which doesn't require creating calendar objects. + udtitvfmt_formatToResult(dif, x.toDouble(), y.toDouble(), formatted, + &status); + } + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return nullptr; + } + + const UFormattedValue* formattedValue = + udtitvfmt_resultAsValue(formatted, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return nullptr; + } + + return formattedValue; +} + +/** + * PartitionDateTimeRangePattern ( dateTimeFormat, x, y ), steps 9-11. + * + * Examine the formatted value to see if any interval span field is present. + */ +static bool DateFieldsPracticallyEqual(JSContext* cx, + const UFormattedValue* formattedValue, + bool* equal) { + UErrorCode status = U_ZERO_ERROR; + UConstrainedFieldPosition* fpos = ucfpos_open(&status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + ScopedICUObject toCloseFpos(fpos); + + // We're only interested in UFIELD_CATEGORY_DATE_INTERVAL_SPAN fields. + ucfpos_constrainCategory(fpos, UFIELD_CATEGORY_DATE_INTERVAL_SPAN, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + bool hasSpan = ufmtval_nextPosition(formattedValue, fpos, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + // When no date interval span field was found, both dates are "practically + // equal" per PartitionDateTimeRangePattern. + *equal = !hasSpan; + return true; +} + +/** + * FormatDateTimeRange( dateTimeFormat, x, y ) + */ +static bool FormatDateTimeRange(JSContext* cx, const UDateFormat* df, + const UDateIntervalFormat* dif, ClippedTime x, + ClippedTime y, MutableHandleValue result) { + UErrorCode status = U_ZERO_ERROR; + UFormattedDateInterval* formatted = udtitvfmt_openResult(&status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + ScopedICUObject toClose( + formatted); + + const UFormattedValue* formattedValue = + PartitionDateTimeRangePattern(cx, df, dif, formatted, x, y); + if (!formattedValue) { + return false; + } + + // PartitionDateTimeRangePattern, steps 9-11. + bool equal; + if (!DateFieldsPracticallyEqual(cx, formattedValue, &equal)) { + return false; + } + + // PartitionDateTimeRangePattern, step 12. + if (equal) { + return intl_FormatDateTime(cx, df, x, result); + } + + JSString* resultStr = intl::FormattedValueToString(cx, formattedValue); + if (!resultStr) { + return false; + } + + result.setString(resultStr); + return true; +} + +/** + * FormatDateTimeRangeToParts ( dateTimeFormat, x, y ) + */ +static bool FormatDateTimeRangeToParts(JSContext* cx, const UDateFormat* df, + const UDateIntervalFormat* dif, + ClippedTime x, ClippedTime y, + MutableHandleValue result) { + UErrorCode status = U_ZERO_ERROR; + UFormattedDateInterval* formatted = udtitvfmt_openResult(&status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + ScopedICUObject toClose( + formatted); + + const UFormattedValue* formattedValue = + PartitionDateTimeRangePattern(cx, df, dif, formatted, x, y); + if (!formattedValue) { + return false; + } + + // PartitionDateTimeRangePattern, steps 9-11. + bool equal; + if (!DateFieldsPracticallyEqual(cx, formattedValue, &equal)) { + return false; + } + + // PartitionDateTimeRangePattern, step 12. + if (equal) { + FieldType source = &JSAtomState::shared; + return intl_FormatToPartsDateTime(cx, df, x, source, result); + } + + RootedString overallResult(cx, + intl::FormattedValueToString(cx, formattedValue)); + if (!overallResult) { + return false; + } + + RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx)); + if (!partsArray) { + return false; + } + + size_t lastEndIndex = 0; + RootedObject singlePart(cx); + RootedValue val(cx); + + auto AppendPart = [&](FieldType type, size_t beginIndex, size_t endIndex, + FieldType source) { + singlePart = NewBuiltinClassInstance(cx); + if (!singlePart) { + return false; + } + + val = StringValue(cx->names().*type); + if (!DefineDataProperty(cx, singlePart, cx->names().type, val)) { + return false; + } + + JSLinearString* partSubstr = NewDependentString( + cx, overallResult, beginIndex, endIndex - beginIndex); + if (!partSubstr) { + return false; + } + + val = StringValue(partSubstr); + if (!DefineDataProperty(cx, singlePart, cx->names().value, val)) { + return false; + } + + val = StringValue(cx->names().*source); + if (!DefineDataProperty(cx, singlePart, cx->names().source, val)) { + return false; + } + + if (!NewbornArrayPush(cx, partsArray, ObjectValue(*singlePart))) { + return false; + } + + lastEndIndex = endIndex; + return true; + }; + + UConstrainedFieldPosition* fpos = ucfpos_open(&status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + ScopedICUObject toCloseFpos(fpos); + + size_t categoryEndIndex = 0; + FieldType source = &JSAtomState::shared; + + while (true) { + bool hasMore = ufmtval_nextPosition(formattedValue, fpos, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + if (!hasMore) { + break; + } + + int32_t category = ucfpos_getCategory(fpos, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + int32_t field = ucfpos_getField(fpos, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + int32_t beginIndexInt, endIndexInt; + ucfpos_getIndexes(fpos, &beginIndexInt, &endIndexInt, &status); + if (U_FAILURE(status)) { + intl::ReportInternalError(cx); + return false; + } + + MOZ_ASSERT(beginIndexInt >= 0); + MOZ_ASSERT(endIndexInt >= 0); + MOZ_ASSERT(beginIndexInt <= endIndexInt, + "field iterator returning invalid range"); + + size_t beginIndex = size_t(beginIndexInt); + size_t endIndex = size_t(endIndexInt); + + // Indices are guaranteed to be returned in order (from left to right). + MOZ_ASSERT(lastEndIndex <= beginIndex, + "field iteration didn't return fields in order start to " + "finish as expected"); + + if (category == UFIELD_CATEGORY_DATE_INTERVAL_SPAN) { + // Append any remaining literal parts before changing the source kind. + if (lastEndIndex < beginIndex) { + if (!AppendPart(&JSAtomState::literal, lastEndIndex, beginIndex, + source)) { + return false; + } + } + + // The special field category UFIELD_CATEGORY_DATE_INTERVAL_SPAN has only + // two allowed values (0 or 1), indicating the begin of the start- resp. + // end-date. + MOZ_ASSERT(field == 0 || field == 1, + "span category has unexpected value"); + + source = field == 0 ? &JSAtomState::startRange : &JSAtomState::endRange; + categoryEndIndex = endIndex; + continue; + } + + // Ignore categories other than UFIELD_CATEGORY_DATE. + if (category != UFIELD_CATEGORY_DATE) { + continue; + } + + // Append the field if supported. If not supported, append it as part of the + // next literal part. + if (FieldType type = + GetFieldTypeForFormatField(static_cast(field))) { + if (lastEndIndex < beginIndex) { + if (!AppendPart(&JSAtomState::literal, lastEndIndex, beginIndex, + source)) { + return false; + } + } + + if (!AppendPart(type, beginIndex, endIndex, source)) { + return false; + } + } + + if (endIndex == categoryEndIndex) { + // Append any remaining literal parts before changing the source kind. + if (lastEndIndex < endIndex) { + if (!AppendPart(&JSAtomState::literal, lastEndIndex, endIndex, + source)) { + return false; + } + } + + source = &JSAtomState::shared; + } + } + + // Append any final literal. + if (lastEndIndex < overallResult->length()) { + if (!AppendPart(&JSAtomState::literal, lastEndIndex, + overallResult->length(), source)) { + return false; + } + } + + result.setObject(*partsArray); + return true; +} + +bool js::intl_FormatDateTimeRange(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 4); + MOZ_ASSERT(args[0].isObject()); + MOZ_ASSERT(args[1].isNumber()); + MOZ_ASSERT(args[2].isNumber()); + MOZ_ASSERT(args[3].isBoolean()); + + Rooted dateTimeFormat(cx); + dateTimeFormat = &args[0].toObject().as(); + + bool formatToParts = args[3].toBoolean(); + + // PartitionDateTimeRangePattern, steps 1-2. + ClippedTime x = TimeClip(args[1].toNumber()); + if (!x.isValid()) { + JS_ReportErrorNumberASCII( + cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE, "DateTimeFormat", + formatToParts ? "formatRangeToParts" : "formatRange"); + return false; + } + + // PartitionDateTimeRangePattern, steps 3-4. + ClippedTime y = TimeClip(args[2].toNumber()); + if (!y.isValid()) { + JS_ReportErrorNumberASCII( + cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE, "DateTimeFormat", + formatToParts ? "formatRangeToParts" : "formatRange"); + return false; + } + + // Self-hosted code should have checked this condition. + MOZ_ASSERT(x.toDouble() <= y.toDouble(), + "start date mustn't be after the end date"); + + // Obtain a cached UDateFormat object. + UDateFormat* df = dateTimeFormat->getDateFormat(); + if (!df) { + df = NewUDateFormat(cx, dateTimeFormat); + if (!df) { + return false; + } + dateTimeFormat->setDateFormat(df); + + intl::AddICUCellMemory(dateTimeFormat, + DateTimeFormatObject::UDateFormatEstimatedMemoryUse); + } + + // Obtain a cached UDateIntervalFormat object. + UDateIntervalFormat* dif = dateTimeFormat->getDateIntervalFormat(); + if (!dif) { + dif = NewUDateIntervalFormat(cx, dateTimeFormat); + if (!dif) { + return false; + } + dateTimeFormat->setDateIntervalFormat(dif); + + intl::AddICUCellMemory( + dateTimeFormat, + DateTimeFormatObject::UDateIntervalFormatEstimatedMemoryUse); + } + + // Use the UDateIntervalFormat to actually format the time range. + return formatToParts + ? FormatDateTimeRangeToParts(cx, df, dif, x, y, args.rval()) + : FormatDateTimeRange(cx, df, dif, x, y, args.rval()); +} + +#else +bool js::intl_FormatDateTimeRange(JSContext* cx, unsigned argc, Value* vp) { + MOZ_CRASH("FormatDateTimeRange requires ICU draft APIs"); } +#endif // U_HIDE_DRAFT_API diff --git a/js/src/builtin/intl/DateTimeFormat.h b/js/src/builtin/intl/DateTimeFormat.h index c38ef1935f..d62b935a2f 100644 --- a/js/src/builtin/intl/DateTimeFormat.h +++ b/js/src/builtin/intl/DateTimeFormat.h @@ -14,6 +14,7 @@ #include "vm/NativeObject.h" using UDateFormat = void*; +struct UDateIntervalFormat; namespace js { @@ -24,14 +25,18 @@ class DateTimeFormatObject : public NativeObject { static constexpr uint32_t INTERNALS_SLOT = 0; static constexpr uint32_t UDATE_FORMAT_SLOT = 1; - static constexpr uint32_t SLOT_COUNT = 2; + static constexpr uint32_t UDATE_INTERVAL_FORMAT_SLOT = 2; + static constexpr uint32_t SLOT_COUNT = 3; static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT, "INTERNALS_SLOT must match self-hosting define for internals " "object slot"); - // Estimated memory use for UDateFormat. - static constexpr size_t EstimatedMemoryUse = 91626; + // Estimated memory use for UDateFormat (see IcuMemoryUsage). + static constexpr size_t UDateFormatEstimatedMemoryUse = 91922; + + // Estimated memory use for UDateIntervalFormat (see IcuMemoryUsage). + static constexpr size_t UDateIntervalFormatEstimatedMemoryUse = 119856; UDateFormat* getDateFormat() const { const auto& slot = getFixedSlot(UDATE_FORMAT_SLOT); @@ -45,6 +50,18 @@ class DateTimeFormatObject : public NativeObject { setFixedSlot(UDATE_FORMAT_SLOT, PrivateValue(dateFormat)); } + UDateIntervalFormat* getDateIntervalFormat() const { + const auto& slot = getFixedSlot(UDATE_INTERVAL_FORMAT_SLOT); + if (slot.isUndefined()) { + return nullptr; + } + return static_cast(slot.toPrivate()); + } + + void setDateIntervalFormat(UDateIntervalFormat* dateIntervalFormat) { + setFixedSlot(UDATE_INTERVAL_FORMAT_SLOT, PrivateValue(dateIntervalFormat)); + } + private: static const JSClassOps classOps_; static const ClassSpec classSpec_; @@ -176,6 +193,15 @@ extern MOZ_MUST_USE bool intl_patternForSkeleton(JSContext* cx, unsigned argc, extern MOZ_MUST_USE bool intl_patternForStyle(JSContext* cx, unsigned argc, JS::Value* vp); +/** + * Return a skeleton for the pattern in the date-time format pattern language of + * Unicode Technical Standard 35, Unicode Locale Data Markup Language. + * + * Usage: skeleton = intl_skeletonForPattern(pattern) + */ +extern MOZ_MUST_USE bool intl_skeletonForPattern(JSContext* cx, unsigned argc, + JS::Value* vp); + /** * Returns a String value representing x (which must be a Number value) * according to the effective locale and the formatting options of the @@ -188,6 +214,18 @@ extern MOZ_MUST_USE bool intl_patternForStyle(JSContext* cx, unsigned argc, extern MOZ_MUST_USE bool intl_FormatDateTime(JSContext* cx, unsigned argc, JS::Value* vp); +/** + * Returns a String value representing the range between x and y (which both + * must be Number values) according to the effective locale and the formatting + * options of the given DateTimeFormat. + * + * Spec: Intl.DateTimeFormat.prototype.formatRange proposal + * + * Usage: formatted = intl_FormatDateTimeRange(dateTimeFmt, x, y, formatToParts) + */ +extern MOZ_MUST_USE bool intl_FormatDateTimeRange(JSContext* cx, unsigned argc, + JS::Value* vp); + } // namespace js #endif /* builtin_intl_DateTimeFormat_h */ diff --git a/js/src/builtin/intl/DateTimeFormat.js b/js/src/builtin/intl/DateTimeFormat.js index 9340961d5e..60a9f12c98 100644 --- a/js/src/builtin/intl/DateTimeFormat.js +++ b/js/src/builtin/intl/DateTimeFormat.js @@ -92,9 +92,11 @@ function resolveDateTimeFormatInternals(lazyDateTimeFormatData) { formatOpt.hourCycle = r.hc; // Steps 26-30, more or less - see comment after this function. + var skeleton; var pattern; if (lazyDateTimeFormatData.patternOption !== undefined) { pattern = lazyDateTimeFormatData.patternOption; + skeleton = intl_skeletonForPattern(pattern); internalProps.patternOption = lazyDateTimeFormatData.patternOption; } else if (lazyDateTimeFormatData.dateStyle !== undefined || @@ -105,14 +107,17 @@ function resolveDateTimeFormatInternals(lazyDateTimeFormatData) { lazyDateTimeFormatData.timeZone, formatOpt.hour12, formatOpt.hourCycle); + skeleton = intl_skeletonForPattern(pattern); internalProps.dateStyle = lazyDateTimeFormatData.dateStyle; internalProps.timeStyle = lazyDateTimeFormatData.timeStyle; } else { - pattern = toBestICUPattern(dataLocale, formatOpt); + skeleton = toICUSkeleton(formatOpt); + pattern = toBestICUPattern(dataLocale, skeleton, formatOpt); } // Step 31. + internalProps.skeleton = skeleton; internalProps.pattern = pattern; // The caller is responsible for associating |internalProps| with the right @@ -533,10 +538,9 @@ function InitializeDateTimeFormat(dateTimeFormat, thisValue, locales, options, m /* eslint-disable complexity */ /** - * Returns an ICU pattern string for the given locale and representing the - * specified options as closely as possible given available locale data. + * Returns an ICU skeleton string representing the specified options. */ -function toBestICUPattern(locale, options) { +function toICUSkeleton(options) { // Create an ICU skeleton representing the specified options. See // http://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table var skeleton = ""; @@ -673,11 +677,18 @@ function toBestICUPattern(locale, options) { skeleton += "zzzz"; break; } + return skeleton; +} +/* eslint-enable complexity */ +/** + * Returns an ICU pattern string for the given locale and representing the + * specified skeleton as closely as possible given available locale data. + */ +function toBestICUPattern(locale, skeleton, options) { // Let ICU convert the ICU skeleton to an ICU pattern for the given locale. return intl_patternForSkeleton(locale, skeleton, options.hourCycle); } -/* eslint-enable complexity */ /** * Returns a new options object that includes the provided options (if any) @@ -884,16 +895,94 @@ function Intl_DateTimeFormat_formatToParts(date) { "Intl_DateTimeFormat_formatToParts"); } - // Ensure the DateTimeFormat internals are resolved. - getDateTimeFormatInternals(dtf); - // Steps 4-5. var x = (date === undefined) ? std_Date_now() : ToNumber(date); + // Ensure the DateTimeFormat internals are resolved. + getDateTimeFormatInternals(dtf); + // Step 6. return intl_FormatDateTime(dtf, x, /* formatToParts = */ true); } +/** + * Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + * + * Spec: Intl.DateTimeFormat.prototype.formatRange proposal + */ +function Intl_DateTimeFormat_formatRange(startDate, endDate) { + // Step 1. + var dtf = this; + + // Steps 2-3. + if (!IsObject(dtf) || (dtf = GuardToDateTimeFormat(dtf)) === null) { + return callFunction(CallDateTimeFormatMethodIfWrapped, this, startDate, endDate, + "Intl_DateTimeFormat_formatRange"); + } + + // Step 4. + if (startDate === undefined || endDate === undefined) { + ThrowTypeError(JSMSG_UNDEFINED_DATE, startDate === undefined ? "start" : "end", + "formatRange"); + } + + // Step 5. + var x = ToNumber(startDate); + + // Step 6. + var y = ToNumber(endDate); + + // Step 7. + if (x > y) { + ThrowRangeError(JSMSG_START_AFTER_END_DATE, "formatRange"); + } + + // Ensure the DateTimeFormat internals are resolved. + getDateTimeFormatInternals(dtf); + + // Step 8. + return intl_FormatDateTimeRange(dtf, x, y, /* formatToParts = */ false); +} + +/** + * Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + * + * Spec: Intl.DateTimeFormat.prototype.formatRange proposal + */ +function Intl_DateTimeFormat_formatRangeToParts(startDate, endDate) { + // Step 1. + var dtf = this; + + // Steps 2-3. + if (!IsObject(dtf) || (dtf = GuardToDateTimeFormat(dtf)) === null) { + return callFunction(CallDateTimeFormatMethodIfWrapped, this, startDate, endDate, + "Intl_DateTimeFormat_formatRangeToParts"); + } + + // Step 4. + if (startDate === undefined || endDate === undefined) { + ThrowTypeError(JSMSG_UNDEFINED_DATE, startDate === undefined ? "start" : "end", + "formatRangeToParts"); + } + + // Step 5. + var x = ToNumber(startDate); + + // Step 6. + var y = ToNumber(endDate); + + // Step 7. + if (x > y) { + ThrowRangeError(JSMSG_START_AFTER_END_DATE, "formatRangeToParts"); + } + + // Ensure the DateTimeFormat internals are resolved. + getDateTimeFormatInternals(dtf); + + // Step 8. + return intl_FormatDateTimeRange(dtf, x, y, /* formatToParts = */ true); +} + /** * Returns the resolved options for a DateTimeFormat object. * diff --git a/js/src/builtin/intl/DisplayNames.cpp b/js/src/builtin/intl/DisplayNames.cpp index ce98f7f389..3da3571b1b 100644 --- a/js/src/builtin/intl/DisplayNames.cpp +++ b/js/src/builtin/intl/DisplayNames.cpp @@ -22,6 +22,7 @@ #include "builtin/intl/LanguageTag.h" #include "builtin/intl/ScopedICUObject.h" #include "builtin/intl/SharedIntlData.h" +#include "builtin/String.h" #include "gc/AllocKind.h" #include "gc/FreeOp.h" #include "gc/Rooting.h" @@ -72,7 +73,7 @@ const JSClassOps DisplayNamesObject::classOps_ = {nullptr, /* addProperty */ DisplayNamesObject::finalize}; const JSClass DisplayNamesObject::class_ = { - js_Object_str, + "Intl.DisplayNames", JSCLASS_HAS_RESERVED_SLOTS(DisplayNamesObject::SLOT_COUNT) | JSCLASS_HAS_CACHED_PROTO(JSProto_DisplayNames) | JSCLASS_FOREGROUND_FINALIZE, @@ -104,7 +105,7 @@ static const JSPropertySpec displayNames_properties[] = { static bool DisplayNames(JSContext* cx, unsigned argc, Value* vp); const ClassSpec DisplayNamesObject::classSpec_ = { - GenericCreateConstructor, + GenericCreateConstructor, GenericCreatePrototype, displayNames_static_methods, nullptr, @@ -173,6 +174,11 @@ static bool DisplayNames(JSContext* cx, const CallArgs& args, } } + // TypeError anyway, but this gives a better error message. + if (!args.requireAtLeast(cx, "DisplayNames", 2)) { + return false; + } + Rooted displayNames(cx); displayNames = NewObjectWithClassProto(cx, proto); if (!displayNames) { @@ -228,7 +234,7 @@ bool js::AddDisplayNamesConstructor(JSContext* cx, HandleObject intl) { bool js::AddMozDisplayNamesConstructor(JSContext* cx, HandleObject intl) { RootedObject ctor(cx, GlobalObject::createConstructor( - cx, MozDisplayNames, cx->names().DisplayNames, 0)); + cx, MozDisplayNames, cx->names().DisplayNames, 2)); if (!ctor) { return false; } @@ -261,6 +267,8 @@ bool js::AddMozDisplayNamesConstructor(JSContext* cx, HandleObject intl) { enum class DisplayNamesStyle { Long, Short, Narrow }; +enum class DisplayNamesFallback { None, Code }; + static ULocaleDisplayNames* NewULocaleDisplayNames( JSContext* cx, const char* locale, DisplayNamesStyle displayStyle) { UErrorCode status = U_ZERO_ERROR; @@ -328,7 +336,8 @@ static void ReportInvalidOptionError(JSContext* cx, const char* type, static JSString* GetLanguageDisplayName( JSContext* cx, Handle displayNames, const char* locale, - DisplayNamesStyle displayStyle, HandleLinearString languageStr) { + DisplayNamesStyle displayStyle, DisplayNamesFallback fallback, + HandleLinearString languageStr) { bool ok; intl::LanguageTag tag(cx); JS_TRY_VAR_OR_RETURN_NULL( @@ -341,8 +350,6 @@ static JSString* GetLanguageDisplayName( // ICU always canonicalizes the input locale, but since we know that ICU's // canonicalization is incomplete, we need to perform our own canonicalization // to ensure consistent result. - // FIXME: spec issue - language tag canonicalisation not performed: - // https://github.com/tc39/proposal-intl-displaynames/issues/70 if (!tag.canonicalizeBaseName(cx)) { return nullptr; } @@ -358,8 +365,8 @@ static JSString* GetLanguageDisplayName( return nullptr; } - return CallICU(cx, [ldn, &languageChars](UChar* chars, uint32_t size, - UErrorCode* status) { + JSString* str = CallICU(cx, [ldn, &languageChars](UChar* chars, uint32_t size, + UErrorCode* status) { int32_t res = uldn_localeDisplayName(ldn, languageChars.get(), chars, size, status); @@ -371,12 +378,28 @@ static JSString* GetLanguageDisplayName( } return res; }); + if (!str) { + return nullptr; + } + + // Return the canonicalized input when no localized language name was found. + if (str->empty() && fallback == DisplayNamesFallback::Code) { + return NewStringCopyZ(cx, languageChars.get()); + } + + return str; +} + +template +static JSString* NewStringCopy(JSContext* cx, mozilla::Span span) { + return NewStringCopyN(cx, span.data(), span.size()); } static JSString* GetScriptDisplayName(JSContext* cx, Handle displayNames, const char* locale, DisplayNamesStyle displayStyle, + DisplayNamesFallback fallback, HandleLinearString scriptStr) { intl::ScriptSubtag script; if (!intl::ParseStandaloneScriptTag(scriptStr, script)) { @@ -391,8 +414,6 @@ static JSString* GetScriptDisplayName(JSContext* cx, // ICU always canonicalizes the input locale, but since we know that ICU's // canonicalization is incomplete, we need to perform our own canonicalization // to ensure consistent result. - // FIXME: spec issue - language tag canonicalisation not performed: - // https://github.com/tc39/proposal-intl-displaynames/issues/70 if (!tag.canonicalizeBaseName(cx)) { return nullptr; } @@ -410,28 +431,38 @@ static JSString* GetScriptDisplayName(JSContext* cx, return nullptr; } - return CallICU(cx, [locale, &scriptChars](UChar* chars, uint32_t size, - UErrorCode* status) { - int32_t res = - uloc_getDisplayScript(scriptChars.get(), locale, chars, size, status); + JSString* str = + CallICU(cx, [locale, &scriptChars](UChar* chars, uint32_t size, + UErrorCode* status) { + int32_t res = uloc_getDisplayScript(scriptChars.get(), locale, chars, + size, status); + + // |uloc_getDisplayScript| reports U_USING_DEFAULT_WARNING when no + // display name was found. + if (*status == U_USING_DEFAULT_WARNING) { + *status = U_ZERO_ERROR; + res = 0; + } + return res; + }); + if (!str) { + return nullptr; + } + + // Return the canonicalized input when no localized script name was found. + if (str->empty() && fallback == DisplayNamesFallback::Code) { + return NewStringCopy(cx, tag.script().span()); + } - // |uloc_getDisplayScript| reports U_USING_DEFAULT_WARNING when no display - // name was found. - if (*status == U_USING_DEFAULT_WARNING) { - *status = U_ZERO_ERROR; - res = 0; - } - return res; - }); + return str; } // Note: ICU requires the script subtag to be in canonical case. const intl::ScriptSubtag& canonicalScript = tag.script(); - char scriptChars[intl::LanguageTagLimits::ScriptLength + 1]; + char scriptChars[intl::LanguageTagLimits::ScriptLength + 1] = {}; std::copy_n(canonicalScript.span().data(), canonicalScript.length(), scriptChars); - scriptChars[canonicalScript.length()] = '\0'; ULocaleDisplayNames* ldn = GetOrCreateLocaleDisplayNames(cx, displayNames, locale, displayStyle); @@ -439,8 +470,8 @@ static JSString* GetScriptDisplayName(JSContext* cx, return nullptr; } - return CallICU(cx, [ldn, scriptChars](UChar* chars, uint32_t size, - UErrorCode* status) { + JSString* str = CallICU(cx, [ldn, scriptChars](UChar* chars, uint32_t size, + UErrorCode* status) { int32_t res = uldn_scriptDisplayName(ldn, scriptChars, chars, size, status); // |uldn_scriptDisplayName| reports U_ILLEGAL_ARGUMENT_ERROR when no display @@ -451,12 +482,23 @@ static JSString* GetScriptDisplayName(JSContext* cx, } return res; }); + if (!str) { + return nullptr; + } + + // Return the canonicalized input when no localized script name was found. + if (str->empty() && fallback == DisplayNamesFallback::Code) { + return NewStringCopy(cx, tag.script().span()); + } + + return str; } static JSString* GetRegionDisplayName(JSContext* cx, Handle displayNames, const char* locale, DisplayNamesStyle displayStyle, + DisplayNamesFallback fallback, HandleLinearString regionStr) { intl::RegionSubtag region; if (!intl::ParseStandaloneRegionTag(regionStr, region)) { @@ -471,8 +513,6 @@ static JSString* GetRegionDisplayName(JSContext* cx, // ICU always canonicalizes the input locale, but since we know that ICU's // canonicalization is incomplete, we need to perform our own canonicalization // to ensure consistent result. - // FIXME: spec issue - language tag canonicalisation not performed: - // https://github.com/tc39/proposal-intl-displaynames/issues/70 if (!tag.canonicalizeBaseName(cx)) { return nullptr; } @@ -481,10 +521,9 @@ static JSString* GetRegionDisplayName(JSContext* cx, // Note: ICU requires the region subtag to be in canonical case. const intl::RegionSubtag& canonicalRegion = tag.region(); - char regionChars[intl::LanguageTagLimits::RegionLength + 1]; + char regionChars[intl::LanguageTagLimits::RegionLength + 1] = {}; std::copy_n(canonicalRegion.span().data(), canonicalRegion.length(), regionChars); - regionChars[canonicalRegion.length()] = '\0'; ULocaleDisplayNames* ldn = GetOrCreateLocaleDisplayNames(cx, displayNames, locale, displayStyle); @@ -492,8 +531,8 @@ static JSString* GetRegionDisplayName(JSContext* cx, return nullptr; } - return CallICU(cx, [ldn, regionChars](UChar* chars, uint32_t size, - UErrorCode* status) { + JSString* str = CallICU(cx, [ldn, regionChars](UChar* chars, uint32_t size, + UErrorCode* status) { int32_t res = uldn_regionDisplayName(ldn, regionChars, chars, size, status); // |uldn_regionDisplayName| reports U_ILLEGAL_ARGUMENT_ERROR when no display @@ -504,10 +543,21 @@ static JSString* GetRegionDisplayName(JSContext* cx, } return res; }); + if (!str) { + return nullptr; + } + + // Return the canonicalized input when no localized region name was found. + if (str->empty() && fallback == DisplayNamesFallback::Code) { + return NewStringCopy(cx, tag.region().span()); + } + + return str; } static JSString* GetCurrencyDisplayName(JSContext* cx, const char* locale, DisplayNamesStyle displayStyle, + DisplayNamesFallback fallback, HandleLinearString currencyStr) { // Inlined implementation of `IsWellFormedCurrencyCode ( currency )`. if (currencyStr->length() != 3) { @@ -550,12 +600,58 @@ static JSString* GetCurrencyDisplayName(JSContext* cx, const char* locale, MOZ_ASSERT(length >= 0); if (status == U_USING_DEFAULT_WARNING) { + // Return the canonicalized input when no localized currency name was found. + if (fallback == DisplayNamesFallback::Code) { + // Canonical case for currency is upper case. + return js::StringToUpperCase(cx, currencyStr); + } return cx->emptyString(); } return NewStringCopyN(cx, name, size_t(length)); } +#ifdef DEBUG +static bool IsStandaloneMonth(UDateFormatSymbolType symbolType) { + switch (symbolType) { + case UDAT_STANDALONE_MONTHS: + case UDAT_STANDALONE_SHORT_MONTHS: + case UDAT_STANDALONE_NARROW_MONTHS: + return true; + + case UDAT_ERAS: + case UDAT_MONTHS: + case UDAT_SHORT_MONTHS: + case UDAT_WEEKDAYS: + case UDAT_SHORT_WEEKDAYS: + case UDAT_AM_PMS: + case UDAT_LOCALIZED_CHARS: + case UDAT_ERA_NAMES: + case UDAT_NARROW_MONTHS: + case UDAT_NARROW_WEEKDAYS: + case UDAT_STANDALONE_WEEKDAYS: + case UDAT_STANDALONE_SHORT_WEEKDAYS: + case UDAT_STANDALONE_NARROW_WEEKDAYS: + case UDAT_QUARTERS: + case UDAT_SHORT_QUARTERS: + case UDAT_STANDALONE_QUARTERS: + case UDAT_STANDALONE_SHORT_QUARTERS: + case UDAT_SHORTER_WEEKDAYS: + case UDAT_STANDALONE_SHORTER_WEEKDAYS: + case UDAT_CYCLIC_YEARS_WIDE: + case UDAT_CYCLIC_YEARS_ABBREVIATED: + case UDAT_CYCLIC_YEARS_NARROW: + case UDAT_ZODIAC_NAMES_WIDE: + case UDAT_ZODIAC_NAMES_ABBREVIATED: + case UDAT_ZODIAC_NAMES_NARROW: + return false; + } + + MOZ_ASSERT_UNREACHABLE("unenumerated, undocumented symbol type"); + return false; +} +#endif + static ListObject* GetDateTimeDisplayNames( JSContext* cx, Handle displayNames, const char* locale, HandleLinearString calendar, UDateFormatSymbolType symbolType, @@ -607,7 +703,7 @@ static ListObject* GetDateTimeDisplayNames( RootedValue value(cx); for (uint32_t i = 0; i < indices.size(); i++) { - uint32_t index = indices[i]; + int32_t index = indices[i]; JSString* name = CallICU(cx, [fmt, symbolType, index](UChar* chars, int32_t size, UErrorCode* status) { @@ -617,6 +713,10 @@ static ListObject* GetDateTimeDisplayNames( return nullptr; } + // Everything except Undecimber should always have a non-empty name. + MOZ_ASSERT_IF(!IsStandaloneMonth(symbolType) || index != UCAL_UNDECIMBER, + !name->empty()); + value.setString(name); if (!names->append(cx, value)) { return nullptr; @@ -633,15 +733,20 @@ static JSString* GetWeekdayDisplayName(JSContext* cx, HandleLinearString calendar, DisplayNamesStyle displayStyle, HandleLinearString code) { - double weekday; - if (!StringToNumber(cx, code, &weekday)) { - return nullptr; - } + uint8_t weekday; + { + double d; + if (!StringToNumber(cx, code, &d)) { + return nullptr; + } - // Inlined implementation of `IsValidWeekdayCode ( weekday )`. - if (!IsInteger(weekday) || weekday < 1 || weekday > 7) { - ReportInvalidOptionError(cx, "weekday", weekday); - return nullptr; + // Inlined implementation of `IsValidWeekdayCode ( weekday )`. + if (!IsInteger(d) || d < 1 || d > 7) { + ReportInvalidOptionError(cx, "weekday", d); + return nullptr; + } + + weekday = uint8_t(d); } UDateFormatSymbolType symbolType; @@ -672,24 +777,27 @@ static JSString* GetWeekdayDisplayName(JSContext* cx, } MOZ_ASSERT(names->length() == mozilla::ArrayLength(indices)); - return names->get(int32_t(weekday) - 1).toString(); + return names->get(weekday - 1).toString(); } -static JSString* GetMonthDisplayName(JSContext* cx, - Handle displayNames, - const char* locale, - HandleLinearString calendar, - DisplayNamesStyle displayStyle, - HandleLinearString code) { - double month; - if (!StringToNumber(cx, code, &month)) { - return nullptr; - } +static JSString* GetMonthDisplayName( + JSContext* cx, Handle displayNames, const char* locale, + HandleLinearString calendar, DisplayNamesStyle displayStyle, + DisplayNamesFallback fallback, HandleLinearString code) { + uint8_t month; + { + double d; + if (!StringToNumber(cx, code, &d)) { + return nullptr; + } - // Inlined implementation of `IsValidMonthCode ( month )`. - if (!IsInteger(month) || month < 1 || month > 13) { - ReportInvalidOptionError(cx, "month", month); - return nullptr; + // Inlined implementation of `IsValidMonthCode ( month )`. + if (!IsInteger(d) || d < 1 || d > 13) { + ReportInvalidOptionError(cx, "month", d); + return nullptr; + } + + month = uint8_t(d); } UDateFormatSymbolType symbolType; @@ -721,7 +829,11 @@ static JSString* GetMonthDisplayName(JSContext* cx, } MOZ_ASSERT(names->length() == mozilla::ArrayLength(indices)); - return names->get(int32_t(month) - 1).toString(); + JSString* str = names->get(month - 1).toString(); + if (str->empty() && fallback == DisplayNamesFallback::Code) { + return cx->staticStrings().getInt(month); + } + return str; } static JSString* GetQuarterDisplayName(JSContext* cx, @@ -730,15 +842,20 @@ static JSString* GetQuarterDisplayName(JSContext* cx, HandleLinearString calendar, DisplayNamesStyle displayStyle, HandleLinearString code) { - double quarter; - if (!StringToNumber(cx, code, &quarter)) { - return nullptr; - } + uint8_t quarter; + { + double d; + if (!StringToNumber(cx, code, &d)) { + return nullptr; + } - // Inlined implementation of `IsValidQuarterCode ( quarter )`. - if (!IsInteger(quarter) || quarter < 1 || quarter > 4) { - ReportInvalidOptionError(cx, "quarter", quarter); - return nullptr; + // Inlined implementation of `IsValidQuarterCode ( quarter )`. + if (!IsInteger(d) || d < 1 || d > 4) { + ReportInvalidOptionError(cx, "quarter", d); + return nullptr; + } + + quarter = uint8_t(d); } UDateFormatSymbolType symbolType; @@ -765,7 +882,7 @@ static JSString* GetQuarterDisplayName(JSContext* cx, } MOZ_ASSERT(names->length() == mozilla::ArrayLength(indices)); - return names->get(int32_t(quarter) - 1).toString(); + return names->get(quarter - 1).toString(); } static JSString* GetDayPeriodDisplayName( @@ -851,18 +968,22 @@ static JSString* GetDateTimeFieldDisplayName(JSContext* cx, const char* locale, return nullptr; } - return intl::CallICU(cx, [dtpg, field, width](UChar* chars, uint32_t size, - UErrorCode* status) { + JSString* str = intl::CallICU(cx, [dtpg, field, width](UChar* chars, + uint32_t size, + UErrorCode* status) { return udatpg_getFieldDisplayName(dtpg, field, width, chars, size, status); }); + MOZ_ASSERT_IF(str, !str->empty()); + return str; } /** - * intl_ComputeDisplayName(displayNames, locale, calendar, style, type, code) + * intl_ComputeDisplayName(displayNames, locale, calendar, style, fallback, + * type, code) */ bool js::intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() == 6); + MOZ_ASSERT(args.length() == 7); Rooted displayNames( cx, &args[0].toObject().as()); @@ -877,7 +998,7 @@ bool js::intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp) { return false; } - RootedLinearString code(cx, args[5].toString()->ensureLinear(cx)); + RootedLinearString code(cx, args[6].toString()->ensureLinear(cx)); if (!code) { return false; } @@ -899,7 +1020,22 @@ bool js::intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp) { } } - JSLinearString* type = args[4].toString()->ensureLinear(cx); + DisplayNamesFallback displayFallback; + { + JSLinearString* fallback = args[4].toString()->ensureLinear(cx); + if (!fallback) { + return false; + } + + if (StringEqualsLiteral(fallback, "none")) { + displayFallback = DisplayNamesFallback::None; + } else { + MOZ_ASSERT(StringEqualsLiteral(fallback, "code")); + displayFallback = DisplayNamesFallback::Code; + } + } + + JSLinearString* type = args[5].toString()->ensureLinear(cx); if (!type) { return false; } @@ -907,21 +1043,22 @@ bool js::intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp) { JSString* result; if (StringEqualsLiteral(type, "language")) { result = GetLanguageDisplayName(cx, displayNames, locale.get(), - displayStyle, code); + displayStyle, displayFallback, code); } else if (StringEqualsLiteral(type, "script")) { result = GetScriptDisplayName(cx, displayNames, locale.get(), displayStyle, - code); + displayFallback, code); } else if (StringEqualsLiteral(type, "region")) { result = GetRegionDisplayName(cx, displayNames, locale.get(), displayStyle, - code); + displayFallback, code); } else if (StringEqualsLiteral(type, "currency")) { - result = GetCurrencyDisplayName(cx, locale.get(), displayStyle, code); + result = GetCurrencyDisplayName(cx, locale.get(), displayStyle, + displayFallback, code); } else if (StringEqualsLiteral(type, "weekday")) { result = GetWeekdayDisplayName(cx, displayNames, locale.get(), calendar, displayStyle, code); } else if (StringEqualsLiteral(type, "month")) { result = GetMonthDisplayName(cx, displayNames, locale.get(), calendar, - displayStyle, code); + displayStyle, displayFallback, code); } else if (StringEqualsLiteral(type, "quarter")) { result = GetQuarterDisplayName(cx, displayNames, locale.get(), calendar, displayStyle, code); @@ -936,6 +1073,12 @@ bool js::intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp) { return false; } - args.rval().setString(result); + if (!result->empty()) { + args.rval().setString(result); + } else if (displayFallback == DisplayNamesFallback::Code) { + args.rval().setString(code); + } else { + args.rval().setUndefined(); + } return true; } diff --git a/js/src/builtin/intl/DisplayNames.h b/js/src/builtin/intl/DisplayNames.h index 1e022312b8..ae9d23d807 100644 --- a/js/src/builtin/intl/DisplayNames.h +++ b/js/src/builtin/intl/DisplayNames.h @@ -14,13 +14,12 @@ #include "NamespaceImports.h" #include "builtin/SelfHostingDefines.h" +#include "js/Class.h" // JSClass, JSClassOps, js::ClassSpec #include "js/Value.h" #include "vm/JSObject.h" #include "vm/List.h" #include "vm/NativeObject.h" -struct JS_PUBLIC_API JSClass; -struct JSClassOps; struct JS_PUBLIC_API JSContext; class JS_PUBLIC_API JSFreeOp; @@ -43,7 +42,7 @@ class DisplayNamesObject : public NativeObject { "INTERNALS_SLOT must match self-hosting define for internals " "object slot"); - // Estimated memory use for ULocaleDisplayNames. + // Estimated memory use for ULocaleDisplayNames (see IcuMemoryUsage). static constexpr size_t EstimatedMemoryUse = 1256; ULocaleDisplayNames* getLocaleDisplayNames() const { @@ -78,11 +77,11 @@ class DisplayNamesObject : public NativeObject { }; /** - * Return the display name for the requested code or the empty string if no - * applicable display name was found. + * Return the display name for the requested code or undefined if no applicable + * display name was found. * * Usage: result = intl_ComputeDisplayName(displayNames, locale, calendar, - * style, type, code) + * style, fallback, type, code) */ extern MOZ_MUST_USE bool intl_ComputeDisplayName(JSContext* cx, unsigned argc, Value* vp); diff --git a/js/src/builtin/intl/DisplayNames.js b/js/src/builtin/intl/DisplayNames.js index 0f1b228177..4d9aa29426 100644 --- a/js/src/builtin/intl/DisplayNames.js +++ b/js/src/builtin/intl/DisplayNames.js @@ -119,8 +119,19 @@ function InitializeDisplayNames(displayNames, locales, options, mozExtensions) { // opt: // opt object computed in InitializeDisplayNames // { // localeMatcher: "lookup" / "best fit", + // + // ca: string matching a Unicode extension type, // optional // } // + // localeMatcher: "lookup" / "best fit", + // + // style: "narrow" / "short" / "long", + // + // type: "language" / "region" / "script" / "currency" / "weekday" / + // "month" / "quarter" / "dayPeriod" / "dateTimeField" + // + // fallback: "code" / "none", + // // mozExtensions: true / false, // } // @@ -133,18 +144,15 @@ function InitializeDisplayNames(displayNames, locales, options, mozExtensions) { var requestedLocales = CanonicalizeLocaleList(locales); lazyDisplayNamesData.requestedLocales = requestedLocales; - // Steps 4-5. - if (options === undefined) - options = std_Object_create(null); - else - options = ToObject(options); + // Step 4. + options = ToObject(options); - // Step 6. + // Step 5. var opt = new Record(); lazyDisplayNamesData.opt = opt; lazyDisplayNamesData.mozExtensions = mozExtensions; - // Steps 8-9. + // Steps 7-8. var matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); opt.localeMatcher = matcher; @@ -152,27 +160,32 @@ function InitializeDisplayNames(displayNames, locales, options, mozExtensions) { var calendar = GetOption(options, "calendar", "string", undefined, undefined); if (calendar !== undefined) { - calendar = intl_ValidateAndCanonicalizeUnicodeExtensionType(calendar, "calendar"); + calendar = intl_ValidateAndCanonicalizeUnicodeExtensionType(calendar, "calendar", "ca"); } opt.ca = calendar; } - // Step 11. + // Step 10. var style = GetOption(options, "style", "string", ["narrow", "short", "long"], "long"); - // Step 12. + // Step 11. lazyDisplayNamesData.style = style; - // Step 13. + // Step 12. var type; if (mozExtensions) { type = GetOption(options, "type", "string", ["language", "region", "script", "currency", "weekday", "month", - "quarter", "dayPeriod", "dateTimeField"], "language"); + "quarter", "dayPeriod", "dateTimeField"], undefined); } else { type = GetOption(options, "type", "string", - ["language", "region", "script", "currency"], "language"); + ["language", "region", "script", "currency"], undefined); + } + + // Step 13. + if (type === undefined) { + ThrowTypeError(JSMSG_UNDEFINED_TYPE); } // Step 14. @@ -219,33 +232,16 @@ function Intl_DisplayNames_of(code) { return callFunction(CallDisplayNamesMethodIfWrapped, this, "Intl_DisplayNames_of"); } + code = ToString(code); + var internals = getDisplayNamesInternals(displayNames); // Unpack the internals object to avoid a slow runtime to selfhosted JS call // in |intl_ComputeDisplayName()|. - var {locale, calendar = "", style, type} = internals; - - code = ToString(code); - - // Steps 5-7. - var name = intl_ComputeDisplayName(displayNames, locale, calendar, style, type, code); - - // Step 8. - // This implementation returns the empty string instead of undefined if no - // result was found. - if (name !== "") { - return name; - } - - // Step 9. - if (internals.fallback === "code") { - // TODO: spec should require case normalisation: - // https://github.com/tc39/proposal-intl-displaynames/issues/72 - return code; - } + var {locale, calendar = "", style, type, fallback} = internals; - // Step 10. - return undefined; + // Steps 5-10. + return intl_ComputeDisplayName(displayNames, locale, calendar, style, fallback, type, code); } /** diff --git a/js/src/builtin/intl/IcuMemoryUsage.java b/js/src/builtin/intl/IcuMemoryUsage.java index aff38a3c67..b6afde8331 100644 --- a/js/src/builtin/intl/IcuMemoryUsage.java +++ b/js/src/builtin/intl/IcuMemoryUsage.java @@ -9,6 +9,12 @@ import java.util.stream.Collectors; /** + * Java program to estimate the memory usage of ICU objects (bug 1585536). + * + * It computes for each Intl constructor the amount of allocated memory. We're + * currently using the maximum memory ("max" in the output) to estimate the + * memory consumption of ICU objects. + * * Insert before {@code JS_InitWithFailureDiagnostic} in "js.cpp": * *
@@ -118,7 +124,7 @@ private static long parsePointer(Matcher m, int group) {
         return Long.parseLong(m.group(group), 16);
     }
 
-    private static void measure(String exec, String constructor, String initializer) throws IOException {
+    private static void measure(String exec, String constructor, String description, String initializer) throws IOException {
         var locales = Arrays.stream(Locale.getAvailableLocales()).map(Locale::toLanguageTag).sorted()
                 .collect(Collectors.toUnmodifiableList());
 
@@ -169,7 +175,7 @@ private static void measure(String exec, String constructor, String initializer)
 
         var stats = memory.statistics();
 
-        System.out.printf("%s%n", constructor);
+        System.out.printf("%s%n", description);
         System.out.printf("  max: %d%n", stats.getMax());
         System.out.printf("  min: %d%n", stats.getMin());
         System.out.printf("  avg: %.0f%n", stats.getAverage());
@@ -189,20 +195,32 @@ public static void main(String[] args) throws IOException {
             throw new RuntimeException("The first argument must point to the SpiderMonkey shell executable");
         }
 
-        var objects = new ArrayList>();
-        objects.add(Map.entry("Collator", "o.compare('a', 'b')"));
-        objects.add(Map.entry("DateTimeFormat", "o.format(0)"));
-        objects.add(Map.entry("DisplayNames", "o.of('en')"));
-        objects.add(Map.entry("ListFormat", "o.format(['a', 'b'])"));
-        objects.add(Map.entry("NumberFormat", "o.format(0)"));
+        record Entry (String constructor, String description, String initializer) {
+            public static Entry of(String constructor, String description, String initializer) {
+                return new Entry(constructor, description, initializer);
+            }
+
+            public static Entry of(String constructor, String initializer) {
+                return new Entry(constructor, constructor, initializer);
+            }
+        }
+
+        var objects = new ArrayList();
+        objects.add(Entry.of("Collator", "o.compare('a', 'b')"));
+        objects.add(Entry.of("DateTimeFormat", "DateTimeFormat (UDateFormat)", "o.format(0)"));
+        objects.add(Entry.of("DateTimeFormat", "DateTimeFormat (UDateFormat+UDateIntervalFormat)",
+                             "o.formatRange(0, 24*60*60*1000)"));
+        objects.add(Entry.of("DisplayNames", "o.of('en')"));
+        objects.add(Entry.of("ListFormat", "o.format(['a', 'b'])"));
+        objects.add(Entry.of("NumberFormat", "o.format(0)"));
         // Instantiates UPluralRules and UNumberFormatter
-        // objects.add(Map.entry("PluralRules", "o.select(0)"));
+        // objects.add(Entry.of("PluralRules", "o.select(0)"));
         // Instantiates only UPluralRules
-        objects.add(Map.entry("PluralRules", "o.resolvedOptions()"));
-        objects.add(Map.entry("RelativeTimeFormat", "o.format(0, 'hour')"));
+        objects.add(Entry.of("PluralRules", "o.resolvedOptions()"));
+        objects.add(Entry.of("RelativeTimeFormat", "o.format(0, 'hour')"));
 
         for (var entry : objects) {
-            measure(args[0], entry.getKey(), entry.getValue());
+            measure(args[0], entry.constructor, entry.description, entry.initializer);
         }
     }
 
diff --git a/js/src/builtin/intl/IntlObject.cpp b/js/src/builtin/intl/IntlObject.cpp
index 8fad9f0284..b60d50d0a5 100644
--- a/js/src/builtin/intl/IntlObject.cpp
+++ b/js/src/builtin/intl/IntlObject.cpp
@@ -836,6 +836,5 @@ static const ClassSpec IntlClassSpec = {
     CreateIntlObject, nullptr, intl_static_methods, nullptr,
     nullptr,          nullptr, IntlClassFinish};
 
-const JSClass js::IntlClass = {js_Object_str,
-                               JSCLASS_HAS_CACHED_PROTO(JSProto_Intl),
+const JSClass js::IntlClass = {"Intl", JSCLASS_HAS_CACHED_PROTO(JSProto_Intl),
                                JS_NULL_CLASS_OPS, &IntlClassSpec};
diff --git a/js/src/builtin/intl/LanguageTagGenerated.cpp b/js/src/builtin/intl/LanguageTagGenerated.cpp
index b322f9ec3d..b018889d65 100644
--- a/js/src/builtin/intl/LanguageTagGenerated.cpp
+++ b/js/src/builtin/intl/LanguageTagGenerated.cpp
@@ -447,8 +447,8 @@ void js::intl::LanguageTag::performComplexRegionMappings() {
     }
     else if (language().equalTo("kaa") ||
              language().equalTo("sog") ||
-             (language().equalTo("und") && script().equalTo("Sogd")) ||
              (language().equalTo("und") && script().equalTo("Chrs")) ||
+             (language().equalTo("und") && script().equalTo("Sogd")) ||
              (language().equalTo("und") && script().equalTo("Sogo")) ||
              language().equalTo("uz") ||
              language().equalTo("xco")) {
@@ -483,9 +483,9 @@ void js::intl::LanguageTag::performComplexRegionMappings() {
         (language().equalTo("ku") && script().equalTo("Arab")) ||
         language().equalTo("mis") ||
         language().equalTo("syr") ||
-        (language().equalTo("und") && script().equalTo("Xsux")) ||
         (language().equalTo("und") && script().equalTo("Hatr")) ||
-        (language().equalTo("und") && script().equalTo("Syrc"))) {
+        (language().equalTo("und") && script().equalTo("Syrc")) ||
+        (language().equalTo("und") && script().equalTo("Xsux"))) {
       setRegion("IQ");
     }
     else {
@@ -566,8 +566,8 @@ void js::intl::LanguageTag::performComplexRegionMappings() {
     }
     else if (language().equalTo("kaa") ||
              language().equalTo("sog") ||
-             (language().equalTo("und") && script().equalTo("Sogd")) ||
              (language().equalTo("und") && script().equalTo("Chrs")) ||
+             (language().equalTo("und") && script().equalTo("Sogd")) ||
              (language().equalTo("und") && script().equalTo("Sogo")) ||
              language().equalTo("uz") ||
              language().equalTo("xco")) {
diff --git a/js/src/builtin/intl/ListFormat.cpp b/js/src/builtin/intl/ListFormat.cpp
index 9ac2e505eb..d825426281 100644
--- a/js/src/builtin/intl/ListFormat.cpp
+++ b/js/src/builtin/intl/ListFormat.cpp
@@ -6,7 +6,6 @@
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
-#include "mozilla/Casting.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Unused.h"
@@ -36,7 +35,6 @@
 
 using namespace js;
 
-using mozilla::AssertedCast;
 using mozilla::CheckedInt;
 
 using js::intl::CallICU;
@@ -56,7 +54,7 @@ const JSClassOps ListFormatObject::classOps_ = {
     nullptr,                     // trace
 };
 const JSClass ListFormatObject::class_ = {
-    js_Object_str,
+    "Intl.ListFormat",
     JSCLASS_HAS_RESERVED_SLOTS(ListFormatObject::SLOT_COUNT) |
         JSCLASS_HAS_CACHED_PROTO(JSProto_ListFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
@@ -331,19 +329,6 @@ static bool FormatList(JSContext* cx, UListFormatter* lf,
   return true;
 }
 
-static JSString* FormattedValueToString(JSContext* cx,
-                                        const UFormattedValue* formattedValue) {
-  UErrorCode status = U_ZERO_ERROR;
-  int32_t strLength;
-  const char16_t* str = ufmtval_getString(formattedValue, &strLength, &status);
-  if (U_FAILURE(status)) {
-    intl::ReportInternalError(cx);
-    return nullptr;
-  }
-
-  return NewStringCopyN(cx, str, AssertedCast(strLength));
-}
-
 /**
  * FormatListToParts ( listFormat, list )
  */
@@ -377,7 +362,8 @@ static bool FormatListToParts(JSContext* cx, UListFormatter* lf,
     return false;
   }
 
-  RootedString overallResult(cx, FormattedValueToString(cx, formattedValue));
+  RootedString overallResult(cx,
+                             intl::FormattedValueToString(cx, formattedValue));
   if (!overallResult) {
     return false;
   }
diff --git a/js/src/builtin/intl/ListFormat.h b/js/src/builtin/intl/ListFormat.h
index 4123c712fe..26df07b8b3 100644
--- a/js/src/builtin/intl/ListFormat.h
+++ b/js/src/builtin/intl/ListFormat.h
@@ -32,7 +32,7 @@ class ListFormatObject : public NativeObject {
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
 
-  // Estimated memory use for UListFormatter.
+  // Estimated memory use for UListFormatter (see IcuMemoryUsage).
   static constexpr size_t EstimatedMemoryUse = 24;
 
   UListFormatter* getListFormatter() const {
diff --git a/js/src/builtin/intl/Locale.cpp b/js/src/builtin/intl/Locale.cpp
index 7246ffbb2e..c65a3b0485 100644
--- a/js/src/builtin/intl/Locale.cpp
+++ b/js/src/builtin/intl/Locale.cpp
@@ -46,7 +46,7 @@ using intl::LanguageTag;
 using intl::LanguageTagParser;
 
 const JSClass LocaleObject::class_ = {
-    js_Object_str,
+    "Intl.Locale",
     JSCLASS_HAS_RESERVED_SLOTS(LocaleObject::SLOT_COUNT) |
         JSCLASS_HAS_CACHED_PROTO(JSProto_Locale),
     JS_NULL_CLASS_OPS, &LocaleObject::classSpec_};
diff --git a/js/src/builtin/intl/NumberFormat.cpp b/js/src/builtin/intl/NumberFormat.cpp
index 5ecf10b1c1..8dcc9a91a9 100644
--- a/js/src/builtin/intl/NumberFormat.cpp
+++ b/js/src/builtin/intl/NumberFormat.cpp
@@ -79,7 +79,7 @@ const JSClassOps NumberFormatObject::classOps_ = {
 };
 
 const JSClass NumberFormatObject::class_ = {
-    js_Object_str,
+    "Intl.NumberFormat",
     JSCLASS_HAS_RESERVED_SLOTS(NumberFormatObject::SLOT_COUNT) |
         JSCLASS_HAS_CACHED_PROTO(JSProto_NumberFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
diff --git a/js/src/builtin/intl/NumberFormat.h b/js/src/builtin/intl/NumberFormat.h
index 99917734b7..75a1fff78f 100644
--- a/js/src/builtin/intl/NumberFormat.h
+++ b/js/src/builtin/intl/NumberFormat.h
@@ -32,7 +32,8 @@ class NumberFormatObject : public NativeObject {
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
 
-  // Estimated memory use for UNumberFormatter and UFormattedNumber.
+  // Estimated memory use for UNumberFormatter and UFormattedNumber
+  // (see IcuMemoryUsage).
   static constexpr size_t EstimatedMemoryUse = 750;
 
   UNumberFormatter* getNumberFormatter() const {
diff --git a/js/src/builtin/intl/NumberFormat.js b/js/src/builtin/intl/NumberFormat.js
index 9ac75bf535..196f0a78de 100644
--- a/js/src/builtin/intl/NumberFormat.js
+++ b/js/src/builtin/intl/NumberFormat.js
@@ -663,12 +663,12 @@ function Intl_NumberFormat_formatToParts(value) {
                             "Intl_NumberFormat_formatToParts");
     }
 
-    var internals = getNumberFormatInternals(nf);
-    var unitStyle = internals.style === "unit";
-
     // Step 4.
     var x = ToNumeric(value);
 
+    var internals = getNumberFormatInternals(nf);
+    var unitStyle = internals.style === "unit";
+
     // Step 5.
     return intl_FormatNumber(nf, x, /* formatToParts = */ true, unitStyle);
 }
diff --git a/js/src/builtin/intl/PluralRules.cpp b/js/src/builtin/intl/PluralRules.cpp
index a3a65903ee..909c4a1a97 100644
--- a/js/src/builtin/intl/PluralRules.cpp
+++ b/js/src/builtin/intl/PluralRules.cpp
@@ -51,7 +51,7 @@ const JSClassOps PluralRulesObject::classOps_ = {
 };
 
 const JSClass PluralRulesObject::class_ = {
-    js_Object_str,
+    "Intl.PluralRules",
     JSCLASS_HAS_RESERVED_SLOTS(PluralRulesObject::SLOT_COUNT) |
         JSCLASS_HAS_CACHED_PROTO(JSProto_PluralRules) |
         JSCLASS_FOREGROUND_FINALIZE,
diff --git a/js/src/builtin/intl/PluralRules.h b/js/src/builtin/intl/PluralRules.h
index 57ef3fec88..a42e7438bd 100644
--- a/js/src/builtin/intl/PluralRules.h
+++ b/js/src/builtin/intl/PluralRules.h
@@ -33,10 +33,11 @@ class PluralRulesObject : public NativeObject {
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
 
-  // Estimated memory use for UNumberFormatter and UFormattedNumber.
+  // Estimated memory use for UNumberFormatter and UFormattedNumber
+  // (see IcuMemoryUsage).
   static constexpr size_t UNumberFormatterEstimatedMemoryUse = 750;
 
-  // Estimated memory use for UPluralRules.
+  // Estimated memory use for UPluralRules (see IcuMemoryUsage).
   static constexpr size_t UPluralRulesEstimatedMemoryUse = 2976;
 
   UPluralRules* getPluralRules() const {
diff --git a/js/src/builtin/intl/PluralRules.js b/js/src/builtin/intl/PluralRules.js
index d2ac311df7..1672fef507 100644
--- a/js/src/builtin/intl/PluralRules.js
+++ b/js/src/builtin/intl/PluralRules.js
@@ -196,12 +196,12 @@ function Intl_PluralRules_select(value) {
                             "Intl_PluralRules_select");
     }
 
-    // Ensure the PluralRules internals are resolved.
-    getPluralRulesInternals(pluralRules);
-
     // Step 4.
     let n = ToNumber(value);
 
+    // Ensure the PluralRules internals are resolved.
+    getPluralRulesInternals(pluralRules);
+
     // Step 5.
     return intl_SelectPluralRule(pluralRules, n);
 }
diff --git a/js/src/builtin/intl/RelativeTimeFormat.cpp b/js/src/builtin/intl/RelativeTimeFormat.cpp
index a2f9419efe..4808e57bb0 100644
--- a/js/src/builtin/intl/RelativeTimeFormat.cpp
+++ b/js/src/builtin/intl/RelativeTimeFormat.cpp
@@ -17,6 +17,7 @@
 #include "js/PropertySpec.h"
 #include "unicode/udisplaycontext.h"
 #include "unicode/uloc.h"
+#include "unicode/unum.h"
 #include "unicode/ureldatefmt.h"
 #include "unicode/utypes.h"
 #include "vm/GlobalObject.h"
@@ -49,7 +50,7 @@ const JSClassOps RelativeTimeFormatObject::classOps_ = {
 };
 
 const JSClass RelativeTimeFormatObject::class_ = {
-    js_Object_str,
+    "Intl.RelativeTimeFormat",
     JSCLASS_HAS_RESERVED_SLOTS(RelativeTimeFormatObject::SLOT_COUNT) |
         JSCLASS_HAS_CACHED_PROTO(JSProto_RelativeTimeFormat) |
         JSCLASS_FOREGROUND_FINALIZE,
@@ -230,13 +231,42 @@ static URelativeDateTimeFormatter* NewURelativeDateTimeFormatter(
   }
 
   UErrorCode status = U_ZERO_ERROR;
+  UNumberFormat* nf = unum_open(UNUM_DECIMAL, nullptr, 0,
+                                IcuLocale(locale.get()), nullptr, &status);
+  if (U_FAILURE(status)) {
+    intl::ReportInternalError(cx);
+    return nullptr;
+  }
+  ScopedICUObject toClose(nf);
+
+  // Use the default values as if a new Intl.NumberFormat had been constructed.
+  unum_setAttribute(nf, UNUM_MIN_INTEGER_DIGITS, 1);
+  unum_setAttribute(nf, UNUM_MIN_FRACTION_DIGITS, 0);
+  unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, 3);
+  unum_setAttribute(nf, UNUM_GROUPING_USED, true);
+
+  // The undocumented magic value -2 is needed to request locale-specific data.
+  // See |icu::number::impl::Grouper::{fGrouping1, fGrouping2, fMinGrouping}|.
+  //
+  // Future ICU versions (> ICU 67) will expose it as a proper constant:
+  // https://unicode-org.atlassian.net/browse/ICU-21109
+  // https://github.com/unicode-org/icu/pull/1152
+  constexpr int32_t useLocaleData = -2;
+
+  unum_setAttribute(nf, UNUM_GROUPING_SIZE, useLocaleData);
+  unum_setAttribute(nf, UNUM_SECONDARY_GROUPING_SIZE, useLocaleData);
+  unum_setAttribute(nf, UNUM_MINIMUM_GROUPING_DIGITS, useLocaleData);
+
   URelativeDateTimeFormatter* rtf =
-      ureldatefmt_open(IcuLocale(locale.get()), nullptr, relDateTimeStyle,
+      ureldatefmt_open(IcuLocale(locale.get()), nf, relDateTimeStyle,
                        UDISPCTX_CAPITALIZATION_FOR_STANDALONE, &status);
   if (U_FAILURE(status)) {
     intl::ReportInternalError(cx);
     return nullptr;
   }
+
+  // Ownership was transferred to the URelativeDateTimeFormatter.
+  toClose.forget();
   return rtf;
 }
 
diff --git a/js/src/builtin/intl/RelativeTimeFormat.h b/js/src/builtin/intl/RelativeTimeFormat.h
index 8023eb650a..6908387c07 100644
--- a/js/src/builtin/intl/RelativeTimeFormat.h
+++ b/js/src/builtin/intl/RelativeTimeFormat.h
@@ -33,7 +33,7 @@ class RelativeTimeFormatObject : public NativeObject {
                 "INTERNALS_SLOT must match self-hosting define for internals "
                 "object slot");
 
-  // Estimated memory use for URelativeDateTimeFormatter.
+  // Estimated memory use for URelativeDateTimeFormatter (see IcuMemoryUsage).
   static constexpr size_t EstimatedMemoryUse = 278;
 
   URelativeDateTimeFormatter* getRelativeDateTimeFormatter() const {
diff --git a/js/src/builtin/intl/RelativeTimeFormat.js b/js/src/builtin/intl/RelativeTimeFormat.js
index 70768ae124..b62400b622 100644
--- a/js/src/builtin/intl/RelativeTimeFormat.js
+++ b/js/src/builtin/intl/RelativeTimeFormat.js
@@ -189,15 +189,15 @@ function Intl_RelativeTimeFormat_format(value, unit) {
                             "Intl_RelativeTimeFormat_format");
     }
 
-    // Ensure the RelativeTimeFormat internals are resolved.
-    var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
-
     // Step 3.
     let t = ToNumber(value);
 
     // Step 4.
     let u = ToString(unit);
 
+    // Ensure the RelativeTimeFormat internals are resolved.
+    var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
+
     // Step 5.
     return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric,
                                    false);
@@ -222,15 +222,15 @@ function Intl_RelativeTimeFormat_formatToParts(value, unit) {
                             "Intl_RelativeTimeFormat_formatToParts");
     }
 
-    // Ensure the RelativeTimeFormat internals are resolved.
-    var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
-
     // Step 3.
     let t = ToNumber(value);
 
     // Step 4.
     let u = ToString(unit);
 
+    // Ensure the RelativeTimeFormat internals are resolved.
+    var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
+
     // Step 5.
     return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.numeric,
                                    true);
diff --git a/js/src/builtin/intl/make_intl_data.py b/js/src/builtin/intl/make_intl_data.py
index 8ff78d01f3..89aa68f3c6 100644
--- a/js/src/builtin/intl/make_intl_data.py
+++ b/js/src/builtin/intl/make_intl_data.py
@@ -319,12 +319,11 @@ def hash_key(default, non_default_replacements):
 
         first_case = True
         for replacement_region in replacement_regions:
-            replacement_language_script = sorted(((language, script)
-                                                  for (language, script, region) in (
-                                                      non_default_replacements
-                                                  )
-                                                  if region == replacement_region),
-                                                 key=itemgetter(0))
+            replacement_language_script = sorted((language, script)
+                                                 for (language, script, region) in (
+                                                     non_default_replacements
+                                                 )
+                                                 if region == replacement_region)
 
             if_kind = u"if" if first_case else u"else if"
             first_case = False
@@ -1337,6 +1336,23 @@ def updateCLDRLangTags(args):
     out = args.out
     filename = args.file
 
+    # Determine current CLDR version from ICU.
+    if version is None:
+        icuDir = os.path.join(topsrcdir, "intl/icu/source")
+        if not os.path.isdir(icuDir):
+            raise RuntimeError("not a directory: {}".format(icuDir))
+
+        reVersion = re.compile(r'\s*cldrVersion\{"(\d+(?:\.\d+)?)"\}')
+
+        for line in flines(os.path.join(icuDir, "data/misc/supplementalData.txt")):
+            m = reVersion.match(line)
+            if m:
+                version = m.group(1)
+                break
+
+        if version is None:
+            raise RuntimeError("can't resolve CLDR version")
+
     url = url.replace("", version)
 
     print("Arguments:")
@@ -2076,11 +2092,38 @@ def generateTzDataTestBackzoneLinks(tzdataDir, version, ignoreBackzone, testDir)
     )
 
 
+def generateTzDataTestVersion(tzdataDir, version, testDir):
+    fileName = "timeZone_version.js"
+
+    with io.open(os.path.join(testDir, fileName), mode="w", encoding="utf-8", newline="") as f:
+        println = partial(print, file=f)
+
+        println(u'// |reftest| skip-if(!this.hasOwnProperty("Intl"))')
+        println(u"")
+        println(generatedFileWarning)
+        println(tzdataVersionComment.format(version))
+        println(u"""const tzdata = "{0}";""".format(version))
+
+        println(u"""
+if (typeof getICUOptions === "undefined") {
+    var getICUOptions = SpecialPowers.Cu.getJSTestingFunctions().getICUOptions;
+}
+
+var options = getICUOptions();
+
+assertEq(options.tzdata, tzdata);
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0, "ok");
+""")
+
+
 def generateTzDataTests(tzdataDir, version, ignoreBackzone, testDir):
     generateTzDataTestBackwardLinks(tzdataDir, version, ignoreBackzone, testDir)
     generateTzDataTestNotBackwardLinks(tzdataDir, version, ignoreBackzone, testDir)
     generateTzDataTestBackzone(tzdataDir, version, ignoreBackzone, testDir)
     generateTzDataTestBackzoneLinks(tzdataDir, version, ignoreBackzone, testDir)
+    generateTzDataTestVersion(tzdataDir, version, testDir)
 
 
 def updateTzdata(topsrcdir, args):
@@ -2752,7 +2795,6 @@ def EnsureHttps(v):
                                              help="Update CLDR language tags data")
     parser_cldr_tags.add_argument("--version",
                                   metavar="VERSION",
-                                  required=True,
                                   help="CLDR version number")
     parser_cldr_tags.add_argument("--url",
                                   metavar="URL",
diff --git a/js/src/builtin/streams/ClassSpecMacro.h b/js/src/builtin/streams/ClassSpecMacro.h
index 145c6b91d9..f122eabd71 100644
--- a/js/src/builtin/streams/ClassSpecMacro.h
+++ b/js/src/builtin/streams/ClassSpecMacro.h
@@ -31,7 +31,7 @@
                                    classFlags,                               \
                                classOps, &cls::classSpec_};                  \
                                                                              \
-  const JSClass cls::protoClass_ = {"object",                                \
+  const JSClass cls::protoClass_ = {#cls ".prototype",                       \
                                     JSCLASS_HAS_CACHED_PROTO(JSProto_##cls), \
                                     JS_NULL_CLASS_OPS, &cls::classSpec_};
 
diff --git a/js/src/builtin/streams/HandlerFunction-inl.h b/js/src/builtin/streams/HandlerFunction-inl.h
index d3013b769e..1688cab753 100644
--- a/js/src/builtin/streams/HandlerFunction-inl.h
+++ b/js/src/builtin/streams/HandlerFunction-inl.h
@@ -67,9 +67,20 @@ inline MOZ_MUST_USE JSFunction* NewHandlerWithExtra(
   return handlerFun;
 }
 
+inline MOZ_MUST_USE JSFunction* NewHandlerWithExtraValue(
+    JSContext* cx, Native handler, JS::Handle target,
+    JS::Handle extra) {
+  cx->check(extra);
+  JSFunction* handlerFun = NewHandler(cx, handler, target);
+  if (handlerFun) {
+    handlerFun->setExtendedSlot(StreamHandlerFunctionSlot_Extra, extra);
+  }
+  return handlerFun;
+}
+
 /**
- * Helper for handler functions that "close over" a value that is always a
- * direct reference to an object of class T, never a wrapper.
+ * Within the call of a handler function that "closes over" a target value that
+ * is always a |T*| object (and never a wrapper around one), return that |T*|.
  */
 template 
 inline MOZ_MUST_USE T* TargetFromHandler(const JS::CallArgs& args) {
@@ -80,15 +91,22 @@ inline MOZ_MUST_USE T* TargetFromHandler(const JS::CallArgs& args) {
 }
 
 /**
- * Helper for handler functions that "close over" a value that is always a
- * direct reference to an object of class T, never a wrapper.
+ * Within the call of a handler function that "closes over" a target value and
+ * an extra value, return that extra value.
+ */
+inline MOZ_MUST_USE JS::Value ExtraValueFromHandler(const JS::CallArgs& args) {
+  JSFunction& func = args.callee().as();
+  return func.getExtendedSlot(StreamHandlerFunctionSlot_Extra);
+}
+
+/**
+ * Within the call of a handler function that "closes over" a target value and
+ * an extra value, where that extra value is always a |T*| object (and never a
+ * wrapper around one), return that |T*|.
  */
 template 
 inline MOZ_MUST_USE T* ExtraFromHandler(const JS::CallArgs& args) {
-  JSFunction& func = args.callee().as();
-  return &func.getExtendedSlot(StreamHandlerFunctionSlot_Extra)
-              .toObject()
-              .as();
+  return &ExtraValueFromHandler(args).toObject().as();
 }
 
 }  // namespace js
diff --git a/js/src/builtin/streams/PipeToState-inl.h b/js/src/builtin/streams/PipeToState-inl.h
new file mode 100644
index 0000000000..664ed57735
--- /dev/null
+++ b/js/src/builtin/streams/PipeToState-inl.h
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* ReadableStream pipe-to operation captured state. */
+
+#ifndef builtin_streams_PipeToState_inl_h
+#define builtin_streams_PipeToState_inl_h
+
+#include "builtin/streams/PipeToState.h"
+
+#include "mozilla/Assertions.h"  // MOZ_ASSERT
+#include "mozilla/Attributes.h"  // MOZ_MUST_USE
+
+#include "jstypes.h"  // JS_PUBLIC_API
+
+#include "js/RootingAPI.h"  // JS::Handle
+#include "vm/JSContext.h"   // JSContext
+#include "vm/Runtime.h"     // JSRuntime
+
+#include "vm/Compartment-inl.h"  // js::UnwrapAndDowncastValue
+#include "vm/JSContext-inl.h"    // JSContext::check
+
+struct JS_PUBLIC_API JSContext;
+class JS_PUBLIC_API JSObject;
+
+namespace js {
+
+/**
+ * Returns the unwrapped |AbortSignal| instance associated with a given pipe-to
+ * operation.
+ *
+ * The pipe-to operation must be known to have had an |AbortSignal| associated
+ * with it.
+ *
+ * If the signal is a wrapper, it will be unwrapped, so the result might not be
+ * an object from the currently active compartment.
+ */
+inline MOZ_MUST_USE JSObject* UnwrapSignalFromPipeToState(
+    JSContext* cx, JS::Handle pipeToState) {
+  cx->check(pipeToState);
+
+  MOZ_ASSERT(pipeToState->hasSignal());
+  return UnwrapAndDowncastValue(
+      cx, pipeToState->getFixedSlot(PipeToState::Slot_Signal),
+      cx->runtime()->maybeAbortSignalClass());
+}
+
+}  // namespace js
+
+#endif  // builtin_streams_PipeToState_inl_h
diff --git a/js/src/builtin/streams/PipeToState.cpp b/js/src/builtin/streams/PipeToState.cpp
index 4fadadbd81..1a714b3bbc 100644
--- a/js/src/builtin/streams/PipeToState.cpp
+++ b/js/src/builtin/streams/PipeToState.cpp
@@ -4,7 +4,7 @@
 
 /* ReadableStream.prototype.pipeTo state. */
 
-#include "builtin/streams/PipeToState.h"
+#include "builtin/streams/PipeToState-inl.h"
 
 #include "mozilla/Assertions.h"  // MOZ_ASSERT
 #include "mozilla/Attributes.h"  // MOZ_MUST_USE
@@ -15,22 +15,27 @@
 
 #include "builtin/Promise.h"  // js::RejectPromiseWithPendingError
 #include "builtin/streams/ReadableStream.h"        // js::ReadableStream
-#include "builtin/streams/ReadableStreamReader.h"  // js::CreateReadableStreamDefaultReader, js::ForAuthorCodeBool, js::ReadableStreamDefaultReader
+#include "builtin/streams/ReadableStreamReader.h"  // js::CreateReadableStreamDefaultReader, js::ForAuthorCodeBool, js::ReadableStreamDefaultReader, js::ReadableStreamReaderGenericRelease
 #include "builtin/streams/WritableStream.h"        // js::WritableStream
 #include "builtin/streams/WritableStreamDefaultWriter.h"  // js::CreateWritableStreamDefaultWriter, js::WritableStreamDefaultWriter
 #include "builtin/streams/WritableStreamOperations.h"  // js::WritableStreamCloseQueuedOrInFlight
-#include "js/CallArgs.h"       // JS::CallArgsFromVp, JS::CallArgs
-#include "js/Class.h"          // JSClass, JSCLASS_HAS_RESERVED_SLOTS
-#include "js/Promise.h"        // JS::AddPromiseReactions
-#include "js/RootingAPI.h"     // JS::Handle, JS::Rooted
+#include "builtin/streams/WritableStreamWriterOperations.h"  // js::WritableStreamDefaultWriter{GetDesiredSize,Release,Write}
+#include "js/CallArgs.h"    // JS::CallArgsFromVp, JS::CallArgs
+#include "js/Class.h"       // JSClass, JSCLASS_HAS_RESERVED_SLOTS
+#include "js/Promise.h"     // JS::AddPromiseReactions
+#include "js/RootingAPI.h"  // JS::Handle, JS::Rooted
+#include "js/Value.h"  // JS::{,Int32,Magic,Object}Value, JS::UndefinedHandleValue
+#include "vm/JSContext.h"      // JSContext
 #include "vm/PromiseObject.h"  // js::PromiseObject
+#include "vm/Runtime.h"        // JSRuntime
 
-#include "builtin/streams/HandlerFunction-inl.h"  // js::NewHandler, js::TargetFromHandler
+#include "builtin/streams/HandlerFunction-inl.h"  // js::ExtraValueFromHandler, js::NewHandler{,WithExtraValue}, js::TargetFromHandler
 #include "builtin/streams/ReadableStreamReader-inl.h"  // js::UnwrapReaderFromStream, js::UnwrapStreamFromReader
 #include "builtin/streams/WritableStream-inl.h"  // js::UnwrapWriterFromStream
 #include "builtin/streams/WritableStreamDefaultWriter-inl.h"  // js::UnwrapStreamFromWriter
 #include "vm/JSContext-inl.h"  // JSContext::check
 #include "vm/JSObject-inl.h"   // js::NewBuiltinClassInstance
+#include "vm/Realm-inl.h"      // js::AutoRealm
 
 using mozilla::Maybe;
 using mozilla::Nothing;
@@ -40,33 +45,29 @@ using JS::CallArgs;
 using JS::CallArgsFromVp;
 using JS::Handle;
 using JS::Int32Value;
+using JS::MagicValue;
 using JS::ObjectValue;
 using JS::Rooted;
+using JS::UndefinedHandleValue;
 using JS::Value;
 
+using js::ExtraValueFromHandler;
 using js::GetErrorMessage;
 using js::NewHandler;
+using js::NewHandlerWithExtraValue;
 using js::PipeToState;
+using js::PromiseObject;
 using js::ReadableStream;
 using js::ReadableStreamDefaultReader;
+using js::ReadableStreamReaderGenericRelease;
 using js::TargetFromHandler;
 using js::UnwrapReaderFromStream;
 using js::UnwrapStreamFromWriter;
 using js::UnwrapWriterFromStream;
 using js::WritableStream;
 using js::WritableStreamDefaultWriter;
-
-// This typedef is undoubtedly not the right one for the long run, but it's
-// enough to be placeholder for now.
-using Action = bool (*)(JSContext*, Handle state);
-
-static MOZ_MUST_USE bool DummyAction(JSContext* cx,
-                                     Handle state) {
-  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                            JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
-                            "pipeTo dummy action");
-  return false;
-}
+using js::WritableStreamDefaultWriterRelease;
+using js::WritableStreamDefaultWriterWrite;
 
 static ReadableStream* GetUnwrappedSource(JSContext* cx,
                                           Handle state) {
@@ -93,11 +94,227 @@ static bool WritableAndNotClosing(const WritableStream* unwrappedDest) {
          WritableStreamCloseQueuedOrInFlight(unwrappedDest);
 }
 
+static MOZ_MUST_USE bool Finalize(JSContext* cx, Handle state,
+                                  Handle> error) {
+  cx->check(state);
+  cx->check(error);
+
+  // Step 1: Perform ! WritableStreamDefaultWriterRelease(writer).
+  Rooted writer(cx, state->writer());
+  cx->check(writer);
+  if (!WritableStreamDefaultWriterRelease(cx, writer)) {
+    return false;
+  }
+
+  // Step 2: Perform ! ReadableStreamReaderGenericRelease(reader).
+  Rooted reader(cx, state->reader());
+  cx->check(reader);
+  if (!ReadableStreamReaderGenericRelease(cx, reader)) {
+    return false;
+  }
+
+  // Step 3: If signal is not undefined, remove abortAlgorithm from signal.
+  // XXX
+
+  Rooted promise(cx, state->promise());
+  cx->check(promise);
+
+  // Step 4: If error was given, reject promise with error.
+  if (error.isSome()) {
+    Rooted errorVal(cx, *error.get());
+    return PromiseObject::reject(cx, promise, errorVal);
+  }
+
+  // Step 5: Otherwise, resolve promise with undefined.
+  return PromiseObject::resolve(cx, promise, UndefinedHandleValue);
+}
+
+static MOZ_MUST_USE bool Finalize(JSContext* cx, unsigned argc, Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  Rooted state(cx, TargetFromHandler(args));
+  cx->check(state);
+
+  Rooted> optionalError(cx, Nothing());
+  if (Value maybeError = ExtraValueFromHandler(args);
+      !maybeError.isMagic(JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR)) {
+    optionalError = Some(maybeError);
+  }
+  cx->check(optionalError);
+
+  if (!Finalize(cx, state, optionalError)) {
+    return false;
+  }
+
+  args.rval().setUndefined();
+  return true;
+}
+
+// Shutdown with an action, steps d-f:
+//   d. Let p be the result of performing action.
+//   e. Upon fulfillment of p, finalize, passing along originalError if it was
+//      given.
+//   f. Upon rejection of p with reason newError, finalize with newError.
+static MOZ_MUST_USE bool ActAndFinalize(JSContext* cx,
+                                        Handle state,
+                                        Handle> error) {
+  // Step d: Let p be the result of performing action.
+  Rooted p(cx);
+  switch (state->shutdownAction()) {
+    // This corresponds to the action performed by |abortAlgorithm| in
+    // ReadableStreamPipeTo step 14.1.5.
+    case PipeToState::ShutdownAction::AbortAlgorithm: {
+      MOZ_ASSERT(error.get().isSome());
+
+      // From ReadableStreamPipeTo:
+      // Step 14.1.2: Let actions be an empty ordered set.
+      // Step 14.1.3: If preventAbort is false, append the following action to
+      //              actions:
+      // Step 14.1.3.1: If dest.[[state]] is "writable", return
+      //                ! WritableStreamAbort(dest, error).
+      // Step 14.1.3.2: Otherwise, return a promise resolved with undefined.
+      // Step 14.1.4: If preventCancel is false, append the following action
+      //               action to actions:
+      // Step 14.1.4.1.: If source.[[state]] is "readable", return
+      //                 ! ReadableStreamCancel(source, error).
+      // Step 14.1.4.2: Otherwise, return a promise resolved with undefined.
+      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
+                                "any required actions during abortAlgorithm");
+      return false;
+    }
+
+    // This corresponds to the action in "shutdown with an action of
+    // ! WritableStreamAbort(dest, source.[[storedError]]) and with
+    // source.[[storedError]]."
+    case PipeToState::ShutdownAction::AbortDestStream: {
+      MOZ_ASSERT(error.get().isSome());
+
+      Rooted unwrappedDest(cx, GetUnwrappedDest(cx, state));
+      if (!unwrappedDest) {
+        return false;
+      }
+
+      Rooted sourceStoredError(cx, *error.get());
+      cx->check(sourceStoredError);
+
+      p = WritableStreamAbort(cx, unwrappedDest, sourceStoredError);
+      break;
+    }
+
+    // This corresponds to two actions:
+    //
+    // * The action in "shutdown with an action of
+    //   ! ReadableStreamCancel(source, dest.[[storedError]]) and with
+    //   dest.[[storedError]]" as used in "Errors must be propagated backward:
+    //   if dest.[[state]] is or becomes 'errored'".
+    // * The action in "shutdown with an action of
+    //   ! ReadableStreamCancel(source, destClosed) and with destClosed" as used
+    //   in "Closing must be propagated backward: if
+    //   ! WritableStreamCloseQueuedOrInFlight(dest) is true or dest.[[state]]
+    //   is 'closed'".
+    //
+    // The different reason-values are passed as |error|.
+    case PipeToState::ShutdownAction::CancelSource: {
+      MOZ_ASSERT(error.get().isSome());
+
+      Rooted unwrappedSource(cx,
+                                              GetUnwrappedSource(cx, state));
+      if (!unwrappedSource) {
+        return false;
+      }
+
+      Rooted reason(cx, *error.get());
+      cx->check(reason);
+
+      p = ReadableStreamCancel(cx, unwrappedSource, reason);
+      break;
+    }
+
+    // This corresponds to the action in "shutdown with an action of
+    // ! WritableStreamDefaultWriterCloseWithErrorPropagation(writer)" as done
+    // in "Closing must be propagated forward: if source.[[state]] is or becomes
+    // 'closed'".
+    case PipeToState::ShutdownAction::CloseWriterWithErrorPropagation: {
+      MOZ_ASSERT(error.get().isNothing());
+
+      Rooted writer(cx, state->writer());
+      cx->check(writer);  // just for good measure: we don't depend on this
+
+      p = WritableStreamDefaultWriterCloseWithErrorPropagation(cx, writer);
+      break;
+    }
+  }
+  if (!p) {
+    return false;
+  }
+
+  // Step e: Upon fulfillment of p, finalize, passing along originalError if it
+  //         was given.
+  Rooted onFulfilled(cx);
+  {
+    Rooted optionalError(
+        cx, error.isSome()
+                ? *error.get()
+                : MagicValue(JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR));
+    onFulfilled = NewHandlerWithExtraValue(cx, Finalize, state, optionalError);
+    if (!onFulfilled) {
+      return false;
+    }
+  }
+
+  // Step f: Upon rejection of p with reason newError, finalize with newError.
+  auto OnRejected = [](JSContext* cx, unsigned argc, Value* vp) {
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    Rooted state(cx, TargetFromHandler(args));
+    cx->check(state);
+
+    Rooted> newError(cx, Some(args[0]));
+    cx->check(newError);
+    if (!Finalize(cx, state, newError)) {
+      return false;
+    }
+
+    args.rval().setUndefined();
+    return true;
+  };
+
+  Rooted onRejected(cx, NewHandler(cx, OnRejected, state));
+  if (!onRejected) {
+    return false;
+  }
+
+  return JS::AddPromiseReactions(cx, p, onFulfilled, onRejected);
+}
+
+static MOZ_MUST_USE bool ActAndFinalize(JSContext* cx, unsigned argc,
+                                        Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  Rooted state(cx, TargetFromHandler(args));
+  cx->check(state);
+
+  Rooted> optionalError(cx, Nothing());
+  if (Value maybeError = ExtraValueFromHandler(args);
+      !maybeError.isMagic(JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR)) {
+    optionalError = Some(maybeError);
+  }
+  cx->check(optionalError);
+
+  if (!ActAndFinalize(cx, state, optionalError)) {
+    return false;
+  }
+
+  args.rval().setUndefined();
+  return true;
+}
+
 // Shutdown with an action: if any of the above requirements ask to shutdown
 // with an action action, optionally with an error originalError, then:
 static MOZ_MUST_USE bool ShutdownWithAction(
-    JSContext* cx, Handle state, Action action,
-    Handle> originalError) {
+    JSContext* cx, Handle state,
+    PipeToState::ShutdownAction action, Handle> originalError) {
   cx->check(state);
   cx->check(originalError);
 
@@ -109,6 +326,9 @@ static MOZ_MUST_USE bool ShutdownWithAction(
   // Step b: Set shuttingDown to true.
   state->setShuttingDown();
 
+  // Save the action away for later, potentially asynchronous, use.
+  state->setShutdownAction(action);
+
   // Step c: If dest.[[state]] is "writable" and
   //         ! WritableStreamCloseQueuedOrInFlight(dest) is false,
   WritableStream* unwrappedDest = GetUnwrappedDest(cx, state);
@@ -118,20 +338,43 @@ static MOZ_MUST_USE bool ShutdownWithAction(
   if (WritableAndNotClosing(unwrappedDest)) {
     // Step c.i:  If any chunks have been read but not yet written, write them
     //            to dest.
+    //
+    // Any chunk that has been read, will have been processed and a pending
+    // write for it created by this point.  (A pending read has not been "read".
+    // And any pending read, will not be processed into a pending write because
+    // of the |state->setShuttingDown()| above in concert with the early exit
+    // in this case in |ReadFulfilled|.)
+
     // Step c.ii: Wait until every chunk that has been read has been written
     //            (i.e. the corresponding promises have settled).
+    if (PromiseObject* p = state->lastWriteRequest()) {
+      Rooted lastWriteRequest(cx, p);
+
+      Rooted extra(
+          cx,
+          originalError.isSome()
+              ? *originalError.get()
+              : MagicValue(JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR));
+
+      Rooted actAndfinalize(
+          cx, NewHandlerWithExtraValue(cx, ActAndFinalize, state, extra));
+      if (!actAndfinalize) {
+        return false;
+      }
+
+      return JS::AddPromiseReactions(cx, lastWriteRequest, actAndfinalize,
+                                     actAndfinalize);
+    }
+
+    // If no last write request was ever created, we can fall through and
+    // synchronously perform the remaining steps.
   }
 
   // Step d: Let p be the result of performing action.
   // Step e: Upon fulfillment of p, finalize, passing along originalError if it
   //         was given.
   // Step f: Upon rejection of p with reason newError, finalize with newError.
-
-  // XXX fill me in!
-  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                            JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
-                            "pipeTo shutdown with action");
-  return false;
+  return ActAndFinalize(cx, state, originalError);
 }
 
 // Shutdown: if any of the above requirements or steps ask to shutdown,
@@ -156,19 +399,41 @@ static MOZ_MUST_USE bool Shutdown(JSContext* cx, Handle state,
     return false;
   }
   if (WritableAndNotClosing(unwrappedDest)) {
-    // Step c.i:  If any chunks have been read but not yet written, write them
-    //            to dest.
-    // Step c.ii: Wait until every chunk that has been read has been written
-    //            (i.e. the corresponding promises have settled).
+    // Step 1: If any chunks have been read but not yet written, write them to
+    //         dest.
+    //
+    // Any chunk that has been read, will have been processed and a pending
+    // write for it created by this point.  (A pending read has not been "read".
+    // And any pending read, will not be processed into a pending write because
+    // of the |state->setShuttingDown()| above in concert with the early exit
+    // in this case in |ReadFulfilled|.)
+
+    // Step 2: Wait until every chunk that has been read has been written
+    //         (i.e. the corresponding promises have settled).
+    if (PromiseObject* p = state->lastWriteRequest()) {
+      Rooted lastWriteRequest(cx, p);
+
+      Rooted extra(
+          cx,
+          error.isSome()
+              ? *error.get()
+              : MagicValue(JS_READABLESTREAM_PIPETO_FINALIZE_WITHOUT_ERROR));
+
+      Rooted finalize(
+          cx, NewHandlerWithExtraValue(cx, Finalize, state, extra));
+      if (!finalize) {
+        return false;
+      }
+
+      return JS::AddPromiseReactions(cx, lastWriteRequest, finalize, finalize);
+    }
+
+    // If no last write request was ever created, we can fall through and
+    // synchronously perform the remaining steps.
   }
 
   // Step d: Finalize, passing along error if it was given.
-
-  // XXX fill me in!
-  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                            JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
-                            "pipeTo shutdown");
-  return false;
+  return Finalize(cx, state, error);
 }
 
 /**
@@ -186,6 +451,37 @@ static MOZ_MUST_USE bool OnSourceErrored(
     return false;
   }
 
+  // If |source| becomes errored not during a pending read, it's clear we must
+  // react immediately.
+  //
+  // But what if |source| becomes errored *during* a pending read?  Should this
+  // first error, or the pending-read second error, predominate?  Two semantics
+  // are possible when |source|/|dest| become closed or errored while there's a
+  // pending read:
+  //
+  //   1. Wait until the read fulfills or rejects, then respond to the
+  //      closure/error without regard to the read having fulfilled or rejected.
+  //      (This will simply not react to the read being rejected, or it will
+  //      queue up the read chunk to be written during shutdown.)
+  //   2. React to the closure/error immediately per "Error and close states
+  //      must be propagated".  Then when the read fulfills or rejects later, do
+  //      nothing.
+  //
+  // The spec doesn't clearly require either semantics.  It requires that
+  // *already-read* chunks be written (at least if |dest| didn't become errored
+  // or closed such that no further writes can occur).  But it's silent as to
+  // not-fully-read chunks.  (These semantic differences may only be observable
+  // with very carefully constructed readable/writable streams.)
+  //
+  // It seems best, generally, to react to the temporally-earliest problem that
+  // arises, so we implement option #2.  (Blink, in contrast, currently
+  // implements option #1.)
+  //
+  // All specified reactions to a closure/error invoke either the shutdown, or
+  // shutdown with an action, algorithms.  Those algorithms each abort if either
+  // shutdown algorithm has already been invoked.  So we don't need to do
+  // anything special here to deal with a pending read.
+
   // ii. Otherwise (if preventAbort is true), shutdown with
   //     source.[[storedError]].
   if (state->preventAbort()) {
@@ -197,7 +493,9 @@ static MOZ_MUST_USE bool OnSourceErrored(
   //    ! WritableStreamAbort(dest, source.[[storedError]]) and with
   //    source.[[storedError]].
   else {
-    if (!ShutdownWithAction(cx, state, DummyAction, storedError)) {
+    if (!ShutdownWithAction(cx, state,
+                            PipeToState::ShutdownAction::AbortDestStream,
+                            storedError)) {
       return false;
     }
   }
@@ -220,6 +518,14 @@ static MOZ_MUST_USE bool OnDestErrored(JSContext* cx,
     return false;
   }
 
+  // As in |OnSourceErrored| above, we must deal with the case of |dest|
+  // erroring before a pending read has fulfilled or rejected.
+  //
+  // As noted there, we handle the *first* error that arises.  And because this
+  // algorithm immediately invokes a shutdown algorithm, and shutting down will
+  // inhibit future shutdown attempts, we don't need to do anything special
+  // *here*, either.
+
   // ii. Otherwise (if preventCancel is true), shutdown with
   //     dest.[[storedError]].
   if (state->preventCancel()) {
@@ -231,7 +537,9 @@ static MOZ_MUST_USE bool OnDestErrored(JSContext* cx,
   //    ! ReadableStreamCancel(source, dest.[[storedError]]) and with
   //    dest.[[storedError]].
   else {
-    if (!ShutdownWithAction(cx, state, DummyAction, storedError)) {
+    if (!ShutdownWithAction(cx, state,
+                            PipeToState::ShutdownAction::CancelSource,
+                            storedError)) {
       return false;
     }
   }
@@ -250,6 +558,13 @@ static MOZ_MUST_USE bool OnSourceClosed(JSContext* cx,
 
   Rooted> noError(cx, Nothing());
 
+  // It shouldn't be possible for |source| to become closed *during* a pending
+  // read: such spontaneous closure *should* be enqueued for processing *after*
+  // the settling of the pending read.  (Note also that a [[closedPromise]]
+  // resolution in |ReadableStreamClose| occurs only after all pending reads are
+  // resolved.)  So we need not do anything to handle a source closure while a
+  // read is in progress.
+
   // ii. Otherwise (if preventClose is true), shutdown.
   if (state->preventClose()) {
     if (!Shutdown(cx, state, noError)) {
@@ -259,7 +574,10 @@ static MOZ_MUST_USE bool OnSourceClosed(JSContext* cx,
   // i. If preventClose is false, shutdown with an action of
   //    ! WritableStreamDefaultWriterCloseWithErrorPropagation(writer).
   else {
-    if (!ShutdownWithAction(cx, state, DummyAction, noError)) {
+    if (!ShutdownWithAction(
+            cx, state,
+            PipeToState::ShutdownAction::CloseWriterWithErrorPropagation,
+            noError)) {
       return false;
     }
   }
@@ -302,6 +620,18 @@ static MOZ_MUST_USE bool OnDestClosed(JSContext* cx,
     destClosed = Some(v.get());
   }
 
+  // As in all the |On{Source,Dest}{Closed,Errored}| above, we must consider the
+  // possibility that we're in the middle of a pending read.  |state->writer()|
+  // has a lock on |dest| here, so we know only we can be writing chunks to
+  // |dest| -- but there's no reason why |dest| couldn't become closed of its
+  // own accord here (for example, a socket might become closed on its own), and
+  // such closure may or may not be equivalent to error.
+  //
+  // For the reasons noted in |OnSourceErrored|, we process closure in the
+  // middle of a pending read immediately, without delaying for that read to
+  // fulfill or reject.  We trigger a shutdown operation below, which will
+  // ensure shutdown only occurs once, so we need not do anything special here.
+
   // iv. Otherwise (if preventCancel is true), shutdown with destClosed.
   if (state->preventCancel()) {
     if (!Shutdown(cx, state, destClosed)) {
@@ -311,7 +641,8 @@ static MOZ_MUST_USE bool OnDestClosed(JSContext* cx,
   // iii. If preventCancel is false, shutdown with an action of
   //      ! ReadableStreamCancel(source, destClosed) and with destClosed.
   else {
-    if (!ShutdownWithAction(cx, state, DummyAction, destClosed)) {
+    if (!ShutdownWithAction(
+            cx, state, PipeToState::ShutdownAction::CancelSource, destClosed)) {
       return false;
     }
   }
@@ -445,12 +776,276 @@ static inline JSObject* GetClosedPromise(
   return unwrappedAccessor->closedPromise();
 }
 
+static MOZ_MUST_USE bool ReadFromSource(JSContext* cx,
+                                        Handle state);
+
+static bool ReadFulfilled(JSContext* cx, Handle state,
+                          Handle result) {
+  cx->check(state);
+  cx->check(result);
+
+  state->clearPendingRead();
+
+  // "Shutdown must stop activity: if shuttingDown becomes true, the user agent
+  // must not initiate further reads from reader, and must only perform writes
+  // of already-read chunks".
+  //
+  // We may reach this point after |On{Source,Dest}{Clos,Error}ed| has responded
+  // to an out-of-band change.  Per the comment in |OnSourceErrored|, we want to
+  // allow the implicated shutdown to proceed, and we don't want to interfere
+  // with or additionally alter its operation.  Particularly, we don't want to
+  // queue up the successfully-read chunk (if there was one, and this isn't just
+  // reporting "done") to be written: it wasn't "already-read" when that
+  // error/closure happened.
+  //
+  // All specified reactions to a closure/error invoke either the shutdown, or
+  // shutdown with an action, algorithms.  Those algorithms each abort if either
+  // shutdown algorithm has already been invoked.  So we check for shutdown here
+  // in case of asynchronous closure/error and abort if shutdown has already
+  // started (and possibly finished).
+  if (state->shuttingDown()) {
+    return true;
+  }
+
+  {
+    bool done;
+    {
+      Rooted doneVal(cx);
+      if (!GetProperty(cx, result, result, cx->names().done, &doneVal)) {
+        return false;
+      }
+      done = doneVal.toBoolean();
+    }
+
+    if (done) {
+      // All chunks have been read from |reader| and written to |writer| (but
+      // not necessarily fulfilled yet, in the latter case).  Proceed as if
+      // |source| is now closed.  (This will asynchronously wait until any
+      // pending writes have fulfilled.)
+      return OnSourceClosed(cx, state);
+    }
+  }
+
+  // A chunk was read, and *at the time the read was requested*, |dest| was
+  // ready to accept a write.  (Only one read is processed at a time per
+  // |state->hasPendingRead()|, so this condition remains true now.)  Write the
+  // chunk to |dest|.
+  {
+    Rooted chunk(cx);
+    if (!GetProperty(cx, result, result, cx->names().value, &chunk)) {
+      return false;
+    }
+
+    Rooted writer(cx, state->writer());
+    cx->check(writer);
+
+    PromiseObject* writeRequest =
+        WritableStreamDefaultWriterWrite(cx, writer, chunk);
+    if (!writeRequest) {
+      return false;
+    }
+
+    // Stash away this new last write request.  (The shutdown process will react
+    // to this write request to finish shutdown only once all pending writes are
+    // completed.)
+    state->updateLastWriteRequest(writeRequest);
+  }
+
+  // Read another chunk if this write didn't fill up |dest|.
+  //
+  // While we (properly) ignored |state->shuttingDown()| earlier, this call will
+  // *not* initiate a fresh read if |!state->shuttingDown()|.
+  return ReadFromSource(cx, state);
+}
+
+static bool ReadFulfilled(JSContext* cx, unsigned argc, Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+  MOZ_ASSERT(args.length() == 1);
+
+  Rooted state(cx, TargetFromHandler(args));
+  cx->check(state);
+
+  Rooted result(cx, &args[0].toObject());
+  cx->check(result);
+
+  if (!ReadFulfilled(cx, state, result)) {
+    return false;
+  }
+
+  args.rval().setUndefined();
+  return true;
+}
+
+static bool ReadFromSource(JSContext* cx, unsigned argc, Value* vp);
+
+static MOZ_MUST_USE bool ReadFromSource(JSContext* cx,
+                                        Handle state) {
+  cx->check(state);
+
+  MOZ_ASSERT(!state->hasPendingRead(),
+             "should only have one read in flight at a time, because multiple "
+             "reads could cause the latter read to ignore backpressure "
+             "signals");
+
+  // "Shutdown must stop activity: if shuttingDown becomes true, the user agent
+  // must not initiate further reads from reader..."
+  if (state->shuttingDown()) {
+    return true;
+  }
+
+  Rooted writer(cx, state->writer());
+  cx->check(writer);
+
+  // "While WritableStreamDefaultWriterGetDesiredSize(writer) is ≤ 0 or is null,
+  // the user agent must not read from reader."
+  Rooted desiredSize(cx);
+  if (!WritableStreamDefaultWriterGetDesiredSize(cx, writer, &desiredSize)) {
+    return false;
+  }
+
+  // If we're in the middle of erroring or are fully errored, either way the
+  // |dest|-closed reaction queued up in |StartPiping| will do the right
+  // thing, so do nothing here.
+  if (desiredSize.isNull()) {
+#ifdef DEBUG
+    {
+      WritableStream* unwrappedDest = GetUnwrappedDest(cx, state);
+      if (!unwrappedDest) {
+        return false;
+      }
+
+      MOZ_ASSERT(unwrappedDest->erroring() || unwrappedDest->errored());
+    }
+#endif
+
+    return true;
+  }
+
+  // If |dest| isn't ready to receive writes yet (i.e. backpressure applies),
+  // resume when it is.
+  MOZ_ASSERT(desiredSize.isNumber());
+  if (desiredSize.toNumber() <= 0) {
+    Rooted readyPromise(cx, writer->readyPromise());
+    cx->check(readyPromise);
+
+    Rooted readFromSource(cx,
+                                       NewHandler(cx, ReadFromSource, state));
+    if (!readFromSource) {
+      return false;
+    }
+
+    // Resume when there's writable capacity.  Don't bother handling rejection:
+    // if this happens, the stream is going to be errored shortly anyway, and
+    // |StartPiping| has us ready to react to that already.
+    //
+    // XXX Double-check the claim that we need not handle rejections and that a
+    //     rejection of [[readyPromise]] *necessarily* is always followed by
+    //     rejection of [[closedPromise]].
+    return JS::AddPromiseReactionsIgnoringUnhandledRejection(
+        cx, readyPromise, readFromSource, nullptr);
+  }
+
+  // |dest| is ready to receive at least one write.  Read one chunk from the
+  // reader now that we're not subject to backpressure.
+  Rooted reader(cx, state->reader());
+  cx->check(reader);
+
+  Rooted readRequest(
+      cx, js::ReadableStreamDefaultReaderRead(cx, reader));
+  if (!readRequest) {
+    return false;
+  }
+
+  Rooted readFulfilled(cx, NewHandler(cx, ReadFulfilled, state));
+  if (!readFulfilled) {
+    return false;
+  }
+
+#ifdef DEBUG
+  MOZ_ASSERT(!state->pendingReadWouldBeRejected());
+
+  // The specification for ReadableStreamError ensures that rejecting a read or
+  // read-into request is immediately followed by rejecting the reader's
+  // [[closedPromise]].  Therefore, it does not appear *necessary* to handle the
+  // rejected case -- the [[closedPromise]] reaction will do so for us.
+  //
+  // However, this is all very stateful and gnarly, so we implement a rejection
+  // handler that sets a flag to indicate the read was rejected.  Then if the
+  // [[closedPromise]] reaction function is invoked, we can assert that *if*
+  // a read is recorded as pending at that instant, a reject handler would have
+  // been invoked for it.
+  auto ReadRejected = [](JSContext* cx, unsigned argc, Value* vp) {
+    CallArgs args = CallArgsFromVp(argc, vp);
+    MOZ_ASSERT(args.length() == 1);
+
+    Rooted state(cx, TargetFromHandler(args));
+    cx->check(state);
+
+    state->setPendingReadWouldBeRejected();
+
+    args.rval().setUndefined();
+    return true;
+  };
+
+  Rooted readRejected(cx, NewHandler(cx, ReadRejected, state));
+  if (!readRejected) {
+    return false;
+  }
+#else
+  auto readRejected = nullptr;
+#endif
+
+  // Once the chunk is read, immediately write it and attempt to read more.
+  // Don't bother handling a rejection: |source| will be closed/errored, and
+  // |StartPiping| poised us to react to that already.
+  if (!JS::AddPromiseReactionsIgnoringUnhandledRejection(
+          cx, readRequest, readFulfilled, readRejected)) {
+    return false;
+  }
+
+  // The spec is clear that a write started before an error/stream-closure is
+  // encountered must be completed before shutdown.  It is *not* clear that a
+  // read that hasn't yet fulfilled should delay shutdown (or until that read's
+  // successive write is completed).
+  //
+  // It seems easiest to explain, both from a user perspective (no read is ever
+  // just dropped on the ground) and an implementer perspective (if we *don't*
+  // delay, then a read could be started, a shutdown could be started, then the
+  // read could finish but we can't write it which arguably conflicts with the
+  // requirement that chunks that have been read must be written before shutdown
+  // completes), to delay.  XXX file a spec issue to require this!
+  state->setPendingRead();
+  return true;
+}
+
+static bool ReadFromSource(JSContext* cx, unsigned argc, Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  Rooted state(cx, TargetFromHandler(args));
+  cx->check(state);
+
+  if (!ReadFromSource(cx, state)) {
+    return false;
+  }
+
+  args.rval().setUndefined();
+  return true;
+}
+
 static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
                                      Handle unwrappedSource,
                                      Handle unwrappedDest) {
   cx->check(state);
 
-  // If source/dest are closed or errored, don't start piping.
+  // "Shutdown must stop activity: if shuttingDown becomes true, the user agent
+  // must not initiate further reads from reader..."
+  MOZ_ASSERT(!state->shuttingDown(), "can't be shutting down when starting");
+
+  // "Error and close states must be propagated: the following conditions must
+  // be applied in order."
+  //
+  // Before piping has started, we have to check for source/dest being errored
+  // or closed manually.
   bool erroredOrClosed;
   if (!SourceOrDestErroredOrClosed(cx, state, unwrappedSource, unwrappedDest,
                                    &erroredOrClosed)) {
@@ -460,8 +1055,8 @@ static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
     return true;
   }
 
-  // In the long run, react to source/dest becoming errored or closed using
-  // separate promises.
+  // *After* piping has started, add reactions to respond to source/dest
+  // becoming errored or closed.
   {
     Rooted unwrappedClosedPromise(cx);
     Rooted onClosed(cx);
@@ -505,10 +1100,38 @@ static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
     }
   }
 
-  // XXX Operations extending beyond preconditions are not yet implemented.
+  return ReadFromSource(cx, state);
+}
+
+/**
+ * Stream spec, 4.8.1. ReadableStreamPipeTo ( source, dest,
+ *                                            preventClose, preventAbort,
+ *                                            preventCancel[, signal] )
+ * Step 14.1 abortAlgorithm.
+ */
+static MOZ_MUST_USE bool PerformAbortAlgorithm(JSContext* cx,
+                                               Handle state) {
+  cx->check(state);
+
+  // Step 14.1: Let abortAlgorithm be the following steps:
+  // Step 14.1.1: Let error be a new "AbortError" DOMException.
+  // Step 14.1.2: Let actions be an empty ordered set.
+  // Step 14.1.3: If preventAbort is false, append the following action to
+  //              actions:
+  // Step 14.1.3.1: If dest.[[state]] is "writable", return
+  //                ! WritableStreamAbort(dest, error).
+  // Step 14.1.3.2: Otherwise, return a promise resolved with undefined.
+  // Step 14.1.4: If preventCancel is false, append the following action action
+  //              to actions:
+  // Step 14.1.4.1: If source.[[state]] is "readable", return
+  //                ! ReadableStreamCancel(source, error).
+  // Step 14.1.4.2: Otherwise, return a promise resolved with undefined.
+  // Step 14.1.5: Shutdown with an action consisting of getting a promise to
+  //              wait for all of the actions in actions, and with error.
+  // XXX jwalden
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
-                            "pipeTo");
+                            "abortAlgorithm steps");
   return false;
 }
 
@@ -524,14 +1147,20 @@ static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
     Handle unwrappedDest, bool preventClose, bool preventAbort,
     bool preventCancel, Handle signal) {
   cx->check(promise);
+  cx->check(signal);
+
+  Rooted state(cx, NewBuiltinClassInstance(cx));
+  if (!state) {
+    return nullptr;
+  }
 
   // Step 4. Assert: signal is undefined or signal is an instance of the
   //         AbortSignal interface.
-#ifdef DEBUG
+  MOZ_ASSERT(state->getFixedSlot(Slot_Signal).isUndefined());
   if (signal) {
-    // XXX jwalden need to add JSAPI hooks to recognize AbortSignal instances
+    // |signal| is double-checked to be an |AbortSignal| further down.
+    state->initFixedSlot(Slot_Signal, ObjectValue(*signal));
   }
-#endif
 
   // Step 5: Assert: ! IsReadableStreamLocked(source) is false.
   MOZ_ASSERT(!unwrappedSource->locked());
@@ -539,11 +1168,6 @@ static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
   // Step 6: Assert: ! IsWritableStreamLocked(dest) is false.
   MOZ_ASSERT(!unwrappedDest->isLocked());
 
-  Rooted state(cx, NewBuiltinClassInstance(cx));
-  if (!state) {
-    return nullptr;
-  }
-
   MOZ_ASSERT(state->getFixedSlot(Slot_Promise).isUndefined());
   state->initFixedSlot(Slot_Promise, ObjectValue(*promise));
 
@@ -592,8 +1216,44 @@ static MOZ_MUST_USE bool StartPiping(JSContext* cx, Handle state,
   // Step 12 ("Let promise be a new promise.") was performed by the caller and
   // |promise| was its result.
 
+  // XXX This used to be step 13 but is now step 14, all the step-comments of
+  //     the overall algorithm need renumbering.
   // Step 13: If signal is not undefined,
-  // XXX jwalden need JSAPI to add an algorithm/steps to an AbortSignal
+  if (signal) {
+    // Step 14.2: If signal’s aborted flag is set, perform abortAlgorithm and
+    //         return promise.
+    bool aborted;
+    {
+      // Sadly, we can't assert |signal| is an |AbortSignal| here because it
+      // could have become a nuked CCW since it was type-checked.
+      JSObject* unwrappedSignal = UnwrapSignalFromPipeToState(cx, state);
+      if (!unwrappedSignal) {
+        return nullptr;
+      }
+
+      JSRuntime* rt = cx->runtime();
+      MOZ_ASSERT(unwrappedSignal->hasClass(rt->maybeAbortSignalClass()));
+
+      AutoRealm ar(cx, unwrappedSignal);
+      aborted = rt->abortSignalIsAborted(unwrappedSignal);
+    }
+    if (aborted) {
+      if (!PerformAbortAlgorithm(cx, state)) {
+        return nullptr;
+      }
+
+      // Returning |state| here will cause |promise| to be returned by the
+      // overall algorithm.
+      return state;
+    }
+
+    // Step 14.3: Add abortAlgorithm to signal.
+    // XXX jwalden need JSAPI to add an algorithm/steps to an AbortSignal
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                              JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED,
+                              "adding abortAlgorithm to signal");
+    return nullptr;
+  }
 
   // Step 14: In parallel, using reader and writer, read all chunks from source
   //          and write them to dest.
diff --git a/js/src/builtin/streams/PipeToState.h b/js/src/builtin/streams/PipeToState.h
index c43991f029..0bcd4b6eed 100644
--- a/js/src/builtin/streams/PipeToState.h
+++ b/js/src/builtin/streams/PipeToState.h
@@ -7,7 +7,8 @@
 #ifndef builtin_streams_PipeToState_h
 #define builtin_streams_PipeToState_h
 
-#include "mozilla/Assertions.h"  // MOZ_ASSERT
+#include "mozilla/Assertions.h"          // MOZ_ASSERT
+#include "mozilla/WrappingOperations.h"  // mozilla::WrapToSigned
 
 #include   // uint32_t
 
@@ -70,23 +71,110 @@ class PipeToState : public NativeObject {
      */
     Slot_Writer,
 
+    /**
+     * The |PromiseObject*| of the last write performed to the destinationg
+     * |WritableStream| using the writer in |Slot_Writer|.  If no writes have
+     * yet been performed, this slot contains |undefined|.
+     *
+     * This promise is created inside a handler function in the same compartment
+     * and realm as this |PipeToState|, so it is always a |PromiseObject*| and
+     * never a wrapper around one.
+     */
+    Slot_LastWriteRequest,
+
+    /**
+     * Either |undefined| or an |AbortSignal| instance specified by the user,
+     * whose controller may be used to externally abort the piping algorithm.
+     *
+     * This signal is user-provided, so it may be a wrapper around an
+     * |AbortSignal| not from the same compartment as this.
+     */
+    Slot_Signal,
+
     SlotCount,
   };
 
+  // The set of possible actions to be passed to the "shutdown with an action"
+  // algorithm.
+  //
+  // We store actions as numbers because 1) handler functions already devote
+  // their extra slots to target and extra value; and 2) storing a full function
+  // pointer would require an extra slot, while storing as number packs into
+  // existing flag storage.
+  enum class ShutdownAction {
+    /** The action used during |abortAlgorithm|.*/
+    AbortAlgorithm,
+
+    /**
+     * The action taken when |source| errors and aborting is not prevented, to
+     * abort |dest| with |source|'s error.
+     */
+    AbortDestStream,
+
+    /**
+     * The action taken when |dest| becomes errored or closed and canceling is
+     * not prevented, to cancel |source| with |dest|'s error.
+     */
+    CancelSource,
+
+    /**
+     * The action taken when |source| closes and closing is not prevented, to
+     * close the writer while propagating any error in it.
+     */
+    CloseWriterWithErrorPropagation,
+
+  };
+
  private:
   enum Flags : uint32_t {
-    Flag_ShuttingDown = 0b0001,
+    /**
+     * The action passed to the "shutdown with an action" algorithm.
+     *
+     * Note that because only the first "shutdown" and "shutdown with an action"
+     * operation has any effect, we can store this action in |PipeToState| in
+     * the first invocation of either operation without worrying about it being
+     * overwritten.
+     *
+     * Purely for convenience, we encode this in the lowest bits so that the
+     * result of a mask is the underlying value of the correct |ShutdownAction|.
+     */
+    Flag_ShutdownActionBits = 0b0000'0011,
+
+    Flag_ShuttingDown = 0b0000'0100,
+
+    Flag_PendingRead = 0b0000'1000,
+#ifdef DEBUG
+    Flag_PendingReadWouldBeRejected = 0b0001'0000,
+#endif
 
-    Flag_PreventClose = 0b0010,
-    Flag_PreventAbort = 0b0100,
-    Flag_PreventCancel = 0b1000,
+    Flag_PreventClose = 0b0010'0000,
+    Flag_PreventAbort = 0b0100'0000,
+    Flag_PreventCancel = 0b1000'0000,
   };
 
   uint32_t flags() const { return getFixedSlot(Slot_Flags).toInt32(); }
   void setFlags(uint32_t flags) {
-    setFixedSlot(Slot_Flags, JS::Int32Value(flags));
+    setFixedSlot(Slot_Flags, JS::Int32Value(mozilla::WrapToSigned(flags)));
   }
 
+  // Flags start out zeroed, so the initially-stored shutdown action value will
+  // be this value.  (This is also the value of an *initialized* shutdown
+  // action, but it doesn't seem worth the trouble to store an extra bit to
+  // detect this specific action being recorded multiple times, purely for
+  // assertions.)
+  static constexpr ShutdownAction UninitializedAction =
+      ShutdownAction::AbortAlgorithm;
+
+  static_assert(Flag_ShutdownActionBits & 1,
+                "shutdown action bits must be low-order bits so that we can "
+                "cast ShutdownAction values directly to bits to store");
+
+  static constexpr uint32_t MaxAction =
+      static_cast(ShutdownAction::CloseWriterWithErrorPropagation);
+
+  static_assert(MaxAction <= Flag_ShutdownActionBits,
+                "max action shouldn't overflow available bits to store it");
+
  public:
   static const JSClass class_;
 
@@ -106,16 +194,80 @@ class PipeToState : public NativeObject {
                 .as();
   }
 
+  PromiseObject* lastWriteRequest() const {
+    const auto& slot = getFixedSlot(Slot_LastWriteRequest);
+    if (slot.isUndefined()) {
+      return nullptr;
+    }
+
+    return &slot.toObject().as();
+  }
+
+  void updateLastWriteRequest(PromiseObject* writeRequest) {
+    MOZ_ASSERT(writeRequest != nullptr);
+    setFixedSlot(Slot_LastWriteRequest, JS::ObjectValue(*writeRequest));
+  }
+
+  bool hasSignal() const {
+    JS::Value v = getFixedSlot(Slot_Signal);
+    MOZ_ASSERT(v.isObject() || v.isUndefined());
+    return v.isObject();
+  }
+
   bool shuttingDown() const { return flags() & Flag_ShuttingDown; }
   void setShuttingDown() {
     MOZ_ASSERT(!shuttingDown());
     setFlags(flags() | Flag_ShuttingDown);
   }
 
+  ShutdownAction shutdownAction() const {
+    MOZ_ASSERT(shuttingDown(),
+               "must be shutting down to have a shutdown action");
+
+    uint32_t bits = flags() & Flag_ShutdownActionBits;
+    static_assert(Flag_ShutdownActionBits & 1,
+                  "shutdown action bits are assumed to be low-order bits that "
+                  "don't have to be shifted down to ShutdownAction's range");
+
+    MOZ_ASSERT(bits <= MaxAction, "bits must encode a valid action");
+
+    return static_cast(bits);
+  }
+
+  void setShutdownAction(ShutdownAction action) {
+    MOZ_ASSERT(shuttingDown(),
+               "must be protected by the |shuttingDown| boolean to save the "
+               "shutdown action");
+    MOZ_ASSERT(shutdownAction() == UninitializedAction,
+               "should only set shutdown action once");
+
+    setFlags(flags() | static_cast(action));
+  }
+
   bool preventClose() const { return flags() & Flag_PreventClose; }
   bool preventAbort() const { return flags() & Flag_PreventAbort; }
   bool preventCancel() const { return flags() & Flag_PreventCancel; }
 
+  bool hasPendingRead() const { return flags() & Flag_PendingRead; }
+  void setPendingRead() {
+    MOZ_ASSERT(!hasPendingRead());
+    setFlags(flags() | Flag_PendingRead);
+  }
+  void clearPendingRead() {
+    MOZ_ASSERT(hasPendingRead());
+    setFlags(flags() & ~Flag_PendingRead);
+  }
+
+#ifdef DEBUG
+  bool pendingReadWouldBeRejected() const {
+    return flags() & Flag_PendingReadWouldBeRejected;
+  }
+  void setPendingReadWouldBeRejected() {
+    MOZ_ASSERT(!pendingReadWouldBeRejected());
+    setFlags(flags() | Flag_PendingReadWouldBeRejected);
+  }
+#endif
+
   void initFlags(bool preventClose, bool preventAbort, bool preventCancel) {
     MOZ_ASSERT(getFixedSlot(Slot_Flags).isUndefined());
 
diff --git a/js/src/builtin/streams/ReadableStream.cpp b/js/src/builtin/streams/ReadableStream.cpp
index 165a05336d..aebc87988f 100644
--- a/js/src/builtin/streams/ReadableStream.cpp
+++ b/js/src/builtin/streams/ReadableStream.cpp
@@ -32,10 +32,10 @@
 #include "vm/JSObject.h"          // js::GetPrototypeFromBuiltinConstructor
 #include "vm/ObjectOperations.h"  // js::GetProperty
 #include "vm/PlainObject.h"       // js::PlainObject
-#include "vm/Runtime.h"           // JSAtomState
+#include "vm/Runtime.h"           // JSAtomState, JSRuntime
 #include "vm/StringType.h"        // js::EqualStrings, js::ToString
 
-#include "vm/Compartment-inl.h"   // js::UnwrapAndTypeCheck{Argument,This}
+#include "vm/Compartment-inl.h"   // js::UnwrapAndTypeCheck{Argument,This,Value}
 #include "vm/JSObject-inl.h"      // js::NewBuiltinClassInstance
 #include "vm/NativeObject-inl.h"  // js::ThrowIfNotConstructing
 
@@ -56,6 +56,7 @@ using js::ReturnPromiseRejectedWithPendingError;
 using js::ToString;
 using js::UnwrapAndTypeCheckArgument;
 using js::UnwrapAndTypeCheckThis;
+using js::UnwrapAndTypeCheckValue;
 using js::WritableStream;
 
 using JS::CallArgs;
@@ -412,22 +413,18 @@ static bool ReadableStream_pipeTo(JSContext* cx, unsigned argc, Value* vp) {
   //         AbortSignal interface, return a promise rejected with a TypeError
   //         exception.
   Rooted signal(cx, nullptr);
-  do {
-    if (signalVal.isUndefined()) {
-      break;
+  if (!signalVal.isUndefined()) {
+    if (!UnwrapAndTypeCheckValue(
+            cx, signalVal, cx->runtime()->maybeAbortSignalClass(), [cx] {
+              JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                        JSMSG_READABLESTREAM_PIPETO_BAD_SIGNAL);
+            })) {
+      return ReturnPromiseRejectedWithPendingError(cx, args);
     }
 
-    if (signalVal.isObject()) {
-      // XXX jwalden need some JSAPI hooks to detect AbortSignal instances, or
-      //             something
-
-      signal = &signalVal.toObject();
-    }
-
-    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                              JSMSG_READABLESTREAM_PIPETO_BAD_SIGNAL);
-    return ReturnPromiseRejectedWithPendingError(cx, args);
-  } while (false);
+    // Note: |signal| can be a wrapper.
+    signal = &signalVal.toObject();
+  }
 
   // Step 5: If ! IsReadableStreamLocked(this) is true, return a promise
   //         rejected with a TypeError exception.
@@ -548,5 +545,6 @@ const JSClass ReadableStream::class_ = {
     JS_NULL_CLASS_OPS, &ReadableStream::classSpec_};
 
 const JSClass ReadableStream::protoClass_ = {
-    "object", JSCLASS_HAS_CACHED_PROTO(JSProto_ReadableStream),
-    JS_NULL_CLASS_OPS, &ReadableStream::classSpec_};
+    "ReadableStream.prototype",
+    JSCLASS_HAS_CACHED_PROTO(JSProto_ReadableStream), JS_NULL_CLASS_OPS,
+    &ReadableStream::classSpec_};
diff --git a/js/src/builtin/streams/ReadableStreamOperations.cpp b/js/src/builtin/streams/ReadableStreamOperations.cpp
index 8ec9e0a9b1..c1339c60a3 100644
--- a/js/src/builtin/streams/ReadableStreamOperations.cpp
+++ b/js/src/builtin/streams/ReadableStreamOperations.cpp
@@ -9,8 +9,6 @@
 #include "mozilla/Assertions.h"  // MOZ_ASSERT{,_IF}
 #include "mozilla/Attributes.h"  // MOZ_MUST_USE
 
-#include "jsapi.h"  // JS_SetPrivate
-
 #include "builtin/Array.h"                // js::NewDenseFullyAllocatedArray
 #include "builtin/Promise.h"              // js::RejectPromiseWithPendingError
 #include "builtin/streams/PipeToState.h"  // js::PipeToState
@@ -33,8 +31,9 @@
 #include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithValue
 #include "builtin/streams/ReadableStreamReader-inl.h"  // js::UnwrapReaderFromStream
 #include "vm/Compartment-inl.h"  // JS::Compartment::wrap, js::Unwrap{Callee,Internal}Slot
-#include "vm/JSObject-inl.h"  // js::IsCallable, js::NewObjectWithClassProto
-#include "vm/Realm-inl.h"     // js::AutoRealm
+#include "vm/JSContext-inl.h"  // JSContext::check
+#include "vm/JSObject-inl.h"   // js::IsCallable, js::NewObjectWithClassProto
+#include "vm/Realm-inl.h"      // js::AutoRealm
 
 using js::IsCallable;
 using js::NewHandler;
@@ -135,7 +134,7 @@ static MOZ_MUST_USE ReadableStream* CreateReadableStream(
     return nullptr;
   }
 
-  JS_SetPrivate(stream, nsISupportsObject_alreadyAddreffed);
+  stream->setPrivate(nsISupportsObject_alreadyAddreffed);
 
   // Step 1: Set stream.[[state]] to "readable".
   stream->initStateBits(Readable);
@@ -617,6 +616,8 @@ PromiseObject* js::ReadableStreamPipeTo(JSContext* cx,
                                         bool preventClose, bool preventAbort,
                                         bool preventCancel,
                                         Handle signal) {
+  cx->check(signal);
+
   // Step 1. Assert: ! IsReadableStream(source) is true.
   // Step 2. Assert: ! IsWritableStream(dest) is true.
   // Step 3. Assert: Type(preventClose) is Boolean, Type(preventAbort) is
diff --git a/js/src/builtin/streams/StreamAPI.cpp b/js/src/builtin/streams/StreamAPI.cpp
index 7c07cc076a..a9c726a694 100644
--- a/js/src/builtin/streams/StreamAPI.cpp
+++ b/js/src/builtin/streams/StreamAPI.cpp
@@ -9,9 +9,9 @@
 
 #include   // uint32_t, uintptr_t
 
-#include "jsapi.h"        // js::AssertHeapIsIdle, JS_ReportErrorNumberASCII
-#include "jsfriendapi.h"  // JS_GetArrayBufferViewData, js::IsObjectInContextCompartment, js::GetErrorMessage, JSMSG_*
-#include "jstypes.h"      // JS_{FRIEND,PUBLIC}_API
+#include "jsapi.h"  // js::AssertHeapIsIdle, JS_ReportErrorNumberASCII
+#include "jsfriendapi.h"  // js::GetErrorMessage, js::IsObjectInContextCompartment, JSMSG_*
+#include "jstypes.h"  // JS_{FRIEND,PUBLIC}_API
 
 #include "builtin/Stream.h"  // js::ReadableByteStreamController{,Close}, js::ReadableStreamDefaultController{,Close}, js::StreamController
 #include "builtin/streams/ReadableStream.h"  // js::ReadableStream
@@ -22,7 +22,9 @@
 #include "builtin/streams/ReadableStreamReader.h"  // js::ReadableStream{,Default}Reader, js::ForAuthorCodeBool
 #include "builtin/streams/StreamController.h"  // js::StreamController
 #include "gc/Zone.h"                           // JS::Zone
+#include "js/experimental/TypedData.h"  // JS_GetArrayBufferViewData, JS_NewUint8Array
 #include "js/GCAPI.h"       // JS::AutoCheckCannotGC, JS::AutoSuppressGCAnalysis
+#include "js/Object.h"      // JS::SetPrivate
 #include "js/RootingAPI.h"  // JS::{,Mutable}Handle, JS::Rooted
 #include "js/Stream.h"      // JS::ReadableStreamUnderlyingSource
 #include "js/Value.h"       // JS::{,Object,Undefined}Value
@@ -395,7 +397,7 @@ JS_PUBLIC_API bool JS::ReadableStreamUpdateDataAvailableFromSource(
 
 JS_PUBLIC_API void JS::ReadableStreamReleaseCCObject(JSObject* streamObj) {
   MOZ_ASSERT(JS::IsReadableStream(streamObj));
-  JS_SetPrivate(streamObj, nullptr);
+  JS::SetPrivate(streamObj, nullptr);
 }
 
 JS_PUBLIC_API bool JS::ReadableStreamTee(JSContext* cx,
@@ -600,3 +602,9 @@ JS_PUBLIC_API JSObject* JS::ReadableStreamDefaultReaderRead(
 
   return js::ReadableStreamDefaultReaderRead(cx, unwrappedReader);
 }
+
+void JS::InitAbortSignalHandling(const JSClass* clasp,
+                                 AbortSignalIsAborted isAborted,
+                                 JSContext* cx) {
+  cx->runtime()->initAbortSignalHandling(clasp, isAborted);
+}
diff --git a/js/src/builtin/streams/WritableStreamOperations.cpp b/js/src/builtin/streams/WritableStreamOperations.cpp
index 92defc11a1..ae44f2e02d 100644
--- a/js/src/builtin/streams/WritableStreamOperations.cpp
+++ b/js/src/builtin/streams/WritableStreamOperations.cpp
@@ -11,7 +11,7 @@
 
 #include   // uint32_t
 
-#include "jsapi.h"        // JS_ReportErrorASCII, JS_SetPrivate
+#include "jsapi.h"        // JS_ReportErrorASCII
 #include "jsfriendapi.h"  // js::GetErrorMessage, JSMSG_*
 
 #include "builtin/streams/MiscellaneousOperations.h"  // js::PromiseRejectedWithPendingError
@@ -76,7 +76,7 @@ WritableStream* WritableStream::create(
     return nullptr;
   }
 
-  JS_SetPrivate(stream, nsISupportsObject_alreadyAddreffed);
+  stream->setPrivate(nsISupportsObject_alreadyAddreffed);
 
   stream->initWritableState();
 
diff --git a/js/src/builtin/streams/WritableStreamWriterOperations.cpp b/js/src/builtin/streams/WritableStreamWriterOperations.cpp
index 120456e886..05b3be0fb1 100644
--- a/js/src/builtin/streams/WritableStreamWriterOperations.cpp
+++ b/js/src/builtin/streams/WritableStreamWriterOperations.cpp
@@ -19,11 +19,11 @@
 #include "builtin/streams/WritableStreamDefaultWriter.h"  // js::WritableStreamDefaultWriter
 #include "builtin/streams/WritableStreamOperations.h"  // js::WritableStream{Abort,CloseQueuedOrInFlight}
 #include "js/Promise.h"                                // JS::PromiseState
-#include "js/Value.h"          // JS::Value, JS::{Int32,Null}Value
-#include "vm/Compartment.h"    // JS::Compartment
-#include "vm/Interpreter.h"    // js::GetAndClearException
-#include "vm/JSContext.h"      // JSContext
-#include "vm/PromiseObject.h"  // js::PromiseObject
+#include "js/Value.h"        // JS::Value, JS::{Int32,Null}Value
+#include "vm/Compartment.h"  // JS::Compartment
+#include "vm/Interpreter.h"  // js::GetAndClearException
+#include "vm/JSContext.h"    // JSContext
+#include "vm/PromiseObject.h"  // js::PromiseObject, js::PromiseResolvedWithUndefined
 
 #include "builtin/Promise-inl.h"  // js::SetSettledPromiseIsHandled
 #include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined
@@ -74,7 +74,7 @@ JSObject* js::WritableStreamDefaultWriterAbort(
  * Streams spec, 4.6.3.
  * WritableStreamDefaultWriterClose ( writer )
  */
-JSObject* js::WritableStreamDefaultWriterClose(
+PromiseObject* js::WritableStreamDefaultWriterClose(
     JSContext* cx, Handle unwrappedWriter) {
   // Step 1: Let stream be writer.[[ownerWritableStream]].
   // Step 2: Assert: stream is not undefined.
@@ -139,6 +139,45 @@ JSObject* js::WritableStreamDefaultWriterClose(
   return promise;
 }
 
+/**
+ * Streams spec.
+ * WritableStreamDefaultWriterCloseWithErrorPropagation ( writer )
+ */
+PromiseObject* js::WritableStreamDefaultWriterCloseWithErrorPropagation(
+    JSContext* cx, Handle unwrappedWriter) {
+  // Step 1: Let stream be writer.[[ownerWritableStream]].
+  // Step 2: Assert: stream is not undefined.
+  WritableStream* unwrappedStream = UnwrapStreamFromWriter(cx, unwrappedWriter);
+  if (!unwrappedStream) {
+    return nullptr;
+  }
+
+  // Step 3: Let state be stream.[[state]].
+  // Step 4: If ! WritableStreamCloseQueuedOrInFlight(stream) is true or state
+  //         is "closed", return a promise resolved with undefined.
+  if (WritableStreamCloseQueuedOrInFlight(unwrappedStream) ||
+      unwrappedStream->closed()) {
+    return PromiseResolvedWithUndefined(cx);
+  }
+
+  // Step 5: If state is "errored", return a promise rejected with
+  //         stream.[[storedError]].
+  if (unwrappedStream->errored()) {
+    Rooted storedError(cx, unwrappedStream->storedError());
+    if (!cx->compartment()->wrap(cx, &storedError)) {
+      return nullptr;
+    }
+
+    return PromiseObject::unforgeableReject(cx, storedError);
+  }
+
+  // Step 6: Assert: state is "writable" or "erroring".
+  MOZ_ASSERT(unwrappedStream->writable() ^ unwrappedStream->erroring());
+
+  // Step 7: Return ! WritableStreamDefaultWriterClose(writer).
+  return WritableStreamDefaultWriterClose(cx, unwrappedWriter);
+}
+
 using GetField = JSObject* (WritableStreamDefaultWriter::*)() const;
 using SetField = void (WritableStreamDefaultWriter::*)(JSObject*);
 
diff --git a/js/src/builtin/streams/WritableStreamWriterOperations.h b/js/src/builtin/streams/WritableStreamWriterOperations.h
index 61e7742895..808e293447 100644
--- a/js/src/builtin/streams/WritableStreamWriterOperations.h
+++ b/js/src/builtin/streams/WritableStreamWriterOperations.h
@@ -24,7 +24,10 @@ extern JSObject* WritableStreamDefaultWriterAbort(
     JSContext* cx, JS::Handle unwrappedWriter,
     JS::Handle reason);
 
-extern JSObject* WritableStreamDefaultWriterClose(
+extern PromiseObject* WritableStreamDefaultWriterClose(
+    JSContext* cx, JS::Handle unwrappedWriter);
+
+extern PromiseObject* WritableStreamDefaultWriterCloseWithErrorPropagation(
     JSContext* cx, JS::Handle unwrappedWriter);
 
 extern MOZ_MUST_USE bool WritableStreamDefaultWriterEnsureClosedPromiseRejected(
diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp
index 41be8946c3..b4875ab2d9 100644
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -40,6 +40,8 @@
 #include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
 #include "js/ArrayBuffer.h"  // JS::{IsArrayBufferObject,GetArrayBufferData,GetArrayBuffer{ByteLength,Data}}
 #include "js/CharacterEncoding.h"
+#include "js/experimental/TypedData.h"  // JS_GetArrayBufferView{Type,Data}, JS_GetTypedArrayByteLength, JS_IsArrayBufferViewObject, JS_IsTypedArrayObject
+#include "js/Object.h"  // JS::GetPrivate, JS::GetReservedSlot, JS::SetPrivate
 #include "js/PropertySpec.h"
 #include "js/SharedArrayBuffer.h"  // JS::{GetSharedArrayBuffer{ByteLength,Data},IsSharedArrayBufferObject}
 #include "js/StableStringChars.h"
@@ -51,6 +53,7 @@
 #include "util/Windows.h"
 #include "vm/JSContext.h"
 #include "vm/JSFunction.h"
+#include "vm/JSObject.h"
 
 #include "vm/JSObject-inl.h"
 
@@ -264,6 +267,7 @@ bool ValueSetter(JSContext* cx, const JS::CallArgs& args);
 static bool Address(JSContext* cx, unsigned argc, Value* vp);
 static bool ReadString(JSContext* cx, unsigned argc, Value* vp);
 static bool ReadStringReplaceMalformed(JSContext* cx, unsigned argc, Value* vp);
+static bool ReadTypedArray(JSContext* cx, unsigned argc, Value* vp);
 static bool ToSource(JSContext* cx, unsigned argc, Value* vp);
 static JSString* GetSourceString(JSContext* cx, HandleObject typeObj,
                                  void* data);
@@ -337,6 +341,7 @@ namespace Methods {
 static bool Dispose(JSContext* cx, unsigned argc, Value* vp);
 static bool Forget(JSContext* cx, unsigned argc, Value* vp);
 static bool ReadString(JSContext* cx, unsigned argc, Value* vp);
+static bool ReadTypedArray(JSContext* cx, unsigned argc, Value* vp);
 static bool ToSource(JSContext* cx, unsigned argc, Value* vp);
 static bool ToString(JSContext* cx, unsigned argc, Value* vp);
 }  // namespace Methods
@@ -591,6 +596,7 @@ static const JSFunctionSpec sCDataFunctions[] = {
     JS_FN("readString", CData::ReadString, 0, CDATAFN_FLAGS),
     JS_FN("readStringReplaceMalformed", CData::ReadStringReplaceMalformed, 0,
           CDATAFN_FLAGS),
+    JS_FN("readTypedArray", CData::ReadTypedArray, 0, CDATAFN_FLAGS),
     JS_FN("toSource", CData::ToSource, 0, CDATAFN_FLAGS),
     JS_FN("toString", CData::ToSource, 0, CDATAFN_FLAGS),
     JS_FS_END};
@@ -601,6 +607,8 @@ static const JSFunctionSpec sCDataFinalizerFunctions[] = {
     JS_FN("forget", CDataFinalizer::Methods::Forget, 0, CDATAFINALIZERFN_FLAGS),
     JS_FN("readString", CDataFinalizer::Methods::ReadString, 0,
           CDATAFINALIZERFN_FLAGS),
+    JS_FN("readTypedArray", CDataFinalizer::Methods::ReadTypedArray, 0,
+          CDATAFINALIZERFN_FLAGS),
     JS_FN("toString", CDataFinalizer::Methods::ToString, 0,
           CDATAFINALIZERFN_FLAGS),
     JS_FN("toSource", CDataFinalizer::Methods::ToSource, 0,
@@ -837,11 +845,11 @@ static MOZ_ALWAYS_INLINE size_t Align(size_t val, size_t align) {
 static ABICode GetABICode(JSObject* obj) {
   // make sure we have an object representing a CABI class,
   // and extract the enumerated class type from the reserved slot.
-  if (JS_GetClass(obj) != &sCABIClass) {
+  if (!obj->hasClass(&sCABIClass)) {
     return INVALID_ABI;
   }
 
-  Value result = JS_GetReservedSlot(obj, SLOT_ABICODE);
+  Value result = JS::GetReservedSlot(obj, SLOT_ABICODE);
   return ABICode(result.toInt32());
 }
 
@@ -972,9 +980,9 @@ static void BuildFunctionTypeSource(JSContext* cx, HandleObject funObj,
   MOZ_ASSERT(CData::IsCData(funObj) || CType::IsCType(funObj));
 
   if (CData::IsCData(funObj)) {
-    Value slot = JS_GetReservedSlot(funObj, SLOT_REFERENT);
+    Value slot = JS::GetReservedSlot(funObj, SLOT_REFERENT);
     if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) {
-      slot = JS_GetReservedSlot(funObj, SLOT_FUNNAME);
+      slot = JS::GetReservedSlot(funObj, SLOT_FUNNAME);
       MOZ_ASSERT(!slot.isUndefined());
       RootedObject typeObj(cx, CData::GetCType(funObj));
       RootedObject baseTypeObj(cx, PointerType::GetBaseType(typeObj));
@@ -1506,7 +1514,7 @@ static bool FunctionArgumentLengthMismatch(
     JSContext* cx, unsigned expectedCount, unsigned actualCount,
     HandleObject funObj, HandleObject typeObj, bool isVariadic) {
   JS::UniqueChars funStr;
-  Value slot = JS_GetReservedSlot(funObj, SLOT_REFERENT);
+  Value slot = JS::GetReservedSlot(funObj, SLOT_REFERENT);
   if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) {
     funStr = FunctionTypeSourceForError(cx, funObj);
   } else {
@@ -1677,6 +1685,18 @@ static bool NonStringBaseError(JSContext* cx, HandleValue thisVal) {
   return false;
 }
 
+static bool NonTypedArrayBaseError(JSContext* cx, HandleValue thisVal) {
+  JS::UniqueChars valBytes;
+  const char* valStr = CTypesToSourceForError(cx, thisVal, valBytes);
+  if (!valStr) {
+    return false;
+  }
+
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NON_TYPEDARRAY_BASE, valStr);
+  return false;
+}
+
 static bool NullPointerError(JSContext* cx, const char* action,
                              HandleObject obj) {
   MOZ_ASSERT(JS::StringIsASCII(action));
@@ -1834,6 +1854,19 @@ MOZ_MUST_USE JSObject* GetThisObject(JSContext* cx, const CallArgs& args,
   return &args.thisv().toObject();
 }
 
+static bool DefineToStringTag(JSContext* cx, HandleObject obj,
+                              const char* toStringTag) {
+  RootedString toStringTagStr(cx, JS_NewStringCopyZ(cx, toStringTag));
+  if (!toStringTagStr) {
+    return false;
+  }
+
+  RootedId toStringTagId(cx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(
+                                 cx, JS::SymbolCode::toStringTag)));
+  return JS_DefinePropertyById(cx, obj, toStringTagId, toStringTagStr,
+                               JSPROP_READONLY);
+}
+
 static JSObject* InitCTypeClass(JSContext* cx, HandleObject ctypesObj) {
   JSFunction* fun = JS_DefineFunction(cx, ctypesObj, "CType", ConstructAbstract,
                                       0, CTYPESCTOR_FLAGS);
@@ -1869,6 +1902,10 @@ static JSObject* InitCTypeClass(JSContext* cx, HandleObject ctypesObj) {
       !JS_DefineFunctions(cx, prototype, sCTypeFunctions))
     return nullptr;
 
+  if (!DefineToStringTag(cx, prototype, "CType")) {
+    return nullptr;
+  }
+
   if (!JS_FreezeObject(cx, ctor) || !JS_FreezeObject(cx, prototype)) {
     return nullptr;
   }
@@ -1887,6 +1924,10 @@ static JSObject* InitABIClass(JSContext* cx) {
     return nullptr;
   }
 
+  if (!DefineToStringTag(cx, obj, "CABI")) {
+    return nullptr;
+  }
+
   return obj;
 }
 
@@ -1927,6 +1968,10 @@ static JSObject* InitCDataClass(JSContext* cx, HandleObject parent,
       !JS_DefineFunctions(cx, prototype, sCDataFunctions))
     return nullptr;
 
+  if (!DefineToStringTag(cx, prototype, "CData")) {
+    return nullptr;
+  }
+
   if (  // !JS_FreezeObject(cx, prototype) || // XXX fixme - see bug 541212!
       !JS_FreezeObject(cx, ctor))
     return nullptr;
@@ -2041,6 +2086,17 @@ static JSObject* InitInt64Class(JSContext* cx, HandleObject parent,
     return nullptr;
   }
 
+  if (clasp == &sInt64ProtoClass) {
+    if (!DefineToStringTag(cx, prototype, "Int64")) {
+      return nullptr;
+    }
+  } else {
+    MOZ_ASSERT(clasp == &sUInt64ProtoClass);
+    if (!DefineToStringTag(cx, prototype, "UInt64")) {
+      return nullptr;
+    }
+  }
+
   RootedObject ctor(cx, JS_GetConstructor(cx, prototype));
   if (!ctor) {
     return nullptr;
@@ -2048,7 +2104,6 @@ static JSObject* InitInt64Class(JSContext* cx, HandleObject parent,
 
   // Define the 'join' function as an extended native and stash
   // ctypes.{Int64,UInt64}.prototype in a reserved slot of the new function.
-  MOZ_ASSERT(clasp == &sInt64ProtoClass || clasp == &sUInt64ProtoClass);
   JSNative native = (clasp == &sInt64ProtoClass) ? Int64::Join : UInt64::Join;
   JSFunction* fun = js::DefineFunctionWithReserved(cx, ctor, "join", native, 2,
                                                    CTYPESFN_FLAGS);
@@ -2277,7 +2332,7 @@ static bool InitTypeClasses(JSContext* cx, HandleObject ctypesObj) {
 }
 
 bool IsCTypesGlobal(JSObject* obj) {
-  return JS_GetClass(obj) == &sCTypesGlobalClass;
+  return obj->hasClass(&sCTypesGlobalClass);
 }
 
 bool IsCTypesGlobal(HandleValue v) {
@@ -2288,7 +2343,7 @@ bool IsCTypesGlobal(HandleValue v) {
 const JSCTypesCallbacks* GetCallbacks(JSObject* obj) {
   MOZ_ASSERT(IsCTypesGlobal(obj));
 
-  Value result = JS_GetReservedSlot(obj, SLOT_CALLBACKS);
+  Value result = JS::GetReservedSlot(obj, SLOT_CALLBACKS);
   if (result.isUndefined()) {
     return nullptr;
   }
@@ -2342,6 +2397,10 @@ JS_PUBLIC_API bool JS_InitCTypesClass(JSContext* cx, HandleObject global) {
       !JS_DefineProperties(cx, ctypes, sModuleProps))
     return false;
 
+  if (!DefineToStringTag(cx, ctypes, "ctypes")) {
+    return false;
+  }
+
   // Set up ctypes.CDataFinalizer.prototype.
   RootedObject ctor(cx);
   if (!GetObjectProperty(cx, ctypes, "CDataFinalizer", &ctor)) {
@@ -2357,6 +2416,10 @@ JS_PUBLIC_API bool JS_InitCTypesClass(JSContext* cx, HandleObject global) {
     return false;
   }
 
+  if (!DefineToStringTag(cx, prototype, "CDataFinalizer")) {
+    return false;
+  }
+
   if (!JS_DefineProperty(cx, ctor, "prototype", prototype,
                          JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
     return false;
@@ -2388,10 +2451,10 @@ JS_FRIEND_API size_t SizeOfDataIfCDataObject(mozilla::MallocSizeOf mallocSizeOf,
   }
 
   size_t n = 0;
-  Value slot = JS_GetReservedSlot(obj, ctypes::SLOT_OWNS);
+  Value slot = JS::GetReservedSlot(obj, ctypes::SLOT_OWNS);
   if (!slot.isUndefined()) {
     bool owns = slot.toBoolean();
-    slot = JS_GetReservedSlot(obj, ctypes::SLOT_DATA);
+    slot = JS::GetReservedSlot(obj, ctypes::SLOT_DATA);
     if (!slot.isUndefined()) {
       char** buffer = static_cast(slot.toPrivate());
       n += mallocSizeOf(buffer);
@@ -3234,8 +3297,7 @@ static bool ImplicitConvert(JSContext* cx, HandleValue val,
       sourceData = valObj;
       sourceType = CDataFinalizer::GetCType(cx, sourceData);
 
-      CDataFinalizer::Private* p =
-          (CDataFinalizer::Private*)JS_GetPrivate(sourceData);
+      auto* p = (CDataFinalizer::Private*)JS::GetPrivate(sourceData);
 
       if (!p) {
         // We have called |dispose| or |forget| already.
@@ -4382,7 +4444,7 @@ static void FinalizeFFIType(JSFreeOp* fop, JSObject* obj, const Value& slot,
 
 void CType::Finalize(JSFreeOp* fop, JSObject* obj) {
   // Make sure our TypeCode slot is legit. If it's not, bail.
-  Value slot = JS_GetReservedSlot(obj, SLOT_TYPECODE);
+  Value slot = JS::GetReservedSlot(obj, SLOT_TYPECODE);
   if (slot.isUndefined()) {
     return;
   }
@@ -4391,7 +4453,7 @@ void CType::Finalize(JSFreeOp* fop, JSObject* obj) {
   switch (TypeCode(slot.toInt32())) {
     case TYPE_function: {
       // Free the FunctionInfo.
-      slot = JS_GetReservedSlot(obj, SLOT_FNINFO);
+      slot = JS::GetReservedSlot(obj, SLOT_FNINFO);
       if (!slot.isUndefined()) {
         auto fninfo = static_cast(slot.toPrivate());
         fop->delete_(obj, fninfo, MemoryUse::CTypeFunctionInfo);
@@ -4403,7 +4465,7 @@ void CType::Finalize(JSFreeOp* fop, JSObject* obj) {
       size_t fieldCount = 0;
 
       // Free the FieldInfoHash table.
-      slot = JS_GetReservedSlot(obj, SLOT_FIELDINFO);
+      slot = JS::GetReservedSlot(obj, SLOT_FIELDINFO);
       if (!slot.isUndefined()) {
         auto info = static_cast(slot.toPrivate());
         fieldCount = info->count();
@@ -4411,7 +4473,7 @@ void CType::Finalize(JSFreeOp* fop, JSObject* obj) {
       }
 
       // Free the ffi_type info.
-      Value slot = JS_GetReservedSlot(obj, SLOT_FFITYPE);
+      Value slot = JS::GetReservedSlot(obj, SLOT_FFITYPE);
       if (!slot.isUndefined()) {
         size_t elementCount = fieldCount != 0 ? fieldCount + 1 : 2;
         FinalizeFFIType(fop, obj, slot, elementCount);
@@ -4423,7 +4485,7 @@ void CType::Finalize(JSFreeOp* fop, JSObject* obj) {
 
     case TYPE_array: {
       // Free the ffi_type info.
-      Value slot = JS_GetReservedSlot(obj, SLOT_FFITYPE);
+      Value slot = JS::GetReservedSlot(obj, SLOT_FFITYPE);
       if (!slot.isUndefined()) {
         size_t elementCount = ArrayType::GetLength(obj);
         FinalizeFFIType(fop, obj, slot, elementCount);
@@ -4479,16 +4541,16 @@ void CType::Trace(JSTracer* trc, JSObject* obj) {
   }
 }
 
-bool CType::IsCType(JSObject* obj) { return JS_GetClass(obj) == &sCTypeClass; }
+bool CType::IsCType(JSObject* obj) { return obj->hasClass(&sCTypeClass); }
 
 bool CType::IsCTypeProto(JSObject* obj) {
-  return JS_GetClass(obj) == &sCTypeProtoClass;
+  return obj->hasClass(&sCTypeProtoClass);
 }
 
 TypeCode CType::GetTypeCode(JSObject* typeObj) {
   MOZ_ASSERT(IsCType(typeObj));
 
-  Value result = JS_GetReservedSlot(typeObj, SLOT_TYPECODE);
+  Value result = JS::GetReservedSlot(typeObj, SLOT_TYPECODE);
   return TypeCode(result.toInt32());
 }
 
@@ -4570,7 +4632,7 @@ bool CType::TypesEqual(JSObject* t1, JSObject* t2) {
 bool CType::GetSafeSize(JSObject* obj, size_t* result) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value size = JS_GetReservedSlot(obj, SLOT_SIZE);
+  Value size = JS::GetReservedSlot(obj, SLOT_SIZE);
 
   // The "size" property can be an int, a double, or JS::UndefinedValue()
   // (for arrays of undefined length), and must always fit in a size_t.
@@ -4590,7 +4652,7 @@ bool CType::GetSafeSize(JSObject* obj, size_t* result) {
 size_t CType::GetSize(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value size = JS_GetReservedSlot(obj, SLOT_SIZE);
+  Value size = JS::GetReservedSlot(obj, SLOT_SIZE);
 
   MOZ_ASSERT(!size.isUndefined());
 
@@ -4607,7 +4669,7 @@ size_t CType::GetSize(JSObject* obj) {
 bool CType::IsSizeDefined(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value size = JS_GetReservedSlot(obj, SLOT_SIZE);
+  Value size = JS::GetReservedSlot(obj, SLOT_SIZE);
 
   // The "size" property can be an int, a double, or JS::UndefinedValue()
   // (for arrays of undefined length), and must always fit in a size_t.
@@ -4618,14 +4680,14 @@ bool CType::IsSizeDefined(JSObject* obj) {
 size_t CType::GetAlignment(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_ALIGN);
+  Value slot = JS::GetReservedSlot(obj, SLOT_ALIGN);
   return static_cast(slot.toInt32());
 }
 
 ffi_type* CType::GetFFIType(JSContext* cx, JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_FFITYPE);
+  Value slot = JS::GetReservedSlot(obj, SLOT_FFITYPE);
 
   if (!slot.isUndefined()) {
     return static_cast(slot.toPrivate());
@@ -4656,7 +4718,7 @@ ffi_type* CType::GetFFIType(JSContext* cx, JSObject* obj) {
 JSString* CType::GetName(JSContext* cx, HandleObject obj) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value string = JS_GetReservedSlot(obj, SLOT_NAME);
+  Value string = JS::GetReservedSlot(obj, SLOT_NAME);
   if (!string.isUndefined()) {
     return string.toString();
   }
@@ -4679,7 +4741,7 @@ JSObject* CType::GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot) {
   MOZ_ASSERT(CType::IsCTypeProto(proto));
 
   // Get the desired prototype.
-  Value result = JS_GetReservedSlot(proto, slot);
+  Value result = JS::GetReservedSlot(proto, slot);
   return &result.toObject();
 }
 
@@ -4697,7 +4759,7 @@ JSObject* CType::GetProtoFromType(JSContext* cx, JSObject* objArg,
   MOZ_ASSERT(CType::IsCTypeProto(proto));
 
   // Get the requested ctypes.{Pointer,Array,Struct,Function}Type.prototype.
-  Value result = JS_GetReservedSlot(proto, slot);
+  Value result = JS::GetReservedSlot(proto, slot);
   MOZ_ASSERT(result.isObject());
   return &result.toObject();
 }
@@ -4714,7 +4776,7 @@ bool CType::PrototypeGetter(JSContext* cx, const JS::CallArgs& args) {
   RootedObject obj(cx, &args.thisv().toObject());
   unsigned slot = CType::IsCTypeProto(obj) ? (unsigned)SLOT_OURDATAPROTO
                                            : (unsigned)SLOT_PROTO;
-  args.rval().set(JS_GetReservedSlot(obj, slot));
+  args.rval().set(JS::GetReservedSlot(obj, slot));
   MOZ_ASSERT(args.rval().isObject() || args.rval().isUndefined());
   return true;
 }
@@ -4736,7 +4798,7 @@ bool CType::NameGetter(JSContext* cx, const JS::CallArgs& args) {
 
 bool CType::SizeGetter(JSContext* cx, const JS::CallArgs& args) {
   RootedObject obj(cx, &args.thisv().toObject());
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_SIZE));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_SIZE));
   MOZ_ASSERT(args.rval().isNumber() || args.rval().isUndefined());
   return true;
 }
@@ -4853,7 +4915,7 @@ bool CType::HasInstance(JSContext* cx, HandleObject obj, MutableHandleValue v,
                         bool* bp) {
   MOZ_ASSERT(CType::IsCType(obj));
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_PROTO);
+  Value slot = JS::GetReservedSlot(obj, SLOT_PROTO);
   JS::Rooted prototype(cx, &slot.toObject());
   MOZ_ASSERT(prototype);
   MOZ_ASSERT(CData::IsCDataProto(prototype));
@@ -4890,7 +4952,7 @@ static JSObject* CType::GetGlobalCTypes(JSContext* cx, JSObject* objArg) {
   MOZ_ASSERT(objTypeProto);
   MOZ_ASSERT(CType::IsCTypeProto(objTypeProto));
 
-  Value valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES);
+  Value valCTypes = JS::GetReservedSlot(objTypeProto, SLOT_CTYPES);
   MOZ_ASSERT(valCTypes.isObject());
   return &valCTypes.toObject();
 }
@@ -4899,7 +4961,7 @@ static JSObject* CType::GetGlobalCTypes(JSContext* cx, JSObject* objArg) {
 ** ABI implementation
 *******************************************************************************/
 
-bool ABI::IsABI(JSObject* obj) { return JS_GetClass(obj) == &sCABIClass; }
+bool ABI::IsABI(JSObject* obj) { return obj->hasClass(&sCABIClass); }
 
 bool ABI::ToSource(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
@@ -4970,7 +5032,7 @@ bool PointerType::Create(JSContext* cx, unsigned argc, Value* vp) {
 
 JSObject* PointerType::CreateInternal(JSContext* cx, HandleObject baseType) {
   // check if we have a cached PointerType on our base CType.
-  Value slot = JS_GetReservedSlot(baseType, SLOT_PTR);
+  Value slot = JS::GetReservedSlot(baseType, SLOT_PTR);
   if (!slot.isUndefined()) {
     return &slot.toObject();
   }
@@ -5094,7 +5156,7 @@ bool PointerType::ConstructData(JSContext* cx, HandleObject obj,
 JSObject* PointerType::GetBaseType(JSObject* obj) {
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_pointer);
 
-  Value type = JS_GetReservedSlot(obj, SLOT_TARGET_T);
+  Value type = JS::GetReservedSlot(obj, SLOT_TARGET_T);
   MOZ_ASSERT(!type.isNull());
   return &type.toObject();
 }
@@ -5118,7 +5180,7 @@ bool PointerType::IsPointer(HandleValue v) {
 
 bool PointerType::TargetTypeGetter(JSContext* cx, const JS::CallArgs& args) {
   RootedObject obj(cx, &args.thisv().toObject());
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_TARGET_T));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_TARGET_T));
   MOZ_ASSERT(args.rval().isObject());
   return true;
 }
@@ -5432,7 +5494,7 @@ JSObject* ArrayType::GetBaseType(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array);
 
-  Value type = JS_GetReservedSlot(obj, SLOT_ELEMENT_T);
+  Value type = JS::GetReservedSlot(obj, SLOT_ELEMENT_T);
   MOZ_ASSERT(!type.isNull());
   return &type.toObject();
 }
@@ -5441,7 +5503,7 @@ bool ArrayType::GetSafeLength(JSObject* obj, size_t* result) {
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array);
 
-  Value length = JS_GetReservedSlot(obj, SLOT_LENGTH);
+  Value length = JS::GetReservedSlot(obj, SLOT_LENGTH);
 
   // The "length" property can be an int, a double, or JS::UndefinedValue()
   // (for arrays of undefined length), and must always fit in a size_t.
@@ -5462,7 +5524,7 @@ size_t ArrayType::GetLength(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_array);
 
-  Value length = JS_GetReservedSlot(obj, SLOT_LENGTH);
+  Value length = JS::GetReservedSlot(obj, SLOT_LENGTH);
 
   MOZ_ASSERT(!length.isUndefined());
 
@@ -5541,7 +5603,7 @@ bool ArrayType::IsArrayOrArrayType(HandleValue v) {
 
 bool ArrayType::ElementTypeGetter(JSContext* cx, const JS::CallArgs& args) {
   RootedObject obj(cx, &args.thisv().toObject());
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_ELEMENT_T));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_ELEMENT_T));
   MOZ_ASSERT(args.rval().isObject());
   return true;
 }
@@ -5555,7 +5617,7 @@ bool ArrayType::LengthGetter(JSContext* cx, const JS::CallArgs& args) {
     obj = CData::GetCType(obj);
   }
 
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_LENGTH));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_LENGTH));
   MOZ_ASSERT(args.rval().isNumber() || args.rval().isUndefined());
   return true;
 }
@@ -6204,7 +6266,7 @@ const FieldInfoHash* StructType::GetFieldInfo(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_struct);
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_FIELDINFO);
+  Value slot = JS::GetReservedSlot(obj, SLOT_FIELDINFO);
   MOZ_ASSERT(!slot.isUndefined() && slot.toPrivate());
 
   return static_cast(slot.toPrivate());
@@ -6271,7 +6333,7 @@ bool StructType::IsStruct(HandleValue v) {
 bool StructType::FieldsArrayGetter(JSContext* cx, const JS::CallArgs& args) {
   RootedObject obj(cx, &args.thisv().toObject());
 
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_FIELDS));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_FIELDS));
 
   if (!CType::IsSizeDefined(obj)) {
     MOZ_ASSERT(args.rval().isUndefined());
@@ -6602,9 +6664,15 @@ static bool PrepareCIF(JSContext* cx, FunctionInfo* fninfo) {
     return false;
   }
 
-  ffi_status status =
-      ffi_prep_cif(&fninfo->mCIF, abi, fninfo->mFFITypes.length(), rtype,
-                   fninfo->mFFITypes.begin());
+  ffi_status status;
+  if (fninfo->mIsVariadic) {
+    status = ffi_prep_cif_var(&fninfo->mCIF, abi, fninfo->mArgTypes.length(),
+                              fninfo->mFFITypes.length(), rtype,
+                              fninfo->mFFITypes.begin());
+  } else {
+    status = ffi_prep_cif(&fninfo->mCIF, abi, fninfo->mFFITypes.length(), rtype,
+                          fninfo->mFFITypes.begin());
+  }
 
   switch (status) {
     case FFI_OK:
@@ -6939,7 +7007,7 @@ bool FunctionType::Call(JSContext* cx, unsigned argc, Value* vp) {
   }
 
   // Check if we have a Library object. If we do, make sure it's open.
-  Value slot = JS_GetReservedSlot(obj, SLOT_REFERENT);
+  Value slot = JS::GetReservedSlot(obj, SLOT_REFERENT);
   if (!slot.isUndefined() && Library::IsLibrary(&slot.toObject())) {
     PRLibrary* library = Library::GetLibrary(&slot.toObject());
     if (!library) {
@@ -7090,7 +7158,7 @@ FunctionInfo* FunctionType::GetFunctionInfo(JSObject* obj) {
   MOZ_ASSERT(CType::IsCType(obj));
   MOZ_ASSERT(CType::GetTypeCode(obj) == TYPE_function);
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_FNINFO);
+  Value slot = JS::GetReservedSlot(obj, SLOT_FNINFO);
   MOZ_ASSERT(!slot.isUndefined() && slot.toPrivate());
 
   return static_cast(slot.toPrivate());
@@ -7107,7 +7175,7 @@ bool FunctionType::IsFunctionType(HandleValue v) {
 bool FunctionType::ArgTypesGetter(JSContext* cx, const JS::CallArgs& args) {
   JS::Rooted obj(cx, &args.thisv().toObject());
 
-  args.rval().set(JS_GetReservedSlot(obj, SLOT_ARGS_T));
+  args.rval().set(JS::GetReservedSlot(obj, SLOT_ARGS_T));
   if (!args.rval().isUndefined()) {
     return true;
   }
@@ -7260,7 +7328,7 @@ JSObject* CClosure::Create(JSContext* cx, HandleObject typeObj,
 
 void CClosure::Trace(JSTracer* trc, JSObject* obj) {
   // Make sure our ClosureInfo slot is legit. If it's not, bail.
-  Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO);
+  Value slot = JS::GetReservedSlot(obj, SLOT_CLOSUREINFO);
   if (slot.isUndefined()) {
     return;
   }
@@ -7275,7 +7343,7 @@ void CClosure::Trace(JSTracer* trc, JSObject* obj) {
 
 void CClosure::Finalize(JSFreeOp* fop, JSObject* obj) {
   // Make sure our ClosureInfo slot is legit. If it's not, bail.
-  Value slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO);
+  Value slot = JS::GetReservedSlot(obj, SLOT_CLOSUREINFO);
   if (slot.isUndefined()) {
     return;
   }
@@ -7461,7 +7529,7 @@ JSObject* CData::Create(JSContext* cx, HandleObject typeObj,
   MOZ_ASSERT_IF(refObj && CData::IsCData(refObj), !ownResult);
 
   // Get the 'prototype' property from the type.
-  Value slot = JS_GetReservedSlot(typeObj, SLOT_PROTO);
+  Value slot = JS::GetReservedSlot(typeObj, SLOT_PROTO);
   MOZ_ASSERT(slot.isObject());
 
   RootedObject proto(cx, &slot.toObject());
@@ -7529,21 +7597,21 @@ JSObject* CData::Create(JSContext* cx, HandleObject typeObj,
 
 void CData::Finalize(JSFreeOp* fop, JSObject* obj) {
   // Delete our buffer, and the data it contains if we own it.
-  Value slot = JS_GetReservedSlot(obj, SLOT_OWNS);
+  Value slot = JS::GetReservedSlot(obj, SLOT_OWNS);
   if (slot.isUndefined()) {
     return;
   }
 
   bool owns = slot.toBoolean();
 
-  slot = JS_GetReservedSlot(obj, SLOT_DATA);
+  slot = JS::GetReservedSlot(obj, SLOT_DATA);
   if (slot.isUndefined()) {
     return;
   }
   char** buffer = static_cast(slot.toPrivate());
 
   if (owns) {
-    JSObject* typeObj = &JS_GetReservedSlot(obj, SLOT_CTYPE).toObject();
+    JSObject* typeObj = &JS::GetReservedSlot(obj, SLOT_CTYPE).toObject();
     size_t size = CType::GetSize(typeObj);
     fop->free_(obj, *buffer, size, MemoryUse::CDataBuffer);
   }
@@ -7554,7 +7622,7 @@ JSObject* CData::GetCType(JSObject* dataObj) {
   dataObj = MaybeUnwrapArrayWrapper(dataObj);
   MOZ_ASSERT(CData::IsCData(dataObj));
 
-  Value slot = JS_GetReservedSlot(dataObj, SLOT_CTYPE);
+  Value slot = JS::GetReservedSlot(dataObj, SLOT_CTYPE);
   JSObject* typeObj = slot.toObjectOrNull();
   MOZ_ASSERT(CType::IsCType(typeObj));
   return typeObj;
@@ -7564,7 +7632,7 @@ void* CData::GetData(JSObject* dataObj) {
   dataObj = MaybeUnwrapArrayWrapper(dataObj);
   MOZ_ASSERT(CData::IsCData(dataObj));
 
-  Value slot = JS_GetReservedSlot(dataObj, SLOT_DATA);
+  Value slot = JS::GetReservedSlot(dataObj, SLOT_DATA);
 
   void** buffer = static_cast(slot.toPrivate());
   MOZ_ASSERT(buffer);
@@ -7576,7 +7644,7 @@ bool CData::IsCData(JSObject* obj) {
   // Assert we don't have an array wrapper.
   MOZ_ASSERT(MaybeUnwrapArrayWrapper(obj) == obj);
 
-  return JS_GetClass(obj) == &sCDataClass;
+  return obj->hasClass(&sCDataClass);
 }
 
 bool CData::IsCDataMaybeUnwrap(MutableHandleObject obj) {
@@ -7589,7 +7657,7 @@ bool CData::IsCData(HandleValue v) {
 }
 
 bool CData::IsCDataProto(JSObject* obj) {
-  return JS_GetClass(obj) == &sCDataProtoClass;
+  return obj->hasClass(&sCDataProtoClass);
 }
 
 bool CData::ValueGetter(JSContext* cx, const JS::CallArgs& args) {
@@ -7712,27 +7780,20 @@ bool CData::GetRuntime(JSContext* cx, unsigned argc, Value* vp) {
   return true;
 }
 
-using InflateUTF8Method = JS::TwoByteCharsZ (*)(JSContext*, const JS::UTF8Chars,
-                                                size_t*, arena_id_t);
-
-static bool ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8,
-                             unsigned argc, Value* vp, const char* funName,
-                             arena_id_t destArenaId) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-  if (args.length() != 0) {
-    return ArgumentLengthError(cx, funName, "no", "s");
-  }
-
-  RootedObject obj(cx, GetThisObject(cx, args, funName));
+// Unwrap the `this` object to a CData object, or extract a CData object from a
+// CDataFinalizer.
+static bool GetThisDataObject(JSContext* cx, const CallArgs& args,
+                              const char* funName, MutableHandleObject obj) {
+  obj.set(GetThisObject(cx, args, funName));
   if (!obj) {
     return IncompatibleThisProto(cx, funName, args.thisv());
   }
-  if (!CData::IsCDataMaybeUnwrap(&obj)) {
+  if (!CData::IsCDataMaybeUnwrap(obj)) {
     if (!CDataFinalizer::IsCDataFinalizer(obj)) {
       return IncompatibleThisProto(cx, funName, args.thisv());
     }
 
-    CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(obj);
+    auto* p = (CDataFinalizer::Private*)JS::GetPrivate(obj);
     if (!p) {
       return EmptyFinalizerCallError(cx, funName);
     }
@@ -7746,12 +7807,31 @@ static bool ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8,
       return IncompatibleThisProto(cx, funName, args.thisv());
     }
 
-    obj = dataVal.toObjectOrNull();
-    if (!obj || !CData::IsCDataMaybeUnwrap(&obj)) {
+    obj.set(dataVal.toObjectOrNull());
+    if (!obj || !CData::IsCDataMaybeUnwrap(obj)) {
       return IncompatibleThisProto(cx, funName, args.thisv());
     }
   }
 
+  return true;
+}
+
+typedef JS::TwoByteCharsZ (*InflateUTF8Method)(JSContext*, const JS::UTF8Chars,
+                                               size_t*, arena_id_t);
+
+static bool ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8,
+                             unsigned argc, Value* vp, const char* funName,
+                             arena_id_t destArenaId) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+  if (args.length() != 0) {
+    return ArgumentLengthError(cx, funName, "no", "s");
+  }
+
+  RootedObject obj(cx);
+  if (!GetThisDataObject(cx, args, funName, &obj)) {
+    return false;
+  }
+
   // Make sure we are a pointer to, or an array of, an 8-bit or 16-bit
   // character or integer type.
   JSObject* baseType;
@@ -7844,6 +7924,146 @@ bool CData::ReadStringReplaceMalformed(JSContext* cx, unsigned argc,
                           js::StringBufferArena);
 }
 
+using TypedArrayConstructor = JSObject* (*)(JSContext*, uint32_t);
+
+template 
+TypedArrayConstructor GetTypedArrayConstructorImpl() {
+  if (std::is_floating_point_v) {
+    switch (sizeof(Type)) {
+      case 4:
+        return JS_NewFloat32Array;
+      case 8:
+        return JS_NewFloat64Array;
+      default:
+        return nullptr;
+    }
+  }
+
+  constexpr bool isSigned = std::is_signed_v;
+  switch (sizeof(Type)) {
+    case 1:
+      return isSigned ? JS_NewInt8Array : JS_NewUint8Array;
+    case 2:
+      return isSigned ? JS_NewInt16Array : JS_NewUint16Array;
+    case 4:
+      return isSigned ? JS_NewInt32Array : JS_NewUint32Array;
+    default:
+      return nullptr;
+  }
+}
+
+static TypedArrayConstructor GetTypedArrayConstructor(TypeCode baseType) {
+  switch (baseType) {
+#define MACRO(name, ctype, _) \
+  case TYPE_##name:           \
+    return GetTypedArrayConstructorImpl();
+    CTYPES_FOR_EACH_TYPE(MACRO)
+#undef MACRO
+    default:
+      return nullptr;
+  }
+}
+
+static bool ReadTypedArrayCommon(JSContext* cx, unsigned argc, Value* vp,
+                                 const char* funName) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+  if (args.length() != 0) {
+    return ArgumentLengthError(cx, funName, "no", "s");
+  }
+
+  RootedObject obj(cx);
+  if (!GetThisDataObject(cx, args, funName, &obj)) {
+    return false;
+  }
+
+  // Make sure we are a pointer to, or an array of, a type that is compatible
+  // with a typed array base type.
+  JSObject* baseType;
+  JSObject* typeObj = CData::GetCType(obj);
+  TypeCode typeCode = CType::GetTypeCode(typeObj);
+  void* data;
+  mozilla::Maybe length;
+  switch (typeCode) {
+    case TYPE_pointer:
+      baseType = PointerType::GetBaseType(typeObj);
+      data = *static_cast(CData::GetData(obj));
+      if (data == nullptr) {
+        return NullPointerError(cx, "read contents of", obj);
+      }
+      break;
+    case TYPE_array:
+      baseType = ArrayType::GetBaseType(typeObj);
+      data = CData::GetData(obj);
+      length.emplace(ArrayType::GetLength(typeObj));
+      break;
+    default:
+      return TypeError(cx, "PointerType or ArrayType", args.thisv());
+  }
+
+  TypeCode baseTypeCode = CType::GetTypeCode(baseType);
+
+  // For string inputs only, use strlen to determine the length.
+  switch (baseTypeCode) {
+    case TYPE_char:
+    case TYPE_signed_char:
+    case TYPE_unsigned_char:
+      if (!length) {
+        length.emplace(js_strnlen(static_cast(data), INT32_MAX));
+      }
+      break;
+
+    case TYPE_char16_t:
+      if (!length) {
+        length.emplace(js_strlen(static_cast(data)));
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  if (!length) {
+    return NonStringBaseError(cx, args.thisv());
+  }
+
+  auto makeTypedArray = GetTypedArrayConstructor(baseTypeCode);
+  if (!makeTypedArray) {
+    return NonTypedArrayBaseError(cx, args.thisv());
+  }
+
+  CheckedInt size = *length;
+  size *= CType::GetSize(baseType);
+  if (!size.isValid() ||
+      size.value() > ArrayBufferObject::MaxBufferByteLength) {
+    return SizeOverflow(cx, "data", "typed array");
+  }
+
+  JSObject* result = makeTypedArray(cx, *length);
+  if (!result) {
+    return false;
+  }
+
+  AutoCheckCannotGC nogc(cx);
+  bool isShared;
+  void* buffer = JS_GetArrayBufferViewData(&result->as(),
+                                           &isShared, nogc);
+  MOZ_ASSERT(!isShared);
+  memcpy(buffer, data, size.value());
+
+  args.rval().setObject(*result);
+  return true;
+}
+
+bool CData::ReadTypedArray(JSContext* cx, unsigned argc, Value* vp) {
+  return ReadTypedArrayCommon(cx, argc, vp, "CData.prototype.readTypedArray");
+}
+
+bool CDataFinalizer::Methods::ReadTypedArray(JSContext* cx, unsigned argc,
+                                             Value* vp) {
+  return ReadTypedArrayCommon(cx, argc, vp,
+                              "CDataFinalizer.prototype.readTypedArray");
+}
+
 JSString* CData::GetSourceString(JSContext* cx, HandleObject typeObj,
                                  void* data) {
   // Walk the types, building up the toSource() string.
@@ -7900,13 +8120,14 @@ bool CData::ToSource(JSContext* cx, unsigned argc, Value* vp) {
 }
 
 bool CData::ErrnoGetter(JSContext* cx, const JS::CallArgs& args) {
-  args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), SLOT_ERRNO));
+  args.rval().set(JS::GetReservedSlot(&args.thisv().toObject(), SLOT_ERRNO));
   return true;
 }
 
 #if defined(XP_WIN)
 bool CData::LastErrorGetter(JSContext* cx, const JS::CallArgs& args) {
-  args.rval().set(JS_GetReservedSlot(&args.thisv().toObject(), SLOT_LASTERROR));
+  args.rval().set(
+      JS::GetReservedSlot(&args.thisv().toObject(), SLOT_LASTERROR));
   return true;
 }
 #endif  // defined(XP_WIN)
@@ -7924,7 +8145,7 @@ bool CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc,
                                  InformalValueTypeName(args.thisv()));
   }
 
-  CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(objThis);
+  auto* p = (CDataFinalizer::Private*)JS::GetPrivate(objThis);
 
   JSString* strMessage;
   if (!p) {
@@ -7945,7 +8166,7 @@ bool CDataFinalizer::Methods::ToSource(JSContext* cx, unsigned argc,
     AppendString(cx, source, srcValue);
     AppendString(cx, source, ", ");
     Value valCodePtrType =
-        JS_GetReservedSlot(objThis, SLOT_DATAFINALIZER_CODETYPE);
+        JS::GetReservedSlot(objThis, SLOT_DATAFINALIZER_CODETYPE);
     if (valCodePtrType.isPrimitive()) {
       return false;
     }
@@ -7988,7 +8209,7 @@ bool CDataFinalizer::Methods::ToString(JSContext* cx, unsigned argc,
 
   JSString* strMessage;
   RootedValue value(cx);
-  if (!JS_GetPrivate(objThis)) {
+  if (!JS::GetPrivate(objThis)) {
     // Pre-check whether CDataFinalizer::GetValue can fail
     // to avoid reporting an error when not appropriate.
     strMessage = JS_NewStringCopyZ(cx, "[CDataFinalizer - empty]");
@@ -8008,13 +8229,13 @@ bool CDataFinalizer::Methods::ToString(JSContext* cx, unsigned argc,
 }
 
 bool CDataFinalizer::IsCDataFinalizer(JSObject* obj) {
-  return JS_GetClass(obj) == &sCDataFinalizerClass;
+  return obj->hasClass(&sCDataFinalizerClass);
 }
 
 JSObject* CDataFinalizer::GetCType(JSContext* cx, JSObject* obj) {
   MOZ_ASSERT(IsCDataFinalizer(obj));
 
-  Value valData = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE);
+  Value valData = JS::GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE);
   if (valData.isUndefined()) {
     return nullptr;
   }
@@ -8026,7 +8247,7 @@ bool CDataFinalizer::GetValue(JSContext* cx, JSObject* obj,
                               MutableHandleValue aResult) {
   MOZ_ASSERT(IsCDataFinalizer(obj));
 
-  CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(obj);
+  auto* p = (CDataFinalizer::Private*)JS::GetPrivate(obj);
 
   if (!p) {
     // We have called |dispose| or |forget| already.
@@ -8225,7 +8446,7 @@ bool CDataFinalizer::Construct(JSContext* cx, unsigned argc, Value* vp) {
   p->cargs_size = sizeArg;
   p->code = code;
 
-  JS_SetPrivate(objResult, p.release());
+  JS::SetPrivate(objResult, p.release());
   args.rval().setObject(*objResult);
   return true;
 }
@@ -8295,7 +8516,7 @@ bool CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, Value* vp) {
                                  args.thisv());
   }
 
-  CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(obj);
+  auto* p = (CDataFinalizer::Private*)JS::GetPrivate(obj);
 
   if (!p) {
     return EmptyFinalizerCallError(cx, "CDataFinalizer.prototype.forget");
@@ -8341,13 +8562,13 @@ bool CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, Value* vp) {
                                  args.thisv());
   }
 
-  CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(obj);
+  auto* p = (CDataFinalizer::Private*)JS::GetPrivate(obj);
 
   if (!p) {
     return EmptyFinalizerCallError(cx, "CDataFinalizer.prototype.dispose");
   }
 
-  Value valType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE);
+  Value valType = JS::GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE);
   MOZ_ASSERT(valType.isObject());
 
   RootedObject objCTypes(cx, CType::GetGlobalCTypes(cx, &valType.toObject()));
@@ -8355,7 +8576,7 @@ bool CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, Value* vp) {
     return false;
   }
 
-  Value valCodePtrType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_CODETYPE);
+  Value valCodePtrType = JS::GetReservedSlot(obj, SLOT_DATAFINALIZER_CODETYPE);
   MOZ_ASSERT(valCodePtrType.isObject());
   JSObject* objCodePtrType = &valCodePtrType.toObject();
 
@@ -8400,7 +8621,7 @@ bool CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, Value* vp) {
  * strong references.
  */
 void CDataFinalizer::Finalize(JSFreeOp* fop, JSObject* obj) {
-  CDataFinalizer::Private* p = (CDataFinalizer::Private*)JS_GetPrivate(obj);
+  auto* p = (CDataFinalizer::Private*)JS::GetPrivate(obj);
 
   if (!p) {
     return;
@@ -8436,7 +8657,7 @@ void CDataFinalizer::Cleanup(CDataFinalizer::Private* p, JSObject* obj) {
 
   MOZ_ASSERT(CDataFinalizer::IsCDataFinalizer(obj));
 
-  JS_SetPrivate(obj, nullptr);
+  JS::SetPrivate(obj, nullptr);
   for (int i = 0; i < CDATAFINALIZER_SLOTS; ++i) {
     JS_SetReservedSlot(obj, i, JS::NullValue());
   }
@@ -8470,7 +8691,7 @@ JSObject* Int64Base::Construct(JSContext* cx, HandleObject proto, uint64_t data,
 }
 
 void Int64Base::Finalize(JSFreeOp* fop, JSObject* obj) {
-  Value slot = JS_GetReservedSlot(obj, SLOT_INT64);
+  Value slot = JS::GetReservedSlot(obj, SLOT_INT64);
   if (slot.isUndefined()) {
     return;
   }
@@ -8482,7 +8703,7 @@ void Int64Base::Finalize(JSFreeOp* fop, JSObject* obj) {
 uint64_t Int64Base::GetInt(JSObject* obj) {
   MOZ_ASSERT(Int64::IsInt64(obj) || UInt64::IsUInt64(obj));
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_INT64);
+  Value slot = JS::GetReservedSlot(obj, SLOT_INT64);
   return *static_cast(slot.toPrivate());
 }
 
@@ -8588,7 +8809,7 @@ bool Int64::Construct(JSContext* cx, unsigned argc, Value* vp) {
   RootedObject callee(cx, &args.callee());
   MOZ_ALWAYS_TRUE(JS_GetProperty(cx, callee, "prototype", &slot));
   RootedObject proto(cx, slot.toObjectOrNull());
-  MOZ_ASSERT(JS_GetClass(proto) == &sInt64ProtoClass);
+  MOZ_ASSERT(proto->hasClass(&sInt64ProtoClass));
 
   JSObject* result = Int64Base::Construct(cx, proto, i, false);
   if (!result) {
@@ -8599,7 +8820,7 @@ bool Int64::Construct(JSContext* cx, unsigned argc, Value* vp) {
   return true;
 }
 
-bool Int64::IsInt64(JSObject* obj) { return JS_GetClass(obj) == &sInt64Class; }
+bool Int64::IsInt64(JSObject* obj) { return obj->hasClass(&sInt64Class); }
 
 bool Int64::ToString(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
@@ -8726,7 +8947,7 @@ bool Int64::Join(JSContext* cx, unsigned argc, Value* vp) {
 
   Value slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
   RootedObject proto(cx, &slot.toObject());
-  MOZ_ASSERT(JS_GetClass(proto) == &sInt64ProtoClass);
+  MOZ_ASSERT(proto->hasClass(&sInt64ProtoClass));
 
   JSObject* result = Int64Base::Construct(cx, proto, i, false);
   if (!result) {
@@ -8759,7 +8980,7 @@ bool UInt64::Construct(JSContext* cx, unsigned argc, Value* vp) {
   RootedObject callee(cx, &args.callee());
   MOZ_ALWAYS_TRUE(JS_GetProperty(cx, callee, "prototype", &slot));
   RootedObject proto(cx, &slot.toObject());
-  MOZ_ASSERT(JS_GetClass(proto) == &sUInt64ProtoClass);
+  MOZ_ASSERT(proto->hasClass(&sUInt64ProtoClass));
 
   JSObject* result = Int64Base::Construct(cx, proto, u, true);
   if (!result) {
@@ -8770,9 +8991,7 @@ bool UInt64::Construct(JSContext* cx, unsigned argc, Value* vp) {
   return true;
 }
 
-bool UInt64::IsUInt64(JSObject* obj) {
-  return JS_GetClass(obj) == &sUInt64Class;
-}
+bool UInt64::IsUInt64(JSObject* obj) { return obj->hasClass(&sUInt64Class); }
 
 bool UInt64::ToString(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
@@ -8895,7 +9114,7 @@ bool UInt64::Join(JSContext* cx, unsigned argc, Value* vp) {
 
   Value slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
   RootedObject proto(cx, &slot.toObject());
-  MOZ_ASSERT(JS_GetClass(proto) == &sUInt64ProtoClass);
+  MOZ_ASSERT(proto->hasClass(&sUInt64ProtoClass));
 
   JSObject* result = Int64Base::Construct(cx, proto, u, true);
   if (!result) {
diff --git a/js/src/ctypes/Library.cpp b/js/src/ctypes/Library.cpp
index 57d3afba63..9fffffa1f0 100644
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -10,8 +10,10 @@
 #include "ctypes/CTypes.h"
 #include "js/CharacterEncoding.h"
 #include "js/MemoryFunctions.h"
+#include "js/Object.h"  // JS::GetReservedSlot
 #include "js/PropertySpec.h"
 #include "js/StableStringChars.h"
+#include "vm/JSObject.h"
 
 using JS::AutoStableStringChars;
 
@@ -197,14 +199,12 @@ JSObject* Library::Create(JSContext* cx, HandleValue path,
   return libraryObj;
 }
 
-bool Library::IsLibrary(JSObject* obj) {
-  return JS_GetClass(obj) == &sLibraryClass;
-}
+bool Library::IsLibrary(JSObject* obj) { return obj->hasClass(&sLibraryClass); }
 
 PRLibrary* Library::GetLibrary(JSObject* obj) {
   MOZ_ASSERT(IsLibrary(obj));
 
-  Value slot = JS_GetReservedSlot(obj, SLOT_LIBRARY);
+  Value slot = JS::GetReservedSlot(obj, SLOT_LIBRARY);
   return static_cast(slot.toPrivate());
 }
 
diff --git a/js/src/ctypes/ctypes.msg b/js/src/ctypes/ctypes.msg
index 93187e43fd..25e9f428a6 100644
--- a/js/src/ctypes/ctypes.msg
+++ b/js/src/ctypes/ctypes.msg
@@ -5,7 +5,7 @@
 /*
  * This is the jsctypes error message file.
  *
- * For syntax details, see js/src/js.msg.
+ * For syntax details, see js/public/friend/ErrorNumbers.msg.
  */
 
 MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, JSEXN_ERR, NULL)
@@ -69,6 +69,7 @@ MSG_DEF(CTYPESMSG_CANNOT_CONSTRUCT,1, JSEXN_TYPEERR, "cannot construct from {0}"
 MSG_DEF(CTYPESMSG_UNDEFINED_SIZE,2, JSEXN_TYPEERR, "cannot {0} pointer of undefined size {1}")
 MSG_DEF(CTYPESMSG_NULL_POINTER,  2, JSEXN_TYPEERR, "cannot {0} null pointer {1}")
 MSG_DEF(CTYPESMSG_NON_STRING_BASE,1, JSEXN_TYPEERR, "base type {0} is not an 8-bit or 16-bit integer or character type")
+MSG_DEF(CTYPESMSG_NON_TYPEDARRAY_BASE,1, JSEXN_TYPEERR, "base type {0} is not compatible with a typed array element type")
 
 /* cast */
 MSG_DEF(CTYPESMSG_UNDEFINED_SIZE_CAST,1, JSEXN_TYPEERR, "target type {0} has undefined size")
diff --git a/js/src/debugger/DebugScript.cpp b/js/src/debugger/DebugScript.cpp
index 65b367f81e..2ad78ce3b2 100644
--- a/js/src/debugger/DebugScript.cpp
+++ b/js/src/debugger/DebugScript.cpp
@@ -6,9 +6,10 @@
 
 #include "mozilla/Assertions.h"  // for AssertionConditionType
 #include "mozilla/HashTable.h"   // for HashMapEntry, HashTable<>::Ptr, HashMap
-#include "mozilla/Move.h"        // for std::move
 #include "mozilla/UniquePtr.h"   // for UniquePtr
 
+#include   // for std::move
+
 #include "jsapi.h"
 
 #include "debugger/DebugAPI.h"  // for DebugAPI
@@ -154,25 +155,13 @@ void DebugScript::destroyBreakpointSite(JSFreeOp* fop, JSScript* script,
   }
 }
 
-/* static */
-void DebugScript::clearBreakpointsIn(JSFreeOp* fop, Realm* realm, Debugger* dbg,
-                                     JSObject* handler) {
-  for (auto base = realm->zone()->cellIter(); !base.done();
-       base.next()) {
-    MOZ_ASSERT_IF(base->hasDebugScript(), base->hasBytecode());
-    if (base->realm() == realm && base->hasDebugScript()) {
-      clearBreakpointsIn(fop, base->asJSScript(), dbg, handler);
-    }
-  }
-}
-
 /* static */
 void DebugScript::clearBreakpointsIn(JSFreeOp* fop, JSScript* script,
                                      Debugger* dbg, JSObject* handler) {
+  MOZ_ASSERT(script);
   // Breakpoints hold wrappers in the script's compartment for the handler. Make
   // sure we don't try to search for the unwrapped handler.
-  MOZ_ASSERT_IF(script && handler,
-                script->compartment() == handler->compartment());
+  MOZ_ASSERT_IF(handler, script->compartment() == handler->compartment());
 
   if (!script->hasDebugScript()) {
     return;
diff --git a/js/src/debugger/DebugScript.h b/js/src/debugger/DebugScript.h
index 7a61a38c0c..4526f3bb28 100644
--- a/js/src/debugger/DebugScript.h
+++ b/js/src/debugger/DebugScript.h
@@ -87,8 +87,6 @@ class DebugScript {
   static void destroyBreakpointSite(JSFreeOp* fop, JSScript* script,
                                     jsbytecode* pc);
 
-  static void clearBreakpointsIn(JSFreeOp* fop, JS::Realm* realm, Debugger* dbg,
-                                 JSObject* handler);
   static void clearBreakpointsIn(JSFreeOp* fop, JSScript* script, Debugger* dbg,
                                  JSObject* handler);
 
diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp
index 9a9c4a2c15..f8572d48cd 100644
--- a/js/src/debugger/Debugger.cpp
+++ b/js/src/debugger/Debugger.cpp
@@ -7,10 +7,8 @@
 #include "mozilla/Attributes.h"        // for MOZ_STACK_CLASS, MOZ_RAII
 #include "mozilla/DebugOnly.h"         // for DebugOnly
 #include "mozilla/DoublyLinkedList.h"  // for DoublyLinkedList<>::Iterator
-#include "mozilla/GuardObjects.h"      // for MOZ_GUARD_OBJECT_NOTIFIER_PARAM
 #include "mozilla/HashTable.h"         // for HashSet<>::Range, HashMapEntry
 #include "mozilla/Maybe.h"             // for Maybe, Nothing, Some
-#include "mozilla/Move.h"              // for std::move
 #include "mozilla/ScopeExit.h"         // for MakeScopeExit, ScopeExit
 #include "mozilla/ThreadLocal.h"       // for ThreadLocal
 #include "mozilla/TimeStamp.h"         // for TimeStamp, TimeDuration
@@ -23,6 +21,7 @@
 #include     // for size_t
 #include     // for uint32_t, uint64_t, int32_t
 #include     // for strlen, strcmp
+#include      // for std::move
 
 #include "jsapi.h"        // for CallArgs, CallArgsFromVp
 #include "jsfriendapi.h"  // for GetErrorMessage
@@ -58,37 +57,37 @@
 #include "jit/BaselineJIT.h"           // for FinishDiscardBaselineScript
 #include "jit/Ion.h"                   // for JitContext
 #include "jit/JitScript.h"             // for JitScript
-#include "jit/JSJitFrameIter.h"       // for InlineFrameIterator
-#include "jit/RematerializedFrame.h"  // for RematerializedFrame
-#include "js/Conversions.h"           // for ToBoolean, ToUint32
-#include "js/Debug.h"                 // for Builder::Object, Builder
-#include "js/GCAPI.h"                 // for GarbageCollectionEvent
-#include "js/HeapAPI.h"               // for ExposeObjectToActiveJS
-#include "js/Promise.h"               // for AutoDebuggerJobQueueInterruption
-#include "js/Proxy.h"                 // for PropertyDescriptor
-#include "js/SourceText.h"            // for SourceOwnership, SourceText
-#include "js/StableStringChars.h"     // for AutoStableStringChars
-#include "js/UbiNode.h"               // for Node, RootList, Edge
-#include "js/UbiNodeBreadthFirst.h"   // for BreadthFirst
-#include "js/Warnings.h"              // for AutoSuppressWarningReporter
-#include "js/Wrapper.h"               // for CheckedUnwrapStatic
-#include "util/Text.h"                // for DuplicateString, js_strlen
-#include "vm/ArrayObject.h"           // for ArrayObject
-#include "vm/AsyncFunction.h"         // for AsyncFunctionGeneratorObject
-#include "vm/AsyncIteration.h"        // for AsyncGeneratorObject
-#include "vm/BytecodeUtil.h"          // for JSDVG_IGNORE_STACK
-#include "vm/Compartment.h"           // for CrossCompartmentKey
-#include "vm/EnvironmentObject.h"     // for IsSyntacticEnvironment
-#include "vm/ErrorReporting.h"        // for ReportErrorToGlobal
-#include "vm/GeneratorObject.h"       // for AbstractGeneratorObject
-#include "vm/GlobalObject.h"          // for GlobalObject
-#include "vm/Interpreter.h"           // for Call, ReportIsNotFunction
-#include "vm/Iteration.h"             // for CreateIterResultObject
-#include "vm/JSAtom.h"                // for Atomize, ClassName
-#include "vm/JSContext.h"             // for JSContext
-#include "vm/JSFunction.h"            // for JSFunction
-#include "vm/JSObject.h"              // for JSObject, RequireObject
-#include "vm/ObjectGroup.h"           // for TenuredObject
+#include "jit/JSJitFrameIter.h"        // for InlineFrameIterator
+#include "jit/RematerializedFrame.h"   // for RematerializedFrame
+#include "js/Conversions.h"            // for ToBoolean, ToUint32
+#include "js/Debug.h"                  // for Builder::Object, Builder
+#include "js/GCAPI.h"                  // for GarbageCollectionEvent
+#include "js/HeapAPI.h"                // for ExposeObjectToActiveJS
+#include "js/Promise.h"                // for AutoDebuggerJobQueueInterruption
+#include "js/Proxy.h"                  // for PropertyDescriptor
+#include "js/SourceText.h"             // for SourceOwnership, SourceText
+#include "js/StableStringChars.h"      // for AutoStableStringChars
+#include "js/UbiNode.h"                // for Node, RootList, Edge
+#include "js/UbiNodeBreadthFirst.h"    // for BreadthFirst
+#include "js/Warnings.h"               // for AutoSuppressWarningReporter
+#include "js/Wrapper.h"                // for CheckedUnwrapStatic
+#include "util/Text.h"                 // for DuplicateString, js_strlen
+#include "vm/ArrayObject.h"            // for ArrayObject
+#include "vm/AsyncFunction.h"          // for AsyncFunctionGeneratorObject
+#include "vm/AsyncIteration.h"         // for AsyncGeneratorObject
+#include "vm/BytecodeUtil.h"           // for JSDVG_IGNORE_STACK
+#include "vm/Compartment.h"            // for CrossCompartmentKey
+#include "vm/EnvironmentObject.h"      // for IsSyntacticEnvironment
+#include "vm/ErrorReporting.h"         // for ReportErrorToGlobal
+#include "vm/GeneratorObject.h"        // for AbstractGeneratorObject
+#include "vm/GlobalObject.h"           // for GlobalObject
+#include "vm/Interpreter.h"            // for Call, ReportIsNotFunction
+#include "vm/Iteration.h"              // for CreateIterResultObject
+#include "vm/JSAtom.h"                 // for Atomize, ClassName
+#include "vm/JSContext.h"              // for JSContext
+#include "vm/JSFunction.h"             // for JSFunction
+#include "vm/JSObject.h"               // for JSObject, RequireObject
+#include "vm/ObjectGroup.h"            // for TenuredObject
 #include "vm/ObjectOperations.h"      // for DefineDataProperty
 #include "vm/PlainObject.h"           // for js::PlainObject
 #include "vm/PromiseObject.h"         // for js::PromiseObject
@@ -109,7 +108,9 @@
 #include "wasm/WasmTypes.h"           // for WasmInstanceObjectVector
 
 #include "debugger/DebugAPI-inl.h"
-#include "debugger/Frame-inl.h"    // for DebuggerFrame::hasGeneratorInfo
+#include "debugger/Environment-inl.h"  // for DebuggerEnvironment::owner
+#include "debugger/Frame-inl.h"        // for DebuggerFrame::hasGeneratorInfo
+#include "debugger/Object-inl.h"   // for DebuggerObject::owner and isInstance.
 #include "debugger/Script-inl.h"   // for DebuggerScript::getReferent
 #include "gc/GC-inl.h"             // for ZoneCellIter
 #include "gc/Marking-inl.h"        // for MaybeForwarded
@@ -172,8 +173,38 @@ JSScript* js::GetOrCreateFunctionScript(JSContext* cx, HandleFunction fun) {
   return JSFunction::getOrCreateScript(cx, fun);
 }
 
+ArrayObject* js::GetFunctionParameterNamesArray(JSContext* cx,
+                                                HandleFunction fun) {
+  RootedValueVector names(cx);
+
+  // The default value for each argument is |undefined|.
+  if (!names.growBy(fun->nargs())) {
+    return nullptr;
+  }
+
+  if (IsInterpretedNonSelfHostedFunction(fun) && fun->nargs() > 0) {
+    RootedScript script(cx, GetOrCreateFunctionScript(cx, fun));
+    if (!script) {
+      return nullptr;
+    }
+
+    MOZ_ASSERT(fun->nargs() == script->numArgs());
+
+    PositionalFormalParameterIter fi(script);
+    for (size_t i = 0; i < fun->nargs(); i++, fi++) {
+      MOZ_ASSERT(fi.argumentSlot() == i);
+      if (JSAtom* atom = fi.name()) {
+        cx->markAtom(atom);
+        names[i].setString(atom);
+      }
+    }
+  }
+
+  return NewDenseCopiedArray(cx, names.length(), names.begin());
+}
+
 bool js::ValueToIdentifier(JSContext* cx, HandleValue v, MutableHandleId id) {
-  if (!ValueToId(cx, v, id)) {
+  if (!ToPropertyKey(cx, v, id)) {
     return false;
   }
   if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
@@ -525,6 +556,18 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
   cx->runtime()->debuggerList().insertBack(this);
 }
 
+template 
+static void RemoveDebuggerEntry(
+    mozilla::DoublyLinkedList& list, Debugger* dbg) {
+  // The "probably" here is because there could technically be multiple lists
+  // with this type signature and theoretically the debugger could be an entry
+  // in a different one. That is not actually possible however because there
+  // is only one list the debugger could be in.
+  if (list.ElementProbablyInList(dbg)) {
+    list.remove(dbg);
+  }
+}
+
 Debugger::~Debugger() {
   MOZ_ASSERT(debuggees.empty());
   allocationsLog.clear();
@@ -537,23 +580,10 @@ Debugger::~Debugger() {
   // We don't have to worry about locking here since Debugger is not
   // background finalized.
   JSContext* cx = TlsContext.get();
-  if (onNewGlobalObjectWatchersLink.mPrev ||
-      onNewGlobalObjectWatchersLink.mNext ||
-      cx->runtime()->onNewGlobalObjectWatchers().begin() ==
-          JSRuntime::WatchersList::Iterator(this)) {
-    cx->runtime()->onNewGlobalObjectWatchers().remove(this);
-  }
+  RemoveDebuggerEntry(cx->runtime()->onNewGlobalObjectWatchers(), this);
+  RemoveDebuggerEntry(cx->runtime()->onGarbageCollectionWatchers(), this);
 }
 
-static_assert(unsigned(DebuggerFrame::OWNER_SLOT) ==
-              unsigned(DebuggerScript::OWNER_SLOT));
-static_assert(unsigned(DebuggerFrame::OWNER_SLOT) ==
-              unsigned(DebuggerSource::OWNER_SLOT));
-static_assert(unsigned(DebuggerFrame::OWNER_SLOT) ==
-              unsigned(JSSLOT_DEBUGOBJECT_OWNER));
-static_assert(unsigned(DebuggerFrame::OWNER_SLOT) ==
-              unsigned(DebuggerEnvironment::OWNER_SLOT));
-
 #ifdef DEBUG
 /* static */
 bool Debugger::isChildJSObject(JSObject* obj) {
@@ -565,15 +595,6 @@ bool Debugger::isChildJSObject(JSObject* obj) {
 }
 #endif
 
-/* static */
-Debugger* Debugger::fromChildJSObject(JSObject* obj) {
-  MOZ_ASSERT(isChildJSObject(obj));
-  JSObject* dbgobj = &obj->as()
-                          .getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER)
-                          .toObject();
-  return fromJSObject(dbgobj);
-}
-
 bool Debugger::hasMemory() const {
   return object->getReservedSlot(JSSLOT_DEBUG_MEMORY_INSTANCE).isObject();
 }
@@ -609,34 +630,23 @@ bool Debugger::getFrame(JSContext* cx, const FrameIter& iter,
 
   FrameMap::AddPtr p = frames.lookupForAdd(referent);
   if (!p) {
-    RootedDebuggerFrame frame(cx);
-
-    // If this is a generator frame, there may be an existing
-    // Debugger.Frame object that isn't in `frames` because the generator
-    // was suspended, popping the stack frame, and later resumed (and we
-    // were not stepping, so did not pass through slowPathOnResumeFrame).
     Rooted genObj(cx);
     if (referent.isGeneratorFrame()) {
-      {
-        AutoRealm ar(cx, referent.callee());
-        genObj = GetGeneratorObjectForFrame(cx, referent);
-      }
-      if (genObj) {
-        GeneratorWeakMap::Ptr gp = generatorFrames.lookup(genObj);
-        if (gp) {
-          frame = gp->value();
-          MOZ_ASSERT(&frame->unwrappedGenerator() == genObj);
-
-          // We have found an existing Debugger.Frame object. But
-          // since it was previously popped (see comment above), it
-          // is not currently "live". We must revive it.
-          if (!frame->resume(iter)) {
-            return false;
-          }
-          if (!ensureExecutionObservabilityOfFrame(cx, referent)) {
-            return false;
-          }
-        }
+      AutoRealm ar(cx, referent.callee());
+      genObj = GetGeneratorObjectForFrame(cx, referent);
+
+      // If this frame has a generator associated with it, but no on-stack
+      // Debugger.Frame object was found, there should not be a suspended
+      // Debugger.Frame either because otherwise slowPathOnResumeFrame would
+      // have already populated the "frames" map with a Debugger.Frame.
+      MOZ_ASSERT_IF(genObj, !generatorFrames.has(genObj));
+
+      // If the frame's generator is closed, there is no way to associate the
+      // generator with the frame successfully because there is no way to
+      // get the generator's callee script, and even if we could, having it
+      // there would in no way affect the behavior of the frame.
+      if (genObj && genObj->isClosed()) {
+        genObj = nullptr;
       }
 
       // If no AbstractGeneratorObject exists yet, we create a Debugger.Frame
@@ -644,28 +654,38 @@ bool Debugger::getFrame(JSContext* cx, const FrameIter& iter,
       // with the AbstractGeneratorObject later when we hit JSOp::Generator.
     }
 
+    // Create and populate the Debugger.Frame object.
+    RootedObject proto(
+        cx, &object->getReservedSlot(JSSLOT_DEBUG_FRAME_PROTO).toObject());
+    RootedNativeObject debugger(cx, object);
+
+    RootedDebuggerFrame frame(
+        cx, DebuggerFrame::create(cx, proto, debugger, &iter, genObj));
     if (!frame) {
-      // Create and populate the Debugger.Frame object.
-      RootedObject proto(
-          cx, &object->getReservedSlot(JSSLOT_DEBUG_FRAME_PROTO).toObject());
-      RootedNativeObject debugger(cx, object);
+      return false;
+    }
 
-      frame = DebuggerFrame::create(cx, proto, debugger, &iter, genObj);
-      if (!frame) {
-        return false;
-      }
+    auto terminateDebuggerFrameGuard = MakeScopeExit([&] {
+      terminateDebuggerFrame(cx->defaultFreeOp(), this, frame, referent);
+    });
 
-      if (!ensureExecutionObservabilityOfFrame(cx, referent)) {
+    if (genObj) {
+      DependentAddPtr genPtr(cx, generatorFrames, genObj);
+      if (!genPtr.add(cx, generatorFrames, genObj, frame)) {
         return false;
       }
     }
 
+    if (!ensureExecutionObservabilityOfFrame(cx, referent)) {
+      return false;
+    }
+
     if (!frames.add(p, referent, frame)) {
-      frame->freeFrameIterData(cx->defaultFreeOp());
-      frame->clearGeneratorInfo(cx->runtime()->defaultFreeOp(), this);
       ReportOutOfMemory(cx);
       return false;
     }
+
+    terminateDebuggerFrameGuard.release();
   }
 
   result.set(p->value());
@@ -679,13 +699,13 @@ bool Debugger::getFrame(JSContext* cx, Handle genObj,
   // stack for the generator's frame, but for the moment, we only need this
   // function to handle generators we've found on promises' reaction records,
   // which should always be suspended.
-  MOZ_ASSERT(!genObj->isRunning());
+  MOZ_ASSERT(genObj->isSuspended());
 
   // Do we have an existing Debugger.Frame for this generator?
-  GeneratorWeakMap::Ptr gp = generatorFrames.lookup(genObj);
-  if (gp) {
-    MOZ_ASSERT(&gp->value()->unwrappedGenerator() == genObj);
-    result.set(gp->value());
+  DependentAddPtr p(cx, generatorFrames, genObj);
+  if (p) {
+    MOZ_ASSERT(&p->value()->unwrappedGenerator() == genObj);
+    result.set(p->value());
     return true;
   }
 
@@ -699,6 +719,12 @@ bool Debugger::getFrame(JSContext* cx, Handle genObj,
     return false;
   }
 
+  if (!p.add(cx, generatorFrames, genObj, result)) {
+    terminateDebuggerFrame(cx->runtime()->defaultFreeOp(), this, result,
+                           NullFramePtr());
+    return false;
+  }
+
   return true;
 }
 
@@ -867,9 +893,20 @@ bool DebugAPI::slowPathOnResumeFrame(JSContext* cx, AbstractFramePtr frame) {
       cx, GetGeneratorObjectForFrame(cx, frame));
   MOZ_ASSERT(genObj);
 
+  // If there is an OOM, we mark all of the Debugger.Frame objects terminated
+  // because we want to ensure that none of the frames are in a partially
+  // initialized state where they are in "generatorFrames" but not "frames".
+  auto terminateDebuggerFramesGuard = MakeScopeExit([&] {
+    Debugger::terminateDebuggerFrames(cx, frame);
+
+    MOZ_ASSERT(!DebugAPI::inFrameMaps(frame));
+  });
+
   // For each debugger, if there is an existing Debugger.Frame object for the
   // resumed `frame`, update it with the new frame pointer and make sure the
   // frame is observable.
+  FrameIter iter(cx);
+  MOZ_ASSERT(iter.abstractFramePtr() == frame);
   for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
     Debugger* dbg = entry.dbg;
     if (Debugger::GeneratorWeakMap::Ptr generatorEntry =
@@ -880,18 +917,14 @@ bool DebugAPI::slowPathOnResumeFrame(JSContext* cx, AbstractFramePtr frame) {
         ReportOutOfMemory(cx);
         return false;
       }
-
-      FrameIter iter(cx);
-      MOZ_ASSERT(iter.abstractFramePtr() == frame);
       if (!frameObj->resume(iter)) {
         return false;
       }
-      if (!Debugger::ensureExecutionObservabilityOfFrame(cx, frame)) {
-        return false;
-      }
     }
   }
 
+  terminateDebuggerFramesGuard.release();
+
   return slowPathOnEnterFrame(cx, frame);
 }
 
@@ -1035,8 +1068,11 @@ bool DebugAPI::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame,
     // flag that says to leave those frames `.live`. Note that if the completion
     // is a suspension but success is false, the generator gets closed, not
     // suspended.
-    Debugger::removeFromFrameMapsAndClearBreakpointsIn(
-        cx, frame, success && completion.get().suspending());
+    if (success && completion.get().suspending()) {
+      Debugger::suspendGeneratorDebuggerFrames(cx, frame);
+    } else {
+      Debugger::terminateDebuggerFrames(cx, frame);
+    }
   });
 
   // The onPop handler and associated clean up logic should not run multiple
@@ -1077,7 +1113,7 @@ bool DebugAPI::slowPathOnLeaveFrame(JSContext* cx, AbstractFramePtr frame,
       // For each Debugger.Frame, fire its onPop handler, if any.
       for (size_t i = 0; i < frames.length(); i++) {
         HandleDebuggerFrame frameobj = frames[i];
-        Debugger* dbg = Debugger::fromChildJSObject(frameobj);
+        Debugger* dbg = frameobj->owner();
         EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
 
         // Removing a global from a Debugger's debuggee set kills all of that
@@ -1166,27 +1202,45 @@ bool DebugAPI::slowPathOnNewGenerator(JSContext* cx, AbstractFramePtr frame,
   // `frame` may already have been exposed to debugger code. The
   // AbstractGeneratorObject for this generator call, though, has just been
   // created. It must be associated with any existing Debugger.Frames.
+
+  // Initializing frames with their associated generator is critical to the
+  // functionality of the debugger, so if there is an OOM, we want to
+  // cleanly terminate all of the frames.
+  auto terminateDebuggerFramesGuard =
+      MakeScopeExit([&] { Debugger::terminateDebuggerFrames(cx, frame); });
+
   bool ok = true;
-  Debugger::forEachDebuggerFrame(frame, [&](DebuggerFrame* frameObjPtr) {
-    if (!ok) {
-      return;
-    }
+  Debugger::forEachOnStackDebuggerFrame(
+      frame, [&](Debugger* dbg, DebuggerFrame* frameObjPtr) {
+        if (!ok) {
+          return;
+        }
 
-    RootedDebuggerFrame frameObj(cx, frameObjPtr);
-    {
-      AutoRealm ar(cx, frameObj);
+        RootedDebuggerFrame frameObj(cx, frameObjPtr);
 
-      if (!frameObj->setGeneratorInfo(cx, genObj)) {
-        ReportOutOfMemory(cx);
+        AutoRealm ar(cx, frameObj);
 
-        // This leaves `genObj` and `frameObj` unassociated. It's OK
-        // because we won't pause again with this generator on the stack:
-        // the caller will immediately discard `genObj` and unwind `frame`.
-        ok = false;
-      }
-    }
-  });
-  return ok;
+        if (!frameObj->setGeneratorInfo(cx, genObj)) {
+          // This leaves `genObj` and `frameObj` unassociated. It's OK
+          // because we won't pause again with this generator on the stack:
+          // the caller will immediately discard `genObj` and unwind `frame`.
+          ok = false;
+          return;
+        }
+
+        DependentAddPtr genPtr(
+            cx, dbg->generatorFrames, genObj);
+        if (!genPtr.add(cx, dbg->generatorFrames, genObj, frameObj)) {
+          ok = false;
+        }
+      });
+
+  if (!ok) {
+    return false;
+  }
+
+  terminateDebuggerFramesGuard.release();
+  return true;
 }
 
 /* static */
@@ -1395,19 +1449,18 @@ bool Debugger::wrapDebuggeeObject(JSContext* cx, HandleObject obj,
   return true;
 }
 
-static NativeObject* ToNativeDebuggerObject(JSContext* cx,
-                                            MutableHandleObject obj) {
-  if (obj->getClass() != &DebuggerObject::class_) {
+static DebuggerObject* ToNativeDebuggerObject(JSContext* cx,
+                                              MutableHandleObject obj) {
+  if (!obj->is()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_NOT_EXPECTED_TYPE, "Debugger",
                               "Debugger.Object", obj->getClass()->name);
     return nullptr;
   }
 
-  NativeObject* ndobj = &obj->as();
+  DebuggerObject* ndobj = &obj->as();
 
-  Value owner = ndobj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER);
-  if (owner.isUndefined()) {
+  if (!ndobj->isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_PROTO,
                               "Debugger.Object", "Debugger.Object");
     return nullptr;
@@ -1417,19 +1470,18 @@ static NativeObject* ToNativeDebuggerObject(JSContext* cx,
 }
 
 bool Debugger::unwrapDebuggeeObject(JSContext* cx, MutableHandleObject obj) {
-  NativeObject* ndobj = ToNativeDebuggerObject(cx, obj);
+  DebuggerObject* ndobj = ToNativeDebuggerObject(cx, obj);
   if (!ndobj) {
     return false;
   }
 
-  Value owner = ndobj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER);
-  if (&owner.toObject() != object) {
+  if (ndobj->owner() != Debugger::fromJSObject(object)) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_DEBUG_WRONG_OWNER, "Debugger.Object");
     return false;
   }
 
-  obj.set(static_cast(ndobj->getPrivate()));
+  obj.set(ndobj->referent());
   return true;
 }
 
@@ -2587,7 +2639,7 @@ bool DebugAPI::onSingleStep(JSContext* cx) {
         continue;
       }
 
-      Debugger* dbg = Debugger::fromChildJSObject(frame);
+      Debugger* dbg = frame->owner();
       EnterDebuggeeNoExecute nx(cx, *dbg, adjqi);
 
       bool result = dbg->enterDebuggerHook(cx, [&]() -> bool {
@@ -2893,11 +2945,7 @@ class MOZ_RAII ExecutionObservableRealms
   HashSet zones_;
 
  public:
-  explicit ExecutionObservableRealms(
-      JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : realms_(cx), zones_(cx) {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-  }
+  explicit ExecutionObservableRealms(JSContext* cx) : realms_(cx), zones_(cx) {}
 
   bool add(Realm* realm) {
     return realms_.put(realm) && zones_.put(realm->zone());
@@ -2916,8 +2964,6 @@ class MOZ_RAII ExecutionObservableRealms
     // don't match.
     return iter.hasUsableAbstractFramePtr() && realms_.has(iter.realm());
   }
-
-  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 // Given a particular AbstractFramePtr F that has become observable, this
@@ -2929,11 +2975,7 @@ class MOZ_RAII ExecutionObservableFrame
   AbstractFramePtr frame_;
 
  public:
-  explicit ExecutionObservableFrame(
-      AbstractFramePtr frame MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : frame_(frame) {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-  }
+  explicit ExecutionObservableFrame(AbstractFramePtr frame) : frame_(frame) {}
 
   Zone* singleZone() const override {
     // We never inline across realms, let alone across zones, so
@@ -2985,8 +3027,6 @@ class MOZ_RAII ExecutionObservableFrame
     return iter.hasUsableAbstractFramePtr() &&
            iter.abstractFramePtr() == frame_;
   }
-
-  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 class MOZ_RAII ExecutionObservableScript
@@ -2994,11 +3034,8 @@ class MOZ_RAII ExecutionObservableScript
   RootedScript script_;
 
  public:
-  ExecutionObservableScript(JSContext* cx,
-                            JSScript* script MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : script_(cx, script) {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-  }
+  ExecutionObservableScript(JSContext* cx, JSScript* script)
+      : script_(cx, script) {}
 
   Zone* singleZone() const override { return script_->zone(); }
   JSScript* singleScriptForZoneInvalidation() const override { return script_; }
@@ -3021,8 +3058,6 @@ class MOZ_RAII ExecutionObservableScript
     return iter.hasUsableAbstractFramePtr() && !iter.isWasm() &&
            iter.abstractFramePtr().script() == script_;
   }
-
-  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /* static */
@@ -3203,11 +3238,37 @@ bool Debugger::updateExecutionObservabilityOfScripts(
 
 template 
 /* static */
-void Debugger::forEachDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
+void Debugger::forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
   for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
     Debugger* dbg = entry.dbg;
     if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
-      fn(frameEntry->value());
+      fn(dbg, frameEntry->value());
+    }
+  }
+}
+
+template 
+/* static */
+void Debugger::forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
+                                                      AbstractFramePtr frame,
+                                                      FrameFn fn) {
+  Rooted genObj(
+      cx, frame.isGeneratorFrame() ? GetGeneratorObjectForFrame(cx, frame)
+                                   : nullptr);
+
+  for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
+    Debugger* dbg = entry.dbg;
+
+    DebuggerFrame* frameObj = nullptr;
+    if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
+      frameObj = frameEntry->value();
+    } else if (GeneratorWeakMap::Ptr frameEntry =
+                   dbg->generatorFrames.lookup(genObj)) {
+      frameObj = frameEntry->value();
+    }
+
+    if (frameObj) {
+      fn(dbg, frameObj);
     }
   }
 }
@@ -3216,7 +3277,7 @@ void Debugger::forEachDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
 bool Debugger::getDebuggerFrames(AbstractFramePtr frame,
                                  MutableHandle frames) {
   bool hadOOM = false;
-  forEachDebuggerFrame(frame, [&](DebuggerFrame* frameobj) {
+  forEachOnStackDebuggerFrame(frame, [&](Debugger*, DebuggerFrame* frameobj) {
     if (!hadOOM && !frames.append(frameobj)) {
       hadOOM = true;
     }
@@ -3586,14 +3647,14 @@ bool DebugAPI::edgeIsInDebuggerWeakmap(JSRuntime* rt, JSObject* src,
     return false;
   }
 
-  Debugger* dbg = Debugger::fromChildJSObject(src);
-  MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
-
   if (src->is()) {
+    DebuggerFrame* frame = &src->as();
+    Debugger* dbg = frame->owner();
+    MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
+
     if (dst.is()) {
       // The generatorFrames map is not keyed on the associated JSScript. Get
       // the key from the source object and check everything matches.
-      DebuggerFrame* frame = &src->as();
       AbstractGeneratorObject* genObj = &frame->unwrappedGenerator();
       return frame->generatorScript() == &dst.as() &&
              dbg->generatorFrames.hasEntry(genObj, src);
@@ -3604,14 +3665,21 @@ bool DebugAPI::edgeIsInDebuggerWeakmap(JSRuntime* rt, JSObject* src,
                &dst.as().as(), src);
   }
   if (src->is()) {
+    Debugger* dbg = src->as().owner();
+    MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
     return dst.is() &&
            dbg->objects.hasEntry(&dst.as(), src);
   }
   if (src->is()) {
+    Debugger* dbg = src->as().owner();
+    MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
     return dst.is() &&
            dbg->environments.hasEntry(&dst.as(), src);
   }
   if (src->is()) {
+    Debugger* dbg = src->as().owner();
+    MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
+
     return src->as().getReferent().match(
         [=](BaseScript* script) {
           return dst.is() && script == &dst.as() &&
@@ -3623,6 +3691,9 @@ bool DebugAPI::edgeIsInDebuggerWeakmap(JSRuntime* rt, JSObject* src,
         });
   }
   if (src->is()) {
+    Debugger* dbg = src->as().owner();
+    MOZ_ASSERT(RuntimeHasDebugger(rt, dbg));
+
     return src->as().getReferent().match(
         [=](ScriptSourceObject* sso) {
           return dst.is() && sso == &dst.as() &&
@@ -3811,7 +3882,16 @@ void DebugAPI::sweepAll(JSFreeOp* fop) {
            e.popFront()) {
         DebuggerFrame* frameObj = e.front().value();
         if (IsAboutToBeFinalizedUnbarriered(&frameObj)) {
-          frameObj->clearGeneratorInfo(fop, dbg, &e);
+          // If the DebuggerFrame is being finalized, that means either:
+          //  1) It is not present in "frames".
+          //  2) The Debugger itself is also being finalized.
+          //
+          // In the first case, passing the frame is not necessary because there
+          // isn't a frame entry to clear, and in the second case,
+          // removeDebuggeeGlobal below will iterate and remove the entries
+          // anyway, so things will be cleaned up properly.
+          Debugger::terminateDebuggerFrame(fop, dbg, frameObj, NullFramePtr(),
+                                           nullptr, &e);
         }
       }
     }
@@ -3837,17 +3917,6 @@ void DebugAPI::sweepAll(JSFreeOp* fop) {
   }
 }
 
-/* static */
-void Debugger::detachAllDebuggersFromGlobal(JSFreeOp* fop,
-                                            GlobalObject* global) {
-  const Realm::DebuggerVector& debuggers = global->getDebuggers();
-  MOZ_ASSERT(!debuggers.empty());
-  while (!debuggers.empty()) {
-    debuggers.back().dbg->removeDebuggeeGlobal(fop, global, nullptr,
-                                               Debugger::FromSweep::No);
-  }
-}
-
 static inline bool SweepZonesInSameGroup(Zone* a, Zone* b) {
   // Ensure two zones are swept in the same sweep group by adding an edge
   // between them in each direction.
@@ -4060,6 +4129,38 @@ bool Debugger::setHookImpl(JSContext* cx, const CallArgs& args, Debugger& dbg,
   return true;
 }
 
+/* static */
+bool Debugger::getGarbageCollectionHook(JSContext* cx, const CallArgs& args,
+                                        Debugger& dbg) {
+  return getHookImpl(cx, args, dbg, OnGarbageCollection);
+}
+
+/* static */
+bool Debugger::setGarbageCollectionHook(JSContext* cx, const CallArgs& args,
+                                        Debugger& dbg) {
+  Rooted oldHook(cx, dbg.getHook(OnGarbageCollection));
+
+  if (!setHookImpl(cx, args, dbg, OnGarbageCollection)) {
+    // We want to maintain the invariant that the hook is always set when the
+    // Debugger is in the runtime's list, and vice-versa, so if we return early
+    // and don't adjust the watcher list below, we need to be sure that the
+    // hook didn't change.
+    MOZ_ASSERT(dbg.getHook(OnGarbageCollection) == oldHook);
+    return false;
+  }
+
+  // Add or remove ourselves from the runtime's list of Debuggers that care
+  // about garbage collection.
+  JSObject* newHook = dbg.getHook(OnGarbageCollection);
+  if (!oldHook && newHook) {
+    cx->runtime()->onGarbageCollectionWatchers().pushBack(&dbg);
+  } else if (oldHook && !newHook) {
+    cx->runtime()->onGarbageCollectionWatchers().remove(&dbg);
+  }
+
+  return true;
+}
+
 bool Debugger::CallData::getOnDebuggerStatement() {
   return getHookImpl(cx, args, *dbg, OnDebuggerStatement);
 }
@@ -4433,11 +4534,15 @@ bool Debugger::CallData::getNewestFrame() {
 }
 
 bool Debugger::CallData::clearAllBreakpoints() {
-  for (WeakGlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty();
-       r.popFront()) {
-    DebugScript::clearBreakpointsIn(cx->runtime()->defaultFreeOp(),
-                                    r.front()->realm(), dbg, nullptr);
+  JSFreeOp* fop = cx->defaultFreeOp();
+  Breakpoint* nextbp;
+  for (Breakpoint* bp = dbg->firstBreakpoint(); bp; bp = nextbp) {
+    nextbp = bp->nextInDebugger();
+
+    bp->remove(fop);
   }
+  MOZ_ASSERT(!dbg->firstBreakpoint());
+
   return true;
 }
 
@@ -4676,23 +4781,6 @@ void Debugger::removeDebuggeeGlobal(JSFreeOp* fop, GlobalObject* global,
   MOZ_ASSERT(debuggeeZones.has(global->zone()));
   MOZ_ASSERT_IF(debugEnum, debugEnum->front().unbarrieredGet() == global);
 
-  // FIXME Debugger::slowPathOnLeaveFrame needs to kill all Debugger.Frame
-  // objects referring to a particular JS stack frame. This is hard if
-  // Debugger objects that are no longer debugging the relevant global might
-  // have live Frame objects. So we take the easy way out and kill them here.
-  // This is a bug, since it's observable and contrary to the spec. One
-  // possible fix would be to put such objects into a compartment-wide bag
-  // which slowPathOnLeaveFrame would have to examine.
-  for (FrameMap::Enum e(frames); !e.empty(); e.popFront()) {
-    AbstractFramePtr frame = e.front().key();
-    DebuggerFrame* frameobj = e.front().value();
-    if (frame.hasGlobal(global)) {
-      frameobj->freeFrameIterData(fop);
-      frameobj->maybeDecrementStepperCounter(fop, frame);
-      e.removeFront();
-    }
-  }
-
   // Clear this global's generators from generatorFrames as well.
   //
   // This method can be called either from script (dbg.removeDebuggee) or during
@@ -4708,13 +4796,20 @@ void Debugger::removeDebuggeeGlobal(JSFreeOp* fop, GlobalObject* global,
   if (fromSweep == FromSweep::No) {
     for (GeneratorWeakMap::Enum e(generatorFrames); !e.empty(); e.popFront()) {
       AbstractGeneratorObject& genObj = *e.front().key();
-      DebuggerFrame& frameObj = *e.front().value();
-      if (genObj.isClosed() || &genObj.callee().global() == global) {
-        frameObj.clearGeneratorInfo(fop, this, &e);
+      if (&genObj.global() == global) {
+        terminateDebuggerFrame(fop, this, e.front().value(), NullFramePtr(),
+                               nullptr, &e);
       }
     }
   }
 
+  for (FrameMap::Enum e(frames); !e.empty(); e.popFront()) {
+    AbstractFramePtr frame = e.front().key();
+    if (frame.hasGlobal(global)) {
+      terminateDebuggerFrame(fop, this, e.front().value(), frame, &e);
+    }
+  }
+
   auto& globalDebuggersVector = global->getDebuggers();
 
   // The relation must be removed from up to three places:
@@ -4893,14 +4988,13 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase {
         return false;
       }
 
-      Value owner =
-          debuggerSource.toObject().as().getReservedSlot(
-              DebuggerSource::OWNER_SLOT);
+      DebuggerSource& debuggerSourceObj =
+          debuggerSource.toObject().as();
 
       // The given source must have an owner. Otherwise, it's a
       // Debugger.Source.prototype, which would match no scripts, and is
       // probably a mistake.
-      if (!owner.isObject()) {
+      if (!debuggerSourceObj.isInstance()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                   JSMSG_DEBUG_PROTO, "Debugger.Source",
                                   "Debugger.Source");
@@ -4910,14 +5004,14 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase {
       // If it does have an owner, it should match the Debugger we're
       // calling findScripts on. It would work fine even if it didn't,
       // but mixing Debugger.Sources is probably a sign of confusion.
-      if (&owner.toObject() != debugger->object) {
+      if (debuggerSourceObj.owner() != debugger) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                   JSMSG_DEBUG_WRONG_OWNER, "Debugger.Source");
         return false;
       }
 
       hasSource = true;
-      source = debuggerSource.toObject().as().getReferent();
+      source = debuggerSourceObj.getReferent();
     }
 
     // Check for a 'displayURL' property.
@@ -5865,16 +5959,20 @@ bool Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp) {
   bool result = true;
 
   CompileOptions options(cx);
-  LifoAllocScope allocScope(&cx->tempLifoAlloc());
-  frontend::CompilationInfo compilationInfo(cx, allocScope, options);
-  if (!compilationInfo.init(cx)) {
+  Rooted compilationInfo(
+      cx, frontend::CompilationInfo(cx, options));
+  if (!compilationInfo.get().input.initForGlobal(cx)) {
     return false;
   }
 
+  LifoAllocScope allocScope(&cx->tempLifoAlloc());
+  frontend::CompilationState compilationState(cx, allocScope, options);
+
   JS::AutoSuppressWarningReporter suppressWarnings(cx);
   frontend::Parser parser(
       cx, options, chars.twoByteChars(), length,
-      /* foldConstants = */ true, compilationInfo, nullptr, nullptr);
+      /* foldConstants = */ true, compilationInfo.get(), compilationState,
+      nullptr, nullptr);
   if (!parser.checkOptions() || !parser.parse()) {
     // We ran into an error. If it was because we ran out of memory we report
     // it in the usual way.
@@ -5903,12 +6001,12 @@ bool Debugger::CallData::adoptDebuggeeValue() {
   RootedValue v(cx, args[0]);
   if (v.isObject()) {
     RootedObject obj(cx, &v.toObject());
-    NativeObject* ndobj = ToNativeDebuggerObject(cx, &obj);
+    DebuggerObject* ndobj = ToNativeDebuggerObject(cx, &obj);
     if (!ndobj) {
       return false;
     }
 
-    obj.set(static_cast(ndobj->getPrivate()));
+    obj.set(ndobj->referent());
     v = ObjectValue(*obj);
 
     if (!dbg->wrapDebuggeeValue(cx, &v)) {
@@ -6177,19 +6275,20 @@ bool Debugger::observesWasm(wasm::Instance* instance) const {
 /* static */
 bool Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from,
                                 AbstractFramePtr to, ScriptFrameIter& iter) {
-  auto removeFromDebuggerFramesOnExit = MakeScopeExit([&] {
-    // Remove any remaining old entries on exit, as the 'from' frame will
-    // be gone. This is only done in the failure case. On failure, the
-    // removeToDebuggerFramesOnExit lambda below will rollback any frames
-    // that were replaced, resulting in !frameMaps(to). On success, the
-    // range will be empty, as all from Frame.Debugger instances will have
-    // been removed.
-    MOZ_ASSERT_IF(DebugAPI::inFrameMaps(to), !DebugAPI::inFrameMaps(from));
-    removeFromFrameMapsAndClearBreakpointsIn(cx, from);
-
-    // Rekey missingScopes to maintain Debugger.Environment identity and
-    // forward liveScopes to point to the new frame.
-    DebugEnvironments::forwardLiveFrame(cx, from, to);
+  MOZ_ASSERT(from != to);
+
+  // Rekey missingScopes to maintain Debugger.Environment identity and
+  // forward liveScopes to point to the new frame.
+  DebugEnvironments::forwardLiveFrame(cx, from, to);
+
+  // If we hit an OOM anywhere in here, we need to make sure there aren't any
+  // Debugger.Frame objects left partially-initialized.
+  auto terminateDebuggerFramesOnExit = MakeScopeExit([&] {
+    terminateDebuggerFrames(cx, from);
+    terminateDebuggerFrames(cx, to);
+
+    MOZ_ASSERT(!DebugAPI::inFrameMaps(from));
+    MOZ_ASSERT(!DebugAPI::inFrameMaps(to));
   });
 
   // Forward live Debugger.Frame objects.
@@ -6197,103 +6296,75 @@ bool Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from,
   if (!getDebuggerFrames(from, &frames)) {
     // An OOM here means that all Debuggers' frame maps still contain
     // entries for 'from' and no entries for 'to'. Since the 'from' frame
-    // will be gone, they are removed by removeFromDebuggerFramesOnExit
+    // will be gone, they are removed by terminateDebuggerFramesOnExit
     // above.
     return false;
   }
 
-  // If during the loop below we hit an OOM, we must also rollback any of
-  // the frames that were successfully replaced. For OSR frames, OOM here
-  // means those frames will pop from the OSR trampoline, which does not
-  // call Debugger::onLeaveFrame.
-  auto removeToDebuggerFramesOnExit =
-      MakeScopeExit([&] { removeFromFrameMapsAndClearBreakpointsIn(cx, to); });
-
   for (size_t i = 0; i < frames.length(); i++) {
     HandleDebuggerFrame frameobj = frames[i];
-    Debugger* dbg = Debugger::fromChildJSObject(frameobj);
+    Debugger* dbg = frameobj->owner();
 
     // Update frame object's ScriptFrameIter::data pointer.
-    frameobj->freeFrameIterData(cx->runtime()->defaultFreeOp());
-    ScriptFrameIter::Data* data = iter.copyData();
-    if (!data) {
-      // An OOM here means that some Debuggers' frame maps may still
-      // contain entries for 'from' and some Debuggers' frame maps may
-      // also contain entries for 'to'. Thus both
-      // removeFromDebuggerFramesOnExit and
-      // removeToDebuggerFramesOnExit must both run.
-      //
-      // The current frameobj in question is still in its Debugger's
-      // frame map keyed by 'from', so it will be covered by
-      // removeFromDebuggerFramesOnExit.
+    if (!frameobj->replaceFrameIterData(cx, iter)) {
       return false;
     }
-    frameobj->setFrameIterData(data);
-
-    // Remove old frame.
-    dbg->frames.remove(from);
 
     // Add the frame object with |to| as key.
     if (!dbg->frames.putNew(to, frameobj)) {
-      // This OOM is subtle. At this point, both
-      // removeFromDebuggerFramesOnExit and removeToDebuggerFramesOnExit
-      // must both run for the same reason given above.
-      //
-      // The difference is that the current frameobj is no longer in its
-      // Debugger's frame map, so it will not be cleaned up by neither
-      // lambda. Manually clean it up here.
-      JSFreeOp* fop = cx->runtime()->defaultFreeOp();
-      frameobj->freeFrameIterData(fop);
-      frameobj->maybeDecrementStepperCounter(fop, to);
-
       ReportOutOfMemory(cx);
       return false;
     }
+
+    // Remove the old frame entry after all fallible operations are completed
+    // so that an OOM will be able to clean up properly.
+    dbg->frames.remove(from);
   }
 
   // All frames successfuly replaced, cancel the rollback.
-  removeToDebuggerFramesOnExit.release();
+  terminateDebuggerFramesOnExit.release();
 
+  MOZ_ASSERT(!DebugAPI::inFrameMaps(from));
+  MOZ_ASSERT_IF(!frames.empty(), DebugAPI::inFrameMaps(to));
   return true;
 }
 
 /* static */
 bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
   bool foundAny = false;
-  Debugger::forEachDebuggerFrame(
-      frame, [&](DebuggerFrame* frameobj) { foundAny = true; });
+  Debugger::forEachOnStackDebuggerFrame(
+      frame, [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
   return foundAny;
 }
 
 /* static */
-void Debugger::removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx,
-                                                        AbstractFramePtr frame,
-                                                        bool suspending) {
-  forEachDebuggerFrame(frame, [&](DebuggerFrame* frameobj) {
-    JSFreeOp* fop = cx->runtime()->defaultFreeOp();
-    frameobj->freeFrameIterData(fop);
-
-    Debugger* dbg = Debugger::fromChildJSObject(frameobj);
-    dbg->frames.remove(frame);
-
-    if (frameobj->hasGeneratorInfo()) {
-      // If this is a generator's final pop, remove its entry from
-      // generatorFrames. Such an entry exists if and only if the
-      // Debugger.Frame's generator has been set.
-      if (!suspending) {
-        // Terminally exiting a generator.
+void Debugger::suspendGeneratorDebuggerFrames(JSContext* cx,
+                                              AbstractFramePtr frame) {
+  JSFreeOp* fop = cx->runtime()->defaultFreeOp();
+  forEachOnStackDebuggerFrame(
+      frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
+        dbg->frames.remove(frame);
+
 #if DEBUG
-        AbstractGeneratorObject& genObj = frameobj->unwrappedGenerator();
+        MOZ_ASSERT(dbgFrame->hasGeneratorInfo());
+        AbstractGeneratorObject& genObj = dbgFrame->unwrappedGenerator();
         GeneratorWeakMap::Ptr p = dbg->generatorFrames.lookup(&genObj);
         MOZ_ASSERT(p);
-        MOZ_ASSERT(p->value() == frameobj);
+        MOZ_ASSERT(p->value() == dbgFrame);
 #endif
-        frameobj->clearGeneratorInfo(fop, dbg);
-      }
-    } else {
-      frameobj->maybeDecrementStepperCounter(fop, frame);
-    }
-  });
+
+        dbgFrame->suspend(fop);
+      });
+}
+
+/* static */
+void Debugger::terminateDebuggerFrames(JSContext* cx, AbstractFramePtr frame) {
+  JSFreeOp* fop = cx->runtime()->defaultFreeOp();
+
+  forEachOnStackOrSuspendedDebuggerFrame(
+      cx, frame, [&](Debugger* dbg, DebuggerFrame* dbgFrame) {
+        Debugger::terminateDebuggerFrame(fop, dbg, dbgFrame, frame);
+      });
 
   // If this is an eval frame, then from the debugger's perspective the
   // script is about to be destroyed. Remove any breakpoints in it.
@@ -6304,6 +6375,38 @@ void Debugger::removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx,
   }
 }
 
+/* static */
+void Debugger::terminateDebuggerFrame(
+    JSFreeOp* fop, Debugger* dbg, DebuggerFrame* dbgFrame,
+    AbstractFramePtr frame, FrameMap::Enum* maybeFramesEnum,
+    GeneratorWeakMap::Enum* maybeGeneratorFramesEnum) {
+  // If we were not passed the frame, either we are destroying a frame early
+  // on before it was inserted into the "frames" list, or else we are
+  // terminating a frame from "generatorFrames" and the "frames" entries will
+  // be cleaned up later on with a second call to this function.
+  MOZ_ASSERT_IF(!frame, !maybeFramesEnum);
+  MOZ_ASSERT_IF(!frame, dbgFrame->hasGeneratorInfo());
+  MOZ_ASSERT_IF(!dbgFrame->hasGeneratorInfo(), !maybeGeneratorFramesEnum);
+
+  if (frame) {
+    if (maybeFramesEnum) {
+      maybeFramesEnum->removeFront();
+    } else {
+      dbg->frames.remove(frame);
+    }
+  }
+
+  if (dbgFrame->hasGeneratorInfo()) {
+    if (maybeGeneratorFramesEnum) {
+      maybeGeneratorFramesEnum->removeFront();
+    } else {
+      dbg->generatorFrames.remove(&dbgFrame->unwrappedGenerator());
+    }
+  }
+
+  dbgFrame->terminate(fop, frame);
+}
+
 DebuggerDebuggeeLink* Debugger::getDebuggeeLink() {
   return &object->getReservedSlot(JSSLOT_DEBUG_DEBUGGEE_LINK)
               .toObject()
@@ -6353,7 +6456,7 @@ void DebugAPI::handleUnrecoverableIonBailoutError(
   // Ion bailout can fail due to overrecursion. In such cases we cannot
   // honor any further Debugger hooks on the frame, and need to ensure that
   // its Debugger.Frame entry is cleaned up.
-  Debugger::removeFromFrameMapsAndClearBreakpointsIn(cx, frame);
+  Debugger::terminateDebuggerFrames(cx, frame);
 }
 
 /*** JS::dbg::Builder *******************************************************/
@@ -6548,10 +6651,9 @@ bool Debugger::isDebuggerCrossCompartmentEdge(JSObject* obj,
   } else if (obj->is()) {
     referent = obj->as().getReferentRawObject();
   } else if (obj->is()) {
-    referent = static_cast(obj->as().getPrivate());
+    referent = obj->as().referent();
   } else if (obj->is()) {
-    referent =
-        static_cast(obj->as().getPrivate());
+    referent = obj->as().referent();
   }
 
   return referent == target;
@@ -6676,9 +6778,9 @@ JSObject* GarbageCollectionEvent::toJSObject(JSContext* cx) const {
 JS_PUBLIC_API bool FireOnGarbageCollectionHookRequired(JSContext* cx) {
   AutoCheckCannotGC noGC;
 
-  for (Debugger* dbg : cx->runtime()->debuggerList()) {
-    if (dbg->observedGC(cx->runtime()->gc.majorGCCount()) &&
-        dbg->getHook(Debugger::OnGarbageCollection)) {
+  for (auto& dbg : cx->runtime()->onGarbageCollectionWatchers()) {
+    MOZ_ASSERT(dbg.getHook(Debugger::OnGarbageCollection));
+    if (dbg.observedGC(cx->runtime()->gc.majorGCCount())) {
       return true;
     }
   }
@@ -6696,10 +6798,10 @@ JS_PUBLIC_API bool FireOnGarbageCollectionHook(
     // participated in this GC.
     AutoCheckCannotGC noGC;
 
-    for (Debugger* dbg : cx->runtime()->debuggerList()) {
-      if (dbg->observedGC(data->majorGCNumber()) &&
-          dbg->getHook(Debugger::OnGarbageCollection)) {
-        if (!triggered.append(dbg->object)) {
+    for (auto& dbg : cx->runtime()->onGarbageCollectionWatchers()) {
+      MOZ_ASSERT(dbg.getHook(Debugger::OnGarbageCollection));
+      if (dbg.observedGC(data->majorGCNumber())) {
+        if (!triggered.append(dbg.object)) {
           JS_ReportOutOfMemory(cx);
           return false;
         }
@@ -6710,10 +6812,12 @@ JS_PUBLIC_API bool FireOnGarbageCollectionHook(
   for (; !triggered.empty(); triggered.popBack()) {
     Debugger* dbg = Debugger::fromJSObject(triggered.back());
 
-    mozilla::Unused << dbg->enterDebuggerHook(cx, [&]() -> bool {
-      return dbg->fireOnGarbageCollectionHook(cx, data);
-    });
-    MOZ_ASSERT(!cx->isExceptionPending());
+    if (dbg->getHook(Debugger::OnGarbageCollection)) {
+      mozilla::Unused << dbg->enterDebuggerHook(cx, [&]() -> bool {
+        return dbg->fireOnGarbageCollectionHook(cx, data);
+      });
+      MOZ_ASSERT(!cx->isExceptionPending());
+    }
   }
 
   return true;
diff --git a/js/src/debugger/Debugger.h b/js/src/debugger/Debugger.h
index c1ecf38a61..e65eb4b8dd 100644
--- a/js/src/debugger/Debugger.h
+++ b/js/src/debugger/Debugger.h
@@ -11,7 +11,6 @@
 #include "mozilla/HashTable.h"         // for HashSet, DefaultHasher (ptr only)
 #include "mozilla/LinkedList.h"        // for LinkedList (ptr only)
 #include "mozilla/Maybe.h"             // for Maybe, Nothing
-#include "mozilla/Move.h"              // for std::move
 #include "mozilla/Range.h"             // for Range
 #include "mozilla/Result.h"            // for Result
 #include "mozilla/TimeStamp.h"         // for TimeStamp
@@ -19,11 +18,12 @@
 
 #include   // for size_t
 #include   // for uint32_t, uint64_t, uintptr_t
+#include    // for std::move
 
-#include "jsapi.h"    // for Handle, UnsafeTraceRoot
-#include "jstypes.h"  // for JS_GC_ZEAL
+#include "jsapi.h"             // for Handle, UnsafeTraceRoot
+#include "jstypes.h"           // for JS_GC_ZEAL
+#include "NamespaceImports.h"  // for Value, HandleObject
 
-#include "NamespaceImports.h"       // for Value, HandleObject
 #include "debugger/DebugAPI.h"      // for DebugAPI
 #include "debugger/Object.h"        // for DebuggerObject
 #include "ds/TraceableFifo.h"       // for TraceableFifo
@@ -393,13 +393,8 @@ class DebuggerWeakMap : private WeakMap, HeapPtr> {
  public:
   void traceCrossCompartmentEdges(JSTracer* tracer) {
     for (Enum e(*this); !e.empty(); e.popFront()) {
+      TraceEdge(tracer, &e.front().mutableKey(), "Debugger WeakMap key");
       e.front().value()->trace(tracer);
-      Key key = e.front().key();
-      TraceEdge(tracer, &key, "Debugger WeakMap key");
-      if (key != e.front().key()) {
-        e.rekeyFront(key);
-      }
-      key.unsafeSet(nullptr);
     }
   }
 
@@ -516,6 +511,7 @@ class Debugger : private mozilla::LinkedListElement {
   template 
   friend class DebuggerList;
   friend struct JSRuntime::GlobalObjectWatchersLinkAccess;
+  friend struct JSRuntime::GarbageCollectionWatchersLinkAccess;
   friend class SavedStacks;
   friend class ScriptedOnStepHandler;
   friend class ScriptedOnPopHandler;
@@ -610,15 +606,6 @@ class Debugger : private mozilla::LinkedListElement {
     }
   };
 
-  // Barrier methods so we can have WeakHeapPtr.
-  static void readBarrier(Debugger* dbg) {
-    InternalBarrierMethods::readBarrier(dbg->object);
-  }
-  static void writeBarrierPost(Debugger** vp, Debugger* prev, Debugger* next) {}
-#ifdef DEBUG
-  static void assertThingIsNotGray(Debugger* dbg) { return; }
-#endif
-
  private:
   GCPtrNativeObject object; /* The Debugger object. Strong reference. */
   WeakGlobalObjectSet
@@ -703,6 +690,13 @@ class Debugger : private mozilla::LinkedListElement {
    */
   mozilla::DoublyLinkedListElement onNewGlobalObjectWatchersLink;
 
+  /*
+   * If this Debugger has a onGarbageCollection handler, then
+   * this link is inserted into the list headed by
+   * JSRuntime::onGarbageCollectionWatchers.
+   */
+  mozilla::DoublyLinkedListElement onGarbageCollectionWatchersLink;
+
   /*
    * Map from stack frames that are currently on the stack to Debugger.Frame
    * instances.
@@ -883,6 +877,13 @@ class Debugger : private mozilla::LinkedListElement {
   static MOZ_MUST_USE bool setHookImpl(JSContext* cx, const CallArgs& args,
                                        Debugger& dbg, Hook which);
 
+  static MOZ_MUST_USE bool getGarbageCollectionHook(JSContext* cx,
+                                                    const CallArgs& args,
+                                                    Debugger& dbg);
+  static MOZ_MUST_USE bool setGarbageCollectionHook(JSContext* cx,
+                                                    const CallArgs& args,
+                                                    Debugger& dbg);
+
   static bool isCompilableUnit(JSContext* cx, unsigned argc, Value* vp);
   static bool construct(JSContext* cx, unsigned argc, Value* vp);
 
@@ -892,9 +893,35 @@ class Debugger : private mozilla::LinkedListElement {
   static const JSFunctionSpec methods[];
   static const JSFunctionSpec static_methods[];
 
-  static void removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx,
-                                                       AbstractFramePtr frame,
-                                                       bool suspending = false);
+  /**
+   * Suspend the DebuggerFrame, clearing on-stack data but leaving it linked
+   * with the AbstractGeneratorObject so it can be re-used later.
+   */
+  static void suspendGeneratorDebuggerFrames(JSContext* cx,
+                                             AbstractFramePtr frame);
+
+  /**
+   * Terminate the DebuggerFrame, clearing all data associated with the frame
+   * so that it cannot be used to introspect stack frame data.
+   */
+  static void terminateDebuggerFrames(JSContext* cx, AbstractFramePtr frame);
+
+  /**
+   * Terminate a given DebuggerFrame, removing all internal state and all
+   * references to the frame from the Debugger itself. If the frame is being
+   * terminated while 'frames' or 'generatorFrames' are being iterated, pass a
+   * pointer to the iteration Enum to remove the entry and ensure that iteration
+   * behaves properly.
+   *
+   * The AbstractFramePtr may be omited in a call so long as it is either
+   * called again later with the correct 'frame', or the frame itself has never
+   * had on-stack data or a 'frames' entry and has never had an onStep handler.
+   */
+  static void terminateDebuggerFrame(
+      JSFreeOp* fop, Debugger* dbg, DebuggerFrame* dbgFrame,
+      AbstractFramePtr frame, FrameMap::Enum* maybeFramesEnum = nullptr,
+      GeneratorWeakMap::Enum* maybeGeneratorFramesEnum = nullptr);
+
   static bool updateExecutionObservabilityOfFrames(
       JSContext* cx, const DebugAPI::ExecutionObservableSet& obs,
       IsObserving observing);
@@ -905,8 +932,12 @@ class Debugger : private mozilla::LinkedListElement {
       JSContext* cx, DebugAPI::ExecutionObservableSet& obs,
       IsObserving observing);
 
-  template 
-  static void forEachDebuggerFrame(AbstractFramePtr frame, FrameFn fn);
+  template 
+  static void forEachOnStackDebuggerFrame(AbstractFramePtr frame, FrameFn fn);
+  template 
+  static void forEachOnStackOrSuspendedDebuggerFrame(JSContext* cx,
+                                                     AbstractFramePtr frame,
+                                                     FrameFn fn);
 
   /*
    * Return a vector containing all Debugger.Frame instances referring to
@@ -1072,7 +1103,6 @@ class Debugger : private mozilla::LinkedListElement {
 #ifdef DEBUG
   static bool isChildJSObject(JSObject* obj);
 #endif
-  static Debugger* fromChildJSObject(JSObject* obj);
 
   Zone* zone() const { return toJSObject()->zone(); }
 
@@ -1081,7 +1111,6 @@ class Debugger : private mozilla::LinkedListElement {
 
   WeakGlobalObjectSet::Range allDebuggees() const { return debuggees.all(); }
 
-  static void detachAllDebuggersFromGlobal(JSFreeOp* fop, GlobalObject* global);
 #ifdef DEBUG
   static bool isDebuggerCrossCompartmentEdge(JSObject* obj,
                                              const js::gc::Cell* cell);
@@ -1224,6 +1253,22 @@ class Debugger : private mozilla::LinkedListElement {
   Debugger& operator=(const Debugger&) = delete;
 };
 
+// Specialize InternalBarrierMethods so we can have WeakHeapPtr.
+template <>
+struct InternalBarrierMethods {
+  static bool isMarkable(Debugger* dbg) { return dbg->toJSObject(); }
+
+  static void postBarrier(Debugger** vp, Debugger* prev, Debugger* next) {}
+
+  static void readBarrier(Debugger* dbg) {
+    InternalBarrierMethods::readBarrier(dbg->toJSObject());
+  }
+
+#ifdef DEBUG
+  static void assertThingIsNotGray(Debugger* dbg) {}
+#endif
+};
+
 /**
  * This class exists for one specific reason. If a given Debugger object is in
  * a state where:
@@ -1542,6 +1587,7 @@ MOZ_MUST_USE bool ReportObjectRequired(JSContext* cx);
 JSObject* IdVectorToArray(JSContext* cx, Handle ids);
 bool IsInterpretedNonSelfHostedFunction(JSFunction* fun);
 JSScript* GetOrCreateFunctionScript(JSContext* cx, HandleFunction fun);
+ArrayObject* GetFunctionParameterNamesArray(JSContext* cx, HandleFunction fun);
 bool ValueToIdentifier(JSContext* cx, HandleValue v, MutableHandleId id);
 bool ValueToStableChars(JSContext* cx, const char* fnname, HandleValue value,
                         JS::AutoStableStringChars& stableChars);
diff --git a/js/src/debugger/DebuggerMemory.cpp b/js/src/debugger/DebuggerMemory.cpp
index 5fcb3e4f97..9526cf3fb1 100644
--- a/js/src/debugger/DebuggerMemory.cpp
+++ b/js/src/debugger/DebuggerMemory.cpp
@@ -5,10 +5,10 @@
 #include "debugger/DebuggerMemory.h"
 
 #include "mozilla/Maybe.h"
-#include "mozilla/Move.h"
 #include "mozilla/Vector.h"
 
 #include 
+#include 
 
 #include "builtin/MapObject.h"
 #include "debugger/Debugger.h"
@@ -348,13 +348,11 @@ bool DebuggerMemory::CallData::getAllocationsLogOverflowed() {
 }
 
 bool DebuggerMemory::CallData::getOnGarbageCollection() {
-  return Debugger::getHookImpl(cx, args, *memory->getDebugger(),
-                               Debugger::OnGarbageCollection);
+  return Debugger::getGarbageCollectionHook(cx, args, *memory->getDebugger());
 }
 
 bool DebuggerMemory::CallData::setOnGarbageCollection() {
-  return Debugger::setHookImpl(cx, args, *memory->getDebugger(),
-                               Debugger::OnGarbageCollection);
+  return Debugger::setGarbageCollectionHook(cx, args, *memory->getDebugger());
 }
 
 /* Debugger.Memory.prototype.takeCensus */
diff --git a/js/src/debugger/Environment-inl.h b/js/src/debugger/Environment-inl.h
index d779626dfa..4543709718 100644
--- a/js/src/debugger/Environment-inl.h
+++ b/js/src/debugger/Environment-inl.h
@@ -15,7 +15,15 @@
 
 class JS_PUBLIC_API JSObject;
 
+// The Debugger.Environment.prototype object also has a class of
+// DebuggerEnvironment::class_ so we differentiate instances from the prototype
+// based on the presence of an owner debugger.
+inline bool js::DebuggerEnvironment::isInstance() const {
+  return !getReservedSlot(OWNER_SLOT).isUndefined();
+}
+
 inline js::Debugger* js::DebuggerEnvironment::owner() const {
+  MOZ_ASSERT(isInstance());
   JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
   return Debugger::fromJSObject(dbgobj);
 }
diff --git a/js/src/debugger/Environment.cpp b/js/src/debugger/Environment.cpp
index 3c34cb6654..61d9779332 100644
--- a/js/src/debugger/Environment.cpp
+++ b/js/src/debugger/Environment.cpp
@@ -21,7 +21,6 @@
 #include "gc/Tracer.h"       // for TraceManuallyBarrieredCrossCompartmentEdge
 #include "js/HeapAPI.h"      // for IsInsideNursery
 #include "vm/Compartment.h"  // for Compartment
-#include "vm/EnvironmentObject.h"  // for JSObject::is, DebugEnvironmentProxy
 #include "vm/JSAtom.h"             // for Atomize, PinAtom
 #include "vm/JSContext.h"          // for JSContext
 #include "vm/JSFunction.h"         // for JSFunction
@@ -86,7 +85,7 @@ static DebuggerEnvironment* DebuggerEnvironment_checkThis(
   if (!thisobj) {
     return nullptr;
   }
-  if (thisobj->getClass() != &DebuggerEnvironment::class_) {
+  if (!thisobj->is()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Environment",
                               "method", thisobj->getClass()->name);
@@ -95,9 +94,8 @@ static DebuggerEnvironment* DebuggerEnvironment_checkThis(
 
   // Forbid Debugger.Environment.prototype, which is of class
   // DebuggerEnvironment::class_ but isn't a real working Debugger.Environment.
-  // The prototype object is distinguished by having no referent.
   DebuggerEnvironment* nthisobj = &thisobj->as();
-  if (!nthisobj->getPrivate()) {
+  if (!nthisobj->isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Environment",
                               "method", "prototype object");
diff --git a/js/src/debugger/Environment.h b/js/src/debugger/Environment.h
index cd1c18504e..dc11cabf5f 100644
--- a/js/src/debugger/Environment.h
+++ b/js/src/debugger/Environment.h
@@ -69,11 +69,8 @@ class DebuggerEnvironment : public NativeObject {
                                        HandleDebuggerEnvironment environment,
                                        HandleId id, HandleValue value);
 
- private:
-  static const JSClassOps classOps_;
-
-  static const JSPropertySpec properties_[];
-  static const JSFunctionSpec methods_[];
+  bool isInstance() const;
+  Debugger* owner() const;
 
   Env* referent() const {
     Env* env = static_cast(getPrivate());
@@ -81,7 +78,11 @@ class DebuggerEnvironment : public NativeObject {
     return env;
   }
 
-  Debugger* owner() const;
+ private:
+  static const JSClassOps classOps_;
+
+  static const JSPropertySpec properties_[];
+  static const JSFunctionSpec methods_[];
 
   bool requireDebuggee(JSContext* cx) const;
 
diff --git a/js/src/debugger/Frame.cpp b/js/src/debugger/Frame.cpp
index 72d1aa539c..07c958c31e 100644
--- a/js/src/debugger/Frame.cpp
+++ b/js/src/debugger/Frame.cpp
@@ -7,7 +7,6 @@
 #include "mozilla/Assertions.h"   // for AssertionConditionType
 #include "mozilla/HashTable.h"    // for HashMapEntry
 #include "mozilla/Maybe.h"        // for Maybe
-#include "mozilla/Move.h"         // for std::move
 #include "mozilla/Range.h"        // for Range
 #include "mozilla/RangedPtr.h"    // for RangedPtr
 #include "mozilla/Result.h"       // for Result
@@ -18,6 +17,7 @@
 #include   // for size_t
 #include   // for int32_t
 #include   // for strlen
+#include    // for std::move
 
 #include "jsapi.h"        // for CallArgs, Handle
 #include "jsfriendapi.h"  // for GetErrorMessage
@@ -31,44 +31,46 @@
 #include "debugger/Object.h"               // for DebuggerObject
 #include "debugger/Script.h"               // for DebuggerScript
 #include "frontend/BytecodeCompilation.h"  // for CompileEvalScript
-#include "frontend/SharedContext.h"        // for GlobalScharedContext
-#include "gc/Barrier.h"                    // for HeapPtr
-#include "gc/FreeOp.h"                     // for JSFreeOp
-#include "gc/GC.h"                         // for MemoryUse
-#include "gc/Marking.h"                    // for IsAboutToBeFinalized
-#include "gc/Rooting.h"                    // for RootedDebuggerFrame
-#include "gc/Tracer.h"                     // for TraceCrossCompartmentEdge
-#include "gc/ZoneAllocator.h"              // for AddCellMemory
-#include "jit/JSJitFrameIter.h"            // for InlineFrameIterator
-#include "jit/RematerializedFrame.h"       // for RematerializedFrame
-#include "js/Proxy.h"                      // for PrivateValue
-#include "js/SourceText.h"                 // for SourceText, SourceOwnership
-#include "js/StableStringChars.h"          // for AutoStableStringChars
-#include "vm/ArgumentsObject.h"            // for ArgumentsObject
-#include "vm/ArrayObject.h"                // for ArrayObject
-#include "vm/AsyncFunction.h"              // for AsyncFunctionGeneratorObject
-#include "vm/AsyncIteration.h"             // for AsyncGeneratorObject
-#include "vm/BytecodeUtil.h"               // for JSDVG_SEARCH_STACK
-#include "vm/Compartment.h"                // for Compartment
-#include "vm/EnvironmentObject.h"          // for IsGlobalLexicalEnvironment
-#include "vm/GeneratorObject.h"            // for AbstractGeneratorObject
-#include "vm/GlobalObject.h"               // for GlobalObject
-#include "vm/Interpreter.h"                // for Call, ExecuteKernel
-#include "vm/JSAtom.h"                     // for Atomize
-#include "vm/JSContext.h"                  // for JSContext, ReportValueError
-#include "vm/JSFunction.h"                 // for JSFunction, NewNativeFunction
-#include "vm/JSObject.h"                   // for JSObject, RequireObject
-#include "vm/JSScript.h"                   // for JSScript
-#include "vm/NativeObject.h"               // for NativeDefineDataProperty
-#include "vm/Realm.h"                      // for AutoRealm
-#include "vm/Runtime.h"                    // for JSAtomState
-#include "vm/Scope.h"                      // for PositionalFormalParameterIter
-#include "vm/Stack.h"                      // for AbstractFramePtr, FrameIter
-#include "vm/StringType.h"                 // for PropertyName, JSString
-#include "wasm/WasmDebug.h"                // for DebugState
-#include "wasm/WasmInstance.h"             // for Instance
-#include "wasm/WasmJS.h"                   // for WasmInstanceObject
-#include "wasm/WasmTypes.h"                // for DebugFrame
+#include "frontend/CompilationInfo.h"  // for CompilationInfo, CompilationGCOutput
+#include "frontend/SharedContext.h"    // for GlobalScharedContext
+#include "gc/Barrier.h"                // for HeapPtr
+#include "gc/FreeOp.h"                 // for JSFreeOp
+#include "gc/GC.h"                     // for MemoryUse
+#include "gc/Marking.h"                // for IsAboutToBeFinalized
+#include "gc/Rooting.h"                // for RootedDebuggerFrame
+#include "gc/Tracer.h"                 // for TraceCrossCompartmentEdge
+#include "gc/ZoneAllocator.h"          // for AddCellMemory
+#include "jit/JSJitFrameIter.h"        // for InlineFrameIterator
+#include "jit/RematerializedFrame.h"  // for RematerializedFrame
+#include "js/Object.h"                // for SetReservedSlot
+#include "js/Proxy.h"                 // for PrivateValue
+#include "js/SourceText.h"            // for SourceText, SourceOwnership
+#include "js/StableStringChars.h"     // for AutoStableStringChars
+#include "vm/ArgumentsObject.h"       // for ArgumentsObject
+#include "vm/ArrayObject.h"           // for ArrayObject
+#include "vm/AsyncFunction.h"         // for AsyncFunctionGeneratorObject
+#include "vm/AsyncIteration.h"        // for AsyncGeneratorObject
+#include "vm/BytecodeUtil.h"          // for JSDVG_SEARCH_STACK
+#include "vm/Compartment.h"           // for Compartment
+#include "vm/EnvironmentObject.h"     // for IsGlobalLexicalEnvironment
+#include "vm/GeneratorObject.h"       // for AbstractGeneratorObject
+#include "vm/GlobalObject.h"          // for GlobalObject
+#include "vm/Interpreter.h"           // for Call, ExecuteKernel
+#include "vm/JSAtom.h"                // for Atomize
+#include "vm/JSContext.h"             // for JSContext, ReportValueError
+#include "vm/JSFunction.h"            // for JSFunction, NewNativeFunction
+#include "vm/JSObject.h"              // for JSObject, RequireObject
+#include "vm/JSScript.h"              // for JSScript
+#include "vm/NativeObject.h"          // for NativeDefineDataProperty
+#include "vm/Realm.h"                 // for AutoRealm
+#include "vm/Runtime.h"               // for JSAtomState
+#include "vm/Scope.h"                 // for PositionalFormalParameterIter
+#include "vm/Stack.h"                 // for AbstractFramePtr, FrameIter
+#include "vm/StringType.h"            // for PropertyName, JSString
+#include "wasm/WasmDebug.h"           // for DebugState
+#include "wasm/WasmInstance.h"        // for Instance
+#include "wasm/WasmJS.h"              // for WasmInstanceObject
+#include "wasm/WasmTypes.h"           // for DebugFrame
 
 #include "debugger/Debugger-inl.h"  // for Debugger::fromJSObject
 #include "gc/WeakMap-inl.h"         // for WeakMap::remove
@@ -151,7 +153,7 @@ bool ScriptedOnPopHandler::onPop(JSContext* cx, HandleDebuggerFrame frame,
                                  const Completion& completion,
                                  ResumeMode& resumeMode,
                                  MutableHandleValue vp) {
-  Debugger* dbg = Debugger::fromChildJSObject(frame);
+  Debugger* dbg = frame->owner();
 
   RootedValue completionValue(cx);
   if (!completion.buildCompletionValue(cx, dbg, &completionValue)) {
@@ -169,18 +171,18 @@ bool ScriptedOnPopHandler::onPop(JSContext* cx, HandleDebuggerFrame frame,
 
 size_t ScriptedOnPopHandler::allocSize() const { return sizeof(*this); }
 
-inline js::Debugger* js::DebuggerFrame::owner() const {
+// The Debugger.Frame.prototype object also has a class of
+// DebuggerFrame::class_ so we differentiate instances from the prototype
+// based on the presence of an owner debugger.
+bool js::DebuggerFrame::isInstance() const {
+  return !getReservedSlot(OWNER_SLOT).isUndefined();
+}
+js::Debugger* js::DebuggerFrame::owner() const {
+  MOZ_ASSERT(isInstance());
   JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
   return Debugger::fromJSObject(dbgobj);
 }
 
-inline bool js::DebuggerFrame::hasIncrementedStepper() const {
-  return getReservedSlot(HAS_INCREMENTED_STEPPER_SLOT).toBoolean();
-}
-inline void js::DebuggerFrame::setHasIncrementedStepper(bool incremented) {
-  setReservedSlot(HAS_INCREMENTED_STEPPER_SLOT, BooleanValue(incremented));
-}
-
 const JSClassOps DebuggerFrame::classOps_ = {
     nullptr,                         // addProperty
     nullptr,                         // delProperty
@@ -243,7 +245,6 @@ DebuggerFrame* DebuggerFrame::create(
   }
 
   frame->setReservedSlot(OWNER_SLOT, ObjectValue(*debugger));
-  frame->setReservedSlot(HAS_INCREMENTED_STEPPER_SLOT, BooleanValue(false));
 
   if (maybeIter) {
     FrameIter::Data* data = maybeIter->copyData();
@@ -256,6 +257,7 @@ DebuggerFrame* DebuggerFrame::create(
 
   if (maybeGenerator) {
     if (!frame->setGeneratorInfo(cx, maybeGenerator)) {
+      frame->freeFrameIterData(cx->runtime()->defaultFreeOp());
       return nullptr;
     }
   }
@@ -352,63 +354,62 @@ bool DebuggerFrame::setGeneratorInfo(JSContext* cx,
                                      Handle genObj) {
   cx->check(this);
 
-  Debugger::GeneratorWeakMap::AddPtr p =
-      owner()->generatorFrames.lookupForAdd(genObj);
-  if (p) {
-    MOZ_ASSERT(p->value() == this);
-    MOZ_ASSERT(&unwrappedGenerator() == genObj);
-    return true;
-  }
+  MOZ_ASSERT(!hasGeneratorInfo());
+  MOZ_ASSERT(!genObj->isClosed());
+
+  // When we initialize the generator information, we do not need to adjust
+  // the stepper increment, because either it was already incremented when
+  // the step hook was added, or we're setting this into on a new DebuggerFrame
+  // that has not yet had the chance for a hook to be added to it.
+  MOZ_ASSERT_IF(onStepHandler(), frameIterData());
+  MOZ_ASSERT_IF(!frameIterData(), !onStepHandler());
 
-  // There are three relations we must establish:
+  // There are two relations we must establish:
   //
   // 1) The DebuggerFrame must point to the AbstractGeneratorObject.
   //
-  // 2) generatorFrames must map the AbstractGeneratorObject to the
-  //    DebuggerFrame.
-  //
-  // 3) The generator's script's observer count must be bumped.
+  // 2) The generator's script's observer count must be bumped.
+
   RootedScript script(cx, genObj->callee().nonLazyScript());
-  auto* info = cx->new_(genObj, script);
+  auto info = cx->make_unique(genObj, script);
   if (!info) {
-    ReportOutOfMemory(cx);
     return false;
   }
-  auto infoGuard = MakeScopeExit([&] { js_delete(info); });
 
-  if (!owner()->generatorFrames.relookupOrAdd(p, genObj, this)) {
-    ReportOutOfMemory(cx);
+  AutoRealm ar(cx, script);
+
+  // All frames running a debuggee script must themselves be marked as
+  // debuggee frames. Bumping a script's generator observer count makes it a
+  // debuggee, so we need to mark all frames on the stack running it as
+  // debuggees as well, not just this one. This call takes care of all that.
+  if (!Debugger::ensureExecutionObservabilityOfScript(cx, script)) {
     return false;
   }
-  auto generatorFramesGuard =
-      MakeScopeExit([&] { owner()->generatorFrames.remove(genObj); });
-
-  {
-    AutoRealm ar(cx, script);
-
-    // All frames running a debuggee script must themselves be marked as
-    // debuggee frames. Bumping a script's generator observer count makes it a
-    // debuggee, so we need to mark all frames on the stack running it as
-    // debuggees as well, not just this one. This call takes care of all that.
-    if (!Debugger::ensureExecutionObservabilityOfScript(cx, script)) {
-      return false;
-    }
 
-    if (!DebugScript::incrementGeneratorObserverCount(cx, script)) {
-      return false;
-    }
+  if (!DebugScript::incrementGeneratorObserverCount(cx, script)) {
+    return false;
   }
 
-  InitReservedSlot(this, GENERATOR_INFO_SLOT, info,
+  InitReservedSlot(this, GENERATOR_INFO_SLOT, info.release(),
                    MemoryUse::DebuggerFrameGeneratorInfo);
-
-  generatorFramesGuard.release();
-  infoGuard.release();
-
   return true;
 }
 
-void DebuggerFrame::clearGeneratorInfo(JSFreeOp* fop) {
+void DebuggerFrame::terminate(JSFreeOp* fop, AbstractFramePtr frame) {
+  if (frameIterData()) {
+    // If no frame pointer was provided to decrement the stepper counter,
+    // then we must be terminating a generator, otherwise the stepper count
+    // would have no way to synchronize properly.
+    MOZ_ASSERT_IF(!frame, hasGeneratorInfo());
+
+    freeFrameIterData(fop);
+    if (frame && !hasGeneratorInfo() && onStepHandler()) {
+      // If we are terminating a non-generator frame that had a step handler,
+      // we need to decrement the counter to keep things in sync.
+      decrementStepperCounter(fop, frame);
+    }
+  }
+
   if (!hasGeneratorInfo()) {
     return;
   }
@@ -425,7 +426,11 @@ void DebuggerFrame::clearGeneratorInfo(JSFreeOp* fop) {
   if (!info->isGeneratorScriptAboutToBeFinalized()) {
     JSScript* generatorScript = info->generatorScript();
     DebugScript::decrementGeneratorObserverCount(fop, generatorScript);
-    maybeDecrementStepperCounter(fop, generatorScript);
+    if (onStepHandler()) {
+      // If we are terminating a generator frame that had a step handler,
+      // we need to decrement the counter to keep things in sync.
+      decrementStepperCounter(fop, generatorScript);
+    }
   }
 
   // 1) The DebuggerFrame must no longer point to the AbstractGeneratorObject.
@@ -433,23 +438,13 @@ void DebuggerFrame::clearGeneratorInfo(JSFreeOp* fop) {
   fop->delete_(this, info, MemoryUse::DebuggerFrameGeneratorInfo);
 }
 
-void DebuggerFrame::clearGeneratorInfo(
-    JSFreeOp* fop, Debugger* owner,
-    Debugger::GeneratorWeakMap::Enum* maybeGeneratorFramesEnum) {
-  if (!hasGeneratorInfo()) {
-    return;
-  }
+void DebuggerFrame::suspend(JSFreeOp* fop) {
+  // There must be generator info because otherwise this would be the same
+  // overall behavior as terminate() except that here we do not properly
+  // adjust stepper counts.
+  MOZ_ASSERT(hasGeneratorInfo());
 
-  // 2) generatorFrames must no longer map the AbstractGeneratorObject to the
-  // DebuggerFrame.
-  GeneratorInfo* info = generatorInfo();
-  if (maybeGeneratorFramesEnum) {
-    maybeGeneratorFramesEnum->removeFront();
-  } else {
-    owner->generatorFrames.remove(&info->unwrappedGenerator());
-  }
-
-  clearGeneratorInfo(fop);
+  freeFrameIterData(fop);
 }
 
 /* static */
@@ -474,11 +469,7 @@ bool DebuggerFrame::getCallee(JSContext* cx, HandleDebuggerFrame frame,
 bool DebuggerFrame::getIsConstructing(JSContext* cx, HandleDebuggerFrame frame,
                                       bool& result) {
   if (frame->isOnStack()) {
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     result = iter.isFunctionFrame() && iter.isConstructing();
   } else {
@@ -544,11 +535,7 @@ bool DebuggerFrame::getEnvironment(JSContext* cx, HandleDebuggerFrame frame,
   Rooted env(cx);
 
   if (frame->isOnStack()) {
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     {
       AutoRealm ar(cx, iter.abstractFramePtr().environmentChain());
@@ -579,11 +566,7 @@ bool DebuggerFrame::getEnvironment(JSContext* cx, HandleDebuggerFrame frame,
 bool DebuggerFrame::getOffset(JSContext* cx, HandleDebuggerFrame frame,
                               size_t& result) {
   if (frame->isOnStack()) {
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     AbstractFramePtr referent = DebuggerFrame::getReferent(frame);
     if (referent.isWasmDebugFrame()) {
@@ -611,12 +594,7 @@ bool DebuggerFrame::getOlder(JSContext* cx, HandleDebuggerFrame frame,
                              MutableHandleDebuggerFrame result) {
   if (frame->isOnStack()) {
     Debugger* dbg = frame->owner();
-
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     while (true) {
       Activation& activation = *iter.activation();
@@ -692,12 +670,7 @@ bool DebuggerFrame::getThis(JSContext* cx, HandleDebuggerFrame frame,
     if (!requireScriptReferent(cx, frame)) {
       return false;
     }
-
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     {
       AbstractFramePtr frame = iter.abstractFramePtr();
@@ -800,24 +773,22 @@ bool DebuggerFrame::setOnStepHandler(JSContext* cx, HandleDebuggerFrame frame,
 
     // Adjust execution observability and step counts on whatever code (JS or
     // Wasm) this frame is running.
-    if (handler) {
-      if (!frame->maybeIncrementStepperCounter(cx, referent)) {
+    if (handler && !prior) {
+      if (!frame->incrementStepperCounter(cx, referent)) {
         return false;
       }
-    } else {
-      frame->maybeDecrementStepperCounter(cx->runtime()->defaultFreeOp(),
-                                          referent);
+    } else if (!handler && prior) {
+      frame->decrementStepperCounter(cx->runtime()->defaultFreeOp(), referent);
     }
   } else if (frame->isSuspended()) {
     RootedScript script(cx, frame->generatorInfo()->generatorScript());
 
-    if (handler) {
-      if (!frame->maybeIncrementStepperCounter(cx, script)) {
+    if (handler && !prior) {
+      if (!frame->incrementStepperCounter(cx, script)) {
         return false;
       }
-    } else {
-      frame->maybeDecrementStepperCounter(cx->runtime()->defaultFreeOp(),
-                                          script);
+    } else if (!handler && prior) {
+      frame->decrementStepperCounter(cx->runtime()->defaultFreeOp(), script);
     }
   } else {
     // If the frame is entirely dead, we still allow setting the onStep
@@ -840,14 +811,10 @@ bool DebuggerFrame::setOnStepHandler(JSContext* cx, HandleDebuggerFrame frame,
   return true;
 }
 
-bool DebuggerFrame::maybeIncrementStepperCounter(JSContext* cx,
-                                                 AbstractFramePtr referent) {
-  if (hasIncrementedStepper()) {
-    return true;
-  }
-
+bool DebuggerFrame::incrementStepperCounter(JSContext* cx,
+                                            AbstractFramePtr referent) {
   if (!referent.isWasmDebugFrame()) {
-    return maybeIncrementStepperCounter(cx, referent.script());
+    return incrementStepperCounter(cx, referent.script());
   }
 
   wasm::Instance* instance = referent.asWasmDebugFrame()->instance();
@@ -857,16 +824,10 @@ bool DebuggerFrame::maybeIncrementStepperCounter(JSContext* cx,
     return false;
   }
 
-  setHasIncrementedStepper(true);
   return true;
 }
 
-bool DebuggerFrame::maybeIncrementStepperCounter(JSContext* cx,
-                                                 JSScript* script) {
-  if (hasIncrementedStepper()) {
-    return true;
-  }
-
+bool DebuggerFrame::incrementStepperCounter(JSContext* cx, JSScript* script) {
   // Single stepping toggled off->on.
   AutoRealm ar(cx, script);
   // Ensure observability *before* incrementing the step mode count.
@@ -879,18 +840,13 @@ bool DebuggerFrame::maybeIncrementStepperCounter(JSContext* cx,
     return false;
   }
 
-  setHasIncrementedStepper(true);
   return true;
 }
 
-void DebuggerFrame::maybeDecrementStepperCounter(JSFreeOp* fop,
-                                                 AbstractFramePtr referent) {
-  if (!hasIncrementedStepper()) {
-    return;
-  }
-
+void DebuggerFrame::decrementStepperCounter(JSFreeOp* fop,
+                                            AbstractFramePtr referent) {
   if (!referent.isWasmDebugFrame()) {
-    maybeDecrementStepperCounter(fop, referent.script());
+    decrementStepperCounter(fop, referent.script());
     return;
   }
 
@@ -898,18 +854,11 @@ void DebuggerFrame::maybeDecrementStepperCounter(JSFreeOp* fop,
   wasm::DebugFrame* wasmFrame = referent.asWasmDebugFrame();
   // Single stepping toggled on->off.
   instance->debug().decrementStepperCount(fop, wasmFrame->funcIndex());
-  setHasIncrementedStepper(false);
 }
 
-void DebuggerFrame::maybeDecrementStepperCounter(JSFreeOp* fop,
-                                                 JSScript* script) {
-  if (!hasIncrementedStepper()) {
-    return;
-  }
-
+void DebuggerFrame::decrementStepperCounter(JSFreeOp* fop, JSScript* script) {
   // Single stepping toggled on->off.
   DebugScript::decrementStepperCount(fop, script);
-  setHasIncrementedStepper(false);
 }
 
 /* static */
@@ -973,8 +922,6 @@ static bool EvaluateInEnv(JSContext* cx, Handle env,
     options.setForceStrictMode();
   }
 
-  SourceExtent extent = SourceExtent::makeGlobalExtent(chars.length(), options);
-
   SourceText srcBuf;
   if (!srcBuf.init(cx, chars.begin().get(), chars.length(),
                    SourceOwnership::Borrowed)) {
@@ -1001,16 +948,7 @@ static bool EvaluateInEnv(JSContext* cx, Handle env,
       return false;
     }
 
-    LifoAllocScope allocScope(&cx->tempLifoAlloc());
-    frontend::CompilationInfo compilationInfo(cx, allocScope, options, scope,
-                                              env);
-    if (!compilationInfo.init(cx)) {
-      return false;
-    }
-
-    frontend::EvalSharedContext evalsc(cx, compilationInfo, scope,
-                                       compilationInfo.directives, extent);
-    script = frontend::CompileEvalScript(compilationInfo, evalsc, srcBuf);
+    script = frontend::CompileEvalScript(cx, options, srcBuf, scope, env);
     if (!script) {
       return false;
     }
@@ -1021,17 +959,10 @@ static bool EvaluateInEnv(JSContext* cx, Handle env,
     // users of executeInGlobal, like the web console, may add new bindings to
     // the global scope.
 
-    LifoAllocScope allocScope(&cx->tempLifoAlloc());
-    frontend::CompilationInfo compilationInfo(cx, allocScope, options);
-    if (!compilationInfo.init(cx)) {
-      return false;
-    }
     MOZ_ASSERT(scopeKind == ScopeKind::Global ||
                scopeKind == ScopeKind::NonSyntactic);
 
-    frontend::GlobalSharedContext globalsc(cx, scopeKind, compilationInfo,
-                                           compilationInfo.directives, extent);
-    script = frontend::CompileGlobalScript(compilationInfo, globalsc, srcBuf);
+    script = frontend::CompileGlobalScript(cx, options, srcBuf, scopeKind);
     if (!script) {
       return false;
     }
@@ -1144,12 +1075,7 @@ Result DebuggerFrame::eval(JSContext* cx, HandleDebuggerFrame frame,
   MOZ_ASSERT(frame->isOnStack());
 
   Debugger* dbg = frame->owner();
-
-  Maybe maybeIter;
-  if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-    return cx->alreadyReportedError();
-  }
-  FrameIter& iter = *maybeIter;
+  FrameIter iter = frame->getFrameIter(cx);
 
   UpdateFrameIterPc(iter);
 
@@ -1159,7 +1085,7 @@ Result DebuggerFrame::eval(JSContext* cx, HandleDebuggerFrame frame,
 bool DebuggerFrame::isOnStack() const { return !!getPrivate(); }
 
 bool DebuggerFrame::isOnStackMaybeForwarded() const {
-  return !!getPrivate(numFixedSlotsMaybeForwarded());
+  return !!getPrivateMaybeForwarded();
 }
 
 OnStepHandler* DebuggerFrame::onStepHandler() const {
@@ -1204,11 +1130,12 @@ AbstractFramePtr DebuggerFrame::getReferent(HandleDebuggerFrame frame) {
   return iter.abstractFramePtr();
 }
 
-/* static */
-bool DebuggerFrame::getFrameIter(JSContext* cx, HandleDebuggerFrame frame,
-                                 Maybe& result) {
-  result.emplace(*frame->frameIterData());
-  return true;
+FrameIter DebuggerFrame::getFrameIter(JSContext* cx) {
+  FrameIter::Data* data = frameIterData();
+  MOZ_ASSERT(data);
+  MOZ_ASSERT(data->cx_ == cx);
+
+  return FrameIter(*data);
 }
 
 /* static */
@@ -1237,6 +1164,16 @@ void DebuggerFrame::freeFrameIterData(JSFreeOp* fop) {
   }
 }
 
+bool DebuggerFrame::replaceFrameIterData(JSContext* cx, const FrameIter& iter) {
+  FrameIter::Data* data = iter.copyData();
+  if (!data) {
+    return false;
+  }
+  freeFrameIterData(cx->runtime()->defaultFreeOp());
+  setFrameIterData(data);
+  return true;
+}
+
 /* static */
 void DebuggerFrame::finalize(JSFreeOp* fop, JSObject* obj) {
   MOZ_ASSERT(fop->onMainThread());
@@ -1244,10 +1181,10 @@ void DebuggerFrame::finalize(JSFreeOp* fop, JSObject* obj) {
   DebuggerFrame& frameobj = obj->as();
 
   // Connections between dying Debugger.Frames and their
-  // AbstractGeneratorObjects should have been broken in DebugAPI::sweepAll.
+  // AbstractGeneratorObjects, as well as the frame's stack data should have
+  // been by a call to terminate() from sweepAll or some other place.
   MOZ_ASSERT(!frameobj.hasGeneratorInfo());
-
-  frameobj.freeFrameIterData(fop);
+  MOZ_ASSERT(!frameobj.frameIterData());
   OnStepHandler* onStepHandler = frameobj.onStepHandler();
   if (onStepHandler) {
     onStepHandler->drop(fop, &frameobj);
@@ -1279,7 +1216,7 @@ DebuggerFrame* DebuggerFrame::check(JSContext* cx, HandleValue thisv) {
   if (!thisobj) {
     return nullptr;
   }
-  if (thisobj->getClass() != &class_) {
+  if (!thisobj->is()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Frame",
                               "method", thisobj->getClass()->name);
@@ -1289,11 +1226,8 @@ DebuggerFrame* DebuggerFrame::check(JSContext* cx, HandleValue thisv) {
   RootedDebuggerFrame frame(cx, &thisobj->as());
 
   // Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_
-  // but isn't really a working Debugger.Frame object. The prototype object
-  // is distinguished by having a nullptr private value. Also, forbid popped
-  // frames.
-  if (!frame->getPrivate() &&
-      frame->getReservedSlot(OWNER_SLOT).isUndefined()) {
+  // but isn't really a working Debugger.Frame object.
+  if (!frame->isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Frame",
                               "method", "prototype object");
@@ -1511,7 +1445,7 @@ bool DebuggerFrame::CallData::asyncPromiseGetter() {
 
   RootedScript script(cx);
   if (frame->isOnStack()) {
-    FrameIter iter(*frame->frameIterData());
+    FrameIter iter = frame->getFrameIter(cx);
     AbstractFramePtr framePtr = iter.abstractFramePtr();
 
     if (!framePtr.isWasmDebugFrame()) {
@@ -1556,12 +1490,7 @@ bool DebuggerFrame::getOlderSavedFrame(JSContext* cx, HandleDebuggerFrame frame,
                                        MutableHandleSavedFrame result) {
   if (frame->isOnStack()) {
     Debugger* dbg = frame->owner();
-
-    Maybe maybeIter;
-    if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-      return false;
-    }
-    FrameIter& iter = *maybeIter;
+    FrameIter iter = frame->getFrameIter(cx);
 
     while (true) {
       Activation& activation = *iter.activation();
@@ -1649,8 +1578,8 @@ static bool DebuggerArguments_getArg(JSContext* cx, unsigned argc, Value* vp) {
     return false;
   }
 
-  FrameIter frameIter(*thisobj->frameIterData());
-  AbstractFramePtr frame = frameIter.abstractFramePtr();
+  FrameIter iter = thisobj->getFrameIter(cx);
+  AbstractFramePtr frame = iter.abstractFramePtr();
 
   // TODO handle wasm frame arguments -- they are not yet reflectable.
   MOZ_ASSERT(!frame.isWasmDebugFrame(), "a wasm frame args");
@@ -1690,7 +1619,7 @@ static bool DebuggerArguments_getArg(JSContext* cx, unsigned argc, Value* vp) {
     arg.setUndefined();
   }
 
-  if (!Debugger::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, &arg)) {
+  if (!thisobj->owner()->wrapDebuggeeValue(cx, &arg)) {
     return false;
   }
   args.rval().set(arg);
@@ -1708,7 +1637,7 @@ DebuggerArguments* DebuggerArguments::create(JSContext* cx, HandleObject proto,
     return nullptr;
   }
 
-  SetReservedSlot(obj, FRAME_SLOT, ObjectValue(*frame));
+  JS::SetReservedSlot(obj, FRAME_SLOT, ObjectValue(*frame));
 
   MOZ_ASSERT(referent.numActualArgs() <= 0x7fffffff);
   unsigned fargc = referent.numActualArgs();
@@ -1758,9 +1687,9 @@ bool DebuggerFrame::CallData::getScript() {
 
   RootedDebuggerScript scriptObject(cx);
 
-  Debugger* debug = Debugger::fromChildJSObject(frame);
+  Debugger* debug = frame->owner();
   if (frame->isOnStack()) {
-    FrameIter iter(*frame->frameIterData());
+    FrameIter iter = frame->getFrameIter(cx);
     AbstractFramePtr framePtr = iter.abstractFramePtr();
 
     if (framePtr.isWasmDebugFrame()) {
diff --git a/js/src/debugger/Frame.h b/js/src/debugger/Frame.h
index 07cd7bbeed..e1dc44f881 100644
--- a/js/src/debugger/Frame.h
+++ b/js/src/debugger/Frame.h
@@ -124,8 +124,6 @@ class DebuggerFrame : public NativeObject {
     ONSTEP_HANDLER_SLOT,
     ONPOP_HANDLER_SLOT,
 
-    HAS_INCREMENTED_STEPPER_SLOT,
-
     // If this is a frame for a generator call, and the generator object has
     // been created (which doesn't happen until after default argument
     // evaluation and destructuring), then this is a PrivateValue pointing to a
@@ -245,9 +243,6 @@ class DebuggerFrame : public NativeObject {
    * allows this function to be used while iterating over generatorFrames.
    */
   void clearGeneratorInfo(JSFreeOp* fop);
-  void clearGeneratorInfo(
-      JSFreeOp* fop, Debugger* owner,
-      Debugger::GeneratorWeakMap::Enum* maybeGeneratorFramesEnum = nullptr);
 
   /*
    * Called after a generator/async frame is resumed, before exposing this
@@ -257,6 +252,9 @@ class DebuggerFrame : public NativeObject {
 
   bool hasAnyHooks() const;
 
+  bool isInstance() const;
+  Debugger* owner() const;
+
  private:
   static const JSClassOps classOps_;
 
@@ -266,9 +264,6 @@ class DebuggerFrame : public NativeObject {
   static void finalize(JSFreeOp* fop, JSObject* obj);
 
   static AbstractFramePtr getReferent(HandleDebuggerFrame frame);
-  static MOZ_MUST_USE bool getFrameIter(JSContext* cx,
-                                        HandleDebuggerFrame frame,
-                                        mozilla::Maybe& result);
   static MOZ_MUST_USE bool requireScriptReferent(JSContext* cx,
                                                  HandleDebuggerFrame frame);
 
@@ -276,22 +271,23 @@ class DebuggerFrame : public NativeObject {
 
   struct CallData;
 
-  Debugger* owner() const;
-
-  bool hasIncrementedStepper() const;
-  void setHasIncrementedStepper(bool incremented);
+  MOZ_MUST_USE bool incrementStepperCounter(JSContext* cx,
+                                            AbstractFramePtr referent);
+  MOZ_MUST_USE bool incrementStepperCounter(JSContext* cx, JSScript* script);
+  void decrementStepperCounter(JSFreeOp* fop, JSScript* script);
+  void decrementStepperCounter(JSFreeOp* fop, AbstractFramePtr referent);
 
-  MOZ_MUST_USE bool maybeIncrementStepperCounter(JSContext* cx,
-                                                 AbstractFramePtr referent);
-  MOZ_MUST_USE bool maybeIncrementStepperCounter(JSContext* cx,
-                                                 JSScript* script);
-  void maybeDecrementStepperCounter(JSFreeOp* fop, JSScript* script);
-
- public:
   FrameIter::Data* frameIterData() const;
   void setFrameIterData(FrameIter::Data*);
   void freeFrameIterData(JSFreeOp* fop);
-  void maybeDecrementStepperCounter(JSFreeOp* fop, AbstractFramePtr referent);
+
+ public:
+  FrameIter getFrameIter(JSContext* cx);
+
+  void terminate(JSFreeOp* fop, AbstractFramePtr frame);
+  void suspend(JSFreeOp* fop);
+
+  MOZ_MUST_USE bool replaceFrameIterData(JSContext* cx, const FrameIter&);
 
   class GeneratorInfo;
   inline GeneratorInfo* generatorInfo() const;
diff --git a/js/src/debugger/NoExecute.cpp b/js/src/debugger/NoExecute.cpp
index d91abc5fc6..06a8dcd30b 100644
--- a/js/src/debugger/NoExecute.cpp
+++ b/js/src/debugger/NoExecute.cpp
@@ -11,13 +11,14 @@
 #include "jsapi.h"        // for Handle
 #include "jsfriendapi.h"  // for DumpBacktrace, GetErrorMessage
 
-#include "debugger/Debugger.h"  // for Debugger
-#include "gc/Barrier.h"         // for GCPtrNativeObject
-#include "js/Promise.h"         // for AutoDebuggerJobQueueInterruption
-#include "vm/JSContext.h"       // for ProtectedDataContextArg, JSContext
-#include "vm/JSScript.h"        // for JSScript
-#include "vm/Realm.h"           // for AutoRealm, Realm
-#include "vm/Warnings.h"        // for WarnNumberLatin1
+#include "debugger/Debugger.h"        // for Debugger
+#include "gc/Barrier.h"               // for GCPtrNativeObject
+#include "js/friend/DumpFunctions.h"  // for DumpBacktrace
+#include "js/Promise.h"               // for AutoDebuggerJobQueueInterruption
+#include "vm/JSContext.h"             // for ProtectedDataContextArg, JSContext
+#include "vm/JSScript.h"              // for JSScript
+#include "vm/Realm.h"                 // for AutoRealm, Realm
+#include "vm/Warnings.h"              // for WarnNumberLatin1
 
 #include "vm/Realm-inl.h"  // for AutoRealm::AutoRealm
 
diff --git a/js/src/debugger/Object-inl.h b/js/src/debugger/Object-inl.h
index 084fb2b336..b0797b94e2 100644
--- a/js/src/debugger/Object-inl.h
+++ b/js/src/debugger/Object-inl.h
@@ -18,7 +18,15 @@
 
 #include "debugger/Debugger-inl.h"  // for Debugger::fromJSObject
 
+// The Debugger.Object.prototype object also has a class of
+// DebuggerObject::class_ so we differentiate instances from the prototype
+// based on the presence of an owner debugger.
+inline bool js::DebuggerObject::isInstance() const {
+  return !getReservedSlot(OWNER_SLOT).isUndefined();
+}
+
 inline js::Debugger* js::DebuggerObject::owner() const {
+  MOZ_ASSERT(isInstance());
   JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
   return Debugger::fromJSObject(dbgobj);
 }
diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp
index 84fce24f6b..77382b928d 100644
--- a/js/src/debugger/Object.cpp
+++ b/js/src/debugger/Object.cpp
@@ -29,45 +29,47 @@
 #include "gc/Tracer.h"  // for TraceManuallyBarrieredCrossCompartmentEdge
 #include "js/CompilationAndEvaluation.h"  //  for Compile
 #include "js/Conversions.h"               // for ToObject
-#include "js/HeapAPI.h"                   // for IsInsideNursery
-#include "js/Promise.h"                   // for PromiseState
-#include "js/Proxy.h"                     // for PropertyDescriptor
-#include "js/StableStringChars.h"         // for AutoStableStringChars
-#include "proxy/ScriptedProxyHandler.h"   // for ScriptedProxyHandler
-#include "vm/ArgumentsObject.h"           // for ARGS_LENGTH_MAX
-#include "vm/ArrayObject.h"               // for ArrayObject
-#include "vm/AsyncFunction.h"             // for AsyncGeneratorObject
-#include "vm/AsyncIteration.h"            // for AsyncFunctionGeneratorObject
-#include "vm/BytecodeUtil.h"              // for JSDVG_SEARCH_STACK
-#include "vm/Compartment.h"               // for Compartment
-#include "vm/EnvironmentObject.h"         // for GetDebugEnvironmentForFunction
-#include "vm/ErrorObject.h"               // for JSObject::is, ErrorObject
-#include "vm/GeneratorObject.h"           // for AbstractGeneratorObject
-#include "vm/GlobalObject.h"              // for JSObject::is, GlobalObject
-#include "vm/Instrumentation.h"           // for RealmInstrumentation
-#include "vm/Interpreter.h"               // for Call
-#include "vm/JSAtom.h"                    // for Atomize, js_apply_str
-#include "vm/JSContext.h"                 // for JSContext, ReportValueError
-#include "vm/JSFunction.h"                // for JSFunction
-#include "vm/JSScript.h"                  // for JSScript
-#include "vm/NativeObject.h"              // for NativeObject, JSObject::is
-#include "vm/ObjectGroup.h"               // for GenericObject, NewObjectKind
-#include "vm/ObjectOperations.h"          // for DefineProperty
-#include "vm/PlainObject.h"               // for js::PlainObject
-#include "vm/PromiseObject.h"             // for js::PromiseObject
-#include "vm/Realm.h"                     // for AutoRealm, ErrorCopier, Realm
-#include "vm/Runtime.h"                   // for JSAtomState
-#include "vm/SavedFrame.h"                // for SavedFrame
-#include "vm/Scope.h"                     // for PositionalFormalParameterIter
-#include "vm/SelfHosting.h"               // for GetClonedSelfHostedFunctionName
-#include "vm/Shape.h"                     // for Shape
-#include "vm/Stack.h"                     // for InvokeArgs
-#include "vm/StringType.h"                // for JSAtom, PropertyName
-#include "vm/WrapperObject.h"             // for JSObject::is, WrapperObject
+#include "js/friend/WindowProxy.h"  // for IsWindow, IsWindowProxy, ToWindowIfWindowProxy
+#include "js/HeapAPI.h"             // for IsInsideNursery
+#include "js/Promise.h"             // for PromiseState
+#include "js/Proxy.h"               // for PropertyDescriptor
+#include "js/SourceText.h"          // for SourceText
+#include "js/StableStringChars.h"        // for AutoStableStringChars
+#include "js/String.h"                   // for JS::StringHasLatin1Chars
+#include "proxy/ScriptedProxyHandler.h"  // for ScriptedProxyHandler
+#include "vm/ArgumentsObject.h"          // for ARGS_LENGTH_MAX
+#include "vm/ArrayObject.h"              // for ArrayObject
+#include "vm/AsyncFunction.h"            // for AsyncGeneratorObject
+#include "vm/AsyncIteration.h"           // for AsyncFunctionGeneratorObject
+#include "vm/BytecodeUtil.h"             // for JSDVG_SEARCH_STACK
+#include "vm/Compartment.h"              // for Compartment
+#include "vm/EnvironmentObject.h"        // for GetDebugEnvironmentForFunction
+#include "vm/ErrorObject.h"              // for JSObject::is, ErrorObject
+#include "vm/GeneratorObject.h"          // for AbstractGeneratorObject
+#include "vm/GlobalObject.h"             // for JSObject::is, GlobalObject
+#include "vm/Instrumentation.h"          // for RealmInstrumentation
+#include "vm/Interpreter.h"              // for Call
+#include "vm/JSAtom.h"                   // for Atomize, js_apply_str
+#include "vm/JSContext.h"                // for JSContext, ReportValueError
+#include "vm/JSFunction.h"               // for JSFunction
+#include "vm/JSScript.h"                 // for JSScript
+#include "vm/NativeObject.h"             // for NativeObject, JSObject::is
+#include "vm/ObjectGroup.h"              // for GenericObject, NewObjectKind
+#include "vm/ObjectOperations.h"         // for DefineProperty
+#include "vm/PlainObject.h"              // for js::PlainObject
+#include "vm/PromiseObject.h"            // for js::PromiseObject
+#include "vm/Realm.h"                    // for AutoRealm, ErrorCopier, Realm
+#include "vm/Runtime.h"                  // for JSAtomState
+#include "vm/SavedFrame.h"               // for SavedFrame
+#include "vm/Scope.h"                    // for PositionalFormalParameterIter
+#include "vm/SelfHosting.h"              // for GetClonedSelfHostedFunctionName
+#include "vm/Shape.h"                    // for Shape
+#include "vm/Stack.h"                    // for InvokeArgs
+#include "vm/StringType.h"               // for JSAtom, PropertyName
+#include "vm/WrapperObject.h"            // for JSObject::is, WrapperObject
 
 #include "vm/Compartment-inl.h"  // for Compartment::wrap
-#include "vm/JSAtom-inl.h"       // for ValueToId
-#include "vm/JSObject-inl.h"  // for GetObjectClassName, InitClass, NewObjectWithGivenProtoAndKind
+#include "vm/JSObject-inl.h"  // for GetObjectClassName, InitClass, NewObjectWithGivenProtoAndKind, ToPropertyKey
 #include "vm/NativeObject-inl.h"      // for NativeObject::global
 #include "vm/ObjectOperations-inl.h"  // for DeleteProperty, GetProperty
 #include "vm/Realm-inl.h"             // for AutoRealm::AutoRealm
@@ -114,7 +116,7 @@ static DebuggerObject* DebuggerObject_checkThis(JSContext* cx,
   if (!thisobj) {
     return nullptr;
   }
-  if (thisobj->getClass() != &DebuggerObject::class_) {
+  if (!thisobj->is()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Object",
                               "method", thisobj->getClass()->name);
@@ -122,10 +124,9 @@ static DebuggerObject* DebuggerObject_checkThis(JSContext* cx,
   }
 
   // Forbid Debugger.Object.prototype, which is of class DebuggerObject::class_
-  // but isn't a real working Debugger.Object. The prototype object is
-  // distinguished by having no referent.
+  // but isn't a real working Debugger.Object.
   DebuggerObject* nthisobj = &thisobj->as();
-  if (!nthisobj->getPrivate()) {
+  if (!nthisobj->isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Object",
                               "method", "prototype object");
@@ -169,6 +170,7 @@ struct MOZ_STACK_CLASS DebuggerObject::CallData {
   bool boundThisGetter();
   bool boundArgumentsGetter();
   bool allocationSiteGetter();
+  bool isErrorGetter();
   bool errorMessageNameGetter();
   bool errorNotesGetter();
   bool errorLineNumberGetter();
@@ -350,33 +352,19 @@ bool DebuggerObject::CallData::parameterNamesGetter() {
     return true;
   }
 
-  Rooted names(cx, StringVector(cx));
-  if (!DebuggerObject::getParameterNames(cx, object, &names)) {
-    return false;
-  }
+  RootedFunction referent(cx, &object->referent()->as());
 
-  RootedArrayObject obj(cx, NewDenseFullyAllocatedArray(cx, names.length()));
-  if (!obj) {
+  ArrayObject* arr = GetFunctionParameterNamesArray(cx, referent);
+  if (!arr) {
     return false;
   }
 
-  obj->ensureDenseInitializedLength(cx, 0, names.length());
-  for (size_t i = 0; i < names.length(); ++i) {
-    Value v;
-    if (names[i]) {
-      v = StringValue(names[i]);
-    } else {
-      v = UndefinedValue();
-    }
-    obj->setDenseElement(i, v);
-  }
-
-  args.rval().setObject(*obj);
+  args.rval().setObject(*arr);
   return true;
 }
 
 bool DebuggerObject::CallData::scriptGetter() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   if (!referent->is()) {
     args.rval().setUndefined();
@@ -410,7 +398,7 @@ bool DebuggerObject::CallData::scriptGetter() {
 }
 
 bool DebuggerObject::CallData::environmentGetter() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   // Don't bother switching compartments just to check obj's type and get its
   // env.
@@ -498,9 +486,9 @@ bool DebuggerObject::CallData::allocationSiteGetter() {
   return true;
 }
 
-// Returns the "name" field (see js.msg), which may be used as a unique
-// identifier, for any error object with a JSErrorReport or undefined
-// if the object has no JSErrorReport.
+// Returns the "name" field (see js/public/friend/ErrorNumbers.msg), which may
+// be used as a unique identifier, for any error object with a JSErrorReport or
+// undefined if the object has no JSErrorReport.
 bool DebuggerObject::CallData::errorMessageNameGetter() {
   RootedString result(cx);
   if (!DebuggerObject::getErrorMessageName(cx, object, &result)) {
@@ -515,6 +503,11 @@ bool DebuggerObject::CallData::errorMessageNameGetter() {
   return true;
 }
 
+bool DebuggerObject::CallData::isErrorGetter() {
+  args.rval().setBoolean(object->isError());
+  return true;
+}
+
 bool DebuggerObject::CallData::errorNotesGetter() {
   return DebuggerObject::getErrorNotes(cx, object, args.rval());
 }
@@ -712,7 +705,7 @@ bool DebuggerObject::CallData::promiseIDGetter() {
 }
 
 bool DebuggerObject::CallData::promiseDependentPromisesGetter() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   Rooted promise(cx, EnsurePromise(cx, referent));
   if (!promise) {
@@ -806,7 +799,7 @@ bool DebuggerObject::CallData::getOwnPropertySymbolsMethod() {
 
 bool DebuggerObject::CallData::getOwnPropertyDescriptorMethod() {
   RootedId id(cx);
-  if (!ValueToId(cx, args.get(0), &id)) {
+  if (!ToPropertyKey(cx, args.get(0), &id)) {
     return false;
   }
 
@@ -851,7 +844,7 @@ bool DebuggerObject::CallData::definePropertyMethod() {
   }
 
   RootedId id(cx);
-  if (!ValueToId(cx, args[0], &id)) {
+  if (!ToPropertyKey(cx, args[0], &id)) {
     return false;
   }
 
@@ -902,7 +895,7 @@ bool DebuggerObject::CallData::definePropertiesMethod() {
  */
 bool DebuggerObject::CallData::deletePropertyMethod() {
   RootedId id(cx);
-  if (!ValueToId(cx, args.get(0), &id)) {
+  if (!ToPropertyKey(cx, args.get(0), &id)) {
     return false;
   }
 
@@ -938,10 +931,10 @@ bool DebuggerObject::CallData::callMethod() {
 }
 
 bool DebuggerObject::CallData::getPropertyMethod() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   RootedId id(cx);
-  if (!ValueToId(cx, args.get(0), &id)) {
+  if (!ToPropertyKey(cx, args.get(0), &id)) {
     return false;
   }
 
@@ -954,10 +947,10 @@ bool DebuggerObject::CallData::getPropertyMethod() {
 }
 
 bool DebuggerObject::CallData::setPropertyMethod() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   RootedId id(cx);
-  if (!ValueToId(cx, args.get(0), &id)) {
+  if (!ToPropertyKey(cx, args.get(0), &id)) {
     return false;
   }
 
@@ -1047,7 +1040,7 @@ static bool RequireGlobalObject(JSContext* cx, HandleValue dbgobj,
 }
 
 bool DebuggerObject::CallData::asEnvironmentMethod() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   if (!RequireGlobalObject(cx, args.thisv(), referent)) {
     return false;
@@ -1236,7 +1229,7 @@ bool DebuggerObject::CallData::createSource() {
   JS::CompileOptions compileOptions(cx);
   compileOptions.lineno = startLine;
 
-  if (!JS_StringHasLatin1Chars(url)) {
+  if (!JS::StringHasLatin1Chars(url)) {
     JS_ReportErrorASCII(cx, "URL must be a narrow string");
     return false;
   }
@@ -1497,7 +1490,7 @@ struct DebuggerObject::PromiseReactionRecordBuilder
 };
 
 bool DebuggerObject::CallData::getPromiseReactionsMethod() {
-  Debugger* dbg = Debugger::fromChildJSObject(object);
+  Debugger* dbg = object->owner();
 
   Rooted unwrappedPromise(cx, EnsurePromise(cx, referent));
   if (!unwrappedPromise) {
@@ -1536,6 +1529,7 @@ const JSPropertySpec DebuggerObject::properties_[] = {
     JS_DEBUG_PSG("boundThis", boundThisGetter),
     JS_DEBUG_PSG("boundArguments", boundArgumentsGetter),
     JS_DEBUG_PSG("allocationSite", allocationSiteGetter),
+    JS_DEBUG_PSG("isError", isErrorGetter),
     JS_DEBUG_PSG("errorMessageName", errorMessageNameGetter),
     JS_DEBUG_PSG("errorNotes", errorNotesGetter),
     JS_DEBUG_PSG("errorLineNumber", errorLineNumberGetter),
@@ -1626,7 +1620,7 @@ DebuggerObject* DebuggerObject::create(JSContext* cx, HandleObject proto,
   }
 
   obj->setPrivateGCThing(referent);
-  obj->setReservedSlot(JSSLOT_DEBUGOBJECT_OWNER, ObjectValue(*debugger));
+  obj->setReservedSlot(OWNER_SLOT, ObjectValue(*debugger));
 
   return obj;
 }
@@ -1680,7 +1674,7 @@ bool DebuggerObject::isPromise() const {
   JSObject* referent = this->referent();
 
   if (IsCrossCompartmentWrapper(referent)) {
-    /* We only care about promises, so CheckedUnwrapStatic is OK. */
+    // We only care about promises, so CheckedUnwrapStatic is OK.
     referent = CheckedUnwrapStatic(referent);
     if (!referent) {
       return false;
@@ -1690,6 +1684,20 @@ bool DebuggerObject::isPromise() const {
   return referent->is();
 }
 
+bool DebuggerObject::isError() const {
+  JSObject* referent = this->referent();
+
+  if (IsCrossCompartmentWrapper(referent)) {
+    // We only check for error classes, so CheckedUnwrapStatic is OK.
+    referent = CheckedUnwrapStatic(referent);
+    if (!referent) {
+      return false;
+    }
+  }
+
+  return referent->is();
+}
+
 /* static */
 bool DebuggerObject::getClassName(JSContext* cx, HandleDebuggerObject object,
                                   MutableHandleString result) {
@@ -1743,45 +1751,6 @@ double DebuggerObject::promiseTimeToResolution() const {
   return promise()->timeToResolution();
 }
 
-/* static */
-bool DebuggerObject::getParameterNames(JSContext* cx,
-                                       HandleDebuggerObject object,
-                                       MutableHandle result) {
-  MOZ_ASSERT(object->isDebuggeeFunction());
-
-  RootedFunction referent(cx, &object->referent()->as());
-
-  if (!result.growBy(referent->nargs())) {
-    return false;
-  }
-  if (IsInterpretedNonSelfHostedFunction(referent)) {
-    RootedScript script(cx, GetOrCreateFunctionScript(cx, referent));
-    if (!script) {
-      return false;
-    }
-
-    MOZ_ASSERT(referent->nargs() == script->numArgs());
-
-    if (referent->nargs() > 0) {
-      PositionalFormalParameterIter fi(script);
-      for (size_t i = 0; i < referent->nargs(); i++, fi++) {
-        MOZ_ASSERT(fi.argumentSlot() == i);
-        JSAtom* atom = fi.name();
-        if (atom) {
-          cx->markAtom(atom);
-        }
-        result[i].set(atom);
-      }
-    }
-  } else {
-    for (size_t i = 0; i < referent->nargs(); i++) {
-      result[i].set(nullptr);
-    }
-  }
-
-  return true;
-}
-
 /* static */
 bool DebuggerObject::getBoundTargetFunction(
     JSContext* cx, HandleDebuggerObject object,
diff --git a/js/src/debugger/Object.h b/js/src/debugger/Object.h
index 962e82876b..e854f921e5 100644
--- a/js/src/debugger/Object.h
+++ b/js/src/debugger/Object.h
@@ -31,8 +31,6 @@ class EvalOptions;
 class GlobalObject;
 class PromiseObject;
 
-enum { JSSLOT_DEBUGOBJECT_OWNER, JSSLOT_DEBUGOBJECT_COUNT };
-
 class DebuggerObject : public NativeObject {
  public:
   static const JSClass class_;
@@ -49,9 +47,6 @@ class DebuggerObject : public NativeObject {
   static MOZ_MUST_USE bool getClassName(JSContext* cx,
                                         HandleDebuggerObject object,
                                         MutableHandleString result);
-  static MOZ_MUST_USE bool getParameterNames(
-      JSContext* cx, HandleDebuggerObject object,
-      MutableHandle result);
   static MOZ_MUST_USE bool getBoundTargetFunction(
       JSContext* cx, HandleDebuggerObject object,
       MutableHandleDebuggerObject result);
@@ -167,12 +162,22 @@ class DebuggerObject : public NativeObject {
   bool isGlobal() const;
   bool isScriptedProxy() const;
   bool isPromise() const;
+  bool isError() const;
   JSAtom* name(JSContext* cx) const;
   JSAtom* displayName(JSContext* cx) const;
   JS::PromiseState promiseState() const;
   double promiseLifetime() const;
   double promiseTimeToResolution() const;
 
+  bool isInstance() const;
+  Debugger* owner() const;
+
+  JSObject* referent() const {
+    JSObject* obj = (JSObject*)getPrivate();
+    MOZ_ASSERT(obj);
+    return obj;
+  }
+
  private:
   enum { OWNER_SLOT };
 
@@ -184,13 +189,6 @@ class DebuggerObject : public NativeObject {
   static const JSPropertySpec promiseProperties_[];
   static const JSFunctionSpec methods_[];
 
-  JSObject* referent() const {
-    JSObject* obj = (JSObject*)getPrivate();
-    MOZ_ASSERT(obj);
-    return obj;
-  }
-
-  Debugger* owner() const;
   PromiseObject* promise() const;
 
   static MOZ_MUST_USE bool requireGlobal(JSContext* cx,
diff --git a/js/src/debugger/Script-inl.h b/js/src/debugger/Script-inl.h
index 4a9582fe8e..554c6b6725 100644
--- a/js/src/debugger/Script-inl.h
+++ b/js/src/debugger/Script-inl.h
@@ -19,8 +19,23 @@
 #include "vm/NativeObject.h"    // for NativeObject
 #include "wasm/WasmJS.h"        // for WasmInstanceObject
 
+#include "debugger/Debugger-inl.h"  // for Debugger::fromJSObject
+
 class JS_PUBLIC_API JSObject;
 
+// The Debugger.Script.prototype object also has a class of
+// DebuggerScript::class_ so we differentiate instances from the prototype
+// based on the presence of an owner debugger.
+inline bool js::DebuggerScript::isInstance() const {
+  return !getReservedSlot(OWNER_SLOT).isUndefined();
+}
+
+inline js::Debugger* js::DebuggerScript::owner() const {
+  MOZ_ASSERT(isInstance());
+  JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
+  return Debugger::fromJSObject(dbgobj);
+}
+
 js::gc::Cell* js::DebuggerScript::getReferentCell() const {
   return static_cast(getPrivate());
 }
diff --git a/js/src/debugger/Script.cpp b/js/src/debugger/Script.cpp
index 797987b1e4..057c4c674a 100644
--- a/js/src/debugger/Script.cpp
+++ b/js/src/debugger/Script.cpp
@@ -165,8 +165,8 @@ DebuggerScript* DebuggerScript::check(JSContext* cx, HandleValue v) {
   DebuggerScript& scriptObj = thisobj->as();
 
   // Check for Debugger.Script.prototype, which is of class
-  // DebuggerScript::class but whose script is null.
-  if (!scriptObj.getReferentCell()) {
+  // DebuggerScript::class.
+  if (!scriptObj.isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Script",
                               "method", "prototype object");
@@ -216,6 +216,7 @@ struct MOZ_STACK_CLASS DebuggerScript::CallData {
   bool getIsFunction();
   bool getIsModule();
   bool getDisplayName();
+  bool getParameterNames();
   bool getUrl();
   bool getStartLine();
   bool getStartColumn();
@@ -303,7 +304,7 @@ bool DebuggerScript::CallData::getDisplayName() {
     return false;
   }
   JSFunction* func = obj->getReferentScript()->function();
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   JSString* name = func ? func->displayAtom() : nullptr;
   if (!name) {
@@ -319,6 +320,26 @@ bool DebuggerScript::CallData::getDisplayName() {
   return true;
 }
 
+bool DebuggerScript::CallData::getParameterNames() {
+  if (!ensureScriptMaybeLazy()) {
+    return false;
+  }
+
+  RootedFunction fun(cx, referent.as()->function());
+  if (!fun) {
+    args.rval().setUndefined();
+    return true;
+  }
+
+  ArrayObject* arr = GetFunctionParameterNamesArray(cx, fun);
+  if (!arr) {
+    return false;
+  }
+
+  args.rval().setObject(*arr);
+  return true;
+}
+
 bool DebuggerScript::CallData::getUrl() {
   if (!ensureScriptMaybeLazy()) {
     return false;
@@ -412,7 +433,7 @@ class DebuggerScript::GetSourceMatcher {
 };
 
 bool DebuggerScript::CallData::getSource() {
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   GetSourceMatcher matcher(cx, dbg);
   RootedDebuggerSource sourceObject(cx, referent.match(matcher));
@@ -444,7 +465,7 @@ bool DebuggerScript::CallData::getGlobal() {
   if (!ensureScript()) {
     return false;
   }
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   RootedValue v(cx, ObjectValue(script->global()));
   if (!dbg->wrapDebuggeeValue(cx, &v)) {
@@ -503,7 +524,7 @@ bool DebuggerScript::CallData::getChildScripts() {
   if (!ensureScriptMaybeLazy()) {
     return false;
   }
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   RootedObject result(cx, NewDenseEmptyArray(cx));
   if (!result) {
@@ -1432,6 +1453,7 @@ static bool BytecodeIsEffectful(JSOp op) {
     case JSOp::NewObjectWithGroup:
     case JSOp::InitElem:
     case JSOp::InitHiddenElem:
+    case JSOp::InitLockedElem:
     case JSOp::InitElemInc:
     case JSOp::InitElemArray:
     case JSOp::InitProp:
@@ -1508,6 +1530,7 @@ static bool BytecodeIsEffectful(JSOp op) {
     case JSOp::EndIter:
     case JSOp::In:
     case JSOp::HasOwn:
+    case JSOp::CheckPrivateField:
     case JSOp::SetRval:
     case JSOp::Instanceof:
     case JSOp::DebugLeaveLexicalEnv:
@@ -1532,7 +1555,7 @@ static bool BytecodeIsEffectful(JSOp op) {
     case JSOp::CheckClassHeritage:
     case JSOp::FunWithProto:
     case JSOp::ObjWithProto:
-    case JSOp::FunctionProto:
+    case JSOp::BuiltinObject:
     case JSOp::DerivedConstructor:
     case JSOp::CheckThis:
     case JSOp::CheckReturn:
@@ -1640,7 +1663,7 @@ bool DebuggerScript::CallData::getAllOffsets() {
         RootedId id(cx);
         RootedValue v(cx, NumberValue(lineno));
         offsets = NewDenseEmptyArray(cx);
-        if (!offsets || !ValueToId(cx, v, &id)) {
+        if (!offsets || !PrimitiveValueToId(cx, v, &id)) {
           return false;
         }
 
@@ -1881,7 +1904,8 @@ struct DebuggerScript::SetBreakpointMatcher {
     }
 
     // If the Debugger's compartment has killed incoming wrappers, we may not
-    // have gotten usable results from the 'wrap' calls. Treat it as a failure.
+    // have gotten usable results from the 'wrap' calls. Treat it as a
+    // failure.
     if (IsDeadProxyObject(handler_) || IsDeadProxyObject(debuggerObject_)) {
       ReportAccessDenied(cx_);
       return false;
@@ -1982,7 +2006,7 @@ bool DebuggerScript::CallData::setBreakpoint() {
   if (!args.requireAtLeast(cx, "Debugger.Script.setBreakpoint", 2)) {
     return false;
   }
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   size_t offset;
   if (!ScriptOffset(cx, args[0], &offset)) {
@@ -2006,7 +2030,7 @@ bool DebuggerScript::CallData::getBreakpoints() {
   if (!ensureScript()) {
     return false;
   }
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   jsbytecode* pc;
   if (args.length() > 0) {
@@ -2066,9 +2090,9 @@ class DebuggerScript::ClearBreakpointMatcher {
 
     // A Breakpoint belongs logically to its script's compartment, so it holds
     // its handler via a cross-compartment wrapper. But the handler passed to
-    // `clearBreakpoint` is same-compartment with the Debugger. Wrap it here, so
-    // that `DebugScript::clearBreakpointsIn` gets the right value to search
-    // for.
+    // `clearBreakpoint` is same-compartment with the Debugger. Wrap it here,
+    // so that `DebugScript::clearBreakpointsIn` gets the right value to
+    // search for.
     AutoRealm ar(cx_, script);
     if (!cx_->compartment()->wrap(cx_, &handler_)) {
       return false;
@@ -2084,10 +2108,11 @@ class DebuggerScript::ClearBreakpointMatcher {
       return true;
     }
 
-    // A Breakpoint belongs logically to its instance's compartment, so it holds
-    // its handler via a cross-compartment wrapper. But the handler passed to
-    // `clearBreakpoint` is same-compartment with the Debugger. Wrap it here, so
-    // that `DebugState::clearBreakpointsIn` gets the right value to search for.
+    // A Breakpoint belongs logically to its instance's compartment, so it
+    // holds its handler via a cross-compartment wrapper. But the handler
+    // passed to `clearBreakpoint` is same-compartment with the Debugger. Wrap
+    // it here, so that `DebugState::clearBreakpointsIn` gets the right value
+    // to search for.
     AutoRealm ar(cx_, instanceObj);
     if (!cx_->compartment()->wrap(cx_, &handler_)) {
       return false;
@@ -2103,7 +2128,7 @@ bool DebuggerScript::CallData::clearBreakpoint() {
   if (!args.requireAtLeast(cx, "Debugger.Script.clearBreakpoint", 1)) {
     return false;
   }
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
 
   JSObject* handler = RequireObject(cx, args[0]);
   if (!handler) {
@@ -2120,7 +2145,7 @@ bool DebuggerScript::CallData::clearBreakpoint() {
 }
 
 bool DebuggerScript::CallData::clearAllBreakpoints() {
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
   ClearBreakpointMatcher matcher(cx, dbg, nullptr);
   if (!referent.match(matcher)) {
     return false;
@@ -2304,6 +2329,7 @@ const JSPropertySpec DebuggerScript::properties_[] = {
     JS_DEBUG_PSG("isFunction", getIsFunction),
     JS_DEBUG_PSG("isModule", getIsModule),
     JS_DEBUG_PSG("displayName", getDisplayName),
+    JS_DEBUG_PSG("parameterNames", getParameterNames),
     JS_DEBUG_PSG("url", getUrl),
     JS_DEBUG_PSG("startLine", getStartLine),
     JS_DEBUG_PSG("startColumn", getStartColumn),
diff --git a/js/src/debugger/Script.h b/js/src/debugger/Script.h
index 56f0bcbc66..38b477b26c 100644
--- a/js/src/debugger/Script.h
+++ b/js/src/debugger/Script.h
@@ -61,6 +61,9 @@ class DebuggerScript : public NativeObject {
     return getSlot(INSTRUMENTATION_ID_SLOT);
   }
 
+  bool isInstance() const;
+  Debugger* owner() const;
+
  private:
   static const JSClassOps classOps_;
 
diff --git a/js/src/debugger/Source.cpp b/js/src/debugger/Source.cpp
index c95423fa56..bc5886a52b 100644
--- a/js/src/debugger/Source.cpp
+++ b/js/src/debugger/Source.cpp
@@ -12,13 +12,15 @@
 #include   // for memcpy
 #include    // for move
 
-#include "jsapi.h"        // for JS_ReportErrorNumberASCII, JS_CopyStringCharsZ
-#include "jsfriendapi.h"  // for GetErrorMessage, JS_NewUint8Array
+#include "jsapi.h"  // for JS_ReportErrorNumberASCII, JS_CopyStringCharsZ
 
 #include "debugger/Debugger.h"  // for DebuggerSourceReferent, Debugger
 #include "debugger/Script.h"    // for DebuggerScript
 #include "gc/Tracer.h"  // for TraceManuallyBarrieredCrossCompartmentEdge
 #include "js/CompilationAndEvaluation.h"  // for Compile
+#include "js/experimental/TypedData.h"    // for JS_NewUint8Array
+#include "js/friend/ErrorMessages.h"      // for GetErrorMessage, JSMSG_*
+#include "js/SourceText.h"                // for JS::SourceOwnership
 #include "vm/BytecodeUtil.h"              // for JSDVG_SEARCH_STACK
 #include "vm/JSContext.h"                 // for JSContext (ptr only)
 #include "vm/JSObject.h"                  // for JSObject, RequireObject
@@ -32,8 +34,9 @@
 #include "wasm/WasmJS.h"          // for WasmInstanceObject
 #include "wasm/WasmTypes.h"       // for Bytes, RootedWasmInstanceObject
 
-#include "vm/JSObject-inl.h"      // for InitClass
-#include "vm/NativeObject-inl.h"  // for NewTenuredObjectWithGivenProto
+#include "debugger/Debugger-inl.h"  // for Debugger::fromJSObject
+#include "vm/JSObject-inl.h"        // for InitClass
+#include "vm/NativeObject-inl.h"    // for NewTenuredObjectWithGivenProto
 
 namespace js {
 class GlobalObject;
@@ -88,6 +91,12 @@ DebuggerSource* DebuggerSource::create(JSContext* cx, HandleObject proto,
   return sourceObj;
 }
 
+Debugger* DebuggerSource::owner() const {
+  MOZ_ASSERT(isInstance());
+  JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
+  return Debugger::fromJSObject(dbgobj);
+}
+
 // For internal use only.
 NativeObject* DebuggerSource::getReferentRawObject() const {
   return static_cast(getPrivate());
@@ -136,7 +145,7 @@ DebuggerSource* DebuggerSource::check(JSContext* cx, HandleValue thisv) {
 
   DebuggerSource* thisSourceObj = &thisobj->as();
 
-  if (!thisSourceObj->getReferentRawObject()) {
+  if (!thisSourceObj->isInstance()) {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_INCOMPATIBLE_PROTO, "Debugger.Source",
                               "method", "prototype object");
@@ -376,18 +385,20 @@ bool DebuggerSource::CallData::getDisplayURL() {
 }
 
 struct DebuggerSourceGetElementMatcher {
+  JSContext* mCx = nullptr;
+  explicit DebuggerSourceGetElementMatcher(JSContext* cx_) : mCx(cx_) {}
   using ReturnType = JSObject*;
   ReturnType match(HandleScriptSourceObject sourceObject) {
-    return sourceObject->unwrappedElement();
+    return sourceObject->unwrappedElement(mCx);
   }
   ReturnType match(Handle wasmInstance) { return nullptr; }
 };
 
 bool DebuggerSource::CallData::getElement() {
-  DebuggerSourceGetElementMatcher matcher;
+  DebuggerSourceGetElementMatcher matcher(cx);
   if (JSObject* element = referent.match(matcher)) {
     args.rval().setObjectOrNull(element);
-    if (!Debugger::fromChildJSObject(obj)->wrapDebuggeeValue(cx, args.rval())) {
+    if (!obj->owner()->wrapDebuggeeValue(cx, args.rval())) {
       return false;
     }
   } else {
@@ -409,7 +420,7 @@ struct DebuggerSourceGetElementPropertyMatcher {
 bool DebuggerSource::CallData::getElementProperty() {
   DebuggerSourceGetElementPropertyMatcher matcher;
   args.rval().set(referent.match(matcher));
-  return Debugger::fromChildJSObject(obj)->wrapDebuggeeValue(cx, args.rval());
+  return obj->owner()->wrapDebuggeeValue(cx, args.rval());
 }
 
 class DebuggerSourceGetIntroductionScriptMatcher {
@@ -450,7 +461,7 @@ class DebuggerSourceGetIntroductionScriptMatcher {
 };
 
 bool DebuggerSource::CallData::getIntroductionScript() {
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
   DebuggerSourceGetIntroductionScriptMatcher matcher(cx, dbg, args.rval());
   return referent.match(matcher);
 }
@@ -647,7 +658,7 @@ bool DebuggerSource::CallData::reparse() {
     return false;
   }
 
-  Debugger* dbg = Debugger::fromChildJSObject(obj);
+  Debugger* dbg = obj->owner();
   RootedObject scriptDO(cx, dbg->wrapScript(cx, script));
   if (!scriptDO) {
     return false;
diff --git a/js/src/debugger/Source.h b/js/src/debugger/Source.h
index 75899b1e2e..cb8ee037a0 100644
--- a/js/src/debugger/Source.h
+++ b/js/src/debugger/Source.h
@@ -46,6 +46,12 @@ class DebuggerSource : public NativeObject {
 
   struct CallData;
 
+  // The Debugger.Source.prototype object also has a class of
+  // DebuggerSource::class_ so we differentiate instances from the prototype
+  // based on the presence of an owner debugger.
+  bool isInstance() const { return !getReservedSlot(OWNER_SLOT).isUndefined(); }
+  Debugger* owner() const;
+
  private:
   static const JSClassOps classOps_;
 
diff --git a/js/src/devtools/automation/autospider.py b/js/src/devtools/automation/autospider.py
index bdf15135fc..a2812391e8 100644
--- a/js/src/devtools/automation/autospider.py
+++ b/js/src/devtools/automation/autospider.py
@@ -227,6 +227,19 @@ def ensure_dir_exists(name, clobber=True, creation_marker_filename="CREATED-BY-A
 else:
     compiler = 'gcc'
 
+# Need a platform name to use as a key in variant files.
+if args.platform:
+    variant_platform = args.platform.split("-")[0]
+elif platform.system() == 'Windows':
+    variant_platform = 'win64' if word_bits == 64 else 'win32'
+elif platform.system() == 'Linux':
+    variant_platform = 'linux64' if word_bits == 64 else 'linux'
+elif platform.system() == 'Darwin':
+    variant_platform = 'macosx64'
+else:
+    variant_platform = 'other'
+
+
 info("using compiler '{}'".format(compiler))
 
 cxx = {'clang': 'clang++', 'gcc': 'g++', 'cl': 'cl'}.get(compiler)
@@ -297,6 +310,12 @@ def ensure_dir_exists(name, clobber=True, creation_marker_filename="CREATED-BY-A
 if platform.system() == 'Linux' and AUTOMATION:
     CONFIGURE_ARGS = '--enable-stdcxx-compat --disable-gold ' + CONFIGURE_ARGS
 
+# Override environment variant settings conditionally.
+CONFIGURE_ARGS = "{} {}".format(
+    variant.get('conditional-configure-args', {}).get(variant_platform, ''),
+    CONFIGURE_ARGS
+)
+
 # Timeouts.
 ACTIVE_PROCESSES = set()
 
@@ -451,18 +470,6 @@ def normalize_tests(tests):
     return tests
 
 
-# Need a platform name to use as a key in variant files.
-if args.platform:
-    variant_platform = args.platform.split("-")[0]
-elif platform.system() == 'Windows':
-    variant_platform = 'win64' if word_bits == 64 else 'win32'
-elif platform.system() == 'Linux':
-    variant_platform = 'linux64' if word_bits == 64 else 'linux'
-elif platform.system() == 'Darwin':
-    variant_platform = 'macosx64'
-else:
-    variant_platform = 'other'
-
 # Override environment variant settings conditionally.
 for k, v in variant.get('conditional-env', {}).get(variant_platform, {}).items():
     env[k] = v.format(**REPLACEMENTS)
diff --git a/js/src/devtools/automation/variants/compacting b/js/src/devtools/automation/variants/compacting
index 651e18e992..911cfa1c49 100644
--- a/js/src/devtools/automation/variants/compacting
+++ b/js/src/devtools/automation/variants/compacting
@@ -7,11 +7,6 @@
         "JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt",
         "JSTESTS_EXTRA_ARGS": "--exclude-file={DIR}/cgc-jstests-slow.txt"
     },
-    "conditional-env": {
-        "linux64": {
-            "JITTEST_EXTRA_ARGS": "--jitflags=debug --ignore-timeouts={DIR}/cgc-jittest-timeouts.txt --run-binast"
-        }
-    },
     "skip-tests": {
         "win32": ["jstests"],
         "win64": ["jstests"]
diff --git a/js/src/devtools/automation/variants/plain b/js/src/devtools/automation/variants/plain
index 7cdcaed8e3..902e81f41c 100644
--- a/js/src/devtools/automation/variants/plain
+++ b/js/src/devtools/automation/variants/plain
@@ -3,10 +3,5 @@
     "optimize": true,
     "env": {
         "JSTESTS_EXTRA_ARGS": "--jitflags=jstests"
-    },
-    "conditional-env": {
-        "linux64": {
-            "JITTEST_EXTRA_ARGS": "--run-binast"
-        }
     }
 }
diff --git a/js/src/devtools/automation/variants/plaindebug b/js/src/devtools/automation/variants/plaindebug
index 31778fcedf..ee3505abfb 100644
--- a/js/src/devtools/automation/variants/plaindebug
+++ b/js/src/devtools/automation/variants/plaindebug
@@ -1,12 +1,11 @@
 {
     "configure-args": "--enable-rust-simd",
     "debug": true,
+    "compiler": "clang",
     "env": {
         "JSTESTS_EXTRA_ARGS": "--jitflags=debug"
     },
-    "conditional-env": {
-        "linux64": {
-            "JITTEST_EXTRA_ARGS": "--run-binast"
-        }
+    "conditional-configure-args": {
+        "linux64": "--enable-clang-plugin"
     }
 }
diff --git a/js/src/devtools/gc-ubench/argparse.js b/js/src/devtools/gc-ubench/argparse.js
new file mode 100644
index 0000000000..454b53fb71
--- /dev/null
+++ b/js/src/devtools/gc-ubench/argparse.js
@@ -0,0 +1,127 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Command-line argument parser, modeled after but not identical to Python's
+// argparse.
+
+var ArgParser = class {
+  constructor(desc) {
+    this._params = [];
+    this._doc = desc;
+
+    this.add_argument("--help", {
+      help: "display this help message",
+    });
+  }
+
+  // name is '--foo', '-f', or an array of aliases.
+  //
+  // spec is an options object with keys:
+  //   dest: key name to store the result in (optional for long options)
+  //   default: value to use if not passed on command line (optional)
+  //   help: description of the option to show in --help
+  //   options: array of valid choices
+  //
+  // Prefixes of long option names are allowed. If a prefix is ambiguous, it
+  // will match the first parameter added to the ArgParser.
+  add_argument(name, spec) {
+    const names = Array.isArray(name) ? name : [name];
+
+    spec = Object.assign({}, spec);
+    spec.aliases = names;
+    for (const name of names) {
+      if (!name.startsWith("-")) {
+        throw new Error(`unhandled argument syntax '${name}'`);
+      }
+      if (name.startsWith("--")) {
+        spec.dest = spec.dest || name.substr(2);
+      }
+      this._params.push({ name, spec });
+    }
+  }
+
+  parse_args(args) {
+    const opts = {};
+    const rest = [];
+
+    for (const { spec } of this._params) {
+      if (spec.default !== undefined) {
+        opts[spec.dest] = spec.default;
+      }
+    }
+
+    const seen = new Set();
+    for (let i = 0; i < args.length; i++) {
+      const arg = args[i];
+      if (!arg.startsWith("-")) {
+        rest.push(arg);
+        continue;
+      } else if (arg === "--") {
+        rest.push(args.slice(i+1));
+        break;
+      }
+
+      if (arg == "--help" || arg == "-h") {
+        this.help();
+      }
+
+      let parameter;
+      let [passed, value] = arg.split("=");
+      for (const { name, spec } of this._params) {
+        if (passed.startsWith("--")) {
+          if (name.startsWith(passed)) {
+            parameter = spec;
+          }
+        } else if (passed.startsWith("-") && passed === name) {
+          parameter = spec;
+        }
+        if (parameter) {
+          if (value === undefined) {
+            value = args[++i];
+          }
+          opts[parameter.dest] = value;
+          break;
+        }
+      }
+
+      if (parameter) {
+        if (seen.has(parameter)) {
+          throw new Error(`${parameter.aliases[0]} given multiple times`);
+        }
+        seen.add(parameter);
+      } else {
+        throw new Error(`invalid command-line argument '${arg}'`);
+      }
+    }
+
+    for (const { name, spec } of this._params) {
+      if (spec.options && !spec.options.includes(opts[spec.dest])) {
+        throw new Error(`invalid ${name} value '${opts[spec.dest]}'`);
+        opts[spec.dest] = spec.default;
+      }
+    }
+
+    return { opts, rest };
+  }
+
+  help() {
+    print(`Usage: ${this._doc}`);
+    const specs = new Set(this._params.map(p => p.spec));
+    const optstrs = [...specs].map(p => p.aliases.join(", "));
+    let maxlen = Math.max(...optstrs.map(s => s.length));
+    for (const spec of specs) {
+      const name = spec.aliases[0];
+      let helptext = spec.help ?? "undocumented";
+      if ("options" in spec) {
+        helptext += ` (one of ${spec.options.map(x => `'${x}'`).join(", ")})`;
+      }
+      if ("default" in spec) {
+        helptext += ` (default '${spec.default}')`;
+      }
+      const optstr = spec.aliases.join(", ");
+      print(`  ${optstr.padEnd(maxlen)}  ${helptext}`);
+    }
+    quit(0);
+  }
+};
diff --git a/js/src/devtools/gc-ubench/benchmarks/bigTextNodes.js b/js/src/devtools/gc-ubench/benchmarks/bigTextNodes.js
index 93a8aff5b0..0a66be03d3 100644
--- a/js/src/devtools/gc-ubench/benchmarks/bigTextNodes.js
+++ b/js/src/devtools/gc-ubench/benchmarks/bigTextNodes.js
@@ -2,28 +2,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('bigTextNodes', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [ textNode, textNode, ... ]",
+tests.set(
+  "bigTextNodes",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [ textNode, textNode, ... ]",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      enabled: "document" in globalThis,
 
-    defaultGarbagePerFrame: "8",
-    defaultGarbageTotal: "8",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (N) => {
+      defaultGarbagePerFrame: "8",
+      defaultGarbagePiles: "8",
+
+      makeGarbage: N => {
         var a = [];
         var s = "x";
-        for (var i = 0; i < 16; i++)
-            s = s + s;
-        for (var i = 0; i < N; i++)
-            a.push(document.createTextNode(s));
+        for (var i = 0; i < 16; i++) {
+          s = s + s;
+        }
+        for (var i = 0; i < N; i++) {
+          a.push(document.createTextNode(s));
+        }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/deepWeakMap.js b/js/src/devtools/gc-ubench/benchmarks/deepWeakMap.js
new file mode 100644
index 0000000000..bf46d1d97b
--- /dev/null
+++ b/js/src/devtools/gc-ubench/benchmarks/deepWeakMap.js
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+tests.set(
+  "deepWeakMap",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "o={wm,k}; w.mk[k]=o2={wm2,k2}; wm2[k2]=....",
+
+      defaultGarbagePerFrame: "1K",
+      defaultGarbagePiles: "1K",
+
+      load: N => {
+        garbage = new Array(N);
+      },
+
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+
+      makeGarbage: M => {
+        var initial = {};
+        var prev = initial;
+        for (var i = 0; i < M; i++) {
+          var obj = [new WeakMap(), Object.create(null)];
+          obj[0].set(obj[1], prev);
+          prev = obj;
+        }
+        garbage[garbageIndex++] = initial;
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/events.js b/js/src/devtools/gc-ubench/benchmarks/events.js
index 7bb349f8fd..0fe91b7596 100644
--- a/js/src/devtools/gc-ubench/benchmarks/events.js
+++ b/js/src/devtools/gc-ubench/benchmarks/events.js
@@ -2,28 +2,39 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('events', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [ textNode, textNode, ... ]",
+tests.set(
+  "events",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [ textNode, textNode, ... ]",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      enabled: "document" in globalThis,
 
-    defaultGarbagePerFrame: "100K",
-    defaultGarbageTotal: "8",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (N) => {
+      defaultGarbagePerFrame: "100K",
+      defaultGarbagePiles: "8",
+
+      makeGarbage: N => {
         var a = [];
         for (var i = 0; i < N; i++) {
-            var e = document.createEvent("Events");
-            e.initEvent("TestEvent", true, true);
-            a.push(e);
+          var e = document.createEvent("Events");
+          e.initEvent("TestEvent", true, true);
+          a.push(e);
         }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/expandoEvents.js b/js/src/devtools/gc-ubench/benchmarks/expandoEvents.js
index 56f3418ff7..4c6a53c8fe 100644
--- a/js/src/devtools/gc-ubench/benchmarks/expandoEvents.js
+++ b/js/src/devtools/gc-ubench/benchmarks/expandoEvents.js
@@ -2,29 +2,40 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('expandoEvents', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [ textNode, textNode, ... ]",
+tests.set(
+  "expandoEvents",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [ textNode, textNode, ... ]",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      enabled: "document" in globalThis,
 
-    defaultGarbagePerFrame: "100K",
-    defaultGarbageTotal: "8",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (N) => {
+      defaultGarbagePerFrame: "100K",
+      defaultGarbagePiles: "8",
+
+      makeGarbage: N => {
         var a = [];
         for (var i = 0; i < N; i++) {
-            var e = document.createEvent("Events");
-            e.initEvent("TestEvent", true, true);
-            e.color = ["tuna"];
-            a.push(e);
+          var e = document.createEvent("Events");
+          e.initEvent("TestEvent", true, true);
+          e.color = ["tuna"];
+          a.push(e);
         }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayArrayLiteral.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayArrayLiteral.js
index be4c542903..38e16b364a 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayArrayLiteral.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayArrayLiteral.js
@@ -2,19 +2,28 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayArrayLiteral', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [[], ....]",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
+tests.set(
+  "globalArrayArrayLiteral",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [[], ....]",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+      makeGarbage: N => {
         for (var i = 0; i < N; i++) {
-            garbage[garbageIndex++] = ['foo', 'bar', 'baz', 'baa'];
-            if (garbageIndex == garbage.length)
-                garbageIndex = 0;
+          garbage[garbageIndex++] = ["foo", "bar", "baz", "baa"];
+          if (garbageIndex == garbage.length) {
+            garbageIndex = 0;
+          }
         }
-    }
-};
-})());
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayBuffer.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayBuffer.js
index 7994bed084..5eb612216c 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayBuffer.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayBuffer.js
@@ -2,26 +2,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayBuffer', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = ArrayBuffer(N); # (large malloc data)",
+tests.set(
+  "globalArrayBuffer",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = ArrayBuffer(N); # (large malloc data)",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    defaultGarbageTotal: "8K",
-    defaultGarbagePerFrame: "4M",
+      defaultGarbagePiles: "8K",
+      defaultGarbagePerFrame: "4M",
 
-    makeGarbage: (N) => {
+      makeGarbage: N => {
         var ab = new ArrayBuffer(N);
         var view = new Uint8Array(ab);
         view[0] = 1;
         view[N - 1] = 2;
         garbage[garbageIndex++] = ab;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayFgFinalized.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayFgFinalized.js
index 60c19b1d18..fecf97c358 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayFgFinalized.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayFgFinalized.js
@@ -2,26 +2,36 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayFgFinalized', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [ new Map, new Map, ... ]; # (foreground finalized)",
+tests.set(
+  "globalArrayFgFinalized",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description:
+        "var foo = [ new Map, new Map, ... ]; # (foreground finalized)",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    defaultGarbageTotal: "8K",
-    defaultGarbagePerFrame: "1M",
+      defaultGarbagePiles: "8K",
+      defaultGarbagePerFrame: "1M",
 
-    makeGarbage: (N) => {
+      makeGarbage: N => {
         var arr = [];
         for (var i = 0; i < N; i++) {
-            arr.push(new Map);
+          arr.push(new Map());
         }
         garbage[garbageIndex++] = arr;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeArray.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeArray.js
index 41abd33d34..36e2b052a7 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeArray.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeArray.js
@@ -2,21 +2,30 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayLargeArray', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [[...], ....]",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
+tests.set(
+  "globalArrayLargeArray",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [[...], ....]",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+      makeGarbage: N => {
         var a = new Array(N);
         for (var i = 0; i < N; i++) {
-            a[i] = N - i;
+          a[i] = N - i;
         }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeObject.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeObject.js
index 99f43bbfeb..33a31684e5 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeObject.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayLargeObject.js
@@ -2,26 +2,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayLargeObject', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = { LARGE }; # (large slots)",
+tests.set(
+  "globalArrayLargeObject",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = { LARGE }; # (large slots)",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    defaultGarbageTotal: "8K",
-    defaultGarbagePerFrame: "200K",
+      defaultGarbagePiles: "8K",
+      defaultGarbagePerFrame: "200K",
 
-    makeGarbage: (N) => {
+      makeGarbage: N => {
         var obj = {};
         for (var i = 0; i < N; i++) {
-            obj["key" + i] = i;
+          obj["key" + i] = i;
         }
         garbage[garbageIndex++] = obj;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayNewObject.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayNewObject.js
index 07271da7cd..2b2dcd95cb 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayNewObject.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayNewObject.js
@@ -2,19 +2,28 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayNewObject', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [new Object(), ....]",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
+tests.set(
+  "globalArrayNewObject",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [new Object(), ....]",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+      makeGarbage: N => {
         for (var i = 0; i < N; i++) {
-            garbage[garbageIndex++] = new Object();
-            if (garbageIndex == garbage.length)
-                garbageIndex = 0;
+          garbage[garbageIndex++] = new Object();
+          if (garbageIndex == garbage.length) {
+            garbageIndex = 0;
+          }
         }
-    }
-};
-})());
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayObjectLiteral.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayObjectLiteral.js
index f91018b2aa..2ef6d52dba 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayObjectLiteral.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayObjectLiteral.js
@@ -2,19 +2,28 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayObjectLiteral', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [{}, ....]",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
+tests.set(
+  "globalArrayObjectLiteral",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [{}, ....]",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+      makeGarbage: N => {
         for (var i = 0; i < N; i++) {
-            garbage[garbageIndex++] = {a: 'foo', b: 'bar', 0: 'foo', 1: 'bar'};
-            if (garbageIndex == garbage.length)
-                garbageIndex = 0;
+          garbage[garbageIndex++] = { a: "foo", b: "bar", 0: "foo", 1: "bar" };
+          if (garbageIndex == garbage.length) {
+            garbageIndex = 0;
+          }
         }
-    }
-};
-})());
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/globalArrayReallocArray.js b/js/src/devtools/gc-ubench/benchmarks/globalArrayReallocArray.js
index 9487749a53..e8e037eef6 100644
--- a/js/src/devtools/gc-ubench/benchmarks/globalArrayReallocArray.js
+++ b/js/src/devtools/gc-ubench/benchmarks/globalArrayReallocArray.js
@@ -2,21 +2,30 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('globalArrayReallocArray', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [[,,,], ....]",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
+tests.set(
+  "globalArrayReallocArray",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [[,,,], ....]",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
+      makeGarbage: N => {
         var a = [];
         for (var i = 0; i < N; i++) {
-            a[i] = N - i;
+          a[i] = N - i;
         }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/largeArrayPropertyAndElements.js b/js/src/devtools/gc-ubench/benchmarks/largeArrayPropertyAndElements.js
index a01feceb9e..f9181d8993 100644
--- a/js/src/devtools/gc-ubench/benchmarks/largeArrayPropertyAndElements.js
+++ b/js/src/devtools/gc-ubench/benchmarks/largeArrayPropertyAndElements.js
@@ -2,37 +2,39 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('largeArrayPropertyAndElements', (function() {
-  var garbage;
-  var index;
-
-  return {
-    description: "Large array with both properties and elements",
-
-    load: n => {
-      garbage = new Array(n);
-      garbage.fill(null);
-      index = 0;
-    },
-
-    unload: () => {
-      garbage = null;
-      index = 0;
-    },
-
-    defaultGarbageTotal: "100K",
-    defaultGarbagePerFrame: "30K",
-
-    makeGarbage: n => {
-      for (var i = 0; i < n; i++) {
-        index++;
-        index %= garbage.length;
-
-        var obj = {};
-        garbage[index] = obj;
-        garbage["key-" + index] = obj;
-      }
-    }
-  };
-
-}()));
+tests.set(
+  "largeArrayPropertyAndElements",
+  (function() {
+    var garbage;
+    var index;
+
+    return {
+      description: "Large array with both properties and elements",
+
+      load: n => {
+        garbage = new Array(n);
+        garbage.fill(null);
+        index = 0;
+      },
+
+      unload: () => {
+        garbage = null;
+        index = 0;
+      },
+
+      defaultGarbagePiles: "100K",
+      defaultGarbagePerFrame: "30K",
+
+      makeGarbage: n => {
+        for (var i = 0; i < n; i++) {
+          index++;
+          index %= garbage.length;
+
+          var obj = {};
+          garbage[index] = obj;
+          garbage["key-" + index] = obj;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/noAllocation.js b/js/src/devtools/gc-ubench/benchmarks/noAllocation.js
index 1d058f2d02..8e6ba53943 100644
--- a/js/src/devtools/gc-ubench/benchmarks/noAllocation.js
+++ b/js/src/devtools/gc-ubench/benchmarks/noAllocation.js
@@ -2,9 +2,9 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('noAllocation', {
-    description: "Do not generate any garbage.",
-    load: (N) => {},
-    unload: () => {},
-    makeGarbage: (N) => {}
+tests.set("noAllocation", {
+  description: "Do not generate any garbage.",
+  load: N => {},
+  unload: () => {},
+  makeGarbage: N => {},
 });
diff --git a/js/src/devtools/gc-ubench/benchmarks/pairCyclicWeakMap.js b/js/src/devtools/gc-ubench/benchmarks/pairCyclicWeakMap.js
index c9c7d1ced7..83a28fbf89 100644
--- a/js/src/devtools/gc-ubench/benchmarks/pairCyclicWeakMap.js
+++ b/js/src/devtools/gc-ubench/benchmarks/pairCyclicWeakMap.js
@@ -2,36 +2,45 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('pairCyclicWeakMap', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "wm1[k1] = k2; wm2[k2] = k3; wm1[k3] = k4; wm2[k4] = ...",
+tests.set(
+  "pairCyclicWeakMap",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "wm1[k1] = k2; wm2[k2] = k3; wm1[k3] = k4; wm2[k4] = ...",
 
-    defaultGarbagePerFrame: "1K",
-    defaultGarbageTotal: "1K",
+      defaultGarbagePerFrame: "1K",
+      defaultGarbagePiles: "1K",
 
-    load: (N) => { garbage = new Array(N); },
+      load: N => {
+        garbage = new Array(N);
+      },
 
-    unload: () => { garbage = []; garbageIndex = 0; },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (M) => {
+      makeGarbage: M => {
         var wm1 = new WeakMap();
         var wm2 = new WeakMap();
         var initialKey = {};
         var key = initialKey;
         var value = {};
-        for (var i = 0; i < M/2; i++) {
-            wm1.set(key, value);
-            key = value;
-            value = {};
-            wm2.set(key, value);
-            key = value;
-            value = {};
+        for (var i = 0; i < M / 2; i++) {
+          wm1.set(key, value);
+          key = value;
+          value = {};
+          wm2.set(key, value);
+          key = value;
+          value = {};
         }
-        garbage[garbageIndex++] = [ initialKey, wm1, wm2 ];
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        garbage[garbageIndex++] = [initialKey, wm1, wm2];
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js b/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js
index a2f339c374..9fc62b29e2 100644
--- a/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js
+++ b/js/src/devtools/gc-ubench/benchmarks/propertyTreeSplitting.js
@@ -2,28 +2,23 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('propertyTreeSplitting', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "use delete to generate Shape garbage",
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
-    makeGarbage: (N) => {
-        function f()
-        {
-            var a1 = eval;
-            delete eval;
-            eval = a1;
-            var a3 = toString;
-            delete toString;
-            toString = a3;
-        }
+tests.set(
+  "propertyTreeSplitting",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    var obj = {};
+    return {
+      description: "use delete to generate Shape garbage (piles are unused)",
+      load: N => {},
+      unload: () => {},
+      makeGarbage: N => {
         for (var a = 0; a < N; ++a) {
-            garbage[garbageIndex++] = new f();
-            if (garbageIndex == garbage.length)
-                garbageIndex = 0;
+          obj.x = 1;
+          obj.y = 2;
+          delete obj.x;
         }
-    }
-};
-})());
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/selfCyclicWeakMap.js b/js/src/devtools/gc-ubench/benchmarks/selfCyclicWeakMap.js
index 08735c54ac..eb4d9e5787 100644
--- a/js/src/devtools/gc-ubench/benchmarks/selfCyclicWeakMap.js
+++ b/js/src/devtools/gc-ubench/benchmarks/selfCyclicWeakMap.js
@@ -2,32 +2,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('selfCyclicWeakMap', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var wm = new WeakMap(); wm[k1] = k2; wm[k2] = k3; ...",
+tests.set(
+  "selfCyclicWeakMap",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var wm = new WeakMap(); wm[k1] = k2; wm[k2] = k3; ...",
 
-    defaultGarbagePerFrame: "1K",
-    defaultGarbageTotal: "1K",
+      defaultGarbagePerFrame: "1K",
+      defaultGarbagePiles: "1K",
 
-    load: (N) => { garbage = new Array(N); },
+      load: N => {
+        garbage = new Array(N);
+      },
 
-    unload: () => { garbage = []; garbageIndex = 0; },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (M) => {
+      makeGarbage: M => {
         var wm = new WeakMap();
         var initialKey = {};
         var key = initialKey;
         var value = {};
         for (var i = 0; i < M; i++) {
-            wm.set(key, value);
-            key = value;
-            value = {};
+          wm.set(key, value);
+          key = value;
+          value = {};
         }
-        garbage[garbageIndex++] = [ initialKey, wm ];
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        garbage[garbageIndex++] = [initialKey, wm];
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/benchmarks/textNodes.js b/js/src/devtools/gc-ubench/benchmarks/textNodes.js
index 52e177b4a3..07fd07e7b7 100644
--- a/js/src/devtools/gc-ubench/benchmarks/textNodes.js
+++ b/js/src/devtools/gc-ubench/benchmarks/textNodes.js
@@ -2,26 +2,37 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-window.tests.set('textNodes', (function() {
-var garbage = [];
-var garbageIndex = 0;
-return {
-    description: "var foo = [ textNode, textNode, ... ]",
+tests.set(
+  "textNodes",
+  (function() {
+    var garbage = [];
+    var garbageIndex = 0;
+    return {
+      description: "var foo = [ textNode, textNode, ... ]",
 
-    load: (N) => { garbage = new Array(N); },
-    unload: () => { garbage = []; garbageIndex = 0; },
+      enabled: "document" in globalThis,
 
-    defaultGarbagePerFrame: "100K",
-    defaultGarbageTotal: "8",
+      load: N => {
+        garbage = new Array(N);
+      },
+      unload: () => {
+        garbage = [];
+        garbageIndex = 0;
+      },
 
-    makeGarbage: (N) => {
+      defaultGarbagePerFrame: "100K",
+      defaultGarbagePiles: "8",
+
+      makeGarbage: N => {
         var a = [];
         for (var i = 0; i < N; i++) {
-            a.push(document.createTextNode("t" + i));
+          a.push(document.createTextNode("t" + i));
         }
         garbage[garbageIndex++] = a;
-        if (garbageIndex == garbage.length)
-            garbageIndex = 0;
-    }
-};
-})());
+        if (garbageIndex == garbage.length) {
+          garbageIndex = 0;
+        }
+      },
+    };
+  })()
+);
diff --git a/js/src/devtools/gc-ubench/harness.js b/js/src/devtools/gc-ubench/harness.js
index 42dad54fad..c67f0a42c0 100644
--- a/js/src/devtools/gc-ubench/harness.js
+++ b/js/src/devtools/gc-ubench/harness.js
@@ -2,689 +2,368 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-// Per-frame time sampling infra. Also GC'd: hopefully will not perturb things too badly.
-var numSamples = 500;
-var delays = new Array(numSamples);
-var gcs = new Array(numSamples);
-var minorGCs = new Array(numSamples);
-var majorGCs = new Array(numSamples);
-var slices = new Array(numSamples);
-var gcBytes = new Array(numSamples);
-var mallocBytes = new Array(numSamples);
-var sampleIndex = 0;
-var sampleTime = 16; // ms
-var gHistogram = new Map(); // {ms: count}
-
-var stroke = {
-    'gcslice': 'rgb(255,100,0)',
-    'minor': 'rgb(0,255,100)',
-    'initialMajor': 'rgb(180,60,255)'
-};
-
-var features = {
-  trackingSizes: ('mozMemory' in performance),
-  showingGCs: ('mozMemory' in performance),
-};
-
-// Draw state.
-var stopped = 0;
-var start;
-var prev;
-var latencyGraph;
-var memoryGraph;
-var ctx;
-var memoryCtx;
-
-// Current test state.
-var activeTest = undefined;
-var testDuration = undefined; // ms
-var testState = 'idle';  // One of 'idle' or 'running'.
-var testStart = undefined; // ms
-var testQueue = [];
-
 // Global defaults
-var globalDefaultGarbageTotal = "8M";
-var globalDefaultGarbagePerFrame = "8K";
-
-function Graph(ctx) {
-    this.ctx = ctx;
 
-    var { width, height } = ctx.canvas;
-    this.layout = {
-        xAxisLabel_Y: height - 20,
-    };
-}
-
-Graph.prototype.xpos = index => index * 2;
-
-Graph.prototype.clear = function () {
-    var { width, height } = this.ctx.canvas;
-    this.ctx.clearRect(0, 0, width, height);
+// Allocate this much "garbage" per frame. This might correspond exactly to a
+// number of objects/values, or it might be some set of objects, depending on
+// the mutator in question.
+var gDefaultGarbagePerFrame = "8K";
+
+// In order to avoid a performance cliff between when the per-frame garbage
+// fits in the nursery and when it doesn't, most mutators will collect multiple
+// "piles" of garbage and round-robin through them, so that the per-frame
+// garbage stays alive for some number of frames. There will still be some
+// internal temporary allocations that don't end up in the piles; presumably,
+// the nursery will take care of those.
+//
+// If the per-frame garbage is K and the number of piles is P, then some of the
+// garbage will start getting tenured as long as P*K > size(nursery).
+var gDefaultGarbagePiles = "8";
+
+var gDefaultTestDuration = 8.0;
+
+// The Host interface that provides functionality needed by the test harnesses
+// (web + various shells). Subclasses should override with the appropriate
+// functionality. The methods that throw an error must be implemented. The ones
+// that return undefined are optional.
+//
+// Note that currently the web UI doesn't really use the scheduling pieces of
+// this.
+var Host = class {
+  constructor() {}
+  start_turn() {
+    throw new Error("unimplemented");
+  }
+  end_turn() {
+    throw new Error("unimplemented");
+  }
+  suspend(duration) {
+    throw new Error("unimplemented");
+  } // Shell driver only
+  now() {
+    return performance.now();
+  }
+
+  minorGCCount() {
+    return undefined;
+  }
+  majorGCCount() {
+    return undefined;
+  }
+  GCSliceCount() {
+    return undefined;
+  }
+
+  features = {
+    haveMemorySizes: false,
+    haveGCCounts: false,
+  };
 };
 
-Graph.prototype.drawScale = function (delay)
-{
-    this.drawHBar(delay, `${delay}ms`, 'rgb(150,150,150)');
-}
-
-Graph.prototype.draw60fps = function () {
-    this.drawHBar(1000/60, '60fps', '#00cf61', 25);
-}
-
-Graph.prototype.draw30fps = function () {
-    this.drawHBar(1000/30, '30fps', '#cf0061', 25);
-}
-
-Graph.prototype.drawAxisLabels = function (x_label, y_label)
-{
-    var ctx = this.ctx;
-    var { width, height } = ctx.canvas;
-
-    ctx.fillText(x_label, width / 2, this.layout.xAxisLabel_Y);
-
-    ctx.save();
-    ctx.rotate(Math.PI/2);
-    var start = height / 2 - ctx.measureText(y_label).width / 2;
-    ctx.fillText(y_label, start, -width+20);
-    ctx.restore();
-}
-
-Graph.prototype.drawFrame = function () {
-    var ctx = this.ctx;
-    var { width, height } = ctx.canvas;
-
-    // Draw frame to show size
-    ctx.strokeStyle = 'rgb(0,0,0)';
-    ctx.fillStyle = 'rgb(0,0,0)';
-    ctx.beginPath();
-    ctx.moveTo(0, 0);
-    ctx.lineTo(width, 0);
-    ctx.lineTo(width, height);
-    ctx.lineTo(0, height);
-    ctx.closePath();
-    ctx.stroke();
-}
-
-function LatencyGraph(ctx) {
-    Graph.call(this, ctx);
-    console.log(this.ctx);
-}
-
-LatencyGraph.prototype = Object.create(Graph.prototype);
-
-Object.defineProperty(LatencyGraph.prototype, 'constructor', {
-    enumerable: false,
-    value: LatencyGraph });
-
-LatencyGraph.prototype.ypos = function (delay) {
-    var { height } = this.ctx.canvas;
-
-    var r = height + 100 - Math.log(delay) * 64;
-    if (r < 5) return 5;
-    return r;
-}
-
-LatencyGraph.prototype.drawHBar = function (delay, label, color='rgb(0,0,0)', label_offset=0)
-{
-    var ctx = this.ctx;
-
-    ctx.fillStyle = color;
-    ctx.strokeStyle = color;
-    ctx.fillText(label, this.xpos(numSamples) + 4 + label_offset, this.ypos(delay) + 3);
-
-    ctx.beginPath();
-    ctx.moveTo(this.xpos(0), this.ypos(delay));
-    ctx.lineTo(this.xpos(numSamples) + label_offset, this.ypos(delay));
-    ctx.stroke();
-    ctx.strokeStyle = 'rgb(0,0,0)';
-    ctx.fillStyle = 'rgb(0,0,0)';
+function percent(x) {
+  return `${(x*100).toFixed(2)}%`;
 }
 
-LatencyGraph.prototype.draw = function () {
-    var ctx = this.ctx;
-
-    this.clear();
-    this.drawFrame();
-
-    for (var delay of [ 10, 20, 30, 50, 100, 200, 400, 800 ])
-        this.drawScale(delay);
-    this.draw60fps();
-    this.draw30fps();
+function parse_units(v) {
+  if (!v.length) {
+    return NaN;
+  }
+  var lastChar = v[v.length - 1].toLowerCase();
+  if (!isNaN(parseFloat(lastChar))) {
+    return parseFloat(v);
+  }
+  var units = parseFloat(v.substr(0, v.length - 1));
+  if (lastChar == "k") {
+    return units * 1e3;
+  }
+  if (lastChar == "m") {
+    return units * 1e6;
+  }
+  if (lastChar == "g") {
+    return units * 1e9;
+  }
+  return NaN;
+}
+
+var AllocationLoad = class {
+  constructor(info, name) {
+    this.load = info;
+    this.load.name = this.load.name ?? name;
+
+    this._garbagePerFrame =
+      info.garbagePerFrame ||
+      parse_units(info.defaultGarbagePerFrame || gDefaultGarbagePerFrame);
+    this._garbagePiles =
+      info.garbagePiles ||
+      parse_units(info.defaultGarbagePiles || gDefaultGarbagePiles);
+  }
+
+  get name() {
+    return this.load.name;
+  }
+  get description() {
+    return this.load.description;
+  }
+  get garbagePerFrame() {
+    return this._garbagePerFrame;
+  }
+  set garbagePerFrame(amount) {
+    this._garbagePerFrame = amount;
+  }
+  get garbagePiles() {
+    return this._garbagePiles;
+  }
+  set garbagePiles(amount) {
+    this._garbagePiles = amount;
+  }
+
+  start() {
+    this.load.load(this._garbagePiles);
+  }
+
+  stop() {
+    this.load.unload();
+  }
+
+  reload() {
+    this.stop();
+    this.start();
+  }
+
+  tick() {
+    this.load.makeGarbage(this._garbagePerFrame);
+  }
+
+  is_dummy_load() {
+    return this.load.name == "noAllocation";
+  }
+};
 
-    var worst = 0, worstpos = 0;
-    ctx.beginPath();
-    for (var i = 0; i < numSamples; i++) {
-        ctx.lineTo(this.xpos(i), this.ypos(delays[i]));
-        if (delays[i] >= worst) {
-            worst = delays[i];
-            worstpos = i;
-        }
+var LoadCycle = class {
+  constructor(tests_to_run, duration) {
+    this.queue = [...tests_to_run];
+    this.duration = duration;
+    this.idx = -1;
+  }
+
+  get current() {
+    return this.queue[this.idx];
+  }
+
+  start(now = performance.now()) {
+    this.idx = 0;
+    this.cycleStart = this.started = now;
+  }
+
+  tick(now = performance.now()) {
+    if (this.currentLoadElapsed(now) < this.duration) {
+      return;
     }
-    ctx.stroke();
-
-    // Draw vertical lines marking minor and major GCs
-    if (features.showingGCs) {
-        const { width, height } = ctx.canvas;
-
-        ctx.strokeStyle = stroke.gcslice;
-        var idx = sampleIndex % numSamples;
-        const count = {
-            major: majorGCs[idx],
-            minor: 0,
-            slice: slices[idx]
-        };
-        for (var i = 0; i < numSamples; i++) {
-            idx = (sampleIndex + i) % numSamples;
-            const isMajorStart = count.major < majorGCs[idx];
-            if (count.slice < slices[idx]) {
-                if (isMajorStart) ctx.strokeStyle = stroke.initialMajor;
-                ctx.beginPath();
-                ctx.moveTo(this.xpos(idx), 0);
-                ctx.lineTo(this.xpos(idx), this.layout.xAxisLabel_Y);
-                ctx.stroke();
-                if (isMajorStart) ctx.strokeStyle = stroke.gcslice;
-            }
-            count.major = majorGCs[idx];
-            count.slice = slices[idx];
-        }
 
-        ctx.strokeStyle = stroke.minor;
-        idx = sampleIndex % numSamples;
-        count.minor = gcs[idx];
-        for (var i = 0; i < numSamples; i++) {
-            idx = (sampleIndex + i) % numSamples;
-            if (count.minor < minorGCs[idx]) {
-                ctx.beginPath();
-                ctx.moveTo(this.xpos(idx), 0);
-                ctx.lineTo(this.xpos(idx), 20);
-                ctx.stroke();
-            }
-            count.minor = minorGCs[idx];
-        }
+    this.idx++;
+    this.started = now;
+    if (this.idx >= this.queue.length) {
+      this.idx = -1;
     }
+  }
 
-    ctx.fillStyle = 'rgb(255,0,0)';
-    if (worst)
-        ctx.fillText(`${worst.toFixed(2)}ms`, this.xpos(worstpos) - 10, this.ypos(worst) - 14);
-
-    // Mark and label the slowest frame
-    ctx.beginPath();
-    var where = sampleIndex % numSamples;
-    ctx.arc(this.xpos(where), this.ypos(delays[where]), 5, 0, Math.PI*2, true);
-    ctx.fill();
-    ctx.fillStyle = 'rgb(0,0,0)';
-
-    this.drawAxisLabels('Time', 'Pause between frames (log scale)');
-}
-
-function MemoryGraph(ctx) {
-    Graph.call(this, ctx);
-    this.worstEver = this.bestEver = performance.mozMemory.zone.gcBytes;
-    this.limit = Math.max(this.worstEver, performance.mozMemory.zone.gcAllocTrigger);
-}
-
-MemoryGraph.prototype = Object.create(Graph.prototype);
+  done() {
+    return this.idx == -1;
+  }
 
-Object.defineProperty(MemoryGraph.prototype, 'constructor', {
-    enumerable: false,
-    value: MemoryGraph });
+  cycleElapsed(now = performance.now()) {
+    return now - this.cycleStart;
+  }
 
-MemoryGraph.prototype.ypos = function (size) {
-    var { height } = this.ctx.canvas;
-
-    var range = this.limit - this.bestEver;
-    var percent = (size - this.bestEver) / range;
-
-    return (1 - percent) * height * 0.9 + 20;
-}
-
-MemoryGraph.prototype.drawHBar = function (size, label, color='rgb(150,150,150)')
-{
-    var ctx = this.ctx;
-
-    var y = this.ypos(size);
-
-    ctx.fillStyle = color;
-    ctx.strokeStyle = color;
-    ctx.fillText(label, this.xpos(numSamples) + 4, y + 3);
-
-    ctx.beginPath();
-    ctx.moveTo(this.xpos(0), y);
-    ctx.lineTo(this.xpos(numSamples), y);
-    ctx.stroke();
-    ctx.strokeStyle = 'rgb(0,0,0)';
-    ctx.fillStyle = 'rgb(0,0,0)';
-}
-
-function format_gcBytes(bytes) {
-    if (bytes < 4000)
-        return `${bytes} bytes`;
-    else if (bytes < 4e6)
-        return `${(bytes / 1024).toFixed(2)} KB`;
-    else if (bytes < 4e9)
-        return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
-    else
-        return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`;
+  currentLoadElapsed(now = performance.now()) {
+    return now - this.started;
+  }
 };
 
-MemoryGraph.prototype.draw = function () {
-    var ctx = this.ctx;
-
-    this.clear();
-    this.drawFrame();
-
-    var worst = 0, worstpos = 0;
-    for (var i = 0; i < numSamples; i++) {
-        if (gcBytes[i] >= worst) {
-            worst = gcBytes[i];
-            worstpos = i;
-        }
-        if (gcBytes[i] < this.bestEver) {
-            this.bestEver = gcBytes[i];
-        }
+var AllocationLoadManager = class {
+  constructor(tests) {
+    this._loads = new Map();
+    for (const [name, info] of tests.entries()) {
+      this._loads.set(name, new AllocationLoad(info, name));
     }
-
-    if (this.worstEver < worst) {
-        this.worstEver = worst;
-        this.limit = Math.max(this.worstEver, performance.mozMemory.zone.gcAllocTrigger);
+    this._active = undefined;
+    this._paused = false;
+    this._eventsSinceLastTick = 0;
+
+    // Public API
+    this.cycle = null;
+    this.testDurationMS = gDefaultTestDuration * 1000;
+
+    // Constants
+    this.CYCLE_STARTED = 1;
+    this.CYCLE_STOPPED = 2;
+    this.LOAD_ENDED = 4;
+    this.LOAD_STARTED = 8;
+  }
+
+  activeLoad() {
+    return this._active;
+  }
+
+  setActiveLoadByName(name) {
+    if (this._active) {
+      this._active.stop();
     }
-
-    this.drawHBar(this.bestEver, `${format_gcBytes(this.bestEver)} min`, '#00cf61');
-    this.drawHBar(this.worstEver, `${format_gcBytes(this.worstEver)} max`, '#cc1111');
-    this.drawHBar(performance.mozMemory.zone.gcAllocTrigger, `${format_gcBytes(performance.mozMemory.zone.gcAllocTrigger)} trigger`, '#cc11cc');
-
-    ctx.fillStyle = 'rgb(255,0,0)';
-    if (worst)
-        ctx.fillText(format_gcBytes(worst), this.xpos(worstpos) - 10, this.ypos(worst) - 14);
-
-    ctx.beginPath();
-    var where = sampleIndex % numSamples;
-    ctx.arc(this.xpos(where), this.ypos(gcBytes[where]), 5, 0, Math.PI*2, true);
-    ctx.fill();
-
-    ctx.beginPath();
-    for (var i = 0; i < numSamples; i++) {
-        if (i == (sampleIndex + 1) % numSamples)
-            ctx.moveTo(this.xpos(i), this.ypos(gcBytes[i]));
-        else
-            ctx.lineTo(this.xpos(i), this.ypos(gcBytes[i]));
-        if (i == where)
-            ctx.stroke();
+    this._active = this._loads.get(name);
+    this._active.start();
+  }
+
+  deactivateLoad() {
+    this._active.stop();
+    this._active = undefined;
+  }
+
+  get paused() {
+    return this._paused;
+  }
+  set paused(pause) {
+    this._paused = pause;
+  }
+
+  load_running() {
+    return this._active;
+  }
+
+  change_garbagePiles(amount) {
+    if (this._active) {
+      this._active.garbagePiles = amount;
+      this._active.reload();
     }
-    ctx.stroke();
+  }
 
-    this.drawAxisLabels('Time', 'Heap Memory Usage');
-}
-
-function stopstart()
-{
-    if (stopped) {
-        window.requestAnimationFrame(handler);
-        prev = performance.now();
-        start += prev - stopped;
-        document.getElementById('stop').value = 'Pause';
-        stopped = 0;
-    } else {
-        document.getElementById('stop').value = 'Resume';
-        stopped = performance.now();
+  change_garbagePerFrame(amount) {
+    if (this._active) {
+      this._active.garbagePerFrame = amount;
     }
-}
-
-var previous = 0;
-function handler(timestamp)
-{
-    if (stopped)
-        return;
-
-    if (testState === 'running' && (timestamp - testStart) > testDuration)
-        end_test(timestamp);
-
-    if (testState == 'running')
-        document.getElementById("test-progress").textContent = ((testDuration - (timestamp - testStart))/1000).toFixed(1) + " sec";
-
-    activeTest.makeGarbage(activeTest.garbagePerFrame);
-
-    var elt = document.getElementById('data');
-    var delay = timestamp - prev;
-    prev = timestamp;
-
-    // Take the histogram at 10us intervals so that we have enough resolution to capture.
-    // a 16.66[666] target with adequate accuracy.
-    update_histogram(gHistogram, Math.round(delay * 100));
-
-    var t = timestamp - start;
-    var newIndex = Math.round(t / sampleTime);
-    while (sampleIndex < newIndex) {
-        sampleIndex++;
-        var idx = sampleIndex % numSamples;
-        delays[idx] = delay;
-        if (features.trackingSizes)
-            gcBytes[idx] = performance.mozMemory.gcBytes;
-        if (features.showingGCs) {
-            gcs[idx] = performance.mozMemory.gcNumber;
-            minorGCs[idx] = performance.mozMemory.minorGCCount;
-            majorGCs[idx] = performance.mozMemory.majorGCCount;
-
-            // Previous versions lacking sliceCount will fall back to assuming
-            // any GC activity was a major GC slice, even though that
-            // incorrectly includes minor GCs. Although this file is versioned
-            // with the code that implements the new sliceCount field, it is
-            // common to load the gc-ubench index.html with different browser
-            // versions.
-            slices[idx] = performance.mozMemory.sliceCount || performance.mozMemory.gcNumber;
+  }
+
+  tick(now = gHost.now()) {
+    this.lastActive = this._active;
+    let events = this._eventsSinceLastTick;
+    this._eventsSinceLastTick = 0;
+
+    if (this.cycle) {
+      const prev = this.cycle.current;
+      this.cycle.tick(now);
+      if (this.cycle.current != prev) {
+        if (this.cycle.current) {
+          this.setActiveLoadByName(this.cycle.current);
+        } else {
+          this.deactivateLoad();
         }
-    }
-
-    latencyGraph.draw();
-    if (memoryGraph)
-        memoryGraph.draw();
-    window.requestAnimationFrame(handler);
-}
-
-function summarize(arr) {
-    if (arr.length == 0)
-        return [];
-
-    var result = [];
-    var run_start = 0;
-    var prev = arr[0];
-    for (var i = 1; i <= arr.length; i++) {
-        if (i == arr.length || arr[i] != prev) {
-            if (i == run_start + 1) {
-                result.push(arr[i]);
-            } else {
-                result.push(prev + " x " + (i - run_start));
-            }
-            run_start = i;
+        events |= this.LOAD_ENDED;
+        if (this.cycle.done()) {
+          events |= this.CYCLE_STOPPED;
+          this.cycle = null;
+        } else {
+          events |= this.LOAD_STARTED;
         }
-        if (i != arr.length)
-            prev = arr[i];
-    }
-
-    return result;
-}
-
-function update_histogram(histogram, delay)
-{
-    var current = histogram.has(delay) ? histogram.get(delay) : 0;
-    histogram.set(delay, ++current);
-}
-
-function reset_draw_state()
-{
-    for (var i = 0; i < numSamples; i++)
-        delays[i] = 0;
-    start = prev = performance.now();
-    sampleIndex = 0;
-}
-
-function onunload()
-{
-    if (activeTest)
-        activeTest.unload();
-    activeTest = undefined;
-}
-
-function onload()
-{
-    // Load initial test duration.
-    duration_changed();
-
-    // Load initial garbage size.
-    garbage_total_changed();
-    garbage_per_frame_changed();
-
-    // Populate the test selection dropdown.
-    var select = document.getElementById("test-selection");
-    for (var [name, test] of tests) {
-        test.name = name;
-        var option = document.createElement("option");
-        option.id = name;
-        option.text = name;
-        option.title = test.description;
-        select.add(option);
+      }
     }
 
-    // Load the initial test.
-    change_active_test('noAllocation');
-
-    // Polyfill rAF.
-    var requestAnimationFrame =
-        window.requestAnimationFrame || window.mozRequestAnimationFrame ||
-        window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
-    window.requestAnimationFrame = requestAnimationFrame;
-
-    // Acquire our canvas.
-    var canvas = document.getElementById('graph');
-    latencyGraph = new LatencyGraph(canvas.getContext('2d'));
-
-    if (!performance.mozMemory) {
-        document.getElementById('memgraph-disabled').style.display = 'block';
-        document.getElementById('track-sizes-div').style.display = 'none';
+    if (this._active && !this._paused) {
+      this._active.tick();
     }
 
-    trackHeapSizes(document.getElementById('track-sizes').checked);
-
-    // Start drawing.
-    reset_draw_state();
-    window.requestAnimationFrame(handler);
-}
-
-function run_one_test()
-{
-    start_test_cycle([activeTest.name]);
-}
+    return events;
+  }
+
+  startCycle(tests_to_run, now = performance.now()) {
+    this.cycle = new LoadCycle(tests_to_run, this.testDurationMS);
+    this.cycle.start(now);
+    this.setActiveLoadByName(this.cycle.current);
+    this._eventsSinceLastTick |= this.CYCLE_STARTED | this.LOAD_STARTED;
+  }
+
+  cycleStopped() {
+    return !this.cycle || this.cycle.done();
+  }
+
+  currentLoadRemaining(now = gHost.now()) {
+    return this.cycleStopped()
+      ? 0
+      : this.testDurationMS - this.cycle.currentLoadElapsed(now);
+  }
+};
 
-function run_all_tests()
-{
-    start_test_cycle(tests.keys());
-}
+// Current test state.
+var gLoadMgr = undefined;
 
-function start_test_cycle(tests_to_run)
-{
-    // Convert from an iterable to an array for pop.
-    testQueue = [];
-    for (var key of tests_to_run)
-        testQueue.push(key);
-    testState = 'running';
-    testStart = performance.now();
-    gHistogram.clear();
-
-    start_test(testQueue.shift());
-    reset_draw_state();
+function format_with_units(n, label, shortlabel, kbase) {
+  if (n < kbase * 4) {
+    return `${n} ${label}`;
+  } else if (n < kbase ** 2 * 4) {
+    return `${(n / kbase).toFixed(2)}K${shortlabel}`;
+  } else if (n < kbase ** 3 * 4) {
+    return `${(n / kbase ** 2).toFixed(2)}M${shortlabel}`;
+  }
+  return `${(n / kbase ** 3).toFixed(2)}G${shortlabel}`;
 }
 
-function start_test(testName)
-{
-    change_active_test(testName);
-    console.log(`Running test: ${testName}`);
-    document.getElementById("test-selection").value = testName;
+function format_bytes(bytes) {
+  return format_with_units(bytes, "bytes", "B", 1024);
 }
 
-function end_test(timestamp)
-{
-    document.getElementById("test-progress").textContent = "(not running)";
-    report_test_result(activeTest, gHistogram);
-    gHistogram.clear();
-    console.log(`Ending test ${activeTest.name}`);
-    if (testQueue.length) {
-        start_test(testQueue.shift());
-        testStart = timestamp;
-    } else {
-        testState = 'idle';
-        testStart = 0;
-    }
-    reset_draw_state();
+function format_num(n) {
+  return format_with_units(n, "", "", 1000);
 }
 
-function report_test_result(test, histogram)
-{
-    var resultList = document.getElementById('results-display');
-    var resultElem = document.createElement("div");
-    var score = compute_test_score(histogram);
-    var sparks = compute_test_spark_histogram(histogram);
-    var params = `(${format_units(test.garbagePerFrame)},${format_units(test.garbageTotal)})`;
-    resultElem.innerHTML = `${score.toFixed(3)} ms/s : ${sparks} : ${test.name}${params} - ${test.description}`;
-    resultList.appendChild(resultElem);
+function update_histogram(histogram, delay) {
+  // Round to a whole number of 10us intervals to provide enough resolution to
+  // capture a 16ms target with adequate accuracy.
+  delay = Math.round(delay * 100) / 100;
+  var current = histogram.has(delay) ? histogram.get(delay) : 0;
+  histogram.set(delay, ++current);
 }
 
 // Compute a score based on the total ms we missed frames by per second.
-function compute_test_score(histogram)
-{
-    var score = 0;
-    for (var [delay, count] of histogram) {
-        delay = delay / 100;
-        score += Math.abs((delay - 16.66) * count);
-    }
-    score = score / (testDuration / 1000);
-    return Math.round(score * 1000) / 1000;
+function compute_test_score(histogram) {
+  var score = 0;
+  for (let [delay, count] of histogram) {
+    score += Math.abs((delay - 1000 / 60) * count);
+  }
+  score = score / (gLoadMgr.testDurationMS / 1000);
+  return Math.round(score * 1000) / 1000;
 }
 
 // Build a spark-lines histogram for the test results to show with the aggregate score.
-function compute_test_spark_histogram(histogram)
-{
-    var ranges = [
-        [-99999999, 16.6],
-        [16.6, 16.8],
-        [16.8, 25],
-        [25, 33.4],
-        [33.4, 60],
-        [60, 100],
-        [100, 300],
-        [300, 99999999],
-    ];
-    var rescaled = new Map();
-    for (var [delay, count] of histogram) {
-        delay = delay / 100;
-        for (var i = 0; i < ranges.length; ++i) {
-            var low = ranges[i][0];
-            var high = ranges[i][1];
-            if (low <= delay && delay < high) {
-                update_histogram(rescaled, i);
-                break;
-            }
-        }
-    }
-    var total = 0;
-    for (var [i, count] of rescaled)
-        total += count;
-    var sparks = "▁▂▃▄▅▆▇█";
-    var colors = ['#aaaa00', '#007700', '#dd0000', '#ff0000',
-                  '#ff0000', '#ff0000', '#ff0000', '#ff0000'];
-    var line = "";
+function compute_spark_histogram_percents(histogram) {
+  var ranges = [
+    [-99999999, 16.6],
+    [16.6, 16.8],
+    [16.8, 25],
+    [25, 33.4],
+    [33.4, 60],
+    [60, 100],
+    [100, 300],
+    [300, 99999999],
+  ];
+  var rescaled = new Map();
+  for (let [delay] of histogram) {
     for (var i = 0; i < ranges.length; ++i) {
-        var amt = rescaled.has(i) ? rescaled.get(i) : 0;
-        var spark = sparks.charAt(parseInt(amt/total*8));
-        line += `${spark}`;
-    }
-    return line;
-}
-
-function reload_active_test()
-{
-    activeTest.unload();
-    activeTest.load(activeTest.garbageTotal);
-}
-
-function change_active_test(new_test_name)
-{
-    if (activeTest)
-        activeTest.unload();
-    activeTest = tests.get(new_test_name);
-
-    if (!activeTest.garbagePerFrame)
-        activeTest.garbagePerFrame = parse_units(activeTest.defaultGarbagePerFrame || globalDefaultGarbagePerFrame);
-    if (!activeTest.garbageTotal)
-        activeTest.garbageTotal = parse_units(activeTest.defaultGarbageTotal || globalDefaultGarbageTotal);
-
-    document.getElementById("garbage-per-frame").value = format_units(activeTest.garbagePerFrame);
-    document.getElementById("garbage-total").value = format_units(activeTest.garbageTotal);
-
-    activeTest.load(activeTest.garbageTotal);
-}
-
-function duration_changed()
-{
-    var durationInput = document.getElementById('test-duration');
-    testDuration = parseInt(durationInput.value) * 1000;
-    console.log(`Updated test duration to: ${testDuration / 1000} seconds`);
-}
-
-function test_changed()
-{
-    var select = document.getElementById("test-selection");
-    console.log(`Switching to test: ${select.value}`);
-    change_active_test(select.value);
-    gHistogram.clear();
-    reset_draw_state();
-}
-
-function parse_units(v)
-{
-    if (v.length == 0)
-        return NaN;
-    var lastChar = v[v.length - 1].toLowerCase();
-    if (!isNaN(parseFloat(lastChar)))
-        return parseFloat(v);
-    var units = parseFloat(v.substr(0, v.length - 1));
-    if (lastChar == "k")
-        return units * 1e3;
-    if (lastChar == "m")
-        return units * 1e6;
-    if (lastChar == "g")
-        return units * 1e9;
-    return NaN;
-}
-
-function format_units(n)
-{
-    n = String(n);
-    if (n.length > 9 && n.substr(-9) == "000000000")
-        return n.substr(0, n.length - 9) + "G";
-    else if (n.length > 9 && n.substr(-6) == "000000")
-        return n.substr(0, n.length - 6) + "M";
-    else if (n.length > 3 && n.substr(-3) == "000")
-        return n.substr(0, n.length - 3) + "K";
-    else
-        return String(n);
-}
-
-function garbage_total_changed()
-{
-    var value = parse_units(document.getElementById('garbage-total').value);
-    if (isNaN(value))
-        return;
-    if (activeTest) {
-        activeTest.garbageTotal = value;
-        console.log(`Updated garbage-total to ${activeTest.garbageTotal} items`);
-        reload_active_test();
-    }
-    gHistogram.clear();
-    reset_draw_state();
-}
-
-function garbage_per_frame_changed()
-{
-    var value = parse_units(document.getElementById('garbage-per-frame').value);
-    if (isNaN(value))
-        return;
-    if (activeTest) {
-        activeTest.garbagePerFrame = value;
-        console.log(`Updated garbage-per-frame to ${activeTest.garbagePerFrame} items`);
-    }
-}
-
-function trackHeapSizes(track)
-{
-    features.trackingSizes = track;
-
-    var canvas = document.getElementById('memgraph');
-
-    if (features.trackingSizes) {
-        canvas.style.display = 'block';
-        memoryGraph = new MemoryGraph(canvas.getContext('2d'));
-    } else {
-        canvas.style.display = 'none';
-        memoryGraph = null;
+      var low = ranges[i][0];
+      var high = ranges[i][1];
+      if (low <= delay && delay < high) {
+        update_histogram(rescaled, i);
+        break;
+      }
     }
+  }
+  var total = 0;
+  for (const [, count] of rescaled) {
+    total += count;
+  }
+
+  var spark = [];
+  for (let i = 0; i < ranges.length; ++i) {
+    const amt = rescaled.has(i) ? rescaled.get(i) : 0;
+    spark.push(amt / total);
+  }
+
+  return spark;
 }
diff --git a/js/src/devtools/gc-ubench/index.html b/js/src/devtools/gc-ubench/index.html
index e4af9e01ac..e66bfaf0c1 100644
--- a/js/src/devtools/gc-ubench/index.html
+++ b/js/src/devtools/gc-ubench/index.html
@@ -7,27 +7,19 @@
   GC uBench
   
 
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-
+  
   
+  
+  
+
+  
+  
+
+  
+  
 
 
 
@@ -35,7 +27,7 @@
 
 
 
-
+
 
 
@@ -44,18 +36,38 @@
- + Update display: +
- Duration: s - - + Run allocation load + +
+ +
+ Allocation load: + + (init) +
+ +
+     Garbage items per frame: + +
+
+     Garbage piles: +
+
+
- Currently running test load: - + Duration: s + +
@@ -68,17 +80,6 @@     30 fps: n/a
-     Garbage items per frame: - -
-
-     Garbage piles: - -
-
Test Results:
diff --git a/js/src/devtools/gc-ubench/perf.js b/js/src/devtools/gc-ubench/perf.js new file mode 100644 index 0000000000..6e3b3f2c07 --- /dev/null +++ b/js/src/devtools/gc-ubench/perf.js @@ -0,0 +1,234 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Performance monitoring and calculation. + +function round_up(val, interval) { + return val + (interval - (val % interval)); +} + +// Class for inter-frame timing, which handles being paused and resumed. +var FrameTimer = class { + constructor() { + // Start time of the current active test, adjusted for any time spent + // stopped (so `now - this.start` is how long the current active test + // has run for.) + this.start = undefined; + + // Timestamp of callback following the previous frame. + this.prev = undefined; + + // Timestamp when drawing was paused, or zero if drawing is active. + this.stopped = 0; + } + + is_stopped() { + return this.stopped != 0; + } + + start_recording(now = gHost.now()) { + this.start = this.prev = now; + } + + on_frame_finished(now = gHost.now()) { + const delay = now - this.prev; + this.prev = now; + return delay; + } + + pause(now = gHost.now()) { + this.stopped = now; + // Abuse this.prev to store the time elapsed since the previous frame. + // This will be used to adjust this.prev when we resume. + this.prev = now - this.prev; + } + + resume(now = gHost.now()) { + this.prev = now - this.prev; + const stop_duration = now - this.stopped; + this.start += stop_duration; + this.stopped = 0; + } +}; + +// Per-frame time sampling infra. +var sampleTime = 16.666667; // ms +var sampleIndex = 0; + +// Class for maintaining a rolling window of per-frame GC-related counters: +// inter-frame delay, minor/major/slice GC counts, cumulative bytes, etc. +var FrameHistory = class { + constructor(numSamples) { + // Private + this._frameTimer = new FrameTimer(); + this._numSamples = numSamples; + + // Public API + this.delays = new Array(numSamples); + this.gcBytes = new Array(numSamples); + this.mallocBytes = new Array(numSamples); + this.gcs = new Array(numSamples); + this.minorGCs = new Array(numSamples); + this.majorGCs = new Array(numSamples); + this.slices = new Array(numSamples); + + sampleIndex = 0; + this.reset(); + } + + start(now = gHost.now()) { + this._frameTimer.start_recording(now); + } + + reset() { + this.delays.fill(0); + this.gcBytes.fill(0); + this.mallocBytes.fill(0); + this.gcs.fill(this.gcs[sampleIndex]); + this.minorGCs.fill(this.minorGCs[sampleIndex]); + this.majorGCs.fill(this.majorGCs[sampleIndex]); + this.slices.fill(this.slices[sampleIndex]); + + sampleIndex = 0; + } + + get numSamples() { + return this._numSamples; + } + + findMax(collection) { + // Depends on having at least one non-negative entry, and unfilled + // entries being <= max. + var maxIndex = 0; + for (let i = 0; i < this._numSamples; i++) { + if (collection[i] >= collection[maxIndex]) { + maxIndex = i; + } + } + return maxIndex; + } + + findMaxDelay() { + return this.findMax(this.delays); + } + + on_frame(now = gHost.now()) { + const delay = this._frameTimer.on_frame_finished(now); + + // Total time elapsed while the active test has been running. + var t = now - this._frameTimer.start; + var newIndex = Math.round(t / sampleTime); + while (sampleIndex < newIndex) { + sampleIndex++; + var idx = sampleIndex % this._numSamples; + this.delays[idx] = delay; + if (gHost.features.haveMemorySizes) { + this.gcBytes[idx] = gHost.gcBytes; + this.mallocBytes[idx] = gHost.mallocBytes; + } + if (gHost.features.haveGCCounts) { + this.minorGCs[idx] = gHost.minorGCCount; + this.majorGCs[idx] = gHost.majorGCCount; + this.slices[idx] = gHost.GCSliceCount; + } + } + + return delay; + } + + pause() { + this._frameTimer.pause(); + } + + resume() { + this._frameTimer.resume(); + } + + is_stopped() { + return this._frameTimer.is_stopped(); + } +}; + +var PerfTracker = class { + constructor() { + // Private + this._currentLoadStart = undefined; + this._frameCount = undefined; + this._mutating_ms = undefined; + this._suspend_sec = undefined; + this._minorGCs = undefined; + this._majorGCs = undefined; + + // Public + this.results = []; + } + + on_load_start(load, now = gHost.now()) { + this._currentLoadStart = now; + this._frameCount = 0; + this._mutating_ms = 0; + this._suspend_sec = 0; + this._majorGCs = gHost.majorGCCount; + this._minorGCs = gHost.minorGCCount; + } + + on_load_end(load, now = gHost.now()) { + const elapsed_time = (now - this._currentLoadStart) / 1000; + const full_time = round_up(elapsed_time, 1 / 60); + const frame_60fps_limit = Math.round(full_time * 60); + const dropped_60fps_frames = frame_60fps_limit - this._frameCount; + const dropped_60fps_fraction = dropped_60fps_frames / frame_60fps_limit; + + const mutating_and_gc_fraction = this._mutating_ms / (full_time * 1000); + + this.results.push({ + load, + elapsed_time, + mutating: this._mutating_ms / 1000, + mutating_and_gc_fraction, + suspended: this._suspend_sec, + full_time, + frames: this._frameCount, + dropped_60fps_frames, + dropped_60fps_fraction, + majorGCs: gHost.majorGCCount - this._majorGCs, + minorGCs: gHost.minorGCCount - this._minorGCs, + }); + this._currentLoadStart = undefined; + this._frameCount = 0; + } + + after_suspend(wait_sec) { + this._suspend_sec += wait_sec; + } + + before_mutator(now = gHost.now()) { + this._frameCount++; + } + + after_mutator(start_time, end_time = gHost.now()) { + // Warning: this is called before on_load_start is called from + // handle_tick_events. + } + + handle_tick_events(events, loadMgr, tick_start, tick_end) { + // When the load manager switches from one load to another, there will be + // the tick start, the load is switched, the new load runs for a bit, then + // the tick end. Associate the timestamp of the start of the tick with both + // the end of the previous load and the beginning of the new one. + let load_running = true; + if (events & loadMgr.LOAD_ENDED) { + this.on_load_end(loadMgr.lastActive, tick_start); + load_running = false; + } + if (events & loadMgr.LOAD_STARTED) { + this.on_load_start(loadMgr.active, tick_start); + load_running = true; + } + + if (load_running) { + this._mutating_ms += tick_end - tick_start; + } + } +}; diff --git a/js/src/devtools/gc-ubench/scheduler.js b/js/src/devtools/gc-ubench/scheduler.js new file mode 100644 index 0000000000..c0ced38703 --- /dev/null +++ b/js/src/devtools/gc-ubench/scheduler.js @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Frame schedulers: executing a frame's worth of mutation, and possibly +// waiting for a later frame. (These schedulers will halt the main thread, +// allowing background threads to continue working.) + +var Scheduler = class { + constructor(perfMonitor) { + this._perfMonitor = perfMonitor; + } + + start(loadMgr, timestamp) { + return loadMgr.start(timestamp); + } + tick(loadMgr, timestamp) {} + wait_for_next_frame(t0, tick_start, tick_end) {} +}; + +// "Sync to vsync" scheduler: after the mutator is done for a frame, wait until +// the beginning of the next 60fps frame. +var VsyncScheduler = class extends Scheduler { + tick(loadMgr, timestamp) { + this._perfMonitor.before_mutator(timestamp); + gHost.start_turn(); + const events = loadMgr.tick(timestamp); + gHost.end_turn(); + this._perfMonitor.after_mutator(timestamp); + return events; + } + + wait_for_next_frame(t0, tick_start, tick_end) { + // Compute how long until the next 60fps vsync event, and wait that long. + const elapsed = (tick_end - t0) / 1000; + const period = 1 / FPS; + const used = elapsed % period; + const delay = period - used; + gHost.suspend(delay); + this._perfMonitor.after_suspend(delay); + } +}; + +// Try to maintain 60fps, but if we overrun a frame, do more processing +// immediately to make the next frame come up as soon as possible. +var OptimizeForFrameRate = class extends Scheduler { + tick(loadMgr, timestamp) { + this._perfMonitor.before_mutator(timestamp); + gHost.start_turn(); + const events = loadMgr.tick(timestamp); + gHost.end_turn(); + this._perfMonitor.after_mutator(timestamp); + return events; + } + + wait_for_next_frame(t0, tick_start, tick_end) { + const next_frame_ms = round_up(tick_start, 1000 / FPS); + if (tick_end < next_frame_ms) { + const delay = (next_frame_ms - tick_end) / 1000; + gHost.suspend(delay); + this._perfMonitor.after_suspend(delay); + } + } +}; diff --git a/js/src/devtools/gc-ubench/shell-bench.js b/js/src/devtools/gc-ubench/shell-bench.js new file mode 100644 index 0000000000..7ace35461b --- /dev/null +++ b/js/src/devtools/gc-ubench/shell-bench.js @@ -0,0 +1,132 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var FPS = 60; +var gNumSamples = 500; + +// This requires a gHost to have been created that provides host-specific +// facilities. See eg spidermonkey.js. + +loadRelativeToScript("argparse.js"); +loadRelativeToScript("harness.js"); +loadRelativeToScript("scheduler.js"); +loadRelativeToScript("perf.js"); +loadRelativeToScript("test_list.js"); + +var gPerf = new PerfTracker(); + +var tests = new Map(); +foreach_test_file(f => loadRelativeToScript(f)); +for (const [name, info] of tests.entries()) { + if ("enabled" in info && !info.enabled) { + tests.delete(name); + } +} + +function tick(loadMgr, timestamp) { + gPerf.before_mutator(timestamp); + gHost.start_turn(); + const events = loadMgr.tick(timestamp); + gHost.end_turn(); + gPerf.after_mutator(timestamp); + return events; +} + +function report_events(events, loadMgr) { + if (events & loadMgr.LOAD_ENDED) { + print(`${loadMgr.lastActive.name} ended`); + } + if (events & loadMgr.LOAD_STARTED) { + print(`${loadMgr.activeLoad().name} starting`); + } +} + +function run(opts, loads) { + const sequence = []; + for (const mut of loads) { + if (tests.has(mut)) { + sequence.push(mut); + } else if (mut === "all") { + sequence.push(...tests.keys()); + } else { + sequence.push(...[...tests.keys()].filter(t => t.includes(mut))); + } + } + if (loads.length === 0) { + sequence.push(...tests.keys()); + } + + const loadMgr = new AllocationLoadManager(tests); + const perf = new FrameHistory(gNumSamples); + + loadMgr.startCycle(sequence); + const schedulerCtors = { + keepup: OptimizeForFrameRate, + vsync: VsyncScheduler, + }; + const scheduler = new schedulerCtors[opts.sched](gPerf); + + perf.start(); + + const t0 = gHost.now(); + + let possible = 0; + let frames = 0; + while (loadMgr.load_running()) { + const timestamp = gHost.now(); + const events = scheduler.tick(loadMgr, timestamp); + const after_tick = gHost.now(); + + perf.on_frame(timestamp); + + report_events(events, loadMgr); + + frames++; + gPerf.handle_tick_events(events, loadMgr, timestamp, gHost.now()); + if (events & loadMgr.LOAD_ENDED) { + possible += (loadMgr.testDurationMS / 1000) * FPS; + const elapsed = ((after_tick - t0) / 1000).toFixed(2); + print(` observed ${frames} / ${possible} frames in ${elapsed} seconds`); + } + + scheduler.wait_for_next_frame(t0, timestamp, after_tick); + } +} + +function report_results() { + for (const result of gPerf.results) { + const { + load, + elapsed_time, + mutating, + mutating_and_gc_fraction, + suspended, + full_time, + frames, + dropped_60fps_frames, + dropped_60fps_fraction, + minorGCs, + majorGCs, + } = result; + + const drop_pct = percent(dropped_60fps_fraction); + const mut_pct = percent(mutating_and_gc_fraction); + const mut_sec = mutating.toFixed(2); + const full_sec = full_time.toFixed(2); + const susp_sec = suspended.toFixed(2); + print(`${load.name}: + ${frames} (60fps) frames seen out of expected ${Math.floor(full_time * 60)} + ${dropped_60fps_frames} = ${drop_pct} 60fps frames dropped + ${mut_pct} of run spent mutating and GCing (${mut_sec}sec out of ${full_sec}sec vs ${susp_sec} sec waiting) + ${minorGCs} minor GCs, ${majorGCs} major GCs +`); + } +} + +var argparse = new ArgParser("JS shell microbenchmark runner"); +argparse.add_argument("--sched", { + default: "keepup", + options: ["keepup", "vsync"], + help: "frame scheduler" +}); diff --git a/js/src/devtools/gc-ubench/spidermonkey.js b/js/src/devtools/gc-ubench/spidermonkey.js new file mode 100644 index 0000000000..0ad0aa9771 --- /dev/null +++ b/js/src/devtools/gc-ubench/spidermonkey.js @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// SpiderMonkey JS shell benchmark script +// +// Usage: run $JS spidermonkey.js --help + +loadRelativeToScript("shell-bench.js"); + +var SpiderMonkey = class extends Host { + start_turn() {} + + end_turn() { + clearKeptObjects(); + maybegc(); + drainJobQueue(); + } + + suspend(duration) { + sleep(duration); + } + + get minorGCCount() { + return performance.mozMemory.gc.minorGCCount; + } + get majorGCCount() { + return performance.mozMemory.gc.majorGCCount; + } + get GCSliceCount() { + return performance.mozMemory.gc.sliceCount; + } + get gcBytes() { + return performance.mozMemory.gc.zone.gcBytes; + } + get gcAllocTrigger() { + return performance.mozMemory.gc.zone.gcAllocTrigger; + } + + features = { + haveMemorySizes: true, + haveGCCounts: true, + }; +}; + +var gHost = new SpiderMonkey(); +var { opts, rest: mutators } = argparse.parse_args(scriptArgs); +run(opts, mutators); + +print("\nTest results:\n"); +report_results(); + +var outfile = "spidermonkey-results.json"; +var origOut = redirect(outfile); +print(JSON.stringify(gPerf.results)); +redirect(origOut); +print(`Wrote detailed results to ${outfile}`); diff --git a/js/src/devtools/gc-ubench/test_list.js b/js/src/devtools/gc-ubench/test_list.js new file mode 100644 index 0000000000..03ed30cf9e --- /dev/null +++ b/js/src/devtools/gc-ubench/test_list.js @@ -0,0 +1,20 @@ +function foreach_test_file(callback) { + callback("benchmarks/noAllocation.js"); + callback("benchmarks/globalArrayNewObject.js"); + callback("benchmarks/globalArrayArrayLiteral.js"); + callback("benchmarks/globalArrayLargeArray.js"); + callback("benchmarks/globalArrayLargeObject.js"); + callback("benchmarks/globalArrayObjectLiteral.js"); + callback("benchmarks/globalArrayReallocArray.js"); + callback("benchmarks/globalArrayBuffer.js"); + callback("benchmarks/globalArrayFgFinalized.js"); + callback("benchmarks/largeArrayPropertyAndElements.js"); + callback("benchmarks/selfCyclicWeakMap.js"); + callback("benchmarks/pairCyclicWeakMap.js"); + callback("benchmarks/deepWeakMap.js"); + callback("benchmarks/textNodes.js"); + callback("benchmarks/bigTextNodes.js"); + callback("benchmarks/events.js"); + callback("benchmarks/expandoEvents.js"); + callback("benchmarks/propertyTreeSplitting.js"); +} diff --git a/js/src/devtools/gc-ubench/ui.js b/js/src/devtools/gc-ubench/ui.js new file mode 100644 index 0000000000..7ff5892931 --- /dev/null +++ b/js/src/devtools/gc-ubench/ui.js @@ -0,0 +1,696 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var stroke = { + gcslice: "rgb(255,100,0)", + minor: "rgb(0,255,100)", + initialMajor: "rgb(180,60,255)", +}; + +var numSamples = 500; + +var gHistogram = new Map(); // {ms: count} +var gHistory = new FrameHistory(numSamples); + +var latencyGraph; +var memoryGraph; +var ctx; +var memoryCtx; + +var loadState = "(init)"; // One of '(active)', '(inactive)', '(N/A)' +var testState = "idle"; // One of 'idle' or 'running'. +var enabled = { trackingSizes: false }; + +var gMemory = performance.mozMemory?.gc || performance.mozMemory || {}; + +var Firefox = class extends Host { + start_turn() { + // Handled by Gecko. + } + + end_turn() { + // Handled by Gecko. + } + + suspend(duration) { + // Not used; requestAnimationFrame takes its place. + throw new Error("unimplemented"); + } + + get minorGCCount() { + return gMemory.minorGCCount; + } + get majorGCCount() { + return gMemory.majorGCCount; + } + get GCSliceCount() { + return gMemory.sliceCount; + } + get gcBytes() { + return gMemory.zone.gcBytes; + } + get gcAllocTrigger() { + return gMemory.zone.gcAllocTrigger; + } + + features = { + haveMemorySizes: 'gcBytes' in gMemory, + haveGCCounts: 'majorGCCount' in gMemory, + }; +}; + +var gHost = new Firefox(); + +function parse_units(v) { + if (!v.length) { + return NaN; + } + var lastChar = v[v.length - 1].toLowerCase(); + if (!isNaN(parseFloat(lastChar))) { + return parseFloat(v); + } + var units = parseFloat(v.substr(0, v.length - 1)); + if (lastChar == "k") { + return units * 1e3; + } + if (lastChar == "m") { + return units * 1e6; + } + if (lastChar == "g") { + return units * 1e9; + } + return NaN; +} + +var Graph = class { + constructor(ctx) { + this.ctx = ctx; + + var { height } = ctx.canvas; + this.layout = { + xAxisLabel_Y: height - 20, + }; + } + + xpos(index) { + return index * 2; + } + + clear() { + const { width, height } = this.ctx.canvas; + this.ctx.clearRect(0, 0, width, height); + } + + drawScale(delay) { + this.drawHBar(delay, `${delay}ms`, "rgb(150,150,150)"); + } + + draw60fps() { + this.drawHBar(1000 / 60, "60fps", "#00cf61", 25); + } + + draw30fps() { + this.drawHBar(1000 / 30, "30fps", "#cf0061", 25); + } + + drawAxisLabels(x_label, y_label) { + const ctx = this.ctx; + const { width, height } = ctx.canvas; + + ctx.fillText(x_label, width / 2, this.layout.xAxisLabel_Y); + + ctx.save(); + ctx.rotate(Math.PI / 2); + var start = height / 2 - ctx.measureText(y_label).width / 2; + ctx.fillText(y_label, start, -width + 20); + ctx.restore(); + } + + drawFrame() { + const ctx = this.ctx; + const { width, height } = ctx.canvas; + + // Draw frame to show size + ctx.strokeStyle = "rgb(0,0,0)"; + ctx.fillStyle = "rgb(0,0,0)"; + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(width, 0); + ctx.lineTo(width, height); + ctx.lineTo(0, height); + ctx.closePath(); + ctx.stroke(); + } +}; + +var LatencyGraph = class extends Graph { + constructor(ctx) { + super(ctx); + console.log(this.ctx); + } + + ypos(delay) { + const { height } = this.ctx.canvas; + + const r = height + 100 - Math.log(delay) * 64; + if (r < 5) { + return 5; + } + return r; + } + + drawHBar(delay, label, color = "rgb(0,0,0)", label_offset = 0) { + const ctx = this.ctx; + + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.fillText( + label, + this.xpos(numSamples) + 4 + label_offset, + this.ypos(delay) + 3 + ); + + ctx.beginPath(); + ctx.moveTo(this.xpos(0), this.ypos(delay)); + ctx.lineTo(this.xpos(numSamples) + label_offset, this.ypos(delay)); + ctx.stroke(); + ctx.strokeStyle = "rgb(0,0,0)"; + ctx.fillStyle = "rgb(0,0,0)"; + } + + draw() { + const ctx = this.ctx; + + this.clear(); + this.drawFrame(); + + for (var delay of [10, 20, 30, 50, 100, 200, 400, 800]) { + this.drawScale(delay); + } + this.draw60fps(); + this.draw30fps(); + + var worst = 0, + worstpos = 0; + ctx.beginPath(); + for (let i = 0; i < numSamples; i++) { + ctx.lineTo(this.xpos(i), this.ypos(gHistory.delays[i])); + if (gHistory.delays[i] >= worst) { + worst = gHistory.delays[i]; + worstpos = i; + } + } + ctx.stroke(); + + // Draw vertical lines marking minor and major GCs + if (gHost.features.haveGCCounts) { + ctx.strokeStyle = stroke.gcslice; + let idx = sampleIndex % numSamples; + const count = { + major: gHistory.majorGCs[idx], + minor: 0, + slice: gHistory.slices[idx], + }; + for (let i = 0; i < numSamples; i++) { + idx = (sampleIndex + i) % numSamples; + const isMajorStart = count.major < gHistory.majorGCs[idx]; + if (count.slice < gHistory.slices[idx]) { + if (isMajorStart) { + ctx.strokeStyle = stroke.initialMajor; + } + ctx.beginPath(); + ctx.moveTo(this.xpos(idx), 0); + ctx.lineTo(this.xpos(idx), this.layout.xAxisLabel_Y); + ctx.stroke(); + if (isMajorStart) { + ctx.strokeStyle = stroke.gcslice; + } + } + count.major = gHistory.majorGCs[idx]; + count.slice = gHistory.slices[idx]; + } + + ctx.strokeStyle = stroke.minor; + idx = sampleIndex % numSamples; + count.minor = gHistory.minorGCs[idx]; + for (let i = 0; i < numSamples; i++) { + idx = (sampleIndex + i) % numSamples; + if (count.minor < gHistory.minorGCs[idx]) { + ctx.beginPath(); + ctx.moveTo(this.xpos(idx), 0); + ctx.lineTo(this.xpos(idx), 20); + ctx.stroke(); + } + count.minor = gHistory.minorGCs[idx]; + } + } + + ctx.fillStyle = "rgb(255,0,0)"; + if (worst) { + ctx.fillText( + `${worst.toFixed(2)}ms`, + this.xpos(worstpos) - 10, + this.ypos(worst) - 14 + ); + } + + // Mark and label the slowest frame + ctx.beginPath(); + var where = sampleIndex % numSamples; + ctx.arc( + this.xpos(where), + this.ypos(gHistory.delays[where]), + 5, + 0, + Math.PI * 2, + true + ); + ctx.fill(); + ctx.fillStyle = "rgb(0,0,0)"; + + this.drawAxisLabels("Time", "Pause between frames (log scale)"); + } +}; + +var MemoryGraph = class extends Graph { + constructor(ctx) { + super(ctx); + this.worstEver = this.bestEver = gHost.gcBytes(); + this.limit = Math.max(this.worstEver, gHost.gcAllocTrigger); + } + + ypos(size) { + const { height } = this.ctx.canvas; + + const range = this.limit - this.bestEver; + const percent = (size - this.bestEver) / range; + + return (1 - percent) * height * 0.9 + 20; + } + + drawHBar(size, label, color = "rgb(150,150,150)") { + const ctx = this.ctx; + + const y = this.ypos(size); + + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.fillText(label, this.xpos(numSamples) + 4, y + 3); + + ctx.beginPath(); + ctx.moveTo(this.xpos(0), y); + ctx.lineTo(this.xpos(numSamples), y); + ctx.stroke(); + ctx.strokeStyle = "rgb(0,0,0)"; + ctx.fillStyle = "rgb(0,0,0)"; + } + + draw() { + const ctx = this.ctx; + + this.clear(); + this.drawFrame(); + + var worst = 0, + worstpos = 0; + for (let i = 0; i < numSamples; i++) { + if (gHistory.gcBytes[i] >= worst) { + worst = gHistory.gcBytes[i]; + worstpos = i; + } + if (gHistory.gcBytes[i] < this.bestEver) { + this.bestEver = gHistory.gcBytes[i]; + } + } + + if (this.worstEver < worst) { + this.worstEver = worst; + this.limit = Math.max(this.worstEver, gHost.gcAllocTrigger); + } + + this.drawHBar( + this.bestEver, + `${format_bytes(this.bestEver)} min`, + "#00cf61" + ); + this.drawHBar( + this.worstEver, + `${format_bytes(this.worstEver)} max`, + "#cc1111" + ); + this.drawHBar( + gHost.gcAllocTrigger, + `${format_bytes(gHost.gcAllocTrigger)} trigger`, + "#cc11cc" + ); + + ctx.fillStyle = "rgb(255,0,0)"; + if (worst) { + ctx.fillText( + format_bytes(worst), + this.xpos(worstpos) - 10, + this.ypos(worst) - 14 + ); + } + + ctx.beginPath(); + var where = sampleIndex % numSamples; + ctx.arc( + this.xpos(where), + this.ypos(gHistory.gcBytes[where]), + 5, + 0, + Math.PI * 2, + true + ); + ctx.fill(); + + ctx.beginPath(); + for (let i = 0; i < numSamples; i++) { + if (i == (sampleIndex + 1) % numSamples) { + ctx.moveTo(this.xpos(i), this.ypos(gHistory.gcBytes[i])); + } else { + ctx.lineTo(this.xpos(i), this.ypos(gHistory.gcBytes[i])); + } + if (i == where) { + ctx.stroke(); + } + } + ctx.stroke(); + + this.drawAxisLabels("Time", "Heap Memory Usage"); + } +}; + +function onUpdateDisplayChanged() { + const do_graph = document.getElementById("do-graph"); + if (do_graph.checked) { + window.requestAnimationFrame(handler); + gHistory.resume(); + } else { + gHistory.pause(); + } + update_load_state_indicator(); +} + +function onDoLoadChange() { + const do_load = document.getElementById("do-load"); + gLoadMgr.paused = !do_load.checked; + console.log(`load paused: ${gLoadMgr.paused}`); + update_load_state_indicator(); +} + +var previous = 0; +function handler(timestamp) { + if (gHistory.is_stopped()) { + return; + } + + const events = gLoadMgr.tick(timestamp); + if (events & gLoadMgr.LOAD_ENDED) { + end_test(timestamp, gLoadMgr.lastActive); + if (!gLoadMgr.cycleStopped()) { + start_test(); + } + update_load_display(); + } + + if (testState == "running") { + document.getElementById("test-progress").textContent = + (gLoadMgr.currentLoadRemaining(timestamp) / 1000).toFixed(1) + " sec"; + } + + const delay = gHistory.on_frame(timestamp); + + update_histogram(gHistogram, delay); + + latencyGraph.draw(); + if (memoryGraph) { + memoryGraph.draw(); + } + window.requestAnimationFrame(handler); +} + +// For interactive debugging. +// +// ['a', 'b', 'b', 'b', 'c', 'c'] => ['a', 'b x 3', 'c x 2'] +function summarize(arr) { + if (!arr.length) { + return []; + } + + var result = []; + var run_start = 0; + var prev = arr[0]; + for (let i = 1; i <= arr.length; i++) { + if (i == arr.length || arr[i] != prev) { + if (i == run_start + 1) { + result.push(arr[i]); + } else { + result.push(prev + " x " + (i - run_start)); + } + run_start = i; + } + if (i != arr.length) { + prev = arr[i]; + } + } + + return result; +} + +function reset_draw_state() { + gHistory.reset(); +} + +function onunload() { + gLoadMgr.deactivateLoad(); +} + +function onload() { + // The order of `tests` is currently based on their asynchronous load + // order, rather than the listed order. Rearrange by extracting the test + // names from their filenames, which is kind of gross. + _tests = tests; + tests = new Map(); + foreach_test_file(fn => { + // "benchmarks/foo.js" => "foo" + const name = fn.split(/\//)[1].split(/\./)[0]; + tests.set(name, _tests.get(name)); + }); + _tests = undefined; + + gLoadMgr = new AllocationLoadManager(tests); + + // Load initial test duration. + duration_changed(); + + // Load initial garbage size. + garbage_piles_changed(); + garbage_per_frame_changed(); + + // Populate the test selection dropdown. + var select = document.getElementById("test-selection"); + for (var [name, test] of tests) { + test.name = name; + var option = document.createElement("option"); + option.id = name; + option.text = name; + option.title = test.description; + select.add(option); + } + + // Load the initial test. + gLoadMgr.setActiveLoadByName("noAllocation"); + update_load_display(); + document.getElementById("test-selection").value = "noAllocation"; + + // Polyfill rAF. + var requestAnimationFrame = + window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame; + window.requestAnimationFrame = requestAnimationFrame; + + // Acquire our canvas. + var canvas = document.getElementById("graph"); + latencyGraph = new LatencyGraph(canvas.getContext("2d")); + + if (!gHost.features.haveMemorySizes) { + document.getElementById("memgraph-disabled").style.display = "block"; + document.getElementById("track-sizes-div").style.display = "none"; + } + + trackHeapSizes(document.getElementById("track-sizes").checked); + + update_load_state_indicator(); + gHistory.start(); + + // Start drawing. + reset_draw_state(); + window.requestAnimationFrame(handler); +} + +function run_one_test() { + start_test_cycle([gLoadMgr.activeLoad().name]); +} + +function run_all_tests() { + start_test_cycle(tests.keys()); +} + +function start_test_cycle(tests_to_run) { + // Convert from an iterable to an array for pop. + gLoadMgr.startCycle(tests_to_run); + testState = "running"; + gHistogram.clear(); + reset_draw_state(); +} + +function update_load_state_indicator() { + if ( + !gLoadMgr.load_running() || + gLoadMgr.activeLoad().name == "noAllocation" + ) { + loadState = "(none)"; + } else if (gHistory.is_stopped() || gLoadMgr.paused) { + loadState = "(inactive)"; + } else { + loadState = "(active)"; + } + document.getElementById("load-running").textContent = loadState; +} + +function start_test() { + console.log(`Running test: ${gLoadMgr.activeLoad().name}`); + document.getElementById("test-selection").value = gLoadMgr.activeLoad().name; + update_load_state_indicator(); +} + +function end_test(timestamp, load) { + document.getElementById("test-progress").textContent = "(not running)"; + report_test_result(load, gHistogram); + gHistogram.clear(); + console.log(`Ending test ${load.name}`); + if (gLoadMgr.cycleStopped()) { + testState = "idle"; + } + update_load_state_indicator(); + reset_draw_state(); +} + +function compute_test_spark_histogram(histogram) { + const percents = compute_spark_histogram_percents(histogram); + + var sparks = "▁▂▃▄▅▆▇█"; + var colors = [ + "#aaaa00", + "#007700", + "#dd0000", + "#ff0000", + "#ff0000", + "#ff0000", + "#ff0000", + "#ff0000", + ]; + var line = ""; + for (let i = 0; i < percents.length; ++i) { + var spark = sparks.charAt(parseInt(percents[i] * sparks.length)); + line += `${spark}`; + } + return line; +} + +function report_test_result(load, histogram) { + var resultList = document.getElementById("results-display"); + var resultElem = document.createElement("div"); + var score = compute_test_score(histogram); + var sparks = compute_test_spark_histogram(histogram); + var params = `(${format_num(load.garbagePerFrame)},${format_num( + load.garbagePiles + )})`; + resultElem.innerHTML = `${score.toFixed(3)} ms/s : ${sparks} : ${ + load.name + }${params} - ${load.description}`; + resultList.appendChild(resultElem); +} + +function update_load_display() { + const garbage = gLoadMgr.activeLoad() + ? gLoadMgr.activeLoad().garbagePerFrame + : parse_units(gDefaultGarbagePerFrame); + document.getElementById("garbage-per-frame").value = format_num(garbage); + const piles = gLoadMgr.activeLoad() + ? gLoadMgr.activeLoad().garbagePiles + : parse_units(gDefaultGarbagePiles); + document.getElementById("garbage-piles").value = format_num(piles); + update_load_state_indicator(); +} + +function duration_changed() { + var durationInput = document.getElementById("test-duration"); + gLoadMgr.testDurationMS = parseInt(durationInput.value) * 1000; + console.log( + `Updated test duration to: ${gLoadMgr.testDurationMS / 1000} seconds` + ); +} + +function onLoadChange() { + var select = document.getElementById("test-selection"); + console.log(`Switching to test: ${select.value}`); + gLoadMgr.setActiveLoadByName(select.value); + update_load_display(); + gHistogram.clear(); + reset_draw_state(); +} + +function garbage_piles_changed() { + const input = document.getElementById("garbage-piles"); + const value = parse_units(input.value); + if (isNaN(value)) { + update_load_display(); + return; + } + + if (gLoadMgr.load_running()) { + gLoadMgr.change_garbagePiles(value); + console.log( + `Updated garbage-piles to ${gLoadMgr.activeLoad().garbagePiles} items` + ); + } + gHistogram.clear(); + reset_draw_state(); +} + +function garbage_per_frame_changed() { + const input = document.getElementById("garbage-per-frame"); + var value = parse_units(input.value); + if (isNaN(value)) { + update_load_display(); + return; + } + if (gLoadMgr.load_running()) { + gLoadMgr.change_garbagePerFrame = value; + console.log( + `Updated garbage-per-frame to ${ + gLoadMgr.activeLoad().garbagePerFrame + } items` + ); + } +} + +function trackHeapSizes(track) { + enabled.trackingSizes = track && gHost.features.haveMemorySizes; + + var canvas = document.getElementById("memgraph"); + + if (enabled.trackingSizes) { + canvas.style.display = "block"; + memoryGraph = new MemoryGraph(canvas.getContext("2d")); + } else { + canvas.style.display = "none"; + memoryGraph = null; + } +} diff --git a/js/src/devtools/gc-ubench/v8.js b/js/src/devtools/gc-ubench/v8.js new file mode 100644 index 0000000000..0c46c2b4c4 --- /dev/null +++ b/js/src/devtools/gc-ubench/v8.js @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// V8 JS shell benchmark script +// +// Usage: run d8 v8.js -- --help + +globalThis.loadRelativeToScript = load; + +load("shell-bench.js"); + +var V8 = class extends Host { + constructor() { + super(); + this.waitTA = new Int32Array(new SharedArrayBuffer(4)); + } + + start_turn() {} + + end_turn() {} + + suspend(duration) { + const response = Atomics.wait(this.waitTA, 0, 0, duration * 1000); + if (response !== 'timed-out') { + throw new Exception(`unexpected response from Atomics.wait: ${response}`); + } + } + + features = { + haveMemorySizes: false, + haveGCCounts: false + }; +}; + +var gHost = new V8(); + +var { opts, rest: mutators } = argparse.parse_args(arguments); +run(opts, mutators); + +print("\nTest results:\n"); +report_results(); diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index 723ed62bd3..0c319ef6ea 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -388,10 +388,6 @@ function extraRootedGCThings() function extraRootedPointers() { return [ - // These are not actually rooted, but are only used in the context of - // AutoKeepAtoms. - 'js::frontend::TokenStream', - 'js::frontend::TokenStreamAnyChars', ]; } diff --git a/js/src/doc/Debugger/Debugger.Object.md b/js/src/doc/Debugger/Debugger.Object.md index e9236cb70e..a00c486ff0 100644 --- a/js/src/doc/Debugger/Debugger.Object.md +++ b/js/src/doc/Debugger/Debugger.Object.md @@ -118,7 +118,7 @@ var s = f(function () {}); // display name: s< ``` ### `parameterNames` -If the referent is a debuggee function, the names of the its parameters, +If the referent is a debuggee function, the names of its parameters, as an array of strings. If the referent is not a debuggee function, or not a function at all, this is `undefined`. @@ -128,9 +128,9 @@ is `undefined`. If the referent is a function proxy, return an empty array. -If the referent uses destructuring parameters, then the array's elements -reflect the structure of the parameters. For example, if the referent is -a function declared in this way: +If the function uses destructuring parameters, the corresponding array elements +are `undefined`. For example, if the referent is a function declared in this +way: ```js function f(a, [b, c], {d, e:f}) { ... } @@ -140,7 +140,7 @@ then this `Debugger.Object` instance's `parameterNames` property would have the value: ```js -["a", ["b", "c"], {d:"d", e:"f"}] +["a", undefined, undefined] ``` ### `script` @@ -154,6 +154,9 @@ If the referent is a function that is debuggee code, a environment enclosing the function when it was created. If the referent is a function proxy or not debuggee code, this is `undefined`. +### `isError` +`true` if the referent is any potentially wrapped Error; `false` otherwise. + ### `errorMessageName` If the referent is an error created with an engine internal message template this is a string which is the name of the template; `undefined` otherwise. diff --git a/js/src/doc/Debugger/Debugger.Script.md b/js/src/doc/Debugger/Debugger.Script.md index 41abc30bdc..c0d792bb7b 100644 --- a/js/src/doc/Debugger/Debugger.Script.md +++ b/js/src/doc/Debugger/Debugger.Script.md @@ -139,6 +139,28 @@ var s = f(function () {}); // display name: s< **If the instance refers to WebAssembly code**, throw a `TypeError`. +### `parameterNames` +**If the instance refers to a `JSScript`**, the names of its parameters, +as an array of strings. If the script is not a function script this is +`undefined`. + +If the function uses destructuring parameters, the corresponding array elements +are `undefined`. For example, if the referent is a function script declared in this +way: + +```js +function f(a, [b, c], {d, e:f}) { ... } +``` + +then this `Debugger.Script` instance's `parameterNames` property would +have the value: + +```js +["a", undefined, undefined] +``` + +**If the instance refers to WebAssembly code**, throw a `TypeError`. + ### `url` **If the instance refers to a `JSScript`**, the filename or URL from which this script's code was loaded. For scripts created by `eval` or the diff --git a/js/src/ds/Bitmap.cpp b/js/src/ds/Bitmap.cpp index fea1b00283..57dd5c9770 100644 --- a/js/src/ds/Bitmap.cpp +++ b/js/src/ds/Bitmap.cpp @@ -99,19 +99,3 @@ void SparseBitmap::bitwiseOrInto(DenseBitmap& other) const { } } } - -void SparseBitmap::bitwiseOrRangeInto(size_t wordStart, size_t numWords, - uintptr_t* target) const { - size_t blockWord = blockStartWord(wordStart); - - // We only support using a single bit block in this API. - MOZ_ASSERT(numWords && - (blockWord == blockStartWord(wordStart + numWords - 1))); - - BitBlock* block = getBlock(blockWord / WordsInBlock); - if (block) { - for (size_t i = 0; i < numWords; i++) { - target[i] |= (*block)[wordStart - blockWord + i]; - } - } -} diff --git a/js/src/ds/Bitmap.h b/js/src/ds/Bitmap.h index 69fb499990..c0fb015bf0 100644 --- a/js/src/ds/Bitmap.h +++ b/js/src/ds/Bitmap.h @@ -16,6 +16,7 @@ #include "js/AllocPolicy.h" #include "js/HashTable.h" +#include "js/HeapAPI.h" #include "js/Vector.h" // This file provides two classes for representing bitmaps. @@ -48,15 +49,18 @@ class DenseBitmap { uintptr_t word(size_t i) const { return data[i]; } uintptr_t& word(size_t i) { return data[i]; } - void copyBitsFrom(size_t wordStart, size_t numWords, uintptr_t* source) { + template + typename std::enable_if_t, void> + copyBitsFrom(size_t wordStart, size_t numWords, T* source) { MOZ_ASSERT(wordStart + numWords <= data.length()); - // Use std::copy and not std::copy_n because the former requires no - // overlap and so provides extra opportunity to optimize. - std::copy(source, source + numWords, &data[wordStart]); + for (size_t i = 0; i < numWords; i++) { + data[wordStart + i] = source[i]; + } } - void bitwiseOrRangeInto(size_t wordStart, size_t numWords, - uintptr_t* target) const { + template + typename std::enable_if_t, void> + bitwiseOrRangeInto(size_t wordStart, size_t numWords, T* target) const { for (size_t i = 0; i < numWords; i++) { target[i] |= data[wordStart + i]; } @@ -147,8 +151,22 @@ class SparseBitmap { // Currently, this API only supports a range of words that is in a single bit // block. - void bitwiseOrRangeInto(size_t wordStart, size_t numWords, - uintptr_t* target) const; + template + typename std::enable_if_t, void> + bitwiseOrRangeInto(size_t wordStart, size_t numWords, T* target) const { + size_t blockWord = blockStartWord(wordStart); + + // We only support using a single bit block in this API. + MOZ_ASSERT(numWords && + (blockWord == blockStartWord(wordStart + numWords - 1))); + + BitBlock* block = getBlock(blockWord / WordsInBlock); + if (block) { + for (size_t i = 0; i < numWords; i++) { + target[i] |= (*block)[wordStart - blockWord + i]; + } + } + } }; } // namespace js diff --git a/js/src/ds/Fifo.h b/js/src/ds/Fifo.h index 79f79d69a9..a3b19fd00f 100644 --- a/js/src/ds/Fifo.h +++ b/js/src/ds/Fifo.h @@ -5,9 +5,8 @@ #ifndef js_Fifo_h #define js_Fifo_h -#include "mozilla/Move.h" - #include +#include #include "js/Vector.h" diff --git a/js/src/ds/InlineTable.h b/js/src/ds/InlineTable.h index 13475eb5c4..3e84783e5d 100644 --- a/js/src/ds/InlineTable.h +++ b/js/src/ds/InlineTable.h @@ -6,7 +6,8 @@ #define ds_InlineTable_h #include "mozilla/Maybe.h" -#include "mozilla/Move.h" + +#include #include "js/AllocPolicy.h" #include "js/HashTable.h" diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index 0e21938c33..4091aef993 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -9,7 +9,6 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryChecking.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" #include "mozilla/PodOperations.h" #include "mozilla/TemplateLib.h" @@ -17,6 +16,7 @@ #include #include // size_t #include +#include // This data structure supports stacky LIFO allocation (mark/release and // LifoAllocScope). It does not maintain one contiguous segment; instead, it @@ -721,12 +721,9 @@ class LifoAlloc { #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) LifoAlloc* lifoAlloc_; bool prevFallibleScope_; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER public: - explicit AutoFallibleScope( - LifoAlloc* lifoAlloc MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; + explicit AutoFallibleScope(LifoAlloc* lifoAlloc) { lifoAlloc_ = lifoAlloc; prevFallibleScope_ = lifoAlloc->fallibleScope_; lifoAlloc->fallibleScope_ = true; @@ -945,15 +942,12 @@ class MOZ_NON_TEMPORARY_CLASS LifoAllocScope { LifoAlloc* lifoAlloc; LifoAlloc::Mark mark; LifoAlloc::AutoFallibleScope fallibleScope; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER public: - explicit LifoAllocScope(LifoAlloc* lifoAlloc MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + explicit LifoAllocScope(LifoAlloc* lifoAlloc) : lifoAlloc(lifoAlloc), mark(lifoAlloc->mark()), - fallibleScope(lifoAlloc) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } + fallibleScope(lifoAlloc) {} ~LifoAllocScope() { lifoAlloc->release(mark); diff --git a/js/src/ds/OrderedHashTable.h b/js/src/ds/OrderedHashTable.h index 93b8656bd9..0463f801ca 100644 --- a/js/src/ds/OrderedHashTable.h +++ b/js/src/ds/OrderedHashTable.h @@ -36,7 +36,8 @@ */ #include "mozilla/HashFunctions.h" -#include "mozilla/Move.h" + +#include #include "js/HashTable.h" diff --git a/js/src/frontend/AbstractScopePtr.cpp b/js/src/frontend/AbstractScopePtr.cpp index fb1edb2d8d..f66bd3c477 100644 --- a/js/src/frontend/AbstractScopePtr.cpp +++ b/js/src/frontend/AbstractScopePtr.cpp @@ -14,69 +14,46 @@ using namespace js; using namespace js::frontend; -MutableHandle AbstractScopePtr::scopeCreationData() const { +ScopeStencil& AbstractScopePtr::scopeData() const { const Deferred& data = scope_.as(); - return data.compilationInfo.scopeCreationData[data.index.index]; + return data.compilationInfo.stencil.scopeData[data.index.index]; } -// This is used during allocation of the scopes to ensure that we only -// allocate GC scopes with GC-enclosing scopes. This can recurse through -// the scope chain. -// -// Once all ScopeCreation for a compilation tree is centralized, this -// will go away, to be replaced with a single top down GC scope allocation. -// -// This uses an outparam to disambiguate between the case where we have a -// real nullptr scope and we failed to allocate a new scope because of OOM. -bool AbstractScopePtr::getOrCreateScope(JSContext* cx, - MutableHandleScope scope) { - if (isScopeCreationData()) { - MutableHandle scd = scopeCreationData(); - if (scd.get().hasScope()) { - scope.set(scd.get().getScope()); - return true; - } - - scope.set(scd.get().createScope(cx)); - return scope; - } - - scope.set(this->scope()); - return true; +CompilationInfo& AbstractScopePtr::compilationInfo() const { + const Deferred& data = scope_.as(); + return data.compilationInfo; } -Scope* AbstractScopePtr::getExistingScope() const { - if (scope_.is()) { - return scope_.as(); +Scope* AbstractScopePtr::existingScope(CompilationGCOutput& gcOutput) const { + if (isScopeStencil()) { + const Deferred& data = scope_.as(); + Scope* result = gcOutput.scopes[data.index.index]; + MOZ_ASSERT(result, "Scope must already exist to use this method"); + return result; } - MOZ_ASSERT(isScopeCreationData()); - // This should only be called post-reification, as it needs to return a real - // Scope* unless it represents nullptr (in which case the variant should be - // in HeapPtrScope and handled above) - MOZ_ASSERT(scopeCreationData().get().getScope()); - return scopeCreationData().get().getScope(); + return scope(); } ScopeKind AbstractScopePtr::kind() const { MOZ_ASSERT(!isNullptr()); - if (isScopeCreationData()) { - return scopeCreationData().get().kind(); + if (isScopeStencil()) { + return scopeData().kind(); } return scope()->kind(); } AbstractScopePtr AbstractScopePtr::enclosing() const { MOZ_ASSERT(!isNullptr()); - if (isScopeCreationData()) { - return scopeCreationData().get().enclosing(); + if (isScopeStencil()) { + return scopeData().enclosing(compilationInfo()); } return AbstractScopePtr(scope()->enclosing()); } bool AbstractScopePtr::hasEnvironment() const { MOZ_ASSERT(!isNullptr()); - if (isScopeCreationData()) { - return scopeCreationData().get().hasEnvironment(); + if (isScopeStencil()) { + return scopeData().hasEnvironment(); } return scope()->hasEnvironment(); } @@ -85,15 +62,16 @@ bool AbstractScopePtr::isArrow() const { // nullptr will also fail the below assert, so effectively also checking // !isNullptr() MOZ_ASSERT(is()); - if (isScopeCreationData()) { - return scopeCreationData().get().isArrow(); + if (isScopeStencil()) { + return scopeData().isArrow(); } + MOZ_ASSERT(scope()->as().canonicalFunction()); return scope()->as().canonicalFunction()->isArrow(); } uint32_t AbstractScopePtr::nextFrameSlot() const { - if (isScopeCreationData()) { - return scopeCreationData().get().nextFrameSlot(); + if (isScopeStencil()) { + return scopeData().nextFrameSlot(); } switch (kind()) { @@ -105,6 +83,7 @@ uint32_t AbstractScopePtr::nextFrameSlot() const { case ScopeKind::SimpleCatch: case ScopeKind::Catch: case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: return scope()->as().nextFrameSlot(); case ScopeKind::NamedLambda: case ScopeKind::StrictNamedLambda: diff --git a/js/src/frontend/AbstractScopePtr.h b/js/src/frontend/AbstractScopePtr.h index b22d02769e..4609d3909b 100644 --- a/js/src/frontend/AbstractScopePtr.h +++ b/js/src/frontend/AbstractScopePtr.h @@ -5,6 +5,7 @@ #ifndef frontend_AbstractScopePtr_h #define frontend_AbstractScopePtr_h +#include "mozilla/Maybe.h" #include "mozilla/Variant.h" #include "frontend/TypedIndex.h" @@ -18,13 +19,13 @@ namespace js { class Scope; class GlobalScope; class EvalScope; -struct FieldInitializers; +struct MemberInitializers; class GCMarker; namespace frontend { struct CompilationInfo; -class FunctionBox; -class ScopeCreationData; +struct CompilationGCOutput; +class ScopeStencil; } // namespace frontend using ScopeIndex = frontend::TypedIndex; @@ -33,8 +34,8 @@ using HeapPtrScope = HeapPtr; // An interface class to support Scope queries in the frontend without requiring // a GC Allocated scope to necessarily exist. // -// This abstracts Scope* (and a future ScopeCreationData type used within the -// frontend before the Scope is allocated) +// This abstracts Scope* and a ScopeStencil type used within the frontend before +// the Scope is allocated. // // Because a AbstractScopePtr may hold onto a Scope, it must be rooted if a GC // may occur to ensure that the scope is traced. @@ -54,16 +55,10 @@ class AbstractScopePtr { private: ScopeType scope_ = ScopeType(HeapPtrScope()); - // Extract the Scope* represented by this; may be nullptr, and will - // forward through to the ScopeCreationData if it has a Scope* - // - // Should only be used after getOrCreate() has been used to reify this into a - // Scope. - Scope* getExistingScope() const; + Scope* scope() const { return scope_.as(); } public: friend class js::Scope; - friend class js::frontend::FunctionBox; AbstractScopePtr() = default; @@ -73,7 +68,7 @@ class AbstractScopePtr { : scope_(Deferred{scope, compilationInfo}) {} bool isNullptr() const { - if (isScopeCreationData()) { + if (isScopeStencil()) { return false; } return scope_.as() == nullptr; @@ -85,17 +80,15 @@ class AbstractScopePtr { // indicates the end of the scope chain. explicit operator bool() const { return !isNullptr(); } - bool isScopeCreationData() const { return scope_.is(); } + bool isScopeStencil() const { return scope_.is(); } // Note: this handle is rooted in the CompilationInfo. - MutableHandle scopeCreationData() const; - - Scope* scope() const { return scope_.as(); } + frontend::ScopeStencil& scopeData() const; + frontend::CompilationInfo& compilationInfo() const; - // Get a Scope*, creating it from a ScopeCreationData if required. - // Used to allow us to ensure that Scopes are always allocated with - // real GC allocated Enclosing scopes. - bool getOrCreateScope(JSContext* cx, MutableHandleScope scope); + // Concrete GC scope. If a deferred scope, the target must already have been + // converted to a GC scope. + Scope* existingScope(frontend::CompilationGCOutput& gcOutput) const; // This allows us to check whether or not this provider wraps // or otherwise would reify to a particular scope type. diff --git a/js/src/frontend/BCEParserHandle.h b/js/src/frontend/BCEParserHandle.h index 3736423c50..63dda9737d 100644 --- a/js/src/frontend/BCEParserHandle.h +++ b/js/src/frontend/BCEParserHandle.h @@ -8,6 +8,7 @@ #include "frontend/ErrorReporter.h" #include "frontend/FullParseHandler.h" #include "frontend/Parser.h" +#include "frontend/ParserAtom.h" namespace js { namespace frontend { diff --git a/js/src/frontend/BinAST-macros.h b/js/src/frontend/BinAST-macros.h deleted file mode 100644 index 57b42bc67f..0000000000 --- a/js/src/frontend/BinAST-macros.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinAST_macros_h -#define frontend_BinAST_macros_h - -#include "vm/JSContext.h" - -// Evaluate an expression EXPR, checking that the result is not falsy. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define BINJS_TRY(EXPR) \ - do { \ - if (MOZ_UNLIKELY(!(EXPR))) { \ - return cx_->alreadyReportedError(); \ - } \ - } while (false) - -// Evaluate an expression EXPR, checking that the result is not falsy. -// In case of success, assign the result to VAR. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define BINJS_TRY_VAR(VAR, EXPR) \ - do { \ - VAR = (EXPR); \ - if (MOZ_UNLIKELY(!(VAR))) { \ - return cx_->alreadyReportedError(); \ - } \ - } while (false) - -// Evaluate an expression EXPR, checking that the result is not falsy. -// In case of success, assign the result to a new variable VAR. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define BINJS_TRY_DECL(VAR, EXPR) \ - auto VAR = (EXPR); \ - if (MOZ_UNLIKELY(!(VAR))) { \ - return cx_->alreadyReportedError(); \ - } - -#define BINJS_TRY_EMPL(VAR, EXPR) \ - do { \ - auto _tryEmplResult = (EXPR); \ - if (MOZ_UNLIKELY(!_tryEmplResult)) { \ - return cx_->alreadyReportedError(); \ - } \ - (VAR).emplace(_tryEmplResult.unwrap()); \ - } while (false) - -#define BINJS_MOZ_TRY_EMPLACE(VAR, EXPR) \ - do { \ - auto _tryEmplResult = (EXPR); \ - if (MOZ_UNLIKELY(_tryEmplResult.isErr())) { \ - return ::mozilla::Err(_tryEmplResult.unwrapErr()); \ - } \ - (VAR).emplace(_tryEmplResult.unwrap()); \ - } while (false) - -// Evaluate an expression EXPR, checking that the result is a success. -// In case of success, unwrap and assign the result to a new variable VAR. -// -// In case of error, propagate the error. -#define BINJS_MOZ_TRY_DECL(VAR, EXPR) \ - auto _##VAR = (EXPR); \ - if (MOZ_UNLIKELY(_##VAR.isErr())) { \ - return ::mozilla::Err(_##VAR.unwrapErr()); \ - } \ - auto VAR = _##VAR.unwrap(); - -#endif // frontend_BinAST_macros_h diff --git a/js/src/frontend/BinAST.webidl_ b/js/src/frontend/BinAST.webidl_ deleted file mode 100644 index 30853d82e6..0000000000 --- a/js/src/frontend/BinAST.webidl_ +++ /dev/null @@ -1,1015 +0,0 @@ -// Type aliases and enums. - -typedef FrozenArray<(SpreadElement or Expression)> Arguments; -typedef DOMString string; -typedef string Identifier; -typedef string IdentifierName; -typedef string PropertyKey; -typedef string Label; - -enum VariableDeclarationKind { - "var", - "let", - "const" -}; - -enum CompoundAssignmentOperator { - "+=", - "-=", - "*=", - "/=", - "%=", - "**=", - "<<=", - ">>=", - ">>>=", - "|=", - "^=", - "&=" -}; - -enum BinaryOperator { - ",", - "||", - "&&", - "|", - "^", - "&", - "==", - "!=", - "===", - "!==", - "<", - "<=", - ">", - ">=", - "in", - "instanceof", - "<<", - ">>", - ">>>", - "+", - "-", - "*", - "/", - "%", - "**", -}; - -enum UnaryOperator { - "+", - "-", - "!", - "~", - "typeof", - "void", - "delete" -}; - -enum UpdateOperator { - "++", - "--" -}; - -enum AssertedDeclaredKind { - "var", - "non-const lexical", - "const lexical" -}; - -// deferred assertions - -interface AssertedDeclaredName { - attribute IdentifierName name; - attribute AssertedDeclaredKind kind; - attribute boolean isCaptured; -}; - -interface AssertedPositionalParameterName { - attribute unsigned long index; - attribute IdentifierName name; - attribute boolean isCaptured; -}; - -interface AssertedRestParameterName { - attribute IdentifierName name; - attribute boolean isCaptured; -}; - -interface AssertedParameterName { - attribute IdentifierName name; - attribute boolean isCaptured; -}; - -typedef (AssertedPositionalParameterName or - AssertedRestParameterName or - AssertedParameterName) - AssertedMaybePositionalParameterName; - -interface AssertedBoundName { - attribute IdentifierName name; - attribute boolean isCaptured; -}; - -interface AssertedBlockScope { - attribute FrozenArray declaredNames; - attribute boolean hasDirectEval; -}; - -interface AssertedScriptGlobalScope { - attribute FrozenArray declaredNames; - attribute boolean hasDirectEval; -}; - -interface AssertedVarScope { - attribute FrozenArray declaredNames; - attribute boolean hasDirectEval; -}; - -interface AssertedParameterScope { - attribute FrozenArray paramNames; - attribute boolean hasDirectEval; - attribute boolean isSimpleParameterList; -}; - -interface AssertedBoundNamesScope { - attribute FrozenArray boundNames; - attribute boolean hasDirectEval; -}; - -// nodes - -interface Node { - [TypeIndicator] readonly attribute Type type; -}; - -typedef (Script or Module) Program; - -typedef (DoWhileStatement or - ForInStatement or - ForOfStatement or - ForStatement or - WhileStatement) - IterationStatement; - -typedef (Block or - BreakStatement or - ContinueStatement or - ClassDeclaration or - DebuggerStatement or - EmptyStatement or - ExpressionStatement or - FunctionDeclaration or - IfStatement or - IterationStatement or - LabelledStatement or - ReturnStatement or - SwitchStatement or - SwitchStatementWithDefault or - ThrowStatement or - TryCatchStatement or - TryFinallyStatement or - VariableDeclaration or - WithStatement) - Statement; - -typedef (LiteralBooleanExpression or - LiteralInfinityExpression or - LiteralNullExpression or - LiteralNumericExpression or - LiteralStringExpression) - Literal; - -typedef (Literal or - LiteralRegExpExpression or - ArrayExpression or - ArrowExpression or - AssignmentExpression or - BinaryExpression or - CallExpression or - CompoundAssignmentExpression or - ComputedMemberExpression or - ConditionalExpression or - ClassExpression or - FunctionExpression or - IdentifierExpression or - NewExpression or - NewTargetExpression or - ObjectExpression or - UnaryExpression or - StaticMemberExpression or - TemplateExpression or - ThisExpression or - UpdateExpression or - YieldExpression or - YieldStarExpression or - AwaitExpression) - Expression; - -typedef (ComputedPropertyName or - LiteralPropertyName) - PropertyName; - -typedef (Method or Getter or Setter) MethodDefinition; - -typedef (MethodDefinition or - DataProperty or - ShorthandProperty) - ObjectProperty; - -typedef (ExportAllFrom or - ExportFrom or - ExportLocals or - ExportDefault or - Export) - ExportDeclaration; - -typedef (ImportNamespace or Import) ImportDeclaration; - -typedef (EagerFunctionDeclaration or - LazyFunctionDeclaration) FunctionDeclaration; - -typedef (EagerFunctionExpression or - LazyFunctionExpression) FunctionExpression; - -typedef (EagerMethod or LazyMethod) Method; - -typedef (EagerGetter or LazyGetter) Getter; - -typedef (EagerSetter or LazySetter) Setter; - -typedef (EagerArrowExpressionWithFunctionBody or - LazyArrowExpressionWithFunctionBody or - EagerArrowExpressionWithExpression or - LazyArrowExpressionWithExpression) ArrowExpression; - -// bindings - -interface BindingIdentifier : Node { - attribute Identifier name; -}; - -typedef (ObjectBinding or - ArrayBinding) - BindingPattern; -typedef (BindingPattern or - BindingIdentifier) - Binding; - -typedef (AssignmentTargetIdentifier or - ComputedMemberAssignmentTarget or - StaticMemberAssignmentTarget) - SimpleAssignmentTarget; -typedef (ObjectAssignmentTarget or - ArrayAssignmentTarget) - AssignmentTargetPattern; -// `DestructuringAssignmentTarget` -typedef (AssignmentTargetPattern or - SimpleAssignmentTarget) - AssignmentTarget; - -// `FormalParameter` -typedef (Binding or - BindingWithInitializer) - Parameter; - -interface BindingWithInitializer : Node { - attribute Binding binding; - attribute Expression init; -}; - -interface AssignmentTargetIdentifier : Node { - attribute Identifier name; -}; - -interface ComputedMemberAssignmentTarget : Node { - // The object whose property is being assigned. - attribute (Expression or Super) _object; - // The expression resolving to the name of the property to be accessed. - attribute Expression expression; -}; - -interface StaticMemberAssignmentTarget : Node { - // The object whose property is being assigned. - attribute (Expression or Super) _object; - // The name of the property to be accessed. - attribute IdentifierName property; -}; - -// `ArrayBindingPattern` -interface ArrayBinding : Node { - // The elements of the array pattern; a null value represents an elision. - attribute FrozenArray<(Binding or BindingWithInitializer)?> elements; - attribute Binding? rest; -}; - -// `SingleNameBinding` -interface BindingPropertyIdentifier : Node { - attribute BindingIdentifier binding; - attribute Expression? init; -}; - -// `BindingProperty :: PropertyName : BindingElement` -interface BindingPropertyProperty : Node { - attribute PropertyName name; - attribute (Binding or BindingWithInitializer) binding; -}; - -typedef (BindingPropertyIdentifier or - BindingPropertyProperty) - BindingProperty; - -interface ObjectBinding : Node { - attribute FrozenArray properties; -}; - -// This interface represents the case where the initializer is present in -// `AssignmentElement :: DestructuringAssignmentTarget Initializer_opt`. -interface AssignmentTargetWithInitializer : Node { - attribute AssignmentTarget binding; - attribute Expression init; -}; - -// `ArrayAssignmentPattern` -interface ArrayAssignmentTarget : Node { - // The elements of the array pattern; a null value represents an elision. - attribute FrozenArray<(AssignmentTarget or AssignmentTargetWithInitializer?)> elements; - attribute AssignmentTarget? rest; -}; - -// `AssignmentProperty :: IdentifierReference Initializer_opt` -interface AssignmentTargetPropertyIdentifier : Node { - attribute AssignmentTargetIdentifier binding; - attribute Expression? init; -}; - -// `AssignmentProperty :: PropertyName : Node` -interface AssignmentTargetPropertyProperty : Node { - attribute PropertyName name; - attribute (AssignmentTarget or AssignmentTargetWithInitializer) binding; -}; - -typedef (AssignmentTargetPropertyIdentifier or - AssignmentTargetPropertyProperty) - AssignmentTargetProperty; - -// `ObjectAssignmentPattern` -interface ObjectAssignmentTarget : Node { - attribute FrozenArray properties; -}; - - -// classes - -interface ClassExpression : Node { - attribute BindingIdentifier? name; - attribute Expression? super; - attribute FrozenArray elements; -}; - -interface ClassDeclaration : Node { - attribute BindingIdentifier name; - attribute Expression? super; - attribute FrozenArray elements; -}; - -interface ClassElement : Node { - // True iff `IsStatic` of ClassElement is true. - attribute boolean isStatic; - attribute MethodDefinition method; -}; - - -// modules - -interface Module : Node { - attribute AssertedVarScope scope; - attribute FrozenArray directives; - attribute FrozenArray<(ImportDeclaration or ExportDeclaration or Statement)> items; -}; - -// An `ImportDeclaration` not including a namespace import. -interface Import : Node { - attribute string moduleSpecifier; - // `ImportedDefaultBinding`, if present. - attribute BindingIdentifier? defaultBinding; - attribute FrozenArray namedImports; -}; - -// An `ImportDeclaration` including a namespace import. -interface ImportNamespace : Node { - attribute string moduleSpecifier; - // `ImportedDefaultBinding`, if present. - attribute BindingIdentifier? defaultBinding; - attribute BindingIdentifier namespaceBinding; -}; - -interface ImportSpecifier : Node { - // The `IdentifierName` in the production `ImportSpecifier :: IdentifierName as ImportedBinding`; - // absent if this specifier represents the production `ImportSpecifier :: ImportedBinding`. - attribute IdentifierName? name; - attribute BindingIdentifier binding; -}; - -// `export * FromClause;` -interface ExportAllFrom : Node { - attribute string moduleSpecifier; -}; - -// `export ExportClause FromClause;` -interface ExportFrom : Node { - attribute FrozenArray namedExports; - attribute string moduleSpecifier; -}; - -// `export ExportClause;` -interface ExportLocals : Node { - attribute FrozenArray namedExports; -}; - -// `export VariableStatement`, `export Declaration` -interface Export : Node { - attribute (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration; -}; - -// `export default HoistableDeclaration`, -// `export default ClassDeclaration`, -// `export default AssignmentExpression` -interface ExportDefault : Node { - attribute (FunctionDeclaration or ClassDeclaration or Expression) body; -}; - -// `ExportSpecifier`, as part of an `ExportFrom`. -interface ExportFromSpecifier : Node { - // The only `IdentifierName in `ExportSpecifier :: IdentifierName`, - // or the first in `ExportSpecifier :: IdentifierName as IdentifierName`. - attribute IdentifierName name; - // The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`, - // if that is the production represented. - attribute IdentifierName? exportedName; -}; - -// `ExportSpecifier`, as part of an `ExportLocals`. -interface ExportLocalSpecifier : Node { - // The only `IdentifierName in `ExportSpecifier :: IdentifierName`, - // or the first in `ExportSpecifier :: IdentifierName as IdentifierName`. - attribute IdentifierExpression name; - // The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`, if present. - attribute IdentifierName? exportedName; -}; - - -// property definition - -// `MethodDefinition :: PropertyName ( UniqueFormalParameters ) { FunctionBody }`, -// `GeneratorMethod :: * PropertyName ( UniqueFormalParameters ) { GeneratorBody }`, -// `AsyncMethod :: async PropertyName ( UniqueFormalParameters ) { AsyncFunctionBody }` -interface EagerMethod : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute PropertyName name; - attribute unsigned long length; - attribute FrozenArray directives; - attribute FunctionOrMethodContents contents; -}; -interface LazyMethod : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute PropertyName name; - attribute unsigned long length; - attribute FrozenArray directives; - [Lazy] attribute FunctionOrMethodContents contents; -}; - -// `get PropertyName ( ) { FunctionBody }` -interface EagerGetter : Node { - attribute PropertyName name; - attribute FrozenArray directives; - attribute GetterContents contents; -}; -interface LazyGetter : Node { - attribute PropertyName name; - attribute FrozenArray directives; - [Lazy] attribute GetterContents contents; -}; - -interface GetterContents : Node { - attribute boolean isThisCaptured; - attribute AssertedVarScope bodyScope; - attribute FunctionBody body; -}; - -// `set PropertyName ( PropertySetParameterList ) { FunctionBody }` -interface EagerSetter : Node { - attribute PropertyName name; - attribute unsigned long length; - attribute FrozenArray directives; - attribute SetterContents contents; -}; -interface LazySetter : Node { - attribute PropertyName name; - attribute unsigned long length; - attribute FrozenArray directives; - [Lazy] attribute SetterContents contents; -}; - -interface SetterContents : Node { - attribute boolean isThisCaptured; - attribute AssertedParameterScope parameterScope; - attribute Parameter param; - attribute AssertedVarScope bodyScope; - attribute FunctionBody body; -}; - -// `PropertyDefinition :: PropertyName : AssignmentExpression` -interface DataProperty : Node { - attribute PropertyName name; - // The `AssignmentExpression`. - attribute Expression expression; -}; - -// `PropertyDefinition :: IdentifierReference` -interface ShorthandProperty : Node { - // The `IdentifierReference`. - attribute IdentifierExpression name; -}; - -interface ComputedPropertyName : Node { - attribute Expression expression; -}; - -// `LiteralPropertyName` -interface LiteralPropertyName : Node { - attribute string value; -}; - - -// literals - -// `BooleanLiteral` -interface LiteralBooleanExpression : Node { - attribute boolean value; -}; - -// A `NumericLiteral` for which the Number value of its MV is positive infinity. -interface LiteralInfinityExpression : Node { }; - -// `NullLiteral` -interface LiteralNullExpression : Node { }; - -// `NumericLiteral` -interface LiteralNumericExpression : Node { - attribute double value; -}; - -// `RegularExpressionLiteral` -interface LiteralRegExpExpression : Node { - attribute string pattern; - attribute string flags; -}; - -// `StringLiteral` -interface LiteralStringExpression : Node { - attribute string value; -}; - - -// other expressions - -// `ArrayLiteral` -interface ArrayExpression : Node { - // The elements of the array literal; a null value represents an elision. - attribute FrozenArray<(SpreadElement or Expression)?> elements; -}; - -// `ArrowFunction`, -// `AsyncArrowFunction` -interface EagerArrowExpressionWithFunctionBody : Node { - // True for `AsyncArrowFunction`, false otherwise. - attribute boolean isAsync; - attribute unsigned long length; - attribute FrozenArray directives; - attribute ArrowExpressionContentsWithFunctionBody contents; -}; -interface LazyArrowExpressionWithFunctionBody : Node { - // True for `AsyncArrowFunction`, false otherwise. - attribute boolean isAsync; - attribute unsigned long length; - attribute FrozenArray directives; - [Lazy] attribute ArrowExpressionContentsWithFunctionBody contents; -}; -interface EagerArrowExpressionWithExpression : Node { - // True for `AsyncArrowFunction`, false otherwise. - attribute boolean isAsync; - attribute unsigned long length; - attribute ArrowExpressionContentsWithExpression contents; -}; -interface LazyArrowExpressionWithExpression : Node { - // True for `AsyncArrowFunction`, false otherwise. - attribute boolean isAsync; - attribute unsigned long length; - [Lazy] attribute ArrowExpressionContentsWithExpression contents; -}; - -interface ArrowExpressionContentsWithFunctionBody : Node { - attribute AssertedParameterScope parameterScope; - attribute FormalParameters params; - attribute AssertedVarScope bodyScope; - attribute FunctionBody body; -}; - -interface ArrowExpressionContentsWithExpression : Node { - attribute AssertedParameterScope parameterScope; - attribute FormalParameters params; - attribute AssertedVarScope bodyScope; - attribute Expression body; -}; - -// `AssignmentExpression :: LeftHandSideExpression = AssignmentExpression` -interface AssignmentExpression : Node { - // The `LeftHandSideExpression`. - attribute AssignmentTarget binding; - // The `AssignmentExpression` following the `=`. - attribute Expression expression; -}; - -// `ExponentiationExpression`, -// `MultiplicativeExpression`, -// `AdditiveExpression`, -// `ShiftExpression`, -// `RelationalExpression`, -// `EqualityExpression`, -// `BitwiseANDExpression`, -// `BitwiseXORExpression`, -// `BitwiseORExpression`, -// `LogicalANDExpression`, -// `LogicalORExpression` -interface BinaryExpression : Node { - attribute BinaryOperator operator; - // The expression before the operator. - attribute Expression left; - // The expression after the operator. - attribute Expression right; -}; - -interface CallExpression : Node { - attribute (Expression or Super) callee; - attribute Arguments arguments; -}; - -// `AssignmentExpression :: LeftHandSideExpression AssignmentOperator AssignmentExpression` -interface CompoundAssignmentExpression : Node { - attribute CompoundAssignmentOperator operator; - // The `LeftHandSideExpression`. - attribute SimpleAssignmentTarget binding; - // The `AssignmentExpression`. - attribute Expression expression; -}; - -interface ComputedMemberExpression : Node { - // The object whose property is being accessed. - attribute (Expression or Super) _object; - // The expression resolving to the name of the property to be accessed. - attribute Expression expression; -}; - -// `ConditionalExpression :: LogicalORExpression ? AssignmentExpression : AssignmentExpression` -interface ConditionalExpression : Node { - // The `LogicalORExpression`. - attribute Expression test; - // The first `AssignmentExpression`. - attribute Expression consequent; - // The second `AssignmentExpression`. - attribute Expression alternate; -}; - -// `FunctionExpression`, -// `GeneratorExpression`, -// `AsyncFunctionExpression`, -interface EagerFunctionExpression : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute BindingIdentifier? name; - attribute unsigned long length; - attribute FrozenArray directives; - attribute FunctionExpressionContents contents; -}; -interface LazyFunctionExpression : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute BindingIdentifier? name; - attribute unsigned long length; - attribute FrozenArray directives; - [Lazy] attribute FunctionExpressionContents contents; -}; - -interface FunctionExpressionContents : Node { - attribute boolean isFunctionNameCaptured; - attribute boolean isThisCaptured; - attribute AssertedParameterScope parameterScope; - attribute FormalParameters params; - attribute AssertedVarScope bodyScope; - attribute FunctionBody body; -}; - -// `IdentifierReference` -interface IdentifierExpression : Node { - attribute Identifier name; -}; - -interface NewExpression : Node { - attribute Expression callee; - attribute Arguments arguments; -}; - -interface NewTargetExpression : Node { }; - -interface ObjectExpression : Node { - attribute FrozenArray properties; -}; - -interface UnaryExpression : Node { - attribute UnaryOperator operator; - attribute Expression operand; -}; - -interface StaticMemberExpression : Node { - // The object whose property is being accessed. - attribute (Expression or Super) _object; - // The name of the property to be accessed. - attribute IdentifierName property; -}; - -// `TemplateLiteral`, -// `MemberExpression :: MemberExpression TemplateLiteral`, -// `CallExpression : CallExpression TemplateLiteral` -interface TemplateExpression : Node { - // The second `MemberExpression` or `CallExpression`, if present. - attribute Expression? tag; - // The contents of the template. This list must be alternating - // TemplateElements and Expressions, beginning and ending with - // TemplateElement. - attribute FrozenArray<(Expression or TemplateElement)> elements; -}; - -// `PrimaryExpression :: this` -interface ThisExpression : Node { }; - -// `UpdateExpression :: LeftHandSideExpression ++`, -// `UpdateExpression :: LeftHandSideExpression --`, -// `UpdateExpression :: ++ LeftHandSideExpression`, -// `UpdateExpression :: -- LeftHandSideExpression` -interface UpdateExpression : Node { - // True for `UpdateExpression :: ++ LeftHandSideExpression` and - // `UpdateExpression :: -- LeftHandSideExpression`, false otherwise. - attribute boolean isPrefix; - attribute UpdateOperator operator; - attribute SimpleAssignmentTarget operand; -}; - -// `YieldExpression :: yield`, -// `YieldExpression :: yield AssignmentExpression` -interface YieldExpression : Node { - // The `AssignmentExpression`, if present. - attribute Expression? expression; -}; - -// `YieldExpression :: yield * AssignmentExpression` -interface YieldStarExpression : Node { - attribute Expression expression; -}; - -interface AwaitExpression : Node { - attribute Expression expression; -}; - - -// other statements - -interface BreakStatement : Node { - attribute Label? label; -}; - -interface ContinueStatement : Node { - attribute Label? label; -}; - -interface DebuggerStatement : Node { }; - -interface DoWhileStatement : Node { - attribute Expression test; - attribute Statement body; -}; - -interface EmptyStatement : Node { }; - -interface ExpressionStatement : Node { - attribute Expression expression; -}; - -interface ForInOfBinding : Node { - attribute VariableDeclarationKind kind; - attribute Binding binding; -}; - -// `for ( LeftHandSideExpression in Expression ) Statement`, -// `for ( var ForBinding in Expression ) Statement`, -// `for ( ForDeclaration in Expression ) Statement`, -// `for ( var BindingIdentifier Initializer in Expression ) Statement` -interface ForInStatement : Node { - // The expression or declaration before `in`. - attribute (ForInOfBinding or AssignmentTarget) left; - // The expression after `in`. - attribute Expression right; - attribute Statement body; -}; - -// `for ( LeftHandSideExpression of Expression ) Statement`, -// `for ( var ForBinding of Expression ) Statement`, -// `for ( ForDeclaration of Expression ) Statement` -interface ForOfStatement : Node { - // The expression or declaration before `of`. - attribute (ForInOfBinding or AssignmentTarget) left; - // The expression after `of`. - attribute Expression right; - attribute Statement body; -}; - -// `for ( Expression ; Expression ; Expression ) Statement`, -// `for ( var VariableDeclarationList ; Expression ; Expression ) Statement` -interface ForStatement : Node { - // The expression or declaration before the first `;`, if present. - attribute (VariableDeclaration or Expression)? init; - // The expression before the second `;`, if present - attribute Expression? test; - // The expression after the second `;`, if present - attribute Expression? update; - attribute Statement body; -}; - -// `if ( Expression ) Statement`, -// `if ( Expression ) Statement else Statement`, -interface IfStatement : Node { - attribute Expression test; - // The first `Statement`. - attribute Statement consequent; - // The second `Statement`, if present. - attribute Statement? alternate; -}; - -interface LabelledStatement : Node { - attribute Label label; - attribute Statement body; -}; - -interface ReturnStatement : Node { - attribute Expression? expression; -}; - -// A `SwitchStatement` whose `CaseBlock` is -// `CaseBlock :: { CaseClauses }`. -interface SwitchStatement : Node { - attribute Expression discriminant; - attribute FrozenArray cases; -}; - -// A `SwitchStatement` whose `CaseBlock` is -// `CaseBlock :: { CaseClauses DefaultClause CaseClauses }`. -interface SwitchStatementWithDefault : Node { - attribute Expression discriminant; - // The `CaseClauses` before the `DefaultClause`. - attribute FrozenArray preDefaultCases; - // The `DefaultClause`. - attribute SwitchDefault defaultCase; - // The `CaseClauses` after the `DefaultClause`. - attribute FrozenArray postDefaultCases; -}; - -interface ThrowStatement : Node { - attribute Expression expression; -}; - -// `TryStatement :: try Block Catch` -interface TryCatchStatement : Node { - attribute Block body; - attribute CatchClause catchClause; -}; - -// `TryStatement :: try Block Finally`, -// `TryStatement :: try Block Catch Finally` -interface TryFinallyStatement : Node { - // The `Block`. - attribute Block body; - // The `Catch`, if present. - attribute CatchClause? catchClause; - // The `Finally`. - attribute Block finalizer; -}; - -interface WhileStatement : Node { - attribute Expression test; - attribute Statement body; -}; - -interface WithStatement : Node { - attribute Expression _object; - attribute Statement body; -}; - - -// other nodes - -interface Block : Node { - attribute AssertedBlockScope scope; - attribute FrozenArray statements; -}; - -// `Catch` -interface CatchClause : Node { - attribute AssertedBoundNamesScope bindingScope; - attribute Binding binding; - attribute Block body; -}; - -// An item in a `DirectivePrologue` -interface Directive : Node { - attribute string rawValue; -}; - -interface FormalParameters : Node { - attribute FrozenArray items; - attribute Binding? rest; -}; - -typedef FrozenArray FunctionBody; - - - -// `FunctionDeclaration`, -// `GeneratorDeclaration`, -// `AsyncFunctionDeclaration` -interface EagerFunctionDeclaration : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute BindingIdentifier name; - attribute unsigned long length; - attribute FrozenArray directives; - attribute FunctionOrMethodContents contents; -}; - -interface LazyFunctionDeclaration : Node { - attribute boolean isAsync; - attribute boolean isGenerator; - attribute BindingIdentifier name; - attribute unsigned long length; - attribute FrozenArray directives; - [Lazy] attribute FunctionOrMethodContents contents; -}; - -interface FunctionOrMethodContents : Node { - attribute boolean isThisCaptured; - attribute AssertedParameterScope parameterScope; - attribute FormalParameters params; - attribute AssertedVarScope bodyScope; - attribute FunctionBody body; -}; - - -interface Script : Node { - attribute AssertedScriptGlobalScope scope; - attribute FrozenArray directives; - attribute FrozenArray statements; -}; - -interface SpreadElement : Node { - attribute Expression expression; -}; - -// `super` -interface Super : Node { }; - -// `CaseClause` -interface SwitchCase : Node { - attribute Expression test; - attribute FrozenArray consequent; -}; - -// `DefaultClause` -interface SwitchDefault : Node { - attribute FrozenArray consequent; -}; - -// `TemplateCharacters` -interface TemplateElement : Node { - attribute string rawValue; -}; - -interface VariableDeclaration : Node { - attribute VariableDeclarationKind kind; - [NonEmpty] attribute FrozenArray declarators; -}; - -interface VariableDeclarator : Node { - attribute Binding binding; - attribute Expression? init; -}; diff --git a/js/src/frontend/BinAST.yaml b/js/src/frontend/BinAST.yaml deleted file mode 100644 index 1c85dd8db9..0000000000 --- a/js/src/frontend/BinAST.yaml +++ /dev/null @@ -1,1663 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -parser: - class-template: - template - class-name: - BinASTParser - type-ok: - ParseNode* - default-value: - nullptr - list: - append: | - result->appendWithoutOrderAssumption(item); - -# Rules for generating BinASTParser.cpp -cpp: - header: | - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - // To generate this file, see the documentation in - // js/src/frontend/binast/README.md. - - #include "frontend/BinASTParser.h" - - #include "mozilla/ArrayUtils.h" - #include "mozilla/Casting.h" - #include "mozilla/Maybe.h" - #include "mozilla/Move.h" - #include "mozilla/PodOperations.h" - #include "mozilla/Vector.h" - - #include "frontend/BinAST-macros.h" - #include "frontend/BinASTTokenReaderContext.h" - #include "frontend/BinASTTokenReaderMultipart.h" - #include "frontend/FullParseHandler.h" - #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind - #include "frontend/ParseNode.h" - #include "frontend/Parser.h" - #include "frontend/SharedContext.h" - #include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags - #include "new-regexp/RegExpAPI.h" - #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind - #include "vm/RegExpObject.h" - - #include "frontend/ParseContext-inl.h" - - using JS::RegExpFlag; - using JS::RegExpFlags; - - namespace js::frontend { - - // Compare a bunch of `uint8_t` values (as returned by the tokenizer_) with - // a string literal (and ONLY a string literal). - template - bool operator==(const typename Tok::Chars& left, const char (&right)[N]) { - return Tok::equals(left, right); - } - - footer: | - - // Force class instantiation. - // This ensures that the symbols are built, without having to export all our - // code (and its baggage of #include and macros) in the header. - template class BinASTParser; - template class BinASTParser; - - } // namespace js::frontend - -hpp: - # Rules for generating BinASTParser.h - class: - header: | - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - // To generate this file, see the documentation in - // js/src/frontend/binast/README.md. - - #ifndef frontend_BinASTParser_h - #define frontend_BinASTParser_h - - #include "mozilla/Maybe.h" - #include "mozilla/Variant.h" - - #include "frontend/BCEParserHandle.h" - #include "frontend/BinASTParserPerTokenizer.h" - #include "frontend/BinASTToken.h" - #include "frontend/BinASTTokenReaderContext.h" - #include "frontend/BinASTTokenReaderMultipart.h" - #include "frontend/FullParseHandler.h" - #include "frontend/ParseContext.h" - #include "frontend/ParseNode.h" - #include "frontend/SharedContext.h" - - #include "js/CompileOptions.h" - #include "js/GCHashTable.h" - #include "js/GCVector.h" - #include "js/Result.h" - - namespace js { - namespace frontend { - - template - class BinASTParser : public BinASTParserPerTokenizer { - public: - using Base = BinASTParserPerTokenizer; - - using Tokenizer = Tok; - - using AutoList = typename Tokenizer::AutoList; - using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; - using Chars = typename Tokenizer::Chars; - using ListContext = typename BinASTTokenReaderBase::ListContext; - using FieldContext = typename BinASTTokenReaderBase::FieldContext; - using RootContext = typename BinASTTokenReaderBase::RootContext; - using FieldOrRootContext = BinASTTokenReaderBase::FieldOrRootContext; - using FieldOrListContext = BinASTTokenReaderBase::FieldOrListContext; - - public: - // Auto-generated types. - using AssertedDeclaredKind = binast::AssertedDeclaredKind; - using BinaryOperator = binast::BinaryOperator; - using CompoundAssignmentOperator = binast::CompoundAssignmentOperator; - using UnaryOperator = binast::UnaryOperator; - using UpdateOperator = binast::UpdateOperator; - using VariableDeclarationKind = binast::VariableDeclarationKind; - - public: - // BinASTParserPerTokenizer types. - using AssertedScopeKind = typename Base::AssertedScopeKind; - - public: - BinASTParser(JSContext* cx, CompilationInfo& compilationInfo, - const JS::ReadOnlyCompileOptions& options, - Handle lazyScript = nullptr) - : BinASTParserPerTokenizer(cx, compilationInfo, options, - lazyScript) {} - ~BinASTParser() {} - - protected: - // BinASTParserBase fields. - using Base::cx_; - - using Base::alloc_; - using Base::usedNames_; - - using Base::compilationInfo_; - using Base::handler_; - using Base::pc_; - - protected: - // BinASTParserPerTokenizer types. - using AutoVariableDeclarationKind = - typename Base::AutoVariableDeclarationKind; - - protected: - // BinASTParserPerTokenizer fields. - using Base::tokenizer_; - using Base::variableDeclarationKind_; - - protected: - // BinASTParserPerTokenizer methods. - using Base::raiseInvalidClosedVar; - using Base::raiseMissingVariableInAssertedScope; - using Base::raiseMissingDirectEvalInAssertedScope; - using Base::raiseInvalidKind; - using Base::raiseInvalidVariant; - using Base::raiseMissingField; - using Base::raiseEmpty; - using Base::raiseOOM; - using Base::raiseError; - - using Base::makeEmptyFunctionNode; - using Base::setFunctionParametersAndBody; - using Base::buildFunctionBox; - using Base::finishEagerFunction; - using Base::finishLazyFunction; - - using Base::addScopeName; - using Base::captureFunctionName; - - using Base::getDeclaredScope; - using Base::getBoundScope; - using Base::checkBinding; - using Base::checkPositionalParameterIndices; - - using Base::checkFunctionLength; - using Base::checkClosedVars; - - using Base::prependDirectivesToBody; - - using Base::forceStrictIfNecessary; - - using Base::isInvalidKindPossible; - using Base::isInvalidVariantPossible; - - public: - footer: | - }; - - extern template class BinASTParser; - extern template class BinASTParser; - - } // namespace frontend - } // namespace js - - #endif // frontend_BinASTParser_h - - enums: - header: | - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - // To generate this file, see the documentation in - // js/src/frontend/binast/README.md. - - #ifndef frontend_BinASTEnum_h - #define frontend_BinASTEnum_h - - namespace js { - namespace frontend { - namespace binast { - footer: | - } // namespace binast - } // namespace frontend - } // namespace js - - #endif // frontend_BinASTEnum_h - - # Rules for generating BinASTToken.h - tokens: - kind: - doc: | - /** - * The different kinds of Binary AST nodes, as per the specifications of - * Binary AST. - * - * These kinds match roughly with the `ParseNodeKind` used internally. - * - * Usage: - * - * ```c++ - * #define WITH_KIND(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_KIND(WITH_KIND) - * ``` - * - * - * (sorted by alphabetical order) - */ - field: - doc: | - /** - * The different fields of Binary AST nodes, as per the specifications of - * Binary AST. - * - * Usage: - * - * ```c++ - * #define WITH_FIELD(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_FIELD(WITH_FIELD) - * ``` - * - * (sorted by alphabetical order) - */ - variants: - doc: | - /** - * The different variants of Binary AST string enums, as per - * the specifications of Binary AST, as a single macro and - * `enum class`. - * - * Separate enum classes are also defined in BinASTParser.h. - * - * Usage: - * - * ```c++ - * #define WITH_VARIANT(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_VARIANT(WITH_VARIANT) - * ``` - * - * (sorted by alphabetical order) - */ - - header: | - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - - // To generate this file, see the documentation in - // js/src/frontend/binast/README.md. - - #ifndef frontend_BinASTToken_h - #define frontend_BinASTToken_h - - #include - - #include "jstypes.h" - - /** - * Definition of Binary AST tokens. - * - * In the Binary AST world, an AST is composed of nodes, where a node is - * defined by: - * - a Kind (see `BinASTKind`); - * - a list of fields, where each field is: - * - a Name (see `BinASTField`); - * - a Value, which may be either a node or a primitive value. - * - * The mapping between Kind and list of fields is determined entirely by - * the grammar of Binary AST. The mapping between (Kind, Name) and the - * structure of Value is also determined entirely by the grammar of - * Binary AST. - * - * As per the specifications of Binary AST, kinds may be added as the - * language grows, but never removed. The mapping between Kind and list - * of fields may also change to add new fields or make some fields optional, - * but may never remove a field. Finally, the mapping between (Kind, Name) - * and the structure of Value may be modified to add new possible values, - * but never to remove a value. - * - * A Binary AST parser must be able to fail gracefully when confronted with - * unknown Kinds or Names. - */ - - namespace js { - namespace frontend { - footer: | - - /** - * Return a string describing a `BinASTKind`. - */ - const char* describeBinASTKind(const BinASTKind& kind); - - /** - * Return a string describing a `BinASTField`. - */ - const char* describeBinASTField(const BinASTField& field); - - /** - * Return a string describing a `BinASTInterfaceAndField`. - */ - const char* describeBinASTInterfaceAndField(const BinASTInterfaceAndField& field); - - /** - * Return a string describing a `BinASTVariant`. - */ - const char* describeBinASTVariant(const BinASTVariant& variant); - - /** - * Return a string describing a `BinASTList`. - */ - const char* describeBinASTList(const BinASTList& list); - - /** - * Return a sort key for sorting `BinASTKind`s alphabetically. - */ - size_t getBinASTKindSortKey(const BinASTKind& kind); - - /** - * Return a sort key for sorting `BinASTVariant`s alphabetically. - */ - size_t getBinASTVariantSortKey(const BinASTVariant& variant); - - } // namespace frontend - } // namespace js - - #endif // frontend_BinASTToken_h - -Arguments: - init: | - BINJS_TRY_DECL(result, handler_.newList(ParseNodeKind::Arguments, - tokenizer_->pos(start))); - append: - handler_.addList(/* list = */ result, /* kid = */ item); - -ArrayExpression: - build: | - if (elements->empty()) { - elements->setHasNonConstInitializer(); - } - auto result = elements; - -AssertedBlockScope: - type-ok: - Ok - init: | - const auto scopeKind = AssertedScopeKind::Block; - fields: - declaredNames: - extra-args: scopeKind - hasDirectEval: - after: | - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - build: | - if (hasDirectEval && pc_->isFunctionBox() && - !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setHasExtensibleScope(); - } - auto result = Ok(); - -AssertedBoundName: - type-ok: - Ok - extra-params: AssertedScopeKind scopeKind - extra-args: scopeKind - init: | - const bool allowDuplicateName = false; - fields: - isCaptured: - after: | - ParseContext::Scope* scope; - DeclarationKind declKind; - MOZ_TRY(getBoundScope(scopeKind, scope, declKind)); - build: | - MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured, - allowDuplicateName)); - auto result = Ok(); - -AssertedDeclaredName: - inherits: AssertedBoundName - fields: - kind: - after: | - if (kind_ == AssertedDeclaredKind::NonConstLexical) { - return raiseError("Let is not supported in this preview release"); - } - if (kind_ == AssertedDeclaredKind::ConstLexical) { - return raiseError("Const is not supported in this preview release"); - } - isCaptured: - after: | - ParseContext::Scope* scope; - DeclarationKind declKind; - MOZ_TRY(getDeclaredScope(scopeKind, kind_, scope, declKind)); - -AssertedMaybePositionalParameterName: - inherits: AssertedBoundName - extra-params: | - AssertedScopeKind scopeKind, - MutableHandle> positionalParams - extra-args: | - scopeKind, positionalParams - sum-arms: - AssertedRestParameterName: - disabled: true - AssertedParameterName: - disabled: true - -AssertedPositionalParameterName: - inherits: AssertedMaybePositionalParameterName - init: | - bool allowDuplicateName = !pc_->sc()->strict(); - fields: - name: - after: | - // `positionalParams` vector can be shorter than the actual - // parameter length. Resize on demand. - // (see also ListOfAssertedMaybePositionalParameterName) - size_t prevLength = positionalParams.get().length(); - if (index >= prevLength) { - // This is implementation limit, which is not in the spec. - if (index >= ARGNO_LIMIT - 1) { - return raiseError("AssertedPositionalParameterName.index is too big"); - } - size_t newLength = index + 1; - BINJS_TRY(positionalParams.get().resize(newLength)); - for (uint32_t i = prevLength; i < newLength; i++) { - positionalParams.get()[i] = nullptr; - } - } - - if (positionalParams.get()[index]) { - return raiseError("AssertedPositionalParameterName has duplicate entry for the same index"); - } - positionalParams.get()[index] = name; - -AssertedBoundNamesScope: - inherits: AssertedBlockScope - init: | - const auto scopeKind = AssertedScopeKind::Catch; - fields: - boundNames: - extra-args: scopeKind - -AssertedParameterScope: - inherits: AssertedBlockScope - extra-params: | - MutableHandle> positionalParams - extra-args: | - positionalParams - init: | - const auto scopeKind = AssertedScopeKind::Parameter; - fields: - isSimpleParameterList: - after: | - (void) isSimpleParameterList; - paramNames: - extra-args: scopeKind, positionalParams - -AssertedScriptGlobalScope: - inherits: AssertedBlockScope - init: | - const auto scopeKind = AssertedScopeKind::Global; - -AssertedVarScope: - inherits: AssertedBlockScope - init: | - const auto scopeKind = AssertedScopeKind::Var; - -AssignmentExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newAssignment(ParseNodeKind::AssignExpr, - binding, expression)); - -AssignmentTargetIdentifier: - build: | - BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_DECL(result, - handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - -BindingIdentifier: - build: | - BINJS_TRY_DECL(result, - handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - -BinaryExpression: - build: | - ParseNodeKind pnk; - switch (operator_) { - case BinaryOperator::Comma: - pnk = ParseNodeKind::CommaExpr; - break; - case BinaryOperator::LogicalOr: - pnk = ParseNodeKind::OrExpr; - break; - case BinaryOperator::LogicalAnd: - pnk = ParseNodeKind::AndExpr; - break; - case BinaryOperator::BitOr: - pnk = ParseNodeKind::BitOrExpr; - break; - case BinaryOperator::BitXor: - pnk = ParseNodeKind::BitXorExpr; - break; - case BinaryOperator::BitAnd: - pnk = ParseNodeKind::BitAndExpr; - break; - case BinaryOperator::Eq: - pnk = ParseNodeKind::EqExpr; - break; - case BinaryOperator::Neq: - pnk = ParseNodeKind::NeExpr; - break; - case BinaryOperator::StrictEq: - pnk = ParseNodeKind::StrictEqExpr; - break; - case BinaryOperator::StrictNeq: - pnk = ParseNodeKind::StrictNeExpr; - break; - case BinaryOperator::LessThan: - pnk = ParseNodeKind::LtExpr; - break; - case BinaryOperator::LeqThan: - pnk = ParseNodeKind::LeExpr; - break; - case BinaryOperator::GreaterThan: - pnk = ParseNodeKind::GtExpr; - break; - case BinaryOperator::GeqThan: - pnk = ParseNodeKind::GeExpr; - break; - case BinaryOperator::In: - pnk = ParseNodeKind::InExpr; - break; - case BinaryOperator::Instanceof: - pnk = ParseNodeKind::InstanceOfExpr; - break; - case BinaryOperator::Lsh: - pnk = ParseNodeKind::LshExpr; - break; - case BinaryOperator::Rsh: - pnk = ParseNodeKind::RshExpr; - break; - case BinaryOperator::Ursh: - pnk = ParseNodeKind::UrshExpr; - break; - case BinaryOperator::Plus: - pnk = ParseNodeKind::AddExpr; - break; - case BinaryOperator::Minus: - pnk = ParseNodeKind::SubExpr; - break; - case BinaryOperator::Mul: - pnk = ParseNodeKind::MulExpr; - break; - case BinaryOperator::Div: - pnk = ParseNodeKind::DivExpr; - break; - case BinaryOperator::Mod: - pnk = ParseNodeKind::ModExpr; - break; - case BinaryOperator::Pow: - pnk = ParseNodeKind::PowExpr; - break; - } - - ParseNode* result; - // ParseNodeKind::PowExpr is not left-associative - if (left->isKind(pnk) && pnk != ParseNodeKind::PowExpr) { - // Regroup left-associative operations into lists. - left->template as().appendWithoutOrderAssumption(right); - result = left; - } else { - BINJS_TRY_DECL(list, handler_.newList(pnk, tokenizer_->pos(start))); - - list->appendWithoutOrderAssumption(left); - list->appendWithoutOrderAssumption(right); - result = list; - } - -Block: - init: | - ParseContext::Statement stmt(pc_, StatementKind::Block); - ParseContext::Scope currentScope(cx_, pc_, usedNames_); - BINJS_TRY(currentScope.init(pc_)); - build: | - MOZ_TRY(checkClosedVars(currentScope)); - BINJS_TRY_DECL(bindings, - NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); - BINJS_TRY_DECL(result, handler_.newLexicalScope(*bindings, statements)); - -BreakStatement: - fields: - label: - block: - replace: | - RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(FieldContext(BinASTInterfaceAndField::BreakStatement__Label))); - - build: | - if (label) { - if (!IsIdentifier(label)) { - return raiseError("Invalid identifier"); - } - } - - auto validity - = pc_->checkBreakStatement(label ? label->asPropertyName() : nullptr); - if (validity.isErr()) { - switch (validity.unwrapErr()) { - case ParseContext::BreakStatementError::ToughBreak: - this->error(JSMSG_TOUGH_BREAK); - return cx_->alreadyReportedError(); - case ParseContext::BreakStatementError::LabelNotFound: - this->error(JSMSG_LABEL_NOT_FOUND); - return cx_->alreadyReportedError(); - } - } - - BINJS_TRY_DECL(result, - handler_.newBreakStatement(label ? label->asPropertyName() - : nullptr, - tokenizer_->pos(start))); - -CallExpression: - build: | - auto op = JSOp::Call; - - // Try to optimize funcall and funapply at the bytecode level - if (PropertyName* prop = handler_.maybeDottedProperty(callee)) { - if (prop == cx_->names().apply) { - op = JSOp::FunApply; - if (pc_->isFunctionBox()) { - pc_->functionBox()->usesApply = true; - } - } else if (prop == cx_->names().call) { - op = JSOp::FunCall; - } - } - - // Check for direct calls to `eval`. - if (handler_.isEvalName(callee, cx_)) { - if (!pc_->varScope().lookupDeclaredNameForAdd(cx_->names().eval) && - !pc_->innermostScope()->lookupDeclaredNameForAdd(cx_->names().eval)) { - // This is a direct call to `eval`. - if (!pc_->sc()->hasDirectEval()) { - return raiseMissingDirectEvalInAssertedScope(); - } - - op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval; - } - } - - BINJS_TRY_DECL(result, handler_.newCall(callee, arguments, op)); - -CatchClause: - type-ok: - LexicalScopeNode* - init: | - ParseContext::Statement stmt(pc_, StatementKind::Catch); - ParseContext::Scope currentScope(cx_, pc_, usedNames_); - BINJS_TRY(currentScope.init(pc_)); - fields: - binding: - after: | - if (!currentScope.lookupDeclaredName(binding->template as().atom())) { - return raiseError("Missing catch variable in scope"); - } - build: | - MOZ_TRY(checkClosedVars(currentScope)); - BINJS_TRY_DECL(bindings, - NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); - BINJS_TRY_DECL(result, handler_.newLexicalScope(*bindings, body)); - BINJS_TRY(handler_.setupCatchScope(result, binding, body)); - -CompoundAssignmentExpression: - build: | - ParseNodeKind pnk; - switch (operator_){ - case CompoundAssignmentOperator::PlusAssign: - pnk = ParseNodeKind::AddAssignExpr; - break; - case CompoundAssignmentOperator::MinusAssign: - pnk = ParseNodeKind::SubAssignExpr; - break; - case CompoundAssignmentOperator::MulAssign: - pnk = ParseNodeKind::MulAssignExpr; - break; - case CompoundAssignmentOperator::DivAssign: - pnk = ParseNodeKind::DivAssignExpr; - break; - case CompoundAssignmentOperator::ModAssign: - pnk = ParseNodeKind::ModAssignExpr; - break; - case CompoundAssignmentOperator::PowAssign: - pnk = ParseNodeKind::PowAssignExpr; - break; - case CompoundAssignmentOperator::LshAssign: - pnk = ParseNodeKind::LshAssignExpr; - break; - case CompoundAssignmentOperator::RshAssign: - pnk = ParseNodeKind::RshAssignExpr; - break; - case CompoundAssignmentOperator::UrshAssign: - pnk = ParseNodeKind::UrshAssignExpr; - break; - case CompoundAssignmentOperator::BitOrAssign: - pnk = ParseNodeKind::BitOrAssignExpr; - break; - case CompoundAssignmentOperator::BitXorAssign: - pnk = ParseNodeKind::BitXorAssignExpr; - break; - case CompoundAssignmentOperator::BitAndAssign: - pnk = ParseNodeKind::BitAndAssignExpr; - break; - } - BINJS_TRY_DECL(result, handler_.newAssignment(pnk, binding, expression)); - -ComputedMemberAssignmentTarget: - build: | - BINJS_TRY_DECL(result, - handler_.newPropertyByValue(object, expression, - tokenizer_->offset())); - -ComputedMemberExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newPropertyByValue(object, expression, - tokenizer_->offset())); - -ConditionalExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newConditional(test, consequent, alternate)); - -ContinueStatement: - fields: - label: - block: - replace: | - RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(FieldContext(BinASTInterfaceAndField::ContinueStatement__Label))); - - build: | - if (label) { - if (!IsIdentifier(label)) { - return raiseError("ContinueStatement - Label MUST be an identifier"); - } - } - - auto validity - = pc_->checkContinueStatement(label ? label->asPropertyName() : nullptr); - if (validity.isErr()) { - switch (validity.unwrapErr()) { - case ParseContext::ContinueStatementError::NotInALoop: - this->error(JSMSG_BAD_CONTINUE); - return cx_->alreadyReportedError(); - case ParseContext::ContinueStatementError::LabelNotFound: - this->error(JSMSG_LABEL_NOT_FOUND); - return cx_->alreadyReportedError(); - } - } - - BINJS_TRY_DECL(result, - handler_.newContinueStatement(label ? label->asPropertyName() - : nullptr, - tokenizer_->pos(start))); - -DataProperty: - build: | - if (!handler_.isUsableAsObjectPropertyName(name)) { - return raiseError("DataProperty key kind"); - } - - ParseNode* result; - if (name->template is() && - name->template as().atom() == cx_->names().proto) { - BINJS_TRY_VAR(result, - handler_.newUnary(ParseNodeKind::MutateProto, start, - expression)); - } else { - BINJS_TRY_VAR(result, - handler_.newObjectMethodOrPropertyDefinition(name, - expression, - AccessorType::None)); - } - -Directive: - build: | - TokenPos pos = tokenizer_->pos(start); - BINJS_TRY_DECL(result, handler_.newStringLiteral(rawValue, pos)); - -DoWhileStatement: - init: - ParseContext::Statement stmt(pc_, StatementKind::DoLoop); - build: | - BINJS_TRY_DECL(result, - handler_.newDoWhileStatement(body, test, - tokenizer_->pos(start))); - -EagerFunctionDeclaration: - init: | - const auto syntax = FunctionSyntaxKind::Statement; - inherits: EagerFunctionExpression - -LazyFunctionDeclaration: - init: | - const auto syntax = FunctionSyntaxKind::Statement; - inherits: LazyFunctionExpression - -FunctionExpressionContents: - type-ok: - Ok - extra-params: | - uint32_t funLength, - ListNode** paramsOut, - ListNode** bodyOut - extra-args: | - funLength, paramsOut, bodyOut - fields: - isThisCaptured: - after: | - // TODO: Use this in BinASTParser::buildFunction. - (void) isThisCaptured; - isFunctionNameCaptured: - after: | - // Per spec, isFunctionNameCaptured can be true for anonymous - // function. Check isFunctionNameCaptured only for named - // function. - if (pc_->functionBox()->isNamedLambda() && - isFunctionNameCaptured) { - captureFunctionName(); - } - parameterScope: - before: | - Rooted> positionalParams(cx_, GCVector(cx_)); - extra-args: | - &positionalParams - params: - after: | - MOZ_TRY(checkFunctionLength(funLength)); - MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - build: | - *paramsOut = params; - *bodyOut = body; - auto result = Ok(); - -FunctionOrMethodContents: - inherits: FunctionExpressionContents - -GetterContents: - inherits: FunctionExpressionContents - fields: - body: - before: | - BINJS_TRY_DECL(params, handler_.newParamsBody(tokenizer_->pos(start))); - -SetterContents: - inherits: FunctionExpressionContents - fields: - param: - after: | - BINJS_TRY_DECL(params, handler_.newParamsBody(param->pn_pos)); - handler_.addList(params, param); - MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - -EagerFunctionExpression: - init: | - const auto syntax = FunctionSyntaxKind::Expression; - fields: - isGenerator: - after: | - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - isAsync: - after: | - if (isAsync) { - return raiseError("Async function is not supported in this preview release"); - } - contents: - before: | - BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox( - isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) ? name : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - extra-args: | - length, ¶ms, &body - after: | - MOZ_TRY(prependDirectivesToBody(body, directives)); - build: | - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, - handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(result, params, bodyScope)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - -LazyFunctionExpression: - init: | - const auto syntax = FunctionSyntaxKind::Expression; - fields: - isGenerator: - after: | - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - isAsync: - after: | - if (isAsync) { - return raiseError("Async function is not supported in this preview release"); - } - contents: - block: - replace: - // Don't parse the contents until we delazify. - build: | - // TODO: This will become incorrect in the face of ES6 features. - uint32_t nargs = length; - - BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox( - isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, name)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - - auto skipStart = contentsSkip.startOffset(); - auto skipEnd = skipStart + contentsSkip.length(); - MOZ_TRY(finishLazyFunction(funbox, nargs, skipStart, skipEnd)); - -EagerGetter: - init: | - const auto syntax = FunctionSyntaxKind::Setter; - const bool isGenerator = false; - const bool isAsync = false; - const auto accessorType = AccessorType::Getter; - const uint32_t length = 0; - inherits: EagerMethod - -EagerMethod: - init: | - const auto syntax = FunctionSyntaxKind::Method; - const auto accessorType = AccessorType::None; - inherits: EagerFunctionExpression - build: | - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, - handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(method, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(method, params, bodyScope)); - BINJS_TRY_DECL(result, - handler_.newObjectMethodOrPropertyDefinition(name, method, - accessorType)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - -EagerSetter: - init: | - const auto syntax = FunctionSyntaxKind::Setter; - const bool isGenerator = false; - const bool isAsync = false; - const auto accessorType = AccessorType::Setter; - inherits: EagerMethod - -EmptyStatement: - build: - BINJS_TRY_DECL(result, handler_.newEmptyStatement(tokenizer_->pos(start))); - -ExpressionStatement: - build: | - BINJS_TRY_DECL(result, - handler_.newExprStatement(expression)); - -ForInOfBinding: - init: - AutoVariableDeclarationKind kindGuard(this); - build: | - // Restored by `kindGuard`. - variableDeclarationKind_ = kind_; - MOZ_TRY(checkBinding(binding->template as().atom()->asPropertyName())); - ParseNodeKind pnk; - switch (kind_) { - case VariableDeclarationKind::Var: - pnk = ParseNodeKind::VarStmt; - break; - case VariableDeclarationKind::Let: - return raiseError("Let is not supported in this preview release"); - case VariableDeclarationKind::Const: - return raiseError("Const is not supported in this preview release"); - } - BINJS_TRY_DECL(result, - handler_.newDeclarationList(pnk, tokenizer_->pos(start))); - handler_.addList(result, binding); - - - -ForInStatement: - init: | - ParseContext::Statement stmt(pc_, StatementKind::ForInLoop); - - // Implicit scope around the `for`, used to store `for (let x in ...)` - // or `for (const x in ...)`-style declarations. Detail on the - // declaration is stored as part of `scope`. - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - build: | - BINJS_TRY_DECL(forHead, - handler_.newForInOrOfHead(ParseNodeKind::ForIn, left, right, - tokenizer_->pos(start))); - ParseNode* result; - BINJS_TRY_VAR(result, - handler_.newForStatement(start, forHead, body, - /* iflags = */ 0)); - - if (!scope.isEmpty()) { - BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, pc_)); - BINJS_TRY_VAR(result, handler_.newLexicalScope(*bindings, result)); - } - -FormalParameters: - type-ok: - ListNode* - build: | - auto result = items; - if (rest) { - return raiseError("Rest parameter is not supported in this preview release"); - } - -ForStatement: - init: | - ParseContext::Statement stmt(pc_, StatementKind::ForLoop); - - // Implicit scope around the `for`, used to store `for (let x; ...; ...)` - // or `for (const x; ...; ...)`-style declarations. Detail on the - // declaration is stored as part of `BINJS_Scope`. - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - build: | - BINJS_TRY_DECL(forHead, - handler_.newForHead(init, test, update, - tokenizer_->pos(start))); - ParseNode* result; - BINJS_TRY_VAR(result, - handler_.newForStatement(start, forHead, body, - /* iflags = */ 0)); - - if (!scope.isEmpty()) { - BINJS_TRY_DECL(bindings, - NewLexicalScopeData(cx_, scope, alloc_, pc_)); - BINJS_TRY_VAR(result, handler_.newLexicalScope(*bindings, result)); - } - -FunctionBody: - inherits: ListOfStatement - -IdentifierExpression: - build: | - BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_DECL(result, - handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - -IfStatement: - build: | - BINJS_TRY_DECL(result, - handler_.newIfStatement(start, test, consequent, alternate)); - -LabelledStatement: - fields: - label: - after: | - if (!IsIdentifier(label)) { - return raiseError("Invalid identifier"); - } - ParseContext::LabelStatement stmt(pc_, label); - build: | - BINJS_TRY_DECL(result, - handler_.newLabeledStatement(label->asPropertyName(), body, - start)); - -ListOfAssertedBoundName: - extra-params: AssertedScopeKind scopeKind - extra-args: scopeKind - type-ok: - Ok - init: | - (void) start; - auto result = Ok(); - append: | - // Nothing to do here. - -ListOfAssertedMaybePositionalParameterName: - inherits: ListOfAssertedBoundName - extra-params: | - AssertedScopeKind scopeKind, - MutableHandle> positionalParams - extra-args: | - scopeKind, positionalParams - init: | - (void) start; - auto result = Ok(); - // This list contains also destructuring parameters, and the number of - // list items can be greater than the actual parameters, or more than - // ARGNO_LIMIT even if the number of parameters fits into ARGNO_LIMIT. - // Also, the number of parameters can be greater than this list's length - // if one of destructuring parameter is empty. - // - // We resize `positionalParams` vector on demand, to keep the vector - // length match to the known maximum positional parameter index + 1. - -ListOfAssertedDeclaredName: - inherits: ListOfAssertedBoundName - -ListOfDirective: - type-ok: - ListNode* - init: - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - append: - handler_.addStatementToList(result, item); - -ListOfObjectProperty: - type-ok: - ListNode* - init: - BINJS_TRY_DECL(result, handler_.newObjectLiteral(start)); - append: | - if (!item->isConstant()) - result->setHasNonConstInitializer(); - result->appendWithoutOrderAssumption(item); - -ListOfOptionalExpressionOrSpreadElement: - type-ok: - ListNode* - init: - BINJS_TRY_DECL(result, handler_.newArrayLiteral(start)); - append: | - if (item) { - handler_.addArrayElement(result, item); // Infallible. - } else { - BINJS_TRY(handler_.addElision(result, tokenizer_->pos(start))); - } - -ListOfParameter: - type-ok: - ListNode* - init: | - BINJS_TRY_DECL(result, handler_.newParamsBody(tokenizer_->pos(start))); - append: - handler_.addList(/* list = */ result, /* kid = */ item); - -ListOfStatement: - type-ok: - ListNode* - init: - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - append: - handler_.addStatementToList(result, item); - - -#ListOfSpreadElementOrExpression: -# type-ok: -# ListNode* -# init: -# BINJS_TRY_DECL(result, handler_.newParamsBody(tokenizer_->pos())); -# append: -# result->appendWithoutOrderAssumption(item); - -ListOfSwitchCase: - type-ok: - ListNode* - init: - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - append: - handler_.addCaseStatementToList(result, item); - -ListOfVariableDeclarator: - extra-params: ParseNodeKind declarationListKind - type-ok: - ListNode* - init: | - BINJS_TRY_DECL(result, - handler_.newDeclarationList(declarationListKind, - tokenizer_->pos(start))); - -LiteralBooleanExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newBooleanLiteral(value, tokenizer_->pos(start))); - -LiteralNumericExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start))); - -LiteralNullExpression: - build: | - BINJS_TRY_DECL(result, handler_.newNullLiteral(tokenizer_->pos(start))); - -LiteralPropertyName: - build: | - ParseNode* result; - uint32_t index; - if (value->isIndex(&index)) { - BINJS_TRY_VAR(result, - handler_.newNumber(index, NoDecimal, - TokenPos(start, tokenizer_->offset()))); - } else { - BINJS_TRY_VAR(result, - handler_.newObjectLiteralPropertyName(value, - tokenizer_->pos(start))); - } - -LiteralRegExpExpression: - fields: - flags: - block: - replace: | - RegExpFlags reflags = JS::RegExpFlag::NoFlags; - auto flagsContext = FieldContext(BinASTInterfaceAndField::LiteralRegExpExpression__Flags); - if (mozilla::IsSame::value) { - // Hack: optimized `readChars` is not implemented for `BinASTTokenReaderContext`. - RootedAtom flags(cx_); - MOZ_TRY_VAR(flags, tokenizer_->readAtom(flagsContext)); - if (!this->parseRegExpFlags(flags, &reflags)) { - return raiseError("Invalid regexp flags"); - } - } else { - Chars flags(cx_); - MOZ_TRY(tokenizer_->readChars(flags, flagsContext)); - if (!this->parseRegExpFlags(flags, &reflags)) { - return raiseError("Invalid regexp flags"); - } - } - - build: | - Rooted reobj(cx_); - BINJS_TRY_VAR(reobj, - RegExpObject::create(cx_, pattern, reflags, TenuredObject)); - - BINJS_TRY_DECL(result, - handler_.newRegExp(reobj, tokenizer_->pos(start), *this)); - -LiteralStringExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newStringLiteral(value, tokenizer_->pos(start))); - -NewExpression: - build: | - BINJS_TRY_DECL(result, - handler_.newNewExpression(tokenizer_->pos(start).begin, - callee, arguments, /* isSpread = */ false)); - -ObjectExpression: - build: - auto result = properties; - -OptionalCatchClause: - type-ok: - LexicalScopeNode* - -Parameter: - sum-arms: - BindingIdentifier: - after: | - if (!pc_->positionalFormalParameterNames().append( - result->template as().atom())) { - return raiseOOM(); - } - if (pc_->isFunctionBox()) { - pc_->functionBox()->length++; - } - -ReturnStatement: - init: | - if (!pc_->isFunctionBox()) { - // Return statements are permitted only inside functions. - return raiseInvalidKind("Toplevel Statement", BinASTKind::ReturnStatement); - } - - pc_->functionBox()->usesReturn = true; - build: | - BINJS_TRY_DECL(result, - handler_.newReturnStatement(expression, - tokenizer_->pos(start))); - -Script: - fields: - directives: - after: | - forceStrictIfNecessary(pc_->sc(), directives); - build: | - MOZ_TRY(checkClosedVars(pc_->varScope())); - MOZ_TRY(prependDirectivesToBody(/* body = */ statements, directives)); - auto result = statements; - -ShorthandProperty: - build: | - MOZ_ASSERT(name->isKind(ParseNodeKind::Name)); - MOZ_ASSERT(!handler_.isUsableAsObjectPropertyName(name)); - BINJS_TRY_DECL(propName, - handler_.newObjectLiteralPropertyName(name->template as().name(), - tokenizer_->pos(start))); - - BINJS_TRY_DECL(result, - handler_.newShorthandPropertyDefinition(propName, name)); - -SwitchCase: - type-ok: - CaseClause* - build: | - BINJS_TRY_DECL(result, handler_.newCaseOrDefault(start, test, consequent)); - -SwitchDefault: - build: | - BINJS_TRY_DECL(result, - handler_.newCaseOrDefault(start, nullptr, consequent)); - -SwitchStatement: - fields: - discriminant: - after: | - ParseContext::Statement stmt(pc_, StatementKind::Switch); - build: | - BINJS_TRY_DECL(scope, handler_.newLexicalScope(nullptr, cases)); - BINJS_TRY_DECL(result, - handler_.newSwitchStatement(start, discriminant, scope, - /* hasDefault = */ false)); - -SwitchStatementWithDefault: - fields: - discriminant: - after: | - ParseContext::Statement stmt(pc_, StatementKind::Switch); - build: | - // Concatenate `preDefaultCase`, `defaultCase`, `postDefaultCase` - auto cases = preDefaultCases; - handler_.addList(cases, defaultCase); - ParseNode* iter = postDefaultCases->head(); - while (iter) { - ParseNode* next = iter->pn_next; - handler_.addList(cases, iter); - iter = next; - } - BINJS_TRY_DECL(scope, handler_.newLexicalScope(nullptr, cases)); - BINJS_TRY_DECL(result, - handler_.newSwitchStatement(start, discriminant, scope, - /* hasDefault = */ true)); - -StaticMemberAssignmentTarget: - init: - size_t nameStart; - fields: - property: - block: - before: | - nameStart = tokenizer_->offset(); - build: | - BINJS_TRY_DECL(name, - handler_.newPropertyName(property->asPropertyName(), - tokenizer_->pos(nameStart))); - BINJS_TRY_DECL(result, handler_.newPropertyAccess(object, name)); - -StaticMemberExpression: - init: - size_t nameStart; - fields: - property: - block: - before: | - nameStart = tokenizer_->offset(); - build: | - BINJS_TRY_DECL(name, - handler_.newPropertyName(property->asPropertyName(), - tokenizer_->pos(nameStart))); - BINJS_TRY_DECL(result, handler_.newPropertyAccess(object, name)); - -ThisExpression: - build: | - if (pc_->isFunctionBox()) { - pc_->functionBox()->usesThis = true; - } - - TokenPos pos = tokenizer_->pos(start); - ParseNode* thisName(nullptr); - if (pc_->sc()->hasFunctionThisBinding()) { - HandlePropertyName dotThis = cx_->names().dotThis; - BINJS_TRY(usedNames_.noteUse(cx_, dotThis, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_VAR(thisName, handler_.newName(dotThis, pos, cx_)); - } - - BINJS_TRY_DECL(result, handler_.newThisLiteral(pos, thisName)); - -ThrowStatement: - build: | - BINJS_TRY_DECL(result, - handler_.newThrowStatement(expression, - tokenizer_->pos(start))); - -TryCatchStatement: - fields: - body: - block: - declare: - ParseNode* body; - before: | - ParseContext::Statement stmt(pc_, StatementKind::Try); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - build: | - BINJS_TRY_DECL(result, - handler_.newTryStatement(start, body, catchClause, - /* finallyBlock = */ nullptr)); - -TryFinallyStatement: - fields: - body: - block: - declare: - ParseNode* body; - before: | - ParseContext::Statement stmt(pc_, StatementKind::Try); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - finalizer: - block: - declare: - ParseNode* finalizer; - before: | - ParseContext::Statement stmt(pc_, StatementKind::Finally); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - build: | - BINJS_TRY_DECL(result, - handler_.newTryStatement(start, body, catchClause, - finalizer)); - -UnaryExpression: - build: | - ParseNodeKind pnk; - switch (operator_) { - case UnaryOperator::Minus: - pnk = ParseNodeKind::NegExpr; - break; - case UnaryOperator::Plus: - pnk = ParseNodeKind::PosExpr; - break; - case UnaryOperator::Not: - pnk = ParseNodeKind::NotExpr; - break; - case UnaryOperator::BitNot: - pnk = ParseNodeKind::BitNotExpr; - break; - case UnaryOperator::Typeof: { - if (operand->isKind(ParseNodeKind::Name)) { - pnk = ParseNodeKind::TypeOfNameExpr; - } else { - pnk = ParseNodeKind::TypeOfExpr; - } - break; - } - case UnaryOperator::Void: - pnk = ParseNodeKind::VoidExpr; - break; - case UnaryOperator::Delete: { - switch (operand->getKind()) { - case ParseNodeKind::Name: - pnk = ParseNodeKind::DeleteNameExpr; - BINJS_TRY(this->strictModeError(JSMSG_DEPRECATED_DELETE_OPERAND)); - pc_->sc()->setBindingsAccessedDynamically(); - break; - case ParseNodeKind::DotExpr: - pnk = ParseNodeKind::DeletePropExpr; - break; - case ParseNodeKind::ElemExpr: - pnk = ParseNodeKind::DeleteElemExpr; - break; - default: - pnk = ParseNodeKind::DeleteExpr; - } - break; - } - } - BINJS_TRY_DECL(result, handler_.newUnary(pnk, start, operand)); - -UpdateExpression: - build: | - ParseNodeKind pnk; - switch (operator_) { - case UpdateOperator::Incr: - pnk = isPrefix ? ParseNodeKind::PreIncrementExpr - : ParseNodeKind::PostIncrementExpr; - break; - case UpdateOperator::Decr: - pnk = isPrefix ? ParseNodeKind::PreDecrementExpr - : ParseNodeKind::PostDecrementExpr; - break; - } - BINJS_TRY_DECL(result, handler_.newUnary(pnk, start, operand)); - -VariableDeclaration: - init: - AutoVariableDeclarationKind kindGuard(this); - - fields: - kind: - after: | - // Restored by `kindGuard`. - variableDeclarationKind_ = kind_; - ParseNodeKind declarationListKind; - switch (kind_) { - case VariableDeclarationKind::Var: - declarationListKind = ParseNodeKind::VarStmt; - break; - case VariableDeclarationKind::Let: - return raiseError("Let is not supported in this preview release"); - case VariableDeclarationKind::Const: - return raiseError("Const is not supported in this preview release"); - } - declarators: - extra-args: declarationListKind - - build: | - // By specification, the list may not be empty. - if (declarators->empty()) { - return raiseEmpty("VariableDeclaration"); - } - - auto result = declarators; - -VariableDeclarator: - build: | - ParseNode* result; - if (binding->isKind(ParseNodeKind::Name)) { - // `var foo [= bar]`` - NameNode* bindingNameNode = &binding->template as(); - MOZ_TRY(checkBinding(bindingNameNode->atom()->asPropertyName())); - if (init) { - BINJS_TRY_VAR(result, - handler_.finishInitializerAssignment(bindingNameNode, init)); - } else { - result = bindingNameNode; - } - } else { - // `var pattern = bar` - if (!init) { - // Here, `init` is required. - return raiseMissingField("VariableDeclarator (with non-trivial pattern)", - BinASTField::Init); - } - - MOZ_CRASH("Unimplemented: AssertedScope check for BindingPattern variable declaration"); - BINJS_TRY_VAR(result, - handler_.newAssignment(ParseNodeKind::AssignExpr, binding, - init)); - } - -WhileStatement: - init: - ParseContext::Statement stmt(pc_, StatementKind::WhileLoop); - build: - BINJS_TRY_DECL(result, handler_.newWhileStatement(start, test, body)); - -WithStatement: - fields: - body: - before: | - ParseContext::Statement stmt(pc_, StatementKind::With); - build: | - pc_->sc()->setBindingsAccessedDynamically(); - BINJS_TRY_DECL(result, handler_.newWithStatement(start, object, body)); diff --git a/js/src/frontend/BinASTEnum.h b/js/src/frontend/BinASTEnum.h deleted file mode 100644 index 4f3e34351d..0000000000 --- a/js/src/frontend/BinASTEnum.h +++ /dev/null @@ -1,145 +0,0 @@ -// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// To generate this file, see the documentation in -// js/src/frontend/binast/README.md. - -#ifndef frontend_BinASTEnum_h -#define frontend_BinASTEnum_h - -namespace js { -namespace frontend { -namespace binast { - -// ----- Declaring string enums (by lexicographical order) - -enum class AssertedDeclaredKind { - // "var" - Var, - // "non-const lexical" - NonConstLexical, - // "const lexical" - ConstLexical, -}; - -enum class BinaryOperator { - // "," - Comma, - // "||" - LogicalOr, - // "&&" - LogicalAnd, - // "|" - BitOr, - // "^" - BitXor, - // "&" - BitAnd, - // "==" - Eq, - // "!=" - Neq, - // "===" - StrictEq, - // "!==" - StrictNeq, - // "<" - LessThan, - // "<=" - LeqThan, - // ">" - GreaterThan, - // ">=" - GeqThan, - // "in" - In, - // "instanceof" - Instanceof, - // "<<" - Lsh, - // ">>" - Rsh, - // ">>>" - Ursh, - // "+" - Plus, - // "-" - Minus, - // "*" - Mul, - // "/" - Div, - // "%" - Mod, - // "**" - Pow, -}; - -enum class CompoundAssignmentOperator { - // "+=" - PlusAssign, - // "-=" - MinusAssign, - // "*=" - MulAssign, - // "/=" - DivAssign, - // "%=" - ModAssign, - // "**=" - PowAssign, - // "<<=" - LshAssign, - // ">>=" - RshAssign, - // ">>>=" - UrshAssign, - // "|=" - BitOrAssign, - // "^=" - BitXorAssign, - // "&=" - BitAndAssign, -}; - -enum class UnaryOperator { - // "+" - Plus, - // "-" - Minus, - // "!" - Not, - // "~" - BitNot, - // "typeof" - Typeof, - // "void" - Void, - // "delete" - Delete, -}; - -enum class UpdateOperator { - // "++" - Incr, - // "--" - Decr, -}; - -enum class VariableDeclarationKind { - // "var" - Var, - // "let" - Let, - // "const" - Const, -}; - -} // namespace binast -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTEnum_h diff --git a/js/src/frontend/BinASTParser.cpp b/js/src/frontend/BinASTParser.cpp deleted file mode 100644 index 521eaf33b2..0000000000 --- a/js/src/frontend/BinASTParser.cpp +++ /dev/null @@ -1,5064 +0,0 @@ -// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// To generate this file, see the documentation in -// js/src/frontend/binast/README.md. - -#include "frontend/BinASTParser.h" - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Casting.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" -#include "mozilla/PodOperations.h" -#include "mozilla/Vector.h" - -#include - -#include "frontend/BinAST-macros.h" -#include "frontend/BinASTTokenReaderContext.h" -#include "frontend/BinASTTokenReaderMultipart.h" -#include "frontend/FullParseHandler.h" -#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind -#include "frontend/ParseNode.h" -#include "frontend/Parser.h" -#include "frontend/SharedContext.h" -#include "irregexp/RegExpAPI.h" -#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags -#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind -#include "vm/RegExpObject.h" - -#include "frontend/ParseContext-inl.h" - -using JS::RegExpFlag; -using JS::RegExpFlags; - -namespace js::frontend { - -// Compare a bunch of `uint8_t` values (as returned by the tokenizer_) with -// a string literal (and ONLY a string literal). -template -bool operator==(const typename Tok::Chars& left, const char (&right)[N]) { - return Tok::equals(left, right); -} - -// ----- Sums of interfaces (autogenerated, by lexicographical order) -// Sums of sums are flattened. -/* -AssertedMaybePositionalParameterName ::= AssertedParameterName - AssertedPositionalParameterName - AssertedRestParameterName -*/ -template -JS::Result BinASTParser::parseAssertedMaybePositionalParameterName( - AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, - parseSumAssertedMaybePositionalParameterName( - start, kind, scopeKind, positionalParams, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumAssertedMaybePositionalParameterName( - const size_t start, const BinASTKind kind, AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context) { - Ok result; - switch (kind) { - case BinASTKind::AssertedParameterName: - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(AssertedParameterName)"); - case BinASTKind::AssertedPositionalParameterName: - MOZ_TRY_VAR(result, parseInterfaceAssertedPositionalParameterName( - start, scopeKind, positionalParams, context)); - break; - case BinASTKind::AssertedRestParameterName: - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(AssertedRestParameterName)"); - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("AssertedMaybePositionalParameterName", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -AssignmentTarget ::= ArrayAssignmentTarget - AssignmentTargetIdentifier - ComputedMemberAssignmentTarget - ObjectAssignmentTarget - StaticMemberAssignmentTarget -*/ -template -JS::Result BinASTParser::parseAssignmentTarget( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumAssignmentTarget(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumAssignmentTarget( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayAssignmentTarget: - MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, context)); - break; - case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentTargetIdentifier(start, context)); - break; - case BinASTKind::ComputedMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberAssignmentTarget(start, context)); - break; - case BinASTKind::ObjectAssignmentTarget: - MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget(start, context)); - break; - case BinASTKind::StaticMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberAssignmentTarget(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("AssignmentTarget", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -AssignmentTargetOrForInOfBinding ::= ArrayAssignmentTarget - AssignmentTargetIdentifier - ComputedMemberAssignmentTarget - ForInOfBinding - ObjectAssignmentTarget - StaticMemberAssignmentTarget -*/ -template -JS::Result BinASTParser::parseAssignmentTargetOrForInOfBinding( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL( - result, parseSumAssignmentTargetOrForInOfBinding(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result -BinASTParser::parseSumAssignmentTargetOrForInOfBinding( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayAssignmentTarget: - MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, context)); - break; - case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentTargetIdentifier(start, context)); - break; - case BinASTKind::ComputedMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberAssignmentTarget(start, context)); - break; - case BinASTKind::ForInOfBinding: - MOZ_TRY_VAR(result, parseInterfaceForInOfBinding(start, context)); - break; - case BinASTKind::ObjectAssignmentTarget: - MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget(start, context)); - break; - case BinASTKind::StaticMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberAssignmentTarget(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("AssignmentTargetOrForInOfBinding", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -Binding ::= ArrayBinding - BindingIdentifier - ObjectBinding -*/ -template -JS::Result BinASTParser::parseBinding( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumBinding(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumBinding( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayBinding: - MOZ_TRY_VAR(result, parseInterfaceArrayBinding( - start, FieldOrListContext(context))); - break; - case BinASTKind::BindingIdentifier: - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier( - start, FieldOrListContext(context))); - break; - case BinASTKind::ObjectBinding: - MOZ_TRY_VAR(result, parseInterfaceObjectBinding( - start, FieldOrListContext(context))); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("Binding", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -Expression ::= ArrayExpression - AssignmentExpression - AwaitExpression - BinaryExpression - CallExpression - ClassExpression - CompoundAssignmentExpression - ComputedMemberExpression - ConditionalExpression - EagerArrowExpressionWithExpression - EagerArrowExpressionWithFunctionBody - EagerFunctionExpression - IdentifierExpression - LazyArrowExpressionWithExpression - LazyArrowExpressionWithFunctionBody - LazyFunctionExpression - LiteralBooleanExpression - LiteralInfinityExpression - LiteralNullExpression - LiteralNumericExpression - LiteralRegExpExpression - LiteralStringExpression - NewExpression - NewTargetExpression - ObjectExpression - StaticMemberExpression - TemplateExpression - ThisExpression - UnaryExpression - UpdateExpression - YieldExpression - YieldStarExpression -*/ -template -JS::Result BinASTParser::parseExpression( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumExpression(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumExpression( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CompoundAssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, parseInterfaceConditionalExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, parseInterfaceTemplateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression( - start, FieldOrListContext(context))); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("Expression", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -ExpressionOrSpreadElement ::= ArrayExpression - AssignmentExpression - AwaitExpression - BinaryExpression - CallExpression - ClassExpression - CompoundAssignmentExpression - ComputedMemberExpression - ConditionalExpression - EagerArrowExpressionWithExpression - EagerArrowExpressionWithFunctionBody - EagerFunctionExpression - IdentifierExpression - LazyArrowExpressionWithExpression - LazyArrowExpressionWithFunctionBody - LazyFunctionExpression - LiteralBooleanExpression - LiteralInfinityExpression - LiteralNullExpression - LiteralNumericExpression - LiteralRegExpExpression - LiteralStringExpression - NewExpression - NewTargetExpression - ObjectExpression - SpreadElement - StaticMemberExpression - TemplateExpression - ThisExpression - UnaryExpression - UpdateExpression - YieldExpression - YieldStarExpression -*/ -template -JS::Result BinASTParser::parseExpressionOrSpreadElement( - const ListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, - parseSumExpressionOrSpreadElement(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumExpressionOrSpreadElement( - const size_t start, const BinASTKind kind, const ListContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CompoundAssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, parseInterfaceConditionalExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::SpreadElement: - MOZ_TRY_VAR(result, parseInterfaceSpreadElement(start, context)); - break; - case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, parseInterfaceTemplateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression( - start, FieldOrListContext(context))); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("ExpressionOrSpreadElement", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -ExpressionOrSuper ::= ArrayExpression - AssignmentExpression - AwaitExpression - BinaryExpression - CallExpression - ClassExpression - CompoundAssignmentExpression - ComputedMemberExpression - ConditionalExpression - EagerArrowExpressionWithExpression - EagerArrowExpressionWithFunctionBody - EagerFunctionExpression - IdentifierExpression - LazyArrowExpressionWithExpression - LazyArrowExpressionWithFunctionBody - LazyFunctionExpression - LiteralBooleanExpression - LiteralInfinityExpression - LiteralNullExpression - LiteralNumericExpression - LiteralRegExpExpression - LiteralStringExpression - NewExpression - NewTargetExpression - ObjectExpression - StaticMemberExpression - Super - TemplateExpression - ThisExpression - UnaryExpression - UpdateExpression - YieldExpression - YieldStarExpression -*/ -template -JS::Result BinASTParser::parseExpressionOrSuper( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumExpressionOrSuper(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumExpressionOrSuper( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CompoundAssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, parseInterfaceConditionalExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::Super: - MOZ_TRY_VAR(result, parseInterfaceSuper(start, context)); - break; - case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, parseInterfaceTemplateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression( - start, FieldOrListContext(context))); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("ExpressionOrSuper", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -template -JS::Result -BinASTParser::parseSumExpressionOrVariableDeclaration( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::CompoundAssignmentExpression: - MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, parseInterfaceConditionalExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyArrowExpressionWithFunctionBody: - MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, FieldOrListContext(context))); - break; - case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, parseInterfaceTemplateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::VariableDeclaration: - MOZ_TRY_VAR(result, parseInterfaceVariableDeclaration( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression( - start, FieldOrListContext(context))); - break; - case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression( - start, FieldOrListContext(context))); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("ExpressionOrVariableDeclaration", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -ObjectProperty ::= DataProperty - EagerGetter - EagerMethod - EagerSetter - LazyGetter - LazyMethod - LazySetter - ShorthandProperty -*/ -template -JS::Result BinASTParser::parseObjectProperty( - const ListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumObjectProperty(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumObjectProperty( - const size_t start, const BinASTKind kind, const ListContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::DataProperty: - MOZ_TRY_VAR(result, parseInterfaceDataProperty(start, context)); - break; - case BinASTKind::EagerGetter: - MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, context)); - break; - case BinASTKind::EagerMethod: - MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, context)); - break; - case BinASTKind::EagerSetter: - MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, context)); - break; - case BinASTKind::LazyGetter: - MOZ_TRY_VAR(result, parseInterfaceLazyGetter(start, context)); - break; - case BinASTKind::LazyMethod: - MOZ_TRY_VAR(result, parseInterfaceLazyMethod(start, context)); - break; - case BinASTKind::LazySetter: - MOZ_TRY_VAR(result, parseInterfaceLazySetter(start, context)); - break; - case BinASTKind::ShorthandProperty: - MOZ_TRY_VAR(result, parseInterfaceShorthandProperty(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("ObjectProperty", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -Parameter ::= ArrayBinding - BindingIdentifier - BindingWithInitializer - ObjectBinding -*/ -template -JS::Result BinASTParser::parseParameter( - const FieldOrListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumParameter(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumParameter( - const size_t start, const BinASTKind kind, - const FieldOrListContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ArrayBinding: - MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, context)); - break; - case BinASTKind::BindingIdentifier: - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, context)); - if (!pc_->positionalFormalParameterNames().append( - result->template as().atom())) { - return raiseOOM(); - } - if (pc_->isFunctionBox()) { - pc_->functionBox()->length++; - } - break; - case BinASTKind::BindingWithInitializer: - MOZ_TRY_VAR(result, parseInterfaceBindingWithInitializer(start, context)); - break; - case BinASTKind::ObjectBinding: - MOZ_TRY_VAR(result, parseInterfaceObjectBinding(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("Parameter", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -Program ::= Module - Script -*/ -template -JS::Result BinASTParser::parseProgram( - const RootContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumProgram(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumProgram( - const size_t start, const BinASTKind kind, const RootContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::Module: - MOZ_TRY_VAR(result, parseInterfaceModule(start, context)); - break; - case BinASTKind::Script: - MOZ_TRY_VAR(result, parseInterfaceScript(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("Program", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -PropertyName ::= ComputedPropertyName - LiteralPropertyName -*/ -template -JS::Result BinASTParser::parsePropertyName( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumPropertyName(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumPropertyName( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::ComputedPropertyName: - MOZ_TRY_VAR(result, parseInterfaceComputedPropertyName(start, context)); - break; - case BinASTKind::LiteralPropertyName: - MOZ_TRY_VAR(result, parseInterfaceLiteralPropertyName(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("PropertyName", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -SimpleAssignmentTarget ::= AssignmentTargetIdentifier - ComputedMemberAssignmentTarget - StaticMemberAssignmentTarget -*/ -template -JS::Result BinASTParser::parseSimpleAssignmentTarget( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, - parseSumSimpleAssignmentTarget(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumSimpleAssignmentTarget( - const size_t start, const BinASTKind kind, const FieldContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentTargetIdentifier(start, context)); - break; - case BinASTKind::ComputedMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberAssignmentTarget(start, context)); - break; - case BinASTKind::StaticMemberAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberAssignmentTarget(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("SimpleAssignmentTarget", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -/* -Statement ::= Block - BreakStatement - ClassDeclaration - ContinueStatement - DebuggerStatement - DoWhileStatement - EagerFunctionDeclaration - EmptyStatement - ExpressionStatement - ForInStatement - ForOfStatement - ForStatement - IfStatement - LabelledStatement - LazyFunctionDeclaration - ReturnStatement - SwitchStatement - SwitchStatementWithDefault - ThrowStatement - TryCatchStatement - TryFinallyStatement - VariableDeclaration - WhileStatement - WithStatement -*/ -template -JS::Result BinASTParser::parseStatement( - const FieldOrListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - - BINJS_MOZ_TRY_DECL(result, parseSumStatement(start, kind, context)); - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseSumStatement( - const size_t start, const BinASTKind kind, - const FieldOrListContext& context) { - ParseNode* result; - switch (kind) { - case BinASTKind::Block: - MOZ_TRY_VAR(result, parseInterfaceBlock(start, context)); - break; - case BinASTKind::BreakStatement: - MOZ_TRY_VAR(result, parseInterfaceBreakStatement(start, context)); - break; - case BinASTKind::ClassDeclaration: - MOZ_TRY_VAR(result, parseInterfaceClassDeclaration(start, context)); - break; - case BinASTKind::ContinueStatement: - MOZ_TRY_VAR(result, parseInterfaceContinueStatement(start, context)); - break; - case BinASTKind::DebuggerStatement: - MOZ_TRY_VAR(result, parseInterfaceDebuggerStatement(start, context)); - break; - case BinASTKind::DoWhileStatement: - MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, context)); - break; - case BinASTKind::EagerFunctionDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionDeclaration(start, context)); - break; - case BinASTKind::EmptyStatement: - MOZ_TRY_VAR(result, parseInterfaceEmptyStatement(start, context)); - break; - case BinASTKind::ExpressionStatement: - MOZ_TRY_VAR(result, parseInterfaceExpressionStatement(start, context)); - break; - case BinASTKind::ForInStatement: - MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, context)); - break; - case BinASTKind::ForOfStatement: - MOZ_TRY_VAR(result, parseInterfaceForOfStatement(start, context)); - break; - case BinASTKind::ForStatement: - MOZ_TRY_VAR(result, parseInterfaceForStatement(start, context)); - break; - case BinASTKind::IfStatement: - MOZ_TRY_VAR(result, parseInterfaceIfStatement(start, context)); - break; - case BinASTKind::LabelledStatement: - MOZ_TRY_VAR(result, parseInterfaceLabelledStatement(start, context)); - break; - case BinASTKind::LazyFunctionDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionDeclaration(start, context)); - break; - case BinASTKind::ReturnStatement: - MOZ_TRY_VAR(result, parseInterfaceReturnStatement(start, context)); - break; - case BinASTKind::SwitchStatement: - MOZ_TRY_VAR(result, parseInterfaceSwitchStatement(start, context)); - break; - case BinASTKind::SwitchStatementWithDefault: - MOZ_TRY_VAR(result, - parseInterfaceSwitchStatementWithDefault(start, context)); - break; - case BinASTKind::ThrowStatement: - MOZ_TRY_VAR(result, parseInterfaceThrowStatement(start, context)); - break; - case BinASTKind::TryCatchStatement: - MOZ_TRY_VAR(result, parseInterfaceTryCatchStatement(start, context)); - break; - case BinASTKind::TryFinallyStatement: - MOZ_TRY_VAR(result, parseInterfaceTryFinallyStatement(start, context)); - break; - case BinASTKind::VariableDeclaration: - MOZ_TRY_VAR(result, parseInterfaceVariableDeclaration(start, context)); - break; - case BinASTKind::WhileStatement: - MOZ_TRY_VAR(result, parseInterfaceWhileStatement(start, context)); - break; - case BinASTKind::WithStatement: - MOZ_TRY_VAR(result, parseInterfaceWithStatement(start, context)); - break; - default: - if (isInvalidKindPossible()) { - return raiseInvalidKind("Statement", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - return result; -} - -// ----- Interfaces (autogenerated, by lexicographical order) -// When fields have a non-trivial type, implementation is deanonymized and -// delegated to another parser. -template -JS::Result BinASTParser::parseInterfaceArrayAssignmentTarget( - const size_t start, const FieldContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(ArrayAssignmentTarget)"); -} - -template -JS::Result BinASTParser::parseInterfaceArrayBinding( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (ArrayBinding)"); -} - -template -JS::Result BinASTParser::parseInterfaceArrayExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(elements, - parseListOfOptionalExpressionOrSpreadElement(FieldContext( - BinASTInterfaceAndField::ArrayExpression__Elements))); - - if (elements->empty()) { - elements->setHasNonConstInitializer(); - } - auto result = elements; - return result; -} - -/* - interface AssertedBlockScope : Node { - FrozenArray declaredNames; - bool hasDirectEval; - } -*/ -template -JS::Result BinASTParser::parseAssertedBlockScope( - const FieldContext& context) { - BinASTKind kind = BinASTKind::AssertedBlockScope; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedBlockScope(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedBlockScope( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto scopeKind = AssertedScopeKind::Block; - - MOZ_TRY(parseListOfAssertedDeclaredName( - scopeKind, - FieldContext( - BinASTInterfaceAndField::AssertedBlockScope__DeclaredNames))); - - BINJS_MOZ_TRY_DECL( - hasDirectEval, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedBlockScope__HasDirectEval))); - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setFunHasExtensibleScope(); - } - auto result = Ok(); - return result; -} - -/* - interface AssertedBoundName : Node { - [IdentifierName] string name; - bool isCaptured; - } -*/ -template -JS::Result BinASTParser::parseAssertedBoundName( - AssertedScopeKind scopeKind, const ListContext& context) { - BinASTKind kind = BinASTKind::AssertedBoundName; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceAssertedBoundName(start, scopeKind, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedBoundName( - const size_t start, AssertedScopeKind scopeKind, - const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const bool allowDuplicateName = false; - - RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::AssertedBoundName__Name))); - - BINJS_MOZ_TRY_DECL( - isCaptured, tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedBoundName__IsCaptured))); - ParseContext::Scope* scope; - DeclarationKind declKind; - MOZ_TRY(getBoundScope(scopeKind, scope, declKind)); - MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured, - allowDuplicateName)); - auto result = Ok(); - return result; -} - -/* - interface AssertedBoundNamesScope : Node { - FrozenArray boundNames; - bool hasDirectEval; - } -*/ -template -JS::Result BinASTParser::parseAssertedBoundNamesScope( - const FieldContext& context) { - BinASTKind kind = BinASTKind::AssertedBoundNamesScope; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceAssertedBoundNamesScope(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedBoundNamesScope( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto scopeKind = AssertedScopeKind::Catch; - - MOZ_TRY(parseListOfAssertedBoundName( - scopeKind, - FieldContext( - BinASTInterfaceAndField::AssertedBoundNamesScope__BoundNames))); - - BINJS_MOZ_TRY_DECL( - hasDirectEval, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedBoundNamesScope__HasDirectEval))); - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setFunHasExtensibleScope(); - } - auto result = Ok(); - return result; -} - -/* - interface AssertedDeclaredName : Node { - [IdentifierName] string name; - AssertedDeclaredKind kind; - bool isCaptured; - } -*/ -template -JS::Result BinASTParser::parseAssertedDeclaredName( - AssertedScopeKind scopeKind, const ListContext& context) { - BinASTKind kind = BinASTKind::AssertedDeclaredName; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceAssertedDeclaredName(start, scopeKind, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedDeclaredName( - const size_t start, AssertedScopeKind scopeKind, - const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const bool allowDuplicateName = false; - - RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::AssertedDeclaredName__Name))); - - BINJS_MOZ_TRY_DECL(kind_, - parseAssertedDeclaredKind(FieldContext( - BinASTInterfaceAndField::AssertedDeclaredName__Kind))); - if (kind_ == AssertedDeclaredKind::NonConstLexical) { - return raiseError("Let is not supported in this preview release"); - } - if (kind_ == AssertedDeclaredKind::ConstLexical) { - return raiseError("Const is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - isCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedDeclaredName__IsCaptured))); - ParseContext::Scope* scope; - DeclarationKind declKind; - MOZ_TRY(getDeclaredScope(scopeKind, kind_, scope, declKind)); - MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured, - allowDuplicateName)); - auto result = Ok(); - return result; -} - -/* - interface AssertedParameterScope : Node { - FrozenArray paramNames; - bool hasDirectEval; - bool isSimpleParameterList; - } -*/ -template -JS::Result BinASTParser::parseAssertedParameterScope( - MutableHandle> positionalParams, - const FieldContext& context) { - BinASTKind kind = BinASTKind::AssertedParameterScope; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedParameterScope( - start, positionalParams, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedParameterScope( - const size_t start, MutableHandle> positionalParams, - const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto scopeKind = AssertedScopeKind::Parameter; - - MOZ_TRY(parseListOfAssertedMaybePositionalParameterName( - scopeKind, positionalParams, - FieldContext( - BinASTInterfaceAndField::AssertedParameterScope__ParamNames))); - - BINJS_MOZ_TRY_DECL( - hasDirectEval, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedParameterScope__HasDirectEval))); - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - BINJS_MOZ_TRY_DECL(isSimpleParameterList, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField:: - AssertedParameterScope__IsSimpleParameterList))); - (void)isSimpleParameterList; - if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setFunHasExtensibleScope(); - } - auto result = Ok(); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedPositionalParameterName( - const size_t start, AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - bool allowDuplicateName = !pc_->sc()->strict(); - - BINJS_MOZ_TRY_DECL( - index, - tokenizer_->readUnsignedLong(FieldContext( - BinASTInterfaceAndField::AssertedPositionalParameterName__Index))); - - RootedAtom name(cx_); - MOZ_TRY_VAR( - name, - tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::AssertedPositionalParameterName__Name))); - // `positionalParams` vector can be shorter than the actual - // parameter length. Resize on demand. - // (see also ListOfAssertedMaybePositionalParameterName) - size_t prevLength = positionalParams.get().length(); - if (index >= prevLength) { - // This is implementation limit, which is not in the spec. - if (index >= ARGNO_LIMIT - 1) { - return raiseError("AssertedPositionalParameterName.index is too big"); - } - size_t newLength = index + 1; - BINJS_TRY(positionalParams.get().resize(newLength)); - for (uint32_t i = prevLength; i < newLength; i++) { - positionalParams.get()[i] = nullptr; - } - } - - if (positionalParams.get()[index]) { - return raiseError( - "AssertedPositionalParameterName has duplicate entry for the same " - "index"); - } - positionalParams.get()[index] = name; - BINJS_MOZ_TRY_DECL(isCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField:: - AssertedPositionalParameterName__IsCaptured))); - ParseContext::Scope* scope; - DeclarationKind declKind; - MOZ_TRY(getBoundScope(scopeKind, scope, declKind)); - MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured, - allowDuplicateName)); - auto result = Ok(); - return result; -} - -/* - interface AssertedScriptGlobalScope : Node { - FrozenArray declaredNames; - bool hasDirectEval; - } -*/ -template -JS::Result BinASTParser::parseAssertedScriptGlobalScope( - const FieldContext& context) { - BinASTKind kind = BinASTKind::AssertedScriptGlobalScope; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceAssertedScriptGlobalScope(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedScriptGlobalScope( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto scopeKind = AssertedScopeKind::Global; - - MOZ_TRY(parseListOfAssertedDeclaredName( - scopeKind, - FieldContext( - BinASTInterfaceAndField::AssertedScriptGlobalScope__DeclaredNames))); - - BINJS_MOZ_TRY_DECL( - hasDirectEval, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedScriptGlobalScope__HasDirectEval))); - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setFunHasExtensibleScope(); - } - auto result = Ok(); - return result; -} - -/* - interface AssertedVarScope : Node { - FrozenArray declaredNames; - bool hasDirectEval; - } -*/ -template -JS::Result BinASTParser::parseAssertedVarScope( - const FieldContext& context) { - BinASTKind kind = BinASTKind::AssertedVarScope; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedVarScope(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssertedVarScope( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto scopeKind = AssertedScopeKind::Var; - - MOZ_TRY(parseListOfAssertedDeclaredName( - scopeKind, - FieldContext(BinASTInterfaceAndField::AssertedVarScope__DeclaredNames))); - - BINJS_MOZ_TRY_DECL( - hasDirectEval, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::AssertedVarScope__HasDirectEval))); - if (hasDirectEval) { - pc_->sc()->setHasDirectEval(); - pc_->sc()->setBindingsAccessedDynamically(); - } - if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { - // In non-strict mode code, direct calls to eval can - // add variables to the call object. - pc_->functionBox()->setFunHasExtensibleScope(); - } - auto result = Ok(); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAssignmentExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - binding, parseAssignmentTarget(FieldContext( - BinASTInterfaceAndField::AssignmentExpression__Binding))); - - BINJS_MOZ_TRY_DECL( - expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::AssignmentExpression__Expression))); - - BINJS_TRY_DECL(result, handler_.newAssignment(ParseNodeKind::AssignExpr, - binding, expression)); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceAssignmentTargetIdentifier( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom name(cx_); - MOZ_TRY_VAR(name, - tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::AssignmentTargetIdentifier__Name))); - - BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_DECL(result, handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceAwaitExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (AwaitExpression)"); -} - -template -JS::Result BinASTParser::parseInterfaceBinaryExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(operator_, - parseBinaryOperator(FieldContext( - BinASTInterfaceAndField::BinaryExpression__Operator))); - - BINJS_MOZ_TRY_DECL( - left, parseExpression( - FieldContext(BinASTInterfaceAndField::BinaryExpression__Left))); - - BINJS_MOZ_TRY_DECL(right, - parseExpression(FieldContext( - BinASTInterfaceAndField::BinaryExpression__Right))); - - ParseNodeKind pnk; - switch (operator_) { - case BinaryOperator::Comma: - pnk = ParseNodeKind::CommaExpr; - break; - case BinaryOperator::LogicalOr: - pnk = ParseNodeKind::OrExpr; - break; - case BinaryOperator::LogicalAnd: - pnk = ParseNodeKind::AndExpr; - break; - case BinaryOperator::BitOr: - pnk = ParseNodeKind::BitOrExpr; - break; - case BinaryOperator::BitXor: - pnk = ParseNodeKind::BitXorExpr; - break; - case BinaryOperator::BitAnd: - pnk = ParseNodeKind::BitAndExpr; - break; - case BinaryOperator::Eq: - pnk = ParseNodeKind::EqExpr; - break; - case BinaryOperator::Neq: - pnk = ParseNodeKind::NeExpr; - break; - case BinaryOperator::StrictEq: - pnk = ParseNodeKind::StrictEqExpr; - break; - case BinaryOperator::StrictNeq: - pnk = ParseNodeKind::StrictNeExpr; - break; - case BinaryOperator::LessThan: - pnk = ParseNodeKind::LtExpr; - break; - case BinaryOperator::LeqThan: - pnk = ParseNodeKind::LeExpr; - break; - case BinaryOperator::GreaterThan: - pnk = ParseNodeKind::GtExpr; - break; - case BinaryOperator::GeqThan: - pnk = ParseNodeKind::GeExpr; - break; - case BinaryOperator::In: - pnk = ParseNodeKind::InExpr; - break; - case BinaryOperator::Instanceof: - pnk = ParseNodeKind::InstanceOfExpr; - break; - case BinaryOperator::Lsh: - pnk = ParseNodeKind::LshExpr; - break; - case BinaryOperator::Rsh: - pnk = ParseNodeKind::RshExpr; - break; - case BinaryOperator::Ursh: - pnk = ParseNodeKind::UrshExpr; - break; - case BinaryOperator::Plus: - pnk = ParseNodeKind::AddExpr; - break; - case BinaryOperator::Minus: - pnk = ParseNodeKind::SubExpr; - break; - case BinaryOperator::Mul: - pnk = ParseNodeKind::MulExpr; - break; - case BinaryOperator::Div: - pnk = ParseNodeKind::DivExpr; - break; - case BinaryOperator::Mod: - pnk = ParseNodeKind::ModExpr; - break; - case BinaryOperator::Pow: - pnk = ParseNodeKind::PowExpr; - break; - } - - ParseNode* result; - // ParseNodeKind::PowExpr is not left-associative - if (left->isKind(pnk) && pnk != ParseNodeKind::PowExpr) { - // Regroup left-associative operations into lists. - left->template as().appendWithoutOrderAssumption(right); - result = left; - } else { - BINJS_TRY_DECL(list, handler_.newList(pnk, tokenizer_->pos(start))); - - list->appendWithoutOrderAssumption(left); - list->appendWithoutOrderAssumption(right); - result = list; - } - return result; -} - -/* - interface BindingIdentifier : Node { - [IdentifierName] string name; - } -*/ -template -JS::Result BinASTParser::parseBindingIdentifier( - const FieldOrListContext& context) { - BinASTKind kind = BinASTKind::BindingIdentifier; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceBindingIdentifier(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceBindingIdentifier( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::BindingIdentifier__Name))); - - BINJS_TRY_DECL(result, handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceBindingWithInitializer( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(BindingWithInitializer)"); -} - -/* - interface Block : Node { - AssertedBlockScope scope; - FrozenArray statements; - } -*/ -template -JS::Result BinASTParser::parseBlock( - const FieldOrListContext& context) { - BinASTKind kind = BinASTKind::Block; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceBlock(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceBlock( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::Block); - ParseContext::Scope currentScope(cx_, pc_, usedNames_); - BINJS_TRY(currentScope.init(pc_)); - - MOZ_TRY(parseAssertedBlockScope( - FieldContext(BinASTInterfaceAndField::Block__Scope))); - - BINJS_MOZ_TRY_DECL(statements, - parseListOfStatement(FieldContext( - BinASTInterfaceAndField::Block__Statements))); - - MOZ_TRY(checkClosedVars(currentScope)); - BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); - BINJS_TRY_DECL(result, handler_.newLexicalScope(*bindings, statements)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceBreakStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(FieldContext( - BinASTInterfaceAndField::BreakStatement__Label))); - - if (label) { - if (!IsIdentifier(label)) { - return raiseError("Invalid identifier"); - } - } - - auto validity = - pc_->checkBreakStatement(label ? label->asPropertyName() : nullptr); - if (validity.isErr()) { - switch (validity.unwrapErr()) { - case ParseContext::BreakStatementError::ToughBreak: - this->error(JSMSG_TOUGH_BREAK); - return cx_->alreadyReportedError(); - case ParseContext::BreakStatementError::LabelNotFound: - this->error(JSMSG_LABEL_NOT_FOUND); - return cx_->alreadyReportedError(); - } - } - - BINJS_TRY_DECL(result, handler_.newBreakStatement( - label ? label->asPropertyName() : nullptr, - tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceCallExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(callee, - parseExpressionOrSuper(FieldContext( - BinASTInterfaceAndField::CallExpression__Callee))); - - BINJS_MOZ_TRY_DECL(arguments, - parseArguments(FieldContext( - BinASTInterfaceAndField::CallExpression__Arguments))); - - auto op = JSOp::Call; - - // Try to optimize funcall and funapply at the bytecode level - if (PropertyName* prop = handler_.maybeDottedProperty(callee)) { - if (prop == cx_->names().apply) { - op = JSOp::FunApply; - if (pc_->isFunctionBox()) { - pc_->functionBox()->usesApply = true; - } - } else if (prop == cx_->names().call) { - op = JSOp::FunCall; - } - } - - // Check for direct calls to `eval`. - if (handler_.isEvalName(callee, cx_)) { - if (!pc_->varScope().lookupDeclaredNameForAdd(cx_->names().eval) && - !pc_->innermostScope()->lookupDeclaredNameForAdd(cx_->names().eval)) { - // This is a direct call to `eval`. - if (!pc_->sc()->hasDirectEval()) { - return raiseMissingDirectEvalInAssertedScope(); - } - - op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval; - } - } - - BINJS_TRY_DECL(result, handler_.newCall(callee, arguments, op)); - return result; -} - -/* - interface CatchClause : Node { - AssertedBoundNamesScope bindingScope; - Binding binding; - Block body; - } -*/ -template -JS::Result BinASTParser::parseCatchClause( - const FieldContext& context) { - BinASTKind kind = BinASTKind::CatchClause; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceCatchClause(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceCatchClause( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::Catch); - ParseContext::Scope currentScope(cx_, pc_, usedNames_); - BINJS_TRY(currentScope.init(pc_)); - - MOZ_TRY(parseAssertedBoundNamesScope( - FieldContext(BinASTInterfaceAndField::CatchClause__BindingScope))); - - BINJS_MOZ_TRY_DECL(binding, - parseBinding(FieldContext( - BinASTInterfaceAndField::CatchClause__Binding))); - if (!currentScope.lookupDeclaredName( - binding->template as().atom())) { - return raiseError("Missing catch variable in scope"); - } - BINJS_MOZ_TRY_DECL(body, parseBlock(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::CatchClause__Body)))); - - MOZ_TRY(checkClosedVars(currentScope)); - BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); - BINJS_TRY_DECL(result, handler_.newLexicalScope(*bindings, body)); - BINJS_TRY(handler_.setupCatchScope(result, binding, body)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceClassDeclaration( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (ClassDeclaration)"); -} - -template -JS::Result BinASTParser::parseInterfaceClassExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (ClassExpression)"); -} - -template -JS::Result -BinASTParser::parseInterfaceCompoundAssignmentExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - operator_, - parseCompoundAssignmentOperator(FieldContext( - BinASTInterfaceAndField::CompoundAssignmentExpression__Operator))); - - BINJS_MOZ_TRY_DECL( - binding, - parseSimpleAssignmentTarget(FieldContext( - BinASTInterfaceAndField::CompoundAssignmentExpression__Binding))); - - BINJS_MOZ_TRY_DECL( - expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::CompoundAssignmentExpression__Expression))); - - ParseNodeKind pnk; - switch (operator_) { - case CompoundAssignmentOperator::PlusAssign: - pnk = ParseNodeKind::AddAssignExpr; - break; - case CompoundAssignmentOperator::MinusAssign: - pnk = ParseNodeKind::SubAssignExpr; - break; - case CompoundAssignmentOperator::MulAssign: - pnk = ParseNodeKind::MulAssignExpr; - break; - case CompoundAssignmentOperator::DivAssign: - pnk = ParseNodeKind::DivAssignExpr; - break; - case CompoundAssignmentOperator::ModAssign: - pnk = ParseNodeKind::ModAssignExpr; - break; - case CompoundAssignmentOperator::PowAssign: - pnk = ParseNodeKind::PowAssignExpr; - break; - case CompoundAssignmentOperator::LshAssign: - pnk = ParseNodeKind::LshAssignExpr; - break; - case CompoundAssignmentOperator::RshAssign: - pnk = ParseNodeKind::RshAssignExpr; - break; - case CompoundAssignmentOperator::UrshAssign: - pnk = ParseNodeKind::UrshAssignExpr; - break; - case CompoundAssignmentOperator::BitOrAssign: - pnk = ParseNodeKind::BitOrAssignExpr; - break; - case CompoundAssignmentOperator::BitXorAssign: - pnk = ParseNodeKind::BitXorAssignExpr; - break; - case CompoundAssignmentOperator::BitAndAssign: - pnk = ParseNodeKind::BitAndAssignExpr; - break; - } - BINJS_TRY_DECL(result, handler_.newAssignment(pnk, binding, expression)); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceComputedMemberAssignmentTarget( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - object, - parseExpressionOrSuper(FieldContext( - BinASTInterfaceAndField::ComputedMemberAssignmentTarget__Object))); - - BINJS_MOZ_TRY_DECL(expression, - parseExpression(FieldContext( - BinASTInterfaceAndField:: - ComputedMemberAssignmentTarget__Expression))); - - BINJS_TRY_DECL(result, handler_.newPropertyByValue(object, expression, - tokenizer_->offset())); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceComputedMemberExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - object, parseExpressionOrSuper(FieldContext( - BinASTInterfaceAndField::ComputedMemberExpression__Object))); - - BINJS_MOZ_TRY_DECL( - expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::ComputedMemberExpression__Expression))); - - BINJS_TRY_DECL(result, handler_.newPropertyByValue(object, expression, - tokenizer_->offset())); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceComputedPropertyName( - const size_t start, const FieldContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(ComputedPropertyName)"); -} - -template -JS::Result BinASTParser::parseInterfaceConditionalExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - test, parseExpression(FieldContext( - BinASTInterfaceAndField::ConditionalExpression__Test))); - - BINJS_MOZ_TRY_DECL( - consequent, - parseExpression(FieldContext( - BinASTInterfaceAndField::ConditionalExpression__Consequent))); - - BINJS_MOZ_TRY_DECL( - alternate, - parseExpression(FieldContext( - BinASTInterfaceAndField::ConditionalExpression__Alternate))); - - BINJS_TRY_DECL(result, handler_.newConditional(test, consequent, alternate)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceContinueStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(FieldContext( - BinASTInterfaceAndField::ContinueStatement__Label))); - - if (label) { - if (!IsIdentifier(label)) { - return raiseError("ContinueStatement - Label MUST be an identifier"); - } - } - - auto validity = - pc_->checkContinueStatement(label ? label->asPropertyName() : nullptr); - if (validity.isErr()) { - switch (validity.unwrapErr()) { - case ParseContext::ContinueStatementError::NotInALoop: - this->error(JSMSG_BAD_CONTINUE); - return cx_->alreadyReportedError(); - case ParseContext::ContinueStatementError::LabelNotFound: - this->error(JSMSG_LABEL_NOT_FOUND); - return cx_->alreadyReportedError(); - } - } - - BINJS_TRY_DECL(result, handler_.newContinueStatement( - label ? label->asPropertyName() : nullptr, - tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceDataProperty( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(name, parsePropertyName(FieldContext( - BinASTInterfaceAndField::DataProperty__Name))); - - BINJS_MOZ_TRY_DECL(expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::DataProperty__Expression))); - - if (!handler_.isUsableAsObjectPropertyName(name)) { - return raiseError("DataProperty key kind"); - } - - ParseNode* result; - if (name->template is() && - name->template as().atom() == cx_->names().proto) { - BINJS_TRY_VAR(result, handler_.newUnary(ParseNodeKind::MutateProto, start, - expression)); - } else { - BINJS_TRY_VAR(result, handler_.newObjectMethodOrPropertyDefinition( - name, expression, AccessorType::None)); - } - return result; -} - -template -JS::Result BinASTParser::parseInterfaceDebuggerStatement( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (DebuggerStatement)"); -} - -/* - interface Directive : Node { - string rawValue; - } -*/ -template -JS::Result BinASTParser::parseDirective( - const ListContext& context) { - BinASTKind kind = BinASTKind::Directive; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceDirective(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceDirective( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom rawValue(cx_); - MOZ_TRY_VAR(rawValue, tokenizer_->readAtom(FieldContext( - BinASTInterfaceAndField::Directive__RawValue))); - - TokenPos pos = tokenizer_->pos(start); - BINJS_TRY_DECL(result, handler_.newStringLiteral(rawValue, pos)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceDoWhileStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::DoLoop); - - BINJS_MOZ_TRY_DECL( - test, parseExpression( - FieldContext(BinASTInterfaceAndField::DoWhileStatement__Test))); - - BINJS_MOZ_TRY_DECL(body, - parseStatement(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::DoWhileStatement__Body)))); - - BINJS_TRY_DECL( - result, handler_.newDoWhileStatement(body, test, tokenizer_->pos(start))); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceEagerArrowExpressionWithExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(EagerArrowExpressionWithExpression)"); -} - -template -JS::Result -BinASTParser::parseInterfaceEagerArrowExpressionWithFunctionBody( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(EagerArrowExpressionWithFunctionBody)"); -} - -template -JS::Result -BinASTParser::parseInterfaceEagerFunctionDeclaration( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Statement; - - BINJS_MOZ_TRY_DECL( - isAsync, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__IsAsync))); - if (isAsync) { - return raiseError( - "Async function is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - isGenerator, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__IsGenerator))); - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - name, parseBindingIdentifier(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__Name)))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__Length))); - - BINJS_MOZ_TRY_DECL( - directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__Directives))); - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) - ? name - : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - MOZ_TRY(parseFunctionOrMethodContents( - length, ¶ms, &body, - FieldOrRootContext(FieldContext( - BinASTInterfaceAndField::EagerFunctionDeclaration__Contents)))); - MOZ_TRY(prependDirectivesToBody(body, directives)); - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(result, params, bodyScope)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceEagerFunctionExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Expression; - - BINJS_MOZ_TRY_DECL( - isAsync, tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__IsAsync))); - if (isAsync) { - return raiseError( - "Async function is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - isGenerator, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__IsGenerator))); - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - name, parseOptionalBindingIdentifier(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__Name))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__Length))); - - BINJS_MOZ_TRY_DECL( - directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__Directives))); - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) - ? name - : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - MOZ_TRY(parseFunctionExpressionContents( - length, ¶ms, &body, - FieldOrRootContext(FieldContext( - BinASTInterfaceAndField::EagerFunctionExpression__Contents)))); - MOZ_TRY(prependDirectivesToBody(body, directives)); - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(result, params, bodyScope)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceEagerGetter( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Setter; - const bool isGenerator = false; - const bool isAsync = false; - const auto accessorType = AccessorType::Getter; - const uint32_t length = 0; - - BINJS_MOZ_TRY_DECL(name, parsePropertyName(FieldContext( - BinASTInterfaceAndField::EagerGetter__Name))); - - BINJS_MOZ_TRY_DECL(directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::EagerGetter__Directives))); - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) - ? name - : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - MOZ_TRY(parseGetterContents( - length, ¶ms, &body, - FieldContext(BinASTInterfaceAndField::EagerGetter__Contents))); - MOZ_TRY(prependDirectivesToBody(body, directives)); - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(method, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(method, params, bodyScope)); - BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition( - name, method, accessorType)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceEagerMethod( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Method; - const auto accessorType = AccessorType::None; - - BINJS_MOZ_TRY_DECL(isAsync, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerMethod__IsAsync))); - if (isAsync) { - return raiseError( - "Async function is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL(isGenerator, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::EagerMethod__IsGenerator))); - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL(name, parsePropertyName(FieldContext( - BinASTInterfaceAndField::EagerMethod__Name))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong( - FieldContext(BinASTInterfaceAndField::EagerMethod__Length))); - - BINJS_MOZ_TRY_DECL(directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::EagerMethod__Directives))); - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) - ? name - : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - MOZ_TRY(parseFunctionOrMethodContents( - length, ¶ms, &body, - FieldOrRootContext( - FieldContext(BinASTInterfaceAndField::EagerMethod__Contents)))); - MOZ_TRY(prependDirectivesToBody(body, directives)); - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(method, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(method, params, bodyScope)); - BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition( - name, method, accessorType)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceEagerSetter( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Setter; - const bool isGenerator = false; - const bool isAsync = false; - const auto accessorType = AccessorType::Setter; - - BINJS_MOZ_TRY_DECL(name, parsePropertyName(FieldContext( - BinASTInterfaceAndField::EagerSetter__Name))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong( - FieldContext(BinASTInterfaceAndField::EagerSetter__Length))); - - BINJS_MOZ_TRY_DECL(directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::EagerSetter__Directives))); - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, - (syntax != FunctionSyntaxKind::Setter && - syntax != FunctionSyntaxKind::Getter) - ? name - : nullptr)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* body; - MOZ_TRY(parseSetterContents( - length, ¶ms, &body, - FieldContext(BinASTInterfaceAndField::EagerSetter__Contents))); - MOZ_TRY(prependDirectivesToBody(body, directives)); - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body)); - BINJS_MOZ_TRY_DECL(method, makeEmptyFunctionNode(start, syntax, funbox)); - MOZ_TRY(setFunctionParametersAndBody(method, params, bodyScope)); - BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition( - name, method, accessorType)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceEmptyStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_TRY_DECL(result, handler_.newEmptyStatement(tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceExpressionStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::ExpressionStatement__Expression))); - - BINJS_TRY_DECL(result, handler_.newExprStatement(expression)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceForInOfBinding( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - AutoVariableDeclarationKind kindGuard(this); - - BINJS_MOZ_TRY_DECL( - kind_, parseVariableDeclarationKind( - FieldContext(BinASTInterfaceAndField::ForInOfBinding__Kind))); - - BINJS_MOZ_TRY_DECL(binding, - parseBinding(FieldContext( - BinASTInterfaceAndField::ForInOfBinding__Binding))); - - // Restored by `kindGuard`. - variableDeclarationKind_ = kind_; - MOZ_TRY( - checkBinding(binding->template as().atom()->asPropertyName())); - ParseNodeKind pnk; - switch (kind_) { - case VariableDeclarationKind::Var: - pnk = ParseNodeKind::VarStmt; - break; - case VariableDeclarationKind::Let: - return raiseError("Let is not supported in this preview release"); - case VariableDeclarationKind::Const: - return raiseError("Const is not supported in this preview release"); - } - BINJS_TRY_DECL(result, - handler_.newDeclarationList(pnk, tokenizer_->pos(start))); - handler_.addList(result, binding); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceForInStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::ForInLoop); - - // Implicit scope around the `for`, used to store `for (let x in ...)` - // or `for (const x in ...)`-style declarations. Detail on the - // declaration is stored as part of `scope`. - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - - BINJS_MOZ_TRY_DECL(left, parseAssignmentTargetOrForInOfBinding(FieldContext( - BinASTInterfaceAndField::ForInStatement__Left))); - - BINJS_MOZ_TRY_DECL( - right, parseExpression( - FieldContext(BinASTInterfaceAndField::ForInStatement__Right))); - - BINJS_MOZ_TRY_DECL( - body, parseStatement(FieldOrListContext( - FieldContext(BinASTInterfaceAndField::ForInStatement__Body)))); - - BINJS_TRY_DECL(forHead, - handler_.newForInOrOfHead(ParseNodeKind::ForIn, left, right, - tokenizer_->pos(start))); - ParseNode* result; - BINJS_TRY_VAR(result, handler_.newForStatement(start, forHead, body, - /* iflags = */ 0)); - - if (!scope.isEmpty()) { - BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, pc_)); - BINJS_TRY_VAR(result, handler_.newLexicalScope(*bindings, result)); - } - return result; -} - -template -JS::Result BinASTParser::parseInterfaceForOfStatement( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (ForOfStatement)"); -} - -template -JS::Result BinASTParser::parseInterfaceForStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::ForLoop); - - // Implicit scope around the `for`, used to store `for (let x; ...; ...)` - // or `for (const x; ...; ...)`-style declarations. Detail on the - // declaration is stored as part of `BINJS_Scope`. - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - - BINJS_MOZ_TRY_DECL( - init, parseOptionalExpressionOrVariableDeclaration( - FieldContext(BinASTInterfaceAndField::ForStatement__Init))); - - BINJS_MOZ_TRY_DECL(test, parseOptionalExpression(FieldContext( - BinASTInterfaceAndField::ForStatement__Test))); - - BINJS_MOZ_TRY_DECL( - update, parseOptionalExpression( - FieldContext(BinASTInterfaceAndField::ForStatement__Update))); - - BINJS_MOZ_TRY_DECL(body, parseStatement(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::ForStatement__Body)))); - - BINJS_TRY_DECL( - forHead, handler_.newForHead(init, test, update, tokenizer_->pos(start))); - ParseNode* result; - BINJS_TRY_VAR(result, handler_.newForStatement(start, forHead, body, - /* iflags = */ 0)); - - if (!scope.isEmpty()) { - BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, pc_)); - BINJS_TRY_VAR(result, handler_.newLexicalScope(*bindings, result)); - } - return result; -} - -/* - interface FormalParameters : Node { - FrozenArray items; - Binding? rest; - } -*/ -template -JS::Result BinASTParser::parseFormalParameters( - const FieldContext& context) { - BinASTKind kind = BinASTKind::FormalParameters; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceFormalParameters(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceFormalParameters( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(items, - parseListOfParameter(FieldContext( - BinASTInterfaceAndField::FormalParameters__Items))); - - BINJS_MOZ_TRY_DECL( - rest, parseOptionalBinding( - FieldContext(BinASTInterfaceAndField::FormalParameters__Rest))); - - auto result = items; - if (rest) { - return raiseError( - "Rest parameter is not supported in this preview release"); - } - return result; -} - -/* - interface FunctionExpressionContents : Node { - bool isFunctionNameCaptured; - bool isThisCaptured; - AssertedParameterScope parameterScope; - FormalParameters params; - AssertedVarScope bodyScope; - FunctionBody body; - } -*/ -template -JS::Result BinASTParser::parseFunctionExpressionContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldOrRootContext& context) { - BinASTKind kind = BinASTKind::FunctionExpressionContents; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceFunctionExpressionContents( - start, funLength, paramsOut, bodyOut, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceFunctionExpressionContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldOrRootContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - isFunctionNameCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField:: - FunctionExpressionContents__IsFunctionNameCaptured))); - // Per spec, isFunctionNameCaptured can be true for anonymous - // function. Check isFunctionNameCaptured only for named - // function. - if (pc_->functionBox()->isNamedLambda() && isFunctionNameCaptured) { - captureFunctionName(); - } - BINJS_MOZ_TRY_DECL(isThisCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField:: - FunctionExpressionContents__IsThisCaptured))); - // TODO: Use this in BinASTParser::buildFunction. - (void)isThisCaptured; - Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope( - &positionalParams, - FieldContext(BinASTInterfaceAndField:: - FunctionExpressionContents__ParameterScope))); - - BINJS_MOZ_TRY_DECL( - params, - parseFormalParameters(FieldContext( - BinASTInterfaceAndField::FunctionExpressionContents__Params))); - MOZ_TRY(checkFunctionLength(funLength)); - MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope(FieldContext( - BinASTInterfaceAndField::FunctionExpressionContents__BodyScope))); - - BINJS_MOZ_TRY_DECL( - body, parseFunctionBody(FieldContext( - BinASTInterfaceAndField::FunctionExpressionContents__Body))); - - *paramsOut = params; - *bodyOut = body; - auto result = Ok(); - return result; -} - -/* - interface FunctionOrMethodContents : Node { - bool isThisCaptured; - AssertedParameterScope parameterScope; - FormalParameters params; - AssertedVarScope bodyScope; - FunctionBody body; - } -*/ -template -JS::Result BinASTParser::parseFunctionOrMethodContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldOrRootContext& context) { - BinASTKind kind = BinASTKind::FunctionOrMethodContents; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceFunctionOrMethodContents( - start, funLength, paramsOut, bodyOut, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceFunctionOrMethodContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldOrRootContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - isThisCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::FunctionOrMethodContents__IsThisCaptured))); - // TODO: Use this in BinASTParser::buildFunction. - (void)isThisCaptured; - Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope( - &positionalParams, - FieldContext( - BinASTInterfaceAndField::FunctionOrMethodContents__ParameterScope))); - - BINJS_MOZ_TRY_DECL( - params, parseFormalParameters(FieldContext( - BinASTInterfaceAndField::FunctionOrMethodContents__Params))); - MOZ_TRY(checkFunctionLength(funLength)); - MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope(FieldContext( - BinASTInterfaceAndField::FunctionOrMethodContents__BodyScope))); - - BINJS_MOZ_TRY_DECL( - body, parseFunctionBody(FieldContext( - BinASTInterfaceAndField::FunctionOrMethodContents__Body))); - - *paramsOut = params; - *bodyOut = body; - auto result = Ok(); - return result; -} - -/* - interface GetterContents : Node { - bool isThisCaptured; - AssertedVarScope bodyScope; - FunctionBody body; - } -*/ -template -JS::Result BinASTParser::parseGetterContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldContext& context) { - BinASTKind kind = BinASTKind::GetterContents; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceGetterContents(start, funLength, paramsOut, bodyOut, - context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceGetterContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - isThisCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::GetterContents__IsThisCaptured))); - // TODO: Use this in BinASTParser::buildFunction. - (void)isThisCaptured; - MOZ_TRY(parseAssertedVarScope( - FieldContext(BinASTInterfaceAndField::GetterContents__BodyScope))); - - BINJS_TRY_DECL(params, handler_.newParamsBody(tokenizer_->pos(start))); - BINJS_MOZ_TRY_DECL(body, parseFunctionBody(FieldContext( - BinASTInterfaceAndField::GetterContents__Body))); - - *paramsOut = params; - *bodyOut = body; - auto result = Ok(); - return result; -} - -/* - interface IdentifierExpression : Node { - [IdentifierName] string name; - } -*/ -template -JS::Result BinASTParser::parseIdentifierExpression( - const FieldOrListContext& context) { - BinASTKind kind = BinASTKind::IdentifierExpression; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceIdentifierExpression(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceIdentifierExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(FieldContext( - BinASTInterfaceAndField::IdentifierExpression__Name))); - - BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_DECL(result, handler_.newName(name->asPropertyName(), - tokenizer_->pos(start), cx_)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceIfStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(test, parseExpression(FieldContext( - BinASTInterfaceAndField::IfStatement__Test))); - - BINJS_MOZ_TRY_DECL(consequent, - parseStatement(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::IfStatement__Consequent)))); - - BINJS_MOZ_TRY_DECL(alternate, - parseOptionalStatement(FieldContext( - BinASTInterfaceAndField::IfStatement__Alternate))); - - BINJS_TRY_DECL(result, - handler_.newIfStatement(start, test, consequent, alternate)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceLabelledStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readAtom(FieldContext( - BinASTInterfaceAndField::LabelledStatement__Label))); - if (!IsIdentifier(label)) { - return raiseError("Invalid identifier"); - } - ParseContext::LabelStatement stmt(pc_, label); - BINJS_MOZ_TRY_DECL(body, - parseStatement(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::LabelledStatement__Body)))); - - BINJS_TRY_DECL(result, handler_.newLabeledStatement(label->asPropertyName(), - body, start)); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceLazyArrowExpressionWithExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(LazyArrowExpressionWithExpression)"); -} - -template -JS::Result -BinASTParser::parseInterfaceLazyArrowExpressionWithFunctionBody( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(LazyArrowExpressionWithFunctionBody)"); -} - -template -JS::Result BinASTParser::parseInterfaceLazyFunctionDeclaration( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Statement; - - BINJS_MOZ_TRY_DECL( - isAsync, tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__IsAsync))); - if (isAsync) { - return raiseError( - "Async function is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - isGenerator, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__IsGenerator))); - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - name, parseBindingIdentifier(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__Name)))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__Length))); - - BINJS_MOZ_TRY_DECL( - directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__Directives))); - - BINJS_MOZ_TRY_DECL( - contentsSkip, - tokenizer_->readSkippableSubTree(FieldContext( - BinASTInterfaceAndField::LazyFunctionDeclaration__ContentsSkip))); - // Don't parse the contents until we delazify. - - // TODO: This will become incorrect in the face of ES6 features. - uint32_t nargs = length; - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, name)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - - auto skipStart = contentsSkip.startOffset(); - auto skipEnd = skipStart + contentsSkip.length(); - MOZ_TRY(finishLazyFunction(funbox, nargs, skipStart, skipEnd)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceLazyFunctionExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - const auto syntax = FunctionSyntaxKind::Expression; - - BINJS_MOZ_TRY_DECL( - isAsync, tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__IsAsync))); - if (isAsync) { - return raiseError( - "Async function is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - isGenerator, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__IsGenerator))); - if (isGenerator) { - return raiseError("Generator is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - name, parseOptionalBindingIdentifier(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__Name))); - - BINJS_MOZ_TRY_DECL( - length, tokenizer_->readUnsignedLong(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__Length))); - - BINJS_MOZ_TRY_DECL( - directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__Directives))); - - BINJS_MOZ_TRY_DECL( - contentsSkip, - tokenizer_->readSkippableSubTree(FieldContext( - BinASTInterfaceAndField::LazyFunctionExpression__ContentsSkip))); - // Don't parse the contents until we delazify. - - // TODO: This will become incorrect in the face of ES6 features. - uint32_t nargs = length; - - BINJS_MOZ_TRY_DECL(funbox, - buildFunctionBox(isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction, - syntax, name)); - - forceStrictIfNecessary(funbox, directives); - - pc_->sc()->setHasInnerFunctions(); - - BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(start, syntax, funbox)); - - auto skipStart = contentsSkip.startOffset(); - auto skipEnd = skipStart + contentsSkip.length(); - MOZ_TRY(finishLazyFunction(funbox, nargs, skipStart, skipEnd)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceLazyGetter( - const size_t start, const ListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (LazyGetter)"); -} - -template -JS::Result BinASTParser::parseInterfaceLazyMethod( - const size_t start, const ListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (LazyMethod)"); -} - -template -JS::Result BinASTParser::parseInterfaceLazySetter( - const size_t start, const ListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (LazySetter)"); -} - -template -JS::Result -BinASTParser::parseInterfaceLiteralBooleanExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - value, tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::LiteralBooleanExpression__Value))); - - BINJS_TRY_DECL(result, - handler_.newBooleanLiteral(value, tokenizer_->pos(start))); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceLiteralInfinityExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(LiteralInfinityExpression)"); -} - -template -JS::Result BinASTParser::parseInterfaceLiteralNullExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_TRY_DECL(result, handler_.newNullLiteral(tokenizer_->pos(start))); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceLiteralNumericExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - value, tokenizer_->readDouble(FieldContext( - BinASTInterfaceAndField::LiteralNumericExpression__Value))); - - BINJS_TRY_DECL(result, handler_.newNumber(value, DecimalPoint::HasDecimal, - tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceLiteralPropertyName( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom value(cx_); - MOZ_TRY_VAR(value, tokenizer_->readAtom(FieldContext( - BinASTInterfaceAndField::LiteralPropertyName__Value))); - - ParseNode* result; - uint32_t index; - if (value->isIndex(&index)) { - BINJS_TRY_VAR(result, - handler_.newNumber(index, NoDecimal, - TokenPos(start, tokenizer_->offset()))); - } else { - BINJS_TRY_VAR(result, handler_.newObjectLiteralPropertyName( - value, tokenizer_->pos(start))); - } - return result; -} - -template -JS::Result BinASTParser::parseInterfaceLiteralRegExpExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom pattern(cx_); - MOZ_TRY_VAR(pattern, - tokenizer_->readAtom(FieldContext( - BinASTInterfaceAndField::LiteralRegExpExpression__Pattern))); - RegExpFlags reflags = JS::RegExpFlag::NoFlags; - auto flagsContext = - FieldContext(BinASTInterfaceAndField::LiteralRegExpExpression__Flags); - if constexpr (std::is_same_v) { - // Hack: optimized `readChars` is not implemented for - // `BinASTTokenReaderContext`. - RootedAtom flags(cx_); - MOZ_TRY_VAR(flags, tokenizer_->readAtom(flagsContext)); - if (!this->parseRegExpFlags(flags, &reflags)) { - return raiseError("Invalid regexp flags"); - } - } else { - Chars flags(cx_); - MOZ_TRY(tokenizer_->readChars(flags, flagsContext)); - if (!this->parseRegExpFlags(flags, &reflags)) { - return raiseError("Invalid regexp flags"); - } - } - - // Validate the RegExp pattern is valid. - { - JS::CompileOptions dummyOptions(cx_); - DummyTokenStream dummyTokenStream(cx_, dummyOptions); - - LifoAllocScope allocScope(&cx_->tempLifoAlloc()); - BINJS_TRY( - irregexp::CheckPatternSyntax(cx_, dummyTokenStream, pattern, reflags)); - } - - RegExpIndex index(this->getCompilationInfo().regExpData.length()); - BINJS_TRY(this->getCompilationInfo().regExpData.emplaceBack()); - BINJS_TRY( - this->getCompilationInfo().regExpData[index].init(cx_, pattern, reflags)); - - return handler_.newRegExp(index, tokenizer_->pos(start)); -} - -template -JS::Result BinASTParser::parseInterfaceLiteralStringExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - RootedAtom value(cx_); - MOZ_TRY_VAR(value, - tokenizer_->readAtom(FieldContext( - BinASTInterfaceAndField::LiteralStringExpression__Value))); - - BINJS_TRY_DECL(result, - handler_.newStringLiteral(value, tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceModule( - const size_t start, const RootContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (Module)"); -} - -template -JS::Result BinASTParser::parseInterfaceNewExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(callee, - parseExpression(FieldContext( - BinASTInterfaceAndField::NewExpression__Callee))); - - BINJS_MOZ_TRY_DECL(arguments, - parseArguments(FieldContext( - BinASTInterfaceAndField::NewExpression__Arguments))); - - BINJS_TRY_DECL(result, - handler_.newNewExpression(tokenizer_->pos(start).begin, callee, - arguments, /* isSpread = */ false)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceNewTargetExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(NewTargetExpression)"); -} - -template -JS::Result BinASTParser::parseInterfaceObjectAssignmentTarget( - const size_t start, const FieldContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(ObjectAssignmentTarget)"); -} - -template -JS::Result BinASTParser::parseInterfaceObjectBinding( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (ObjectBinding)"); -} - -template -JS::Result BinASTParser::parseInterfaceObjectExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - properties, parseListOfObjectProperty(FieldContext( - BinASTInterfaceAndField::ObjectExpression__Properties))); - - auto result = properties; - return result; -} - -template -JS::Result BinASTParser::parseInterfaceReturnStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - if (!pc_->isFunctionBox()) { - // Return statements are permitted only inside functions. - return raiseInvalidKind("Toplevel Statement", BinASTKind::ReturnStatement); - } - - pc_->functionBox()->usesReturn = true; - - BINJS_MOZ_TRY_DECL( - expression, parseOptionalExpression(FieldContext( - BinASTInterfaceAndField::ReturnStatement__Expression))); - - BINJS_TRY_DECL( - result, handler_.newReturnStatement(expression, tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceScript( - const size_t start, const RootContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - MOZ_TRY(parseAssertedScriptGlobalScope( - FieldContext(BinASTInterfaceAndField::Script__Scope))); - - BINJS_MOZ_TRY_DECL(directives, - parseListOfDirective(FieldContext( - BinASTInterfaceAndField::Script__Directives))); - forceStrictIfNecessary(pc_->sc(), directives); - BINJS_MOZ_TRY_DECL(statements, - parseListOfStatement(FieldContext( - BinASTInterfaceAndField::Script__Statements))); - - MOZ_TRY(checkClosedVars(pc_->varScope())); - MOZ_TRY(prependDirectivesToBody(/* body = */ statements, directives)); - auto result = statements; - return result; -} - -/* - interface SetterContents : Node { - bool isThisCaptured; - AssertedParameterScope parameterScope; - Parameter param; - AssertedVarScope bodyScope; - FunctionBody body; - } -*/ -template -JS::Result BinASTParser::parseSetterContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldContext& context) { - BinASTKind kind = BinASTKind::SetterContents; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceSetterContents(start, funLength, paramsOut, bodyOut, - context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSetterContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - isThisCaptured, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::SetterContents__IsThisCaptured))); - // TODO: Use this in BinASTParser::buildFunction. - (void)isThisCaptured; - Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope( - &positionalParams, - FieldContext(BinASTInterfaceAndField::SetterContents__ParameterScope))); - - BINJS_MOZ_TRY_DECL(param, - parseParameter(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::SetterContents__Param)))); - BINJS_TRY_DECL(params, handler_.newParamsBody(param->pn_pos)); - handler_.addList(params, param); - MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope( - FieldContext(BinASTInterfaceAndField::SetterContents__BodyScope))); - - BINJS_MOZ_TRY_DECL(body, parseFunctionBody(FieldContext( - BinASTInterfaceAndField::SetterContents__Body))); - - *paramsOut = params; - *bodyOut = body; - auto result = Ok(); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceShorthandProperty( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(name, - parseIdentifierExpression(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::ShorthandProperty__Name)))); - - MOZ_ASSERT(name->isKind(ParseNodeKind::Name)); - MOZ_ASSERT(!handler_.isUsableAsObjectPropertyName(name)); - BINJS_TRY_DECL(propName, handler_.newObjectLiteralPropertyName( - name->template as().name(), - tokenizer_->pos(start))); - - BINJS_TRY_DECL(result, - handler_.newShorthandPropertyDefinition(propName, name)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSpreadElement( - const size_t start, const ListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (SpreadElement)"); -} - -template -JS::Result -BinASTParser::parseInterfaceStaticMemberAssignmentTarget( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - size_t nameStart; - - BINJS_MOZ_TRY_DECL( - object, - parseExpressionOrSuper(FieldContext( - BinASTInterfaceAndField::StaticMemberAssignmentTarget__Object))); - - RootedAtom property(cx_); - { - nameStart = tokenizer_->offset(); - MOZ_TRY_VAR( - property, - tokenizer_->readPropertyKey(FieldContext( - BinASTInterfaceAndField::StaticMemberAssignmentTarget__Property))); - } - - BINJS_TRY_DECL(name, handler_.newPropertyName(property->asPropertyName(), - tokenizer_->pos(nameStart))); - BINJS_TRY_DECL(result, handler_.newPropertyAccess(object, name)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceStaticMemberExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - size_t nameStart; - - BINJS_MOZ_TRY_DECL( - object, parseExpressionOrSuper(FieldContext( - BinASTInterfaceAndField::StaticMemberExpression__Object))); - - RootedAtom property(cx_); - { - nameStart = tokenizer_->offset(); - MOZ_TRY_VAR( - property, - tokenizer_->readPropertyKey(FieldContext( - BinASTInterfaceAndField::StaticMemberExpression__Property))); - } - - BINJS_TRY_DECL(name, handler_.newPropertyName(property->asPropertyName(), - tokenizer_->pos(nameStart))); - BINJS_TRY_DECL(result, handler_.newPropertyAccess(object, name)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSuper( - const size_t start, const FieldContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (Super)"); -} - -/* - interface SwitchCase : Node { - Expression test; - FrozenArray consequent; - } -*/ -template -JS::Result BinASTParser::parseSwitchCase( - const ListContext& context) { - BinASTKind kind = BinASTKind::SwitchCase; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchCase(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSwitchCase( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - test, - parseExpression(FieldContext(BinASTInterfaceAndField::SwitchCase__Test))); - - BINJS_MOZ_TRY_DECL(consequent, - parseListOfStatement(FieldContext( - BinASTInterfaceAndField::SwitchCase__Consequent))); - - BINJS_TRY_DECL(result, handler_.newCaseOrDefault(start, test, consequent)); - return result; -} - -/* - interface SwitchDefault : Node { - FrozenArray consequent; - } -*/ -template -JS::Result BinASTParser::parseSwitchDefault( - const FieldContext& context) { - BinASTKind kind = BinASTKind::SwitchDefault; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchDefault(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSwitchDefault( - const size_t start, const FieldContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(consequent, - parseListOfStatement(FieldContext( - BinASTInterfaceAndField::SwitchDefault__Consequent))); - - BINJS_TRY_DECL(result, handler_.newCaseOrDefault(start, nullptr, consequent)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceSwitchStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - discriminant, - parseExpression(FieldContext( - BinASTInterfaceAndField::SwitchStatement__Discriminant))); - ParseContext::Statement stmt(pc_, StatementKind::Switch); - BINJS_MOZ_TRY_DECL(cases, - parseListOfSwitchCase(FieldContext( - BinASTInterfaceAndField::SwitchStatement__Cases))); - - BINJS_TRY_DECL(scope, handler_.newLexicalScope(nullptr, cases)); - BINJS_TRY_DECL(result, handler_.newSwitchStatement(start, discriminant, scope, - /* hasDefault = */ false)); - return result; -} - -template -JS::Result -BinASTParser::parseInterfaceSwitchStatementWithDefault( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - discriminant, - parseExpression(FieldContext( - BinASTInterfaceAndField::SwitchStatementWithDefault__Discriminant))); - ParseContext::Statement stmt(pc_, StatementKind::Switch); - BINJS_MOZ_TRY_DECL(preDefaultCases, - parseListOfSwitchCase(FieldContext( - BinASTInterfaceAndField:: - SwitchStatementWithDefault__PreDefaultCases))); - - BINJS_MOZ_TRY_DECL( - defaultCase, - parseSwitchDefault(FieldContext( - BinASTInterfaceAndField::SwitchStatementWithDefault__DefaultCase))); - - BINJS_MOZ_TRY_DECL(postDefaultCases, - parseListOfSwitchCase(FieldContext( - BinASTInterfaceAndField:: - SwitchStatementWithDefault__PostDefaultCases))); - - // Concatenate `preDefaultCase`, `defaultCase`, `postDefaultCase` - auto cases = preDefaultCases; - handler_.addList(cases, defaultCase); - ParseNode* iter = postDefaultCases->head(); - while (iter) { - ParseNode* next = iter->pn_next; - handler_.addList(cases, iter); - iter = next; - } - BINJS_TRY_DECL(scope, handler_.newLexicalScope(nullptr, cases)); - BINJS_TRY_DECL(result, handler_.newSwitchStatement(start, discriminant, scope, - /* hasDefault = */ true)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceTemplateExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(TemplateExpression)"); -} - -template -JS::Result BinASTParser::parseInterfaceThisExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - if (pc_->isFunctionBox()) { - pc_->functionBox()->usesThis = true; - } - - TokenPos pos = tokenizer_->pos(start); - ParseNode* thisName(nullptr); - if (pc_->sc()->hasFunctionThisBinding()) { - HandlePropertyName dotThis = cx_->names().dotThis; - BINJS_TRY(usedNames_.noteUse(cx_, dotThis, pc_->scriptId(), - pc_->innermostScope()->id())); - BINJS_TRY_VAR(thisName, handler_.newName(dotThis, pos, cx_)); - } - - BINJS_TRY_DECL(result, handler_.newThisLiteral(pos, thisName)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceThrowStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(expression, - parseExpression(FieldContext( - BinASTInterfaceAndField::ThrowStatement__Expression))); - - BINJS_TRY_DECL( - result, handler_.newThrowStatement(expression, tokenizer_->pos(start))); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceTryCatchStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - ParseNode* body; - { - ParseContext::Statement stmt(pc_, StatementKind::Try); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(body, parseBlock(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::TryCatchStatement__Body)))); - } - - BINJS_MOZ_TRY_DECL( - catchClause, - parseCatchClause(FieldContext( - BinASTInterfaceAndField::TryCatchStatement__CatchClause))); - - BINJS_TRY_DECL(result, - handler_.newTryStatement(start, body, catchClause, - /* finallyBlock = */ nullptr)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceTryFinallyStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - ParseNode* body; - { - ParseContext::Statement stmt(pc_, StatementKind::Try); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(body, - parseBlock(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::TryFinallyStatement__Body)))); - } - - BINJS_MOZ_TRY_DECL( - catchClause, - parseOptionalCatchClause(FieldContext( - BinASTInterfaceAndField::TryFinallyStatement__CatchClause))); - - ParseNode* finalizer; - { - ParseContext::Statement stmt(pc_, StatementKind::Finally); - ParseContext::Scope scope(cx_, pc_, usedNames_); - BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(finalizer, - parseBlock(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::TryFinallyStatement__Finalizer)))); - } - - BINJS_TRY_DECL(result, - handler_.newTryStatement(start, body, catchClause, finalizer)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceUnaryExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(operator_, - parseUnaryOperator(FieldContext( - BinASTInterfaceAndField::UnaryExpression__Operator))); - - BINJS_MOZ_TRY_DECL(operand, - parseExpression(FieldContext( - BinASTInterfaceAndField::UnaryExpression__Operand))); - - ParseNodeKind pnk; - switch (operator_) { - case UnaryOperator::Minus: - pnk = ParseNodeKind::NegExpr; - break; - case UnaryOperator::Plus: - pnk = ParseNodeKind::PosExpr; - break; - case UnaryOperator::Not: - pnk = ParseNodeKind::NotExpr; - break; - case UnaryOperator::BitNot: - pnk = ParseNodeKind::BitNotExpr; - break; - case UnaryOperator::Typeof: { - if (operand->isKind(ParseNodeKind::Name)) { - pnk = ParseNodeKind::TypeOfNameExpr; - } else { - pnk = ParseNodeKind::TypeOfExpr; - } - break; - } - case UnaryOperator::Void: - pnk = ParseNodeKind::VoidExpr; - break; - case UnaryOperator::Delete: { - switch (operand->getKind()) { - case ParseNodeKind::Name: - pnk = ParseNodeKind::DeleteNameExpr; - BINJS_TRY(this->strictModeError(JSMSG_DEPRECATED_DELETE_OPERAND)); - pc_->sc()->setBindingsAccessedDynamically(); - break; - case ParseNodeKind::DotExpr: - pnk = ParseNodeKind::DeletePropExpr; - break; - case ParseNodeKind::ElemExpr: - pnk = ParseNodeKind::DeleteElemExpr; - break; - default: - pnk = ParseNodeKind::DeleteExpr; - } - break; - } - } - BINJS_TRY_DECL(result, handler_.newUnary(pnk, start, operand)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceUpdateExpression( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(isPrefix, - tokenizer_->readBool(FieldContext( - BinASTInterfaceAndField::UpdateExpression__IsPrefix))); - - BINJS_MOZ_TRY_DECL(operator_, - parseUpdateOperator(FieldContext( - BinASTInterfaceAndField::UpdateExpression__Operator))); - - BINJS_MOZ_TRY_DECL(operand, - parseSimpleAssignmentTarget(FieldContext( - BinASTInterfaceAndField::UpdateExpression__Operand))); - - ParseNodeKind pnk; - switch (operator_) { - case UpdateOperator::Incr: - pnk = isPrefix ? ParseNodeKind::PreIncrementExpr - : ParseNodeKind::PostIncrementExpr; - break; - case UpdateOperator::Decr: - pnk = isPrefix ? ParseNodeKind::PreDecrementExpr - : ParseNodeKind::PostDecrementExpr; - break; - } - BINJS_TRY_DECL(result, handler_.newUnary(pnk, start, operand)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceVariableDeclaration( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - AutoVariableDeclarationKind kindGuard(this); - - BINJS_MOZ_TRY_DECL(kind_, - parseVariableDeclarationKind(FieldContext( - BinASTInterfaceAndField::VariableDeclaration__Kind))); - // Restored by `kindGuard`. - variableDeclarationKind_ = kind_; - ParseNodeKind declarationListKind; - switch (kind_) { - case VariableDeclarationKind::Var: - declarationListKind = ParseNodeKind::VarStmt; - break; - case VariableDeclarationKind::Let: - return raiseError("Let is not supported in this preview release"); - case VariableDeclarationKind::Const: - return raiseError("Const is not supported in this preview release"); - } - BINJS_MOZ_TRY_DECL( - declarators, - parseListOfVariableDeclarator( - declarationListKind, - FieldContext( - BinASTInterfaceAndField::VariableDeclaration__Declarators))); - - // By specification, the list may not be empty. - if (declarators->empty()) { - return raiseEmpty("VariableDeclaration"); - } - - auto result = declarators; - return result; -} - -/* - interface VariableDeclarator : Node { - Binding binding; - Expression? init; - } -*/ -template -JS::Result BinASTParser::parseVariableDeclarator( - const ListContext& context) { - BinASTKind kind = BinASTKind::VariableDeclarator; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceVariableDeclarator(start, context)); - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseInterfaceVariableDeclarator( - const size_t start, const ListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL( - binding, parseBinding(FieldContext( - BinASTInterfaceAndField::VariableDeclarator__Binding))); - - BINJS_MOZ_TRY_DECL(init, - parseOptionalExpression(FieldContext( - BinASTInterfaceAndField::VariableDeclarator__Init))); - - ParseNode* result; - if (binding->isKind(ParseNodeKind::Name)) { - // `var foo [= bar]`` - NameNode* bindingNameNode = &binding->template as(); - MOZ_TRY(checkBinding(bindingNameNode->atom()->asPropertyName())); - if (init) { - BINJS_TRY_VAR( - result, handler_.finishInitializerAssignment(bindingNameNode, init)); - } else { - result = bindingNameNode; - } - } else { - // `var pattern = bar` - if (!init) { - // Here, `init` is required. - return raiseMissingField("VariableDeclarator (with non-trivial pattern)", - BinASTField::Init); - } - - MOZ_CRASH( - "Unimplemented: AssertedScope check for BindingPattern variable " - "declaration"); - BINJS_TRY_VAR(result, handler_.newAssignment(ParseNodeKind::AssignExpr, - binding, init)); - } - return result; -} - -template -JS::Result BinASTParser::parseInterfaceWhileStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - ParseContext::Statement stmt(pc_, StatementKind::WhileLoop); - - BINJS_MOZ_TRY_DECL(test, parseExpression(FieldContext( - BinASTInterfaceAndField::WhileStatement__Test))); - - BINJS_MOZ_TRY_DECL( - body, parseStatement(FieldOrListContext( - FieldContext(BinASTInterfaceAndField::WhileStatement__Body)))); - - BINJS_TRY_DECL(result, handler_.newWhileStatement(start, test, body)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceWithStatement( - const size_t start, const FieldOrListContext& context) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - BINJS_MOZ_TRY_DECL(object, - parseExpression(FieldContext( - BinASTInterfaceAndField::WithStatement__Object))); - - ParseContext::Statement stmt(pc_, StatementKind::With); - BINJS_MOZ_TRY_DECL(body, parseStatement(FieldOrListContext(FieldContext( - BinASTInterfaceAndField::WithStatement__Body)))); - - pc_->sc()->setBindingsAccessedDynamically(); - BINJS_TRY_DECL(result, handler_.newWithStatement(start, object, body)); - return result; -} - -template -JS::Result BinASTParser::parseInterfaceYieldExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release (YieldExpression)"); -} - -template -JS::Result BinASTParser::parseInterfaceYieldStarExpression( - const size_t start, const FieldOrListContext& context) { - return raiseError( - "FIXME: Not implemented yet in this preview release " - "(YieldStarExpression)"); -} - -// ----- String enums (autogenerated, by lexicographical order) -/* -enum AssertedDeclaredKind { - "var", - "non-const lexical", - "const lexical" -}; -*/ -template -JS::Result::AssertedDeclaredKind> -BinASTParser::parseAssertedDeclaredKind(const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::AssertedDeclaredKindOrVariableDeclarationKindVar: - return AssertedDeclaredKind::Var; - case BinASTVariant::AssertedDeclaredKindNonConstLexical: - return AssertedDeclaredKind::NonConstLexical; - case BinASTVariant::AssertedDeclaredKindConstLexical: - return AssertedDeclaredKind::ConstLexical; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("AssertedDeclaredKind", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -/* -enum BinaryOperator { - ",", - "||", - "&&", - "|", - "^", - "&", - "==", - "!=", - "===", - "!==", - "<", - "<=", - ">", - ">=", - "in", - "instanceof", - "<<", - ">>", - ">>>", - "+", - "-", - "*", - "/", - "%", - "**" -}; -*/ -template -JS::Result::BinaryOperator> -BinASTParser::parseBinaryOperator(const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::BinaryOperatorComma: - return BinaryOperator::Comma; - case BinASTVariant::BinaryOperatorLogicalOr: - return BinaryOperator::LogicalOr; - case BinASTVariant::BinaryOperatorLogicalAnd: - return BinaryOperator::LogicalAnd; - case BinASTVariant::BinaryOperatorBitOr: - return BinaryOperator::BitOr; - case BinASTVariant::BinaryOperatorBitXor: - return BinaryOperator::BitXor; - case BinASTVariant::BinaryOperatorBitAnd: - return BinaryOperator::BitAnd; - case BinASTVariant::BinaryOperatorEq: - return BinaryOperator::Eq; - case BinASTVariant::BinaryOperatorNeq: - return BinaryOperator::Neq; - case BinASTVariant::BinaryOperatorStrictEq: - return BinaryOperator::StrictEq; - case BinASTVariant::BinaryOperatorStrictNeq: - return BinaryOperator::StrictNeq; - case BinASTVariant::BinaryOperatorLessThan: - return BinaryOperator::LessThan; - case BinASTVariant::BinaryOperatorLeqThan: - return BinaryOperator::LeqThan; - case BinASTVariant::BinaryOperatorGreaterThan: - return BinaryOperator::GreaterThan; - case BinASTVariant::BinaryOperatorGeqThan: - return BinaryOperator::GeqThan; - case BinASTVariant::BinaryOperatorIn: - return BinaryOperator::In; - case BinASTVariant::BinaryOperatorInstanceof: - return BinaryOperator::Instanceof; - case BinASTVariant::BinaryOperatorLsh: - return BinaryOperator::Lsh; - case BinASTVariant::BinaryOperatorRsh: - return BinaryOperator::Rsh; - case BinASTVariant::BinaryOperatorUrsh: - return BinaryOperator::Ursh; - case BinASTVariant::BinaryOperatorOrUnaryOperatorPlus: - return BinaryOperator::Plus; - case BinASTVariant::BinaryOperatorOrUnaryOperatorMinus: - return BinaryOperator::Minus; - case BinASTVariant::BinaryOperatorMul: - return BinaryOperator::Mul; - case BinASTVariant::BinaryOperatorDiv: - return BinaryOperator::Div; - case BinASTVariant::BinaryOperatorMod: - return BinaryOperator::Mod; - case BinASTVariant::BinaryOperatorPow: - return BinaryOperator::Pow; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("BinaryOperator", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -/* -enum CompoundAssignmentOperator { - "+=", - "-=", - "*=", - "/=", - "%=", - "**=", - "<<=", - ">>=", - ">>>=", - "|=", - "^=", - "&=" -}; -*/ -template -JS::Result::CompoundAssignmentOperator> -BinASTParser::parseCompoundAssignmentOperator( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::CompoundAssignmentOperatorPlusAssign: - return CompoundAssignmentOperator::PlusAssign; - case BinASTVariant::CompoundAssignmentOperatorMinusAssign: - return CompoundAssignmentOperator::MinusAssign; - case BinASTVariant::CompoundAssignmentOperatorMulAssign: - return CompoundAssignmentOperator::MulAssign; - case BinASTVariant::CompoundAssignmentOperatorDivAssign: - return CompoundAssignmentOperator::DivAssign; - case BinASTVariant::CompoundAssignmentOperatorModAssign: - return CompoundAssignmentOperator::ModAssign; - case BinASTVariant::CompoundAssignmentOperatorPowAssign: - return CompoundAssignmentOperator::PowAssign; - case BinASTVariant::CompoundAssignmentOperatorLshAssign: - return CompoundAssignmentOperator::LshAssign; - case BinASTVariant::CompoundAssignmentOperatorRshAssign: - return CompoundAssignmentOperator::RshAssign; - case BinASTVariant::CompoundAssignmentOperatorUrshAssign: - return CompoundAssignmentOperator::UrshAssign; - case BinASTVariant::CompoundAssignmentOperatorBitOrAssign: - return CompoundAssignmentOperator::BitOrAssign; - case BinASTVariant::CompoundAssignmentOperatorBitXorAssign: - return CompoundAssignmentOperator::BitXorAssign; - case BinASTVariant::CompoundAssignmentOperatorBitAndAssign: - return CompoundAssignmentOperator::BitAndAssign; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("CompoundAssignmentOperator", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -/* -enum UnaryOperator { - "+", - "-", - "!", - "~", - "typeof", - "void", - "delete" -}; -*/ -template -JS::Result::UnaryOperator> -BinASTParser::parseUnaryOperator(const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::BinaryOperatorOrUnaryOperatorPlus: - return UnaryOperator::Plus; - case BinASTVariant::BinaryOperatorOrUnaryOperatorMinus: - return UnaryOperator::Minus; - case BinASTVariant::UnaryOperatorNot: - return UnaryOperator::Not; - case BinASTVariant::UnaryOperatorBitNot: - return UnaryOperator::BitNot; - case BinASTVariant::UnaryOperatorTypeof: - return UnaryOperator::Typeof; - case BinASTVariant::UnaryOperatorVoid: - return UnaryOperator::Void; - case BinASTVariant::UnaryOperatorDelete: - return UnaryOperator::Delete; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("UnaryOperator", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -/* -enum UpdateOperator { - "++", - "--" -}; -*/ -template -JS::Result::UpdateOperator> -BinASTParser::parseUpdateOperator(const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::UpdateOperatorIncr: - return UpdateOperator::Incr; - case BinASTVariant::UpdateOperatorDecr: - return UpdateOperator::Decr; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("UpdateOperator", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -/* -enum VariableDeclarationKind { - "var", - "let", - "const" -}; -*/ -template -JS::Result::VariableDeclarationKind> -BinASTParser::parseVariableDeclarationKind(const FieldContext& context) { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - - switch (variant) { - case BinASTVariant::AssertedDeclaredKindOrVariableDeclarationKindVar: - return VariableDeclarationKind::Var; - case BinASTVariant::VariableDeclarationKindLet: - return VariableDeclarationKind::Let; - case BinASTVariant::VariableDeclarationKindConst: - return VariableDeclarationKind::Const; - default: - if (isInvalidVariantPossible()) { - return raiseInvalidVariant("VariableDeclarationKind", variant); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTVariant should not appear"); - } - } -} - -// ----- Lists (autogenerated, by lexicographical order) - -template -JS::Result BinASTParser::parseArguments( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::Arguments); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newList(ParseNodeKind::Arguments, - tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseExpressionOrSpreadElement(childContext)); - handler_.addList(/* list = */ result, /* kid = */ item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseFunctionBody( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfStatement); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseStatement(FieldOrListContext(childContext))); - handler_.addStatementToList(result, item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfAssertedBoundName( - AssertedScopeKind scopeKind, const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfAssertedBoundName); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - (void)start; - auto result = Ok(); - - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY(parseAssertedBoundName(scopeKind, childContext)); - // Nothing to do here. - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfAssertedDeclaredName( - AssertedScopeKind scopeKind, const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfAssertedDeclaredName); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - (void)start; - auto result = Ok(); - - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY(parseAssertedDeclaredName(scopeKind, childContext)); - // Nothing to do here. - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result -BinASTParser::parseListOfAssertedMaybePositionalParameterName( - AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, - BinASTList::ListOfAssertedMaybePositionalParameterName); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - (void)start; - auto result = Ok(); - // This list contains also destructuring parameters, and the number of - // list items can be greater than the actual parameters, or more than - // ARGNO_LIMIT even if the number of parameters fits into ARGNO_LIMIT. - // Also, the number of parameters can be greater than this list's length - // if one of destructuring parameter is empty. - // - // We resize `positionalParams` vector on demand, to keep the vector - // length match to the known maximum positional parameter index + 1. - - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY(parseAssertedMaybePositionalParameterName( - scopeKind, positionalParams, childContext)); - // Nothing to do here. - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfDirective( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfDirective); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseDirective(childContext)); - handler_.addStatementToList(result, item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfObjectProperty( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfObjectProperty); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newObjectLiteral(start)); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseObjectProperty(childContext)); - if (!item->isConstant()) result->setHasNonConstInitializer(); - result->appendWithoutOrderAssumption(item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result -BinASTParser::parseListOfOptionalExpressionOrSpreadElement( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = ListContext( - context.position_, BinASTList::ListOfOptionalExpressionOrSpreadElement); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newArrayLiteral(start)); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, - parseOptionalExpressionOrSpreadElement(childContext)); - if (item) { - handler_.addArrayElement(result, item); // Infallible. - } else { - BINJS_TRY(handler_.addElision(result, tokenizer_->pos(start))); - } - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfParameter( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfParameter); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newParamsBody(tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseParameter(FieldOrListContext(childContext))); - handler_.addList(/* list = */ result, /* kid = */ item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfStatement( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfStatement); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseStatement(FieldOrListContext(childContext))); - handler_.addStatementToList(result, item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfSwitchCase( - const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfSwitchCase); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseSwitchCase(childContext)); - handler_.addCaseStatementToList(result, item); - } - - MOZ_TRY(guard.done()); - return result; -} - -template -JS::Result BinASTParser::parseListOfVariableDeclarator( - ParseNodeKind declarationListKind, const FieldContext& context) { - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = - ListContext(context.position_, BinASTList::ListOfVariableDeclarator); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext)); - BINJS_TRY_DECL(result, handler_.newDeclarationList(declarationListKind, - tokenizer_->pos(start))); - - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseVariableDeclarator(childContext)); - result->appendWithoutOrderAssumption(item); - } - - MOZ_TRY(guard.done()); - return result; -} - -// ----- Default values (by lexicographical order) -template -JS::Result BinASTParser::parseOptionalBinding( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumBinding(start, kind, context)); - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseOptionalBindingIdentifier( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterOptionalInterface(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else if (!isInvalidKindPossible() || - kind == BinASTKind::BindingIdentifier) { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier( - start, FieldOrListContext(context))); - } else { - if (isInvalidKindPossible()) { - return raiseInvalidKind("BindingIdentifier", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseOptionalCatchClause( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterOptionalInterface(kind, context)); - LexicalScopeNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else if (!isInvalidKindPossible() || kind == BinASTKind::CatchClause) { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseInterfaceCatchClause(start, context)); - } else { - if (isInvalidKindPossible()) { - return raiseInvalidKind("CatchClause", kind); - } else { - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE( - "invalid BinASTKind should not appear"); - } - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseOptionalExpression( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumExpression(start, kind, context)); - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result -BinASTParser::parseOptionalExpressionOrSpreadElement( - const ListContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, - parseSumExpressionOrSpreadElement(start, kind, context)); - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result -BinASTParser::parseOptionalExpressionOrVariableDeclaration( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, - parseSumExpressionOrVariableDeclaration(start, kind, context)); - } - MOZ_TRY(guard.done()); - - return result; -} - -template -JS::Result BinASTParser::parseOptionalStatement( - const FieldContext& context) { - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - ParseNode* result; - if (kind == BinASTKind::_Null) { - result = nullptr; - } else { - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, - parseSumStatement(start, kind, FieldOrListContext(context))); - } - MOZ_TRY(guard.done()); - - return result; -} - -// Force class instantiation. -// This ensures that the symbols are built, without having to export all our -// code (and its baggage of #include and macros) in the header. -template class BinASTParser; -template class BinASTParser; - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTParser.h b/js/src/frontend/BinASTParser.h deleted file mode 100644 index 8796e288f8..0000000000 --- a/js/src/frontend/BinASTParser.h +++ /dev/null @@ -1,491 +0,0 @@ -// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// To generate this file, see the documentation in -// js/src/frontend/binast/README.md. - -#ifndef frontend_BinASTParser_h -#define frontend_BinASTParser_h - -#include "mozilla/Maybe.h" -#include "mozilla/Variant.h" - -#include "frontend/BCEParserHandle.h" -#include "frontend/BinASTParserPerTokenizer.h" -#include "frontend/BinASTToken.h" -#include "frontend/BinASTTokenReaderContext.h" -#include "frontend/BinASTTokenReaderMultipart.h" -#include "frontend/FullParseHandler.h" -#include "frontend/ParseContext.h" -#include "frontend/ParseNode.h" -#include "frontend/SharedContext.h" - -#include "js/CompileOptions.h" -#include "js/GCHashTable.h" -#include "js/GCVector.h" -#include "js/Result.h" - -namespace js { -namespace frontend { - -template -class BinASTParser : public BinASTParserPerTokenizer { - public: - using Base = BinASTParserPerTokenizer; - - using Tokenizer = Tok; - - using AutoList = typename Tokenizer::AutoList; - using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; - using Chars = typename Tokenizer::Chars; - using ListContext = typename BinASTTokenReaderBase::ListContext; - using FieldContext = typename BinASTTokenReaderBase::FieldContext; - using RootContext = typename BinASTTokenReaderBase::RootContext; - using FieldOrRootContext = BinASTTokenReaderBase::FieldOrRootContext; - using FieldOrListContext = BinASTTokenReaderBase::FieldOrListContext; - - public: - // Auto-generated types. - using AssertedDeclaredKind = binast::AssertedDeclaredKind; - using BinaryOperator = binast::BinaryOperator; - using CompoundAssignmentOperator = binast::CompoundAssignmentOperator; - using UnaryOperator = binast::UnaryOperator; - using UpdateOperator = binast::UpdateOperator; - using VariableDeclarationKind = binast::VariableDeclarationKind; - - public: - // BinASTParserPerTokenizer types. - using AssertedScopeKind = typename Base::AssertedScopeKind; - - public: - BinASTParser(JSContext* cx, CompilationInfo& compilationInfo, - const JS::ReadOnlyCompileOptions& options, - Handle lazyScript = nullptr) - : BinASTParserPerTokenizer(cx, compilationInfo, options, - lazyScript) {} - ~BinASTParser() = default; - - protected: - // BinASTParserBase fields. - using Base::cx_; - - using Base::alloc_; - using Base::usedNames_; - - using Base::compilationInfo_; - using Base::handler_; - using Base::pc_; - - protected: - // BinASTParserPerTokenizer types. - using AutoVariableDeclarationKind = - typename Base::AutoVariableDeclarationKind; - - protected: - // BinASTParserPerTokenizer fields. - using Base::tokenizer_; - using Base::variableDeclarationKind_; - - protected: - // BinASTParserPerTokenizer methods. - using Base::raiseEmpty; - using Base::raiseError; - using Base::raiseInvalidClosedVar; - using Base::raiseInvalidKind; - using Base::raiseInvalidVariant; - using Base::raiseMissingDirectEvalInAssertedScope; - using Base::raiseMissingField; - using Base::raiseMissingVariableInAssertedScope; - using Base::raiseOOM; - - using Base::buildFunctionBox; - using Base::finishEagerFunction; - using Base::finishLazyFunction; - using Base::makeEmptyFunctionNode; - using Base::setFunctionParametersAndBody; - - using Base::addScopeName; - using Base::captureFunctionName; - - using Base::checkBinding; - using Base::checkPositionalParameterIndices; - using Base::getBoundScope; - using Base::getDeclaredScope; - - using Base::checkClosedVars; - using Base::checkFunctionLength; - - using Base::prependDirectivesToBody; - - using Base::forceStrictIfNecessary; - - using Base::isInvalidKindPossible; - using Base::isInvalidVariantPossible; - - public: - // ----- Sums of interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr - JS::Result parseAssertedMaybePositionalParameterName( - AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context); - JS::Result parseAssignmentTarget(const FieldContext& context); - JS::Result parseAssignmentTargetOrForInOfBinding( - const FieldContext& context); - JS::Result parseBinding(const FieldContext& context); - JS::Result parseExpression(const FieldContext& context); - JS::Result parseExpressionOrSpreadElement( - const ListContext& context); - JS::Result parseExpressionOrSuper(const FieldContext& context); - JS::Result parseObjectProperty(const ListContext& context); - JS::Result parseParameter(const FieldOrListContext& context); - JS::Result parseProgram(const RootContext& context); - JS::Result parsePropertyName(const FieldContext& context); - JS::Result parseSimpleAssignmentTarget( - const FieldContext& context); - JS::Result parseStatement(const FieldOrListContext& context); - JS::Result parseSumAssertedMaybePositionalParameterName( - const size_t start, const BinASTKind kind, AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context); - JS::Result parseSumAssignmentTarget(const size_t start, - const BinASTKind kind, - const FieldContext& context); - JS::Result parseSumAssignmentTargetOrForInOfBinding( - const size_t start, const BinASTKind kind, const FieldContext& context); - JS::Result parseSumBinding(const size_t start, - const BinASTKind kind, - const FieldContext& context); - JS::Result parseSumExpression(const size_t start, - const BinASTKind kind, - const FieldContext& context); - JS::Result parseSumExpressionOrSpreadElement( - const size_t start, const BinASTKind kind, const ListContext& context); - JS::Result parseSumExpressionOrSuper(const size_t start, - const BinASTKind kind, - const FieldContext& context); - JS::Result parseSumExpressionOrVariableDeclaration( - const size_t start, const BinASTKind kind, const FieldContext& context); - JS::Result parseSumObjectProperty(const size_t start, - const BinASTKind kind, - const ListContext& context); - JS::Result parseSumParameter(const size_t start, - const BinASTKind kind, - const FieldOrListContext& context); - JS::Result parseSumProgram(const size_t start, - const BinASTKind kind, - const RootContext& context); - JS::Result parseSumPropertyName(const size_t start, - const BinASTKind kind, - const FieldContext& context); - JS::Result parseSumSimpleAssignmentTarget( - const size_t start, const BinASTKind kind, const FieldContext& context); - JS::Result parseSumStatement(const size_t start, - const BinASTKind kind, - const FieldOrListContext& context); - - // ----- Interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr - JS::Result parseAssertedBlockScope(const FieldContext& context); - JS::Result parseAssertedBoundName(AssertedScopeKind scopeKind, - const ListContext& context); - JS::Result parseAssertedBoundNamesScope(const FieldContext& context); - JS::Result parseAssertedDeclaredName(AssertedScopeKind scopeKind, - const ListContext& context); - JS::Result parseAssertedParameterScope( - MutableHandle> positionalParams, - const FieldContext& context); - JS::Result parseAssertedScriptGlobalScope(const FieldContext& context); - JS::Result parseAssertedVarScope(const FieldContext& context); - JS::Result parseBindingIdentifier( - const FieldOrListContext& context); - JS::Result parseBlock(const FieldOrListContext& context); - JS::Result parseCatchClause(const FieldContext& context); - JS::Result parseDirective(const ListContext& context); - JS::Result parseFormalParameters(const FieldContext& context); - JS::Result parseFunctionExpressionContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldOrRootContext& context); - JS::Result parseFunctionOrMethodContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, - const FieldOrRootContext& context); - JS::Result parseGetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, - const FieldContext& context); - JS::Result parseIdentifierExpression( - const FieldOrListContext& context); - JS::Result parseSetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, - const FieldContext& context); - JS::Result parseSwitchCase(const ListContext& context); - JS::Result parseSwitchDefault(const FieldContext& context); - JS::Result parseVariableDeclarator(const ListContext& context); - JS::Result parseInterfaceArrayAssignmentTarget( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceArrayBinding( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceArrayExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceAssertedBlockScope(const size_t start, - const FieldContext& context); - JS::Result parseInterfaceAssertedBoundName(const size_t start, - AssertedScopeKind scopeKind, - const ListContext& context); - JS::Result parseInterfaceAssertedBoundNamesScope( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceAssertedDeclaredName(const size_t start, - AssertedScopeKind scopeKind, - const ListContext& context); - JS::Result parseInterfaceAssertedParameterScope( - const size_t start, MutableHandle> positionalParams, - const FieldContext& context); - JS::Result parseInterfaceAssertedPositionalParameterName( - const size_t start, AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const ListContext& context); - JS::Result parseInterfaceAssertedScriptGlobalScope( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceAssertedVarScope(const size_t start, - const FieldContext& context); - JS::Result parseInterfaceAssignmentExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceAssignmentTargetIdentifier( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceAwaitExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceBinaryExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceBindingIdentifier( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceBindingWithInitializer( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceBlock(const size_t start, - const FieldOrListContext& context); - JS::Result parseInterfaceBreakStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceCallExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceCatchClause( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceClassDeclaration( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceClassExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceCompoundAssignmentExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceComputedMemberAssignmentTarget( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceComputedMemberExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceComputedPropertyName( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceConditionalExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceContinueStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceDataProperty(const size_t start, - const ListContext& context); - JS::Result parseInterfaceDebuggerStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceDirective(const size_t start, - const ListContext& context); - JS::Result parseInterfaceDoWhileStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceEagerArrowExpressionWithExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceEagerArrowExpressionWithFunctionBody( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceEagerFunctionDeclaration( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceEagerFunctionExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceEagerGetter(const size_t start, - const ListContext& context); - JS::Result parseInterfaceEagerMethod(const size_t start, - const ListContext& context); - JS::Result parseInterfaceEagerSetter(const size_t start, - const ListContext& context); - JS::Result parseInterfaceEmptyStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceExpressionStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceForInOfBinding( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceForInStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceForOfStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceForStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceFormalParameters( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceFunctionExpressionContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldOrRootContext& context); - JS::Result parseInterfaceFunctionOrMethodContents( - const size_t start, uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut, const FieldOrRootContext& context); - JS::Result parseInterfaceGetterContents(const size_t start, - uint32_t funLength, - ListNode** paramsOut, - ListNode** bodyOut, - const FieldContext& context); - JS::Result parseInterfaceIdentifierExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceIfStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLabelledStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLazyArrowExpressionWithExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLazyArrowExpressionWithFunctionBody( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLazyFunctionDeclaration( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLazyFunctionExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLazyGetter(const size_t start, - const ListContext& context); - JS::Result parseInterfaceLazyMethod(const size_t start, - const ListContext& context); - JS::Result parseInterfaceLazySetter(const size_t start, - const ListContext& context); - JS::Result parseInterfaceLiteralBooleanExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLiteralInfinityExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLiteralNullExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLiteralNumericExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLiteralPropertyName( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceLiteralRegExpExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceLiteralStringExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceModule(const size_t start, - const RootContext& context); - JS::Result parseInterfaceNewExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceNewTargetExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceObjectAssignmentTarget( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceObjectBinding( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceObjectExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceReturnStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceScript(const size_t start, - const RootContext& context); - JS::Result parseInterfaceSetterContents(const size_t start, - uint32_t funLength, - ListNode** paramsOut, - ListNode** bodyOut, - const FieldContext& context); - JS::Result parseInterfaceShorthandProperty( - const size_t start, const ListContext& context); - JS::Result parseInterfaceSpreadElement( - const size_t start, const ListContext& context); - JS::Result parseInterfaceStaticMemberAssignmentTarget( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceStaticMemberExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceSuper(const size_t start, - const FieldContext& context); - JS::Result parseInterfaceSwitchCase(const size_t start, - const ListContext& context); - JS::Result parseInterfaceSwitchDefault( - const size_t start, const FieldContext& context); - JS::Result parseInterfaceSwitchStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceSwitchStatementWithDefault( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceTemplateExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceThisExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceThrowStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceTryCatchStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceTryFinallyStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceUnaryExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceUpdateExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceVariableDeclaration( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceVariableDeclarator( - const size_t start, const ListContext& context); - JS::Result parseInterfaceWhileStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceWithStatement( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceYieldExpression( - const size_t start, const FieldOrListContext& context); - JS::Result parseInterfaceYieldStarExpression( - const size_t start, const FieldOrListContext& context); - - // ----- String enums (by lexicographical order) - JS::Result::AssertedDeclaredKind> - parseAssertedDeclaredKind(const FieldContext& context); - JS::Result::BinaryOperator> parseBinaryOperator( - const FieldContext& context); - JS::Result::CompoundAssignmentOperator> - parseCompoundAssignmentOperator(const FieldContext& context); - JS::Result::UnaryOperator> parseUnaryOperator( - const FieldContext& context); - JS::Result::UpdateOperator> parseUpdateOperator( - const FieldContext& context); - JS::Result::VariableDeclarationKind> - parseVariableDeclarationKind(const FieldContext& context); - - // ----- Lists (by lexicographical order) - JS::Result parseArguments(const FieldContext& context); - JS::Result parseFunctionBody(const FieldContext& context); - JS::Result parseListOfAssertedBoundName(AssertedScopeKind scopeKind, - const FieldContext& context); - JS::Result parseListOfAssertedDeclaredName(AssertedScopeKind scopeKind, - const FieldContext& context); - JS::Result parseListOfAssertedMaybePositionalParameterName( - AssertedScopeKind scopeKind, - MutableHandle> positionalParams, - const FieldContext& context); - JS::Result parseListOfDirective(const FieldContext& context); - JS::Result parseListOfObjectProperty(const FieldContext& context); - JS::Result parseListOfOptionalExpressionOrSpreadElement( - const FieldContext& context); - JS::Result parseListOfParameter(const FieldContext& context); - JS::Result parseListOfStatement(const FieldContext& context); - JS::Result parseListOfSwitchCase(const FieldContext& context); - JS::Result parseListOfVariableDeclarator( - ParseNodeKind declarationListKind, const FieldContext& context); - - // ----- Default values (by lexicographical order) - JS::Result parseOptionalBinding(const FieldContext& context); - JS::Result parseOptionalBindingIdentifier( - const FieldContext& context); - JS::Result parseOptionalCatchClause( - const FieldContext& context); - JS::Result parseOptionalExpression(const FieldContext& context); - JS::Result parseOptionalExpressionOrSpreadElement( - const ListContext& context); - JS::Result parseOptionalExpressionOrVariableDeclaration( - const FieldContext& context); - JS::Result parseOptionalStatement(const FieldContext& context); -}; - -extern template class BinASTParser; -extern template class BinASTParser; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTParser_h diff --git a/js/src/frontend/BinASTParserBase.cpp b/js/src/frontend/BinASTParserBase.cpp deleted file mode 100644 index ff72298fe5..0000000000 --- a/js/src/frontend/BinASTParserBase.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTParserBase.h" - -#include "vm/JSContext-inl.h" - -namespace js::frontend { - -BinASTParserBase::BinASTParserBase(JSContext* cx, - CompilationInfo& compilationInfo) - : ParserSharedBase(cx, compilationInfo, - ParserSharedBase::Kind::BinASTParser) {} - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTParserBase.h b/js/src/frontend/BinASTParserBase.h deleted file mode 100644 index a9db724751..0000000000 --- a/js/src/frontend/BinASTParserBase.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTParserBase_h -#define frontend_BinASTParserBase_h - -#include - -#include "ds/LifoAlloc.h" -#include "frontend/FullParseHandler.h" -#include "frontend/ParseContext.h" -#include "frontend/ParseNode.h" -#include "frontend/Parser.h" -#include "frontend/SharedContext.h" -#include "js/RootingAPI.h" -#include "js/TracingAPI.h" -#include "js/Utility.h" -#include "vm/JSContext.h" -#include "vm/JSScript.h" - -namespace js { -namespace frontend { - -class BinASTParserBase : public ParserSharedBase { - public: - BinASTParserBase(JSContext* cx, CompilationInfo& compilationInfo); - ~BinASTParserBase() = default; - - public: - void trace(JSTracer* trc) override {} -}; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTParserBase_h diff --git a/js/src/frontend/BinASTParserPerTokenizer.cpp b/js/src/frontend/BinASTParserPerTokenizer.cpp deleted file mode 100644 index 54cfbc756a..0000000000 --- a/js/src/frontend/BinASTParserPerTokenizer.cpp +++ /dev/null @@ -1,829 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTParserPerTokenizer.h" - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Casting.h" -#include "mozilla/Maybe.h" -#include "mozilla/Move.h" -#include "mozilla/PodOperations.h" -#include "mozilla/ScopeExit.h" -#include "mozilla/Vector.h" - -#include "frontend/BinAST-macros.h" -#include "frontend/BinASTParser.h" -#include "frontend/BinASTTokenReaderContext.h" -#include "frontend/BinASTTokenReaderMultipart.h" -#include "frontend/FullParseHandler.h" -#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind -#include "frontend/ParseNode.h" -#include "frontend/Parser.h" -#include "frontend/SharedContext.h" - -#include "js/Result.h" -#include "vm/FunctionFlags.h" // js::FunctionFlags -#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind -#include "vm/RegExpObject.h" - -#include "frontend/ParseContext-inl.h" -#include "frontend/SharedContext-inl.h" -#include "vm/JSContext-inl.h" - -// # About compliance with EcmaScript -// -// For the moment, this parser implements ES5. Future versions will be extended -// to ES6 and further on. -// -// By design, it does NOT implement Annex B.3.3. If possible, we would like -// to avoid going down that rabbit hole. -// -// -// # About the AST -// -// At this stage of experimentation, the AST specifications change often. This -// version of the parser attempts to implement -// https://gist.github.com/Yoric/2390f0367515c079172be2526349b294 -// -// -// # About validating the AST -// -// Normally, this implementation validates all properties of the AST *except* -// the order of fields, which is partially constrained by the AST spec (e.g. in -// a block, field `scope` must appear before field `body`, etc.). -// -// -// # About names and scopes -// -// One of the key objectives of the BinAST syntax is to be able to entirely skip -// parsing inner functions until they are needed. With a purely syntactic AST, -// this is generally impossible, as we would need to walk the AST to find -// lexically-bound/var-bound variables, instances of direct eval, etc. -// -// To achieve this, BinAST files contain scope data, as instances of -// `BinJS:Scope` nodes. Rather than walking the AST to assign bindings -// to scopes, we extract data from the `BinJS:Scope` and check it lazily, -// once we actually need to walk the AST. -// -// WARNING: The current implementation DOES NOT perform the check yet. It -// is therefore unsafe. -// -// # About directives -// -// Currently, directives are ignored and treated as regular strings. -// -// They should be treated lazily (whenever we open a subscope), like bindings. - -namespace js::frontend { - -using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr; - -// ------------- Toplevel constructions - -template -BinASTParserPerTokenizer::BinASTParserPerTokenizer( - JSContext* cx, CompilationInfo& compilationInfo, - const JS::ReadOnlyCompileOptions& options, - Handle lazyScript /* = nullptr */) - : BinASTParserBase(cx, compilationInfo), - options_(options), - lazyScript_(cx, lazyScript), - handler_(cx, compilationInfo.allocScope.alloc(), nullptr, - SourceKind::Binary), - variableDeclarationKind_(VariableDeclarationKind::Var) { - MOZ_ASSERT_IF(lazyScript_, lazyScript_->isBinAST()); -} - -template -JS::Result BinASTParserPerTokenizer::parse( - GlobalSharedContext* globalsc, const Vector& data, - BinASTSourceMetadata** metadataPtr) { - return parse(globalsc, data.begin(), data.length(), metadataPtr); -} - -template -JS::Result BinASTParserPerTokenizer::parse( - GlobalSharedContext* globalsc, const uint8_t* start, const size_t length, - BinASTSourceMetadata** metadataPtr) { - auto result = parseAux(globalsc, start, length, metadataPtr); - poison(); // Make sure that the parser is never used again accidentally. - return result; -} - -template -JS::Result BinASTParserPerTokenizer::parseAux( - GlobalSharedContext* globalsc, const uint8_t* start, const size_t length, - BinASTSourceMetadata** metadataPtr) { - MOZ_ASSERT(globalsc); - - tokenizer_.emplace(cx_, this, start, length); - - BinASTParseContext globalpc(cx_, this, globalsc, - /* newDirectives = */ nullptr); - if (MOZ_UNLIKELY(!globalpc.init())) { - return cx_->alreadyReportedError(); - } - - ParseContext::VarScope varScope(cx_, &globalpc, usedNames_); - if (MOZ_UNLIKELY(!varScope.init(&globalpc))) { - return cx_->alreadyReportedError(); - } - - MOZ_TRY(tokenizer_->readHeader()); - - ParseNode* result(nullptr); - const auto topContext = RootContext(); - MOZ_TRY_VAR(result, asFinalParser()->parseProgram(topContext)); - - MOZ_TRY(tokenizer_->readTreeFooter()); - - mozilla::Maybe bindings = - NewGlobalScopeData(cx_, varScope, alloc_, pc_); - if (MOZ_UNLIKELY(!bindings)) { - return cx_->alreadyReportedError(); - } - globalsc->bindings = *bindings; - - if (metadataPtr) { - *metadataPtr = tokenizer_->takeMetadata(); - } - - return result; // Magic conversion to Ok. -} - -template -JS::Result BinASTParserPerTokenizer::parseLazyFunction( - ScriptSource* scriptSource, const size_t firstOffset) { - MOZ_ASSERT(lazyScript_); - MOZ_ASSERT(scriptSource->length() > firstOffset); - - tokenizer_.emplace(cx_, this, scriptSource->binASTSource(), - scriptSource->length()); - - MOZ_TRY(tokenizer_->initFromScriptSource(scriptSource)); - - tokenizer_->seek(firstOffset); - - // For now, only function declarations and function expression are supported. - RootedFunction func(cx_, lazyScript_->function()); - bool isExpr = func->isLambda(); - MOZ_ASSERT(func->kind() == FunctionFlags::FunctionKind::NormalFunction); - - // Poison the tokenizer when we leave to ensure that it's not used again by - // accident. - auto onExit = mozilla::MakeScopeExit([&]() { poison(); }); - - // TODO: This should be actually shared with the auto-generated version. - - auto syntaxKind = - isExpr ? FunctionSyntaxKind::Expression : FunctionSyntaxKind::Statement; - BINJS_MOZ_TRY_DECL( - funbox, buildFunctionBox(lazyScript_->generatorKind(), - lazyScript_->asyncKind(), syntaxKind, nullptr)); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, - // the function. - BinASTParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - BINJS_TRY(funpc.init()); - pc_->functionScope().useAsVarScope(pc_); - MOZ_ASSERT(pc_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, pc_, usedNames_); - BINJS_TRY(lexicalScope.init(pc_)); - ListNode* params; - ListNode* tmpBody; - auto parseFunc = isExpr ? &FinalParser::parseFunctionExpressionContents - : &FinalParser::parseFunctionOrMethodContents; - - // Inject a toplevel context (i.e. no parent) to parse the lazy content. - // In the future, we may move this to a more specific context. - const auto context = FieldOrRootContext(RootContext()); - MOZ_TRY( - (asFinalParser()->*parseFunc)(func->nargs(), ¶ms, &tmpBody, context)); - - uint32_t nargs = params->count(); - - BINJS_TRY_DECL(lexicalScopeData, - NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); - BINJS_TRY_DECL(body, handler_.newLexicalScope(*lexicalScopeData, tmpBody)); - - BINJS_MOZ_TRY_DECL(result, - makeEmptyFunctionNode(firstOffset, syntaxKind, funbox)); - MOZ_TRY(setFunctionParametersAndBody(result, params, body)); - MOZ_TRY(finishEagerFunction(funbox, nargs)); - return result; -} - -template -void BinASTParserPerTokenizer::forceStrictIfNecessary( - SharedContext* sc, ListNode* directives) { - JSAtom* useStrict = cx_->names().useStrict; - - for (const ParseNode* directive : directives->contents()) { - if (directive->as().atom() == useStrict) { - sc->setStrictScript(); - break; - } - } -} - -template -JS::Result BinASTParserPerTokenizer::buildFunctionBox( - GeneratorKind generatorKind, FunctionAsyncKind functionAsyncKind, - FunctionSyntaxKind syntax, ParseNode* name) { - MOZ_ASSERT_IF(!pc_, lazyScript_); - - RootedFunction fun(cx_); - RootedAtom atom(cx_); - FunctionFlags flags; - - // Name might be any of {Identifier,ComputedPropertyName,LiteralPropertyName} - if (name && name->is()) { - atom = name->as().atom(); - } - - if (pc_) { - if (syntax == FunctionSyntaxKind::Statement) { - auto ptr = pc_->varScope().lookupDeclaredName(atom); - if (MOZ_UNLIKELY(!ptr)) { - return raiseError( - "FunctionDeclaration without corresponding AssertedDeclaredName."); - } - - DeclarationKind declaredKind = ptr->value()->kind(); - if (DeclarationKindIsVar(declaredKind)) { - if (MOZ_UNLIKELY(!pc_->atBodyLevel())) { - return raiseError( - "body-level FunctionDeclaration inside non-body-level context."); - } - RedeclareVar(ptr, DeclarationKind::BodyLevelFunction); - } - } - - flags = InitialFunctionFlags(syntax, generatorKind, functionAsyncKind); - } else { - fun = lazyScript_->function(); - - atom = fun->displayAtom(); - flags = fun->flags(); - } - - mozilla::Maybe directives; - if (pc_) { - directives.emplace(pc_); - } else { - directives.emplace(lazyScript_->strict()); - } - - size_t index = this->getCompilationInfo().funcData.length(); - if (!this->getCompilationInfo().functions.emplaceBack(fun)) { - return nullptr; - } - if (!this->getCompilationInfo().funcData.emplaceBack(cx_)) { - return nullptr; - } - - // This extent will be further filled in during parse. - SourceExtent extent; - auto* funbox = alloc_.new_( - cx_, compilationInfo_.traceListHead, extent, getCompilationInfo(), - *directives, generatorKind, functionAsyncKind, atom, flags, index); - if (MOZ_UNLIKELY(!funbox)) { - return raiseOOM(); - } - - compilationInfo_.traceListHead = funbox; - if (pc_) { - funbox->initWithEnclosingParseContext(pc_, flags, syntax); - } else { - frontend::ScopeContext scopeContext(fun->enclosingScope()); - funbox->initFromLazyFunction(fun); - funbox->initWithEnclosingScope(scopeContext, fun->enclosingScope(), flags, - syntax); - } - return funbox; -} - -template -JS::Result BinASTParserPerTokenizer::makeEmptyFunctionNode( - const size_t start, const FunctionSyntaxKind syntaxKind, - FunctionBox* funbox) { - // Lazy script compilation requires basically none of the fields filled out. - TokenPos pos = tokenizer_->pos(start); - - BINJS_TRY_DECL(result, handler_.newFunction(syntaxKind, pos)); - - funbox->setStart(start, 0, pos.begin); - funbox->setEnd(pos.end); - handler_.setFunctionBox(result, funbox); - - return result; -} - -template -JS::Result BinASTParserPerTokenizer::setFunctionParametersAndBody( - FunctionNode* fun, ListNode* params, ParseNode* body) { - params->appendWithoutOrderAssumption(body); - handler_.setFunctionFormalParametersAndBody(fun, params); - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::finishEagerFunction( - FunctionBox* funbox, uint32_t nargs) { - // If this is delazification of a canonical function, the JSFunction object - // already has correct `nargs_`. - if (!lazyScript_ || lazyScript_->function() != funbox->function()) { - funbox->setArgCount(nargs); - } else { - MOZ_ASSERT(funbox->function()->nargs() == nargs); - funbox->setArgCount(nargs); - } - - // BCE will need to generate bytecode for this. - funbox->emitBytecode = true; - - const bool canSkipLazyClosedOverBindings = false; - BINJS_TRY(pc_->declareFunctionArgumentsObject(usedNames_, - canSkipLazyClosedOverBindings)); - BINJS_TRY( - pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)); - - // Check all our bindings after maybe adding function metavars. - MOZ_TRY(checkFunctionClosedVars()); - - BINJS_TRY_DECL(bindings, NewFunctionScopeData(cx_, pc_->functionScope(), - /* hasParameterExprs = */ false, - alloc_, pc_)); - - funbox->functionScopeBindings().set(*bindings); - - // See: JSFunction::needsCallObject() - if (FunctionScopeHasClosedOverBindings(pc_) || - funbox->needsCallObjectRegardlessOfBindings()) { - funbox->setNeedsFunctionEnvironmentObjects(); - } - - if (funbox->isNamedLambda()) { - BINJS_TRY_DECL( - recursiveBinding, - NewLexicalScopeData(cx_, pc_->namedLambdaScope(), alloc_, pc_)); - - funbox->namedLambdaBindings().set(*recursiveBinding); - - // See: JSFunction::needsNamedLambdaEnvironment() - if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) { - funbox->setNeedsFunctionEnvironmentObjects(); - } - } - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::finishLazyFunction( - FunctionBox* funbox, uint32_t nargs, size_t start, size_t end) { - funbox->setArgCount(nargs); - - ScriptStencil& stencil = funbox->functionStencil().get(); - - // Compute the flags for the BaseScript. - using ImmutableFlags = ImmutableScriptFlagsEnum; - stencil.immutableFlags = funbox->immutableFlags(); - stencil.immutableFlags.setFlag(ImmutableFlags::HasMappedArgsObj, - funbox->hasMappedArgsObj()); - stencil.immutableFlags.setFlag(ImmutableFlags::IsLikelyConstructorWrapper, - funbox->isLikelyConstructorWrapper()); - - funbox->extent = SourceExtent(start, end, start, end, - /* lineno = */ 0, start); - - MOZ_TRY(tokenizer_->registerLazyScript(funbox)); - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::addScopeName( - AssertedScopeKind scopeKind, HandleAtom name, ParseContext::Scope* scope, - DeclarationKind declKind, bool isCaptured, bool allowDuplicateName) { - auto ptr = scope->lookupDeclaredNameForAdd(name); - if (ptr) { - if (allowDuplicateName) { - return Ok(); - } - return raiseError("Variable redeclaration"); - } - - BINJS_TRY(scope->addDeclaredName(pc_, ptr, name.get(), declKind, - tokenizer_->offset())); - - if (isCaptured) { - auto declaredPtr = scope->lookupDeclaredName(name); - MOZ_ASSERT(declaredPtr); - declaredPtr->value()->setClosedOver(); - } - - return Ok(); -} - -template -void BinASTParserPerTokenizer::captureFunctionName() { - MOZ_ASSERT(pc_->isFunctionBox()); - MOZ_ASSERT(pc_->functionBox()->isNamedLambda()); - - RootedAtom funName(cx_, pc_->functionBox()->explicitName()); - MOZ_ASSERT(funName); - - auto ptr = pc_->namedLambdaScope().lookupDeclaredName(funName); - MOZ_ASSERT(ptr); - ptr->value()->setClosedOver(); -} - -template -JS::Result BinASTParserPerTokenizer::getDeclaredScope( - AssertedScopeKind scopeKind, AssertedDeclaredKind kind, - ParseContext::Scope*& scope, DeclarationKind& declKind) { - MOZ_ASSERT(scopeKind == AssertedScopeKind::Block || - scopeKind == AssertedScopeKind::Global || - scopeKind == AssertedScopeKind::Var); - switch (kind) { - case AssertedDeclaredKind::Var: - if (MOZ_UNLIKELY(scopeKind == AssertedScopeKind::Block)) { - return raiseError("AssertedBlockScope cannot contain 'var' binding"); - } - declKind = DeclarationKind::Var; - scope = &pc_->varScope(); - break; - case AssertedDeclaredKind::NonConstLexical: - declKind = DeclarationKind::Let; - scope = pc_->innermostScope(); - break; - case AssertedDeclaredKind::ConstLexical: - declKind = DeclarationKind::Const; - scope = pc_->innermostScope(); - break; - } - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::getBoundScope( - AssertedScopeKind scopeKind, ParseContext::Scope*& scope, - DeclarationKind& declKind) { - MOZ_ASSERT(scopeKind == AssertedScopeKind::Catch || - scopeKind == AssertedScopeKind::Parameter); - switch (scopeKind) { - case AssertedScopeKind::Catch: - declKind = DeclarationKind::CatchParameter; - scope = pc_->innermostScope(); - break; - case AssertedScopeKind::Parameter: - MOZ_ASSERT(pc_->isFunctionBox()); - declKind = DeclarationKind::PositionalFormalParameter; - scope = &pc_->functionScope(); - break; - default: - MOZ_ASSERT_UNREACHABLE("Unexpected AssertedScopeKind"); - break; - } - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::checkBinding(JSAtom* name) { - // Check that the variable appears in the corresponding scope. - ParseContext::Scope& scope = - variableDeclarationKind_ == VariableDeclarationKind::Var - ? pc_->varScope() - : *pc_->innermostScope(); - - auto ptr = scope.lookupDeclaredName(name->asPropertyName()); - if (MOZ_UNLIKELY(!ptr)) { - return raiseMissingVariableInAssertedScope(name); - } - - return Ok(); -} - -// Binary AST (revision 8eab67e0c434929a66ff6abe99ff790bca087dda) -// 3.1.5 CheckPositionalParameterIndices. -template -JS::Result BinASTParserPerTokenizer::checkPositionalParameterIndices( - Handle> positionalParams, ListNode* params) { - // positionalParams should have the corresponding entry up to the last - // positional parameter. - - // `positionalParams` corresponds to `expectedParams` parameter in the spec. - // `params` corresponds to `parseTree` in 3.1.9 CheckAssertedScope, and - // `positionalParamNames` parameter - - // Steps 1-3. - // PositionalParameterNames (3.1.9 CheckAssertedScope step 5.d) and - // CreatePositionalParameterIndices (3.1.5 CheckPositionalParameterIndices - // step 1) are done implicitly. - uint32_t i = 0; - const bool hasRest = pc_->functionBox()->hasRest(); - for (ParseNode* param : params->contents()) { - if (param->isKind(ParseNodeKind::AssignExpr)) { - param = param->as().left(); - } - - // At this point, function body is not part of params list. - const bool isRest = hasRest && !param->pn_next; - if (isRest) { - // Rest parameter - - // Step 3. - if (i >= positionalParams.get().length()) { - continue; - } - - if (MOZ_UNLIKELY(positionalParams.get()[i])) { - return raiseError( - "Expected positional parameter per " - "AssertedParameterScope.paramNames, got rest parameter"); - } - } else if (param->isKind(ParseNodeKind::Name)) { - // Simple or default parameter. - - // Step 2.a. - if (MOZ_UNLIKELY(i >= positionalParams.get().length())) { - return raiseError( - "AssertedParameterScope.paramNames doesn't have corresponding " - "entry to positional parameter"); - } - - JSAtom* name = positionalParams.get()[i]; - if (MOZ_UNLIKELY(!name)) { - // Step 2.a.ii.1. - return raiseError( - "Expected destructuring/rest parameter per " - "AssertedParameterScope.paramNames, got positional parameter"); - } - - // Step 2.a.i. - if (MOZ_UNLIKELY(param->as().name() != name)) { - // Step 2.a.ii.1. - return raiseError( - "Name mismatch between AssertedPositionalParameterName in " - "AssertedParameterScope.paramNames and actual parameter"); - } - - // Step 2.a.i.1. - // Implicitly done. - } else { - // Destructuring parameter. - - MOZ_ASSERT(param->isKind(ParseNodeKind::ObjectExpr) || - param->isKind(ParseNodeKind::ArrayExpr)); - - // Step 3. - if (i >= positionalParams.get().length()) { - continue; - } - - if (MOZ_UNLIKELY(positionalParams.get()[i])) { - return raiseError( - "Expected positional parameter per " - "AssertedParameterScope.paramNames, got destructuring parameter"); - } - } - - i++; - } - - // Step 3. - if (MOZ_UNLIKELY(positionalParams.get().length() > params->count())) { - // `positionalParams` has unchecked entries. - return raiseError( - "AssertedParameterScope.paramNames has unmatching items than the " - "actual parameters"); - } - - return Ok(); -} - -// Binary AST (revision 8eab67e0c434929a66ff6abe99ff790bca087dda) -// 3.1.13 CheckFunctionLength. -template -JS::Result BinASTParserPerTokenizer::checkFunctionLength( - uint32_t expectedLength) { - if (MOZ_UNLIKELY(pc_->functionBox()->length != expectedLength)) { - return raiseError("Function length does't match"); - } - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::checkClosedVars( - ParseContext::Scope& scope) { - for (ParseContext::Scope::BindingIter bi = scope.bindings(pc_); bi; bi++) { - if (UsedNamePtr p = usedNames_.lookup(bi.name())) { - bool closedOver; - p->value().noteBoundInScope(pc_->scriptId(), scope.id(), &closedOver); - if (MOZ_UNLIKELY(closedOver && !bi.closedOver())) { - return raiseInvalidClosedVar(bi.name()); - } - } - } - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::checkFunctionClosedVars() { - MOZ_ASSERT(pc_->isFunctionBox()); - - MOZ_TRY(checkClosedVars(*pc_->innermostScope())); - MOZ_TRY(checkClosedVars(pc_->functionScope())); - if (pc_->functionBox()->isNamedLambda()) { - MOZ_TRY(checkClosedVars(pc_->namedLambdaScope())); - } - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::prependDirectivesToBody( - ListNode* body, ListNode* directives) { - if (!directives) { - return Ok(); - } - - if (directives->empty()) { - return Ok(); - } - - MOZ_TRY(prependDirectivesImpl(body, directives->head())); - - return Ok(); -} - -template -JS::Result BinASTParserPerTokenizer::prependDirectivesImpl( - ListNode* body, ParseNode* directive) { - BINJS_TRY(CheckRecursionLimit(cx_)); - - // Prepend in the reverse order by using stack, so that the directives are - // prepended in the original order. - if (ParseNode* next = directive->pn_next) { - MOZ_TRY(prependDirectivesImpl(body, next)); - } - - BINJS_TRY_DECL(statement, - handler_.newExprStatement(directive, directive->pn_pos.end)); - body->prependAndUpdatePos(statement); - - return Ok(); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseInvalidClosedVar(JSAtom* name) { - return raiseError("Captured variable was not declared as captured"); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseMissingVariableInAssertedScope( - JSAtom* name) { - // For the moment, we don't trust inputs sufficiently to put the name - // in an error message. - return raiseError("Missing variable in AssertedScope"); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseMissingDirectEvalInAssertedScope() { - return raiseError("Direct call to `eval` was not declared in AssertedScope"); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseInvalidKind(const char* superKind, - const BinASTKind kind) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, invalid kind %s", superKind, - describeBinASTKind(kind))); - return raiseError(out.string()); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseInvalidVariant(const char* kind, - const BinASTVariant value) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, invalid variant '%s'", kind, - describeBinASTVariant(value))); - - return raiseError(out.string()); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseMissingField(const char* kind, - const BinASTField field) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, missing field '%s'", kind, - describeBinASTField(field))); - - return raiseError(out.string()); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseEmpty(const char* description) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("Empty %s", description)); - - return raiseError(out.string()); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseOOM() { - return tokenizer_->raiseOOM(); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseError(BinASTKind kind, - const char* description) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, %s", describeBinASTKind(kind), description)); - return tokenizer_->raiseError(out.string()); -} - -template -mozilla::GenericErrorResult -BinASTParserPerTokenizer::raiseError(const char* description) { - return tokenizer_->raiseError(description); -} - -template -void BinASTParserPerTokenizer::poison() { - tokenizer_.reset(); -} - -template -bool BinASTParserPerTokenizer::computeErrorMetadata( - ErrorMetadata* err, const ErrorOffset& errorOffset) { - err->filename = getFilename(); - err->lineNumber = 0; - if (errorOffset.is()) { - err->columnNumber = errorOffset.as(); - } else if (errorOffset.is()) { - err->columnNumber = offset(); - } else { - errorOffset.is(); - err->columnNumber = 0; - } - - err->isMuted = options().mutedErrors(); - return true; -} - -template -void BinASTParserPerTokenizer::trace(JSTracer* trc) { - BinASTParserBase::trace(trc); - if (tokenizer_) { - tokenizer_->traceMetadata(trc); - } -} - -template -inline typename BinASTParserPerTokenizer::FinalParser* -BinASTParserPerTokenizer::asFinalParser() { - // Same as GeneralParser::asFinalParser, verify the inheritance to - // make sure the static downcast works. - static_assert(std::is_base_of_v, FinalParser>, - "inheritance relationship required by the static_cast<> below"); - - return static_cast(this); -} - -template -inline const typename BinASTParserPerTokenizer::FinalParser* -BinASTParserPerTokenizer::asFinalParser() const { - static_assert(std::is_base_of_v, FinalParser>, - "inheritance relationship required by the static_cast<> below"); - - return static_cast(this); -} - -// Force class instantiation. -// This ensures that the symbols are built, without having to export all our -// code (and its baggage of #include and macros) in the header. -template class BinASTParserPerTokenizer; -template class BinASTParserPerTokenizer; - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTParserPerTokenizer.h b/js/src/frontend/BinASTParserPerTokenizer.h deleted file mode 100644 index 1c46d091ac..0000000000 --- a/js/src/frontend/BinASTParserPerTokenizer.h +++ /dev/null @@ -1,365 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTParserPerTokenizer_h -#define frontend_BinASTParserPerTokenizer_h - -/** - * A Binary AST parser. - * - * At the time of this writing, this parser implements the grammar of ES5 - * and trusts its input (in particular, variable declarations). - */ - -#include "mozilla/Maybe.h" - -#include - -#include "frontend/BCEParserHandle.h" -#include "frontend/BinASTEnum.h" -#include "frontend/BinASTParserBase.h" -#include "frontend/BinASTToken.h" -#include "frontend/BinASTTokenReaderContext.h" -#include "frontend/BinASTTokenReaderMultipart.h" -#include "frontend/FullParseHandler.h" -#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind -#include "frontend/ParseContext.h" -#include "frontend/ParseNode.h" -#include "frontend/SharedContext.h" -#include "js/CompileOptions.h" -#include "js/GCHashTable.h" -#include "js/GCVector.h" -#include "js/Result.h" -#include "vm/ErrorReporting.h" -#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind - -namespace js { -namespace frontend { - -template -class BinASTParser; - -/** - * The parser for a Binary AST. - * - * By design, this parser never needs to backtrack or look ahead. Errors are not - * recoverable. - */ -template -class BinASTParserPerTokenizer : public BinASTParserBase, - public ErrorReporter, - public BCEParserHandle { - public: - using Tokenizer = Tok; - - using AutoList = typename Tokenizer::AutoList; - using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; - using Chars = typename Tokenizer::Chars; - using RootContext = BinASTTokenReaderBase::RootContext; - using FieldOrRootContext = BinASTTokenReaderBase::FieldOrRootContext; - - public: - // Auto-generated types. - using AssertedDeclaredKind = binast::AssertedDeclaredKind; - using VariableDeclarationKind = binast::VariableDeclarationKind; - - public: - BinASTParserPerTokenizer(JSContext* cx, CompilationInfo& compilationInfo, - const JS::ReadOnlyCompileOptions& options, - Handle lazyScript = nullptr); - - /** - * Parse a buffer, returning a node (which may be nullptr) in case of success - * or Nothing() in case of error. - * - * The instance of `ParseNode` MAY NOT survive the - * `BinASTParserPerTokenizer`. Indeed, destruction of the - * `BinASTParserPerTokenizer` will also destroy the `ParseNode`. - * - * In case of error, the parser reports the JS error. - */ - JS::Result parse(GlobalSharedContext* globalsc, - const uint8_t* start, const size_t length, - BinASTSourceMetadata** metadataPtr = nullptr); - JS::Result parse(GlobalSharedContext* globalsc, - const Vector& data, - BinASTSourceMetadata** metadataPtr = nullptr); - - JS::Result parseLazyFunction(ScriptSource* scriptSource, - const size_t firstOffset); - - protected: - MOZ_MUST_USE JS::Result parseAux( - GlobalSharedContext* globalsc, const uint8_t* start, const size_t length, - BinASTSourceMetadata** metadataPtr = nullptr); - - // --- Raise errors. - // - // These methods return a (failed) JS::Result for convenience. - - MOZ_MUST_USE mozilla::GenericErrorResult raiseInvalidClosedVar( - JSAtom* name); - MOZ_MUST_USE mozilla::GenericErrorResult - raiseMissingVariableInAssertedScope(JSAtom* name); - MOZ_MUST_USE mozilla::GenericErrorResult - raiseMissingDirectEvalInAssertedScope(); - MOZ_MUST_USE mozilla::GenericErrorResult raiseInvalidKind( - const char* superKind, const BinASTKind kind); - MOZ_MUST_USE mozilla::GenericErrorResult raiseInvalidVariant( - const char* kind, const BinASTVariant value); - MOZ_MUST_USE mozilla::GenericErrorResult raiseMissingField( - const char* kind, const BinASTField field); - MOZ_MUST_USE mozilla::GenericErrorResult raiseEmpty( - const char* description); - MOZ_MUST_USE mozilla::GenericErrorResult raiseOOM(); - MOZ_MUST_USE mozilla::GenericErrorResult raiseError( - const char* description); - MOZ_MUST_USE mozilla::GenericErrorResult raiseError( - BinASTKind kind, const char* description); - - // Ensure that this parser will never be used again. - void poison(); - - // The owner or the target of Asserted*Scope. - enum class AssertedScopeKind { - Block, - Catch, - Global, - Parameter, - Var, - }; - - // --- Auxiliary parsing functions - - // Build a function object for a function-producing production. Called AFTER - // creating the scope. - JS::Result buildFunctionBox(GeneratorKind generatorKind, - FunctionAsyncKind functionAsyncKind, - FunctionSyntaxKind syntax, - ParseNode* name); - - JS::Result makeEmptyFunctionNode( - const size_t start, const FunctionSyntaxKind syntaxKind, - FunctionBox* funbox); - MOZ_MUST_USE JS::Result setFunctionParametersAndBody(FunctionNode* fun, - ListNode* params, - ParseNode* body); - - MOZ_MUST_USE JS::Result finishEagerFunction(FunctionBox* funbox, - uint32_t nargs); - MOZ_MUST_USE JS::Result finishLazyFunction(FunctionBox* funbox, - uint32_t nargs, size_t start, - size_t end); - - // Add name to a given scope. - MOZ_MUST_USE JS::Result addScopeName( - AssertedScopeKind scopeKind, HandleAtom name, ParseContext::Scope* scope, - DeclarationKind declKind, bool isCaptured, bool allowDuplicateName); - - void captureFunctionName(); - - // Map AssertedScopeKind and AssertedDeclaredKind for single binding to - // corresponding ParseContext::Scope to store the binding, and - // DeclarationKind for the binding. - MOZ_MUST_USE JS::Result getDeclaredScope(AssertedScopeKind scopeKind, - AssertedDeclaredKind kind, - ParseContext::Scope*& scope, - DeclarationKind& declKind); - MOZ_MUST_USE JS::Result getBoundScope(AssertedScopeKind scopeKind, - ParseContext::Scope*& scope, - DeclarationKind& declKind); - - MOZ_MUST_USE JS::Result checkBinding(JSAtom* name); - - MOZ_MUST_USE JS::Result checkPositionalParameterIndices( - Handle> positionalParams, ListNode* params); - - MOZ_MUST_USE JS::Result checkFunctionLength(uint32_t expectedLength); - - // When leaving a scope, check that none of its bindings are known closed over - // and un-marked. - MOZ_MUST_USE JS::Result checkClosedVars(ParseContext::Scope& scope); - - // As a convenience, a helper that checks the body, parameter, and recursive - // binding scopes. - MOZ_MUST_USE JS::Result checkFunctionClosedVars(); - - // --- Utilities. - - MOZ_MUST_USE JS::Result prependDirectivesToBody(ListNode* body, - ListNode* directives); - - MOZ_MUST_USE JS::Result prependDirectivesImpl(ListNode* body, - ParseNode* directive); - - // Optionally force a strict context without restarting the parse when we see - // a strict directive. - void forceStrictIfNecessary(SharedContext* sc, ListNode* directives); - - // Whether invalid BinASTKind/BinASTVariant can be encoded in the file. - // This is used to avoid generating unnecessary branches for more - // optimized format. - static constexpr bool isInvalidKindPossible() { - return std::is_same_v; - } - static constexpr bool isInvalidVariantPossible() { - return std::is_same_v; - } - - protected: - // Implement ErrorReportMixin. - const JS::ReadOnlyCompileOptions& options_; - - const JS::ReadOnlyCompileOptions& options() const override { - return this->options_; - } - - JSContext* getContext() const override { return cx_; }; - - MOZ_MUST_USE bool strictMode() const override { return pc_->sc()->strict(); } - - MOZ_MUST_USE bool computeErrorMetadata(ErrorMetadata* err, - const ErrorOffset& offset) override; - - private: - void trace(JSTracer* trc) final; - - public: - virtual ErrorReporter& errorReporter() override { return *this; } - virtual const ErrorReporter& errorReporter() const override { return *this; } - - virtual FullParseHandler& astGenerator() override { return handler_; } - - public: - // Implement ErrorReporter. - - virtual void lineAndColumnAt(size_t offset, uint32_t* line, - uint32_t* column) const override { - *line = lineAt(offset); - *column = columnAt(offset); - } - virtual uint32_t lineAt(size_t offset) const override { return 0; } - virtual uint32_t columnAt(size_t offset) const override { return offset; } - - virtual bool isOnThisLine(size_t offset, uint32_t lineNum, - bool* isOnSameLine) const override { - if (lineNum != 0) { - return false; - } - *isOnSameLine = true; - return true; - } - - virtual void currentLineAndColumn(uint32_t* line, - uint32_t* column) const override { - *line = 0; - *column = offset(); - } - size_t offset() const { - if (tokenizer_.isSome()) { - return tokenizer_->offset(); - } - - return 0; - } - virtual bool hasTokenizationStarted() const override { - return tokenizer_.isSome(); - } - virtual const char* getFilename() const override { - return this->options_.filename(); - } - - protected: - Rooted lazyScript_; - FullParseHandler handler_; - - mozilla::Maybe tokenizer_; - VariableDeclarationKind variableDeclarationKind_; - - friend class BinASTParseContext; - friend class AutoVariableDeclarationKind; - - // Helper class: Restore field `variableDeclarationKind` upon leaving a scope. - class MOZ_RAII AutoVariableDeclarationKind { - public: - explicit AutoVariableDeclarationKind( - BinASTParserPerTokenizer* parser MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : parser_(parser), kind(parser->variableDeclarationKind_) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoVariableDeclarationKind() { parser_->variableDeclarationKind_ = kind; } - - private: - BinASTParserPerTokenizer* parser_; - BinASTParserPerTokenizer::VariableDeclarationKind kind; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - }; - - template - bool parseRegExpFlags(CharsT flags, size_t length, JS::RegExpFlags* reflags) { - MOZ_ASSERT(*reflags == JS::RegExpFlag::NoFlags); - for (size_t i = 0; i < length; i++) { - auto c = flags[i]; - if (c == 'g' && !reflags->global()) { - *reflags |= JS::RegExpFlag::Global; - } else if (c == 'i' && !reflags->ignoreCase()) { - *reflags |= JS::RegExpFlag::IgnoreCase; - } else if (c == 'm' && !reflags->multiline()) { - *reflags |= JS::RegExpFlag::Multiline; - } else if (c == 's' && !reflags->dotAll()) { - *reflags |= JS::RegExpFlag::DotAll; - } else if (c == 'u' && !reflags->unicode()) { - *reflags |= JS::RegExpFlag::Unicode; - } else if (c == 'y' && !reflags->sticky()) { - *reflags |= JS::RegExpFlag::Sticky; - } else { - return false; - } - } - - return true; - } - - bool parseRegExpFlags(Chars flags, JS::RegExpFlags* reflags) { - return parseRegExpFlags(flags.begin(), flags.end() - flags.begin(), - reflags); - } - - bool parseRegExpFlags(HandleAtom flags, JS::RegExpFlags* reflags) { - JS::AutoCheckCannotGC nogc; - if (flags->hasLatin1Chars()) { - return parseRegExpFlags(flags->latin1Chars(nogc), flags->length(), - reflags); - } - return parseRegExpFlags(flags->twoByteChars(nogc), flags->length(), - reflags); - } - - private: - // Some methods in this class require access to auto-generated methods in - // BinASTParser which derives this class. - // asFinalParser methods provide the access to BinASTParser class methods - // of this instance. - using FinalParser = BinASTParser; - - inline FinalParser* asFinalParser(); - inline const FinalParser* asFinalParser() const; -}; - -class BinASTParseContext : public ParseContext { - public: - template - BinASTParseContext(JSContext* cx, BinASTParserPerTokenizer* parser, - SharedContext* sc, Directives* newDirectives) - : ParseContext(cx, parser->pc_, sc, *parser, parser->getCompilationInfo(), - newDirectives, /* isFull = */ true) {} -}; - -extern template class BinASTParserPerTokenizer; -extern template class BinASTParserPerTokenizer; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTParserPerTokenizer_h diff --git a/js/src/frontend/BinASTRuntimeSupport.cpp b/js/src/frontend/BinASTRuntimeSupport.cpp deleted file mode 100644 index 059dff0e46..0000000000 --- a/js/src/frontend/BinASTRuntimeSupport.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTRuntimeSupport.h" - -#include // uint32_t - -#include "gc/Tracer.h" // TraceManuallyBarrieredEdge -#include "js/Utility.h" // js_malloc -#include "vm/StringType.h" // JSAtom - -namespace js::frontend { - -BinASTSourceMetadata::~BinASTSourceMetadata() { - if (isMultipart()) { - this->asMultipart()->release(); - } else { - this->asContext()->release(); - } -} - -void BinASTSourceMetadata::trace(JSTracer* tracer) { - if (isMultipart()) { - this->asMultipart()->trace(tracer); - } else { - this->asContext()->trace(tracer); - } -} - -/* static */ -BinASTSourceMetadataMultipart* BinASTSourceMetadataMultipart::create( - const Vector& binASTKinds, uint32_t numStrings) { - uint32_t numBinASTKinds = binASTKinds.length(); - - // Given we can perform GC before filling all `JSAtom*` items - // in the payload, use js_calloc to initialize them with nullptr. - BinASTSourceMetadataMultipart* data = - static_cast( - js_calloc(BinASTSourceMetadataMultipart::totalSize(numBinASTKinds, - numStrings))); - if (MOZ_UNLIKELY(!data)) { - return nullptr; - } - - new (data) BinASTSourceMetadataMultipart(numBinASTKinds, numStrings); - memcpy(data->binASTKindBase(), binASTKinds.begin(), - binASTKinds.length() * sizeof(BinASTKind)); - - return data; -} - -/* static */ -BinASTSourceMetadataMultipart* BinASTSourceMetadataMultipart::create( - uint32_t numBinASTKinds, uint32_t numStrings) { - // Given we can perform GC before filling all `JSAtom*` items - // in the payload, use js_calloc to initialize them with nullptr. - BinASTSourceMetadataMultipart* data = - static_cast( - js_calloc(BinASTSourceMetadataMultipart::totalSize(numBinASTKinds, - numStrings))); - if (MOZ_UNLIKELY(!data)) { - return nullptr; - } - - new (data) BinASTSourceMetadataMultipart(numBinASTKinds, numStrings); - - return data; -} - -void BinASTSourceMetadataMultipart::trace(JSTracer* tracer) { - JSAtom** base = atomsBase(); - for (uint32_t i = 0; i < numStrings_; i++) { - if (base[i]) { - TraceManuallyBarrieredEdge(tracer, &base[i], "BinAST Strings"); - } - } -} - -BinASTSourceMetadataContext* BinASTSourceMetadataContext::create( - uint32_t numStrings) { - // Given we can perform GC before filling all `JSAtom*` items - // in the payload, use js_calloc to initialize them with nullptr. - BinASTSourceMetadataContext* data = static_cast( - js_calloc(BinASTSourceMetadataContext::totalSize(numStrings))); - if (MOZ_UNLIKELY(!data)) { - return nullptr; - } - - new (data) BinASTSourceMetadataContext(numStrings); - - return data; -} - -void BinASTSourceMetadataContext::trace(JSTracer* tracer) { - JSAtom** base = atomsBase(); - for (uint32_t i = 0; i < numStrings_; i++) { - if (base[i]) { - TraceManuallyBarrieredEdge(tracer, &base[i], "BinAST Strings"); - } - } -} - -void BinASTSourceMetadataContext::release() { - if (dictionary_) { - js_free(dictionary_); - dictionary_ = nullptr; - } -} - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTRuntimeSupport.h b/js/src/frontend/BinASTRuntimeSupport.h deleted file mode 100644 index 8e15c89f52..0000000000 --- a/js/src/frontend/BinASTRuntimeSupport.h +++ /dev/null @@ -1,283 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTSupport_h -#define frontend_BinASTSupport_h - -#include "mozilla/Assertions.h" // MOZ_ASSERT -#include "mozilla/HashFunctions.h" // mozilla::HashString -#include "mozilla/Likely.h" // MOZ_UNLIKELY - -#include // uint8_t, uint32_t -#include // strncmp - -#include "frontend/BinASTToken.h" // BinASTVariant, BinASTField, BinASTKind -#include "gc/DeletePolicy.h" // GCManagedDeletePolicy - -#include "js/AllocPolicy.h" // SystemAllocPolicy -#include "js/HashTable.h" // HashMap, HashNumber -#include "js/Result.h" // JS::Result -#include "js/TracingAPI.h" // JSTracer -#include "js/UniquePtr.h" // UniquePtr -#include "js/Vector.h" // Vector - -class JS_PUBLIC_API JSAtom; -struct JS_PUBLIC_API JSContext; - -namespace js { - -class ScriptSource; - -// Support for parsing JS Binary ASTs. -struct BinaryASTSupport { - using BinASTVariant = js::frontend::BinASTVariant; - using BinASTField = js::frontend::BinASTField; - using BinASTKind = js::frontend::BinASTKind; - - // A structure designed to perform fast char* + length lookup - // without copies. - struct CharSlice { - const char* start_; - uint32_t byteLen_; - CharSlice(const CharSlice& other) = default; - CharSlice(const char* start, const uint32_t byteLen) - : start_(start), byteLen_(byteLen) {} - explicit CharSlice(JSContext*) : CharSlice(nullptr, 0) {} - const char* begin() const { return start_; } - const char* end() const { return start_ + byteLen_; } -#ifdef DEBUG - void dump() const { - for (auto c : *this) { - fprintf(stderr, "%c", c); - } - - fprintf(stderr, " (%u)", byteLen_); - } -#endif // DEBUG - - using Lookup = const CharSlice; - static js::HashNumber hash(Lookup l) { - return mozilla::HashString(l.start_, l.byteLen_); - } - static bool match(const Lookup key, Lookup lookup) { - if (key.byteLen_ != lookup.byteLen_) { - return false; - } - return strncmp(key.start_, lookup.start_, key.byteLen_) == 0; - } - }; - - BinaryASTSupport(); - - JS::Result binASTVariant(JSContext*, const CharSlice); - JS::Result binASTKind(JSContext*, const CharSlice); - - bool ensureBinTablesInitialized(JSContext*); - - private: - bool ensureBinASTKindsInitialized(JSContext*); - bool ensureBinASTVariantsInitialized(JSContext*); - - private: - // A HashMap that can be queried without copies from a CharSlice key. - // Initialized on first call. Keys are CharSlices into static strings. - using BinASTKindMap = js::HashMap; - BinASTKindMap binASTKindMap_; - - using BinASTFieldMap = js::HashMap; - BinASTFieldMap binASTFieldMap_; - - using BinASTVariantMap = js::HashMap; - BinASTVariantMap binASTVariantMap_; -}; - -namespace frontend { - -class BinASTSourceMetadataMultipart; -class BinASTSourceMetadataContext; - -class BinASTSourceMetadata { - public: - enum class Type : uint8_t { - Multipart = 0, - Context = 1, - }; - - private: - Type type_; - - public: - BinASTSourceMetadata() = delete; - explicit BinASTSourceMetadata(Type type) : type_(type) {} -#ifdef JS_BUILD_BINAST - ~BinASTSourceMetadata(); -#else - // If JS_BUILD_BINAST isn't defined, BinASTRuntimeSupport.cpp isn't built, - // but still the destructor is referred from ScriptSource::BinAST. - ~BinASTSourceMetadata() {} -#endif // JS_BUILD_BINAST - - Type type() const { return type_; } - - void setType(Type type) { type_ = type; } - - bool isMultipart() const { return type_ == Type::Multipart; } - bool isContext() const { return type_ == Type::Context; } - - inline BinASTSourceMetadataMultipart* asMultipart(); - inline BinASTSourceMetadataContext* asContext(); - - void trace(JSTracer* tracer); -}; - -class alignas(uintptr_t) BinASTSourceMetadataMultipart - : public BinASTSourceMetadata { - using CharSlice = BinaryASTSupport::CharSlice; - - const uint32_t numStrings_; - const uint32_t numBinASTKinds_; - - // The data lives inline in the allocation, after this class. - inline JSAtom** atomsBase() { - return reinterpret_cast(reinterpret_cast(this + 1)); - } - inline CharSlice* sliceBase() { - return reinterpret_cast( - reinterpret_cast(atomsBase()) + - numStrings_ * sizeof(JSAtom*)); - } - inline BinASTKind* binASTKindBase() { - return reinterpret_cast( - reinterpret_cast(sliceBase()) + - numStrings_ * sizeof(CharSlice)); - } - - static inline size_t totalSize(uint32_t numBinASTKinds, uint32_t numStrings) { - return sizeof(BinASTSourceMetadataMultipart) + - numStrings * sizeof(JSAtom*) + numStrings * sizeof(CharSlice) + - numBinASTKinds * sizeof(BinASTKind); - } - - BinASTSourceMetadataMultipart(uint32_t numBinASTKinds, uint32_t numStrings) - : BinASTSourceMetadata(Type::Multipart), - numStrings_(numStrings), - numBinASTKinds_(numBinASTKinds) {} - - void release() {} - - friend class BinASTSourceMetadata; - - friend class js::ScriptSource; - - public: - // Create the BinASTSourceMetadataMultipart instance, with copying - // `binASTKinds`, and allocating `numStrings` atoms/slices. - // - // Use this when the list of BinASTKind is known at the point of allocating - // metadata, like when parsing .binjs file. - static BinASTSourceMetadataMultipart* create( - const Vector& binASTKinds, uint32_t numStrings); - - // Create the BinASTSourceMetadataMultipart instance, with allocating - // `numBinASTKinds` BinASTKinds and `numStrings` atoms/slices. - // - // Use this when the list of BinASTKind is unknown at the point of allocating - // metadata, like when performing XDR decode. - static BinASTSourceMetadataMultipart* create(uint32_t numBinASTKinds, - uint32_t numStrings); - - inline uint32_t numBinASTKinds() { return numBinASTKinds_; } - - inline uint32_t numStrings() { return numStrings_; } - - inline BinASTKind& getBinASTKind(uint32_t index) { - MOZ_ASSERT(index < numBinASTKinds_); - return binASTKindBase()[index]; - } - - inline CharSlice& getSlice(uint32_t index) { - MOZ_ASSERT(index < numStrings_); - return sliceBase()[index]; - } - - inline JSAtom*& getAtom(uint32_t index) { - MOZ_ASSERT(index < numStrings_); - return atomsBase()[index]; - } - - void trace(JSTracer* tracer); -}; - -class HuffmanDictionaryForMetadata; - -class alignas(uintptr_t) BinASTSourceMetadataContext - : public BinASTSourceMetadata { - const uint32_t numStrings_; - HuffmanDictionaryForMetadata* dictionary_; - - // The data lives inline in the allocation, after this class. - inline JSAtom** atomsBase() { - return reinterpret_cast(reinterpret_cast(this + 1)); - } - - static inline size_t totalSize(uint32_t numStrings) { - return sizeof(BinASTSourceMetadataContext) + numStrings * sizeof(JSAtom*); - } - - explicit BinASTSourceMetadataContext(uint32_t numStrings) - : BinASTSourceMetadata(Type::Context), - numStrings_(numStrings), - dictionary_(nullptr) {} - - void release(); - - friend class BinASTSourceMetadata; - - friend class js::ScriptSource; - - public: - // Create the BinASTSourceMetadataContext instance, with allocating - // `numStrings` atoms. - static BinASTSourceMetadataContext* create(uint32_t numStrings); - - HuffmanDictionaryForMetadata* dictionary() { return dictionary_; } - void setDictionary(HuffmanDictionaryForMetadata* dictionary) { - MOZ_ASSERT(!dictionary_); - MOZ_ASSERT(dictionary); - - dictionary_ = dictionary; - } - - inline uint32_t numStrings() { return numStrings_; } - - inline JSAtom*& getAtom(uint32_t index) { - MOZ_ASSERT(index < numStrings_); - return atomsBase()[index]; - } - - void trace(JSTracer* tracer); -}; - -BinASTSourceMetadataMultipart* BinASTSourceMetadata::asMultipart() { - MOZ_ASSERT(isMultipart()); - return reinterpret_cast(this); -} - -BinASTSourceMetadataContext* BinASTSourceMetadata::asContext() { - MOZ_ASSERT(isContext()); - return reinterpret_cast(this); -} - -} // namespace frontend - -using UniqueBinASTSourceMetadataPtr = - UniquePtr>; - -} // namespace js - -#endif // frontend_BinASTSupport_h diff --git a/js/src/frontend/BinASTToken.cpp b/js/src/frontend/BinASTToken.cpp deleted file mode 100644 index 0c17ceed27..0000000000 --- a/js/src/frontend/BinASTToken.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTToken.h" - -#include "mozilla/Maybe.h" - -#include - -#include "frontend/BinASTRuntimeSupport.h" -#include "frontend/TokenStream.h" -#include "js/Result.h" -#include "vm/JSContext.h" - -namespace js { -namespace frontend { - -const BinaryASTSupport::CharSlice BINASTKIND_DESCRIPTIONS[] = { -#define WITH_VARIANT(_, SPEC_NAME, _2) \ - BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1), - FOR_EACH_BIN_KIND(WITH_VARIANT) -#undef WITH_VARIANT -}; - -const BinaryASTSupport::CharSlice BINASTFIELD_DESCRIPTIONS[] = { -#define WITH_VARIANT(_, SPEC_NAME) \ - BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1), - FOR_EACH_BIN_FIELD(WITH_VARIANT) -#undef WITH_VARIANT -}; - -const BinaryASTSupport::CharSlice BINASTVARIANT_DESCRIPTIONS[] = { -#define WITH_VARIANT(_, SPEC_NAME) \ - BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1), - FOR_EACH_BIN_VARIANT(WITH_VARIANT) -#undef WITH_VARIANT -}; - -const BinaryASTSupport::CharSlice BINASTLIST_DESCRIPTIONS[] = { -#define NOTHING(_) -#define EMIT_NAME(_list_name, _content, SPEC_NAME, _type_name) \ - BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1), - FOR_EACH_BIN_LIST(EMIT_NAME, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, - NOTHING, NOTHING, NOTHING) -#undef EMIT_NAME -#undef NOTHING -}; - -const BinaryASTSupport::CharSlice BINASTINTERFACEANDFIELD_DESCRIPTIONS[] = { -#define WITH_VARIANT(_, SPEC_NAME) \ - BinaryASTSupport::CharSlice(SPEC_NAME, sizeof(SPEC_NAME) - 1), - FOR_EACH_BIN_INTERFACE_AND_FIELD(WITH_VARIANT) -#undef WITH_VARIANT -}; - -const BinaryASTSupport::CharSlice& getBinASTKind(const BinASTKind& variant) { - return BINASTKIND_DESCRIPTIONS[static_cast(variant)]; -} - -const BinaryASTSupport::CharSlice& getBinASTVariant( - const BinASTVariant& variant) { - return BINASTVARIANT_DESCRIPTIONS[static_cast(variant)]; -} - -const BinaryASTSupport::CharSlice& getBinASTField(const BinASTField& variant) { - return BINASTFIELD_DESCRIPTIONS[static_cast(variant)]; -} - -const BinaryASTSupport::CharSlice& getBinASTList(const BinASTList& list) { - return BINASTLIST_DESCRIPTIONS[static_cast(list)]; -} - -const BinaryASTSupport::CharSlice& getBinASTInterfaceAndField( - const BinASTInterfaceAndField& interfaceAndField) { - return BINASTINTERFACEANDFIELD_DESCRIPTIONS[static_cast( - interfaceAndField)]; -} - -const char* describeBinASTKind(const BinASTKind& kind) { - return getBinASTKind(kind).begin(); -} - -const char* describeBinASTField(const BinASTField& field) { - return getBinASTField(field).begin(); -} - -const char* describeBinASTVariant(const BinASTVariant& variant) { - return getBinASTVariant(variant).begin(); -} - -const char* describeBinASTList(const BinASTList& list) { - return getBinASTList(list).begin(); -} - -const char* describeBinASTInterfaceAndField( - const BinASTInterfaceAndField& interfaceAndField) { - return getBinASTInterfaceAndField(interfaceAndField).begin(); -} - -size_t getBinASTKindSortKey(const BinASTKind& kind) { - return static_cast(kind); -} - -size_t getBinASTVariantSortKey(const BinASTVariant& variant) { - return static_cast(variant); -} - -} // namespace frontend - -BinaryASTSupport::BinaryASTSupport() - : binASTKindMap_(frontend::BINASTKIND_LIMIT), - binASTFieldMap_(frontend::BINASTFIELD_LIMIT), - binASTVariantMap_(frontend::BINASTVARIANT_LIMIT) {} - -/** - * It is expected that all bin tables are initialized on the main thread, and - * that any helper threads will find the read-only tables properly initialized, - * so that they can do their accesses safely without taking any locks. - */ -bool BinaryASTSupport::ensureBinTablesInitialized(JSContext* cx) { - return ensureBinASTKindsInitialized(cx) && - ensureBinASTVariantsInitialized(cx); -} - -bool BinaryASTSupport::ensureBinASTKindsInitialized(JSContext* cx) { - MOZ_ASSERT(!cx->isHelperThreadContext()); - if (binASTKindMap_.empty()) { - for (size_t i = 0; i < frontend::BINASTKIND_LIMIT; ++i) { - const BinASTKind variant = static_cast(i); - const CharSlice& key = getBinASTKind(variant); - auto ptr = binASTKindMap_.lookupForAdd(key); - MOZ_ASSERT(!ptr); - if (MOZ_UNLIKELY(!binASTKindMap_.add(ptr, key, variant))) { - ReportOutOfMemory(cx); - return false; - } - } - } - - return true; -} - -bool BinaryASTSupport::ensureBinASTVariantsInitialized(JSContext* cx) { - MOZ_ASSERT(!cx->isHelperThreadContext()); - if (binASTVariantMap_.empty()) { - for (size_t i = 0; i < frontend::BINASTVARIANT_LIMIT; ++i) { - const BinASTVariant variant = static_cast(i); - const CharSlice& key = getBinASTVariant(variant); - auto ptr = binASTVariantMap_.lookupForAdd(key); - MOZ_ASSERT(!ptr); - if (MOZ_UNLIKELY(!binASTVariantMap_.add(ptr, key, variant))) { - ReportOutOfMemory(cx); - return false; - } - } - } - return true; -} - -JS::Result BinaryASTSupport::binASTKind( - JSContext* cx, const CharSlice key) { - MOZ_ASSERT_IF(cx->isHelperThreadContext(), !binASTKindMap_.empty()); - if (!cx->isHelperThreadContext()) { - // Initialize Lazily if on main thread. - if (MOZ_UNLIKELY(!ensureBinASTKindsInitialized(cx))) { - return cx->alreadyReportedError(); - } - } - - auto ptr = binASTKindMap_.readonlyThreadsafeLookup(key); - if (!ptr) { - return nullptr; - } - - return &ptr->value(); -} - -JS::Result BinaryASTSupport::binASTVariant( - JSContext* cx, const CharSlice key) { - MOZ_ASSERT_IF(cx->isHelperThreadContext(), !binASTVariantMap_.empty()); - if (!cx->isHelperThreadContext()) { - // Initialize lazily if on main thread. - if (MOZ_UNLIKELY(!ensureBinASTVariantsInitialized(cx))) { - return cx->alreadyReportedError(); - } - } - - auto ptr = binASTVariantMap_.readonlyThreadsafeLookup(key); - if (!ptr) { - return nullptr; - } - - return &ptr->value(); -} - -} // namespace js diff --git a/js/src/frontend/BinASTToken.h b/js/src/frontend/BinASTToken.h deleted file mode 100644 index 3e21ea851f..0000000000 --- a/js/src/frontend/BinASTToken.h +++ /dev/null @@ -1,3869 +0,0 @@ -// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// To generate this file, see the documentation in -// js/src/frontend/binast/README.md. - -#ifndef frontend_BinASTToken_h -#define frontend_BinASTToken_h - -#include - -#include "jstypes.h" - -/** - * Definition of Binary AST tokens. - * - * In the Binary AST world, an AST is composed of nodes, where a node is - * defined by: - * - a Kind (see `BinASTKind`); - * - a list of fields, where each field is: - * - a Name (see `BinASTField`); - * - a Value, which may be either a node or a primitive value. - * - * The mapping between Kind and list of fields is determined entirely by - * the grammar of Binary AST. The mapping between (Kind, Name) and the - * structure of Value is also determined entirely by the grammar of - * Binary AST. - * - * As per the specifications of Binary AST, kinds may be added as the - * language grows, but never removed. The mapping between Kind and list - * of fields may also change to add new fields or make some fields optional, - * but may never remove a field. Finally, the mapping between (Kind, Name) - * and the structure of Value may be modified to add new possible values, - * but never to remove a value. - * - * A Binary AST parser must be able to fail gracefully when confronted with - * unknown Kinds or Names. - */ - -namespace js { -namespace frontend { - -/** - * The different kinds of Binary AST nodes, as per the specifications of - * Binary AST. - * - * These kinds match roughly with the `ParseNodeKind` used internally. - * - * Usage: - * - * ```c++ - * #define WITH_KIND(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_KIND(WITH_KIND) - * ``` - * - * - * (sorted by alphabetical order) - */ -#define FOR_EACH_BIN_KIND(F) \ - F(_Uninitialized, "Uninitialized", UNINITIALIZED) \ - F(_Null, "", NULL) \ - F(ArrayAssignmentTarget, "ArrayAssignmentTarget", ARRAY_ASSIGNMENT_TARGET) \ - F(ArrayBinding, "ArrayBinding", ARRAY_BINDING) \ - F(ArrayExpression, "ArrayExpression", ARRAY_EXPRESSION) \ - F(ArrowExpressionContentsWithExpression, \ - "ArrowExpressionContentsWithExpression", \ - ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION) \ - F(ArrowExpressionContentsWithFunctionBody, \ - "ArrowExpressionContentsWithFunctionBody", \ - ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY) \ - F(AssertedBlockScope, "AssertedBlockScope", ASSERTED_BLOCK_SCOPE) \ - F(AssertedBoundName, "AssertedBoundName", ASSERTED_BOUND_NAME) \ - F(AssertedBoundNamesScope, "AssertedBoundNamesScope", \ - ASSERTED_BOUND_NAMES_SCOPE) \ - F(AssertedDeclaredName, "AssertedDeclaredName", ASSERTED_DECLARED_NAME) \ - F(AssertedParameterName, "AssertedParameterName", ASSERTED_PARAMETER_NAME) \ - F(AssertedParameterScope, "AssertedParameterScope", \ - ASSERTED_PARAMETER_SCOPE) \ - F(AssertedPositionalParameterName, "AssertedPositionalParameterName", \ - ASSERTED_POSITIONAL_PARAMETER_NAME) \ - F(AssertedRestParameterName, "AssertedRestParameterName", \ - ASSERTED_REST_PARAMETER_NAME) \ - F(AssertedScriptGlobalScope, "AssertedScriptGlobalScope", \ - ASSERTED_SCRIPT_GLOBAL_SCOPE) \ - F(AssertedVarScope, "AssertedVarScope", ASSERTED_VAR_SCOPE) \ - F(AssignmentExpression, "AssignmentExpression", ASSIGNMENT_EXPRESSION) \ - F(AssignmentTargetIdentifier, "AssignmentTargetIdentifier", \ - ASSIGNMENT_TARGET_IDENTIFIER) \ - F(AssignmentTargetPropertyIdentifier, "AssignmentTargetPropertyIdentifier", \ - ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER) \ - F(AssignmentTargetPropertyProperty, "AssignmentTargetPropertyProperty", \ - ASSIGNMENT_TARGET_PROPERTY_PROPERTY) \ - F(AssignmentTargetWithInitializer, "AssignmentTargetWithInitializer", \ - ASSIGNMENT_TARGET_WITH_INITIALIZER) \ - F(AwaitExpression, "AwaitExpression", AWAIT_EXPRESSION) \ - F(BinaryExpression, "BinaryExpression", BINARY_EXPRESSION) \ - F(BindingIdentifier, "BindingIdentifier", BINDING_IDENTIFIER) \ - F(BindingPropertyIdentifier, "BindingPropertyIdentifier", \ - BINDING_PROPERTY_IDENTIFIER) \ - F(BindingPropertyProperty, "BindingPropertyProperty", \ - BINDING_PROPERTY_PROPERTY) \ - F(BindingWithInitializer, "BindingWithInitializer", \ - BINDING_WITH_INITIALIZER) \ - F(Block, "Block", BLOCK) \ - F(BreakStatement, "BreakStatement", BREAK_STATEMENT) \ - F(CallExpression, "CallExpression", CALL_EXPRESSION) \ - F(CatchClause, "CatchClause", CATCH_CLAUSE) \ - F(ClassDeclaration, "ClassDeclaration", CLASS_DECLARATION) \ - F(ClassElement, "ClassElement", CLASS_ELEMENT) \ - F(ClassExpression, "ClassExpression", CLASS_EXPRESSION) \ - F(CompoundAssignmentExpression, "CompoundAssignmentExpression", \ - COMPOUND_ASSIGNMENT_EXPRESSION) \ - F(ComputedMemberAssignmentTarget, "ComputedMemberAssignmentTarget", \ - COMPUTED_MEMBER_ASSIGNMENT_TARGET) \ - F(ComputedMemberExpression, "ComputedMemberExpression", \ - COMPUTED_MEMBER_EXPRESSION) \ - F(ComputedPropertyName, "ComputedPropertyName", COMPUTED_PROPERTY_NAME) \ - F(ConditionalExpression, "ConditionalExpression", CONDITIONAL_EXPRESSION) \ - F(ContinueStatement, "ContinueStatement", CONTINUE_STATEMENT) \ - F(DataProperty, "DataProperty", DATA_PROPERTY) \ - F(DebuggerStatement, "DebuggerStatement", DEBUGGER_STATEMENT) \ - F(Directive, "Directive", DIRECTIVE) \ - F(DoWhileStatement, "DoWhileStatement", DO_WHILE_STATEMENT) \ - F(EagerArrowExpressionWithExpression, "EagerArrowExpressionWithExpression", \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION) \ - F(EagerArrowExpressionWithFunctionBody, \ - "EagerArrowExpressionWithFunctionBody", \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY) \ - F(EagerFunctionDeclaration, "EagerFunctionDeclaration", \ - EAGER_FUNCTION_DECLARATION) \ - F(EagerFunctionExpression, "EagerFunctionExpression", \ - EAGER_FUNCTION_EXPRESSION) \ - F(EagerGetter, "EagerGetter", EAGER_GETTER) \ - F(EagerMethod, "EagerMethod", EAGER_METHOD) \ - F(EagerSetter, "EagerSetter", EAGER_SETTER) \ - F(EmptyStatement, "EmptyStatement", EMPTY_STATEMENT) \ - F(Export, "Export", EXPORT) \ - F(ExportAllFrom, "ExportAllFrom", EXPORT_ALL_FROM) \ - F(ExportDefault, "ExportDefault", EXPORT_DEFAULT) \ - F(ExportFrom, "ExportFrom", EXPORT_FROM) \ - F(ExportFromSpecifier, "ExportFromSpecifier", EXPORT_FROM_SPECIFIER) \ - F(ExportLocalSpecifier, "ExportLocalSpecifier", EXPORT_LOCAL_SPECIFIER) \ - F(ExportLocals, "ExportLocals", EXPORT_LOCALS) \ - F(ExpressionStatement, "ExpressionStatement", EXPRESSION_STATEMENT) \ - F(ForInOfBinding, "ForInOfBinding", FOR_IN_OF_BINDING) \ - F(ForInStatement, "ForInStatement", FOR_IN_STATEMENT) \ - F(ForOfStatement, "ForOfStatement", FOR_OF_STATEMENT) \ - F(ForStatement, "ForStatement", FOR_STATEMENT) \ - F(FormalParameters, "FormalParameters", FORMAL_PARAMETERS) \ - F(FunctionExpressionContents, "FunctionExpressionContents", \ - FUNCTION_EXPRESSION_CONTENTS) \ - F(FunctionOrMethodContents, "FunctionOrMethodContents", \ - FUNCTION_OR_METHOD_CONTENTS) \ - F(GetterContents, "GetterContents", GETTER_CONTENTS) \ - F(IdentifierExpression, "IdentifierExpression", IDENTIFIER_EXPRESSION) \ - F(IfStatement, "IfStatement", IF_STATEMENT) \ - F(Import, "Import", IMPORT) \ - F(ImportNamespace, "ImportNamespace", IMPORT_NAMESPACE) \ - F(ImportSpecifier, "ImportSpecifier", IMPORT_SPECIFIER) \ - F(LabelledStatement, "LabelledStatement", LABELLED_STATEMENT) \ - F(LazyArrowExpressionWithExpression, "LazyArrowExpressionWithExpression", \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION) \ - F(LazyArrowExpressionWithFunctionBody, \ - "LazyArrowExpressionWithFunctionBody", \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY) \ - F(LazyFunctionDeclaration, "LazyFunctionDeclaration", \ - LAZY_FUNCTION_DECLARATION) \ - F(LazyFunctionExpression, "LazyFunctionExpression", \ - LAZY_FUNCTION_EXPRESSION) \ - F(LazyGetter, "LazyGetter", LAZY_GETTER) \ - F(LazyMethod, "LazyMethod", LAZY_METHOD) \ - F(LazySetter, "LazySetter", LAZY_SETTER) \ - F(LiteralBooleanExpression, "LiteralBooleanExpression", \ - LITERAL_BOOLEAN_EXPRESSION) \ - F(LiteralInfinityExpression, "LiteralInfinityExpression", \ - LITERAL_INFINITY_EXPRESSION) \ - F(LiteralNullExpression, "LiteralNullExpression", LITERAL_NULL_EXPRESSION) \ - F(LiteralNumericExpression, "LiteralNumericExpression", \ - LITERAL_NUMERIC_EXPRESSION) \ - F(LiteralPropertyName, "LiteralPropertyName", LITERAL_PROPERTY_NAME) \ - F(LiteralRegExpExpression, "LiteralRegExpExpression", \ - LITERAL_REG_EXP_EXPRESSION) \ - F(LiteralStringExpression, "LiteralStringExpression", \ - LITERAL_STRING_EXPRESSION) \ - F(Module, "Module", MODULE) \ - F(NewExpression, "NewExpression", NEW_EXPRESSION) \ - F(NewTargetExpression, "NewTargetExpression", NEW_TARGET_EXPRESSION) \ - F(ObjectAssignmentTarget, "ObjectAssignmentTarget", \ - OBJECT_ASSIGNMENT_TARGET) \ - F(ObjectBinding, "ObjectBinding", OBJECT_BINDING) \ - F(ObjectExpression, "ObjectExpression", OBJECT_EXPRESSION) \ - F(ReturnStatement, "ReturnStatement", RETURN_STATEMENT) \ - F(Script, "Script", SCRIPT) \ - F(SetterContents, "SetterContents", SETTER_CONTENTS) \ - F(ShorthandProperty, "ShorthandProperty", SHORTHAND_PROPERTY) \ - F(SpreadElement, "SpreadElement", SPREAD_ELEMENT) \ - F(StaticMemberAssignmentTarget, "StaticMemberAssignmentTarget", \ - STATIC_MEMBER_ASSIGNMENT_TARGET) \ - F(StaticMemberExpression, "StaticMemberExpression", \ - STATIC_MEMBER_EXPRESSION) \ - F(Super, "Super", SUPER) \ - F(SwitchCase, "SwitchCase", SWITCH_CASE) \ - F(SwitchDefault, "SwitchDefault", SWITCH_DEFAULT) \ - F(SwitchStatement, "SwitchStatement", SWITCH_STATEMENT) \ - F(SwitchStatementWithDefault, "SwitchStatementWithDefault", \ - SWITCH_STATEMENT_WITH_DEFAULT) \ - F(TemplateElement, "TemplateElement", TEMPLATE_ELEMENT) \ - F(TemplateExpression, "TemplateExpression", TEMPLATE_EXPRESSION) \ - F(ThisExpression, "ThisExpression", THIS_EXPRESSION) \ - F(ThrowStatement, "ThrowStatement", THROW_STATEMENT) \ - F(TryCatchStatement, "TryCatchStatement", TRY_CATCH_STATEMENT) \ - F(TryFinallyStatement, "TryFinallyStatement", TRY_FINALLY_STATEMENT) \ - F(UnaryExpression, "UnaryExpression", UNARY_EXPRESSION) \ - F(UpdateExpression, "UpdateExpression", UPDATE_EXPRESSION) \ - F(VariableDeclaration, "VariableDeclaration", VARIABLE_DECLARATION) \ - F(VariableDeclarator, "VariableDeclarator", VARIABLE_DECLARATOR) \ - F(WhileStatement, "WhileStatement", WHILE_STATEMENT) \ - F(WithStatement, "WithStatement", WITH_STATEMENT) \ - F(YieldExpression, "YieldExpression", YIELD_EXPRESSION) \ - F(YieldStarExpression, "YieldStarExpression", YIELD_STAR_EXPRESSION) - -enum class BinASTKind : uint16_t { -#define EMIT_ENUM(name, _1, _2) name, - FOR_EACH_BIN_KIND(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// The number of distinct values of BinASTKind. -const size_t BINASTKIND_LIMIT = 120; - -/** - * The different fields of Binary AST nodes, as per the specifications of - * Binary AST. - * - * Usage: - * - * ```c++ - * #define WITH_FIELD(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_FIELD(WITH_FIELD) - * ``` - * - * (sorted by alphabetical order) - */ -#define FOR_EACH_BIN_FIELD(F) \ - F(Alternate, "alternate") \ - F(Arguments, "arguments") \ - F(Binding, "binding") \ - F(BindingScope, "bindingScope") \ - F(Body, "body") \ - F(BodyScope, "bodyScope") \ - F(BoundNames, "boundNames") \ - F(Callee, "callee") \ - F(Cases, "cases") \ - F(CatchClause, "catchClause") \ - F(Consequent, "consequent") \ - F(Contents, "contents") \ - F(ContentsSkip, "contents_skip") \ - F(Declaration, "declaration") \ - F(Declarators, "declarators") \ - F(DeclaredNames, "declaredNames") \ - F(DefaultBinding, "defaultBinding") \ - F(DefaultCase, "defaultCase") \ - F(Directives, "directives") \ - F(Discriminant, "discriminant") \ - F(Elements, "elements") \ - F(ExportedName, "exportedName") \ - F(Expression, "expression") \ - F(Finalizer, "finalizer") \ - F(Flags, "flags") \ - F(HasDirectEval, "hasDirectEval") \ - F(Index, "index") \ - F(Init, "init") \ - F(IsAsync, "isAsync") \ - F(IsCaptured, "isCaptured") \ - F(IsFunctionNameCaptured, "isFunctionNameCaptured") \ - F(IsGenerator, "isGenerator") \ - F(IsPrefix, "isPrefix") \ - F(IsSimpleParameterList, "isSimpleParameterList") \ - F(IsStatic, "isStatic") \ - F(IsThisCaptured, "isThisCaptured") \ - F(Items, "items") \ - F(Kind, "kind") \ - F(Label, "label") \ - F(Left, "left") \ - F(Length, "length") \ - F(Method, "method") \ - F(ModuleSpecifier, "moduleSpecifier") \ - F(Name, "name") \ - F(NamedExports, "namedExports") \ - F(NamedImports, "namedImports") \ - F(NamespaceBinding, "namespaceBinding") \ - F(Object, "object") \ - F(Operand, "operand") \ - F(Operator, "operator") \ - F(Param, "param") \ - F(ParamNames, "paramNames") \ - F(ParameterScope, "parameterScope") \ - F(Params, "params") \ - F(Pattern, "pattern") \ - F(PostDefaultCases, "postDefaultCases") \ - F(PreDefaultCases, "preDefaultCases") \ - F(Properties, "properties") \ - F(Property, "property") \ - F(RawValue, "rawValue") \ - F(Rest, "rest") \ - F(Right, "right") \ - F(Scope, "scope") \ - F(Statements, "statements") \ - F(Super, "super") \ - F(Tag, "tag") \ - F(Test, "test") \ - F(Update, "update") \ - F(Value, "value") - -enum class BinASTField : uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// The number of distinct values of BinASTField. -const size_t BINASTFIELD_LIMIT = 69; - -#define FOR_EACH_BIN_INTERFACE_AND_FIELD(F) \ - F(ArrayAssignmentTarget__Elements, "ArrayAssignmentTarget::elements") \ - F(ArrayAssignmentTarget__Rest, "ArrayAssignmentTarget::rest") \ - F(ArrayBinding__Elements, "ArrayBinding::elements") \ - F(ArrayBinding__Rest, "ArrayBinding::rest") \ - F(ArrayExpression__Elements, "ArrayExpression::elements") \ - F(ArrowExpressionContentsWithExpression__ParameterScope, \ - "ArrowExpressionContentsWithExpression::parameterScope") \ - F(ArrowExpressionContentsWithExpression__Params, \ - "ArrowExpressionContentsWithExpression::params") \ - F(ArrowExpressionContentsWithExpression__BodyScope, \ - "ArrowExpressionContentsWithExpression::bodyScope") \ - F(ArrowExpressionContentsWithExpression__Body, \ - "ArrowExpressionContentsWithExpression::body") \ - F(ArrowExpressionContentsWithFunctionBody__ParameterScope, \ - "ArrowExpressionContentsWithFunctionBody::parameterScope") \ - F(ArrowExpressionContentsWithFunctionBody__Params, \ - "ArrowExpressionContentsWithFunctionBody::params") \ - F(ArrowExpressionContentsWithFunctionBody__BodyScope, \ - "ArrowExpressionContentsWithFunctionBody::bodyScope") \ - F(ArrowExpressionContentsWithFunctionBody__Body, \ - "ArrowExpressionContentsWithFunctionBody::body") \ - F(AssertedBlockScope__DeclaredNames, "AssertedBlockScope::declaredNames") \ - F(AssertedBlockScope__HasDirectEval, "AssertedBlockScope::hasDirectEval") \ - F(AssertedBoundName__Name, "AssertedBoundName::name") \ - F(AssertedBoundName__IsCaptured, "AssertedBoundName::isCaptured") \ - F(AssertedBoundNamesScope__BoundNames, \ - "AssertedBoundNamesScope::boundNames") \ - F(AssertedBoundNamesScope__HasDirectEval, \ - "AssertedBoundNamesScope::hasDirectEval") \ - F(AssertedDeclaredName__Name, "AssertedDeclaredName::name") \ - F(AssertedDeclaredName__Kind, "AssertedDeclaredName::kind") \ - F(AssertedDeclaredName__IsCaptured, "AssertedDeclaredName::isCaptured") \ - F(AssertedParameterName__Name, "AssertedParameterName::name") \ - F(AssertedParameterName__IsCaptured, "AssertedParameterName::isCaptured") \ - F(AssertedParameterScope__ParamNames, "AssertedParameterScope::paramNames") \ - F(AssertedParameterScope__HasDirectEval, \ - "AssertedParameterScope::hasDirectEval") \ - F(AssertedParameterScope__IsSimpleParameterList, \ - "AssertedParameterScope::isSimpleParameterList") \ - F(AssertedPositionalParameterName__Index, \ - "AssertedPositionalParameterName::index") \ - F(AssertedPositionalParameterName__Name, \ - "AssertedPositionalParameterName::name") \ - F(AssertedPositionalParameterName__IsCaptured, \ - "AssertedPositionalParameterName::isCaptured") \ - F(AssertedRestParameterName__Name, "AssertedRestParameterName::name") \ - F(AssertedRestParameterName__IsCaptured, \ - "AssertedRestParameterName::isCaptured") \ - F(AssertedScriptGlobalScope__DeclaredNames, \ - "AssertedScriptGlobalScope::declaredNames") \ - F(AssertedScriptGlobalScope__HasDirectEval, \ - "AssertedScriptGlobalScope::hasDirectEval") \ - F(AssertedVarScope__DeclaredNames, "AssertedVarScope::declaredNames") \ - F(AssertedVarScope__HasDirectEval, "AssertedVarScope::hasDirectEval") \ - F(AssignmentExpression__Binding, "AssignmentExpression::binding") \ - F(AssignmentExpression__Expression, "AssignmentExpression::expression") \ - F(AssignmentTargetIdentifier__Name, "AssignmentTargetIdentifier::name") \ - F(AssignmentTargetPropertyIdentifier__Binding, \ - "AssignmentTargetPropertyIdentifier::binding") \ - F(AssignmentTargetPropertyIdentifier__Init, \ - "AssignmentTargetPropertyIdentifier::init") \ - F(AssignmentTargetPropertyProperty__Name, \ - "AssignmentTargetPropertyProperty::name") \ - F(AssignmentTargetPropertyProperty__Binding, \ - "AssignmentTargetPropertyProperty::binding") \ - F(AssignmentTargetWithInitializer__Binding, \ - "AssignmentTargetWithInitializer::binding") \ - F(AssignmentTargetWithInitializer__Init, \ - "AssignmentTargetWithInitializer::init") \ - F(AwaitExpression__Expression, "AwaitExpression::expression") \ - F(BinaryExpression__Operator, "BinaryExpression::operator") \ - F(BinaryExpression__Left, "BinaryExpression::left") \ - F(BinaryExpression__Right, "BinaryExpression::right") \ - F(BindingIdentifier__Name, "BindingIdentifier::name") \ - F(BindingPropertyIdentifier__Binding, "BindingPropertyIdentifier::binding") \ - F(BindingPropertyIdentifier__Init, "BindingPropertyIdentifier::init") \ - F(BindingPropertyProperty__Name, "BindingPropertyProperty::name") \ - F(BindingPropertyProperty__Binding, "BindingPropertyProperty::binding") \ - F(BindingWithInitializer__Binding, "BindingWithInitializer::binding") \ - F(BindingWithInitializer__Init, "BindingWithInitializer::init") \ - F(Block__Scope, "Block::scope") \ - F(Block__Statements, "Block::statements") \ - F(BreakStatement__Label, "BreakStatement::label") \ - F(CallExpression__Callee, "CallExpression::callee") \ - F(CallExpression__Arguments, "CallExpression::arguments") \ - F(CatchClause__BindingScope, "CatchClause::bindingScope") \ - F(CatchClause__Binding, "CatchClause::binding") \ - F(CatchClause__Body, "CatchClause::body") \ - F(ClassDeclaration__Name, "ClassDeclaration::name") \ - F(ClassDeclaration__Super, "ClassDeclaration::super") \ - F(ClassDeclaration__Elements, "ClassDeclaration::elements") \ - F(ClassElement__IsStatic, "ClassElement::isStatic") \ - F(ClassElement__Method, "ClassElement::method") \ - F(ClassExpression__Name, "ClassExpression::name") \ - F(ClassExpression__Super, "ClassExpression::super") \ - F(ClassExpression__Elements, "ClassExpression::elements") \ - F(CompoundAssignmentExpression__Operator, \ - "CompoundAssignmentExpression::operator") \ - F(CompoundAssignmentExpression__Binding, \ - "CompoundAssignmentExpression::binding") \ - F(CompoundAssignmentExpression__Expression, \ - "CompoundAssignmentExpression::expression") \ - F(ComputedMemberAssignmentTarget__Object, \ - "ComputedMemberAssignmentTarget::object") \ - F(ComputedMemberAssignmentTarget__Expression, \ - "ComputedMemberAssignmentTarget::expression") \ - F(ComputedMemberExpression__Object, "ComputedMemberExpression::object") \ - F(ComputedMemberExpression__Expression, \ - "ComputedMemberExpression::expression") \ - F(ComputedPropertyName__Expression, "ComputedPropertyName::expression") \ - F(ConditionalExpression__Test, "ConditionalExpression::test") \ - F(ConditionalExpression__Consequent, "ConditionalExpression::consequent") \ - F(ConditionalExpression__Alternate, "ConditionalExpression::alternate") \ - F(ContinueStatement__Label, "ContinueStatement::label") \ - F(DataProperty__Name, "DataProperty::name") \ - F(DataProperty__Expression, "DataProperty::expression") \ - F(Directive__RawValue, "Directive::rawValue") \ - F(DoWhileStatement__Test, "DoWhileStatement::test") \ - F(DoWhileStatement__Body, "DoWhileStatement::body") \ - F(EagerArrowExpressionWithExpression__IsAsync, \ - "EagerArrowExpressionWithExpression::isAsync") \ - F(EagerArrowExpressionWithExpression__Length, \ - "EagerArrowExpressionWithExpression::length") \ - F(EagerArrowExpressionWithExpression__Contents, \ - "EagerArrowExpressionWithExpression::contents") \ - F(EagerArrowExpressionWithFunctionBody__IsAsync, \ - "EagerArrowExpressionWithFunctionBody::isAsync") \ - F(EagerArrowExpressionWithFunctionBody__Length, \ - "EagerArrowExpressionWithFunctionBody::length") \ - F(EagerArrowExpressionWithFunctionBody__Directives, \ - "EagerArrowExpressionWithFunctionBody::directives") \ - F(EagerArrowExpressionWithFunctionBody__Contents, \ - "EagerArrowExpressionWithFunctionBody::contents") \ - F(EagerFunctionDeclaration__IsAsync, "EagerFunctionDeclaration::isAsync") \ - F(EagerFunctionDeclaration__IsGenerator, \ - "EagerFunctionDeclaration::isGenerator") \ - F(EagerFunctionDeclaration__Name, "EagerFunctionDeclaration::name") \ - F(EagerFunctionDeclaration__Length, "EagerFunctionDeclaration::length") \ - F(EagerFunctionDeclaration__Directives, \ - "EagerFunctionDeclaration::directives") \ - F(EagerFunctionDeclaration__Contents, "EagerFunctionDeclaration::contents") \ - F(EagerFunctionExpression__IsAsync, "EagerFunctionExpression::isAsync") \ - F(EagerFunctionExpression__IsGenerator, \ - "EagerFunctionExpression::isGenerator") \ - F(EagerFunctionExpression__Name, "EagerFunctionExpression::name") \ - F(EagerFunctionExpression__Length, "EagerFunctionExpression::length") \ - F(EagerFunctionExpression__Directives, \ - "EagerFunctionExpression::directives") \ - F(EagerFunctionExpression__Contents, "EagerFunctionExpression::contents") \ - F(EagerGetter__Name, "EagerGetter::name") \ - F(EagerGetter__Directives, "EagerGetter::directives") \ - F(EagerGetter__Contents, "EagerGetter::contents") \ - F(EagerMethod__IsAsync, "EagerMethod::isAsync") \ - F(EagerMethod__IsGenerator, "EagerMethod::isGenerator") \ - F(EagerMethod__Name, "EagerMethod::name") \ - F(EagerMethod__Length, "EagerMethod::length") \ - F(EagerMethod__Directives, "EagerMethod::directives") \ - F(EagerMethod__Contents, "EagerMethod::contents") \ - F(EagerSetter__Name, "EagerSetter::name") \ - F(EagerSetter__Length, "EagerSetter::length") \ - F(EagerSetter__Directives, "EagerSetter::directives") \ - F(EagerSetter__Contents, "EagerSetter::contents") \ - F(Export__Declaration, "Export::declaration") \ - F(ExportAllFrom__ModuleSpecifier, "ExportAllFrom::moduleSpecifier") \ - F(ExportDefault__Body, "ExportDefault::body") \ - F(ExportFrom__NamedExports, "ExportFrom::namedExports") \ - F(ExportFrom__ModuleSpecifier, "ExportFrom::moduleSpecifier") \ - F(ExportFromSpecifier__Name, "ExportFromSpecifier::name") \ - F(ExportFromSpecifier__ExportedName, "ExportFromSpecifier::exportedName") \ - F(ExportLocalSpecifier__Name, "ExportLocalSpecifier::name") \ - F(ExportLocalSpecifier__ExportedName, "ExportLocalSpecifier::exportedName") \ - F(ExportLocals__NamedExports, "ExportLocals::namedExports") \ - F(ExpressionStatement__Expression, "ExpressionStatement::expression") \ - F(ForInOfBinding__Kind, "ForInOfBinding::kind") \ - F(ForInOfBinding__Binding, "ForInOfBinding::binding") \ - F(ForInStatement__Left, "ForInStatement::left") \ - F(ForInStatement__Right, "ForInStatement::right") \ - F(ForInStatement__Body, "ForInStatement::body") \ - F(ForOfStatement__Left, "ForOfStatement::left") \ - F(ForOfStatement__Right, "ForOfStatement::right") \ - F(ForOfStatement__Body, "ForOfStatement::body") \ - F(ForStatement__Init, "ForStatement::init") \ - F(ForStatement__Test, "ForStatement::test") \ - F(ForStatement__Update, "ForStatement::update") \ - F(ForStatement__Body, "ForStatement::body") \ - F(FormalParameters__Items, "FormalParameters::items") \ - F(FormalParameters__Rest, "FormalParameters::rest") \ - F(FunctionExpressionContents__IsFunctionNameCaptured, \ - "FunctionExpressionContents::isFunctionNameCaptured") \ - F(FunctionExpressionContents__IsThisCaptured, \ - "FunctionExpressionContents::isThisCaptured") \ - F(FunctionExpressionContents__ParameterScope, \ - "FunctionExpressionContents::parameterScope") \ - F(FunctionExpressionContents__Params, "FunctionExpressionContents::params") \ - F(FunctionExpressionContents__BodyScope, \ - "FunctionExpressionContents::bodyScope") \ - F(FunctionExpressionContents__Body, "FunctionExpressionContents::body") \ - F(FunctionOrMethodContents__IsThisCaptured, \ - "FunctionOrMethodContents::isThisCaptured") \ - F(FunctionOrMethodContents__ParameterScope, \ - "FunctionOrMethodContents::parameterScope") \ - F(FunctionOrMethodContents__Params, "FunctionOrMethodContents::params") \ - F(FunctionOrMethodContents__BodyScope, \ - "FunctionOrMethodContents::bodyScope") \ - F(FunctionOrMethodContents__Body, "FunctionOrMethodContents::body") \ - F(GetterContents__IsThisCaptured, "GetterContents::isThisCaptured") \ - F(GetterContents__BodyScope, "GetterContents::bodyScope") \ - F(GetterContents__Body, "GetterContents::body") \ - F(IdentifierExpression__Name, "IdentifierExpression::name") \ - F(IfStatement__Test, "IfStatement::test") \ - F(IfStatement__Consequent, "IfStatement::consequent") \ - F(IfStatement__Alternate, "IfStatement::alternate") \ - F(Import__ModuleSpecifier, "Import::moduleSpecifier") \ - F(Import__DefaultBinding, "Import::defaultBinding") \ - F(Import__NamedImports, "Import::namedImports") \ - F(ImportNamespace__ModuleSpecifier, "ImportNamespace::moduleSpecifier") \ - F(ImportNamespace__DefaultBinding, "ImportNamespace::defaultBinding") \ - F(ImportNamespace__NamespaceBinding, "ImportNamespace::namespaceBinding") \ - F(ImportSpecifier__Name, "ImportSpecifier::name") \ - F(ImportSpecifier__Binding, "ImportSpecifier::binding") \ - F(LabelledStatement__Label, "LabelledStatement::label") \ - F(LabelledStatement__Body, "LabelledStatement::body") \ - F(LazyArrowExpressionWithExpression__IsAsync, \ - "LazyArrowExpressionWithExpression::isAsync") \ - F(LazyArrowExpressionWithExpression__Length, \ - "LazyArrowExpressionWithExpression::length") \ - F(LazyArrowExpressionWithExpression__ContentsSkip, \ - "LazyArrowExpressionWithExpression::contents_skip") \ - F(LazyArrowExpressionWithExpression__Contents, \ - "LazyArrowExpressionWithExpression::contents") \ - F(LazyArrowExpressionWithFunctionBody__IsAsync, \ - "LazyArrowExpressionWithFunctionBody::isAsync") \ - F(LazyArrowExpressionWithFunctionBody__Length, \ - "LazyArrowExpressionWithFunctionBody::length") \ - F(LazyArrowExpressionWithFunctionBody__Directives, \ - "LazyArrowExpressionWithFunctionBody::directives") \ - F(LazyArrowExpressionWithFunctionBody__ContentsSkip, \ - "LazyArrowExpressionWithFunctionBody::contents_skip") \ - F(LazyArrowExpressionWithFunctionBody__Contents, \ - "LazyArrowExpressionWithFunctionBody::contents") \ - F(LazyFunctionDeclaration__IsAsync, "LazyFunctionDeclaration::isAsync") \ - F(LazyFunctionDeclaration__IsGenerator, \ - "LazyFunctionDeclaration::isGenerator") \ - F(LazyFunctionDeclaration__Name, "LazyFunctionDeclaration::name") \ - F(LazyFunctionDeclaration__Length, "LazyFunctionDeclaration::length") \ - F(LazyFunctionDeclaration__Directives, \ - "LazyFunctionDeclaration::directives") \ - F(LazyFunctionDeclaration__ContentsSkip, \ - "LazyFunctionDeclaration::contents_skip") \ - F(LazyFunctionDeclaration__Contents, "LazyFunctionDeclaration::contents") \ - F(LazyFunctionExpression__IsAsync, "LazyFunctionExpression::isAsync") \ - F(LazyFunctionExpression__IsGenerator, \ - "LazyFunctionExpression::isGenerator") \ - F(LazyFunctionExpression__Name, "LazyFunctionExpression::name") \ - F(LazyFunctionExpression__Length, "LazyFunctionExpression::length") \ - F(LazyFunctionExpression__Directives, "LazyFunctionExpression::directives") \ - F(LazyFunctionExpression__ContentsSkip, \ - "LazyFunctionExpression::contents_skip") \ - F(LazyFunctionExpression__Contents, "LazyFunctionExpression::contents") \ - F(LazyGetter__Name, "LazyGetter::name") \ - F(LazyGetter__Directives, "LazyGetter::directives") \ - F(LazyGetter__ContentsSkip, "LazyGetter::contents_skip") \ - F(LazyGetter__Contents, "LazyGetter::contents") \ - F(LazyMethod__IsAsync, "LazyMethod::isAsync") \ - F(LazyMethod__IsGenerator, "LazyMethod::isGenerator") \ - F(LazyMethod__Name, "LazyMethod::name") \ - F(LazyMethod__Length, "LazyMethod::length") \ - F(LazyMethod__Directives, "LazyMethod::directives") \ - F(LazyMethod__ContentsSkip, "LazyMethod::contents_skip") \ - F(LazyMethod__Contents, "LazyMethod::contents") \ - F(LazySetter__Name, "LazySetter::name") \ - F(LazySetter__Length, "LazySetter::length") \ - F(LazySetter__Directives, "LazySetter::directives") \ - F(LazySetter__ContentsSkip, "LazySetter::contents_skip") \ - F(LazySetter__Contents, "LazySetter::contents") \ - F(LiteralBooleanExpression__Value, "LiteralBooleanExpression::value") \ - F(LiteralNumericExpression__Value, "LiteralNumericExpression::value") \ - F(LiteralPropertyName__Value, "LiteralPropertyName::value") \ - F(LiteralRegExpExpression__Pattern, "LiteralRegExpExpression::pattern") \ - F(LiteralRegExpExpression__Flags, "LiteralRegExpExpression::flags") \ - F(LiteralStringExpression__Value, "LiteralStringExpression::value") \ - F(Module__Scope, "Module::scope") \ - F(Module__Directives, "Module::directives") \ - F(Module__Items, "Module::items") \ - F(NewExpression__Callee, "NewExpression::callee") \ - F(NewExpression__Arguments, "NewExpression::arguments") \ - F(ObjectAssignmentTarget__Properties, "ObjectAssignmentTarget::properties") \ - F(ObjectBinding__Properties, "ObjectBinding::properties") \ - F(ObjectExpression__Properties, "ObjectExpression::properties") \ - F(ReturnStatement__Expression, "ReturnStatement::expression") \ - F(Script__Scope, "Script::scope") \ - F(Script__Directives, "Script::directives") \ - F(Script__Statements, "Script::statements") \ - F(SetterContents__IsThisCaptured, "SetterContents::isThisCaptured") \ - F(SetterContents__ParameterScope, "SetterContents::parameterScope") \ - F(SetterContents__Param, "SetterContents::param") \ - F(SetterContents__BodyScope, "SetterContents::bodyScope") \ - F(SetterContents__Body, "SetterContents::body") \ - F(ShorthandProperty__Name, "ShorthandProperty::name") \ - F(SpreadElement__Expression, "SpreadElement::expression") \ - F(StaticMemberAssignmentTarget__Object, \ - "StaticMemberAssignmentTarget::object") \ - F(StaticMemberAssignmentTarget__Property, \ - "StaticMemberAssignmentTarget::property") \ - F(StaticMemberExpression__Object, "StaticMemberExpression::object") \ - F(StaticMemberExpression__Property, "StaticMemberExpression::property") \ - F(SwitchCase__Test, "SwitchCase::test") \ - F(SwitchCase__Consequent, "SwitchCase::consequent") \ - F(SwitchDefault__Consequent, "SwitchDefault::consequent") \ - F(SwitchStatement__Discriminant, "SwitchStatement::discriminant") \ - F(SwitchStatement__Cases, "SwitchStatement::cases") \ - F(SwitchStatementWithDefault__Discriminant, \ - "SwitchStatementWithDefault::discriminant") \ - F(SwitchStatementWithDefault__PreDefaultCases, \ - "SwitchStatementWithDefault::preDefaultCases") \ - F(SwitchStatementWithDefault__DefaultCase, \ - "SwitchStatementWithDefault::defaultCase") \ - F(SwitchStatementWithDefault__PostDefaultCases, \ - "SwitchStatementWithDefault::postDefaultCases") \ - F(TemplateElement__RawValue, "TemplateElement::rawValue") \ - F(TemplateExpression__Tag, "TemplateExpression::tag") \ - F(TemplateExpression__Elements, "TemplateExpression::elements") \ - F(ThrowStatement__Expression, "ThrowStatement::expression") \ - F(TryCatchStatement__Body, "TryCatchStatement::body") \ - F(TryCatchStatement__CatchClause, "TryCatchStatement::catchClause") \ - F(TryFinallyStatement__Body, "TryFinallyStatement::body") \ - F(TryFinallyStatement__CatchClause, "TryFinallyStatement::catchClause") \ - F(TryFinallyStatement__Finalizer, "TryFinallyStatement::finalizer") \ - F(UnaryExpression__Operator, "UnaryExpression::operator") \ - F(UnaryExpression__Operand, "UnaryExpression::operand") \ - F(UpdateExpression__IsPrefix, "UpdateExpression::isPrefix") \ - F(UpdateExpression__Operator, "UpdateExpression::operator") \ - F(UpdateExpression__Operand, "UpdateExpression::operand") \ - F(VariableDeclaration__Kind, "VariableDeclaration::kind") \ - F(VariableDeclaration__Declarators, "VariableDeclaration::declarators") \ - F(VariableDeclarator__Binding, "VariableDeclarator::binding") \ - F(VariableDeclarator__Init, "VariableDeclarator::init") \ - F(WhileStatement__Test, "WhileStatement::test") \ - F(WhileStatement__Body, "WhileStatement::body") \ - F(WithStatement__Object, "WithStatement::object") \ - F(WithStatement__Body, "WithStatement::body") \ - F(YieldExpression__Expression, "YieldExpression::expression") \ - F(YieldStarExpression__Expression, "YieldStarExpression::expression") - -enum class BinASTInterfaceAndField : uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_INTERFACE_AND_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// Iteration through the interfaces of sum ArrowExpression -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ARROW_EXPRESSION(F) \ - F(ArrowExpression, 0, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ArrowExpression::EagerArrowExpressionWithExpression") \ - F(ArrowExpression, 1, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ArrowExpression::EagerArrowExpressionWithFunctionBody") \ - F(ArrowExpression, 2, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ArrowExpression::LazyArrowExpressionWithExpression") \ - F(ArrowExpression, 3, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ArrowExpression::LazyArrowExpressionWithFunctionBody") - -const size_t BINAST_SUM_ARROW_EXPRESSION_LIMIT = 4; - -// Iteration through the interfaces of sum AssertedMaybePositionalParameterName -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME( \ - F) \ - F(AssertedMaybePositionalParameterName, 0, AssertedParameterName, \ - ASSERTED_PARAMETER_NAME, \ - "AssertedMaybePositionalParameterName::AssertedParameterName") \ - F(AssertedMaybePositionalParameterName, 1, AssertedPositionalParameterName, \ - ASSERTED_POSITIONAL_PARAMETER_NAME, \ - "AssertedMaybePositionalParameterName::AssertedPositionalParameterName") \ - F(AssertedMaybePositionalParameterName, 2, AssertedRestParameterName, \ - ASSERTED_REST_PARAMETER_NAME, \ - "AssertedMaybePositionalParameterName::AssertedRestParameterName") - -const size_t BINAST_SUM_ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME_LIMIT = 3; - -// Iteration through the interfaces of sum AssignmentTarget -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET(F) \ - F(AssignmentTarget, 0, ArrayAssignmentTarget, ARRAY_ASSIGNMENT_TARGET, \ - "AssignmentTarget::ArrayAssignmentTarget") \ - F(AssignmentTarget, 1, AssignmentTargetIdentifier, \ - ASSIGNMENT_TARGET_IDENTIFIER, \ - "AssignmentTarget::AssignmentTargetIdentifier") \ - F(AssignmentTarget, 2, ComputedMemberAssignmentTarget, \ - COMPUTED_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTarget::ComputedMemberAssignmentTarget") \ - F(AssignmentTarget, 3, ObjectAssignmentTarget, OBJECT_ASSIGNMENT_TARGET, \ - "AssignmentTarget::ObjectAssignmentTarget") \ - F(AssignmentTarget, 4, StaticMemberAssignmentTarget, \ - STATIC_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTarget::StaticMemberAssignmentTarget") - -const size_t BINAST_SUM_ASSIGNMENT_TARGET_LIMIT = 5; - -// Iteration through the interfaces of sum -// AssignmentTargetOrAssignmentTargetWithInitializer -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER( \ - F) \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 0, \ - ArrayAssignmentTarget, ARRAY_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "ArrayAssignmentTarget") \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 1, \ - AssignmentTargetIdentifier, ASSIGNMENT_TARGET_IDENTIFIER, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "AssignmentTargetIdentifier") \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 2, \ - AssignmentTargetWithInitializer, ASSIGNMENT_TARGET_WITH_INITIALIZER, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "AssignmentTargetWithInitializer") \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 3, \ - ComputedMemberAssignmentTarget, COMPUTED_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "ComputedMemberAssignmentTarget") \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 4, \ - ObjectAssignmentTarget, OBJECT_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "ObjectAssignmentTarget") \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, 5, \ - StaticMemberAssignmentTarget, STATIC_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrAssignmentTargetWithInitializer::" \ - "StaticMemberAssignmentTarget") - -const size_t - BINAST_SUM_ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER_LIMIT = - 6; - -// Iteration through the interfaces of sum AssignmentTargetOrForInOfBinding -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING( \ - F) \ - F(AssignmentTargetOrForInOfBinding, 0, ArrayAssignmentTarget, \ - ARRAY_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrForInOfBinding::ArrayAssignmentTarget") \ - F(AssignmentTargetOrForInOfBinding, 1, AssignmentTargetIdentifier, \ - ASSIGNMENT_TARGET_IDENTIFIER, \ - "AssignmentTargetOrForInOfBinding::AssignmentTargetIdentifier") \ - F(AssignmentTargetOrForInOfBinding, 2, ComputedMemberAssignmentTarget, \ - COMPUTED_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrForInOfBinding::ComputedMemberAssignmentTarget") \ - F(AssignmentTargetOrForInOfBinding, 3, ForInOfBinding, FOR_IN_OF_BINDING, \ - "AssignmentTargetOrForInOfBinding::ForInOfBinding") \ - F(AssignmentTargetOrForInOfBinding, 4, ObjectAssignmentTarget, \ - OBJECT_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrForInOfBinding::ObjectAssignmentTarget") \ - F(AssignmentTargetOrForInOfBinding, 5, StaticMemberAssignmentTarget, \ - STATIC_MEMBER_ASSIGNMENT_TARGET, \ - "AssignmentTargetOrForInOfBinding::StaticMemberAssignmentTarget") - -const size_t BINAST_SUM_ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING_LIMIT = 6; - -// Iteration through the interfaces of sum AssignmentTargetPattern -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_PATTERN(F) \ - F(AssignmentTargetPattern, 0, ArrayAssignmentTarget, \ - ARRAY_ASSIGNMENT_TARGET, "AssignmentTargetPattern::ArrayAssignmentTarget") \ - F(AssignmentTargetPattern, 1, ObjectAssignmentTarget, \ - OBJECT_ASSIGNMENT_TARGET, \ - "AssignmentTargetPattern::ObjectAssignmentTarget") - -const size_t BINAST_SUM_ASSIGNMENT_TARGET_PATTERN_LIMIT = 2; - -// Iteration through the interfaces of sum AssignmentTargetProperty -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ASSIGNMENT_TARGET_PROPERTY(F) \ - F(AssignmentTargetProperty, 0, AssignmentTargetPropertyIdentifier, \ - ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER, \ - "AssignmentTargetProperty::AssignmentTargetPropertyIdentifier") \ - F(AssignmentTargetProperty, 1, AssignmentTargetPropertyProperty, \ - ASSIGNMENT_TARGET_PROPERTY_PROPERTY, \ - "AssignmentTargetProperty::AssignmentTargetPropertyProperty") - -const size_t BINAST_SUM_ASSIGNMENT_TARGET_PROPERTY_LIMIT = 2; - -// Iteration through the interfaces of sum Binding -#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING(F) \ - F(Binding, 0, ArrayBinding, ARRAY_BINDING, "Binding::ArrayBinding") \ - F(Binding, 1, BindingIdentifier, BINDING_IDENTIFIER, \ - "Binding::BindingIdentifier") \ - F(Binding, 2, ObjectBinding, OBJECT_BINDING, "Binding::ObjectBinding") - -const size_t BINAST_SUM_BINDING_LIMIT = 3; - -// Iteration through the interfaces of sum BindingOrBindingWithInitializer -#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_OR_BINDING_WITH_INITIALIZER(F) \ - F(BindingOrBindingWithInitializer, 0, ArrayBinding, ARRAY_BINDING, \ - "BindingOrBindingWithInitializer::ArrayBinding") \ - F(BindingOrBindingWithInitializer, 1, BindingIdentifier, BINDING_IDENTIFIER, \ - "BindingOrBindingWithInitializer::BindingIdentifier") \ - F(BindingOrBindingWithInitializer, 2, BindingWithInitializer, \ - BINDING_WITH_INITIALIZER, \ - "BindingOrBindingWithInitializer::BindingWithInitializer") \ - F(BindingOrBindingWithInitializer, 3, ObjectBinding, OBJECT_BINDING, \ - "BindingOrBindingWithInitializer::ObjectBinding") - -const size_t BINAST_SUM_BINDING_OR_BINDING_WITH_INITIALIZER_LIMIT = 4; - -// Iteration through the interfaces of sum BindingPattern -#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_PATTERN(F) \ - F(BindingPattern, 0, ArrayBinding, ARRAY_BINDING, \ - "BindingPattern::ArrayBinding") \ - F(BindingPattern, 1, ObjectBinding, OBJECT_BINDING, \ - "BindingPattern::ObjectBinding") - -const size_t BINAST_SUM_BINDING_PATTERN_LIMIT = 2; - -// Iteration through the interfaces of sum BindingProperty -#define FOR_EACH_BIN_INTERFACE_IN_SUM_BINDING_PROPERTY(F) \ - F(BindingProperty, 0, BindingPropertyIdentifier, \ - BINDING_PROPERTY_IDENTIFIER, "BindingProperty::BindingPropertyIdentifier") \ - F(BindingProperty, 1, BindingPropertyProperty, BINDING_PROPERTY_PROPERTY, \ - "BindingProperty::BindingPropertyProperty") - -const size_t BINAST_SUM_BINDING_PROPERTY_LIMIT = 2; - -// Iteration through the interfaces of sum -// ClassDeclarationOrExpressionOrFunctionDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION( \ - F) \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 0, ArrayExpression, \ - ARRAY_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::ArrayExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 1, \ - AssignmentExpression, ASSIGNMENT_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::AssignmentExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 2, AwaitExpression, \ - AWAIT_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::AwaitExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 3, BinaryExpression, \ - BINARY_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::BinaryExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 4, CallExpression, \ - CALL_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::CallExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 5, ClassDeclaration, \ - CLASS_DECLARATION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::ClassDeclaration") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 6, ClassExpression, \ - CLASS_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::ClassExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 7, \ - CompoundAssignmentExpression, COMPOUND_ASSIGNMENT_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "CompoundAssignmentExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 8, \ - ComputedMemberExpression, COMPUTED_MEMBER_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "ComputedMemberExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 9, \ - ConditionalExpression, CONDITIONAL_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "ConditionalExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 10, \ - EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "EagerArrowExpressionWithExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 11, \ - EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "EagerArrowExpressionWithFunctionBody") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 12, \ - EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "EagerFunctionDeclaration") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 13, \ - EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "EagerFunctionExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 14, \ - IdentifierExpression, IDENTIFIER_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::IdentifierExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 15, \ - LazyArrowExpressionWithExpression, LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LazyArrowExpressionWithExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 16, \ - LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LazyArrowExpressionWithFunctionBody") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 17, \ - LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LazyFunctionDeclaration") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 18, \ - LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LazyFunctionExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 19, \ - LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralBooleanExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 20, \ - LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralInfinityExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 21, \ - LiteralNullExpression, LITERAL_NULL_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralNullExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 22, \ - LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralNumericExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 23, \ - LiteralRegExpExpression, LITERAL_REG_EXP_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralRegExpExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 24, \ - LiteralStringExpression, LITERAL_STRING_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "LiteralStringExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 25, NewExpression, \ - NEW_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::NewExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 26, \ - NewTargetExpression, NEW_TARGET_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::NewTargetExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 27, ObjectExpression, \ - OBJECT_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::ObjectExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 28, \ - StaticMemberExpression, STATIC_MEMBER_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::" \ - "StaticMemberExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 29, TemplateExpression, \ - TEMPLATE_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::TemplateExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 30, ThisExpression, \ - THIS_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::ThisExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 31, UnaryExpression, \ - UNARY_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::UnaryExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 32, UpdateExpression, \ - UPDATE_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::UpdateExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 33, YieldExpression, \ - YIELD_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::YieldExpression") \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, 34, \ - YieldStarExpression, YIELD_STAR_EXPRESSION, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration::YieldStarExpression") - -const size_t - BINAST_SUM_CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION_LIMIT = - 35; - -// Iteration through the interfaces of sum -// ClassDeclarationOrFunctionDeclarationOrVariableDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION( \ - F) \ - F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 0, \ - ClassDeclaration, CLASS_DECLARATION, \ - "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::" \ - "ClassDeclaration") \ - F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 1, \ - EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION, \ - "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::" \ - "EagerFunctionDeclaration") \ - F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 2, \ - LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION, \ - "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::" \ - "LazyFunctionDeclaration") \ - F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, 3, \ - VariableDeclaration, VARIABLE_DECLARATION, \ - "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration::" \ - "VariableDeclaration") - -const size_t - BINAST_SUM_CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION_LIMIT = - 4; - -// Iteration through the interfaces of sum ExportDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPORT_DECLARATION(F) \ - F(ExportDeclaration, 0, Export, EXPORT, "ExportDeclaration::Export") \ - F(ExportDeclaration, 1, ExportAllFrom, EXPORT_ALL_FROM, \ - "ExportDeclaration::ExportAllFrom") \ - F(ExportDeclaration, 2, ExportDefault, EXPORT_DEFAULT, \ - "ExportDeclaration::ExportDefault") \ - F(ExportDeclaration, 3, ExportFrom, EXPORT_FROM, \ - "ExportDeclaration::ExportFrom") \ - F(ExportDeclaration, 4, ExportLocals, EXPORT_LOCALS, \ - "ExportDeclaration::ExportLocals") - -const size_t BINAST_SUM_EXPORT_DECLARATION_LIMIT = 5; - -// Iteration through the interfaces of sum -// ExportDeclarationOrImportDeclarationOrStatement -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT( \ - F) \ - F(ExportDeclarationOrImportDeclarationOrStatement, 0, Block, BLOCK, \ - "ExportDeclarationOrImportDeclarationOrStatement::Block") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 1, BreakStatement, \ - BREAK_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::BreakStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 2, ClassDeclaration, \ - CLASS_DECLARATION, \ - "ExportDeclarationOrImportDeclarationOrStatement::ClassDeclaration") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 3, ContinueStatement, \ - CONTINUE_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ContinueStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 4, DebuggerStatement, \ - DEBUGGER_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::DebuggerStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 5, DoWhileStatement, \ - DO_WHILE_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::DoWhileStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 6, \ - EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION, \ - "ExportDeclarationOrImportDeclarationOrStatement::" \ - "EagerFunctionDeclaration") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 7, EmptyStatement, \ - EMPTY_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::EmptyStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 8, Export, EXPORT, \ - "ExportDeclarationOrImportDeclarationOrStatement::Export") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 9, ExportAllFrom, \ - EXPORT_ALL_FROM, \ - "ExportDeclarationOrImportDeclarationOrStatement::ExportAllFrom") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 10, ExportDefault, \ - EXPORT_DEFAULT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ExportDefault") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 11, ExportFrom, \ - EXPORT_FROM, \ - "ExportDeclarationOrImportDeclarationOrStatement::ExportFrom") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 12, ExportLocals, \ - EXPORT_LOCALS, \ - "ExportDeclarationOrImportDeclarationOrStatement::ExportLocals") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 13, ExpressionStatement, \ - EXPRESSION_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ExpressionStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 14, ForInStatement, \ - FOR_IN_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ForInStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 15, ForOfStatement, \ - FOR_OF_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ForOfStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 16, ForStatement, \ - FOR_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ForStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 17, IfStatement, \ - IF_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::IfStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 18, Import, IMPORT, \ - "ExportDeclarationOrImportDeclarationOrStatement::Import") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 19, ImportNamespace, \ - IMPORT_NAMESPACE, \ - "ExportDeclarationOrImportDeclarationOrStatement::ImportNamespace") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 20, LabelledStatement, \ - LABELLED_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::LabelledStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 21, \ - LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION, \ - "ExportDeclarationOrImportDeclarationOrStatement::" \ - "LazyFunctionDeclaration") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 22, ReturnStatement, \ - RETURN_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ReturnStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 23, SwitchStatement, \ - SWITCH_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::SwitchStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 24, \ - SwitchStatementWithDefault, SWITCH_STATEMENT_WITH_DEFAULT, \ - "ExportDeclarationOrImportDeclarationOrStatement::" \ - "SwitchStatementWithDefault") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 25, ThrowStatement, \ - THROW_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::ThrowStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 26, TryCatchStatement, \ - TRY_CATCH_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::TryCatchStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 27, TryFinallyStatement, \ - TRY_FINALLY_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::TryFinallyStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 28, VariableDeclaration, \ - VARIABLE_DECLARATION, \ - "ExportDeclarationOrImportDeclarationOrStatement::VariableDeclaration") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 29, WhileStatement, \ - WHILE_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::WhileStatement") \ - F(ExportDeclarationOrImportDeclarationOrStatement, 30, WithStatement, \ - WITH_STATEMENT, \ - "ExportDeclarationOrImportDeclarationOrStatement::WithStatement") - -const size_t - BINAST_SUM_EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT_LIMIT = 31; - -// Iteration through the interfaces of sum Expression -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION(F) \ - F(Expression, 0, ArrayExpression, ARRAY_EXPRESSION, \ - "Expression::ArrayExpression") \ - F(Expression, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION, \ - "Expression::AssignmentExpression") \ - F(Expression, 2, AwaitExpression, AWAIT_EXPRESSION, \ - "Expression::AwaitExpression") \ - F(Expression, 3, BinaryExpression, BINARY_EXPRESSION, \ - "Expression::BinaryExpression") \ - F(Expression, 4, CallExpression, CALL_EXPRESSION, \ - "Expression::CallExpression") \ - F(Expression, 5, ClassExpression, CLASS_EXPRESSION, \ - "Expression::ClassExpression") \ - F(Expression, 6, CompoundAssignmentExpression, \ - COMPOUND_ASSIGNMENT_EXPRESSION, \ - "Expression::CompoundAssignmentExpression") \ - F(Expression, 7, ComputedMemberExpression, COMPUTED_MEMBER_EXPRESSION, \ - "Expression::ComputedMemberExpression") \ - F(Expression, 8, ConditionalExpression, CONDITIONAL_EXPRESSION, \ - "Expression::ConditionalExpression") \ - F(Expression, 9, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "Expression::EagerArrowExpressionWithExpression") \ - F(Expression, 10, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "Expression::EagerArrowExpressionWithFunctionBody") \ - F(Expression, 11, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \ - "Expression::EagerFunctionExpression") \ - F(Expression, 12, IdentifierExpression, IDENTIFIER_EXPRESSION, \ - "Expression::IdentifierExpression") \ - F(Expression, 13, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "Expression::LazyArrowExpressionWithExpression") \ - F(Expression, 14, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "Expression::LazyArrowExpressionWithFunctionBody") \ - F(Expression, 15, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION, \ - "Expression::LazyFunctionExpression") \ - F(Expression, 16, LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION, \ - "Expression::LiteralBooleanExpression") \ - F(Expression, 17, LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION, \ - "Expression::LiteralInfinityExpression") \ - F(Expression, 18, LiteralNullExpression, LITERAL_NULL_EXPRESSION, \ - "Expression::LiteralNullExpression") \ - F(Expression, 19, LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION, \ - "Expression::LiteralNumericExpression") \ - F(Expression, 20, LiteralRegExpExpression, LITERAL_REG_EXP_EXPRESSION, \ - "Expression::LiteralRegExpExpression") \ - F(Expression, 21, LiteralStringExpression, LITERAL_STRING_EXPRESSION, \ - "Expression::LiteralStringExpression") \ - F(Expression, 22, NewExpression, NEW_EXPRESSION, \ - "Expression::NewExpression") \ - F(Expression, 23, NewTargetExpression, NEW_TARGET_EXPRESSION, \ - "Expression::NewTargetExpression") \ - F(Expression, 24, ObjectExpression, OBJECT_EXPRESSION, \ - "Expression::ObjectExpression") \ - F(Expression, 25, StaticMemberExpression, STATIC_MEMBER_EXPRESSION, \ - "Expression::StaticMemberExpression") \ - F(Expression, 26, TemplateExpression, TEMPLATE_EXPRESSION, \ - "Expression::TemplateExpression") \ - F(Expression, 27, ThisExpression, THIS_EXPRESSION, \ - "Expression::ThisExpression") \ - F(Expression, 28, UnaryExpression, UNARY_EXPRESSION, \ - "Expression::UnaryExpression") \ - F(Expression, 29, UpdateExpression, UPDATE_EXPRESSION, \ - "Expression::UpdateExpression") \ - F(Expression, 30, YieldExpression, YIELD_EXPRESSION, \ - "Expression::YieldExpression") \ - F(Expression, 31, YieldStarExpression, YIELD_STAR_EXPRESSION, \ - "Expression::YieldStarExpression") - -const size_t BINAST_SUM_EXPRESSION_LIMIT = 32; - -// Iteration through the interfaces of sum ExpressionOrSpreadElement -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_SPREAD_ELEMENT(F) \ - F(ExpressionOrSpreadElement, 0, ArrayExpression, ARRAY_EXPRESSION, \ - "ExpressionOrSpreadElement::ArrayExpression") \ - F(ExpressionOrSpreadElement, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION, \ - "ExpressionOrSpreadElement::AssignmentExpression") \ - F(ExpressionOrSpreadElement, 2, AwaitExpression, AWAIT_EXPRESSION, \ - "ExpressionOrSpreadElement::AwaitExpression") \ - F(ExpressionOrSpreadElement, 3, BinaryExpression, BINARY_EXPRESSION, \ - "ExpressionOrSpreadElement::BinaryExpression") \ - F(ExpressionOrSpreadElement, 4, CallExpression, CALL_EXPRESSION, \ - "ExpressionOrSpreadElement::CallExpression") \ - F(ExpressionOrSpreadElement, 5, ClassExpression, CLASS_EXPRESSION, \ - "ExpressionOrSpreadElement::ClassExpression") \ - F(ExpressionOrSpreadElement, 6, CompoundAssignmentExpression, \ - COMPOUND_ASSIGNMENT_EXPRESSION, \ - "ExpressionOrSpreadElement::CompoundAssignmentExpression") \ - F(ExpressionOrSpreadElement, 7, ComputedMemberExpression, \ - COMPUTED_MEMBER_EXPRESSION, \ - "ExpressionOrSpreadElement::ComputedMemberExpression") \ - F(ExpressionOrSpreadElement, 8, ConditionalExpression, \ - CONDITIONAL_EXPRESSION, \ - "ExpressionOrSpreadElement::ConditionalExpression") \ - F(ExpressionOrSpreadElement, 9, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrSpreadElement::EagerArrowExpressionWithExpression") \ - F(ExpressionOrSpreadElement, 10, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrSpreadElement::EagerArrowExpressionWithFunctionBody") \ - F(ExpressionOrSpreadElement, 11, EagerFunctionExpression, \ - EAGER_FUNCTION_EXPRESSION, \ - "ExpressionOrSpreadElement::EagerFunctionExpression") \ - F(ExpressionOrSpreadElement, 12, IdentifierExpression, \ - IDENTIFIER_EXPRESSION, "ExpressionOrSpreadElement::IdentifierExpression") \ - F(ExpressionOrSpreadElement, 13, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrSpreadElement::LazyArrowExpressionWithExpression") \ - F(ExpressionOrSpreadElement, 14, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrSpreadElement::LazyArrowExpressionWithFunctionBody") \ - F(ExpressionOrSpreadElement, 15, LazyFunctionExpression, \ - LAZY_FUNCTION_EXPRESSION, \ - "ExpressionOrSpreadElement::LazyFunctionExpression") \ - F(ExpressionOrSpreadElement, 16, LiteralBooleanExpression, \ - LITERAL_BOOLEAN_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralBooleanExpression") \ - F(ExpressionOrSpreadElement, 17, LiteralInfinityExpression, \ - LITERAL_INFINITY_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralInfinityExpression") \ - F(ExpressionOrSpreadElement, 18, LiteralNullExpression, \ - LITERAL_NULL_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralNullExpression") \ - F(ExpressionOrSpreadElement, 19, LiteralNumericExpression, \ - LITERAL_NUMERIC_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralNumericExpression") \ - F(ExpressionOrSpreadElement, 20, LiteralRegExpExpression, \ - LITERAL_REG_EXP_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralRegExpExpression") \ - F(ExpressionOrSpreadElement, 21, LiteralStringExpression, \ - LITERAL_STRING_EXPRESSION, \ - "ExpressionOrSpreadElement::LiteralStringExpression") \ - F(ExpressionOrSpreadElement, 22, NewExpression, NEW_EXPRESSION, \ - "ExpressionOrSpreadElement::NewExpression") \ - F(ExpressionOrSpreadElement, 23, NewTargetExpression, NEW_TARGET_EXPRESSION, \ - "ExpressionOrSpreadElement::NewTargetExpression") \ - F(ExpressionOrSpreadElement, 24, ObjectExpression, OBJECT_EXPRESSION, \ - "ExpressionOrSpreadElement::ObjectExpression") \ - F(ExpressionOrSpreadElement, 25, SpreadElement, SPREAD_ELEMENT, \ - "ExpressionOrSpreadElement::SpreadElement") \ - F(ExpressionOrSpreadElement, 26, StaticMemberExpression, \ - STATIC_MEMBER_EXPRESSION, \ - "ExpressionOrSpreadElement::StaticMemberExpression") \ - F(ExpressionOrSpreadElement, 27, TemplateExpression, TEMPLATE_EXPRESSION, \ - "ExpressionOrSpreadElement::TemplateExpression") \ - F(ExpressionOrSpreadElement, 28, ThisExpression, THIS_EXPRESSION, \ - "ExpressionOrSpreadElement::ThisExpression") \ - F(ExpressionOrSpreadElement, 29, UnaryExpression, UNARY_EXPRESSION, \ - "ExpressionOrSpreadElement::UnaryExpression") \ - F(ExpressionOrSpreadElement, 30, UpdateExpression, UPDATE_EXPRESSION, \ - "ExpressionOrSpreadElement::UpdateExpression") \ - F(ExpressionOrSpreadElement, 31, YieldExpression, YIELD_EXPRESSION, \ - "ExpressionOrSpreadElement::YieldExpression") \ - F(ExpressionOrSpreadElement, 32, YieldStarExpression, YIELD_STAR_EXPRESSION, \ - "ExpressionOrSpreadElement::YieldStarExpression") - -const size_t BINAST_SUM_EXPRESSION_OR_SPREAD_ELEMENT_LIMIT = 33; - -// Iteration through the interfaces of sum ExpressionOrSuper -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_SUPER(F) \ - F(ExpressionOrSuper, 0, ArrayExpression, ARRAY_EXPRESSION, \ - "ExpressionOrSuper::ArrayExpression") \ - F(ExpressionOrSuper, 1, AssignmentExpression, ASSIGNMENT_EXPRESSION, \ - "ExpressionOrSuper::AssignmentExpression") \ - F(ExpressionOrSuper, 2, AwaitExpression, AWAIT_EXPRESSION, \ - "ExpressionOrSuper::AwaitExpression") \ - F(ExpressionOrSuper, 3, BinaryExpression, BINARY_EXPRESSION, \ - "ExpressionOrSuper::BinaryExpression") \ - F(ExpressionOrSuper, 4, CallExpression, CALL_EXPRESSION, \ - "ExpressionOrSuper::CallExpression") \ - F(ExpressionOrSuper, 5, ClassExpression, CLASS_EXPRESSION, \ - "ExpressionOrSuper::ClassExpression") \ - F(ExpressionOrSuper, 6, CompoundAssignmentExpression, \ - COMPOUND_ASSIGNMENT_EXPRESSION, \ - "ExpressionOrSuper::CompoundAssignmentExpression") \ - F(ExpressionOrSuper, 7, ComputedMemberExpression, \ - COMPUTED_MEMBER_EXPRESSION, "ExpressionOrSuper::ComputedMemberExpression") \ - F(ExpressionOrSuper, 8, ConditionalExpression, CONDITIONAL_EXPRESSION, \ - "ExpressionOrSuper::ConditionalExpression") \ - F(ExpressionOrSuper, 9, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrSuper::EagerArrowExpressionWithExpression") \ - F(ExpressionOrSuper, 10, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrSuper::EagerArrowExpressionWithFunctionBody") \ - F(ExpressionOrSuper, 11, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \ - "ExpressionOrSuper::EagerFunctionExpression") \ - F(ExpressionOrSuper, 12, IdentifierExpression, IDENTIFIER_EXPRESSION, \ - "ExpressionOrSuper::IdentifierExpression") \ - F(ExpressionOrSuper, 13, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrSuper::LazyArrowExpressionWithExpression") \ - F(ExpressionOrSuper, 14, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrSuper::LazyArrowExpressionWithFunctionBody") \ - F(ExpressionOrSuper, 15, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION, \ - "ExpressionOrSuper::LazyFunctionExpression") \ - F(ExpressionOrSuper, 16, LiteralBooleanExpression, \ - LITERAL_BOOLEAN_EXPRESSION, "ExpressionOrSuper::LiteralBooleanExpression") \ - F(ExpressionOrSuper, 17, LiteralInfinityExpression, \ - LITERAL_INFINITY_EXPRESSION, \ - "ExpressionOrSuper::LiteralInfinityExpression") \ - F(ExpressionOrSuper, 18, LiteralNullExpression, LITERAL_NULL_EXPRESSION, \ - "ExpressionOrSuper::LiteralNullExpression") \ - F(ExpressionOrSuper, 19, LiteralNumericExpression, \ - LITERAL_NUMERIC_EXPRESSION, "ExpressionOrSuper::LiteralNumericExpression") \ - F(ExpressionOrSuper, 20, LiteralRegExpExpression, \ - LITERAL_REG_EXP_EXPRESSION, "ExpressionOrSuper::LiteralRegExpExpression") \ - F(ExpressionOrSuper, 21, LiteralStringExpression, LITERAL_STRING_EXPRESSION, \ - "ExpressionOrSuper::LiteralStringExpression") \ - F(ExpressionOrSuper, 22, NewExpression, NEW_EXPRESSION, \ - "ExpressionOrSuper::NewExpression") \ - F(ExpressionOrSuper, 23, NewTargetExpression, NEW_TARGET_EXPRESSION, \ - "ExpressionOrSuper::NewTargetExpression") \ - F(ExpressionOrSuper, 24, ObjectExpression, OBJECT_EXPRESSION, \ - "ExpressionOrSuper::ObjectExpression") \ - F(ExpressionOrSuper, 25, StaticMemberExpression, STATIC_MEMBER_EXPRESSION, \ - "ExpressionOrSuper::StaticMemberExpression") \ - F(ExpressionOrSuper, 26, Super, SUPER, "ExpressionOrSuper::Super") \ - F(ExpressionOrSuper, 27, TemplateExpression, TEMPLATE_EXPRESSION, \ - "ExpressionOrSuper::TemplateExpression") \ - F(ExpressionOrSuper, 28, ThisExpression, THIS_EXPRESSION, \ - "ExpressionOrSuper::ThisExpression") \ - F(ExpressionOrSuper, 29, UnaryExpression, UNARY_EXPRESSION, \ - "ExpressionOrSuper::UnaryExpression") \ - F(ExpressionOrSuper, 30, UpdateExpression, UPDATE_EXPRESSION, \ - "ExpressionOrSuper::UpdateExpression") \ - F(ExpressionOrSuper, 31, YieldExpression, YIELD_EXPRESSION, \ - "ExpressionOrSuper::YieldExpression") \ - F(ExpressionOrSuper, 32, YieldStarExpression, YIELD_STAR_EXPRESSION, \ - "ExpressionOrSuper::YieldStarExpression") - -const size_t BINAST_SUM_EXPRESSION_OR_SUPER_LIMIT = 33; - -// Iteration through the interfaces of sum ExpressionOrTemplateElement -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_TEMPLATE_ELEMENT(F) \ - F(ExpressionOrTemplateElement, 0, ArrayExpression, ARRAY_EXPRESSION, \ - "ExpressionOrTemplateElement::ArrayExpression") \ - F(ExpressionOrTemplateElement, 1, AssignmentExpression, \ - ASSIGNMENT_EXPRESSION, \ - "ExpressionOrTemplateElement::AssignmentExpression") \ - F(ExpressionOrTemplateElement, 2, AwaitExpression, AWAIT_EXPRESSION, \ - "ExpressionOrTemplateElement::AwaitExpression") \ - F(ExpressionOrTemplateElement, 3, BinaryExpression, BINARY_EXPRESSION, \ - "ExpressionOrTemplateElement::BinaryExpression") \ - F(ExpressionOrTemplateElement, 4, CallExpression, CALL_EXPRESSION, \ - "ExpressionOrTemplateElement::CallExpression") \ - F(ExpressionOrTemplateElement, 5, ClassExpression, CLASS_EXPRESSION, \ - "ExpressionOrTemplateElement::ClassExpression") \ - F(ExpressionOrTemplateElement, 6, CompoundAssignmentExpression, \ - COMPOUND_ASSIGNMENT_EXPRESSION, \ - "ExpressionOrTemplateElement::CompoundAssignmentExpression") \ - F(ExpressionOrTemplateElement, 7, ComputedMemberExpression, \ - COMPUTED_MEMBER_EXPRESSION, \ - "ExpressionOrTemplateElement::ComputedMemberExpression") \ - F(ExpressionOrTemplateElement, 8, ConditionalExpression, \ - CONDITIONAL_EXPRESSION, \ - "ExpressionOrTemplateElement::ConditionalExpression") \ - F(ExpressionOrTemplateElement, 9, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrTemplateElement::EagerArrowExpressionWithExpression") \ - F(ExpressionOrTemplateElement, 10, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrTemplateElement::EagerArrowExpressionWithFunctionBody") \ - F(ExpressionOrTemplateElement, 11, EagerFunctionExpression, \ - EAGER_FUNCTION_EXPRESSION, \ - "ExpressionOrTemplateElement::EagerFunctionExpression") \ - F(ExpressionOrTemplateElement, 12, IdentifierExpression, \ - IDENTIFIER_EXPRESSION, \ - "ExpressionOrTemplateElement::IdentifierExpression") \ - F(ExpressionOrTemplateElement, 13, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrTemplateElement::LazyArrowExpressionWithExpression") \ - F(ExpressionOrTemplateElement, 14, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrTemplateElement::LazyArrowExpressionWithFunctionBody") \ - F(ExpressionOrTemplateElement, 15, LazyFunctionExpression, \ - LAZY_FUNCTION_EXPRESSION, \ - "ExpressionOrTemplateElement::LazyFunctionExpression") \ - F(ExpressionOrTemplateElement, 16, LiteralBooleanExpression, \ - LITERAL_BOOLEAN_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralBooleanExpression") \ - F(ExpressionOrTemplateElement, 17, LiteralInfinityExpression, \ - LITERAL_INFINITY_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralInfinityExpression") \ - F(ExpressionOrTemplateElement, 18, LiteralNullExpression, \ - LITERAL_NULL_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralNullExpression") \ - F(ExpressionOrTemplateElement, 19, LiteralNumericExpression, \ - LITERAL_NUMERIC_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralNumericExpression") \ - F(ExpressionOrTemplateElement, 20, LiteralRegExpExpression, \ - LITERAL_REG_EXP_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralRegExpExpression") \ - F(ExpressionOrTemplateElement, 21, LiteralStringExpression, \ - LITERAL_STRING_EXPRESSION, \ - "ExpressionOrTemplateElement::LiteralStringExpression") \ - F(ExpressionOrTemplateElement, 22, NewExpression, NEW_EXPRESSION, \ - "ExpressionOrTemplateElement::NewExpression") \ - F(ExpressionOrTemplateElement, 23, NewTargetExpression, \ - NEW_TARGET_EXPRESSION, "ExpressionOrTemplateElement::NewTargetExpression") \ - F(ExpressionOrTemplateElement, 24, ObjectExpression, OBJECT_EXPRESSION, \ - "ExpressionOrTemplateElement::ObjectExpression") \ - F(ExpressionOrTemplateElement, 25, StaticMemberExpression, \ - STATIC_MEMBER_EXPRESSION, \ - "ExpressionOrTemplateElement::StaticMemberExpression") \ - F(ExpressionOrTemplateElement, 26, TemplateElement, TEMPLATE_ELEMENT, \ - "ExpressionOrTemplateElement::TemplateElement") \ - F(ExpressionOrTemplateElement, 27, TemplateExpression, TEMPLATE_EXPRESSION, \ - "ExpressionOrTemplateElement::TemplateExpression") \ - F(ExpressionOrTemplateElement, 28, ThisExpression, THIS_EXPRESSION, \ - "ExpressionOrTemplateElement::ThisExpression") \ - F(ExpressionOrTemplateElement, 29, UnaryExpression, UNARY_EXPRESSION, \ - "ExpressionOrTemplateElement::UnaryExpression") \ - F(ExpressionOrTemplateElement, 30, UpdateExpression, UPDATE_EXPRESSION, \ - "ExpressionOrTemplateElement::UpdateExpression") \ - F(ExpressionOrTemplateElement, 31, YieldExpression, YIELD_EXPRESSION, \ - "ExpressionOrTemplateElement::YieldExpression") \ - F(ExpressionOrTemplateElement, 32, YieldStarExpression, \ - YIELD_STAR_EXPRESSION, "ExpressionOrTemplateElement::YieldStarExpression") - -const size_t BINAST_SUM_EXPRESSION_OR_TEMPLATE_ELEMENT_LIMIT = 33; - -// Iteration through the interfaces of sum ExpressionOrVariableDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_EXPRESSION_OR_VARIABLE_DECLARATION(F) \ - F(ExpressionOrVariableDeclaration, 0, ArrayExpression, ARRAY_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ArrayExpression") \ - F(ExpressionOrVariableDeclaration, 1, AssignmentExpression, \ - ASSIGNMENT_EXPRESSION, \ - "ExpressionOrVariableDeclaration::AssignmentExpression") \ - F(ExpressionOrVariableDeclaration, 2, AwaitExpression, AWAIT_EXPRESSION, \ - "ExpressionOrVariableDeclaration::AwaitExpression") \ - F(ExpressionOrVariableDeclaration, 3, BinaryExpression, BINARY_EXPRESSION, \ - "ExpressionOrVariableDeclaration::BinaryExpression") \ - F(ExpressionOrVariableDeclaration, 4, CallExpression, CALL_EXPRESSION, \ - "ExpressionOrVariableDeclaration::CallExpression") \ - F(ExpressionOrVariableDeclaration, 5, ClassExpression, CLASS_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ClassExpression") \ - F(ExpressionOrVariableDeclaration, 6, CompoundAssignmentExpression, \ - COMPOUND_ASSIGNMENT_EXPRESSION, \ - "ExpressionOrVariableDeclaration::CompoundAssignmentExpression") \ - F(ExpressionOrVariableDeclaration, 7, ComputedMemberExpression, \ - COMPUTED_MEMBER_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ComputedMemberExpression") \ - F(ExpressionOrVariableDeclaration, 8, ConditionalExpression, \ - CONDITIONAL_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ConditionalExpression") \ - F(ExpressionOrVariableDeclaration, 9, EagerArrowExpressionWithExpression, \ - EAGER_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrVariableDeclaration::EagerArrowExpressionWithExpression") \ - F(ExpressionOrVariableDeclaration, 10, EagerArrowExpressionWithFunctionBody, \ - EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrVariableDeclaration::EagerArrowExpressionWithFunctionBody") \ - F(ExpressionOrVariableDeclaration, 11, EagerFunctionExpression, \ - EAGER_FUNCTION_EXPRESSION, \ - "ExpressionOrVariableDeclaration::EagerFunctionExpression") \ - F(ExpressionOrVariableDeclaration, 12, IdentifierExpression, \ - IDENTIFIER_EXPRESSION, \ - "ExpressionOrVariableDeclaration::IdentifierExpression") \ - F(ExpressionOrVariableDeclaration, 13, LazyArrowExpressionWithExpression, \ - LAZY_ARROW_EXPRESSION_WITH_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LazyArrowExpressionWithExpression") \ - F(ExpressionOrVariableDeclaration, 14, LazyArrowExpressionWithFunctionBody, \ - LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY, \ - "ExpressionOrVariableDeclaration::LazyArrowExpressionWithFunctionBody") \ - F(ExpressionOrVariableDeclaration, 15, LazyFunctionExpression, \ - LAZY_FUNCTION_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LazyFunctionExpression") \ - F(ExpressionOrVariableDeclaration, 16, LiteralBooleanExpression, \ - LITERAL_BOOLEAN_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralBooleanExpression") \ - F(ExpressionOrVariableDeclaration, 17, LiteralInfinityExpression, \ - LITERAL_INFINITY_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralInfinityExpression") \ - F(ExpressionOrVariableDeclaration, 18, LiteralNullExpression, \ - LITERAL_NULL_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralNullExpression") \ - F(ExpressionOrVariableDeclaration, 19, LiteralNumericExpression, \ - LITERAL_NUMERIC_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralNumericExpression") \ - F(ExpressionOrVariableDeclaration, 20, LiteralRegExpExpression, \ - LITERAL_REG_EXP_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralRegExpExpression") \ - F(ExpressionOrVariableDeclaration, 21, LiteralStringExpression, \ - LITERAL_STRING_EXPRESSION, \ - "ExpressionOrVariableDeclaration::LiteralStringExpression") \ - F(ExpressionOrVariableDeclaration, 22, NewExpression, NEW_EXPRESSION, \ - "ExpressionOrVariableDeclaration::NewExpression") \ - F(ExpressionOrVariableDeclaration, 23, NewTargetExpression, \ - NEW_TARGET_EXPRESSION, \ - "ExpressionOrVariableDeclaration::NewTargetExpression") \ - F(ExpressionOrVariableDeclaration, 24, ObjectExpression, OBJECT_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ObjectExpression") \ - F(ExpressionOrVariableDeclaration, 25, StaticMemberExpression, \ - STATIC_MEMBER_EXPRESSION, \ - "ExpressionOrVariableDeclaration::StaticMemberExpression") \ - F(ExpressionOrVariableDeclaration, 26, TemplateExpression, \ - TEMPLATE_EXPRESSION, \ - "ExpressionOrVariableDeclaration::TemplateExpression") \ - F(ExpressionOrVariableDeclaration, 27, ThisExpression, THIS_EXPRESSION, \ - "ExpressionOrVariableDeclaration::ThisExpression") \ - F(ExpressionOrVariableDeclaration, 28, UnaryExpression, UNARY_EXPRESSION, \ - "ExpressionOrVariableDeclaration::UnaryExpression") \ - F(ExpressionOrVariableDeclaration, 29, UpdateExpression, UPDATE_EXPRESSION, \ - "ExpressionOrVariableDeclaration::UpdateExpression") \ - F(ExpressionOrVariableDeclaration, 30, VariableDeclaration, \ - VARIABLE_DECLARATION, \ - "ExpressionOrVariableDeclaration::VariableDeclaration") \ - F(ExpressionOrVariableDeclaration, 31, YieldExpression, YIELD_EXPRESSION, \ - "ExpressionOrVariableDeclaration::YieldExpression") \ - F(ExpressionOrVariableDeclaration, 32, YieldStarExpression, \ - YIELD_STAR_EXPRESSION, \ - "ExpressionOrVariableDeclaration::YieldStarExpression") - -const size_t BINAST_SUM_EXPRESSION_OR_VARIABLE_DECLARATION_LIMIT = 33; - -// Iteration through the interfaces of sum FunctionDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_FUNCTION_DECLARATION(F) \ - F(FunctionDeclaration, 0, EagerFunctionDeclaration, \ - EAGER_FUNCTION_DECLARATION, \ - "FunctionDeclaration::EagerFunctionDeclaration") \ - F(FunctionDeclaration, 1, LazyFunctionDeclaration, \ - LAZY_FUNCTION_DECLARATION, "FunctionDeclaration::LazyFunctionDeclaration") - -const size_t BINAST_SUM_FUNCTION_DECLARATION_LIMIT = 2; - -// Iteration through the interfaces of sum FunctionExpression -#define FOR_EACH_BIN_INTERFACE_IN_SUM_FUNCTION_EXPRESSION(F) \ - F(FunctionExpression, 0, EagerFunctionExpression, EAGER_FUNCTION_EXPRESSION, \ - "FunctionExpression::EagerFunctionExpression") \ - F(FunctionExpression, 1, LazyFunctionExpression, LAZY_FUNCTION_EXPRESSION, \ - "FunctionExpression::LazyFunctionExpression") - -const size_t BINAST_SUM_FUNCTION_EXPRESSION_LIMIT = 2; - -// Iteration through the interfaces of sum Getter -#define FOR_EACH_BIN_INTERFACE_IN_SUM_GETTER(F) \ - F(Getter, 0, EagerGetter, EAGER_GETTER, "Getter::EagerGetter") \ - F(Getter, 1, LazyGetter, LAZY_GETTER, "Getter::LazyGetter") - -const size_t BINAST_SUM_GETTER_LIMIT = 2; - -// Iteration through the interfaces of sum ImportDeclaration -#define FOR_EACH_BIN_INTERFACE_IN_SUM_IMPORT_DECLARATION(F) \ - F(ImportDeclaration, 0, Import, IMPORT, "ImportDeclaration::Import") \ - F(ImportDeclaration, 1, ImportNamespace, IMPORT_NAMESPACE, \ - "ImportDeclaration::ImportNamespace") - -const size_t BINAST_SUM_IMPORT_DECLARATION_LIMIT = 2; - -// Iteration through the interfaces of sum IterationStatement -#define FOR_EACH_BIN_INTERFACE_IN_SUM_ITERATION_STATEMENT(F) \ - F(IterationStatement, 0, DoWhileStatement, DO_WHILE_STATEMENT, \ - "IterationStatement::DoWhileStatement") \ - F(IterationStatement, 1, ForInStatement, FOR_IN_STATEMENT, \ - "IterationStatement::ForInStatement") \ - F(IterationStatement, 2, ForOfStatement, FOR_OF_STATEMENT, \ - "IterationStatement::ForOfStatement") \ - F(IterationStatement, 3, ForStatement, FOR_STATEMENT, \ - "IterationStatement::ForStatement") \ - F(IterationStatement, 4, WhileStatement, WHILE_STATEMENT, \ - "IterationStatement::WhileStatement") - -const size_t BINAST_SUM_ITERATION_STATEMENT_LIMIT = 5; - -// Iteration through the interfaces of sum Literal -#define FOR_EACH_BIN_INTERFACE_IN_SUM_LITERAL(F) \ - F(Literal, 0, LiteralBooleanExpression, LITERAL_BOOLEAN_EXPRESSION, \ - "Literal::LiteralBooleanExpression") \ - F(Literal, 1, LiteralInfinityExpression, LITERAL_INFINITY_EXPRESSION, \ - "Literal::LiteralInfinityExpression") \ - F(Literal, 2, LiteralNullExpression, LITERAL_NULL_EXPRESSION, \ - "Literal::LiteralNullExpression") \ - F(Literal, 3, LiteralNumericExpression, LITERAL_NUMERIC_EXPRESSION, \ - "Literal::LiteralNumericExpression") \ - F(Literal, 4, LiteralStringExpression, LITERAL_STRING_EXPRESSION, \ - "Literal::LiteralStringExpression") - -const size_t BINAST_SUM_LITERAL_LIMIT = 5; - -// Iteration through the interfaces of sum Method -#define FOR_EACH_BIN_INTERFACE_IN_SUM_METHOD(F) \ - F(Method, 0, EagerMethod, EAGER_METHOD, "Method::EagerMethod") \ - F(Method, 1, LazyMethod, LAZY_METHOD, "Method::LazyMethod") - -const size_t BINAST_SUM_METHOD_LIMIT = 2; - -// Iteration through the interfaces of sum MethodDefinition -#define FOR_EACH_BIN_INTERFACE_IN_SUM_METHOD_DEFINITION(F) \ - F(MethodDefinition, 0, EagerGetter, EAGER_GETTER, \ - "MethodDefinition::EagerGetter") \ - F(MethodDefinition, 1, EagerMethod, EAGER_METHOD, \ - "MethodDefinition::EagerMethod") \ - F(MethodDefinition, 2, EagerSetter, EAGER_SETTER, \ - "MethodDefinition::EagerSetter") \ - F(MethodDefinition, 3, LazyGetter, LAZY_GETTER, \ - "MethodDefinition::LazyGetter") \ - F(MethodDefinition, 4, LazyMethod, LAZY_METHOD, \ - "MethodDefinition::LazyMethod") \ - F(MethodDefinition, 5, LazySetter, LAZY_SETTER, \ - "MethodDefinition::LazySetter") - -const size_t BINAST_SUM_METHOD_DEFINITION_LIMIT = 6; - -// Iteration through the interfaces of sum ObjectProperty -#define FOR_EACH_BIN_INTERFACE_IN_SUM_OBJECT_PROPERTY(F) \ - F(ObjectProperty, 0, DataProperty, DATA_PROPERTY, \ - "ObjectProperty::DataProperty") \ - F(ObjectProperty, 1, EagerGetter, EAGER_GETTER, \ - "ObjectProperty::EagerGetter") \ - F(ObjectProperty, 2, EagerMethod, EAGER_METHOD, \ - "ObjectProperty::EagerMethod") \ - F(ObjectProperty, 3, EagerSetter, EAGER_SETTER, \ - "ObjectProperty::EagerSetter") \ - F(ObjectProperty, 4, LazyGetter, LAZY_GETTER, "ObjectProperty::LazyGetter") \ - F(ObjectProperty, 5, LazyMethod, LAZY_METHOD, "ObjectProperty::LazyMethod") \ - F(ObjectProperty, 6, LazySetter, LAZY_SETTER, "ObjectProperty::LazySetter") \ - F(ObjectProperty, 7, ShorthandProperty, SHORTHAND_PROPERTY, \ - "ObjectProperty::ShorthandProperty") - -const size_t BINAST_SUM_OBJECT_PROPERTY_LIMIT = 8; - -// Iteration through the interfaces of sum Parameter -#define FOR_EACH_BIN_INTERFACE_IN_SUM_PARAMETER(F) \ - F(Parameter, 0, ArrayBinding, ARRAY_BINDING, "Parameter::ArrayBinding") \ - F(Parameter, 1, BindingIdentifier, BINDING_IDENTIFIER, \ - "Parameter::BindingIdentifier") \ - F(Parameter, 2, BindingWithInitializer, BINDING_WITH_INITIALIZER, \ - "Parameter::BindingWithInitializer") \ - F(Parameter, 3, ObjectBinding, OBJECT_BINDING, "Parameter::ObjectBinding") - -const size_t BINAST_SUM_PARAMETER_LIMIT = 4; - -// Iteration through the interfaces of sum Program -#define FOR_EACH_BIN_INTERFACE_IN_SUM_PROGRAM(F) \ - F(Program, 0, Module, MODULE, "Program::Module") \ - F(Program, 1, Script, SCRIPT, "Program::Script") - -const size_t BINAST_SUM_PROGRAM_LIMIT = 2; - -// Iteration through the interfaces of sum PropertyName -#define FOR_EACH_BIN_INTERFACE_IN_SUM_PROPERTY_NAME(F) \ - F(PropertyName, 0, ComputedPropertyName, COMPUTED_PROPERTY_NAME, \ - "PropertyName::ComputedPropertyName") \ - F(PropertyName, 1, LiteralPropertyName, LITERAL_PROPERTY_NAME, \ - "PropertyName::LiteralPropertyName") - -const size_t BINAST_SUM_PROPERTY_NAME_LIMIT = 2; - -// Iteration through the interfaces of sum Setter -#define FOR_EACH_BIN_INTERFACE_IN_SUM_SETTER(F) \ - F(Setter, 0, EagerSetter, EAGER_SETTER, "Setter::EagerSetter") \ - F(Setter, 1, LazySetter, LAZY_SETTER, "Setter::LazySetter") - -const size_t BINAST_SUM_SETTER_LIMIT = 2; - -// Iteration through the interfaces of sum SimpleAssignmentTarget -#define FOR_EACH_BIN_INTERFACE_IN_SUM_SIMPLE_ASSIGNMENT_TARGET(F) \ - F(SimpleAssignmentTarget, 0, AssignmentTargetIdentifier, \ - ASSIGNMENT_TARGET_IDENTIFIER, \ - "SimpleAssignmentTarget::AssignmentTargetIdentifier") \ - F(SimpleAssignmentTarget, 1, ComputedMemberAssignmentTarget, \ - COMPUTED_MEMBER_ASSIGNMENT_TARGET, \ - "SimpleAssignmentTarget::ComputedMemberAssignmentTarget") \ - F(SimpleAssignmentTarget, 2, StaticMemberAssignmentTarget, \ - STATIC_MEMBER_ASSIGNMENT_TARGET, \ - "SimpleAssignmentTarget::StaticMemberAssignmentTarget") - -const size_t BINAST_SUM_SIMPLE_ASSIGNMENT_TARGET_LIMIT = 3; - -// Iteration through the interfaces of sum Statement -#define FOR_EACH_BIN_INTERFACE_IN_SUM_STATEMENT(F) \ - F(Statement, 0, Block, BLOCK, "Statement::Block") \ - F(Statement, 1, BreakStatement, BREAK_STATEMENT, \ - "Statement::BreakStatement") \ - F(Statement, 2, ClassDeclaration, CLASS_DECLARATION, \ - "Statement::ClassDeclaration") \ - F(Statement, 3, ContinueStatement, CONTINUE_STATEMENT, \ - "Statement::ContinueStatement") \ - F(Statement, 4, DebuggerStatement, DEBUGGER_STATEMENT, \ - "Statement::DebuggerStatement") \ - F(Statement, 5, DoWhileStatement, DO_WHILE_STATEMENT, \ - "Statement::DoWhileStatement") \ - F(Statement, 6, EagerFunctionDeclaration, EAGER_FUNCTION_DECLARATION, \ - "Statement::EagerFunctionDeclaration") \ - F(Statement, 7, EmptyStatement, EMPTY_STATEMENT, \ - "Statement::EmptyStatement") \ - F(Statement, 8, ExpressionStatement, EXPRESSION_STATEMENT, \ - "Statement::ExpressionStatement") \ - F(Statement, 9, ForInStatement, FOR_IN_STATEMENT, \ - "Statement::ForInStatement") \ - F(Statement, 10, ForOfStatement, FOR_OF_STATEMENT, \ - "Statement::ForOfStatement") \ - F(Statement, 11, ForStatement, FOR_STATEMENT, "Statement::ForStatement") \ - F(Statement, 12, IfStatement, IF_STATEMENT, "Statement::IfStatement") \ - F(Statement, 13, LabelledStatement, LABELLED_STATEMENT, \ - "Statement::LabelledStatement") \ - F(Statement, 14, LazyFunctionDeclaration, LAZY_FUNCTION_DECLARATION, \ - "Statement::LazyFunctionDeclaration") \ - F(Statement, 15, ReturnStatement, RETURN_STATEMENT, \ - "Statement::ReturnStatement") \ - F(Statement, 16, SwitchStatement, SWITCH_STATEMENT, \ - "Statement::SwitchStatement") \ - F(Statement, 17, SwitchStatementWithDefault, SWITCH_STATEMENT_WITH_DEFAULT, \ - "Statement::SwitchStatementWithDefault") \ - F(Statement, 18, ThrowStatement, THROW_STATEMENT, \ - "Statement::ThrowStatement") \ - F(Statement, 19, TryCatchStatement, TRY_CATCH_STATEMENT, \ - "Statement::TryCatchStatement") \ - F(Statement, 20, TryFinallyStatement, TRY_FINALLY_STATEMENT, \ - "Statement::TryFinallyStatement") \ - F(Statement, 21, VariableDeclaration, VARIABLE_DECLARATION, \ - "Statement::VariableDeclaration") \ - F(Statement, 22, WhileStatement, WHILE_STATEMENT, \ - "Statement::WhileStatement") \ - F(Statement, 23, WithStatement, WITH_STATEMENT, "Statement::WithStatement") - -const size_t BINAST_SUM_STATEMENT_LIMIT = 24; - -// Strongly typed iterations through the fields of interfaces. -// -// Each of these macros accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as -// `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as -// `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as -// `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, -// element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as -// `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as -// `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called -// as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNINITIALIZED( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// Strongly typed iteration through the fields of interface _Null. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NULL( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface . -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NULL = 0; - -// Strongly typed iteration through the fields of interface -// ArrayAssignmentTarget. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_ASSIGNMENT_TARGET( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ArrayAssignmentTarget, Elements, 0, \ - LIST(ListOfAssignmentTargetOrAssignmentTargetWithInitializer, \ - SUM(AssignmentTargetOrAssignmentTargetWithInitializer)), \ - "ArrayAssignmentTarget::elements") \ - F(ArrayAssignmentTarget, Rest, 1, OPTIONAL_SUM(AssignmentTarget), \ - "ArrayAssignmentTarget::rest") - -// The number of fields of interface ArrayAssignmentTarget. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_ASSIGNMENT_TARGET = 2; - -// Strongly typed iteration through the fields of interface ArrayBinding. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_BINDING( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ArrayBinding, Elements, 0, \ - LIST(ListOfOptionalBindingOrBindingWithInitializer, \ - OPTIONAL_SUM(BindingOrBindingWithInitializer)), \ - "ArrayBinding::elements") \ - F(ArrayBinding, Rest, 1, OPTIONAL_SUM(Binding), "ArrayBinding::rest") - -// The number of fields of interface ArrayBinding. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_BINDING = 2; - -// Strongly typed iteration through the fields of interface ArrayExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARRAY_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ArrayExpression, Elements, 0, \ - LIST(ListOfOptionalExpressionOrSpreadElement, \ - OPTIONAL_SUM(ExpressionOrSpreadElement)), \ - "ArrayExpression::elements") - -// The number of fields of interface ArrayExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARRAY_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface -// ArrowExpressionContentsWithExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ArrowExpressionContentsWithExpression, ParameterScope, 0, \ - INTERFACE(AssertedParameterScope), \ - "ArrowExpressionContentsWithExpression::parameterScope") \ - F(ArrowExpressionContentsWithExpression, Params, 1, \ - INTERFACE(FormalParameters), \ - "ArrowExpressionContentsWithExpression::params") \ - F(ArrowExpressionContentsWithExpression, BodyScope, 2, \ - INTERFACE(AssertedVarScope), \ - "ArrowExpressionContentsWithExpression::bodyScope") \ - F(ArrowExpressionContentsWithExpression, Body, 3, SUM(Expression), \ - "ArrowExpressionContentsWithExpression::body") - -// The number of fields of interface ArrowExpressionContentsWithExpression. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_EXPRESSION = - 4; - -// Strongly typed iteration through the fields of interface -// ArrowExpressionContentsWithFunctionBody. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ArrowExpressionContentsWithFunctionBody, ParameterScope, 0, \ - INTERFACE(AssertedParameterScope), \ - "ArrowExpressionContentsWithFunctionBody::parameterScope") \ - F(ArrowExpressionContentsWithFunctionBody, Params, 1, \ - INTERFACE(FormalParameters), \ - "ArrowExpressionContentsWithFunctionBody::params") \ - F(ArrowExpressionContentsWithFunctionBody, BodyScope, 2, \ - INTERFACE(AssertedVarScope), \ - "ArrowExpressionContentsWithFunctionBody::bodyScope") \ - F(ArrowExpressionContentsWithFunctionBody, Body, 3, \ - LIST(ListOfStatement, SUM(Statement)), \ - "ArrowExpressionContentsWithFunctionBody::body") - -// The number of fields of interface ArrowExpressionContentsWithFunctionBody. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ARROW_EXPRESSION_CONTENTS_WITH_FUNCTION_BODY = - 4; - -// Strongly typed iteration through the fields of interface AssertedBlockScope. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BLOCK_SCOPE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedBlockScope, DeclaredNames, 0, \ - LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)), \ - "AssertedBlockScope::declaredNames") \ - F(AssertedBlockScope, HasDirectEval, 1, PRIMITIVE(Boolean), \ - "AssertedBlockScope::hasDirectEval") - -// The number of fields of interface AssertedBlockScope. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BLOCK_SCOPE = 2; - -// Strongly typed iteration through the fields of interface AssertedBoundName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BOUND_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedBoundName, Name, 0, PRIMITIVE(IdentifierName), \ - "AssertedBoundName::name") \ - F(AssertedBoundName, IsCaptured, 1, PRIMITIVE(Boolean), \ - "AssertedBoundName::isCaptured") - -// The number of fields of interface AssertedBoundName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BOUND_NAME = 2; - -// Strongly typed iteration through the fields of interface -// AssertedBoundNamesScope. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_BOUND_NAMES_SCOPE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedBoundNamesScope, BoundNames, 0, \ - LIST(ListOfAssertedBoundName, INTERFACE(AssertedBoundName)), \ - "AssertedBoundNamesScope::boundNames") \ - F(AssertedBoundNamesScope, HasDirectEval, 1, PRIMITIVE(Boolean), \ - "AssertedBoundNamesScope::hasDirectEval") - -// The number of fields of interface AssertedBoundNamesScope. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_BOUND_NAMES_SCOPE = - 2; - -// Strongly typed iteration through the fields of interface -// AssertedDeclaredName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_DECLARED_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedDeclaredName, Name, 0, PRIMITIVE(IdentifierName), \ - "AssertedDeclaredName::name") \ - F(AssertedDeclaredName, Kind, 1, STRING_ENUM(AssertedDeclaredKind), \ - "AssertedDeclaredName::kind") \ - F(AssertedDeclaredName, IsCaptured, 2, PRIMITIVE(Boolean), \ - "AssertedDeclaredName::isCaptured") - -// The number of fields of interface AssertedDeclaredName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_DECLARED_NAME = 3; - -// Strongly typed iteration through the fields of interface -// AssertedParameterName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_PARAMETER_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedParameterName, Name, 0, PRIMITIVE(IdentifierName), \ - "AssertedParameterName::name") \ - F(AssertedParameterName, IsCaptured, 1, PRIMITIVE(Boolean), \ - "AssertedParameterName::isCaptured") - -// The number of fields of interface AssertedParameterName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_PARAMETER_NAME = 2; - -// Strongly typed iteration through the fields of interface -// AssertedParameterScope. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_PARAMETER_SCOPE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedParameterScope, ParamNames, 0, \ - LIST(ListOfAssertedMaybePositionalParameterName, \ - SUM(AssertedMaybePositionalParameterName)), \ - "AssertedParameterScope::paramNames") \ - F(AssertedParameterScope, HasDirectEval, 1, PRIMITIVE(Boolean), \ - "AssertedParameterScope::hasDirectEval") \ - F(AssertedParameterScope, IsSimpleParameterList, 2, PRIMITIVE(Boolean), \ - "AssertedParameterScope::isSimpleParameterList") - -// The number of fields of interface AssertedParameterScope. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_PARAMETER_SCOPE = 3; - -// Strongly typed iteration through the fields of interface -// AssertedPositionalParameterName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_POSITIONAL_PARAMETER_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedPositionalParameterName, Index, 0, PRIMITIVE(UnsignedLong), \ - "AssertedPositionalParameterName::index") \ - F(AssertedPositionalParameterName, Name, 1, PRIMITIVE(IdentifierName), \ - "AssertedPositionalParameterName::name") \ - F(AssertedPositionalParameterName, IsCaptured, 2, PRIMITIVE(Boolean), \ - "AssertedPositionalParameterName::isCaptured") - -// The number of fields of interface AssertedPositionalParameterName. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_POSITIONAL_PARAMETER_NAME = 3; - -// Strongly typed iteration through the fields of interface -// AssertedRestParameterName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_REST_PARAMETER_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedRestParameterName, Name, 0, PRIMITIVE(IdentifierName), \ - "AssertedRestParameterName::name") \ - F(AssertedRestParameterName, IsCaptured, 1, PRIMITIVE(Boolean), \ - "AssertedRestParameterName::isCaptured") - -// The number of fields of interface AssertedRestParameterName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_REST_PARAMETER_NAME = - 2; - -// Strongly typed iteration through the fields of interface -// AssertedScriptGlobalScope. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_SCRIPT_GLOBAL_SCOPE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedScriptGlobalScope, DeclaredNames, 0, \ - LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)), \ - "AssertedScriptGlobalScope::declaredNames") \ - F(AssertedScriptGlobalScope, HasDirectEval, 1, PRIMITIVE(Boolean), \ - "AssertedScriptGlobalScope::hasDirectEval") - -// The number of fields of interface AssertedScriptGlobalScope. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_SCRIPT_GLOBAL_SCOPE = - 2; - -// Strongly typed iteration through the fields of interface AssertedVarScope. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSERTED_VAR_SCOPE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssertedVarScope, DeclaredNames, 0, \ - LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName)), \ - "AssertedVarScope::declaredNames") \ - F(AssertedVarScope, HasDirectEval, 1, PRIMITIVE(Boolean), \ - "AssertedVarScope::hasDirectEval") - -// The number of fields of interface AssertedVarScope. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSERTED_VAR_SCOPE = 2; - -// Strongly typed iteration through the fields of interface -// AssignmentExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssignmentExpression, Binding, 0, SUM(AssignmentTarget), \ - "AssignmentExpression::binding") \ - F(AssignmentExpression, Expression, 1, SUM(Expression), \ - "AssignmentExpression::expression") - -// The number of fields of interface AssignmentExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface -// AssignmentTargetIdentifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_IDENTIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssignmentTargetIdentifier, Name, 0, PRIMITIVE(IdentifierName), \ - "AssignmentTargetIdentifier::name") - -// The number of fields of interface AssignmentTargetIdentifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_IDENTIFIER = - 1; - -// Strongly typed iteration through the fields of interface -// AssignmentTargetPropertyIdentifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssignmentTargetPropertyIdentifier, Binding, 0, \ - INTERFACE(AssignmentTargetIdentifier), \ - "AssignmentTargetPropertyIdentifier::binding") \ - F(AssignmentTargetPropertyIdentifier, Init, 1, OPTIONAL_SUM(Expression), \ - "AssignmentTargetPropertyIdentifier::init") - -// The number of fields of interface AssignmentTargetPropertyIdentifier. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_IDENTIFIER = - 2; - -// Strongly typed iteration through the fields of interface -// AssignmentTargetPropertyProperty. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_PROPERTY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssignmentTargetPropertyProperty, Name, 0, SUM(PropertyName), \ - "AssignmentTargetPropertyProperty::name") \ - F(AssignmentTargetPropertyProperty, Binding, 1, \ - SUM(AssignmentTargetOrAssignmentTargetWithInitializer), \ - "AssignmentTargetPropertyProperty::binding") - -// The number of fields of interface AssignmentTargetPropertyProperty. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_PROPERTY_PROPERTY = - 2; - -// Strongly typed iteration through the fields of interface -// AssignmentTargetWithInitializer. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_ASSIGNMENT_TARGET_WITH_INITIALIZER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AssignmentTargetWithInitializer, Binding, 0, SUM(AssignmentTarget), \ - "AssignmentTargetWithInitializer::binding") \ - F(AssignmentTargetWithInitializer, Init, 1, SUM(Expression), \ - "AssignmentTargetWithInitializer::init") - -// The number of fields of interface AssignmentTargetWithInitializer. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_ASSIGNMENT_TARGET_WITH_INITIALIZER = 2; - -// Strongly typed iteration through the fields of interface AwaitExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_AWAIT_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(AwaitExpression, Expression, 0, SUM(Expression), \ - "AwaitExpression::expression") - -// The number of fields of interface AwaitExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_AWAIT_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface BinaryExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINARY_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BinaryExpression, Operator, 0, STRING_ENUM(BinaryOperator), \ - "BinaryExpression::operator") \ - F(BinaryExpression, Left, 1, SUM(Expression), "BinaryExpression::left") \ - F(BinaryExpression, Right, 2, SUM(Expression), "BinaryExpression::right") - -// The number of fields of interface BinaryExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINARY_EXPRESSION = 3; - -// Strongly typed iteration through the fields of interface BindingIdentifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_IDENTIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BindingIdentifier, Name, 0, PRIMITIVE(IdentifierName), \ - "BindingIdentifier::name") - -// The number of fields of interface BindingIdentifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_IDENTIFIER = 1; - -// Strongly typed iteration through the fields of interface -// BindingPropertyIdentifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_PROPERTY_IDENTIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BindingPropertyIdentifier, Binding, 0, INTERFACE(BindingIdentifier), \ - "BindingPropertyIdentifier::binding") \ - F(BindingPropertyIdentifier, Init, 1, OPTIONAL_SUM(Expression), \ - "BindingPropertyIdentifier::init") - -// The number of fields of interface BindingPropertyIdentifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_PROPERTY_IDENTIFIER = - 2; - -// Strongly typed iteration through the fields of interface -// BindingPropertyProperty. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_PROPERTY_PROPERTY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BindingPropertyProperty, Name, 0, SUM(PropertyName), \ - "BindingPropertyProperty::name") \ - F(BindingPropertyProperty, Binding, 1, SUM(BindingOrBindingWithInitializer), \ - "BindingPropertyProperty::binding") - -// The number of fields of interface BindingPropertyProperty. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_PROPERTY_PROPERTY = 2; - -// Strongly typed iteration through the fields of interface -// BindingWithInitializer. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BINDING_WITH_INITIALIZER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BindingWithInitializer, Binding, 0, SUM(Binding), \ - "BindingWithInitializer::binding") \ - F(BindingWithInitializer, Init, 1, SUM(Expression), \ - "BindingWithInitializer::init") - -// The number of fields of interface BindingWithInitializer. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BINDING_WITH_INITIALIZER = 2; - -// Strongly typed iteration through the fields of interface Block. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BLOCK( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Block, Scope, 0, INTERFACE(AssertedBlockScope), "Block::scope") \ - F(Block, Statements, 1, LIST(ListOfStatement, SUM(Statement)), \ - "Block::statements") - -// The number of fields of interface Block. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BLOCK = 2; - -// Strongly typed iteration through the fields of interface BreakStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_BREAK_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(BreakStatement, Label, 0, PRIMITIVE(MaybeString), "BreakStatement::label") - -// The number of fields of interface BreakStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_BREAK_STATEMENT = 1; - -// Strongly typed iteration through the fields of interface CallExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CALL_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(CallExpression, Callee, 0, SUM(ExpressionOrSuper), \ - "CallExpression::callee") \ - F(CallExpression, Arguments, 1, \ - LIST(Arguments, SUM(ExpressionOrSpreadElement)), \ - "CallExpression::arguments") - -// The number of fields of interface CallExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CALL_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface CatchClause. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CATCH_CLAUSE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(CatchClause, BindingScope, 0, INTERFACE(AssertedBoundNamesScope), \ - "CatchClause::bindingScope") \ - F(CatchClause, Binding, 1, SUM(Binding), "CatchClause::binding") \ - F(CatchClause, Body, 2, INTERFACE(Block), "CatchClause::body") - -// The number of fields of interface CatchClause. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CATCH_CLAUSE = 3; - -// Strongly typed iteration through the fields of interface ClassDeclaration. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_DECLARATION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ClassDeclaration, Name, 0, INTERFACE(BindingIdentifier), \ - "ClassDeclaration::name") \ - F(ClassDeclaration, Super, 1, OPTIONAL_SUM(Expression), \ - "ClassDeclaration::super") \ - F(ClassDeclaration, Elements, 2, \ - LIST(ListOfClassElement, INTERFACE(ClassElement)), \ - "ClassDeclaration::elements") - -// The number of fields of interface ClassDeclaration. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_DECLARATION = 3; - -// Strongly typed iteration through the fields of interface ClassElement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_ELEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ClassElement, IsStatic, 0, PRIMITIVE(Boolean), "ClassElement::isStatic") \ - F(ClassElement, Method, 1, SUM(MethodDefinition), "ClassElement::method") - -// The number of fields of interface ClassElement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_ELEMENT = 2; - -// Strongly typed iteration through the fields of interface ClassExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CLASS_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ClassExpression, Name, 0, OPTIONAL_INTERFACE(BindingIdentifier), \ - "ClassExpression::name") \ - F(ClassExpression, Super, 1, OPTIONAL_SUM(Expression), \ - "ClassExpression::super") \ - F(ClassExpression, Elements, 2, \ - LIST(ListOfClassElement, INTERFACE(ClassElement)), \ - "ClassExpression::elements") - -// The number of fields of interface ClassExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CLASS_EXPRESSION = 3; - -// Strongly typed iteration through the fields of interface -// CompoundAssignmentExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPOUND_ASSIGNMENT_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(CompoundAssignmentExpression, Operator, 0, \ - STRING_ENUM(CompoundAssignmentOperator), \ - "CompoundAssignmentExpression::operator") \ - F(CompoundAssignmentExpression, Binding, 1, SUM(SimpleAssignmentTarget), \ - "CompoundAssignmentExpression::binding") \ - F(CompoundAssignmentExpression, Expression, 2, SUM(Expression), \ - "CompoundAssignmentExpression::expression") - -// The number of fields of interface CompoundAssignmentExpression. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPOUND_ASSIGNMENT_EXPRESSION = 3; - -// Strongly typed iteration through the fields of interface -// ComputedMemberAssignmentTarget. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_MEMBER_ASSIGNMENT_TARGET( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ComputedMemberAssignmentTarget, Object, 0, SUM(ExpressionOrSuper), \ - "ComputedMemberAssignmentTarget::object") \ - F(ComputedMemberAssignmentTarget, Expression, 1, SUM(Expression), \ - "ComputedMemberAssignmentTarget::expression") - -// The number of fields of interface ComputedMemberAssignmentTarget. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_MEMBER_ASSIGNMENT_TARGET = 2; - -// Strongly typed iteration through the fields of interface -// ComputedMemberExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_MEMBER_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ComputedMemberExpression, Object, 0, SUM(ExpressionOrSuper), \ - "ComputedMemberExpression::object") \ - F(ComputedMemberExpression, Expression, 1, SUM(Expression), \ - "ComputedMemberExpression::expression") - -// The number of fields of interface ComputedMemberExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_MEMBER_EXPRESSION = - 2; - -// Strongly typed iteration through the fields of interface -// ComputedPropertyName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_COMPUTED_PROPERTY_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ComputedPropertyName, Expression, 0, SUM(Expression), \ - "ComputedPropertyName::expression") - -// The number of fields of interface ComputedPropertyName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_COMPUTED_PROPERTY_NAME = 1; - -// Strongly typed iteration through the fields of interface -// ConditionalExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CONDITIONAL_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ConditionalExpression, Test, 0, SUM(Expression), \ - "ConditionalExpression::test") \ - F(ConditionalExpression, Consequent, 1, SUM(Expression), \ - "ConditionalExpression::consequent") \ - F(ConditionalExpression, Alternate, 2, SUM(Expression), \ - "ConditionalExpression::alternate") - -// The number of fields of interface ConditionalExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CONDITIONAL_EXPRESSION = 3; - -// Strongly typed iteration through the fields of interface ContinueStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_CONTINUE_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ContinueStatement, Label, 0, PRIMITIVE(MaybeString), \ - "ContinueStatement::label") - -// The number of fields of interface ContinueStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_CONTINUE_STATEMENT = 1; - -// Strongly typed iteration through the fields of interface DataProperty. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DATA_PROPERTY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(DataProperty, Name, 0, SUM(PropertyName), "DataProperty::name") \ - F(DataProperty, Expression, 1, SUM(Expression), "DataProperty::expression") - -// The number of fields of interface DataProperty. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DATA_PROPERTY = 2; - -// Strongly typed iteration through the fields of interface DebuggerStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DEBUGGER_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface DebuggerStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DEBUGGER_STATEMENT = 0; - -// Strongly typed iteration through the fields of interface Directive. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DIRECTIVE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Directive, RawValue, 0, PRIMITIVE(String), "Directive::rawValue") - -// The number of fields of interface Directive. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DIRECTIVE = 1; - -// Strongly typed iteration through the fields of interface DoWhileStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_DO_WHILE_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(DoWhileStatement, Test, 0, SUM(Expression), "DoWhileStatement::test") \ - F(DoWhileStatement, Body, 1, SUM(Statement), "DoWhileStatement::body") - -// The number of fields of interface DoWhileStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_DO_WHILE_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface -// EagerArrowExpressionWithExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerArrowExpressionWithExpression, IsAsync, 0, PRIMITIVE(Boolean), \ - "EagerArrowExpressionWithExpression::isAsync") \ - F(EagerArrowExpressionWithExpression, Length, 1, PRIMITIVE(UnsignedLong), \ - "EagerArrowExpressionWithExpression::length") \ - F(EagerArrowExpressionWithExpression, Contents, 2, \ - INTERFACE(ArrowExpressionContentsWithExpression), \ - "EagerArrowExpressionWithExpression::contents") - -// The number of fields of interface EagerArrowExpressionWithExpression. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_EXPRESSION = - 3; - -// Strongly typed iteration through the fields of interface -// EagerArrowExpressionWithFunctionBody. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerArrowExpressionWithFunctionBody, IsAsync, 0, PRIMITIVE(Boolean), \ - "EagerArrowExpressionWithFunctionBody::isAsync") \ - F(EagerArrowExpressionWithFunctionBody, Length, 1, PRIMITIVE(UnsignedLong), \ - "EagerArrowExpressionWithFunctionBody::length") \ - F(EagerArrowExpressionWithFunctionBody, Directives, 2, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerArrowExpressionWithFunctionBody::directives") \ - F(EagerArrowExpressionWithFunctionBody, Contents, 3, \ - INTERFACE(ArrowExpressionContentsWithFunctionBody), \ - "EagerArrowExpressionWithFunctionBody::contents") - -// The number of fields of interface EagerArrowExpressionWithFunctionBody. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_ARROW_EXPRESSION_WITH_FUNCTION_BODY = - 4; - -// Strongly typed iteration through the fields of interface -// EagerFunctionDeclaration. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_FUNCTION_DECLARATION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerFunctionDeclaration, IsAsync, 0, PRIMITIVE(Boolean), \ - "EagerFunctionDeclaration::isAsync") \ - F(EagerFunctionDeclaration, IsGenerator, 1, PRIMITIVE(Boolean), \ - "EagerFunctionDeclaration::isGenerator") \ - F(EagerFunctionDeclaration, Name, 2, INTERFACE(BindingIdentifier), \ - "EagerFunctionDeclaration::name") \ - F(EagerFunctionDeclaration, Length, 3, PRIMITIVE(UnsignedLong), \ - "EagerFunctionDeclaration::length") \ - F(EagerFunctionDeclaration, Directives, 4, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerFunctionDeclaration::directives") \ - F(EagerFunctionDeclaration, Contents, 5, \ - INTERFACE(FunctionOrMethodContents), "EagerFunctionDeclaration::contents") - -// The number of fields of interface EagerFunctionDeclaration. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_FUNCTION_DECLARATION = - 6; - -// Strongly typed iteration through the fields of interface -// EagerFunctionExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_FUNCTION_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerFunctionExpression, IsAsync, 0, PRIMITIVE(Boolean), \ - "EagerFunctionExpression::isAsync") \ - F(EagerFunctionExpression, IsGenerator, 1, PRIMITIVE(Boolean), \ - "EagerFunctionExpression::isGenerator") \ - F(EagerFunctionExpression, Name, 2, OPTIONAL_INTERFACE(BindingIdentifier), \ - "EagerFunctionExpression::name") \ - F(EagerFunctionExpression, Length, 3, PRIMITIVE(UnsignedLong), \ - "EagerFunctionExpression::length") \ - F(EagerFunctionExpression, Directives, 4, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerFunctionExpression::directives") \ - F(EagerFunctionExpression, Contents, 5, \ - INTERFACE(FunctionExpressionContents), \ - "EagerFunctionExpression::contents") - -// The number of fields of interface EagerFunctionExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_FUNCTION_EXPRESSION = 6; - -// Strongly typed iteration through the fields of interface EagerGetter. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_GETTER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerGetter, Name, 0, SUM(PropertyName), "EagerGetter::name") \ - F(EagerGetter, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerGetter::directives") \ - F(EagerGetter, Contents, 2, INTERFACE(GetterContents), \ - "EagerGetter::contents") - -// The number of fields of interface EagerGetter. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_GETTER = 3; - -// Strongly typed iteration through the fields of interface EagerMethod. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_METHOD( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerMethod, IsAsync, 0, PRIMITIVE(Boolean), "EagerMethod::isAsync") \ - F(EagerMethod, IsGenerator, 1, PRIMITIVE(Boolean), \ - "EagerMethod::isGenerator") \ - F(EagerMethod, Name, 2, SUM(PropertyName), "EagerMethod::name") \ - F(EagerMethod, Length, 3, PRIMITIVE(UnsignedLong), "EagerMethod::length") \ - F(EagerMethod, Directives, 4, LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerMethod::directives") \ - F(EagerMethod, Contents, 5, INTERFACE(FunctionOrMethodContents), \ - "EagerMethod::contents") - -// The number of fields of interface EagerMethod. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_METHOD = 6; - -// Strongly typed iteration through the fields of interface EagerSetter. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EAGER_SETTER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(EagerSetter, Name, 0, SUM(PropertyName), "EagerSetter::name") \ - F(EagerSetter, Length, 1, PRIMITIVE(UnsignedLong), "EagerSetter::length") \ - F(EagerSetter, Directives, 2, LIST(ListOfDirective, INTERFACE(Directive)), \ - "EagerSetter::directives") \ - F(EagerSetter, Contents, 3, INTERFACE(SetterContents), \ - "EagerSetter::contents") - -// The number of fields of interface EagerSetter. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EAGER_SETTER = 4; - -// Strongly typed iteration through the fields of interface EmptyStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EMPTY_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface EmptyStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EMPTY_STATEMENT = 0; - -// Strongly typed iteration through the fields of interface Export. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Export, Declaration, 0, \ - SUM(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration), \ - "Export::declaration") - -// The number of fields of interface Export. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT = 1; - -// Strongly typed iteration through the fields of interface ExportAllFrom. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_ALL_FROM( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportAllFrom, ModuleSpecifier, 0, PRIMITIVE(String), \ - "ExportAllFrom::moduleSpecifier") - -// The number of fields of interface ExportAllFrom. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_ALL_FROM = 1; - -// Strongly typed iteration through the fields of interface ExportDefault. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_DEFAULT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportDefault, Body, 0, \ - SUM(ClassDeclarationOrExpressionOrFunctionDeclaration), \ - "ExportDefault::body") - -// The number of fields of interface ExportDefault. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_DEFAULT = 1; - -// Strongly typed iteration through the fields of interface ExportFrom. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_FROM( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportFrom, NamedExports, 0, \ - LIST(ListOfExportFromSpecifier, INTERFACE(ExportFromSpecifier)), \ - "ExportFrom::namedExports") \ - F(ExportFrom, ModuleSpecifier, 1, PRIMITIVE(String), \ - "ExportFrom::moduleSpecifier") - -// The number of fields of interface ExportFrom. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_FROM = 2; - -// Strongly typed iteration through the fields of interface ExportFromSpecifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_FROM_SPECIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportFromSpecifier, Name, 0, PRIMITIVE(IdentifierName), \ - "ExportFromSpecifier::name") \ - F(ExportFromSpecifier, ExportedName, 1, PRIMITIVE(MaybeIdentifierName), \ - "ExportFromSpecifier::exportedName") - -// The number of fields of interface ExportFromSpecifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_FROM_SPECIFIER = 2; - -// Strongly typed iteration through the fields of interface -// ExportLocalSpecifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_LOCAL_SPECIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportLocalSpecifier, Name, 0, INTERFACE(IdentifierExpression), \ - "ExportLocalSpecifier::name") \ - F(ExportLocalSpecifier, ExportedName, 1, PRIMITIVE(MaybePropertyKey), \ - "ExportLocalSpecifier::exportedName") - -// The number of fields of interface ExportLocalSpecifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_LOCAL_SPECIFIER = 2; - -// Strongly typed iteration through the fields of interface ExportLocals. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPORT_LOCALS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExportLocals, NamedExports, 0, \ - LIST(ListOfExportLocalSpecifier, INTERFACE(ExportLocalSpecifier)), \ - "ExportLocals::namedExports") - -// The number of fields of interface ExportLocals. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPORT_LOCALS = 1; - -// Strongly typed iteration through the fields of interface ExpressionStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_EXPRESSION_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ExpressionStatement, Expression, 0, SUM(Expression), \ - "ExpressionStatement::expression") - -// The number of fields of interface ExpressionStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_EXPRESSION_STATEMENT = 1; - -// Strongly typed iteration through the fields of interface ForInOfBinding. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_IN_OF_BINDING( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ForInOfBinding, Kind, 0, STRING_ENUM(VariableDeclarationKind), \ - "ForInOfBinding::kind") \ - F(ForInOfBinding, Binding, 1, SUM(Binding), "ForInOfBinding::binding") - -// The number of fields of interface ForInOfBinding. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_IN_OF_BINDING = 2; - -// Strongly typed iteration through the fields of interface ForInStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_IN_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ForInStatement, Left, 0, SUM(AssignmentTargetOrForInOfBinding), \ - "ForInStatement::left") \ - F(ForInStatement, Right, 1, SUM(Expression), "ForInStatement::right") \ - F(ForInStatement, Body, 2, SUM(Statement), "ForInStatement::body") - -// The number of fields of interface ForInStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_IN_STATEMENT = 3; - -// Strongly typed iteration through the fields of interface ForOfStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_OF_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ForOfStatement, Left, 0, SUM(AssignmentTargetOrForInOfBinding), \ - "ForOfStatement::left") \ - F(ForOfStatement, Right, 1, SUM(Expression), "ForOfStatement::right") \ - F(ForOfStatement, Body, 2, SUM(Statement), "ForOfStatement::body") - -// The number of fields of interface ForOfStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_OF_STATEMENT = 3; - -// Strongly typed iteration through the fields of interface ForStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FOR_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ForStatement, Init, 0, OPTIONAL_SUM(ExpressionOrVariableDeclaration), \ - "ForStatement::init") \ - F(ForStatement, Test, 1, OPTIONAL_SUM(Expression), "ForStatement::test") \ - F(ForStatement, Update, 2, OPTIONAL_SUM(Expression), "ForStatement::update") \ - F(ForStatement, Body, 3, SUM(Statement), "ForStatement::body") - -// The number of fields of interface ForStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FOR_STATEMENT = 4; - -// Strongly typed iteration through the fields of interface FormalParameters. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FORMAL_PARAMETERS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(FormalParameters, Items, 0, LIST(ListOfParameter, SUM(Parameter)), \ - "FormalParameters::items") \ - F(FormalParameters, Rest, 1, OPTIONAL_SUM(Binding), "FormalParameters::rest") - -// The number of fields of interface FormalParameters. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FORMAL_PARAMETERS = 2; - -// Strongly typed iteration through the fields of interface -// FunctionExpressionContents. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FUNCTION_EXPRESSION_CONTENTS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(FunctionExpressionContents, IsFunctionNameCaptured, 0, PRIMITIVE(Boolean), \ - "FunctionExpressionContents::isFunctionNameCaptured") \ - F(FunctionExpressionContents, IsThisCaptured, 1, PRIMITIVE(Boolean), \ - "FunctionExpressionContents::isThisCaptured") \ - F(FunctionExpressionContents, ParameterScope, 2, \ - INTERFACE(AssertedParameterScope), \ - "FunctionExpressionContents::parameterScope") \ - F(FunctionExpressionContents, Params, 3, INTERFACE(FormalParameters), \ - "FunctionExpressionContents::params") \ - F(FunctionExpressionContents, BodyScope, 4, INTERFACE(AssertedVarScope), \ - "FunctionExpressionContents::bodyScope") \ - F(FunctionExpressionContents, Body, 5, \ - LIST(ListOfStatement, SUM(Statement)), "FunctionExpressionContents::body") - -// The number of fields of interface FunctionExpressionContents. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FUNCTION_EXPRESSION_CONTENTS = - 6; - -// Strongly typed iteration through the fields of interface -// FunctionOrMethodContents. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_FUNCTION_OR_METHOD_CONTENTS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(FunctionOrMethodContents, IsThisCaptured, 0, PRIMITIVE(Boolean), \ - "FunctionOrMethodContents::isThisCaptured") \ - F(FunctionOrMethodContents, ParameterScope, 1, \ - INTERFACE(AssertedParameterScope), \ - "FunctionOrMethodContents::parameterScope") \ - F(FunctionOrMethodContents, Params, 2, INTERFACE(FormalParameters), \ - "FunctionOrMethodContents::params") \ - F(FunctionOrMethodContents, BodyScope, 3, INTERFACE(AssertedVarScope), \ - "FunctionOrMethodContents::bodyScope") \ - F(FunctionOrMethodContents, Body, 4, LIST(ListOfStatement, SUM(Statement)), \ - "FunctionOrMethodContents::body") - -// The number of fields of interface FunctionOrMethodContents. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_FUNCTION_OR_METHOD_CONTENTS = - 5; - -// Strongly typed iteration through the fields of interface GetterContents. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_GETTER_CONTENTS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(GetterContents, IsThisCaptured, 0, PRIMITIVE(Boolean), \ - "GetterContents::isThisCaptured") \ - F(GetterContents, BodyScope, 1, INTERFACE(AssertedVarScope), \ - "GetterContents::bodyScope") \ - F(GetterContents, Body, 2, LIST(ListOfStatement, SUM(Statement)), \ - "GetterContents::body") - -// The number of fields of interface GetterContents. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_GETTER_CONTENTS = 3; - -// Strongly typed iteration through the fields of interface -// IdentifierExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IDENTIFIER_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(IdentifierExpression, Name, 0, PRIMITIVE(IdentifierName), \ - "IdentifierExpression::name") - -// The number of fields of interface IdentifierExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IDENTIFIER_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface IfStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IF_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(IfStatement, Test, 0, SUM(Expression), "IfStatement::test") \ - F(IfStatement, Consequent, 1, SUM(Statement), "IfStatement::consequent") \ - F(IfStatement, Alternate, 2, OPTIONAL_SUM(Statement), \ - "IfStatement::alternate") - -// The number of fields of interface IfStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IF_STATEMENT = 3; - -// Strongly typed iteration through the fields of interface Import. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Import, ModuleSpecifier, 0, PRIMITIVE(String), "Import::moduleSpecifier") \ - F(Import, DefaultBinding, 1, OPTIONAL_INTERFACE(BindingIdentifier), \ - "Import::defaultBinding") \ - F(Import, NamedImports, 2, \ - LIST(ListOfImportSpecifier, INTERFACE(ImportSpecifier)), \ - "Import::namedImports") - -// The number of fields of interface Import. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT = 3; - -// Strongly typed iteration through the fields of interface ImportNamespace. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT_NAMESPACE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ImportNamespace, ModuleSpecifier, 0, PRIMITIVE(String), \ - "ImportNamespace::moduleSpecifier") \ - F(ImportNamespace, DefaultBinding, 1, OPTIONAL_INTERFACE(BindingIdentifier), \ - "ImportNamespace::defaultBinding") \ - F(ImportNamespace, NamespaceBinding, 2, INTERFACE(BindingIdentifier), \ - "ImportNamespace::namespaceBinding") - -// The number of fields of interface ImportNamespace. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT_NAMESPACE = 3; - -// Strongly typed iteration through the fields of interface ImportSpecifier. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_IMPORT_SPECIFIER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ImportSpecifier, Name, 0, PRIMITIVE(MaybePropertyKey), \ - "ImportSpecifier::name") \ - F(ImportSpecifier, Binding, 1, INTERFACE(BindingIdentifier), \ - "ImportSpecifier::binding") - -// The number of fields of interface ImportSpecifier. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_IMPORT_SPECIFIER = 2; - -// Strongly typed iteration through the fields of interface LabelledStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LABELLED_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LabelledStatement, Label, 0, PRIMITIVE(String), \ - "LabelledStatement::label") \ - F(LabelledStatement, Body, 1, SUM(Statement), "LabelledStatement::body") - -// The number of fields of interface LabelledStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LABELLED_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface -// LazyArrowExpressionWithExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyArrowExpressionWithExpression, IsAsync, 0, PRIMITIVE(Boolean), \ - "LazyArrowExpressionWithExpression::isAsync") \ - F(LazyArrowExpressionWithExpression, Length, 1, PRIMITIVE(UnsignedLong), \ - "LazyArrowExpressionWithExpression::length") \ - F(LazyArrowExpressionWithExpression, ContentsSkip, 2, PRIMITIVE(Lazy), \ - "LazyArrowExpressionWithExpression::contents_skip") \ - F(LazyArrowExpressionWithExpression, Contents, 3, \ - INTERFACE(ArrowExpressionContentsWithExpression), \ - "LazyArrowExpressionWithExpression::contents") - -// The number of fields of interface LazyArrowExpressionWithExpression. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_EXPRESSION = - 4; - -// Strongly typed iteration through the fields of interface -// LazyArrowExpressionWithFunctionBody. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyArrowExpressionWithFunctionBody, IsAsync, 0, PRIMITIVE(Boolean), \ - "LazyArrowExpressionWithFunctionBody::isAsync") \ - F(LazyArrowExpressionWithFunctionBody, Length, 1, PRIMITIVE(UnsignedLong), \ - "LazyArrowExpressionWithFunctionBody::length") \ - F(LazyArrowExpressionWithFunctionBody, Directives, 2, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazyArrowExpressionWithFunctionBody::directives") \ - F(LazyArrowExpressionWithFunctionBody, ContentsSkip, 3, PRIMITIVE(Lazy), \ - "LazyArrowExpressionWithFunctionBody::contents_skip") \ - F(LazyArrowExpressionWithFunctionBody, Contents, 4, \ - INTERFACE(ArrowExpressionContentsWithFunctionBody), \ - "LazyArrowExpressionWithFunctionBody::contents") - -// The number of fields of interface LazyArrowExpressionWithFunctionBody. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_ARROW_EXPRESSION_WITH_FUNCTION_BODY = - 5; - -// Strongly typed iteration through the fields of interface -// LazyFunctionDeclaration. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_FUNCTION_DECLARATION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyFunctionDeclaration, IsAsync, 0, PRIMITIVE(Boolean), \ - "LazyFunctionDeclaration::isAsync") \ - F(LazyFunctionDeclaration, IsGenerator, 1, PRIMITIVE(Boolean), \ - "LazyFunctionDeclaration::isGenerator") \ - F(LazyFunctionDeclaration, Name, 2, INTERFACE(BindingIdentifier), \ - "LazyFunctionDeclaration::name") \ - F(LazyFunctionDeclaration, Length, 3, PRIMITIVE(UnsignedLong), \ - "LazyFunctionDeclaration::length") \ - F(LazyFunctionDeclaration, Directives, 4, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazyFunctionDeclaration::directives") \ - F(LazyFunctionDeclaration, ContentsSkip, 5, PRIMITIVE(Lazy), \ - "LazyFunctionDeclaration::contents_skip") \ - F(LazyFunctionDeclaration, Contents, 6, INTERFACE(FunctionOrMethodContents), \ - "LazyFunctionDeclaration::contents") - -// The number of fields of interface LazyFunctionDeclaration. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_FUNCTION_DECLARATION = 7; - -// Strongly typed iteration through the fields of interface -// LazyFunctionExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_FUNCTION_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyFunctionExpression, IsAsync, 0, PRIMITIVE(Boolean), \ - "LazyFunctionExpression::isAsync") \ - F(LazyFunctionExpression, IsGenerator, 1, PRIMITIVE(Boolean), \ - "LazyFunctionExpression::isGenerator") \ - F(LazyFunctionExpression, Name, 2, OPTIONAL_INTERFACE(BindingIdentifier), \ - "LazyFunctionExpression::name") \ - F(LazyFunctionExpression, Length, 3, PRIMITIVE(UnsignedLong), \ - "LazyFunctionExpression::length") \ - F(LazyFunctionExpression, Directives, 4, \ - LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazyFunctionExpression::directives") \ - F(LazyFunctionExpression, ContentsSkip, 5, PRIMITIVE(Lazy), \ - "LazyFunctionExpression::contents_skip") \ - F(LazyFunctionExpression, Contents, 6, \ - INTERFACE(FunctionExpressionContents), "LazyFunctionExpression::contents") - -// The number of fields of interface LazyFunctionExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_FUNCTION_EXPRESSION = 7; - -// Strongly typed iteration through the fields of interface LazyGetter. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_GETTER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyGetter, Name, 0, SUM(PropertyName), "LazyGetter::name") \ - F(LazyGetter, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazyGetter::directives") \ - F(LazyGetter, ContentsSkip, 2, PRIMITIVE(Lazy), "LazyGetter::contents_skip") \ - F(LazyGetter, Contents, 3, INTERFACE(GetterContents), "LazyGetter::contents") - -// The number of fields of interface LazyGetter. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_GETTER = 4; - -// Strongly typed iteration through the fields of interface LazyMethod. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_METHOD( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazyMethod, IsAsync, 0, PRIMITIVE(Boolean), "LazyMethod::isAsync") \ - F(LazyMethod, IsGenerator, 1, PRIMITIVE(Boolean), "LazyMethod::isGenerator") \ - F(LazyMethod, Name, 2, SUM(PropertyName), "LazyMethod::name") \ - F(LazyMethod, Length, 3, PRIMITIVE(UnsignedLong), "LazyMethod::length") \ - F(LazyMethod, Directives, 4, LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazyMethod::directives") \ - F(LazyMethod, ContentsSkip, 5, PRIMITIVE(Lazy), "LazyMethod::contents_skip") \ - F(LazyMethod, Contents, 6, INTERFACE(FunctionOrMethodContents), \ - "LazyMethod::contents") - -// The number of fields of interface LazyMethod. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_METHOD = 7; - -// Strongly typed iteration through the fields of interface LazySetter. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LAZY_SETTER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LazySetter, Name, 0, SUM(PropertyName), "LazySetter::name") \ - F(LazySetter, Length, 1, PRIMITIVE(UnsignedLong), "LazySetter::length") \ - F(LazySetter, Directives, 2, LIST(ListOfDirective, INTERFACE(Directive)), \ - "LazySetter::directives") \ - F(LazySetter, ContentsSkip, 3, PRIMITIVE(Lazy), "LazySetter::contents_skip") \ - F(LazySetter, Contents, 4, INTERFACE(SetterContents), "LazySetter::contents") - -// The number of fields of interface LazySetter. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LAZY_SETTER = 5; - -// Strongly typed iteration through the fields of interface -// LiteralBooleanExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_BOOLEAN_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LiteralBooleanExpression, Value, 0, PRIMITIVE(Boolean), \ - "LiteralBooleanExpression::value") - -// The number of fields of interface LiteralBooleanExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_BOOLEAN_EXPRESSION = - 1; - -// Strongly typed iteration through the fields of interface -// LiteralInfinityExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_INFINITY_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface LiteralInfinityExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_INFINITY_EXPRESSION = - 0; - -// Strongly typed iteration through the fields of interface -// LiteralNullExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_NULL_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface LiteralNullExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_NULL_EXPRESSION = 0; - -// Strongly typed iteration through the fields of interface -// LiteralNumericExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_NUMERIC_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LiteralNumericExpression, Value, 0, PRIMITIVE(Number), \ - "LiteralNumericExpression::value") - -// The number of fields of interface LiteralNumericExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_NUMERIC_EXPRESSION = - 1; - -// Strongly typed iteration through the fields of interface LiteralPropertyName. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_PROPERTY_NAME( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LiteralPropertyName, Value, 0, PRIMITIVE(String), \ - "LiteralPropertyName::value") - -// The number of fields of interface LiteralPropertyName. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_PROPERTY_NAME = 1; - -// Strongly typed iteration through the fields of interface -// LiteralRegExpExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_REG_EXP_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LiteralRegExpExpression, Pattern, 0, PRIMITIVE(String), \ - "LiteralRegExpExpression::pattern") \ - F(LiteralRegExpExpression, Flags, 1, PRIMITIVE(String), \ - "LiteralRegExpExpression::flags") - -// The number of fields of interface LiteralRegExpExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_REG_EXP_EXPRESSION = - 2; - -// Strongly typed iteration through the fields of interface -// LiteralStringExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_LITERAL_STRING_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(LiteralStringExpression, Value, 0, PRIMITIVE(String), \ - "LiteralStringExpression::value") - -// The number of fields of interface LiteralStringExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_LITERAL_STRING_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface Module. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_MODULE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Module, Scope, 0, INTERFACE(AssertedVarScope), "Module::scope") \ - F(Module, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)), \ - "Module::directives") \ - F(Module, Items, 2, \ - LIST(ListOfExportDeclarationOrImportDeclarationOrStatement, \ - SUM(ExportDeclarationOrImportDeclarationOrStatement)), \ - "Module::items") - -// The number of fields of interface Module. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_MODULE = 3; - -// Strongly typed iteration through the fields of interface NewExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NEW_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(NewExpression, Callee, 0, SUM(Expression), "NewExpression::callee") \ - F(NewExpression, Arguments, 1, \ - LIST(Arguments, SUM(ExpressionOrSpreadElement)), \ - "NewExpression::arguments") - -// The number of fields of interface NewExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NEW_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface NewTargetExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_NEW_TARGET_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface NewTargetExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_NEW_TARGET_EXPRESSION = 0; - -// Strongly typed iteration through the fields of interface -// ObjectAssignmentTarget. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_ASSIGNMENT_TARGET( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ObjectAssignmentTarget, Properties, 0, \ - LIST(ListOfAssignmentTargetProperty, SUM(AssignmentTargetProperty)), \ - "ObjectAssignmentTarget::properties") - -// The number of fields of interface ObjectAssignmentTarget. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_ASSIGNMENT_TARGET = 1; - -// Strongly typed iteration through the fields of interface ObjectBinding. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_BINDING( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ObjectBinding, Properties, 0, \ - LIST(ListOfBindingProperty, SUM(BindingProperty)), \ - "ObjectBinding::properties") - -// The number of fields of interface ObjectBinding. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_BINDING = 1; - -// Strongly typed iteration through the fields of interface ObjectExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_OBJECT_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ObjectExpression, Properties, 0, \ - LIST(ListOfObjectProperty, SUM(ObjectProperty)), \ - "ObjectExpression::properties") - -// The number of fields of interface ObjectExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_OBJECT_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface ReturnStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_RETURN_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ReturnStatement, Expression, 0, OPTIONAL_SUM(Expression), \ - "ReturnStatement::expression") - -// The number of fields of interface ReturnStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_RETURN_STATEMENT = 1; - -// Strongly typed iteration through the fields of interface Script. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SCRIPT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(Script, Scope, 0, INTERFACE(AssertedScriptGlobalScope), "Script::scope") \ - F(Script, Directives, 1, LIST(ListOfDirective, INTERFACE(Directive)), \ - "Script::directives") \ - F(Script, Statements, 2, LIST(ListOfStatement, SUM(Statement)), \ - "Script::statements") - -// The number of fields of interface Script. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SCRIPT = 3; - -// Strongly typed iteration through the fields of interface SetterContents. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SETTER_CONTENTS( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SetterContents, IsThisCaptured, 0, PRIMITIVE(Boolean), \ - "SetterContents::isThisCaptured") \ - F(SetterContents, ParameterScope, 1, INTERFACE(AssertedParameterScope), \ - "SetterContents::parameterScope") \ - F(SetterContents, Param, 2, SUM(Parameter), "SetterContents::param") \ - F(SetterContents, BodyScope, 3, INTERFACE(AssertedVarScope), \ - "SetterContents::bodyScope") \ - F(SetterContents, Body, 4, LIST(ListOfStatement, SUM(Statement)), \ - "SetterContents::body") - -// The number of fields of interface SetterContents. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SETTER_CONTENTS = 5; - -// Strongly typed iteration through the fields of interface ShorthandProperty. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SHORTHAND_PROPERTY( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ShorthandProperty, Name, 0, INTERFACE(IdentifierExpression), \ - "ShorthandProperty::name") - -// The number of fields of interface ShorthandProperty. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SHORTHAND_PROPERTY = 1; - -// Strongly typed iteration through the fields of interface SpreadElement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SPREAD_ELEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SpreadElement, Expression, 0, SUM(Expression), "SpreadElement::expression") - -// The number of fields of interface SpreadElement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SPREAD_ELEMENT = 1; - -// Strongly typed iteration through the fields of interface -// StaticMemberAssignmentTarget. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_STATIC_MEMBER_ASSIGNMENT_TARGET( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(StaticMemberAssignmentTarget, Object, 0, SUM(ExpressionOrSuper), \ - "StaticMemberAssignmentTarget::object") \ - F(StaticMemberAssignmentTarget, Property, 1, PRIMITIVE(PropertyKey), \ - "StaticMemberAssignmentTarget::property") - -// The number of fields of interface StaticMemberAssignmentTarget. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_STATIC_MEMBER_ASSIGNMENT_TARGET = 2; - -// Strongly typed iteration through the fields of interface -// StaticMemberExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_STATIC_MEMBER_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(StaticMemberExpression, Object, 0, SUM(ExpressionOrSuper), \ - "StaticMemberExpression::object") \ - F(StaticMemberExpression, Property, 1, PRIMITIVE(PropertyKey), \ - "StaticMemberExpression::property") - -// The number of fields of interface StaticMemberExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_STATIC_MEMBER_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface Super. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SUPER( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface Super. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SUPER = 0; - -// Strongly typed iteration through the fields of interface SwitchCase. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_CASE( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SwitchCase, Test, 0, SUM(Expression), "SwitchCase::test") \ - F(SwitchCase, Consequent, 1, LIST(ListOfStatement, SUM(Statement)), \ - "SwitchCase::consequent") - -// The number of fields of interface SwitchCase. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_CASE = 2; - -// Strongly typed iteration through the fields of interface SwitchDefault. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_DEFAULT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SwitchDefault, Consequent, 0, LIST(ListOfStatement, SUM(Statement)), \ - "SwitchDefault::consequent") - -// The number of fields of interface SwitchDefault. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_DEFAULT = 1; - -// Strongly typed iteration through the fields of interface SwitchStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SwitchStatement, Discriminant, 0, SUM(Expression), \ - "SwitchStatement::discriminant") \ - F(SwitchStatement, Cases, 1, LIST(ListOfSwitchCase, INTERFACE(SwitchCase)), \ - "SwitchStatement::cases") - -// The number of fields of interface SwitchStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface -// SwitchStatementWithDefault. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_SWITCH_STATEMENT_WITH_DEFAULT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(SwitchStatementWithDefault, Discriminant, 0, SUM(Expression), \ - "SwitchStatementWithDefault::discriminant") \ - F(SwitchStatementWithDefault, PreDefaultCases, 1, \ - LIST(ListOfSwitchCase, INTERFACE(SwitchCase)), \ - "SwitchStatementWithDefault::preDefaultCases") \ - F(SwitchStatementWithDefault, DefaultCase, 2, INTERFACE(SwitchDefault), \ - "SwitchStatementWithDefault::defaultCase") \ - F(SwitchStatementWithDefault, PostDefaultCases, 3, \ - LIST(ListOfSwitchCase, INTERFACE(SwitchCase)), \ - "SwitchStatementWithDefault::postDefaultCases") - -// The number of fields of interface SwitchStatementWithDefault. -const size_t - BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_SWITCH_STATEMENT_WITH_DEFAULT = 4; - -// Strongly typed iteration through the fields of interface TemplateElement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TEMPLATE_ELEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(TemplateElement, RawValue, 0, PRIMITIVE(String), \ - "TemplateElement::rawValue") - -// The number of fields of interface TemplateElement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TEMPLATE_ELEMENT = 1; - -// Strongly typed iteration through the fields of interface TemplateExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TEMPLATE_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(TemplateExpression, Tag, 0, OPTIONAL_SUM(Expression), \ - "TemplateExpression::tag") \ - F(TemplateExpression, Elements, 1, \ - LIST(ListOfExpressionOrTemplateElement, SUM(ExpressionOrTemplateElement)), \ - "TemplateExpression::elements") - -// The number of fields of interface TemplateExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TEMPLATE_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface ThisExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_THIS_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) - -// The number of fields of interface ThisExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_THIS_EXPRESSION = 0; - -// Strongly typed iteration through the fields of interface ThrowStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_THROW_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(ThrowStatement, Expression, 0, SUM(Expression), \ - "ThrowStatement::expression") - -// The number of fields of interface ThrowStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_THROW_STATEMENT = 1; - -// Strongly typed iteration through the fields of interface TryCatchStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TRY_CATCH_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(TryCatchStatement, Body, 0, INTERFACE(Block), "TryCatchStatement::body") \ - F(TryCatchStatement, CatchClause, 1, INTERFACE(CatchClause), \ - "TryCatchStatement::catchClause") - -// The number of fields of interface TryCatchStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TRY_CATCH_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface TryFinallyStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_TRY_FINALLY_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(TryFinallyStatement, Body, 0, INTERFACE(Block), \ - "TryFinallyStatement::body") \ - F(TryFinallyStatement, CatchClause, 1, OPTIONAL_INTERFACE(CatchClause), \ - "TryFinallyStatement::catchClause") \ - F(TryFinallyStatement, Finalizer, 2, INTERFACE(Block), \ - "TryFinallyStatement::finalizer") - -// The number of fields of interface TryFinallyStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_TRY_FINALLY_STATEMENT = 3; - -// Strongly typed iteration through the fields of interface UnaryExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNARY_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(UnaryExpression, Operator, 0, STRING_ENUM(UnaryOperator), \ - "UnaryExpression::operator") \ - F(UnaryExpression, Operand, 1, SUM(Expression), "UnaryExpression::operand") - -// The number of fields of interface UnaryExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_UNARY_EXPRESSION = 2; - -// Strongly typed iteration through the fields of interface UpdateExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UPDATE_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(UpdateExpression, IsPrefix, 0, PRIMITIVE(Boolean), \ - "UpdateExpression::isPrefix") \ - F(UpdateExpression, Operator, 1, STRING_ENUM(UpdateOperator), \ - "UpdateExpression::operator") \ - F(UpdateExpression, Operand, 2, SUM(SimpleAssignmentTarget), \ - "UpdateExpression::operand") - -// The number of fields of interface UpdateExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_UPDATE_EXPRESSION = 3; - -// Strongly typed iteration through the fields of interface VariableDeclaration. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_VARIABLE_DECLARATION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(VariableDeclaration, Kind, 0, STRING_ENUM(VariableDeclarationKind), \ - "VariableDeclaration::kind") \ - F(VariableDeclaration, Declarators, 1, \ - LIST(ListOfVariableDeclarator, INTERFACE(VariableDeclarator)), \ - "VariableDeclaration::declarators") - -// The number of fields of interface VariableDeclaration. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_VARIABLE_DECLARATION = 2; - -// Strongly typed iteration through the fields of interface VariableDeclarator. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_VARIABLE_DECLARATOR( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(VariableDeclarator, Binding, 0, SUM(Binding), \ - "VariableDeclarator::binding") \ - F(VariableDeclarator, Init, 1, OPTIONAL_SUM(Expression), \ - "VariableDeclarator::init") - -// The number of fields of interface VariableDeclarator. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_VARIABLE_DECLARATOR = 2; - -// Strongly typed iteration through the fields of interface WhileStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_WHILE_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(WhileStatement, Test, 0, SUM(Expression), "WhileStatement::test") \ - F(WhileStatement, Body, 1, SUM(Statement), "WhileStatement::body") - -// The number of fields of interface WhileStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_WHILE_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface WithStatement. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_WITH_STATEMENT( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(WithStatement, Object, 0, SUM(Expression), "WithStatement::object") \ - F(WithStatement, Body, 1, SUM(Statement), "WithStatement::body") - -// The number of fields of interface WithStatement. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_WITH_STATEMENT = 2; - -// Strongly typed iteration through the fields of interface YieldExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_YIELD_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(YieldExpression, Expression, 0, OPTIONAL_SUM(Expression), \ - "YieldExpression::expression") - -// The number of fields of interface YieldExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_YIELD_EXPRESSION = 1; - -// Strongly typed iteration through the fields of interface YieldStarExpression. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_YIELD_STAR_EXPRESSION( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) \ - F(YieldStarExpression, Expression, 0, SUM(Expression), \ - "YieldStarExpression::expression") - -// The number of fields of interface YieldStarExpression. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_YIELD_STAR_EXPRESSION = 1; -// The total number of fields across all interfaces. Used typically to maintain -// a probability table per field. -const size_t BINAST_INTERFACE_AND_FIELD_LIMIT = 275; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_INTERFACE_AND_FIELD_LIMIT. -#define BINAST_PARAM_NUMBER_OF_INTERFACE_AND_FIELD(X) \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X), (X) - -/** - * The different variants of Binary AST string enums, as per - * the specifications of Binary AST, as a single macro and - * `enum class`. - * - * Separate enum classes are also defined in BinASTParser.h. - * - * Usage: - * - * ```c++ - * #define WITH_VARIANT(CPP_NAME, SPEC_NAME) ... - * FOR_EACH_BIN_VARIANT(WITH_VARIANT) - * ``` - * - * (sorted by alphabetical order) - */ -#define FOR_EACH_BIN_VARIANT(F) \ - F(UnaryOperatorNot, "!") \ - F(BinaryOperatorNeq, "!=") \ - F(BinaryOperatorStrictNeq, "!==") \ - F(BinaryOperatorMod, "%") \ - F(CompoundAssignmentOperatorModAssign, "%=") \ - F(BinaryOperatorBitAnd, "&") \ - F(BinaryOperatorLogicalAnd, "&&") \ - F(CompoundAssignmentOperatorBitAndAssign, "&=") \ - F(BinaryOperatorMul, "*") \ - F(BinaryOperatorPow, "**") \ - F(CompoundAssignmentOperatorPowAssign, "**=") \ - F(CompoundAssignmentOperatorMulAssign, "*=") \ - F(BinaryOperatorOrUnaryOperatorPlus, "+") \ - F(UpdateOperatorIncr, "++") \ - F(CompoundAssignmentOperatorPlusAssign, "+=") \ - F(BinaryOperatorComma, ",") \ - F(BinaryOperatorOrUnaryOperatorMinus, "-") \ - F(UpdateOperatorDecr, "--") \ - F(CompoundAssignmentOperatorMinusAssign, "-=") \ - F(BinaryOperatorDiv, "/") \ - F(CompoundAssignmentOperatorDivAssign, "/=") \ - F(BinaryOperatorLessThan, "<") \ - F(BinaryOperatorLsh, "<<") \ - F(CompoundAssignmentOperatorLshAssign, "<<=") \ - F(BinaryOperatorLeqThan, "<=") \ - F(BinaryOperatorEq, "==") \ - F(BinaryOperatorStrictEq, "===") \ - F(BinaryOperatorGreaterThan, ">") \ - F(BinaryOperatorGeqThan, ">=") \ - F(BinaryOperatorRsh, ">>") \ - F(CompoundAssignmentOperatorRshAssign, ">>=") \ - F(BinaryOperatorUrsh, ">>>") \ - F(CompoundAssignmentOperatorUrshAssign, ">>>=") \ - F(BinaryOperatorBitXor, "^") \ - F(CompoundAssignmentOperatorBitXorAssign, "^=") \ - F(VariableDeclarationKindConst, "const") \ - F(AssertedDeclaredKindConstLexical, "const lexical") \ - F(UnaryOperatorDelete, "delete") \ - F(BinaryOperatorIn, "in") \ - F(BinaryOperatorInstanceof, "instanceof") \ - F(VariableDeclarationKindLet, "let") \ - F(AssertedDeclaredKindNonConstLexical, "non-const lexical") \ - F(UnaryOperatorTypeof, "typeof") \ - F(AssertedDeclaredKindOrVariableDeclarationKindVar, "var") \ - F(UnaryOperatorVoid, "void") \ - F(BinaryOperatorBitOr, "|") \ - F(CompoundAssignmentOperatorBitOrAssign, "|=") \ - F(BinaryOperatorLogicalOr, "||") \ - F(UnaryOperatorBitNot, "~") - -enum class BinASTVariant : uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_VARIANT(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// The number of distinct values of BinASTVariant. -const size_t BINASTVARIANT_LIMIT = 49; - -#define FOR_EACH_BIN_STRING_ENUM(F) \ - F(AssertedDeclaredKind, "AssertedDeclaredKind", ASSERTED_DECLARED_KIND) \ - F(BinaryOperator, "BinaryOperator", BINARY_OPERATOR) \ - F(CompoundAssignmentOperator, "CompoundAssignmentOperator", \ - COMPOUND_ASSIGNMENT_OPERATOR) \ - F(UnaryOperator, "UnaryOperator", UNARY_OPERATOR) \ - F(UpdateOperator, "UpdateOperator", UPDATE_OPERATOR) \ - F(VariableDeclarationKind, "VariableDeclarationKind", \ - VARIABLE_DECLARATION_KIND) - -enum class BinASTStringEnum : uint16_t { -#define EMIT_ENUM(NAME, _HUMAN_NAME, _MACRO_NAME) NAME, - FOR_EACH_BIN_STRING_ENUM(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// The number of distinct values of BinASTStringEnum. -const size_t BINASTSTRINGENUM_LIMIT = 6; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_ASSERTED_DECLARED_KIND_BY_STRING_ORDER( \ - F) \ - F(AssertedDeclaredKind, AssertedDeclaredKindConstLexical, "const lexical") \ - F(AssertedDeclaredKind, AssertedDeclaredKindNonConstLexical, \ - "non-const lexical") \ - F(AssertedDeclaredKind, AssertedDeclaredKindOrVariableDeclarationKindVar, \ - "var") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_ASSERTED_DECLARED_KIND_BY_WEBIDL_ORDER( \ - F) \ - F(AssertedDeclaredKind, AssertedDeclaredKindOrVariableDeclarationKindVar, \ - "var") \ - F(AssertedDeclaredKind, AssertedDeclaredKindNonConstLexical, \ - "non-const lexical") \ - F(AssertedDeclaredKind, AssertedDeclaredKindConstLexical, "const lexical") - -const size_t BIN_AST_STRING_ENUM_ASSERTED_DECLARED_KIND_LIMIT = 3; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_BINARY_OPERATOR_BY_STRING_ORDER(F) \ - F(BinaryOperator, BinaryOperatorNeq, "!=") \ - F(BinaryOperator, BinaryOperatorStrictNeq, "!==") \ - F(BinaryOperator, BinaryOperatorMod, "%") \ - F(BinaryOperator, BinaryOperatorBitAnd, "&") \ - F(BinaryOperator, BinaryOperatorLogicalAnd, "&&") \ - F(BinaryOperator, BinaryOperatorMul, "*") \ - F(BinaryOperator, BinaryOperatorPow, "**") \ - F(BinaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+") \ - F(BinaryOperator, BinaryOperatorComma, ",") \ - F(BinaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-") \ - F(BinaryOperator, BinaryOperatorDiv, "/") \ - F(BinaryOperator, BinaryOperatorLessThan, "<") \ - F(BinaryOperator, BinaryOperatorLsh, "<<") \ - F(BinaryOperator, BinaryOperatorLeqThan, "<=") \ - F(BinaryOperator, BinaryOperatorEq, "==") \ - F(BinaryOperator, BinaryOperatorStrictEq, "===") \ - F(BinaryOperator, BinaryOperatorGreaterThan, ">") \ - F(BinaryOperator, BinaryOperatorGeqThan, ">=") \ - F(BinaryOperator, BinaryOperatorRsh, ">>") \ - F(BinaryOperator, BinaryOperatorUrsh, ">>>") \ - F(BinaryOperator, BinaryOperatorBitXor, "^") \ - F(BinaryOperator, BinaryOperatorIn, "in") \ - F(BinaryOperator, BinaryOperatorInstanceof, "instanceof") \ - F(BinaryOperator, BinaryOperatorBitOr, "|") \ - F(BinaryOperator, BinaryOperatorLogicalOr, "||") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_BINARY_OPERATOR_BY_WEBIDL_ORDER(F) \ - F(BinaryOperator, BinaryOperatorComma, ",") \ - F(BinaryOperator, BinaryOperatorLogicalOr, "||") \ - F(BinaryOperator, BinaryOperatorLogicalAnd, "&&") \ - F(BinaryOperator, BinaryOperatorBitOr, "|") \ - F(BinaryOperator, BinaryOperatorBitXor, "^") \ - F(BinaryOperator, BinaryOperatorBitAnd, "&") \ - F(BinaryOperator, BinaryOperatorEq, "==") \ - F(BinaryOperator, BinaryOperatorNeq, "!=") \ - F(BinaryOperator, BinaryOperatorStrictEq, "===") \ - F(BinaryOperator, BinaryOperatorStrictNeq, "!==") \ - F(BinaryOperator, BinaryOperatorLessThan, "<") \ - F(BinaryOperator, BinaryOperatorLeqThan, "<=") \ - F(BinaryOperator, BinaryOperatorGreaterThan, ">") \ - F(BinaryOperator, BinaryOperatorGeqThan, ">=") \ - F(BinaryOperator, BinaryOperatorIn, "in") \ - F(BinaryOperator, BinaryOperatorInstanceof, "instanceof") \ - F(BinaryOperator, BinaryOperatorLsh, "<<") \ - F(BinaryOperator, BinaryOperatorRsh, ">>") \ - F(BinaryOperator, BinaryOperatorUrsh, ">>>") \ - F(BinaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+") \ - F(BinaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-") \ - F(BinaryOperator, BinaryOperatorMul, "*") \ - F(BinaryOperator, BinaryOperatorDiv, "/") \ - F(BinaryOperator, BinaryOperatorMod, "%") \ - F(BinaryOperator, BinaryOperatorPow, "**") - -const size_t BIN_AST_STRING_ENUM_BINARY_OPERATOR_LIMIT = 25; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_BY_STRING_ORDER( \ - F) \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorModAssign, "%=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitAndAssign, "&=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorPowAssign, "**=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorMulAssign, "*=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorPlusAssign, "+=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorMinusAssign, "-=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorDivAssign, "/=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorLshAssign, "<<=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorRshAssign, ">>=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorUrshAssign, ">>>=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitXorAssign, "^=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitOrAssign, "|=") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_BY_WEBIDL_ORDER( \ - F) \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorPlusAssign, "+=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorMinusAssign, "-=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorMulAssign, "*=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorDivAssign, "/=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorModAssign, "%=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorPowAssign, "**=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorLshAssign, "<<=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorRshAssign, ">>=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorUrshAssign, ">>>=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitOrAssign, "|=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitXorAssign, "^=") \ - F(CompoundAssignmentOperator, CompoundAssignmentOperatorBitAndAssign, "&=") - -const size_t BIN_AST_STRING_ENUM_COMPOUND_ASSIGNMENT_OPERATOR_LIMIT = 12; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UNARY_OPERATOR_BY_STRING_ORDER(F) \ - F(UnaryOperator, UnaryOperatorNot, "!") \ - F(UnaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+") \ - F(UnaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-") \ - F(UnaryOperator, UnaryOperatorDelete, "delete") \ - F(UnaryOperator, UnaryOperatorTypeof, "typeof") \ - F(UnaryOperator, UnaryOperatorVoid, "void") \ - F(UnaryOperator, UnaryOperatorBitNot, "~") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UNARY_OPERATOR_BY_WEBIDL_ORDER(F) \ - F(UnaryOperator, BinaryOperatorOrUnaryOperatorPlus, "+") \ - F(UnaryOperator, BinaryOperatorOrUnaryOperatorMinus, "-") \ - F(UnaryOperator, UnaryOperatorNot, "!") \ - F(UnaryOperator, UnaryOperatorBitNot, "~") \ - F(UnaryOperator, UnaryOperatorTypeof, "typeof") \ - F(UnaryOperator, UnaryOperatorVoid, "void") \ - F(UnaryOperator, UnaryOperatorDelete, "delete") - -const size_t BIN_AST_STRING_ENUM_UNARY_OPERATOR_LIMIT = 7; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UPDATE_OPERATOR_BY_STRING_ORDER(F) \ - F(UpdateOperator, UpdateOperatorIncr, "++") \ - F(UpdateOperator, UpdateOperatorDecr, "--") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_UPDATE_OPERATOR_BY_WEBIDL_ORDER(F) \ - F(UpdateOperator, UpdateOperatorIncr, "++") \ - F(UpdateOperator, UpdateOperatorDecr, "--") - -const size_t BIN_AST_STRING_ENUM_UPDATE_OPERATOR_LIMIT = 2; - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_VARIABLE_DECLARATION_KIND_BY_STRING_ORDER( \ - F) \ - F(VariableDeclarationKind, VariableDeclarationKindConst, "const") \ - F(VariableDeclarationKind, VariableDeclarationKindLet, "let") \ - F(VariableDeclarationKind, AssertedDeclaredKindOrVariableDeclarationKindVar, \ - "var") - -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_VARIABLE_DECLARATION_KIND_BY_WEBIDL_ORDER( \ - F) \ - F(VariableDeclarationKind, AssertedDeclaredKindOrVariableDeclarationKindVar, \ - "var") \ - F(VariableDeclarationKind, VariableDeclarationKindLet, "let") \ - F(VariableDeclarationKind, VariableDeclarationKindConst, "const") - -const size_t BIN_AST_STRING_ENUM_VARIABLE_DECLARATION_KIND_LIMIT = 3; - -// This macro accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as -// `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as -// `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as -// `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, -// element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as -// `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as -// `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called -// as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_LIST(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, \ - SUM, OPTIONAL_SUM, STRING_ENUM, \ - OPTIONAL_STRING_ENUM) \ - F(Arguments, ExpressionOrSpreadElement, "Arguments", \ - LIST(Arguments, SUM(ExpressionOrSpreadElement))) \ - F(ListOfAssertedBoundName, AssertedBoundName, "ListOfAssertedBoundName", \ - LIST(ListOfAssertedBoundName, INTERFACE(AssertedBoundName))) \ - F(ListOfAssertedDeclaredName, AssertedDeclaredName, \ - "ListOfAssertedDeclaredName", \ - LIST(ListOfAssertedDeclaredName, INTERFACE(AssertedDeclaredName))) \ - F(ListOfAssertedMaybePositionalParameterName, \ - AssertedMaybePositionalParameterName, \ - "ListOfAssertedMaybePositionalParameterName", \ - LIST(ListOfAssertedMaybePositionalParameterName, \ - SUM(AssertedMaybePositionalParameterName))) \ - F(ListOfAssignmentTargetOrAssignmentTargetWithInitializer, \ - AssignmentTargetOrAssignmentTargetWithInitializer, \ - "ListOfAssignmentTargetOrAssignmentTargetWithInitializer", \ - LIST(ListOfAssignmentTargetOrAssignmentTargetWithInitializer, \ - SUM(AssignmentTargetOrAssignmentTargetWithInitializer))) \ - F(ListOfAssignmentTargetProperty, AssignmentTargetProperty, \ - "ListOfAssignmentTargetProperty", \ - LIST(ListOfAssignmentTargetProperty, SUM(AssignmentTargetProperty))) \ - F(ListOfBindingProperty, BindingProperty, "ListOfBindingProperty", \ - LIST(ListOfBindingProperty, SUM(BindingProperty))) \ - F(ListOfClassElement, ClassElement, "ListOfClassElement", \ - LIST(ListOfClassElement, INTERFACE(ClassElement))) \ - F(ListOfDirective, Directive, "ListOfDirective", \ - LIST(ListOfDirective, INTERFACE(Directive))) \ - F(ListOfExportDeclarationOrImportDeclarationOrStatement, \ - ExportDeclarationOrImportDeclarationOrStatement, \ - "ListOfExportDeclarationOrImportDeclarationOrStatement", \ - LIST(ListOfExportDeclarationOrImportDeclarationOrStatement, \ - SUM(ExportDeclarationOrImportDeclarationOrStatement))) \ - F(ListOfExportFromSpecifier, ExportFromSpecifier, \ - "ListOfExportFromSpecifier", \ - LIST(ListOfExportFromSpecifier, INTERFACE(ExportFromSpecifier))) \ - F(ListOfExportLocalSpecifier, ExportLocalSpecifier, \ - "ListOfExportLocalSpecifier", \ - LIST(ListOfExportLocalSpecifier, INTERFACE(ExportLocalSpecifier))) \ - F(ListOfExpressionOrTemplateElement, ExpressionOrTemplateElement, \ - "ListOfExpressionOrTemplateElement", \ - LIST(ListOfExpressionOrTemplateElement, SUM(ExpressionOrTemplateElement))) \ - F(ListOfImportSpecifier, ImportSpecifier, "ListOfImportSpecifier", \ - LIST(ListOfImportSpecifier, INTERFACE(ImportSpecifier))) \ - F(ListOfObjectProperty, ObjectProperty, "ListOfObjectProperty", \ - LIST(ListOfObjectProperty, SUM(ObjectProperty))) \ - F(ListOfOptionalBindingOrBindingWithInitializer, \ - OptionalBindingOrBindingWithInitializer, \ - "ListOfOptionalBindingOrBindingWithInitializer", \ - LIST(ListOfOptionalBindingOrBindingWithInitializer, \ - OPTIONAL_SUM(BindingOrBindingWithInitializer))) \ - F(ListOfOptionalExpressionOrSpreadElement, \ - OptionalExpressionOrSpreadElement, \ - "ListOfOptionalExpressionOrSpreadElement", \ - LIST(ListOfOptionalExpressionOrSpreadElement, \ - OPTIONAL_SUM(ExpressionOrSpreadElement))) \ - F(ListOfParameter, Parameter, "ListOfParameter", \ - LIST(ListOfParameter, SUM(Parameter))) \ - F(ListOfStatement, Statement, "ListOfStatement", \ - LIST(ListOfStatement, SUM(Statement))) \ - F(ListOfSwitchCase, SwitchCase, "ListOfSwitchCase", \ - LIST(ListOfSwitchCase, INTERFACE(SwitchCase))) \ - F(ListOfVariableDeclarator, VariableDeclarator, "ListOfVariableDeclarator", \ - LIST(ListOfVariableDeclarator, INTERFACE(VariableDeclarator))) - -enum class BinASTList : uint16_t { -#define NOTHING(_) -#define EMIT_ENUM(name, _content, _user, _type_name) name, - FOR_EACH_BIN_LIST(EMIT_ENUM, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, - NOTHING, NOTHING, NOTHING) -#undef EMIT_ENUM -#undef NOTHING -}; - -// The number of distinct list types in the grammar. Used typically to maintain -// a probability table per list type. -const size_t BINAST_NUMBER_OF_LIST_TYPES = 22; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_NUMBER_OF_LIST_TYPES. -#define BINAST_PARAM_NUMBER_OF_LIST_TYPES(X) \ - (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), (X), \ - (X), (X), (X), (X), (X), (X), (X) - -#define FOR_EACH_BIN_SUM(F) \ - F(ArrowExpression, "ArrowExpression", ARROW_EXPRESSION, \ - SUM(EagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBody)) \ - F(AssertedMaybePositionalParameterName, \ - "AssertedMaybePositionalParameterName", \ - ASSERTED_MAYBE_POSITIONAL_PARAMETER_NAME, \ - SUM(AssertedParameterNameOrAssertedPositionalParameterNameOrAssertedRestParameterName)) \ - F(AssignmentTarget, "AssignmentTarget", ASSIGNMENT_TARGET, \ - SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrObjectAssignmentTargetOrStaticMemberAssignmentTarget)) \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, \ - "AssignmentTargetOrAssignmentTargetWithInitializer", \ - ASSIGNMENT_TARGET_OR_ASSIGNMENT_TARGET_WITH_INITIALIZER, \ - SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrAssignmentTargetWithInitializerOrComputedMemberAssignmentTargetOrObjectAssignmentTargetOrStaticMemberAssignmentTarget)) \ - F(AssignmentTargetOrForInOfBinding, "AssignmentTargetOrForInOfBinding", \ - ASSIGNMENT_TARGET_OR_FOR_IN_OF_BINDING, \ - SUM(ArrayAssignmentTargetOrAssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrForInOfBindingOrObjectAssignmentTargetOrStaticMemberAssignmentTarget)) \ - F(AssignmentTargetPattern, "AssignmentTargetPattern", \ - ASSIGNMENT_TARGET_PATTERN, \ - SUM(ArrayAssignmentTargetOrObjectAssignmentTarget)) \ - F(AssignmentTargetProperty, "AssignmentTargetProperty", \ - ASSIGNMENT_TARGET_PROPERTY, \ - SUM(AssignmentTargetPropertyIdentifierOrAssignmentTargetPropertyProperty)) \ - F(Binding, "Binding", BINDING, \ - SUM(ArrayBindingOrBindingIdentifierOrObjectBinding)) \ - F(BindingOrBindingWithInitializer, "BindingOrBindingWithInitializer", \ - BINDING_OR_BINDING_WITH_INITIALIZER, \ - SUM(ArrayBindingOrBindingIdentifierOrBindingWithInitializerOrObjectBinding)) \ - F(BindingPattern, "BindingPattern", BINDING_PATTERN, \ - SUM(ArrayBindingOrObjectBinding)) \ - F(BindingProperty, "BindingProperty", BINDING_PROPERTY, \ - SUM(BindingPropertyIdentifierOrBindingPropertyProperty)) \ - F(ClassDeclarationOrExpressionOrFunctionDeclaration, \ - "ClassDeclarationOrExpressionOrFunctionDeclaration", \ - CLASS_DECLARATION_OR_EXPRESSION_OR_FUNCTION_DECLARATION, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassDeclarationOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionDeclarationOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionDeclarationOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \ - F(ClassDeclarationOrFunctionDeclarationOrVariableDeclaration, \ - "ClassDeclarationOrFunctionDeclarationOrVariableDeclaration", \ - CLASS_DECLARATION_OR_FUNCTION_DECLARATION_OR_VARIABLE_DECLARATION, \ - SUM(ClassDeclarationOrEagerFunctionDeclarationOrLazyFunctionDeclarationOrVariableDeclaration)) \ - F(ExportDeclaration, "ExportDeclaration", EXPORT_DECLARATION, \ - SUM(ExportOrExportAllFromOrExportDefaultOrExportFromOrExportLocals)) \ - F(ExportDeclarationOrImportDeclarationOrStatement, \ - "ExportDeclarationOrImportDeclarationOrStatement", \ - EXPORT_DECLARATION_OR_IMPORT_DECLARATION_OR_STATEMENT, \ - SUM(BlockOrBreakStatementOrClassDeclarationOrContinueStatementOrDebuggerStatementOrDoWhileStatementOrEagerFunctionDeclarationOrEmptyStatementOrExportOrExportAllFromOrExportDefaultOrExportFromOrExportLocalsOrExpressionStatementOrForInStatementOrForOfStatementOrForStatementOrIfStatementOrImportOrImportNamespaceOrLabelledStatementOrLazyFunctionDeclarationOrReturnStatementOrSwitchStatementOrSwitchStatementWithDefaultOrThrowStatementOrTryCatchStatementOrTryFinallyStatementOrVariableDeclarationOrWhileStatementOrWithStatement)) \ - F(Expression, "Expression", EXPRESSION, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \ - F(ExpressionOrSpreadElement, "ExpressionOrSpreadElement", \ - EXPRESSION_OR_SPREAD_ELEMENT, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrSpreadElementOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \ - F(ExpressionOrSuper, "ExpressionOrSuper", EXPRESSION_OR_SUPER, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrSuperOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \ - F(ExpressionOrTemplateElement, "ExpressionOrTemplateElement", \ - EXPRESSION_OR_TEMPLATE_ELEMENT, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateElementOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrYieldExpressionOrYieldStarExpression)) \ - F(ExpressionOrVariableDeclaration, "ExpressionOrVariableDeclaration", \ - EXPRESSION_OR_VARIABLE_DECLARATION, \ - SUM(ArrayExpressionOrAssignmentExpressionOrAwaitExpressionOrBinaryExpressionOrCallExpressionOrClassExpressionOrCompoundAssignmentExpressionOrComputedMemberExpressionOrConditionalExpressionOrEagerArrowExpressionWithExpressionOrEagerArrowExpressionWithFunctionBodyOrEagerFunctionExpressionOrIdentifierExpressionOrLazyArrowExpressionWithExpressionOrLazyArrowExpressionWithFunctionBodyOrLazyFunctionExpressionOrLiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralRegExpExpressionOrLiteralStringExpressionOrNewExpressionOrNewTargetExpressionOrObjectExpressionOrStaticMemberExpressionOrTemplateExpressionOrThisExpressionOrUnaryExpressionOrUpdateExpressionOrVariableDeclarationOrYieldExpressionOrYieldStarExpression)) \ - F(FunctionDeclaration, "FunctionDeclaration", FUNCTION_DECLARATION, \ - SUM(EagerFunctionDeclarationOrLazyFunctionDeclaration)) \ - F(FunctionExpression, "FunctionExpression", FUNCTION_EXPRESSION, \ - SUM(EagerFunctionExpressionOrLazyFunctionExpression)) \ - F(Getter, "Getter", GETTER, SUM(EagerGetterOrLazyGetter)) \ - F(ImportDeclaration, "ImportDeclaration", IMPORT_DECLARATION, \ - SUM(ImportOrImportNamespace)) \ - F(IterationStatement, "IterationStatement", ITERATION_STATEMENT, \ - SUM(DoWhileStatementOrForInStatementOrForOfStatementOrForStatementOrWhileStatement)) \ - F(Literal, "Literal", LITERAL, \ - SUM(LiteralBooleanExpressionOrLiteralInfinityExpressionOrLiteralNullExpressionOrLiteralNumericExpressionOrLiteralStringExpression)) \ - F(Method, "Method", METHOD, SUM(EagerMethodOrLazyMethod)) \ - F(MethodDefinition, "MethodDefinition", METHOD_DEFINITION, \ - SUM(EagerGetterOrEagerMethodOrEagerSetterOrLazyGetterOrLazyMethodOrLazySetter)) \ - F(ObjectProperty, "ObjectProperty", OBJECT_PROPERTY, \ - SUM(DataPropertyOrEagerGetterOrEagerMethodOrEagerSetterOrLazyGetterOrLazyMethodOrLazySetterOrShorthandProperty)) \ - F(Parameter, "Parameter", PARAMETER, \ - SUM(ArrayBindingOrBindingIdentifierOrBindingWithInitializerOrObjectBinding)) \ - F(Program, "Program", PROGRAM, SUM(ModuleOrScript)) \ - F(PropertyName, "PropertyName", PROPERTY_NAME, \ - SUM(ComputedPropertyNameOrLiteralPropertyName)) \ - F(Setter, "Setter", SETTER, SUM(EagerSetterOrLazySetter)) \ - F(SimpleAssignmentTarget, "SimpleAssignmentTarget", \ - SIMPLE_ASSIGNMENT_TARGET, \ - SUM(AssignmentTargetIdentifierOrComputedMemberAssignmentTargetOrStaticMemberAssignmentTarget)) \ - F(Statement, "Statement", STATEMENT, \ - SUM(BlockOrBreakStatementOrClassDeclarationOrContinueStatementOrDebuggerStatementOrDoWhileStatementOrEagerFunctionDeclarationOrEmptyStatementOrExpressionStatementOrForInStatementOrForOfStatementOrForStatementOrIfStatementOrLabelledStatementOrLazyFunctionDeclarationOrReturnStatementOrSwitchStatementOrSwitchStatementWithDefaultOrThrowStatementOrTryCatchStatementOrTryFinallyStatementOrVariableDeclarationOrWhileStatementOrWithStatement)) - -enum class BinASTSum : uint16_t { -#define EMIT_ENUM(name, _user, _macro, _type) name, - FOR_EACH_BIN_SUM(EMIT_ENUM) -#undef EMIT_ENUM -}; - -// The number of distinct sum types in the grammar. Used typically to maintain a -// probability table per sum type. -const size_t BINAST_NUMBER_OF_SUM_TYPES = 35; - -/** - * Return a string describing a `BinASTKind`. - */ -const char* describeBinASTKind(const BinASTKind& kind); - -/** - * Return a string describing a `BinASTField`. - */ -const char* describeBinASTField(const BinASTField& field); - -/** - * Return a string describing a `BinASTInterfaceAndField`. - */ -const char* describeBinASTInterfaceAndField( - const BinASTInterfaceAndField& field); - -/** - * Return a string describing a `BinASTVariant`. - */ -const char* describeBinASTVariant(const BinASTVariant& variant); - -/** - * Return a string describing a `BinASTList`. - */ -const char* describeBinASTList(const BinASTList& list); - -/** - * Return a sort key for sorting `BinASTKind`s alphabetically. - */ -size_t getBinASTKindSortKey(const BinASTKind& kind); - -/** - * Return a sort key for sorting `BinASTVariant`s alphabetically. - */ -size_t getBinASTVariantSortKey(const BinASTVariant& variant); - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTToken_h diff --git a/js/src/frontend/BinASTTokenReaderBase.cpp b/js/src/frontend/BinASTTokenReaderBase.cpp deleted file mode 100644 index 692696179b..0000000000 --- a/js/src/frontend/BinASTTokenReaderBase.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTTokenReaderBase.h" - -#include "frontend/BinAST-macros.h" -#include "js/Result.h" - -namespace js::frontend { - -template -using ErrorResult = mozilla::GenericErrorResult; - -// We use signalling NaN (which doesn't exist in the JS syntax) -// to represent a `null` number. -const uint64_t NULL_FLOAT_REPRESENTATION = 0x7FF0000000000001; - -void BinASTTokenReaderBase::updateLatestKnownGood() { - MOZ_ASSERT(current_ >= start_); - const size_t update = current_ - start_; - MOZ_ASSERT(update >= latestKnownGoodPos_); - latestKnownGoodPos_ = update; -} - -ErrorResult BinASTTokenReaderBase::raiseError( - const char* description) { - MOZ_ASSERT(!hasRaisedError()); - errorReporter_->errorNoOffset(JSMSG_BINAST, description); - return cx_->alreadyReportedError(); -} - -ErrorResult BinASTTokenReaderBase::raiseOOM() { - ReportOutOfMemory(cx_); - return cx_->alreadyReportedError(); -} - -ErrorResult BinASTTokenReaderBase::raiseInvalidNumberOfFields( - const BinASTKind kind, const uint32_t expected, const uint32_t got) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, invalid number of fields: expected %u, got %u", - describeBinASTKind(kind), expected, got)); - return raiseError(out.string()); -} - -ErrorResult BinASTTokenReaderBase::raiseInvalidField( - const char* kind, const BinASTField field) { - Sprinter out(cx_); - BINJS_TRY(out.init()); - BINJS_TRY(out.printf("In %s, invalid field '%s'", kind, - describeBinASTField(field))); - return raiseError(out.string()); -} - -bool BinASTTokenReaderBase::hasRaisedError() const { - if (cx_->isHelperThreadContext()) { - // When performing off-main-thread parsing, we don't set a pending - // exception but instead add a pending compile error. - return cx_->isCompileErrorPending(); - } - - return cx_->isExceptionPending(); -} - -TokenPos BinASTTokenReaderBase::pos() { return pos(offset()); } - -TokenPos BinASTTokenReaderBase::pos(size_t start) { - TokenPos pos; - pos.begin = start; - pos.end = current_ - start_; - MOZ_ASSERT(pos.end >= pos.begin); - return pos; -} - -void BinASTTokenReaderBase::seek(size_t offset) { - MOZ_ASSERT(start_ + offset >= start_ && start_ + offset < stop_); - current_ = start_ + offset; -} - -JS::Result BinASTTokenReaderBase::readBuf(uint8_t* bytes, uint32_t len) { - MOZ_ASSERT(!hasRaisedError()); - - if (MOZ_UNLIKELY(stop_ < current_ + len)) { - return raiseError("Buffer exceeds length"); - } - - for (uint32_t i = 0; i < len; ++i) { - *bytes++ = *current_++; - } - - return Ok(); -} - -JS::Result BinASTTokenReaderBase::readByte() { - MOZ_ASSERT(!hasRaisedError()); - - if (MOZ_UNLIKELY(stop_ == current_)) { - return raiseError("Buffer exceeds length"); - } - - return *current_++; -} - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTTokenReaderBase.h b/js/src/frontend/BinASTTokenReaderBase.h deleted file mode 100644 index 77c94e0016..0000000000 --- a/js/src/frontend/BinASTTokenReaderBase.h +++ /dev/null @@ -1,237 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTTokenReaderBase_h -#define frontend_BinASTTokenReaderBase_h - -#include "mozilla/Variant.h" - -#include - -#include "frontend/BinASTToken.h" -#include "frontend/ErrorReporter.h" -#include "frontend/TokenStream.h" - -#include "js/Result.h" -#include "js/TypeDecls.h" - -namespace js { -namespace frontend { - -// A constant used by tokenizers to represent a null float. -extern const uint64_t NULL_FLOAT_REPRESENTATION; - -class MOZ_STACK_CLASS BinASTTokenReaderBase { - public: - template - using ErrorResult = mozilla::GenericErrorResult; - - // Part of variant `Context` - // Reading the root of the tree, before we enter any tagged tuple. - struct RootContext {}; - - // Part of variant `Context` - // Reading an element from a list. - struct ListContext { - const BinASTInterfaceAndField position_; - const BinASTList content_; - ListContext(const BinASTInterfaceAndField position, - const BinASTList content) - : position_(position), content_(content) {} - }; - - // Part of variant `Context` - // Reading a field from an interface. - struct FieldContext { - const BinASTInterfaceAndField position_; - explicit FieldContext(const BinASTInterfaceAndField position) - : position_(position) {} - }; - - // The context in which we read a token. - using FieldOrRootContext = mozilla::Variant; - using FieldOrListContext = mozilla::Variant; - -#ifdef DEBUG - // Utility matcher, used to print a `Context` during debugging. - struct ContextPrinter { - static void print(const char* text, const FieldOrRootContext& context) { - fprintf(stderr, "%s ", text); - context.match(ContextPrinter()); - fprintf(stderr, "\n"); - } - static void print(const char* text, const FieldOrListContext& context) { - fprintf(stderr, "%s ", text); - context.match(ContextPrinter()); - fprintf(stderr, "\n"); - } - - void operator()(const RootContext&) { fprintf(stderr, ""); } - void operator()(const ListContext& context) { - fprintf(stderr, ": %s => %s", - describeBinASTInterfaceAndField(context.position_), - describeBinASTList(context.content_)); - } - void operator()(const FieldContext& context) { - fprintf(stderr, ": %s", - describeBinASTInterfaceAndField(context.position_)); - } - }; -#endif // DEBUG - - // The information needed to skip a subtree. - class SkippableSubTree { - public: - SkippableSubTree(const size_t startOffset, const size_t length) - : startOffset_(startOffset), length_(length) {} - - // The position in the source buffer at which the subtree starts. - // - // `SkippableSubTree` does *not* attempt to keep anything alive. - size_t startOffset() const { return startOffset_; } - - // The length of the subtree. - size_t length() const { return length_; } - - private: - const size_t startOffset_; - const size_t length_; - }; - - /** - * Return the position of the latest token. - */ - TokenPos pos(); - TokenPos pos(size_t startOffset); - size_t offset() const { return current_ - start_; } - - // Set the tokenizer's cursor in the file. Use with caution. - void seek(size_t offset); - - /** - * Poison this tokenizer. - */ - void poison(); - - /** - * Raise an error. - * - * Once `raiseError` has been called, the tokenizer is poisoned. - */ - MOZ_MUST_USE ErrorResult raiseError(const char* description); - MOZ_MUST_USE ErrorResult raiseOOM(); - MOZ_MUST_USE ErrorResult raiseInvalidNumberOfFields( - const BinASTKind kind, const uint32_t expected, const uint32_t got); - MOZ_MUST_USE ErrorResult raiseInvalidField( - const char* kind, const BinASTField field); - - protected: - BinASTTokenReaderBase(JSContext* cx, ErrorReporter* er, const uint8_t* start, - const size_t length) - : cx_(cx), - errorReporter_(er), - poisoned_(false), - start_(start), - current_(start), - stop_(start + length), - latestKnownGoodPos_(0) { - MOZ_ASSERT(errorReporter_); - } - - /** - * Read a single byte. - */ - MOZ_MUST_USE JS::Result readByte(); - - /** - * Read several bytes. - * - * If there is not enough data, or if the tokenizer has previously been - * poisoned, return an error. - */ - MOZ_MUST_USE JS::Result readBuf(uint8_t* bytes, uint32_t len); - - /** - * Read a sequence of chars, ensuring that they match an expected - * sequence of chars. - * - * @param value The sequence of chars to expect, NUL-terminated. - */ - template - MOZ_MUST_USE JS::Result readConst(const char (&value)[N]) { - updateLatestKnownGood(); - if (MOZ_UNLIKELY(!matchConst(value, false))) { - return raiseError("Could not find expected literal"); - } - return Ok(); - } - - /** - * Read a sequence of chars, consuming the bytes only if they match an - * expected sequence of chars. - * - * @param value The sequence of chars to expect, NUL-terminated. - * @param expectNul If true, expect NUL in the stream, otherwise don't. - * @return true if `value` represents the next few chars in the - * internal buffer, false otherwise. If `true`, the chars are consumed, - * otherwise there is no side-effect. - */ - template - MOZ_MUST_USE bool matchConst(const char (&value)[N], bool expectNul) { - MOZ_ASSERT(N > 0); - MOZ_ASSERT(value[N - 1] == 0); - MOZ_ASSERT(!hasRaisedError()); - - if (MOZ_UNLIKELY(current_ + N - 1 > stop_)) { - return false; - } - -#ifndef FUZZING - // Perform lookup, without side-effects. - if (memcmp(current_, value, N + (expectNul ? 0 : -1) /*implicit NUL*/) != - 0) { - return false; - } -#endif - - // Looks like we have a match. Now perform side-effects - current_ += N + (expectNul ? 0 : -1); - updateLatestKnownGood(); - return true; - } - - void updateLatestKnownGood(); - - bool hasRaisedError() const; - - JSContext* cx_; - - ErrorReporter* errorReporter_; - - // `true` if we have encountered an error. Errors are non recoverable. - // Attempting to read from a poisoned tokenizer will cause assertion errors. - bool poisoned_; - - // The first byte of the buffer. Not owned. - const uint8_t* start_; - - // The current position. - const uint8_t* current_; - - // The last+1 byte of the buffer. - const uint8_t* stop_; - - // Latest known good position. Used for error reporting. - size_t latestKnownGoodPos_; - - private: - BinASTTokenReaderBase(const BinASTTokenReaderBase&) = delete; - BinASTTokenReaderBase(BinASTTokenReaderBase&&) = delete; - BinASTTokenReaderBase& operator=(BinASTTokenReaderBase&) = delete; -}; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTTokenReaderBase_h diff --git a/js/src/frontend/BinASTTokenReaderContext.cpp b/js/src/frontend/BinASTTokenReaderContext.cpp deleted file mode 100644 index 2708d97a2f..0000000000 --- a/js/src/frontend/BinASTTokenReaderContext.cpp +++ /dev/null @@ -1,3268 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTTokenReaderContext.h" - -#include "mozilla/OperatorNewExtensions.h" // mozilla::KnownNotNull -#include "mozilla/Result.h" // MOZ_TRY* -#include "mozilla/ScopeExit.h" // mozilla::MakeScopeExit - -#include // std::numeric_limits -#include // memchr, memcmp, memmove - -#include "ds/FixedLengthVector.h" // FixedLengthVector -#include "ds/Sort.h" // MergeSort -#include "frontend/BinAST-macros.h" // BINJS_TRY*, BINJS_MOZ_TRY* -#include "gc/Rooting.h" // RootedAtom -#include "js/AllocPolicy.h" // SystemAllocPolicy -#include "js/UniquePtr.h" // js::UniquePtr -#include "js/Utility.h" // js_free -#include "js/Vector.h" // js::Vector -#include "util/StringBuffer.h" // StringBuffer -#include "vm/JSAtom.h" // AtomizeWTF8Chars -#include "vm/JSScript.h" // ScriptSource - -namespace js::frontend { - -#ifdef BINAST_CX_MAGIC_HEADER // Context 0.1 doesn't implement the planned - // magic header. - -// The magic header, at the start of every binjs file. -const char CX_MAGIC_HEADER[] = - "\x89" - "BJS\r\n\0\n"; - -// The latest format version understood by this tokenizer. -const uint32_t MAGIC_FORMAT_VERSION = 2; - -#endif // BINAST_CX_MAGIC_HEADER - -// The maximal length of a single Huffman code, in bits. -// -// Hardcoded in the format. -const uint8_t MAX_CODE_BIT_LENGTH = 20; - -// The maximal number of bits needed to represent bit lengths. -const uint8_t MAX_BIT_LENGTH_BIT_LENGTH = 5; -static_assert(1 << (MAX_BIT_LENGTH_BIT_LENGTH - 1) < MAX_CODE_BIT_LENGTH, - "MAX_BIT_LENGTH_BIT_LENGTH - 1 bits MUST be insufficient to " - "store MAX_CODE_BIT_LENGTH"); -static_assert( - 1 << MAX_BIT_LENGTH_BIT_LENGTH >= MAX_CODE_BIT_LENGTH, - "MAX_BIT_LENGTH bits MUST be sufficient to store MAX_CODE_BIT_LENGTH"); - -// The maximal length of a Huffman prefix. -// -// This is distinct from MAX_CODE_BIT_LENGTH as we commonly load -// more bites than necessary, just to be on the safe side. -const uint8_t MAX_PREFIX_BIT_LENGTH = 32; - -// The length of the bit buffer, in bits. -const uint8_t BIT_BUFFER_SIZE = 64; - -// Number of bits into the `bitBuffer` read at each step. -const uint8_t BIT_BUFFER_READ_UNIT = 8; - -// Hardcoded limits to avoid allocating too eagerly. -const uint32_t MAX_NUMBER_OF_SYMBOLS = 32768; -const uint32_t MAX_LIST_LENGTH = - std::min((uint32_t)32768, NativeObject::MAX_DENSE_ELEMENTS_COUNT); -const size_t HUFFMAN_STACK_INITIAL_CAPACITY = 1024; - -// The number of elements in each sum. -// Note: `extern` is needed to forward declare. -extern const size_t SUM_LIMITS[BINAST_NUMBER_OF_SUM_TYPES]; - -// For each sum, an array of BinASTKind corresponding to the possible value. -// The length of `SUM_RESOLUTIONS[i]` is `SUM_LIMITS[i]`. -// Note: `extern` is needed to forward declare. -extern const BinASTKind* SUM_RESOLUTIONS[BINAST_NUMBER_OF_SUM_TYPES]; - -// The number of elements in each enum. -// Note: `extern` is needed to forward declare. -extern const size_t STRING_ENUM_LIMITS[BINASTSTRINGENUM_LIMIT]; - -// For each string enum, an array of BinASTVariant corresponding to the possible -// value. The length of `STRING_ENUM_RESOLUTIONS[i]` is `STRING_ENUM_LIMITS[i]`. -// Note: `extern` is needed to forward declare. -extern const BinASTVariant* STRING_ENUM_RESOLUTIONS[BINASTSTRINGENUM_LIMIT]; - -using Compression = BinASTTokenReaderContext::Compression; -using EndOfFilePolicy = BinASTTokenReaderContext::EndOfFilePolicy; - -#define WRAP_INTERFACE(TYPE) Interface::Maker(BinASTKind::TYPE) -#define WRAP_MAYBE_INTERFACE(TYPE) MaybeInterface::Maker(BinASTKind::TYPE) -#define WRAP_PRIMITIVE(TYPE) TYPE -#define WRAP_LIST(TYPE, _) List::Maker(BinASTList::TYPE) -#define WRAP_SUM(TYPE) Sum::Maker(BinASTSum::TYPE) -#define WRAP_MAYBE_SUM(TYPE) MaybeSum::Maker(BinASTSum::TYPE) -#define WRAP_STRING_ENUM(TYPE) StringEnum::Maker(BinASTStringEnum::TYPE) -#define WRAP_MAYBE_STRING_ENUM(TYPE) \ - MaybeStringEnum::Maker(BinASTStringEnum::TYPE) - -using CharSlice = BinaryASTSupport::CharSlice; -using Chars = BinASTTokenReaderContext::Chars; - -// Read Huffman tables from the prelude. -class HuffmanPreludeReader { - public: - // Construct a prelude reader. - HuffmanPreludeReader(JSContext* cx, BinASTTokenReaderContext& reader) - : cx_(cx), - reader_(reader), - dictionary_(nullptr), - stack_(cx_), - auxStorageLength_(cx_) {} - - // Start reading the prelude. - MOZ_MUST_USE JS::Result run( - size_t initialCapacity); - - private: - JSContext* cx_; - BinASTTokenReaderContext& reader_; - - // The dictionary we're currently constructing. - UniquePtr dictionary_; - - // Temporary storage for items allocated while reading huffman prelude. - // All items are freed after reading huffman prelude. - TemporaryStorage tempStorage_; - - public: - // Tables may have different representations in the stream. - // - // The value of each variant maps to the value inside the stream. - enum TableHeader : uint8_t { - // Table is optimized to represent a single value. - SingleValue = 0x00, - - // General table, with any number of values. - MultipleValues = 0x01, - - // A special table that contains no value because it is never used. - Unreachable = 0x02, - }; - - // --- Representation of the grammar. - // - // We need to walk the grammar to read the Huffman tables. In this - // implementation, we represent the grammar as a variant type `Entry`, - // composed of subclasses of `EntryBase`. - // - // Note that, while some grammar constructions are theoretically possible - // (e.g. `bool?`), we only implement constructions that actually appear in the - // webidl. Future constructions may be implemented later. - - // Base class for grammar entries. - struct EntryBase { - // The field we are currently reading. - const NormalizedInterfaceAndField identity_; - - explicit EntryBase(const NormalizedInterfaceAndField identity) - : identity_(identity) {} - }; - - // Grammar entries for values that are represented by indexed in a set - // specified by the grammar, e.g booleans, string enums, sums etc - struct EntryIndexed : EntryBase { - // We use `Foo::Indexed` during template substitution to accept - // subclasses of `EntryIndexed`. - using Indexed = Ok; - explicit EntryIndexed(const NormalizedInterfaceAndField identity) - : EntryBase(identity) {} - }; - - struct EntryExplicit : EntryBase { - // We use `Foo::Explicit` during template substitution to accept - // subclasses of `EntryExplicit`. - using Explicit = Ok; - explicit EntryExplicit(const NormalizedInterfaceAndField identity) - : EntryBase(identity) {} - }; - - // A string. - // May be a literal string, identifier name or property key. May not be null. - struct String : EntryExplicit { - explicit String(const NormalizedInterfaceAndField identity) - : EntryExplicit(identity) {} - }; - using IdentifierName = String; - using PropertyKey = String; - - // An optional string. - // May be a literal string, identifier name or property key. - struct MaybeString : EntryExplicit { - explicit MaybeString(const NormalizedInterfaceAndField identity) - : EntryExplicit(identity) {} - }; - using MaybeIdentifierName = MaybeString; - using MaybePropertyKey = MaybeString; - - // A JavaScript number. May not be null. - struct Number : EntryExplicit { - explicit Number(const NormalizedInterfaceAndField identity) - : EntryExplicit(identity) {} - }; - - // A 32-bit integer. May not be null. - struct UnsignedLong : EntryExplicit { - explicit UnsignedLong(const NormalizedInterfaceAndField identity) - : EntryExplicit(identity) {} - }; - - // A boolean. May not be null. - struct Boolean : EntryIndexed { - explicit Boolean(const NormalizedInterfaceAndField identity) - : EntryIndexed(identity) {} - - // Comparing booleans. - // - // As 0 == False < True == 1, we only compare indices. - inline bool lessThan(uint32_t aIndex, uint32_t bIndex) { - MOZ_ASSERT(aIndex <= 1); - MOZ_ASSERT(bIndex <= 1); - return aIndex < bIndex; - } - }; - - // A field encoding a lazy offset. - struct Lazy : EntryExplicit { - explicit Lazy(const NormalizedInterfaceAndField identity) - : EntryExplicit(identity) {} - }; - - // A value of a given interface. May not be null. - struct Interface : EntryIndexed { - // The kind of the interface. - const BinASTKind kind_; - Interface(const NormalizedInterfaceAndField identity, BinASTKind kind) - : EntryIndexed(identity), kind_(kind) {} - - // Utility struct, used in macros to call the constructor as - // `Interface::Maker(kind)(identity)`. - struct Maker { - const BinASTKind kind_; - explicit Maker(BinASTKind kind) : kind_(kind) {} - Interface operator()(const NormalizedInterfaceAndField identity) { - return Interface(identity, kind_); - } - }; - }; - - // An optional value of a given interface. - struct MaybeInterface : EntryIndexed { - // The kind of the interface. - const BinASTKind kind_; - - // Comparing optional interfaces. - // - // As 0 == Null < _ == 1, we only compare indices. - inline bool lessThan(uint32_t aIndex, uint32_t bIndex) { - MOZ_ASSERT(aIndex <= 1); - MOZ_ASSERT(bIndex <= 1); - return aIndex < bIndex; - } - - MaybeInterface(const NormalizedInterfaceAndField identity, BinASTKind kind) - : EntryIndexed(identity), kind_(kind) {} - - // The max number of symbols in a table for this type. - size_t maxMumberOfSymbols() const { return 2; } - - // Utility struct, used in macros to call the constructor as - // `MaybeInterface::Maker(kind)(identity)`. - struct Maker { - const BinASTKind kind_; - explicit Maker(BinASTKind kind) : kind_(kind) {} - MaybeInterface operator()(const NormalizedInterfaceAndField identity) { - return MaybeInterface(identity, kind_); - } - }; - }; - - // A FrozenArray. May not be null. - // - // In practice, this type is used to represent the length of the list. - // Once we have read the model for the length of the list, we push a - // `ListContents` to read the model for the contents of the list. - struct List : EntryExplicit { - // The type of the list, e.g. list of numbers. - // All lists with the same type share a model for their length. - const BinASTList contents_; - - List(const NormalizedInterfaceAndField identity, const BinASTList contents) - : EntryExplicit(identity), contents_(contents) {} - - // Utility struct, used in macros to call the constructor as - // `List::Maker(kind)(identity)`. - struct Maker { - const BinASTList contents_; - explicit Maker(BinASTList contents) : contents_(contents) {} - List operator()(const NormalizedInterfaceAndField identity) { - return {identity, contents_}; - } - }; - }; - - // A FrozenArray. May not be null. - struct ListContents : EntryBase { - explicit ListContents(const NormalizedInterfaceAndField identity) - : EntryBase(identity) {} - }; - - // A choice between several interfaces. May not be null. - struct Sum : EntryIndexed { - // The type of values in the sum. - const BinASTSum contents_; - - // Comparing sum entries alphabetically. - inline bool lessThan(uint32_t aIndex, uint32_t bIndex) { - MOZ_ASSERT(aIndex <= maxNumberOfSymbols()); - MOZ_ASSERT(bIndex <= maxNumberOfSymbols()); - const size_t aKey = getBinASTKindSortKey(interfaceAt(aIndex)); - const size_t bKey = getBinASTKindSortKey(interfaceAt(bIndex)); - return aKey < bKey; - } - - Sum(const NormalizedInterfaceAndField identity, const BinASTSum contents) - : EntryIndexed(identity), contents_(contents) {} - - size_t maxNumberOfSymbols() const { - return SUM_LIMITS[static_cast(contents_)]; - } - - BinASTKind interfaceAt(size_t index) const { - MOZ_ASSERT(index < maxNumberOfSymbols()); - return SUM_RESOLUTIONS[static_cast(contents_)][index]; - } - - // Utility struct, used in macros to call the constructor as - // `Sum::Maker(kind)(identity)`. - struct Maker { - const BinASTSum contents_; - explicit Maker(BinASTSum contents) : contents_(contents) {} - Sum operator()(const NormalizedInterfaceAndField identity) { - return Sum(identity, contents_); - } - }; - }; - - // An optional choice between several interfaces. - struct MaybeSum : EntryIndexed { - // The type of values in the sum. - // We use `BinASTKind::_Null` to represent the null case. - const BinASTSum contents_; - - inline bool lessThan(uint32_t aIndex, uint32_t bIndex) { - return aIndex < bIndex; - } - - MaybeSum(const NormalizedInterfaceAndField identity, - const BinASTSum contents) - : EntryIndexed(identity), contents_(contents) {} - - size_t maxNumberOfSymbols() const { - return SUM_LIMITS[static_cast(contents_)] + 1; - } - - BinASTKind interfaceAt(size_t index) const { - MOZ_ASSERT(index < maxNumberOfSymbols()); - if (index == 0) { - return BinASTKind::_Null; - } - return SUM_RESOLUTIONS[static_cast(contents_)][index - 1]; - } - - // Utility struct, used in macros to call the constructor as - // `MaybeSum::Maker(kind)(identity)`. - struct Maker { - const BinASTSum contents_; - explicit Maker(BinASTSum contents) : contents_(contents) {} - MaybeSum operator()(const NormalizedInterfaceAndField identity) { - return MaybeSum(identity, contents_); - } - }; - }; - - // A choice between several strings. May not be null. - struct StringEnum : EntryIndexed { - // Comparing string enums alphabetically. - inline bool lessThan(uint32_t aIndex, uint32_t bIndex) { - MOZ_ASSERT(aIndex <= maxNumberOfSymbols()); - MOZ_ASSERT(bIndex <= maxNumberOfSymbols()); - const size_t aKey = getBinASTVariantSortKey(variantAt(aIndex)); - const size_t bKey = getBinASTVariantSortKey(variantAt(bIndex)); - return aKey < bKey; - } - - // The values in the enum. - const BinASTStringEnum contents_; - StringEnum(const NormalizedInterfaceAndField identity, - const BinASTStringEnum contents) - : EntryIndexed(identity), contents_(contents) {} - - size_t maxNumberOfSymbols() const { - return STRING_ENUM_LIMITS[static_cast(contents_)]; - } - - BinASTVariant variantAt(size_t index) const { - MOZ_ASSERT(index < maxNumberOfSymbols()); - return STRING_ENUM_RESOLUTIONS[static_cast(contents_)][index]; - } - - // Utility struct, used in macros to call the constructor as - // `StringEnum::Maker(kind)(identity)`. - struct Maker { - const BinASTStringEnum contents_; - explicit Maker(BinASTStringEnum contents) : contents_(contents) {} - StringEnum operator()(const NormalizedInterfaceAndField identity) { - return StringEnum(identity, contents_); - } - }; - }; - - public: - // The entries in the grammar. - using Entry = mozilla::Variant< - // Primitives - Boolean, String, MaybeString, Number, UnsignedLong, Lazy, - // Combinators - Interface, MaybeInterface, List, Sum, MaybeSum, StringEnum>; - -#ifdef DEBUG - // Utility struct, designed to inspect an `Entry` while debugging. - struct PrintEntry { - static void print(const char* text, const Entry& entry) { - fprintf(stderr, "%s ", text); - entry.match(PrintEntry()); - fprintf(stderr, "\n"); - } - void operator()(const EntryBase& entry) { - fprintf(stderr, "%s", - describeBinASTInterfaceAndField(entry.identity_.identity_)); - } - }; -#endif // DEBUG - - private: - // A stack of entries to process. We always process the latest entry added. - Vector stack_; - - /* - Implementation of "To push a field" from the specs. - - As per the spec: - - 1. If the field is in the set of visited contexts, stop - 2. Add the field to the set of visited fields - 3. If the field has a FrozenArray type - a. Determine if the array type is always empty - b. If so, stop - 4. If the effective type is a monomorphic interface, push all of the - interface’s fields - 5. Otherwise, push the field onto the stack - */ - - // Enqueue an entry to the stack. - MOZ_MUST_USE JS::Result pushValue(NormalizedInterfaceAndField identity, - const List& list) { - const auto tableId = TableIdentity(list.contents_); - if (dictionary_->isUnreachable(tableId)) { - // Spec: - // 2. Add the field to the set of visited fields - dictionary_->setInitializing(tableId); - - // Read the lengths immediately. - MOZ_TRY((readTable(tableId, list))); - } - - // Spec: - // 3. If the field has a FrozenArray type - // a. Determine if the array type is always empty - // b. If so, stop - const auto& table = dictionary_->getTable(tableId); - bool empty = true; - for (auto iter : table) { - if (iter->toListLength() > 0) { - empty = false; - break; - } - } - if (empty) { - return Ok(); - } - - // Spec: - // To determine a field’s effective type: - // 1. If the field’s type is an array type, the effective type is the - // array element type. Stop. - - // We now recurse with the contents of the list/array, *without checking - // whether the field has already been visited*. - switch (list.contents_) { -#define WRAP_LIST_2(_, CONTENT) CONTENT -#define EMIT_CASE(LIST_NAME, _CONTENT_TYPE, _HUMAN_NAME, TYPE) \ - case BinASTList::LIST_NAME: \ - return pushValue(list.identity_, TYPE(list.identity_)); - - FOR_EACH_BIN_LIST(EMIT_CASE, WRAP_PRIMITIVE, WRAP_INTERFACE, - WRAP_MAYBE_INTERFACE, WRAP_LIST_2, WRAP_SUM, - WRAP_MAYBE_SUM, WRAP_STRING_ENUM, - WRAP_MAYBE_STRING_ENUM) -#undef EMIT_CASE -#undef WRAP_LIST_2 - } - return Ok(); - } - - MOZ_MUST_USE JS::Result pushValue(NormalizedInterfaceAndField identity, - const Interface& interface) { - const auto tableId = TableIdentity(identity); - if (dictionary_->isUnreachable(tableId)) { - // Effectively, an `Interface` is a sum with a single entry. - auto& table = dictionary_->createTable(tableId); - - MOZ_TRY(table.initWithSingleValue( - cx_, BinASTSymbol::fromKind(BinASTKind(interface.kind_)))); - } - - // Spec: - // 4. If the effective type is a monomorphic interface, push all of the - // interface’s fields - return pushFields(interface.kind_); - } - - // Generic implementation for other cases. - template - MOZ_MUST_USE JS::Result pushValue(NormalizedInterfaceAndField identity, - const Entry& entry) { - // Spec: - // 1. If the field is in the set of visited contexts, stop. - const auto tableId = TableIdentity(identity); - if (!dictionary_->isUnreachable(tableId)) { - // Entry already initialized/initializing. - return Ok(); - } - - // Spec: - // 2. Add the field to the set of visited fields - dictionary_->setInitializing(tableId); - - // Spec: - // 5. Otherwise, push the field onto the stack - BINJS_TRY(stack_.append(entry)); - return Ok(); - } - - // Enqueue all the fields of an interface to the stack. - JS::Result pushFields(BinASTKind tag) { - /* - Generate a static implementation of pushing fields. - - switch (tag) { - case BinASTKind::$TagName: { - MOZ_TRY(pushValue(NormalizedInterfaceAndField(BinASTIterfaceAndField::$Name), - Entry(FIELD_TYPE(NormalizedInterfaceAndField(BinASTInterfaceAndField::$Name))))); - // ... - break; - } - // ... - } - */ - - switch (tag) { -#define EMIT_FIELD(TAG_NAME, FIELD_NAME, FIELD_INDEX, FIELD_TYPE, _) \ - MOZ_TRY(pushValue(NormalizedInterfaceAndField( \ - BinASTInterfaceAndField::TAG_NAME##__##FIELD_NAME), \ - FIELD_TYPE(NormalizedInterfaceAndField( \ - BinASTInterfaceAndField::TAG_NAME##__##FIELD_NAME)))); -#define EMIT_CASE(TAG_ENUM_NAME, _2, TAG_MACRO_NAME) \ - case BinASTKind::TAG_ENUM_NAME: { \ - FOR_EACH_BIN_FIELD_IN_INTERFACE_##TAG_MACRO_NAME( \ - EMIT_FIELD, WRAP_PRIMITIVE, WRAP_INTERFACE, WRAP_MAYBE_INTERFACE, \ - WRAP_LIST, WRAP_SUM, WRAP_MAYBE_SUM, WRAP_STRING_ENUM, \ - WRAP_MAYBE_STRING_ENUM); \ - break; \ - } - FOR_EACH_BIN_KIND(EMIT_CASE) -#undef EMIT_CASE -#undef EMIT_FIELD - } - - return Ok(); - } - - // Read a single symbol. - // For an indexed type, the symbol is fetched from the grammar using `index`. - // We have a guarantee that `index` is always in [0, numberOfSymbols). - template - MOZ_MUST_USE JS::Result readSymbol(const Entry&, size_t index); - - // Read the number of symbols in an entry. - // For an indexed type, theis number is fetched from the grammar. - // We have a guarantee that `index` is always in [0, numberOfSymbols) - template - MOZ_MUST_USE JS::Result readNumberOfSymbols(const Entry&); - - // Read a table in the optimized "only one value" format. - template - MOZ_MUST_USE JS::Result readSingleValueTable(GenericHuffmanTable&, - const Entry&); - - // Read a table in the non-optimized format. - // - // Entries in the table are represented in an order that is specific to each - // type. See the documentation of each `ReadPoppedEntryMatcher::operator()` - // for a discussion on each order. - template - MOZ_MUST_USE JS::Result readMultipleValuesTable( - GenericHuffmanTable& table, Entry entry) { - // Get the number of symbols. - // If `Entry` is an indexed type, this is fetched from the grammar. - BINJS_MOZ_TRY_DECL(numberOfSymbols, readNumberOfSymbols(entry)); - - MOZ_ASSERT(numberOfSymbols <= MAX_NUMBER_OF_SYMBOLS); - - if (numberOfSymbols == 1) { - // Special case: only one symbol. - BINJS_MOZ_TRY_DECL(bitLength, reader_.readByte()); - if (MOZ_UNLIKELY(bitLength != 0)) { - // Since there is a single symbol, it doesn't make sense to have a non-0 - // bit length. - return raiseInvalidTableData(entry.identity_); - } - - // Read the symbol. - // If `Entry` is an indexed type, it is fetched directly from the grammar. - BINJS_MOZ_TRY_DECL( - symbol, readSymbol(entry, /* First and only value */ 0)); - - MOZ_TRY(table.initWithSingleValue(cx_, symbol)); - return Ok(); - } - - MOZ_TRY(readMultipleValuesTableAndAssignCode(table, entry, - numberOfSymbols)); - - // Note that the table may be empty, in the case of a list that never has - // any elements. - return Ok(); - } - - template - MOZ_MUST_USE JS::Result - readMultipleValuesTableAndAssignCode(GenericHuffmanTable& table, Entry entry, - uint32_t numberOfSymbols) { - // Explicit entry: - // - All symbols must be read from disk. - // - Lengths read from disk are bit lengths. - // - Bit lengths are ranked by increasing order. - // - Bit lengths MUST NOT be 0. - - // Data is presented in an order that doesn't match our memory - // representation, so we need to copy `numberOfSymbols` entries. - // We use an auxiliary vector to avoid allocating each time. - MOZ_ASSERT( - auxStorageLength_.empty()); // We must have cleaned it up properly. - BINJS_TRY(auxStorageLength_.reserve(numberOfSymbols + 1)); - - uint8_t largestBitLength = 0; - - // First read and store the bit lengths for all symbols. - for (size_t i = 0; i < numberOfSymbols; ++i) { - BINJS_MOZ_TRY_DECL(bitLength, reader_.readByte()); - if (MOZ_UNLIKELY(bitLength == 0)) { - return raiseInvalidTableData(entry.identity_); - } - if (bitLength > largestBitLength) { - largestBitLength = bitLength; - } - // Already reserved sufficient space above. - auxStorageLength_.infallibleAppend(BitLengthAndIndex(bitLength, i)); - } - // Append a terminator. - // Already reserved sufficient space above. - auxStorageLength_.infallibleAppend( - BitLengthAndIndex(MAX_CODE_BIT_LENGTH, numberOfSymbols)); - - // Now read the symbols and assign bits. - uint32_t code = 0; - MOZ_TRY( - table.initStart(cx_, &tempStorage_, numberOfSymbols, largestBitLength)); - - for (size_t i = 0; i < numberOfSymbols; ++i) { - const auto bitLength = auxStorageLength_[i].bitLength_; - const auto nextBitLength = - auxStorageLength_[i + 1] - .bitLength_; // Guaranteed to exist, as we have a terminator. - - if (MOZ_UNLIKELY(bitLength > nextBitLength)) { - // By format invariant, bit lengths are always non-0 - // and always ranked by increasing order. - return raiseInvalidTableData(entry.identity_); - } - - // Read and add symbol. - BINJS_MOZ_TRY_DECL( - symbol, readSymbol(entry, i)); // Symbol is read from disk. - MOZ_TRY(table.addSymbol(i, code, bitLength, symbol)); - - // Prepare next code. - code = (code + 1) << (nextBitLength - bitLength); - } - - MOZ_TRY(table.initComplete(cx_, &tempStorage_)); - auxStorageLength_.clear(); - return Ok(); - } - - template - MOZ_MUST_USE JS::Result - readMultipleValuesTableAndAssignCode(GenericHuffmanTable& table, Entry entry, - uint32_t numberOfSymbols) { - // In this case, `numberOfSymbols` is actually an upper bound, - // rather than an actual number of symbols. - - // Data is presented in an order that doesn't match our memory - // representation, so we need to copy `numberOfSymbols` entries. - // We use an auxiliary vector to avoid allocating each time. - MOZ_ASSERT( - auxStorageLength_.empty()); // We must have cleaned it up properly. - BINJS_TRY(auxStorageLength_.reserve(numberOfSymbols + 1)); - - // Implicit entry: - // - Symbols are known statically. - // - Lengths MAY be 0. - // - Lengths are not sorted on disk. - - uint8_t largestBitLength = 0; - - // First read the length for all symbols, only store non-0 lengths. - for (size_t i = 0; i < numberOfSymbols; ++i) { - BINJS_MOZ_TRY_DECL(bitLength, reader_.readByte()); - if (MOZ_UNLIKELY(bitLength > MAX_CODE_BIT_LENGTH)) { - MOZ_CRASH("FIXME: Implement error"); - } - if (bitLength > 0) { - // Already reserved sufficient space above. - auxStorageLength_.infallibleAppend(BitLengthAndIndex(bitLength, i)); - if (bitLength > largestBitLength) { - largestBitLength = bitLength; - } - } - } - - if (auxStorageLength_.length() == 1) { - // We have only one symbol, so let's use an optimized table. - BINJS_MOZ_TRY_DECL(symbol, - readSymbol(entry, auxStorageLength_[0].index_)); - MOZ_TRY(table.initWithSingleValue(cx_, symbol)); - auxStorageLength_.clear(); - return Ok(); - } - - // Sort by length then webidl order (which is also the index). - std::sort(auxStorageLength_.begin(), auxStorageLength_.end(), - [&entry](const BitLengthAndIndex& a, - const BitLengthAndIndex& b) -> bool { - MOZ_ASSERT(a.index_ != b.index_); - // Compare first by bit length. - if (a.bitLength_ < b.bitLength_) { - return true; - } - if (a.bitLength_ > b.bitLength_) { - return false; - } - // In case of equal bit length, compare by symbol value. - return entry.lessThan(a.index_, b.index_); - }); - - // Append a terminator. - // Already reserved sufficient space above. - auxStorageLength_.infallibleEmplaceBack(MAX_CODE_BIT_LENGTH, - numberOfSymbols); - - // Now read the symbols and assign bits. - uint32_t code = 0; - MOZ_TRY(table.initStart(cx_, &tempStorage_, auxStorageLength_.length() - 1, - largestBitLength)); - - for (size_t i = 0; i < auxStorageLength_.length() - 1; ++i) { - const auto bitLength = auxStorageLength_[i].bitLength_; - const auto nextBitLength = - auxStorageLength_[i + 1].bitLength_; // Guaranteed to exist, as we - // stop before the terminator. - MOZ_ASSERT(bitLength > 0); - MOZ_ASSERT(bitLength <= nextBitLength); - - // Read symbol from memory and add it. - BINJS_MOZ_TRY_DECL(symbol, - readSymbol(entry, auxStorageLength_[i].index_)); - - MOZ_TRY(table.addSymbol(i, code, bitLength, symbol)); - - // Prepare next code. - code = (code + 1) << (nextBitLength - bitLength); - } - - MOZ_TRY(table.initComplete(cx_, &tempStorage_)); - - auxStorageLength_.clear(); - return Ok(); - } - - // Single-argument version: lookup the table using `dictionary_->table` - // then proceed as three-arguments version. - template - MOZ_MUST_USE JS::Result readTable(Entry entry) { - const auto tableId = TableIdentity(entry.identity_); - if (MOZ_UNLIKELY(!dictionary_->isInitializing(tableId))) { - // We're attempting to re-read a table that has already been read. - // FIXME: Shouldn't this be a MOZ_CRASH? - return raiseDuplicateTableError(entry.identity_); - } - - return readTable(tableId, entry); - } - - // Two-arguments version: pass table identity explicitly. Generally called - // from single-argument version, but may be called manually, e.g. for list - // lengths. - template - MOZ_MUST_USE JS::Result readTable(TableIdentity tableId, Entry entry) { - uint8_t headerByte; - MOZ_TRY_VAR(headerByte, reader_.readByte()); - switch (headerByte) { - case TableHeader::SingleValue: { - auto& table = dictionary_->createTable(tableId); - - // The table contains a single value. - MOZ_TRY((readSingleValueTable(table, entry))); - return Ok(); - } - case TableHeader::MultipleValues: { - auto& table = dictionary_->createTable(tableId); - - // Table contains multiple values. - MOZ_TRY((readMultipleValuesTable(table, entry))); - return Ok(); - } - case TableHeader::Unreachable: - // Table is unreachable, nothing to do. - return Ok(); - default: - return raiseInvalidTableData(entry.identity_); - } - } - - private: - // An auxiliary storage of bit lengths and indices, used when reading - // a table with multiple entries. Used to avoid (re)allocating a - // vector of lengths each time we read a table. - struct BitLengthAndIndex { - BitLengthAndIndex(uint8_t bitLength, size_t index) - : bitLength_(bitLength), index_(index) {} - - // A bitLength, as read from disk. - uint8_t bitLength_; - - // The index of the entry in the table. - size_t index_; - }; - Vector auxStorageLength_; - - // Implementation of pattern-matching cases for `entry.match`. - struct ReadPoppedEntryMatcher { - // The owning HuffmanPreludeReader. - HuffmanPreludeReader& owner; - - explicit ReadPoppedEntryMatcher(HuffmanPreludeReader& owner) - : owner(owner) {} - - // Lazy. - // Values: no value/ - MOZ_MUST_USE JS::Result operator()(const Lazy& entry) { - // Nothing to do. - return Ok(); - } - - // Boolean. - // Values: [false, true], in this order. - MOZ_MUST_USE JS::Result operator()(const Boolean& entry) { - return owner.readTable(entry); - } - - // Interface. - // Values: no value. - MOZ_MUST_USE JS::Result operator()(const Interface& entry) { - // No table here, just push fields. - return owner.pushFields(entry.kind_); - } - - // Optional Interface. - // Values: [null, non-null]. - MOZ_MUST_USE JS::Result operator()(const MaybeInterface& entry) { - // First, we need a table to determine whether the value is `null`. - MOZ_TRY((owner.readTable(entry))); - - // Then, if the table contains `true`, we need the fields of the - // interface. - // FIXME: readTable could return a reference to the table, eliminating an - // array lookup. - const auto tableId = TableIdentity(entry.identity_); - if (owner.dictionary_->isUnreachable(tableId)) { - return Ok(); - } - - const auto& table = owner.dictionary_->getTable(tableId); - if (!table.isMaybeInterfaceAlwaysNull()) { - MOZ_TRY(owner.pushFields(entry.kind_)); - } - return Ok(); - } - - // Sum of interfaces, non-nullable. - // Values: interfaces by the order in `FOR_EACH_BIN_INTERFACE_IN_SUM_*`. - MOZ_MUST_USE JS::Result operator()(const Sum& entry) { - // First, we need a table to determine which values are present. - MOZ_TRY((owner.readTable(entry))); - - // Now, walk the table to enqueue each value if necessary. - // FIXME: readTable could return a reference to the table, eliminating an - // array lookup. - - const auto tableId = TableIdentity(entry.identity_); - if (owner.dictionary_->isInitializing(tableId)) { - return Ok(); - } - - auto index = entry.identity_; - const auto& table = owner.dictionary_->getTable(tableId); - for (auto iter : table) { - MOZ_TRY(owner.pushValue(index, Interface(index, iter->toKind()))); - } - return Ok(); - } - - // Sum of interfaces, nullable. - // Values: `null`, followed by interfaces by the order in - // `FOR_EACH_BIN_INTERFACE_IN_SUM_*`. - MOZ_MUST_USE JS::Result operator()(const MaybeSum& entry) { - // First, we need a table to determine which values are present. - MOZ_TRY((owner.readTable(entry))); - - // Now, walk the table to enqueue each value if necessary. - // FIXME: readTable could return a reference to the table, eliminating an - // array lookup. - const auto tableId = TableIdentity(entry.identity_); - if (owner.dictionary_->isUnreachable(tableId)) { - return Ok(); - } - - auto index = entry.identity_; - const auto& table = owner.dictionary_->getTable(tableId); - for (auto iter : table) { - MOZ_TRY(owner.pushValue(index, Interface(index, iter->toKind()))); - } - return Ok(); - } - - MOZ_MUST_USE JS::Result operator()(const Number& entry) { - return owner.readTable(entry); - } - - MOZ_MUST_USE JS::Result operator()(const String& entry) { - return owner.readTable(entry); - } - - MOZ_MUST_USE JS::Result operator()(const MaybeString& entry) { - return owner.readTable(entry); - } - - MOZ_MUST_USE JS::Result operator()(const StringEnum& entry) { - return owner.readTable(entry); - } - - MOZ_MUST_USE JS::Result operator()(const UnsignedLong& entry) { - return owner.readTable(entry); - } - - MOZ_MUST_USE JS::Result operator()(const List&) { - MOZ_CRASH("Unreachable"); - return Ok(); - } - }; - - template - using ErrorResult = BinASTTokenReaderBase::ErrorResult; - - MOZ_MUST_USE ErrorResult raiseDuplicateTableError( - const NormalizedInterfaceAndField identity) { - return reader_.raiseError("Duplicate table."); - } - - MOZ_MUST_USE ErrorResult raiseInvalidTableData( - const NormalizedInterfaceAndField identity) { - return reader_.raiseError("Invalid data while reading table."); - } -}; - -using Boolean = HuffmanPreludeReader::Boolean; -using Interface = HuffmanPreludeReader::Interface; -using List = HuffmanPreludeReader::List; -using MaybeInterface = HuffmanPreludeReader::MaybeInterface; -using MaybeString = HuffmanPreludeReader::MaybeString; -using MaybeSum = HuffmanPreludeReader::MaybeSum; -using Number = HuffmanPreludeReader::Number; -using String = HuffmanPreludeReader::String; -using StringEnum = HuffmanPreludeReader::StringEnum; -using Sum = HuffmanPreludeReader::Sum; -using UnsignedLong = HuffmanPreludeReader::UnsignedLong; - -BinASTTokenReaderContext::BinASTTokenReaderContext(JSContext* cx, - ErrorReporter* er, - const uint8_t* start, - const size_t length) - : BinASTTokenReaderBase(cx, er, start, length), - metadata_(nullptr), - posBeforeTree_(nullptr), - lazyScripts_(cx) { - MOZ_ASSERT(er); -} - -BinASTTokenReaderContext::~BinASTTokenReaderContext() { - if (metadata_ && metadataOwned_ == MetadataOwnership::Owned) { - UniqueBinASTSourceMetadataPtr ptr(metadata_); - } -} - -template <> -JS::Result -BinASTTokenReaderContext::readBuf( - uint8_t* bytes, uint32_t& len) { - return Base::readBuf(bytes, len); -} - -template <> -JS::Result -BinASTTokenReaderContext::readBuf( - uint8_t* bytes, uint32_t& len) { - len = std::min((uint32_t)(stop_ - current_), len); - return Base::readBuf(bytes, len); -} - -template <> -JS::Result -BinASTTokenReaderContext::handleEndOfStream() { - return raiseError("Unexpected end of stream"); -} - -template <> -JS::Result -BinASTTokenReaderContext::handleEndOfStream() { - return Ok(); -} - -template <> -JS::Result BinASTTokenReaderContext::readByte() { - return Base::readByte(); -} - -BinASTSourceMetadata* BinASTTokenReaderContext::takeMetadata() { - MOZ_ASSERT(metadataOwned_ == MetadataOwnership::Owned); - metadataOwned_ = MetadataOwnership::Unowned; - return metadata_; -} - -JS::Result BinASTTokenReaderContext::initFromScriptSource( - ScriptSource* scriptSource) { - metadata_ = scriptSource->binASTSourceMetadata()->asContext(); - metadataOwned_ = MetadataOwnership::Unowned; - - return Ok(); -} - -JS::Result BinASTTokenReaderContext::readHeader() { - // Check that we don't call this function twice. - MOZ_ASSERT(!posBeforeTree_); - -#if BINAST_CX_MAGIC_HEADER - // Read global headers. - MOZ_TRY(readConst(CX_MAGIC_HEADER)); - BINJS_MOZ_TRY_DECL(version, readVarU32()); - - if (MOZ_UNLIKELY(version != MAGIC_FORMAT_VERSION)) { - return raiseError("Format version not implemented"); - } -#endif // BINAST_CX_MAGIC_HEADER - - MOZ_TRY(readStringPrelude()); - MOZ_TRY(readHuffmanPrelude()); - - return Ok(); -} - -JS::Result BinASTTokenReaderContext::readTreeFooter() { - flushBitStream(); - - BINJS_MOZ_TRY_DECL(numLazy, readVarU32()); - if (numLazy != lazyScripts_.length()) { - return raiseError("The number of lazy functions does not match"); - } - - for (size_t i = 0; i < numLazy; i++) { - BINJS_MOZ_TRY_DECL(len, readVarU32()); - // Use sourceEnd as temporary space to store length of each script. - lazyScripts_[i]->setEnd(len); - } - - for (size_t i = 0; i < numLazy; i++) { - uint32_t begin = offset(); - uint32_t len = lazyScripts_[i]->extent.sourceEnd; - - current_ += len; - - lazyScripts_[i]->setStart(begin, 0, begin); - lazyScripts_[i]->setEnd(begin + len); - } - - return Ok(); -} - -void BinASTTokenReaderContext::flushBitStream() { - current_ -= bitBuffer.numUnusedBytes(); - bitBuffer.flush(); -} - -JS::Result BinASTTokenReaderContext::readStringPrelude() { - BINJS_MOZ_TRY_DECL(stringsNumberOfEntries, readVarU32()); - - const uint32_t MAX_NUMBER_OF_STRINGS = 32768; - - if (MOZ_UNLIKELY(stringsNumberOfEntries > MAX_NUMBER_OF_STRINGS)) { - return raiseError("Too many entries in strings dictionary"); - } - - BinASTSourceMetadataContext* metadata = - BinASTSourceMetadataContext::create(stringsNumberOfEntries); - if (MOZ_UNLIKELY(!metadata)) { - return raiseOOM(); - } - - // Free it if we don't make it out of here alive. Since we don't want to - // calloc(), we need to avoid marking atoms that might not be there. - auto se = mozilla::MakeScopeExit([metadata]() { js_free(metadata); }); - - // Below, we read at most DECODED_BUFFER_SIZE bytes at once and look for - // strings there. We can overrun to the model part, and in that case put - // unused part back to `decodedBuffer_`. - - RootedAtom atom(cx_); - - for (uint32_t stringIndex = 0; stringIndex < stringsNumberOfEntries; - stringIndex++) { - if (MOZ_UNLIKELY(current_ >= stop_)) { - return raiseError("End of file reached while reading strings table"); - } - - const uint8_t* end = - static_cast(memchr(current_, '\0', stop_ - current_)); - if (MOZ_UNLIKELY(!end)) { - return raiseError("Invalid string, missing NUL"); - } - - // FIXME: handle 0x01-escaped string here. - - const char* start = reinterpret_cast(current_); - BINJS_TRY_VAR(atom, AtomizeWTF8Chars(cx_, start, end - current_)); - - metadata->getAtom(stringIndex) = atom; - - // +1 for skipping 0x00. - current_ = end + 1; - } - - // Found all strings. The remaining data is kept in buffer and will be - // used for later read. - - MOZ_ASSERT(!metadata_); - se.release(); - metadata_ = metadata; - metadataOwned_ = MetadataOwnership::Owned; - - return Ok(); -} - -JS::Result BinASTTokenReaderContext::readHuffmanPrelude() { - HuffmanPreludeReader reader(cx_, *this); - BINJS_MOZ_TRY_DECL(dictionary, reader.run(HUFFMAN_STACK_INITIAL_CAPACITY)); - metadata_->setDictionary(dictionary); - return Ok(); -} - -BinASTTokenReaderContext::BitBuffer::BitBuffer() : bits_(0), bitLength_(0) { - static_assert(sizeof(bits_) * 8 == BIT_BUFFER_SIZE, - "Expecting bitBuffer to match BIT_BUFFER_SIZE"); -} - -template -JS::Result BinASTTokenReaderContext::BitBuffer::getHuffmanLookup( - BinASTTokenReaderContext& owner) { - // First, read data if necessary. - - // The algorithm is not intuitive, so consider an example, where the byte - // stream starts with `0b_HGFE_DCBA`, `0b_PONM_LKJI`, `0b_XWVU_TRSQ`, - // `0b_6543_21ZY` - // - // In each byte, bits are stored in the reverse order, so what we want - // is `0b_ABCD_EFGH`, `0b_IJML_MNOP`, `0b_QRST_UVWX`, `0b_YZ12_3456`. - // For the example, let's assume that we have already read - // `0b_ABCD_EFGH`, `0b_IJKL_MNOP` into `bits`, so before the call to - // `getHuffmanLookup`, `bits` initially contains - // `0b_XXXX_XXXX__XXXX_XXXX__ABCD_EFGH__IJKL_MNOP`, where `X` are bits that - // are beyond `bitLength_` - - if (bitLength_ <= MAX_PREFIX_BIT_LENGTH) { - // Keys can be up to MAX_PREFIX_BIT_LENGTH bits long. If we have fewer bits - // available, it's time to reload. We'll try and get as close to 64 bits as - // possible. - - // Make an array to store the new data. We can read up to 8 bytes - uint8_t bytes[8] = {}; - // Determine the number of bytes in `bits` rounded up to the nearest byte. - uint32_t bytesInBits = - (bitLength_ + BIT_BUFFER_READ_UNIT - 1) / BIT_BUFFER_READ_UNIT; - // Determine the number of bytes we need to read to get `bitLength` as close - // as possible to 64 - uint32_t readLen = sizeof(bytes) - bytesInBits; - // Try to read `readLen` bytes. If we read less than 8 bytes, the last `8 - - // readLen` indices contain zeros. Since the most significant bytes of the - // data are stored in the lowest indices, `bytes` is big endian. - MOZ_TRY((owner.readBuf( - bytes, readLen))); - // Combine `bytes` array into `newBits` - uint64_t newBits = (static_cast(bytes[0]) << 56) | - (static_cast(bytes[1]) << 48) | - (static_cast(bytes[2]) << 40) | - (static_cast(bytes[3]) << 32) | - (static_cast(bytes[4]) << 24) | - (static_cast(bytes[5]) << 16) | - (static_cast(bytes[6]) << 8) | - static_cast(bytes[7]); - static_assert(sizeof(bytes) == sizeof(newBits), - "Expecting bytes array to match size of newBits"); - // After reading `readLen` bytes in our example, `bytes` will contain - // `{0b_XWSU_TSRQ, 0b_6543_21ZY, 0, 0, 0, 0, 0, 0}` - // and `newBits` contains zeros in the lower 32 bits and - // `0b_XWSU_TSRQ__6543_21ZY__0000_0000__0000_0000` in the upper 32 bits - - // Remove any zeros if we read less than 8 bytes - newBits >>= (BIT_BUFFER_READ_UNIT * (sizeof(bytes) - readLen)); - // Now the upper 32 bits of `newBits` are all zero and the lower 32 bits - // contain `0b_0000_0000__0000_0000__XWSU_TSRQ__6543_21ZY` - - // Let's reverse the bits in each of the 8 bytes in `newBits` in place - // First swap alternating bits - newBits = ((newBits >> 1) & 0x5555555555555555) | - ((newBits & 0x5555555555555555) << 1); - // Then swap alternating groups of 2 bits - newBits = ((newBits >> 2) & 0x3333333333333333) | - ((newBits & 0x3333333333333333) << 2); - // Finally swap alternating nibbles - newBits = ((newBits >> 4) & 0x0F0F0F0F0F0F0F0F) | - ((newBits & 0x0F0F0F0F0F0F0F0F) << 4); - // Now the lower 32 bits of `newBits` contain - // `0b_0000_0000__0000_0000__QRST_UVWX__YZ12_3456` - - bitLength_ += (BIT_BUFFER_READ_UNIT * readLen); - // Make room for the new data by shifting `bits` to get - // `0b_ABCD_EFGH__IJKL_MNOP__0000_0000__0000_0000` - // check that we're not shifting by 64 since it's UB for a uint64_t - if (readLen != 8) { - bits_ <<= (BIT_BUFFER_READ_UNIT * readLen); - // Finally, combine `newBits` with `bits` to get - // `0b_ABCD_EFGH__IJKL_MNOP__QRST_UVWX__YZ12_3456` - bits_ += newBits; - } - // If read 8 bytes just set `bits` to the new data - else { - bits_ = newBits; - } - // Now, we may prepare a `HuffmanLookup` with up to 32 bits. - if (bitLength_ <= MAX_PREFIX_BIT_LENGTH) { - return HuffmanLookup(bits_, bitLength_); - } - } - - // Keep only 32 bits. We perform the operation on 64 bits to avoid any - // arithmetics surprise. - const uint64_t bitPrefix = bits_ >> (bitLength_ - MAX_PREFIX_BIT_LENGTH); - MOZ_ASSERT(bitPrefix <= uint32_t(-1)); - return HuffmanLookup(bitPrefix, MAX_PREFIX_BIT_LENGTH); -} - -template <> -void BinASTTokenReaderContext::BitBuffer::advanceBitBuffer( - const uint8_t bitLength) { - // It should be impossible to call `advanceBitBuffer` - // with more bits than what we just handed out. - MOZ_ASSERT(bitLength <= bitLength_); - - bitLength_ -= bitLength; - - // Now zero out the bits that are beyond `bitLength_`. - const uint64_t mask = bitLength_ == 0 - ? 0 // >> 64 is UB for a uint64_t - : uint64_t(-1) >> (BIT_BUFFER_SIZE - bitLength_); - bits_ &= mask; - MOZ_ASSERT_IF(bitLength_ != BIT_BUFFER_SIZE, bits_ >> bitLength_ == 0); -} - -void BinASTTokenReaderContext::traceMetadata(JSTracer* trc) { - if (metadata_) { - metadata_->trace(trc); - } -} - -MOZ_MUST_USE mozilla::GenericErrorResult -BinASTTokenReaderContext::raiseInvalidValue() { - errorReporter_->errorNoOffset(JSMSG_BINAST, "Invalid value"); - return cx_->alreadyReportedError(); -} - -MOZ_MUST_USE mozilla::GenericErrorResult -BinASTTokenReaderContext::raiseNotInPrelude() { - errorReporter_->errorNoOffset(JSMSG_BINAST, "Value is not in prelude"); - return cx_->alreadyReportedError(); -} - -struct ExtractBinASTInterfaceAndFieldMatcher { - BinASTInterfaceAndField operator()( - const BinASTTokenReaderBase::FieldContext& context) { - return context.position_; - } - BinASTInterfaceAndField operator()( - const BinASTTokenReaderBase::ListContext& context) { - return context.position_; - } - BinASTInterfaceAndField operator()( - const BinASTTokenReaderBase::RootContext&) { - MOZ_CRASH("The root context has no interface/field"); - } -}; - -JS::Result BinASTTokenReaderContext::readTagFromTable( - const BinASTInterfaceAndField& identity) { - // Extract the table. - const auto tableId = TableIdentity(NormalizedInterfaceAndField(identity)); - const auto& table = metadata_->dictionary()->getTable(tableId); - BINJS_MOZ_TRY_DECL(bits_, - (bitBuffer.getHuffmanLookup(*this))); - - // We're entering either a single interface or a sum. - const auto result = table.lookup(bits_); - if (MOZ_UNLIKELY(!result.isFound())) { - return raiseInvalidValue(); - } - bitBuffer.advanceBitBuffer(result.bitLength()); - return result.value().toKind(); -} - -JS::Result BinASTTokenReaderContext::readFieldFromTable( - const BinASTInterfaceAndField& identity) { - const auto tableId = TableIdentity(NormalizedInterfaceAndField(identity)); - if (!metadata_->dictionary()->isReady(tableId)) { - return raiseNotInPrelude(); - } - - const auto& table = metadata_->dictionary()->getTable(tableId); - BINJS_MOZ_TRY_DECL(bits_, bitBuffer.getHuffmanLookup(*this)); - - const auto result = table.lookup(bits_); - if (MOZ_UNLIKELY(!result.isFound())) { - return raiseInvalidValue(); - } - - bitBuffer.advanceBitBuffer(result.bitLength()); - return result.value(); -} - -JS::Result BinASTTokenReaderContext::readBool( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - return result.toBool(); -} - -JS::Result BinASTTokenReaderContext::readDouble( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - return result.toDouble(); -} - -JS::Result BinASTTokenReaderContext::readMaybeAtom( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - if (result.isNullAtom()) { - return nullptr; - } - return metadata_->getAtom(result.toAtomIndex()); -} - -JS::Result BinASTTokenReaderContext::readAtom( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - MOZ_ASSERT(!result.isNullAtom()); - return metadata_->getAtom(result.toAtomIndex()); -} - -JS::Result BinASTTokenReaderContext::readMaybeIdentifierName( - const FieldContext& context) { - return readMaybeAtom(context); -} - -JS::Result BinASTTokenReaderContext::readIdentifierName( - const FieldContext& context) { - return readAtom(context); -} - -JS::Result BinASTTokenReaderContext::readPropertyKey( - const FieldContext& context) { - return readAtom(context); -} - -JS::Result BinASTTokenReaderContext::readChars(Chars& out, - const FieldContext&) { - return raiseError("readChars is not implemented in BinASTTokenReaderContext"); -} - -JS::Result BinASTTokenReaderContext::readVariant( - const ListContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - return result.toVariant(); -} - -JS::Result BinASTTokenReaderContext::readVariant( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - return result.toVariant(); -} - -JS::Result BinASTTokenReaderContext::readUnsignedLong( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readFieldFromTable(context.position_)); - return result.toUnsignedLong(); -} - -JS::Result -BinASTTokenReaderContext::readSkippableSubTree(const FieldContext&) { - // Postions are set when reading lazy functions after the tree. - return SkippableSubTree(0, 0); -} - -JS::Result BinASTTokenReaderContext::registerLazyScript(FunctionBox* lazy) { - BINJS_TRY(lazyScripts_.append(lazy)); - return Ok(); -} - -JS::Result BinASTTokenReaderContext::enterSum( - BinASTKind& tag, const FieldOrRootContext& context) { - return context.match( - [this, &tag](const BinASTTokenReaderBase::FieldContext& asFieldContext) - -> JS::Result { - // This tuple is the value of the field we're currently reading. - MOZ_TRY_VAR(tag, readTagFromTable(asFieldContext.position_)); - return Ok(); - }, - [&tag](const BinASTTokenReaderBase::RootContext&) -> JS::Result { - // For the moment, the format hardcodes `Script` as root. - tag = BinASTKind::Script; - return Ok(); - }); -} - -JS::Result BinASTTokenReaderContext::enterSum( - BinASTKind& tag, const FieldOrListContext& context) { - return context.match( - [this, &tag](const BinASTTokenReaderBase::FieldContext& asFieldContext) - -> JS::Result { - // This tuple is the value of the field we're currently reading. - MOZ_TRY_VAR(tag, readTagFromTable(asFieldContext.position_)); - return Ok(); - }, - [this, &tag](const BinASTTokenReaderBase::ListContext& asListContext) - -> JS::Result { - // This tuple is an element in a list we're currently reading. - MOZ_TRY_VAR(tag, readTagFromTable(asListContext.position_)); - return Ok(); - }); -} - -JS::Result BinASTTokenReaderContext::enterSum(BinASTKind& tag, - const RootContext& context) { - // For the moment, the format hardcodes `Script` as root. - tag = BinASTKind::Script; - return Ok(); -} - -JS::Result BinASTTokenReaderContext::enterSum(BinASTKind& tag, - const ListContext& context) { - // This tuple is an element in a list we're currently reading. - MOZ_TRY_VAR(tag, readTagFromTable(context.position_)); - return Ok(); -} - -JS::Result BinASTTokenReaderContext::enterSum(BinASTKind& tag, - const FieldContext& context) { - // This tuple is the value of the field we're currently reading. - MOZ_TRY_VAR(tag, readTagFromTable(context.position_)); - return Ok(); -} - -JS::Result BinASTTokenReaderContext::enterList(uint32_t& items, - const ListContext& context) { - const auto tableId = TableIdentity(context.content_); - const auto& table = metadata_->dictionary()->getTable(tableId); - BINJS_MOZ_TRY_DECL(bits_, bitBuffer.getHuffmanLookup(*this)); - const auto result = table.lookup(bits_); - if (MOZ_UNLIKELY(!result.isFound())) { - return raiseInvalidValue(); - } - bitBuffer.advanceBitBuffer(result.bitLength()); - items = result.value().toListLength(); - return Ok(); -} - -// Internal uint32_t -// Note that this is different than varnum in multipart. -// -// Encoded as variable length number. - -template -JS::Result BinASTTokenReaderContext::readVarU32() { - uint32_t result = 0; - uint32_t shift = 0; - while (true) { - MOZ_ASSERT(shift < 32); - uint32_t byte; - MOZ_TRY_VAR(byte, readByte()); - - const uint32_t newResult = result | (byte & 0x7f) << shift; - if (MOZ_UNLIKELY(newResult < result)) { - return raiseError("Overflow during readVarU32"); - } - - result = newResult; - shift += 7; - - if ((byte & 0x80) == 0) { - return result; - } - - if (MOZ_UNLIKELY(shift >= 32)) { - return raiseError("Overflow during readVarU32"); - } - } -} - -JS::Result BinASTTokenReaderContext::readUnpackedLong() { - uint8_t bytes[4]; - uint32_t length = 4; - MOZ_TRY( - (readBuf(bytes, length))); - const uint32_t result = uint32_t(bytes[0]) << 24 | uint32_t(bytes[1]) << 16 | - uint32_t(bytes[2]) << 8 | uint32_t(bytes[3]); - return result; -} - -HuffmanKey::HuffmanKey(const uint32_t bits, const uint8_t bitLength) - : bits_(bits), bitLength_(bitLength) { - MOZ_ASSERT(bitLength_ <= MAX_PREFIX_BIT_LENGTH); - MOZ_ASSERT_IF(bitLength_ != 32 /* >> 32 is UB */, bits >> bitLength == 0); -} - -template -T* TemporaryStorageItem::alloc(JSContext* cx, size_t count) { - total_ += count; - - if (MOZ_LIKELY(head_)) { - if (MOZ_LIKELY(head_->used_ + count < head_->size_)) { - // This chunk still has sufficient space to allocate `count` bytes. - T* ret = head_->entries_ + head_->used_; - head_->used_ += count; - return ret; - } - } - - size_t chunkSize = Chunk::DefaultSize; - if (count > chunkSize) { - chunkSize = count; - } - - // Subtract `sizeof(T)` because `Chunk` already has `T entries_[1]` - // and that we want `T entries_[chunkSize]`. - Chunk* chunk = - reinterpret_cast(cx->template maybe_pod_malloc( - sizeof(Chunk) - sizeof(T) + chunkSize * sizeof(T))); - if (!chunk) { - ReportOutOfMemory(cx); - return nullptr; - } - chunk->used_ = count; - chunk->size_ = chunkSize; - chunk->next_ = head_; - - head_ = chunk; - - return head_->entries_; -} - -template -JS::Result> TemporaryStorage::alloc(JSContext* cx, - size_t count) { - MOZ_CRASH("unsupported type"); - return nullptr; -} - -template <> -JS::Result> TemporaryStorage::alloc( - JSContext* cx, size_t count) { - auto* items = huffmanEntries_.alloc(cx, count); - if (!items) { - return cx->alreadyReportedError(); - } - return mozilla::MakeSpan(items, count); -} - -template <> -JS::Result> -TemporaryStorage::alloc(JSContext* cx, - size_t count) { - auto* items = internalIndices_.alloc(cx, count); - if (!items) { - return cx->alreadyReportedError(); - } - return mozilla::MakeSpan(items, count); -} - -template <> -JS::Result> -TemporaryStorage::alloc(JSContext* cx, size_t count) { - auto* items = singleTables_.alloc(cx, count); - if (!items) { - return cx->alreadyReportedError(); - } - return mozilla::MakeSpan(items, count); -} - -template <> -JS::Result> -TemporaryStorage::alloc(JSContext* cx, size_t count) { - auto* items = twoTables_.alloc(cx, count); - if (!items) { - return cx->alreadyReportedError(); - } - return mozilla::MakeSpan(items, count); -} - -// ---- Implementation of Huffman Tables - -GenericHuffmanTable::Iterator::Iterator( - typename SingleEntryHuffmanTable::Iterator&& iterator) - : implementation_(std::move(iterator)) {} - -GenericHuffmanTable::Iterator::Iterator( - typename TwoEntriesHuffmanTable::Iterator&& iterator) - : implementation_(std::move(iterator)) {} - -GenericHuffmanTable::Iterator::Iterator( - typename SingleLookupHuffmanTable::Iterator&& iterator) - : implementation_(std::move(iterator)) {} - -GenericHuffmanTable::Iterator::Iterator( - typename TwoLookupsHuffmanTable::Iterator&& iterator) - : implementation_(std::move(iterator)) {} - -GenericHuffmanTable::Iterator::Iterator( - typename ThreeLookupsHuffmanTable::Iterator&& iterator) - : implementation_(std::move(iterator)) {} - -void GenericHuffmanTable::Iterator::operator++() { - implementation_.match( - [](typename SingleEntryHuffmanTable::Iterator& iterator) { - iterator.operator++(); - }, - [](typename TwoEntriesHuffmanTable::Iterator& iterator) { - iterator.operator++(); - }, - [](typename SingleLookupHuffmanTable::Iterator& iterator) { - iterator.operator++(); - }, - [](typename TwoLookupsHuffmanTable::Iterator& iterator) { - iterator.operator++(); - }, - [](typename ThreeLookupsHuffmanTable::Iterator& iterator) { - iterator.operator++(); - }); -} - -bool GenericHuffmanTable::Iterator::operator==( - const GenericHuffmanTable::Iterator& other) const { - return implementation_.match( - [other](const typename SingleEntryHuffmanTable::Iterator& iterator) { - return iterator == - other.implementation_ - .template as(); - }, - [other](const typename TwoEntriesHuffmanTable::Iterator& iterator) { - return iterator == - other.implementation_ - .template as(); - }, - [other](const typename SingleLookupHuffmanTable::Iterator& iterator) { - return iterator == - other.implementation_ - .template as(); - }, - [other](const typename TwoLookupsHuffmanTable::Iterator& iterator) { - return iterator == - other.implementation_ - .template as(); - }, - [other](const typename ThreeLookupsHuffmanTable::Iterator& iterator) { - return iterator == - other.implementation_ - .template as(); - }); -} - -bool GenericHuffmanTable::Iterator::operator!=( - const GenericHuffmanTable::Iterator& other) const { - return implementation_.match( - [other](const typename SingleEntryHuffmanTable::Iterator& iterator) { - return iterator != - other.implementation_ - .template as(); - }, - [other](const typename TwoEntriesHuffmanTable::Iterator& iterator) { - return iterator != - other.implementation_ - .template as(); - }, - [other](const typename SingleLookupHuffmanTable::Iterator& iterator) { - return iterator != - other.implementation_ - .template as(); - }, - [other](const typename TwoLookupsHuffmanTable::Iterator& iterator) { - return iterator != - other.implementation_ - .template as(); - }, - [other](const typename ThreeLookupsHuffmanTable::Iterator& iterator) { - return iterator != - other.implementation_ - .template as(); - }); -} - -const BinASTSymbol* GenericHuffmanTable::Iterator::operator*() const { - return implementation_.match( - [](const typename SingleEntryHuffmanTable::Iterator& iterator) { - return iterator.operator*(); - }, - [](const typename TwoEntriesHuffmanTable::Iterator& iterator) { - return iterator.operator*(); - }, - [](const typename SingleLookupHuffmanTable::Iterator& iterator) { - return iterator.operator*(); - }, - [](const typename TwoLookupsHuffmanTable::Iterator& iterator) { - return iterator.operator*(); - }, - [](const typename ThreeLookupsHuffmanTable::Iterator& iterator) { - return iterator.operator*(); - }); -} - -const BinASTSymbol* GenericHuffmanTable::Iterator::operator->() const { - return implementation_.match( - [](const typename SingleEntryHuffmanTable::Iterator& iterator) { - return iterator.operator->(); - }, - [](const typename TwoEntriesHuffmanTable::Iterator& iterator) { - return iterator.operator->(); - }, - [](const typename SingleLookupHuffmanTable::Iterator& iterator) { - return iterator.operator->(); - }, - [](const typename TwoLookupsHuffmanTable::Iterator& iterator) { - return iterator.operator->(); - }, - [](const typename ThreeLookupsHuffmanTable::Iterator& iterator) { - return iterator.operator->(); - }); -} - -GenericHuffmanTable::GenericHuffmanTable() - : implementation_(TableImplementationUninitialized{}) {} - -JS::Result GenericHuffmanTable::initComplete( - JSContext* cx, TemporaryStorage* tempStorage) { - return implementation_.match( - [](SingleEntryHuffmanTable& implementation) -> JS::Result { - MOZ_CRASH("SingleEntryHuffmanTable shouldn't have multiple entries!"); - }, - [cx, - tempStorage](TwoEntriesHuffmanTable& implementation) -> JS::Result { - return implementation.initComplete(cx, tempStorage); - }, - [cx, tempStorage]( - SingleLookupHuffmanTable& implementation) -> JS::Result { - return implementation.initComplete(cx, tempStorage); - }, - [cx, - tempStorage](TwoLookupsHuffmanTable& implementation) -> JS::Result { - return implementation.initComplete(cx, tempStorage); - }, - [cx, tempStorage]( - ThreeLookupsHuffmanTable& implementation) -> JS::Result { - return implementation.initComplete(cx, tempStorage); - }, - [](TableImplementationUninitialized&) -> JS::Result { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - }); -} - -typename GenericHuffmanTable::Iterator GenericHuffmanTable::begin() const { - return implementation_.match( - [](const SingleEntryHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.begin()); - }, - [](const TwoEntriesHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.begin()); - }, - [](const SingleLookupHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.begin()); - }, - [](const TwoLookupsHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.begin()); - }, - [](const ThreeLookupsHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.begin()); - }, - [](const TableImplementationUninitialized&) - -> GenericHuffmanTable::Iterator { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - }); -} - -typename GenericHuffmanTable::Iterator GenericHuffmanTable::end() const { - return implementation_.match( - [](const SingleEntryHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.end()); - }, - [](const TwoEntriesHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.end()); - }, - [](const SingleLookupHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.end()); - }, - [](const TwoLookupsHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.end()); - }, - [](const ThreeLookupsHuffmanTable& implementation) - -> GenericHuffmanTable::Iterator { - return Iterator(implementation.end()); - }, - [](const TableImplementationUninitialized&) - -> GenericHuffmanTable::Iterator { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - }); -} - -JS::Result GenericHuffmanTable::initWithSingleValue( - JSContext* cx, const BinASTSymbol& value) { - // Only one value: use HuffmanImplementationSaturated - MOZ_ASSERT(implementation_.template is< - TableImplementationUninitialized>()); // Make sure that we're - // initializing. - - implementation_ = {mozilla::VariantType{}, value}; - return Ok(); -} - -JS::Result GenericHuffmanTable::initStart(JSContext* cx, - TemporaryStorage* tempStorage, - size_t numberOfSymbols, - uint8_t largestBitLength) { - // Make sure that we have a way to represent all legal bit lengths. - static_assert(MAX_CODE_BIT_LENGTH <= ThreeLookupsHuffmanTable::MAX_BIT_LENGTH, - "ThreeLookupsHuffmanTable cannot hold all bit lengths"); - - // Make sure that we're initializing. - MOZ_ASSERT(implementation_.template is()); - - // Make sure we don't accidentally end up with only one symbol. - MOZ_ASSERT(numberOfSymbols != 1, - "Should have used `initWithSingleValue` instead"); - - if (numberOfSymbols == 2) { - implementation_ = {mozilla::VariantType{}}; - return implementation_.template as().initStart( - cx, tempStorage, numberOfSymbols, largestBitLength); - } - - // Find the (hopefully) fastest implementation of HuffmanTable for - // `largestBitLength`. - // ...hopefully, only one lookup. - if (largestBitLength <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) { - implementation_ = {mozilla::VariantType{}, - SingleLookupHuffmanTable::Use::ToplevelTable}; - return implementation_.template as().initStart( - cx, tempStorage, numberOfSymbols, largestBitLength); - } - - // ...if a single-lookup table would be too large, let's see if - // we can fit in a two-lookup table. - if (largestBitLength <= TwoLookupsHuffmanTable::MAX_BIT_LENGTH) { - implementation_ = {mozilla::VariantType{}}; - return implementation_.template as().initStart( - cx, tempStorage, numberOfSymbols, largestBitLength); - } - - // ...otherwise, we'll need three lookups. - implementation_ = {mozilla::VariantType{}}; - return implementation_.template as().initStart( - cx, tempStorage, numberOfSymbols, largestBitLength); -} - -JS::Result GenericHuffmanTable::addSymbol(size_t index, uint32_t bits, - uint8_t bitLength, - const BinASTSymbol& value) { - return implementation_.match( - [](SingleEntryHuffmanTable&) -> JS::Result { - MOZ_CRASH("SingleEntryHuffmanTable shouldn't have multiple entries!"); - return Ok(); - }, - [index, bits, bitLength, - value](TwoEntriesHuffmanTable& - implementation) mutable /* discard implicit const */ - -> JS::Result { - return implementation.addSymbol(index, bits, bitLength, value); - }, - [index, bits, bitLength, - value](SingleLookupHuffmanTable& - implementation) mutable /* discard implicit const */ - -> JS::Result { - return implementation.addSymbol(index, bits, bitLength, value); - }, - [index, bits, bitLength, - value](TwoLookupsHuffmanTable& - implementation) mutable /* discard implicit const */ - -> JS::Result { - return implementation.addSymbol(index, bits, bitLength, value); - }, - [index, bits, bitLength, - value = value](ThreeLookupsHuffmanTable& - implementation) mutable /* discard implicit const */ - -> JS::Result { - return implementation.addSymbol(index, bits, bitLength, value); - }, - [](TableImplementationUninitialized&) -> JS::Result { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - return Ok(); - }); -} - -HuffmanLookupResult GenericHuffmanTable::lookup(HuffmanLookup key) const { - return implementation_.match( - [key](const SingleEntryHuffmanTable& implementation) - -> HuffmanLookupResult { return implementation.lookup(key); }, - [key](const TwoEntriesHuffmanTable& implementation) - -> HuffmanLookupResult { return implementation.lookup(key); }, - [key](const SingleLookupHuffmanTable& implementation) - -> HuffmanLookupResult { return implementation.lookup(key); }, - [key](const TwoLookupsHuffmanTable& implementation) - -> HuffmanLookupResult { return implementation.lookup(key); }, - [key](const ThreeLookupsHuffmanTable& implementation) - -> HuffmanLookupResult { return implementation.lookup(key); }, - [](const TableImplementationUninitialized&) -> HuffmanLookupResult { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - }); -} - -size_t GenericHuffmanTable::length() const { - return implementation_.match( - [](const SingleEntryHuffmanTable& implementation) -> size_t { - return implementation.length(); - }, - [](const TwoEntriesHuffmanTable& implementation) -> size_t { - return implementation.length(); - }, - [](const SingleLookupHuffmanTable& implementation) -> size_t { - return implementation.length(); - }, - [](const TwoLookupsHuffmanTable& implementation) -> size_t { - return implementation.length(); - }, - [](const ThreeLookupsHuffmanTable& implementation) -> size_t { - return implementation.length(); - }, - [](const TableImplementationUninitialized& implementation) -> size_t { - MOZ_CRASH("GenericHuffmanTable is unitialized!"); - }); -} - -SingleEntryHuffmanTable::Iterator::Iterator(const BinASTSymbol* position) - : position_(position) {} - -void SingleEntryHuffmanTable::Iterator::operator++() { - // There's only one entry, and `nullptr` means `end`. - position_ = nullptr; -} - -const BinASTSymbol* SingleEntryHuffmanTable::Iterator::operator*() const { - return position_; -} - -const BinASTSymbol* SingleEntryHuffmanTable::Iterator::operator->() const { - return position_; -} - -bool SingleEntryHuffmanTable::Iterator::operator==( - const Iterator& other) const { - return position_ == other.position_; -} - -bool SingleEntryHuffmanTable::Iterator::operator!=( - const Iterator& other) const { - return position_ != other.position_; -} - -HuffmanLookupResult SingleEntryHuffmanTable::lookup(HuffmanLookup key) const { - return HuffmanLookupResult::found(0, &value_); -} - -TwoEntriesHuffmanTable::Iterator::Iterator(const BinASTSymbol* position) - : position_(position) {} - -void TwoEntriesHuffmanTable::Iterator::operator++() { position_++; } - -const BinASTSymbol* TwoEntriesHuffmanTable::Iterator::operator*() const { - return position_; -} - -const BinASTSymbol* TwoEntriesHuffmanTable::Iterator::operator->() const { - return position_; -} - -bool TwoEntriesHuffmanTable::Iterator::operator==(const Iterator& other) const { - return position_ == other.position_; -} - -bool TwoEntriesHuffmanTable::Iterator::operator!=(const Iterator& other) const { - return position_ != other.position_; -} - -JS::Result TwoEntriesHuffmanTable::initStart(JSContext* cx, - TemporaryStorage* tempStorage, - size_t numberOfSymbols, - uint8_t largestBitLength) { - // Make sure that we're initializing. - MOZ_ASSERT(numberOfSymbols == 2); - MOZ_ASSERT(largestBitLength == 1); - return Ok(); -} - -JS::Result TwoEntriesHuffmanTable::initComplete( - JSContext* cx, TemporaryStorage* tempStorage) { - return Ok(); -} - -JS::Result TwoEntriesHuffmanTable::addSymbol(size_t index, uint32_t bits, - uint8_t bitLength, - const BinASTSymbol& value) { - // Symbols must be ranked by increasing bits length - MOZ_ASSERT_IF(index == 0, bits == 0); - MOZ_ASSERT_IF(index == 1, bits == 1); - - // FIXME: Throw soft error instead of assert. - MOZ_ASSERT(bitLength == 1); - - values_[index] = value; - return Ok(); -} - -HuffmanLookupResult TwoEntriesHuffmanTable::lookup(HuffmanLookup key) const { - // By invariant, bit lengths are 1. - const auto index = key.leadingBits(1); - return HuffmanLookupResult::found(1, &values_[index]); -} - -SingleLookupHuffmanTable::Iterator::Iterator(const HuffmanEntry* position) - : position_(position) {} - -void SingleLookupHuffmanTable::Iterator::operator++() { position_++; } - -const BinASTSymbol* SingleLookupHuffmanTable::Iterator::operator*() const { - return &position_->value(); -} - -const BinASTSymbol* SingleLookupHuffmanTable::Iterator::operator->() const { - return &position_->value(); -} - -bool SingleLookupHuffmanTable::Iterator::operator==( - const Iterator& other) const { - return position_ == other.position_; -} - -bool SingleLookupHuffmanTable::Iterator::operator!=( - const Iterator& other) const { - return position_ != other.position_; -} - -JS::Result SingleLookupHuffmanTable::initStart( - JSContext* cx, TemporaryStorage* tempStorage, size_t numberOfSymbols, - uint8_t largestBitLength) { - MOZ_ASSERT_IF(largestBitLength != 32, - (uint32_t(1) << largestBitLength) - 1 <= - std::numeric_limits::max()); - - largestBitLength_ = largestBitLength; - - MOZ_TRY_VAR(values_, tempStorage->alloc(cx, numberOfSymbols)); - - const size_t saturatedLength = 1 << largestBitLength_; - MOZ_TRY_VAR(saturated_, - tempStorage->alloc(cx, saturatedLength)); - - // Enlarge `saturated_`, as we're going to fill it in random order. - for (size_t i = 0; i < saturatedLength; ++i) { - // Capacity reserved in this method. - saturated_[i] = InternalIndex(-1); - } - return Ok(); -} - -JS::Result SingleLookupHuffmanTable::initComplete( - JSContext* cx, TemporaryStorage* tempStorage) { - // Double-check that we've initialized properly. - MOZ_ASSERT(largestBitLength_ <= MAX_CODE_BIT_LENGTH); - - // We can end up with empty tables, if this `SingleLookupHuffmanTable` - // is used to store suffixes in a `MultiLookupHuffmanTable` and - // the corresponding prefix is never used. - if (values_.size() == 0) { - MOZ_ASSERT(largestBitLength_ == 0); - return Ok(); - } - -#ifdef DEBUG - bool foundMaxBitLength = false; - for (size_t i = 0; i < saturated_.size(); ++i) { - const uint8_t index = saturated_[i]; - if (use_ != Use::ToplevelTable) { - // The table may not be full. - if (index >= values_.size()) { - continue; - } - } - MOZ_ASSERT(values_[index].key().bitLength_ <= largestBitLength_); - if (values_[index].key().bitLength_ == largestBitLength_) { - foundMaxBitLength = true; - } - } - MOZ_ASSERT(foundMaxBitLength); -#endif // DEBUG - - return Ok(); -} - -JS::Result SingleLookupHuffmanTable::addSymbol(size_t index, uint32_t bits, - uint8_t bitLength, - const BinASTSymbol& value) { - MOZ_ASSERT_IF(largestBitLength_ != 0, bitLength != 0); - MOZ_ASSERT_IF(bitLength != 32 /* >> 32 is UB */, bits >> bitLength == 0); - MOZ_ASSERT(bitLength <= largestBitLength_); - - // First add the value to `values_`. - new (mozilla::KnownNotNull, &values_[index]) - HuffmanEntry(bits, bitLength, value); - - // Notation: in the following, unless otherwise specified, we consider - // values with `largestBitLength_` bits exactly. - // - // When we perform lookup, we will extract `largestBitLength_` bits from the - // key into a value `0bB...B`. We have a match for `value` if and only if - // `0bB...B` may be decomposed into `0bC...CX...X` such that - // - `0bC...C` is `bitLength` bits long; - // - `0bC...C == bits`. - // - // To perform a fast lookup, we precompute all possible values of `0bB...B` - // for which this condition is true. That's all the values of segment - // `[0bC...C0...0, 0bC...C1...1]`. - const HuffmanLookup base(bits, bitLength); - for (size_t i : base.suffixes(largestBitLength_)) { - saturated_[i] = index; - } - - return Ok(); -} - -HuffmanLookupResult SingleLookupHuffmanTable::lookup(HuffmanLookup key) const { - if (values_.size() == 0) { - // If the table is empty, any lookup fails. - return HuffmanLookupResult::notFound(); - } - // ...otherwise, all lookups succeed. - - // Take the `largestBitLength_` highest weight bits of `key`. - // In the documentation of `addSymbol`, this is - // `0bB...B`. - const uint32_t bits = key.leadingBits(largestBitLength_); - - // Invariants: `saturated_.size() == 1 << largestBitLength_` - // and `bits <= 1 << largestBitLength_`. - const size_t index = saturated_[bits]; - if (index >= values_.size()) { - // This is useful only when the `SingleLookupHuffmanTable` - // is used as a cache inside a `MultiLookupHuffmanTable`. - MOZ_ASSERT(use_ == Use::ShortKeys); - return HuffmanLookupResult::notFound(); - } - - // Invariants: `saturated_[i] < values_.size()`. - const auto& entry = values_[index]; - return HuffmanLookupResult::found(entry.key().bitLength_, &entry.value()); -} - -template -MultiLookupHuffmanTable::Iterator::Iterator( - const HuffmanEntry* position) - : position_(position) {} - -template -void MultiLookupHuffmanTable::Iterator::operator++() { - position_++; -} - -template -const BinASTSymbol* MultiLookupHuffmanTable< - Subtable, PrefixBitLength>::Iterator::operator*() const { - return &position_->value(); -} - -template -const BinASTSymbol* MultiLookupHuffmanTable< - Subtable, PrefixBitLength>::Iterator::operator->() const { - return &position_->value(); -} - -template -bool MultiLookupHuffmanTable::Iterator::operator==( - const Iterator& other) const { - return position_ == other.position_; -} - -template -bool MultiLookupHuffmanTable::Iterator::operator!=( - const Iterator& other) const { - return position_ != other.position_; -} - -template -JS::Result MultiLookupHuffmanTable::initStart( - JSContext* cx, TemporaryStorage* tempStorage, size_t numberOfSymbols, - uint8_t largestBitLength) { - static_assert(PrefixBitLength < MAX_CODE_BIT_LENGTH, - "Invalid PrefixBitLength"); - largestBitLength_ = largestBitLength; - - MOZ_TRY_VAR(values_, tempStorage->alloc(cx, numberOfSymbols)); - - auto numTables = 1 << PrefixBitLength; - MOZ_TRY_VAR(suffixTables_, tempStorage->alloc(cx, numTables)); - - return Ok(); -} - -template -JS::Result MultiLookupHuffmanTable::addSymbol( - size_t index, uint32_t bits, uint8_t bitLength, const BinASTSymbol& value) { - MOZ_ASSERT_IF(largestBitLength_ != 0, bitLength != 0); - MOZ_ASSERT(index == 0 || values_[index - 1].key().bitLength_ <= bitLength, - "Symbols must be ranked by increasing bits length"); - MOZ_ASSERT_IF(bitLength != 32 /* >> 32 is UB */, bits >> bitLength == 0); - - new (mozilla::KnownNotNull, &values_[index]) - HuffmanEntry(bits, bitLength, value); - - return Ok(); -} - -template -JS::Result MultiLookupHuffmanTable::initComplete( - JSContext* cx, TemporaryStorage* tempStorage) { - // First, we need to collect the `largestBitLength_` - // and `numberofSymbols` for each subtable. - struct Bucket { - Bucket() : largestBitLength_(0), numberOfSymbols_(0){}; - uint8_t largestBitLength_; - uint32_t numberOfSymbols_; - void addSymbol(uint8_t bitLength) { - ++numberOfSymbols_; - if (bitLength > largestBitLength_) { - largestBitLength_ = bitLength; - } - } - }; - FixedLengthVector buckets; - if (!buckets.allocate(cx, 1 << PrefixBitLength)) { - return cx->alreadyReportedError(); - } - Bucket shortKeysBucket; - - for (const auto& entry : values_) { - if (entry.key().bitLength_ <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) { - // If the key is short, we put it in `shortKeys_` instead of - // `suffixTables`. - shortKeysBucket.addSymbol(entry.key().bitLength_); - continue; - } - const HuffmanLookup lookup(entry.key().bits_, entry.key().bitLength_); - const auto split = lookup.split(PrefixBitLength); - MOZ_ASSERT_IF(split.suffix_.bitLength_ != 32, - split.suffix_.bits_ >> split.suffix_.bitLength_ == 0); - - // Entries that have a sufficient number of bits will be dispatched - // to a single subtable (e.g. A, B, C, D, E, F in the documentation). - // Other entries need to be dispatched to several subtables - // (e.g. G, H in the documentation). - for (const auto index : lookup.suffixes(PrefixBitLength)) { - Bucket& bucket = buckets[index]; - bucket.addSymbol(split.suffix_.bitLength_); - } - } - - FixedLengthVector suffixTablesIndices; - if (MOZ_UNLIKELY(!suffixTablesIndices.allocateUninitialized( - cx, suffixTables_.size()))) { - return cx->alreadyReportedError(); - } - - // We may now create the subtables. - size_t i = 0; - for (auto& bucket : buckets) { - new (mozilla::KnownNotNull, &suffixTables_[i]) Subtable(); - suffixTablesIndices[i] = 0; - - if (bucket.numberOfSymbols_ != 0) { - // Often, a subtable will end up empty because all the prefixes end up - // in `shortKeys_`. In such a case, we want to avoid initializing the - // table. - MOZ_TRY(suffixTables_[i].initStart( - cx, tempStorage, - /* numberOfSymbols = */ bucket.numberOfSymbols_, - /* maxBitLength = */ bucket.largestBitLength_)); - } - - i++; - } - - // Also, create the shortKeys_ fast lookup. - MOZ_TRY(shortKeys_.initStart(cx, tempStorage, - shortKeysBucket.numberOfSymbols_, - shortKeysBucket.largestBitLength_)); - - // Now that all the subtables are created, let's dispatch the values - // among these tables. - size_t shortKeysIndex = 0; - for (size_t i = 0; i < values_.size(); ++i) { - const auto& entry = values_[i]; - if (entry.key().bitLength_ <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) { - // The key fits in `shortKeys_`, let's use this table. - MOZ_TRY(shortKeys_.addSymbol(shortKeysIndex++, entry.key().bits_, - entry.key().bitLength_, - BinASTSymbol::fromSubtableIndex(i))); - continue; - } - - // Otherwise, use one of the suffix tables. - const HuffmanLookup lookup(entry.key().bits_, entry.key().bitLength_); - const auto split = lookup.split(PrefixBitLength); - MOZ_ASSERT_IF(split.suffix_.bitLength_ != 32, - split.suffix_.bits_ >> split.suffix_.bitLength_ == 0); - for (const auto index : lookup.suffixes(PrefixBitLength)) { - auto& sub = suffixTables_[index]; - - // We may now add a reference to `entry` into the sybtable. - MOZ_TRY(sub.addSymbol(suffixTablesIndices[index]++, split.suffix_.bits_, - split.suffix_.bitLength_, - BinASTSymbol::fromSubtableIndex(i))); - } - } - - // Finally, complete initialization of shortKeys_ and subtables. - MOZ_TRY(shortKeys_.initComplete(cx, tempStorage)); - for (size_t i = 0; i < buckets.length(); ++i) { - if (buckets[i].numberOfSymbols_ == 0) { - // Again, we don't want to initialize empty subtables. - continue; - } - auto& sub = suffixTables_[i]; - MOZ_TRY(sub.initComplete(cx, tempStorage)); - } - - return Ok(); -} - -template -HuffmanLookupResult MultiLookupHuffmanTable::lookup( - HuffmanLookup key) const { - { - // Let's first look in shortkeys. - auto subResult = shortKeys_.lookup(key); - if (subResult.isFound()) { - // We have found a result in the shortKeys_ fastpath. - const auto& result = values_[subResult.value().toSubtableIndex()]; - - return HuffmanLookupResult::found(result.key().bitLength_, - &result.value()); - } - } - const auto split = key.split(PrefixBitLength); - if (split.prefix_.bits_ >= suffixTables_.size()) { - return HuffmanLookupResult::notFound(); - } - const Subtable& subtable = suffixTables_[split.prefix_.bits_]; - - auto subResult = subtable.lookup(split.suffix_); - if (!subResult.isFound()) { - // Propagate "not found". - return HuffmanLookupResult::notFound(); - } - - // Otherwise, restore the entire `HuffmanEntry`. - const auto& result = values_[subResult.value().toSubtableIndex()]; - - return HuffmanLookupResult::found(result.key().bitLength_, &result.value()); -} - -// ----- - -// The number of possible interfaces in each sum, indexed by -// `static_cast(BinASTSum)`. -const size_t SUM_LIMITS[]{ -#define WITH_SUM(_ENUM_NAME, _HUMAN_NAME, MACRO_NAME, _TYPE_NAME) \ - BINAST_SUM_##MACRO_NAME##_LIMIT, - FOR_EACH_BIN_SUM(WITH_SUM) -#undef WITH_SUM -}; - -// For each sum S, an array from [0, SUM_LIMITS[S]( to the BinASTKind of the ith -// interface of the sum, ranked by the same sum order as the rest of the . -// -// For instance, as we have -// ArrowExpression ::= EagerArrowExpressionWithExpression -// | EagerArrowExpressionWithFunctionBody -// | ... -// -// SUM_RESOLUTION_ARROW_EXPRESSION[0] == -// BinASTKind::EagerArrowExpressionWithExpression -// SUM_RESOLUTION_ARROW_EXPRESSION[1] == -// BinASTKind::EagerArrowExpressionWithFunctionBody -// ... -#define WITH_SUM_CONTENTS(_SUM_NAME, _INDEX, INTERFACE_NAME, _MACRO_NAME, \ - _SPEC_NAME) \ - BinASTKind::INTERFACE_NAME, -#define WITH_SUM(_ENUM_NAME, _HUMAN_NAME, MACRO_NAME, _TYPE_NAME) \ - const BinASTKind SUM_RESOLUTION_##MACRO_NAME[]{ \ - FOR_EACH_BIN_INTERFACE_IN_SUM_##MACRO_NAME(WITH_SUM_CONTENTS)}; -FOR_EACH_BIN_SUM(WITH_SUM) -#undef WITH_SUM -#undef WITH_SUM_CONTENTS - -const BinASTKind* SUM_RESOLUTIONS[BINAST_NUMBER_OF_SUM_TYPES]{ -#define WITH_SUM(_ENUM_NAME, _HUMAN_NAME, MACRO_NAME, _TYPE_NAME) \ - SUM_RESOLUTION_##MACRO_NAME, - FOR_EACH_BIN_SUM(WITH_SUM) -#undef WITH_SUM -}; - -// The number of possible interfaces in each string enum, indexed by -// `static_cast(BinASTStringEnum)`. -const size_t STRING_ENUM_LIMITS[]{ -#define WITH_ENUM(name, _, MACRO_NAME) BIN_AST_STRING_ENUM_##MACRO_NAME##_LIMIT, - FOR_EACH_BIN_STRING_ENUM(WITH_ENUM) -#undef WITH_ENUM -}; - -#define WITH_ENUM_CONTENTS(_ENUM_NAME, VARIANT_NAME, _HUMAN_NAME) \ - BinASTVariant::VARIANT_NAME, -#define WITH_ENUM(_ENUM_NAME, _, MACRO_NAME) \ - const BinASTVariant STRING_ENUM_RESOLUTION_##MACRO_NAME[]{ \ - FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_##MACRO_NAME##_BY_WEBIDL_ORDER( \ - WITH_ENUM_CONTENTS)}; -FOR_EACH_BIN_STRING_ENUM(WITH_ENUM) -#undef WITH_ENUM -#undef WITH_ENUM_CONTENTS - -const BinASTVariant* STRING_ENUM_RESOLUTIONS[BINASTSTRINGENUM_LIMIT]{ -#define WITH_ENUM(name, _, MACRO_NAME) STRING_ENUM_RESOLUTION_##MACRO_NAME, - FOR_EACH_BIN_STRING_ENUM(WITH_ENUM) -#undef WITH_ENUM -}; - -// Start reading the prelude. -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::run(size_t initialCapacity) { - BINJS_TRY(stack_.reserve(initialCapacity)); - - dictionary_.reset(cx_->new_()); - BINJS_TRY(dictionary_); - - // For the moment, the root node is hardcoded to be a BinASTKind::Script. - // In future versions of the codec, we'll extend the format to handle - // other possible roots (e.g. BinASTKind::Module). - MOZ_TRY(pushFields(BinASTKind::Script)); - while (stack_.length() > 0) { - const Entry entry = stack_.popCopy(); - MOZ_TRY(entry.match(ReadPoppedEntryMatcher(*this))); - } - - auto dictForMetadata = HuffmanDictionaryForMetadata::createFrom( - dictionary_.get(), &tempStorage_); - if (!dictForMetadata) { - ReportOutOfMemory(cx_); - return cx_->alreadyReportedError(); - } - - return dictForMetadata; -} - -// ------ Reading booleans. -// 0 -> False -// 1 -> True - -// Extract the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const Boolean&) { - // Sadly, there are only two booleans known to this date. - return 2; -} - -// Extract symbol from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const Boolean&, size_t index) { - MOZ_ASSERT(index < 2); - return BinASTSymbol::fromBool(index != 0); -} - -// Reading a single-value table of booleans -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const Boolean& entry) { - uint8_t indexByte; - MOZ_TRY_VAR(indexByte, reader_.readByte()); - if (MOZ_UNLIKELY(indexByte >= 2)) { - return raiseInvalidTableData(entry.identity_); - } - - MOZ_TRY( - table.initWithSingleValue(cx_, BinASTSymbol::fromBool(indexByte != 0))); - return Ok(); -} - -// ------ Optional interfaces. -// 0 -> Null -// 1 -> NonNull - -// Extract the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const MaybeInterface&) { - // Null, NonNull - return 2; -} - -// Extract symbol from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const MaybeInterface& entry, size_t index) { - MOZ_ASSERT(index < 2); - return BinASTSymbol::fromKind(index == 0 ? BinASTKind::_Null : entry.kind_); -} - -// Reading a single-value table of optional interfaces -template <> -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const MaybeInterface& entry) { - uint8_t indexByte; - MOZ_TRY_VAR(indexByte, reader_.readByte()); - if (MOZ_UNLIKELY(indexByte >= 2)) { - return raiseInvalidTableData(entry.identity_); - } - - MOZ_TRY(table.initWithSingleValue( - cx_, BinASTSymbol::fromKind(indexByte == 0 ? BinASTKind::_Null - : entry.kind_))); - return Ok(); -} - -// ------ Sums of interfaces -// varnum i -> index `i` in the order defined by -// `FOR_EACH_BIN_INTERFACE_IN_SUM_*` - -// Extract the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const Sum& sum) { - return sum.maxNumberOfSymbols(); -} - -// Extract symbol from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const Sum& entry, size_t index) { - MOZ_ASSERT(index < entry.maxNumberOfSymbols()); - return BinASTSymbol::fromKind(entry.interfaceAt(index)); -} - -// Reading a single-value table of sums of interfaces. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const Sum& sum) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index >= sum.maxNumberOfSymbols())) { - return raiseInvalidTableData(sum.identity_); - } - - MOZ_TRY(table.initWithSingleValue( - cx_, BinASTSymbol::fromKind(sum.interfaceAt(index)))); - return Ok(); -} - -// ------ Optional sums of interfaces -// varnum 0 -> null -// varnum i > 0 -> index `i - 1` in the order defined by -// `FOR_EACH_BIN_INTERFACE_IN_SUM_*` - -// Extract the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const MaybeSum& sum) { - return sum.maxNumberOfSymbols(); -} - -// Extract symbol from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const MaybeSum& sum, size_t index) { - MOZ_ASSERT(index < sum.maxNumberOfSymbols()); - return BinASTSymbol::fromKind(sum.interfaceAt(index)); -} - -// Reading a single-value table of sums of interfaces. -template <> -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::readSingleValueTable(GenericHuffmanTable& table, - const MaybeSum& sum) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index >= sum.maxNumberOfSymbols())) { - return raiseInvalidTableData(sum.identity_); - } - - MOZ_TRY(table.initWithSingleValue( - cx_, BinASTSymbol::fromKind(sum.interfaceAt(index)))); - return Ok(); -} - -// ------ Numbers -// 64 bits, IEEE 754, big endian - -// Read the number of symbols from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const Number& number) { - BINJS_MOZ_TRY_DECL(length, reader_.readVarU32()); - if (MOZ_UNLIKELY(length > MAX_NUMBER_OF_SYMBOLS)) { - return raiseInvalidTableData(number.identity_); - } - return length; -} - -// Read a single symbol from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const Number& number, size_t) { - uint8_t bytes[8]; - MOZ_ASSERT(sizeof(bytes) == sizeof(double)); - - uint32_t len = mozilla::ArrayLength(bytes); - MOZ_TRY((reader_.readBuf( - reinterpret_cast(bytes), len))); - - // Decode big-endian. - const uint64_t asInt = mozilla::BigEndian::readUint64(bytes); - - // Canonicalize NaN, just to make sure another form of signalling NaN - // doesn't slip past us. - return BinASTSymbol::fromDouble( - JS::CanonicalizeNaN(mozilla::BitwiseCast(asInt))); -} - -// Reading a single-value table of numbers. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const Number& number) { - BINJS_MOZ_TRY_DECL(value, readSymbol(number, 0 /* ignored */)); - MOZ_TRY(table.initWithSingleValue(cx_, value)); - return Ok(); -} - -// ------ List lengths -// varnum - -// Read the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const List& list) { - BINJS_MOZ_TRY_DECL(length, reader_.readVarU32()); - if (MOZ_UNLIKELY(length > MAX_NUMBER_OF_SYMBOLS)) { - return raiseInvalidTableData(list.identity_); - } - return length; -} - -// Read a single symbol from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const List& list, size_t) { - BINJS_MOZ_TRY_DECL(length, reader_.readUnpackedLong()); - if (MOZ_UNLIKELY(length > MAX_LIST_LENGTH)) { - return raiseInvalidTableData(list.identity_); - } - return BinASTSymbol::fromListLength(length); -} - -// Reading a single-value table of list lengths. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const List& list) { - BINJS_MOZ_TRY_DECL(length, reader_.readUnpackedLong()); - if (MOZ_UNLIKELY(length > MAX_LIST_LENGTH)) { - return raiseInvalidTableData(list.identity_); - } - MOZ_TRY(table.initWithSingleValue(cx_, BinASTSymbol::fromListLength(length))); - return Ok(); -} - -// ------ Strings, non-nullable -// varnum (index) - -// Read the number of symbols from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const String& string) { - BINJS_MOZ_TRY_DECL(length, reader_.readVarU32()); - if (MOZ_UNLIKELY(length > MAX_NUMBER_OF_SYMBOLS || - length > reader_.metadata_->numStrings())) { - return raiseInvalidTableData(string.identity_); - } - return length; -} - -// Read a single symbol from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const String& entry, size_t) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index > reader_.metadata_->numStrings())) { - return raiseInvalidTableData(entry.identity_); - } - return BinASTSymbol::fromAtomIndex(index); -} - -// Reading a single-value table of string indices. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const String& entry) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index > reader_.metadata_->numStrings())) { - return raiseInvalidTableData(entry.identity_); - } - MOZ_TRY(table.initWithSingleValue(cx_, BinASTSymbol::fromAtomIndex(index))); - return Ok(); -} - -// ------ Optional strings -// varnum 0 -> null -// varnum i > 0 -> string at index i - 1 - -// Read the number of symbols from the metadata. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const MaybeString& entry) { - BINJS_MOZ_TRY_DECL(length, reader_.readVarU32()); - if (MOZ_UNLIKELY(length > MAX_NUMBER_OF_SYMBOLS || - length > reader_.metadata_->numStrings() + 1)) { - return raiseInvalidTableData(entry.identity_); - } - return length; -} - -// Read a single symbol from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const MaybeString& entry, size_t) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - // (index == 0) is specified as `null` value and - // (index > 0) maps to (index - 1)-th atom. - if (index == 0) { - return BinASTSymbol::nullAtom(); - } - if (MOZ_UNLIKELY(index > reader_.metadata_->numStrings() + 1)) { - return raiseInvalidTableData(entry.identity_); - } - return BinASTSymbol::fromAtomIndex(index - 1); -} - -// Reading a single-value table of string indices. -template <> -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const MaybeString& entry) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index > reader_.metadata_->numStrings() + 1)) { - return raiseInvalidTableData(entry.identity_); - } - // (index == 0) is specified as `null` value and - // (index > 0) maps to (index - 1)-th atom. - if (index == 0) { - MOZ_TRY(table.initWithSingleValue(cx_, BinASTSymbol::nullAtom())); - } else { - MOZ_TRY( - table.initWithSingleValue(cx_, BinASTSymbol::fromAtomIndex(index - 1))); - } - return Ok(); -} - -// ------ String Enums -// varnum index in the enum - -// Read the number of symbols from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const StringEnum& entry) { - return entry.maxNumberOfSymbols(); -} - -// Read a single symbol from the grammar. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const StringEnum& entry, size_t index) { - return BinASTSymbol::fromVariant(entry.variantAt(index)); -} - -// Reading a single-value table of string indices. -template <> -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const StringEnum& entry) { - BINJS_MOZ_TRY_DECL(index, reader_.readVarU32()); - if (MOZ_UNLIKELY(index > entry.maxNumberOfSymbols())) { - return raiseInvalidTableData(entry.identity_); - } - - BinASTVariant symbol = entry.variantAt(index); - MOZ_TRY(table.initWithSingleValue(cx_, BinASTSymbol::fromVariant(symbol))); - return Ok(); -} - -// ------ Unsigned Longs -// Unpacked 32-bit - -// Read the number of symbols from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readNumberOfSymbols( - const UnsignedLong& entry) { - BINJS_MOZ_TRY_DECL(length, reader_.readVarU32()); - if (MOZ_UNLIKELY(length > MAX_NUMBER_OF_SYMBOLS)) { - return raiseInvalidTableData(entry.identity_); - } - return length; -} - -// Read a single symbol from the stream. -template <> -MOZ_MUST_USE JS::Result HuffmanPreludeReader::readSymbol( - const UnsignedLong& entry, size_t) { - BINJS_MOZ_TRY_DECL(result, reader_.readUnpackedLong()); - return BinASTSymbol::fromUnsignedLong(result); -} - -// Reading a single-value table of string indices. -template <> -MOZ_MUST_USE JS::Result -HuffmanPreludeReader::readSingleValueTable( - GenericHuffmanTable& table, const UnsignedLong& entry) { - BINJS_MOZ_TRY_DECL(index, reader_.readUnpackedLong()); - MOZ_TRY( - table.initWithSingleValue(cx_, BinASTSymbol::fromUnsignedLong(index))); - return Ok(); -} - -HuffmanDictionaryForMetadata::~HuffmanDictionaryForMetadata() { - // WARNING: If you change the code of this destructor, - // `clearFromIncompleteInitialization` needs to be synchronized. - for (size_t i = 0; i < numTables_; i++) { - tablesBase()[i].~GenericHuffmanTable(); - } - for (size_t i = 0; i < numSingleTables_; i++) { - singleTablesBase()[i].~SingleLookupHuffmanTable(); - } - for (size_t i = 0; i < numTwoTables_; i++) { - twoTablesBase()[i].~TwoLookupsHuffmanTable(); - } -} - -/* static */ -HuffmanDictionaryForMetadata* HuffmanDictionaryForMetadata::createFrom( - HuffmanDictionary* dictionary, TemporaryStorage* tempStorage) { - size_t numTables = dictionary->numTables(); - size_t numHuffmanEntries = tempStorage->numHuffmanEntries(); - size_t numInternalIndices = tempStorage->numInternalIndices(); - while (numInternalIndices * sizeof(InternalIndex) % sizeof(uintptr_t) != 0) { - numInternalIndices++; - } - size_t numSingleTables = tempStorage->numSingleTables(); - size_t numTwoTables = tempStorage->numTwoTables(); - - HuffmanDictionaryForMetadata* data = - static_cast( - js_malloc(totalSize(numTables, numHuffmanEntries, numInternalIndices, - numSingleTables, numTwoTables))); - if (MOZ_UNLIKELY(!data)) { - return nullptr; - } - - new (mozilla::KnownNotNull, data) HuffmanDictionaryForMetadata( - numTables, numHuffmanEntries, numInternalIndices, numSingleTables, - numTwoTables); - - data->moveFrom(dictionary, tempStorage); - return data; -} - -/* static */ -HuffmanDictionaryForMetadata* HuffmanDictionaryForMetadata::create( - size_t numTables, size_t numHuffmanEntries, size_t numInternalIndices, - size_t numSingleTables, size_t numTwoTables) { - HuffmanDictionaryForMetadata* data = - static_cast( - js_malloc(totalSize(numTables, numHuffmanEntries, numInternalIndices, - numSingleTables, numTwoTables))); - if (MOZ_UNLIKELY(!data)) { - return nullptr; - } - - new (mozilla::KnownNotNull, data) HuffmanDictionaryForMetadata( - numTables, numHuffmanEntries, numInternalIndices, numSingleTables, - numTwoTables); - - return data; -} - -void HuffmanDictionaryForMetadata::clearFromIncompleteInitialization( - size_t numInitializedTables, size_t numInitializedSingleTables, - size_t numInitializedTwoTables) { - // This is supposed to be called from AutoClearHuffmanDictionaryForMetadata. - // See AutoClearHuffmanDictionaryForMetadata class comment for more details. - - // Call destructors for already-initialized tables. - for (size_t i = 0; i < numInitializedTables; i++) { - tablesBase()[i].~GenericHuffmanTable(); - } - for (size_t i = 0; i < numInitializedSingleTables; i++) { - singleTablesBase()[i].~SingleLookupHuffmanTable(); - } - for (size_t i = 0; i < numInitializedTwoTables; i++) { - twoTablesBase()[i].~TwoLookupsHuffmanTable(); - } - - // Set the following fields to 0 so that destructor doesn't call tables' - // destructor. - numTables_ = 0; - numSingleTables_ = 0; - numTwoTables_ = 0; -} - -void HuffmanDictionaryForMetadata::moveFrom(HuffmanDictionary* dictionary, - TemporaryStorage* tempStorage) { - // Move tableIndices_ from HuffmanDictionary to the payload of - // HuffmanDictionaryForMetadata. - for (size_t i = 0; i < TableIdentity::Limit; i++) { - // HuffmanDictionaryForMetadata.tableIndices_ is initialized to - // UnreachableIndex, and we don't have to move if - // dictionary->status_[i] == HuffmanDictionary::TableStatus::Unreachable. - if (dictionary->status_[i] == HuffmanDictionary::TableStatus::Ready) { - tableIndices_[i] = dictionary->tableIndices_[i]; - } - } - - // Fill items of each array from the beginning. - auto tablePtr = tablesBase(); - auto huffmanEntryPtr = huffmanEntriesBase(); - auto internalIndexPtr = internalIndicesBase(); - auto singleTablePtr = singleTablesBase(); - auto twoTablePtr = twoTablesBase(); - - // Move the content of SingleLookupHuffmanTable from - // TemporaryStorage to the payload of HuffmanDictionaryForMetadata. - // - // SingleLookupHuffmanTable itself should already be moved to - // HuffmanDictionaryForMetadata. - auto moveSingleTableContent = - [&huffmanEntryPtr, &internalIndexPtr](SingleLookupHuffmanTable& table) { - // table.{values_,saturated_} points the spans in TemporaryStorage. - // Move those items to the payload and then update - // table.{values_,saturated_} to point that range. - - { - size_t size = table.values_.size(); - memmove(huffmanEntryPtr.get(), table.values_.data(), - sizeof(HuffmanEntry) * size); - table.values_ = mozilla::MakeSpan(huffmanEntryPtr.get(), size); - huffmanEntryPtr += size; - } - - { - size_t size = table.saturated_.size(); - memmove(internalIndexPtr.get(), table.saturated_.data(), - sizeof(InternalIndex) * size); - table.saturated_ = mozilla::MakeSpan(internalIndexPtr.get(), size); - internalIndexPtr += size; - } - }; - - // Move the content of TwoLookupsHuffmanTable from - // TemporaryStorage to the payload of HuffmanDictionaryForMetadata. - auto moveTwoTableContent = - [&huffmanEntryPtr, &singleTablePtr, - moveSingleTableContent](TwoLookupsHuffmanTable& table) { - // table.shortKeys_ instance itself is already moved. - // Move the contents to the payload. - moveSingleTableContent(table.shortKeys_); - - // table.{values_,suffixTables_} points the spans in TemporaryStorage. - // Move those items to the payload and then update - // table.{values_,suffixTables_} to point that range. - // Also recursively move the content of suffixTables_. - - { - size_t size = table.values_.size(); - memmove(huffmanEntryPtr.get(), table.values_.data(), - sizeof(HuffmanEntry) * size); - table.values_ = mozilla::MakeSpan(huffmanEntryPtr.get(), size); - huffmanEntryPtr += size; - } - - { - size_t size = table.suffixTables_.size(); - auto head = singleTablePtr.get(); - for (auto& fromSubTable : table.suffixTables_) { - memmove(singleTablePtr.get(), &fromSubTable, - sizeof(SingleLookupHuffmanTable)); - auto& toSubTable = *singleTablePtr; - singleTablePtr++; - - moveSingleTableContent(toSubTable); - } - table.suffixTables_ = mozilla::MakeSpan(head, size); - } - }; - - // Move the content of ThreeLookupsHuffmanTable from - // TemporaryStorage to the payload of HuffmanDictionaryForMetadata. - auto moveThreeTableContent = - [&huffmanEntryPtr, &twoTablePtr, moveSingleTableContent, - moveTwoTableContent](ThreeLookupsHuffmanTable& table) { - // table.shortKeys_ instance itself is already moved. - // Move the contents to the payload. - moveSingleTableContent(table.shortKeys_); - - // table.{values_,suffixTables_} points the spans in TemporaryStorage. - // Move those items to the payload and then update - // table.{values_,suffixTables_} to point that range. - // Also recursively move the content of suffixTables_. - - { - size_t size = table.values_.size(); - memmove(huffmanEntryPtr.get(), table.values_.data(), - sizeof(HuffmanEntry) * size); - table.values_ = mozilla::MakeSpan(huffmanEntryPtr.get(), size); - huffmanEntryPtr += size; - } - - { - size_t size = table.suffixTables_.size(); - auto head = twoTablePtr.get(); - for (auto& fromSubTable : table.suffixTables_) { - memmove(twoTablePtr.get(), &fromSubTable, - sizeof(TwoLookupsHuffmanTable)); - auto& toSubTable = *twoTablePtr; - twoTablePtr++; - - moveTwoTableContent(toSubTable); - } - table.suffixTables_ = mozilla::MakeSpan(head, size); - } - }; - - // Move tables from HuffmanDictionary to the payload of - // HuffmanDictionaryForMetadata, and then move contents of those tables - // to the payload of HuffmanDictionaryForMetadata. - for (size_t i = 0; i < numTables_; i++) { - auto& fromTable = dictionary->tableAtIndex(i); - - if (fromTable.implementation_.is() || - fromTable.implementation_.is()) { - memmove(tablePtr.get(), &fromTable, sizeof(GenericHuffmanTable)); - tablePtr++; - } else if (fromTable.implementation_.is()) { - memmove(tablePtr.get(), &fromTable, sizeof(GenericHuffmanTable)); - auto& specialized = - tablePtr->implementation_.as(); - tablePtr++; - - moveSingleTableContent(specialized); - } else if (fromTable.implementation_.is()) { - memmove(tablePtr.get(), &fromTable, sizeof(GenericHuffmanTable)); - auto& specialized = - tablePtr->implementation_.as(); - tablePtr++; - - moveTwoTableContent(specialized); - } else { - MOZ_ASSERT(fromTable.implementation_.is()); - - memmove(tablePtr.get(), &fromTable, sizeof(GenericHuffmanTable)); - auto& specialized = - tablePtr->implementation_.as(); - tablePtr++; - - moveThreeTableContent(specialized); - } - } -} - -/* static */ -size_t HuffmanDictionaryForMetadata::totalSize(size_t numTables, - size_t numHuffmanEntries, - size_t numInternalIndices, - size_t numSingleTables, - size_t numTwoTables) { - static_assert(alignof(GenericHuffmanTable) % sizeof(uintptr_t) == 0, - "should be aligned to pointer size"); - static_assert(alignof(HuffmanEntry) % sizeof(uintptr_t) == 0, - "should be aligned to pointer size"); - static_assert(alignof(SingleLookupHuffmanTable) % sizeof(uintptr_t) == 0, - "should be aligned to pointer size"); - static_assert(alignof(TwoLookupsHuffmanTable) % sizeof(uintptr_t) == 0, - "should be aligned to pointer size"); - - // InternalIndex is not guaranteed to be aligned to pointer size. - // Make sure `numInternalIndices` meets the requirement that - // the entire block size is aligned to pointer size. - MOZ_ASSERT(numInternalIndices * sizeof(InternalIndex) % sizeof(uintptr_t) == - 0); - - return sizeof(HuffmanDictionaryForMetadata) + - numTables * sizeof(GenericHuffmanTable) + - numHuffmanEntries * sizeof(HuffmanEntry) + - numInternalIndices * sizeof(InternalIndex) + - numSingleTables * sizeof(SingleLookupHuffmanTable) + - numTwoTables * sizeof(TwoLookupsHuffmanTable); -} - -HuffmanDictionary::~HuffmanDictionary() { - for (size_t i = 0; i < nextIndex_; i++) { - tableAtIndex(i).~GenericHuffmanTable(); - } -} - -uint32_t HuffmanLookup::leadingBits(const uint8_t aBitLength) const { - MOZ_ASSERT(aBitLength <= bitLength_); - const uint32_t result = (aBitLength == 0) - ? 0 // Shifting a uint32_t by 32 bits is UB. - : bits_ >> uint32_t(bitLength_ - aBitLength); - return result; -} - -Split HuffmanLookup::split(const uint8_t prefixLength) const { - if (bitLength_ <= prefixLength) { - // Not enough bits, pad with zeros. - return { - /* prefix: HuffmanLookup */ {bits_ << (prefixLength - bitLength_), - prefixLength}, - /* suffix: HuffmanLookup */ {0, 0}, - }; - } - - // Keep `prefixLength` bits from `bits`. - // Pad the rest with 0s to build the suffix. - const uint8_t shift = bitLength_ - prefixLength; - switch (shift) { - case 0: // Special case, as we can't >> 32 - return { - /* prefix: HuffmanLookup */ {bits_, prefixLength}, - /* suffix: HuffmanLookup */ {0, 0}, - }; - case 32: // Special case, as we can't >> 32 - return { - /* prefix: HuffmanLookup */ {0, prefixLength}, - /* suffix: HuffmanLookup */ {bits_, shift}, - }; - } - return { - /* prefix: HuffmanLookup */ {bits_ >> shift, prefixLength}, - /* suffix: HuffmanLookup */ - {bits_ & (std::numeric_limits::max() >> (32 - shift)), shift}, - }; -} - -mozilla::detail::IntegerRange HuffmanLookup::suffixes( - uint8_t expectedBitLength) const { - if (expectedBitLength <= bitLength_) { - // We have too many bits, we need to truncate the HuffmanLookup, - // then return a single element. - const uint8_t shearing = bitLength_ - expectedBitLength; - const size_t first = size_t(bits_) >> shearing; - const size_t last = first; - return mozilla::IntegerRange(first, last + 1); - } - - // We need to pad with lower-weight 0s. - const uint8_t padding = expectedBitLength - bitLength_; - const size_t first = bits_ << padding; - const size_t last = first + (size_t(-1) >> (8 * sizeof(size_t) - padding)); - return mozilla::IntegerRange(first, last + 1); -} - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTTokenReaderContext.h b/js/src/frontend/BinASTTokenReaderContext.h deleted file mode 100644 index 458f2762e0..0000000000 --- a/js/src/frontend/BinASTTokenReaderContext.h +++ /dev/null @@ -1,1876 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTTokenReaderContext_h -#define frontend_BinASTTokenReaderContext_h - -#include "mozilla/Array.h" // mozilla::Array -#include "mozilla/Assertions.h" // MOZ_ASSERT -#include "mozilla/Attributes.h" // MOZ_MUST_USE, MOZ_STACK_CLASS -#include "mozilla/IntegerRange.h" // mozilla::IntegerRange -#include "mozilla/Maybe.h" // mozilla::Maybe -#include "mozilla/RangedPtr.h" // mozilla::RangedPtr -#include "mozilla/Span.h" // mozilla::Span -#include "mozilla/Variant.h" // mozilla::Variant - -#include // size_t -#include // uint8_t, uint32_t - -#include "jstypes.h" // JS_PUBLIC_API -#include "frontend/BinASTRuntimeSupport.h" // CharSlice, BinASTSourceMetadata -#include "frontend/BinASTToken.h" // BinASTVariant, BinASTKind, BinASTField -#include "frontend/BinASTTokenReaderBase.h" // BinASTTokenReaderBase, SkippableSubTree -#include "js/AllocPolicy.h" // SystemAllocPolicy -#include "js/HashTable.h" // HashMap, DefaultHasher -#include "js/Result.h" // JS::Result, Ok, Error -#include "js/Vector.h" // js::Vector - -class JS_PUBLIC_API JSAtom; -class JS_PUBLIC_API JSTracer; -struct JS_PUBLIC_API JSContext; - -namespace js { - -class ScriptSource; - -namespace frontend { - -class ErrorReporter; -class FunctionBox; - -// The format treats several distinct models as the same. -// -// We use `NormalizedInterfaceAndField` as a proxy for `BinASTInterfaceAndField` -// to ensure that we always normalize into the canonical model. -struct NormalizedInterfaceAndField { - const BinASTInterfaceAndField identity_; - explicit NormalizedInterfaceAndField(BinASTInterfaceAndField identity) - : identity_( - identity == BinASTInterfaceAndField:: - StaticMemberAssignmentTarget__Property - ? BinASTInterfaceAndField::StaticMemberExpression__Property - : identity) {} -}; - -template -struct Split { - T prefix_; - T suffix_; -}; - -// A bunch of bits used to lookup a value in a Huffman table. In most cases, -// these are the 32 leading bits of the underlying bit stream. -// -// In a Huffman table, keys have variable bitlength. Consequently, we only know -// the bitlength of the key *after* we have performed the lookup. A -// `HuffmanLookup` is a data structure contained at least as many bits as -// needed to perform the lookup. -// -// Whenever a lookup is performed, the consumer MUST look at the `bitLength` of -// the returned `HuffmanKey` and consume as many bits from the bit stream. -struct HuffmanLookup { - HuffmanLookup(const uint32_t bits, const uint8_t bitLength) - // We zero out the highest `32 - bitLength_` bits. - : bits_(bitLength == 0 - ? 0 // >> 32 is UB - : (bits & (uint32_t(0xFFFFFFFF) >> (32 - bitLength)))), - bitLength_(bitLength) { - MOZ_ASSERT(bitLength_ <= 32); - MOZ_ASSERT_IF(bitLength_ != 32 /* >> 32 is UB */, bits_ >> bitLength_ == 0); - } - - // Return the `bitLength` leading bits of this superset, in the order - // expected to compare to a `HuffmanKey`. The order of bits and bytes - // is ensured by `BitBuffer`. - // - // Note: This only makes sense if `bitLength <= bitLength_`. - // - // So, for instance, if `leadingBits(4)` returns - // `0b_0000_0000__0000_0000__0000_0000__0000_0100`, this is - // equal to Huffman Key `0100`. - uint32_t leadingBits(const uint8_t bitLength) const; - - // Split a HuffmanLookup into a prefix and a suffix. - // - // If the value holds at least `prefixLength` bits, the - // prefix consists in the first `prefixLength` bits and the - // suffix in the remaining bits. - // - // If the value holds fewer bits, the prefix consists in - // all the bits, with 0 padding at the end to ensure that - // the prefix contains exactly `prefixLength` bits. - Split split(const uint8_t prefixLength) const; - - // The buffer holding the bits. At this stage, bits are stored - // in the same order as `HuffmanKey`. See the implementation of - // `BitBuffer` methods for more details about how this order - // is implemented. - // - // If `bitLength_ < 32`, the unused highest bits are guaranteed - // to be 0. - const uint32_t bits_; - - // The actual length of buffer `bits_`. - // - // MUST be within `[0, 32]`. - // - // If `bitLength_ < 32`, it means that some of the highest bits are unused. - const uint8_t bitLength_; - - // Return an iterable data structure representing all possible - // suffixes of this `HuffmanLookup` with `expectedBitLength` - // bits. - // - // If this `HuffmanLookup` is already at least `expectedBitLength` - // bits long, we truncate the `HuffmanLookup` to `expectedBitLength` - // bits and there is only one such suffix. - mozilla::detail::IntegerRange suffixes( - uint8_t expectedBitLength) const; -}; - -// A Huffman Key. -struct HuffmanKey { - // Construct the HuffmanKey. - // - // `bits` and `bitLength` define a buffer containing the standard Huffman - // code for this key. - // - // For instance, if the Huffman code is `0100`, - // - `bits = 0b0000_0000__0000_0000__0000_0000__0000_0100`; - // - `bitLength = 4`. - HuffmanKey(const uint32_t bits, const uint8_t bitLength); - - // The buffer holding the bits. - // - // For a Huffman code of `0100` - // - `bits_ = 0b0000_0000__0000_0000__0000_0000__0000_0100`; - // - // If `bitLength_ < 32`, the unused highest bits are guaranteed - // to be 0. - const uint32_t bits_; - - // The actual length of buffer `bits_`. - // - // MUST be within `[0, 32]`. - // - // If `bitLength_ < 32`, it means that some of the highest bits are unused. - const uint8_t bitLength_; -}; - -// Symbol appears in the table. -// This class is used to store symbols in `*HuffmanTable` classes without having -// multiple implementation or different generated code for each type. -// -// This class doesn't store any tag to determine which kind of symbol it is. -// The consumer MUST use the correct `from*`/`to*` pair. -class alignas(8) BinASTSymbol { - private: - static const size_t NullAtomIndex = size_t(-1); - - uint64_t asBits_; - - explicit BinASTSymbol(uint64_t asBits) : asBits_(asBits) {} - - static BinASTSymbol fromRawBits(uint64_t asBits) { - return BinASTSymbol(asBits); - } - - public: - static BinASTSymbol fromUnsignedLong(uint32_t i) { return fromRawBits(i); } - static BinASTSymbol fromListLength(uint32_t i) { return fromRawBits(i); } - static BinASTSymbol fromSubtableIndex(size_t i) { return fromRawBits(i); } - static BinASTSymbol fromBool(bool b) { return fromRawBits(b); } - static BinASTSymbol fromDouble(double d) { - return fromRawBits(mozilla::BitwiseCast(d)); - } - static BinASTSymbol fromKind(BinASTKind k) { - return fromRawBits(uint64_t(k)); - } - static BinASTSymbol fromVariant(BinASTVariant v) { - return fromRawBits(uint64_t(v)); - } - static BinASTSymbol fromAtomIndex(size_t i) { return fromRawBits(i); } - static BinASTSymbol nullAtom() { return fromRawBits(NullAtomIndex); } - - uint32_t toUnsignedLong() const { return uint32_t(asBits_); } - uint32_t toListLength() const { return uint32_t(asBits_); } - size_t toSubtableIndex() const { return size_t(asBits_); } - bool toBool() const { return bool(asBits_); } - double toDouble() const { return mozilla::BitwiseCast(asBits_); } - BinASTKind toKind() const { return BinASTKind(asBits_); } - BinASTVariant toVariant() const { return BinASTVariant(asBits_); } - - size_t toAtomIndex() const { - MOZ_ASSERT(!isNullAtom()); - return toAtomIndexNoCheck(); - } - - bool isNullAtom() const { return toAtomIndexNoCheck() == NullAtomIndex; } - - private: - size_t toAtomIndexNoCheck() const { return size_t(asBits_); } - - friend class ::js::ScriptSource; -}; - -// An entry in a Huffman table. -class HuffmanEntry { - const HuffmanKey key_; - const BinASTSymbol value_; - - public: - HuffmanEntry(HuffmanKey key, const BinASTSymbol& value) - : key_(key), value_(value) {} - - HuffmanEntry(uint32_t bits, uint8_t bitLength, const BinASTSymbol& value) - : key_(bits, bitLength), value_(value) {} - - const HuffmanKey& key() const { return key_; }; - const BinASTSymbol& value() const { return value_; }; -}; - -// The result of lookup in Huffman table. -class HuffmanLookupResult { - uint8_t bitLength_; - const BinASTSymbol* value_; - - HuffmanLookupResult(uint8_t bitLength, const BinASTSymbol* value) - : bitLength_(bitLength), value_(value) {} - - public: - static HuffmanLookupResult found(uint8_t bitLength, - const BinASTSymbol* value) { - MOZ_ASSERT(value); - return HuffmanLookupResult(bitLength, value); - } - - static HuffmanLookupResult notFound() { - return HuffmanLookupResult(0, nullptr); - } - - bool isFound() const { return !!value_; }; - - uint8_t bitLength() const { - MOZ_ASSERT(isFound()); - return bitLength_; - } - - const BinASTSymbol& value() const { - MOZ_ASSERT(isFound()); - return *value_; - } -}; - -// A flag that determines only whether a value is `null`. -// Used for optional interface. -enum class Nullable { - Null, - NonNull, -}; - -class TemporaryStorage; - -// An implementation of Huffman Tables for single-entry table. -class SingleEntryHuffmanTable { - public: - explicit SingleEntryHuffmanTable(const BinASTSymbol& value) : value_(value) {} - SingleEntryHuffmanTable(SingleEntryHuffmanTable&& other) = default; - - SingleEntryHuffmanTable() = delete; - SingleEntryHuffmanTable(SingleEntryHuffmanTable&) = delete; - - // Lookup a value in the table. - // The key is 0-bit length and this always suceeds. - HuffmanLookupResult lookup(HuffmanLookup key) const; - - // The number of values in the table. - size_t length() const { return 1; } - - // Iterating in the order of insertion. - struct Iterator { - explicit Iterator(const BinASTSymbol* position); - void operator++(); - const BinASTSymbol* operator*() const; - const BinASTSymbol* operator->() const; - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const; - - private: - const BinASTSymbol* position_; - }; - Iterator begin() const { return Iterator(&value_); } - Iterator end() const { return Iterator(nullptr); } - - private: - BinASTSymbol value_; - - friend class HuffmanPreludeReader; - friend class ::js::ScriptSource; -}; - -// An implementation of Huffman Tables for two-entry table. -class TwoEntriesHuffmanTable { - public: - TwoEntriesHuffmanTable() = default; - TwoEntriesHuffmanTable(TwoEntriesHuffmanTable&& other) noexcept = default; - - // Initialize a Huffman table containing `numberOfSymbols`. - // Symbols must be added with `addSymbol`. - // If you initialize with `initStart`, you MUST call `initComplete()` - // at the end of initialization. - JS::Result initStart(JSContext* cx, TemporaryStorage* tempStorage, - size_t numberOfSymbols, uint8_t maxBitLength); - - JS::Result initComplete(JSContext* cx, TemporaryStorage* tempStorage); - - // Add a symbol to a value. - // The symbol is the `index`-th item in this table. - JS::Result addSymbol(size_t index, uint32_t bits, uint8_t bitLength, - const BinASTSymbol& value); - - TwoEntriesHuffmanTable(TwoEntriesHuffmanTable&) = delete; - - // Lookup a value in the table. - // - // The return of this method contains: - // - // - the resulting value (`nullptr` if the value is not in the table); - // - the number of bits in the entry associated to this value. - // - // Note that entries inside a single table are typically associated to - // distinct bit lengths. The caller is responsible for checking - // the result of this method and advancing the bitstream by - // `result.key().bitLength_` bits. - HuffmanLookupResult lookup(HuffmanLookup key) const; - - struct Iterator { - explicit Iterator(const BinASTSymbol* position); - void operator++(); - const BinASTSymbol* operator*() const; - const BinASTSymbol* operator->() const; - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const; - - private: - const BinASTSymbol* position_; - }; - Iterator begin() const { return Iterator(std::begin(values_)); } - Iterator end() const { return Iterator(std::end(values_)); } - - // The number of values in the table. - size_t length() const { return 2; } - - private: - // A buffer for the values added to this table. - BinASTSymbol values_[2] = {BinASTSymbol::fromBool(false), - BinASTSymbol::fromBool(false)}; - - friend class HuffmanPreludeReader; - friend class ::js::ScriptSource; -}; - -// An implementation of Huffman Tables as a vector designed to allow -// constant-time lookups at the expense of high space complexity. -// -// # Time complexity -// -// Lookups take constant time, which essentially consists in two -// simple vector lookups. -// -// # Space complexity -// -// After initialization, a `SingleLookupHuffmanTable` -// requires O(2 ^ max bit length in the table) space: -// -// - A vector `values_` containing one entry per symbol. -// - A vector `saturated_` containing exactly 2 ^ (max bit length in the -// table) entries, which we use to map any combination of `largestBitLength_` -// bits onto the only `HuffmanEntry` that may be reached by a prefix -// of these `largestBitLength_` bits. See below for more details. -// -// # Algorithm -// -// Consider the following Huffman table -// -// Symbol | Binary Code | Int value of Code | Bit Length -// ------ | ------------ | ----------------- | ---------- -// A | 11000 | 24 | 5 -// B | 11001 | 25 | 5 -// C | 1101 | 13 | 4 -// D | 100 | 4 | 3 -// E | 101 | 5 | 3 -// F | 111 | 7 | 3 -// G | 00 | 0 | 2 -// H | 01 | 1 | 2 -// -// By definition of a Huffman Table, the Binary Codes represent -// paths in a Huffman Tree. Consequently, padding these codes -// to the end would not change the result. -// -// Symbol | Binary Code | Int value of Code | Bit Length -// ------ | ------------ | ----------------- | ---------- -// A | 11000 | 24 | 5 -// B | 11001 | 25 | 5 -// C | 1101? | [26...27] | 4 -// D | 100?? | [16...19] | 3 -// E | 101?? | [20..23] | 3 -// F | 111?? | [28..31] | 3 -// G | 00??? | [0...7] | 2 -// H | 01??? | [8...15] | 2 -// -// Row "Int value of Code" now contains all possible values -// that may be expressed in 5 bits. By using these values -// as array indices, we may therefore represent the -// Huffman table as an array: -// -// Index | Symbol | Bit Length -// --------- | ---------- | ------------- -// [0...7] | G | 2 -// [8...15] | H | 2 -// [16...19] | D | 3 -// [20...23] | E | 3 -// 24 | A | 5 -// 25 | B | 5 -// [26...27] | C | 4 -// [28...31] | F | 3 -// -// By using the next 5 bits in the bit buffer, we may, in -// a single lookup, determine the symbol and the bit length. -// -// In the current implementation, to save some space, we have -// two distinct arrays, one (`values_`) with a single instance of each -// symbols bit length, and one (`saturated_`) with indices into that -// array. -class SingleLookupHuffmanTable { - public: - // An index into table `values_`. - // We use `uint8_t` instead of `size_t` to limit the space - // used by the table. - using InternalIndex = uint8_t; - - // An enum used to represent how this table is used. - // Used to perform additional DEBUG assertions. - enum Use { - // Used as a `Subtable` argument of a `MultiLookupHuffmanTable`. - LeafOfMultiLookupHuffmanTable, - // Used as its own table. - ToplevelTable, - // Used as a `shortKeys_` in a `MultiLookupHuffmanTable`. - ShortKeys, - }; - - // The largest bit length that may be represented by this table. - static const uint8_t MAX_BIT_LENGTH = sizeof(InternalIndex) * 8; - - explicit SingleLookupHuffmanTable( - Use use = Use::LeafOfMultiLookupHuffmanTable) - : largestBitLength_(-1) -#ifdef DEBUG - , - use_(use) -#endif // DEBUG - { - } - SingleLookupHuffmanTable(SingleLookupHuffmanTable&& other) = default; - - // Initialize a Huffman table containing `numberOfSymbols`. - // Symbols must be added with `addSymbol`. - // If you initialize with `initStart`, you MUST call `initComplete()` - // at the end of initialization. - JS::Result initStart(JSContext* cx, TemporaryStorage* tempStorage, - size_t numberOfSymbols, uint8_t maxBitLength); - - JS::Result initComplete(JSContext* cx, TemporaryStorage* tempStorage); - - // Add a `(bit, bitLength) => value` mapping. - // The symbol is the `index`-th item in this table. - JS::Result addSymbol(size_t index, uint32_t bits, uint8_t bitLength, - const BinASTSymbol& value); - - SingleLookupHuffmanTable(SingleLookupHuffmanTable&) = delete; - - // Lookup a value in the table. - // - // The return of this method contains: - // - // - the resulting value (`nullptr` if the value is not in the table); - // - the number of bits in the entry associated to this value. - // - // Note that entries inside a single table are typically associated to - // distinct bit lengths. The caller is responsible for checking - // the result of this method and advancing the bitstream by - // `result.key().bitLength_` bits. - HuffmanLookupResult lookup(HuffmanLookup key) const; - - // The number of values in the table. - size_t length() const { return values_.size(); } - - // Iterating in the order of insertion. - struct Iterator { - explicit Iterator(const HuffmanEntry* position); - void operator++(); - const BinASTSymbol* operator*() const; - const BinASTSymbol* operator->() const; - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const; - - private: - const HuffmanEntry* position_; - }; - Iterator begin() const { return Iterator(&values_[0]); } - Iterator end() const { return Iterator(&values_[0] + values_.size()); } - - private: - // The entries in this Huffman Table, sorted in the order of insertion. - // - // Invariant (once `init*` has been called): - // - Length is the number of values inserted in the table. - // - for all i, `values_[i].bitLength_ <= largestBitLength_`. - mozilla::Span values_; - - // The entries in this Huffman table, prepared for lookup. - // - // Invariant (once `init*` has been called): - // - Length is `1 << largestBitLength_`. - // - for all i, `saturated_[i] < values_.size()` - mozilla::Span saturated_; - - friend class HuffmanDictionaryForMetadata; - - // The maximal bitlength of a value in this table. - // - // Invariant (once `init*` has been called): - // - `largestBitLength_ <= MAX_CODE_BIT_LENGTH` - uint8_t largestBitLength_; - -#ifdef DEBUG - Use use_; -#endif // DEBUG - - friend class HuffmanPreludeReader; - friend class ::js::ScriptSource; -}; - -/// A table designed to support fast lookup in large sets of data. -/// In most cases, lookup will be slower than a `SingleLookupHuffmanTable` -/// but, particularly in heavily unbalanced trees, the table will -/// take ~2^prefix_len fewer internal entries than a `SingleLookupHuffmanTable`. -/// -/// Typically, use this table whenever codes range between 10 and 20 bits. -/// -/// # Time complexity -/// -/// A lookup in `MultiLookupHuffmanTable` will also take constant time: - -/// - a constant-time lookup in a `SingleLookupHuffmanTable`, in case we only -/// need to look for a small key; -/// - if the above lookup fails: -/// - a constant-time lookup to determine into which suffix table to perform -/// the lookup; -/// - a constant-time lookup into the suffix table; -/// - a constant-time lookup into the array of values. -/// -/// -/// # Space complexity -/// -/// TBD. Highly dependent on the shape of the Huffman Tree. -/// -/// -/// # Algorithm -/// -/// Consider the following Huffman table -/// -/// Symbol | Binary Code | Bit Length -/// ------ | ------------ | ---------- -/// A | 11000 | 5 -/// B | 11001 | 5 -/// C | 1101 | 4 -/// D | 100 | 3 -/// E | 101 | 3 -/// F | 111 | 3 -/// G | 00 | 2 -/// H | 01 | 2 -/// -/// Let us assume that we have somehow determined that: -/// -/// - we wish to store all values with a bit length of 2 -/// or less in a fast access table. -/// - we wish to use a prefix length of 4. -/// -/// Note: These numbers of 2 and 4 are picked arbitrarily -/// for the example. Actual numbers used may vary. -/// -/// We first extract all values with a bit length of <= 2: -/// -/// Symbol | Binary Code | Bit Length -/// ------ | ------------ | ---------- -/// G | 00 | 2 -/// H | 01 | 2 -/// -/// We store these values in a `SingleLookupHuffmanTable` for fast access. -/// We are now done with these values. Let's deal with the remaining values. -/// -/// Now, as our prefix length is 4, we precompute all possible 3-bit -/// prefixes and split the table across such prefixes. -/// -/// Prefix | Int Value of Prefix | Symbols | Max bit length -/// ------- | ------------------- | --------- | -------------- -/// 0000 | 0 | | 0 -/// 0001 | 1 | | 0 -/// 0010 | 2 | | 0 -/// 0011 | 3 | | 0 -/// 0100 | 4 | | 0 -/// 0101 | 5 | | 0 -/// 0110 | 6 | | 0 -/// 0111 | 7 | | 0 -/// 1000 | 8 | D | 0 -/// 1001 | 9 | D | 0 -/// 1010 | 10 | E | 0 -/// 1011 | 11 | E | 0 -/// 1100 | 12 | A, B | 1 -/// 1101 | 13 | C | 0 -/// 1110 | 14 | F | 0 -/// 1111 | 15 | F | 0 -/// -/// For each prefix, we build the table containing the Symbols, -/// stripping prefix from the Binary Code. -/// - Prefixes 0000-01111 -/// -/// Empty tables. -/// -/// - Prefixes 1000, 1001 -/// -/// Symbol | Binary Code | Bit Length | Total Bit Length -/// ------ | ----------- | ---------- | -------------- -/// D | (none) | 0 | 3 -/// -/// - Prefixes 1010, 1011 -/// -/// Symbol | Binary Code | Bit Length | Total Bit Length -/// ------ | ----------- | ---------- | -------------- -/// E | (none) | 0 | 3 -/// -/// - Prefix 1100 -/// -/// Symbol | Binary Code | Bit Length | Total Bit Length -/// ------ | ----------- | ---------- | ---------------- -/// A | 0 | 1 | 5 -/// B | 1 | 1 | 5 -/// -/// - Prefix 1101 -/// -/// Symbol | Binary Code | Bit Length | Total Bit Length -/// ------ | ----------- | ---------- | ---------------- -/// C | (none) | 0 | 4 -/// -/// - Prefixes 1110, 1111 -/// -/// Symbol | Binary Code | Bit Length | Total Bit Length -/// ------ | ----------- | ---------- | ---------------- -/// F | (none) | 0 | 4 -/// -/// -/// With this transformation, we have represented one table -/// with an initial max bit length of 5 as: -/// -/// - 1 SingleLookupValue table with a max bit length of 3; -/// - 8 empty tables; -/// - 7 tables with a max bit length of 0; -/// - 1 table with a max bit length of 1; -/// -/// Consequently, instead of storing 2^5 = 32 internal references, -/// as we would have done with a SingleLookupHuffmanTable, we only -/// need to store: -/// -/// - 1 subtable with 2^3 = 8 references; -/// - 7 subtables with 1 reference each; -/// - 1 subtable with 2^1 = 2 references. -template -class MultiLookupHuffmanTable { - public: - // The largest bit length that may be represented by this table. - static const uint8_t MAX_BIT_LENGTH = - PrefixBitLength + Subtable::MAX_BIT_LENGTH; - - MultiLookupHuffmanTable() - : shortKeys_(SingleLookupHuffmanTable::Use::ShortKeys), - largestBitLength_(-1) {} - MultiLookupHuffmanTable(MultiLookupHuffmanTable&& other) = default; - - // Initialize a Huffman table containing `numberOfSymbols`. - // Symbols must be added with `addSymbol`. - // If you initialize with `initStart`, you MUST call `initComplete()` - // at the end of initialization. - JS::Result initStart(JSContext* cx, TemporaryStorage* tempStorage, - size_t numberOfSymbols, uint8_t largestBitLength); - - JS::Result initComplete(JSContext* cx, TemporaryStorage* tempStorage); - - // Add a `(bit, bitLength) => value` mapping. - // The symbol is the `index`-th item in this table. - JS::Result addSymbol(size_t index, uint32_t bits, uint8_t bitLength, - const BinASTSymbol& value); - - MultiLookupHuffmanTable(MultiLookupHuffmanTable&) = delete; - - // Lookup a value in the table. - // - // The return of this method contains: - // - // - the resulting value (`nullptr` if the value is not in the table); - // - the number of bits in the entry associated to this value. - // - // Note that entries inside a single table are typically associated to - // distinct bit lengths. The caller is responsible for checking - // the result of this method and advancing the bitstream by - // `result.key().bitLength_` bits. - HuffmanLookupResult lookup(HuffmanLookup key) const; - - // The number of values in the table. - size_t length() const { return values_.size(); } - - // Iterating in the order of insertion. - struct Iterator { - explicit Iterator(const HuffmanEntry* position); - void operator++(); - const BinASTSymbol* operator*() const; - const BinASTSymbol* operator->() const; - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const; - - private: - const HuffmanEntry* position_; - }; - Iterator begin() const { return Iterator(&values_[0]); } - Iterator end() const { return Iterator(&values_[0] + values_.size()); } - - public: - // An index into table `values_`. - // We use `uint8_t` instead of `size_t` to limit the space - // used by the table. - using InternalIndex = uint8_t; - - private: - // Fast lookup for values whose keys fit within 8 bits. - // Such values are not added to `suffixTables`. - SingleLookupHuffmanTable shortKeys_; - - // The entries in this Huffman Table, sorted in the order of insertion. - // - // Invariant (once `init*` has been called): - // - Length is the number of values inserted in the table. - // - for all i, `values_[i].bitLength_ <= largestBitLength_`. - // - // FIXME: In a ThreeLookupsHuffmanTable, we currently store each value - // three times. We could at least get down to twice. - mozilla::Span values_; - - // A mapping from 0..2^prefixBitLen such that index `i` - // maps to a subtable that holds all values associated - // with a key that starts with `HuffmanKey(i, prefixBitLen)`. - // - // Note that, to allow the use of smaller tables, keys - // inside the subtables have been stripped - // from the prefix `HuffmanKey(i, prefixBitLen)`. - mozilla::Span suffixTables_; - - friend class HuffmanDictionaryForMetadata; - - // The maximal bitlength of a value in this table. - // - // Invariant (once `init*` has been called): - // - `largestBitLength_ <= MAX_CODE_BIT_LENGTH` - uint8_t largestBitLength_; - - friend class HuffmanPreludeReader; - friend class ::js::ScriptSource; -}; - -/// A Huffman table suitable for max bit lengths in [8, 14] -using TwoLookupsHuffmanTable = - MultiLookupHuffmanTable; - -/// A Huffman table suitable for max bit lengths in [15, 20] -using ThreeLookupsHuffmanTable = - MultiLookupHuffmanTable; - -// The initial value of GenericHuffmanTable.implementation_, that indicates -// the table isn't yet initialized. -struct TableImplementationUninitialized {}; - -// Generic implementation of Huffman tables. -// -// -struct GenericHuffmanTable { - GenericHuffmanTable(); - - // Initialize a Huffman table containing a single value. - JS::Result initWithSingleValue(JSContext* cx, const BinASTSymbol& value); - - // Initialize a Huffman table containing `numberOfSymbols`. - // Symbols must be added with `addSymbol`. - // If you initialize with `initStart`, you MUST call `initComplete()` - // at the end of initialization. - JS::Result initStart(JSContext* cx, TemporaryStorage* tempStorage, - size_t numberOfSymbols, uint8_t maxBitLength); - - // Add a `(bit, bitLength) => value` mapping. - // The symbol is the `index`-th item in this table. - JS::Result addSymbol(size_t index, uint32_t bits, uint8_t bitLength, - const BinASTSymbol& value); - - JS::Result initComplete(JSContext* cx, TemporaryStorage* tempStorage); - - // The number of values in the table. - size_t length() const; - - struct Iterator { - explicit Iterator(typename SingleEntryHuffmanTable::Iterator&&); - explicit Iterator(typename TwoEntriesHuffmanTable::Iterator&&); - explicit Iterator(typename SingleLookupHuffmanTable::Iterator&&); - explicit Iterator(typename TwoLookupsHuffmanTable::Iterator&&); - explicit Iterator(typename ThreeLookupsHuffmanTable::Iterator&&); - Iterator(Iterator&&) = default; - Iterator(const Iterator&) = default; - void operator++(); - const BinASTSymbol* operator*() const; - const BinASTSymbol* operator->() const; - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const; - - private: - mozilla::Variant - implementation_; - }; - - // Iterating in the order of insertion. - Iterator begin() const; - Iterator end() const; - - // Lookup a value in the table. - // - // The return of this method contains: - // - // - the resulting value (`nullptr` if the value is not in the table); - // - the number of bits in the entry associated to this value. - // - // Note that entries inside a single table are typically associated to - // distinct bit lengths. The caller is responsible for checking - // the result of this method and advancing the bitstream by - // `result.key().bitLength_` bits. - HuffmanLookupResult lookup(HuffmanLookup key) const; - - // `true` if this table only contains values for `null` for maybe-interface - // table. - // This method MUST be used only for maybe-interface table. - bool isMaybeInterfaceAlwaysNull() const { - MOZ_ASSERT(length() == 1 || length() == 2); - - // By definition, we have either 1 or 2 values. - // By definition, if we have 2 values, one of them is not null. - if (length() == 2) { - return false; - } - - // Otherwise, check the single value. - return begin()->toKind() == BinASTKind::_Null; - } - - private: - mozilla::Variant - implementation_; - - friend class HuffmanDictionaryForMetadata; - friend class ::js::ScriptSource; -}; - -// Temporary space to allocate `T` typed items with less alloc/free calls, -// to reduce mutex call inside allocator. -// -// Items are preallocated in `alloc` call, with at least `Chunk::DefaultSize` -// items at once, and freed in the TemporaryStorageItem destructor all at once. -// -// This class is used inside TemporaryStorage. -template -class TemporaryStorageItem { - class Chunk { - public: - // The number of `T` items per single chunk. - static const size_t DefaultSize = 1024; - - // The next (older) chunk in the linked list. - Chunk* next_ = nullptr; - - // The number of already-used items in this chunk. - size_t used_ = 0; - - // The total number of allocated items in this chunk. - // This is usually `DefaultSize`, but becomes larger if the consumer - // tries to allocate more than `DefaultSize` items at once. - size_t size_ = 0; - - // Start of the entries. - // The actual size is defined in TemporaryStorage::alloc. - T entries_[1]; - - Chunk() = default; - }; - - // The total number of used items in this storage. - size_t total_ = 0; - - // The first (latest) chunk in the linked list. - Chunk* head_ = nullptr; - - public: - TemporaryStorageItem() = default; - - ~TemporaryStorageItem() { - Chunk* chunk = head_; - while (chunk) { - Chunk* next = chunk->next_; - js_free(chunk); - chunk = next; - } - } - - // Allocate `count` number of `T` items and returns the pointer to the - // first item. - T* alloc(JSContext* cx, size_t count); - - // The total number of used items in this storage. - size_t total() const { return total_; } -}; - -// Temporary storage used for dynamic allocations while reading the Huffman -// prelude. Once reading is complete, we move them to metadata. -// -// Each items are allocated with `TemporaryStorageItem`, with less alloc/free -// calls (See `TemporaryStorageItem` doc for more details). -class TemporaryStorage { - using InternalIndex = SingleLookupHuffmanTable::InternalIndex; - - static_assert(sizeof(SingleLookupHuffmanTable::InternalIndex) == - sizeof(TwoLookupsHuffmanTable::InternalIndex), - "InternalIndex should be same between tables"); - - TemporaryStorageItem huffmanEntries_; - TemporaryStorageItem internalIndices_; - TemporaryStorageItem singleTables_; - TemporaryStorageItem twoTables_; - - public: - TemporaryStorage() = default; - - // Allocate `count` number of `T` items and returns the span to point the - // allocated items. - template - JS::Result> alloc(JSContext* cx, size_t count); - - // The total number of used items in this storage. - size_t numHuffmanEntries() const { return huffmanEntries_.total(); } - size_t numInternalIndices() const { return internalIndices_.total(); } - size_t numSingleTables() const { return singleTables_.total(); } - size_t numTwoTables() const { return twoTables_.total(); } -}; - -// Handles the mapping from NormalizedInterfaceAndField and BinASTList to -// the index inside the list of huffman tables. -// -// The mapping from `(Interface, Field) -> index` and `List -> index` is -// extracted statically from the webidl specs. -class TableIdentity { - size_t index_; - - static const size_t ListIdentityBase = BINAST_INTERFACE_AND_FIELD_LIMIT; - - public: - // The maximum number of tables. - static const size_t Limit = ListIdentityBase + BINAST_NUMBER_OF_LIST_TYPES; - - explicit TableIdentity(NormalizedInterfaceAndField index) - : index_(static_cast(index.identity_)) {} - explicit TableIdentity(BinASTList list) - : index_(static_cast(list) + ListIdentityBase) {} - - size_t toIndex() const { return index_; } -}; - -class HuffmanDictionary; - -// A Huffman dictionary for the current file, used after reading the dictionary. -// -// A Huffman dictionary consists in a (contiguous) set of Huffman tables -// to predict field values and list lengths, and (contiguous) sets of -// items pointed by each tables. -class alignas(uintptr_t) HuffmanDictionaryForMetadata { - static const uint16_t UnreachableIndex = uint16_t(-1); - - using InternalIndex = uint8_t; - - HuffmanDictionaryForMetadata(size_t numTables, size_t numHuffmanEntries, - size_t numInternalIndices, - size_t numSingleTables, size_t numTwoTables) - : numTables_(numTables), - numHuffmanEntries_(numHuffmanEntries), - numInternalIndices_(numInternalIndices), - numSingleTables_(numSingleTables), - numTwoTables_(numTwoTables) {} - - // This class is allocated with extra payload for storing tables and items. - // The full layout is the following: - // - // HuffmanDictionaryForMetadata - // GenericHuffmanTable[numTables_] - // HuffmanEntry[numHuffmanEntries_] - // InternalIndex[numInternalIndices_] - // SingleLookupHuffmanTable[numSingleTables_] - // TwoLookupsHuffmanTable[numTwoTables_] - - // Accessors for the above payload. - // Each accessor returns the pointer to the first element of each array. - mozilla::RangedPtr tablesBase() { - auto p = reinterpret_cast( - reinterpret_cast(this + 1)); - return mozilla::RangedPtr(p, p, p + numTables_); - } - const mozilla::RangedPtr tablesBase() const { - auto p = reinterpret_cast( - reinterpret_cast(this + 1)); - return mozilla::RangedPtr(p, p, p + numTables_); - } - - mozilla::RangedPtr huffmanEntriesBase() { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_); - return mozilla::RangedPtr(p, p, p + numHuffmanEntries_); - } - const mozilla::RangedPtr huffmanEntriesBase() const { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_); - return mozilla::RangedPtr(p, p, p + numHuffmanEntries_); - } - - mozilla::RangedPtr internalIndicesBase() { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_); - return mozilla::RangedPtr(p, p, p + numInternalIndices_); - } - const mozilla::RangedPtr internalIndicesBase() const { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_); - return mozilla::RangedPtr(p, p, p + numInternalIndices_); - } - - mozilla::RangedPtr singleTablesBase() { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_ + - sizeof(InternalIndex) * numInternalIndices_); - return mozilla::RangedPtr(p, p, - p + numSingleTables_); - } - const mozilla::RangedPtr singleTablesBase() const { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_ + - sizeof(InternalIndex) * numInternalIndices_); - return mozilla::RangedPtr(p, p, - p + numSingleTables_); - } - - mozilla::RangedPtr twoTablesBase() { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_ + - sizeof(InternalIndex) * numInternalIndices_ + - sizeof(SingleLookupHuffmanTable) * numSingleTables_); - return mozilla::RangedPtr(p, p, p + numTwoTables_); - } - const mozilla::RangedPtr twoTablesBase() const { - auto p = reinterpret_cast( - reinterpret_cast(this + 1) + - sizeof(GenericHuffmanTable) * numTables_ + - sizeof(HuffmanEntry) * numHuffmanEntries_ + - sizeof(InternalIndex) * numInternalIndices_ + - sizeof(SingleLookupHuffmanTable) * numSingleTables_); - return mozilla::RangedPtr(p, p, p + numTwoTables_); - } - - public: - HuffmanDictionaryForMetadata() = delete; - ~HuffmanDictionaryForMetadata(); - - // Create HuffmanDictionaryForMetadata by moving data from - // HuffmanDictionary and items allocated in TemporaryStorage. - // - // After calling this, consumers shouldn't use `dictionary` and - // `tempStorage`. - static HuffmanDictionaryForMetadata* createFrom( - HuffmanDictionary* dictionary, TemporaryStorage* tempStorage); - - static HuffmanDictionaryForMetadata* create(size_t numTables, - size_t numHuffmanEntries, - size_t numInternalIndices, - size_t numSingleTables, - size_t numTwoTables); - - void clearFromIncompleteInitialization(size_t numInitializedTables, - size_t numInitializedSingleTables, - size_t numInitializedTwoTables); - - friend class ::js::ScriptSource; - - private: - // Returns the total required size of HuffmanDictionaryForMetadata with - // extra payload to store items, in bytes. - static size_t totalSize(size_t numTables, size_t numHuffmanEntries, - size_t numInternalIndices, size_t numSingleTables, - size_t numTwoTables); - - // After allocating HuffmanDictionaryForMetadata with extra payload, - // move data from HuffmanDictionary and items allocated in TemporaryStorage. - // - // Called by createFrom. - void moveFrom(HuffmanDictionary* dictionary, TemporaryStorage* tempStorage); - - public: - bool isUnreachable(TableIdentity i) const { - return tableIndices_[i.toIndex()] == UnreachableIndex; - } - - bool isReady(TableIdentity i) const { - return tableIndices_[i.toIndex()] != UnreachableIndex; - } - - const GenericHuffmanTable& getTable(TableIdentity i) const { - MOZ_ASSERT(isReady(i)); - return table(i); - } - - private: - size_t numTables_ = 0; - size_t numHuffmanEntries_ = 0; - size_t numInternalIndices_ = 0; - size_t numSingleTables_ = 0; - size_t numTwoTables_ = 0; - - uint16_t tableIndices_[TableIdentity::Limit] = {UnreachableIndex}; - - GenericHuffmanTable& table(TableIdentity i) { - return tableAtIndex(tableIndices_[i.toIndex()]); - } - - const GenericHuffmanTable& table(TableIdentity i) const { - return tableAtIndex(tableIndices_[i.toIndex()]); - } - - GenericHuffmanTable& tableAtIndex(size_t i) { return tablesBase()[i]; } - - const GenericHuffmanTable& tableAtIndex(size_t i) const { - return tablesBase()[i]; - } - - public: - size_t numTables() const { return numTables_; } - size_t numHuffmanEntries() const { return numHuffmanEntries_; } - size_t numInternalIndices() const { return numInternalIndices_; } - size_t numSingleTables() const { return numSingleTables_; } - size_t numTwoTables() const { return numTwoTables_; } - - size_t huffmanEntryIndexOf(HuffmanEntry* entry) { - MOZ_ASSERT(huffmanEntriesBase().get() <= entry && - entry < huffmanEntriesBase().get() + numHuffmanEntries()); - return entry - huffmanEntriesBase().get(); - } - - size_t internalIndexIndexOf(InternalIndex* index) { - MOZ_ASSERT(internalIndicesBase().get() <= index && - index < internalIndicesBase().get() + numInternalIndices()); - return index - internalIndicesBase().get(); - } - - size_t singleTableIndexOf(SingleLookupHuffmanTable* table) { - MOZ_ASSERT(singleTablesBase().get() <= table && - table < singleTablesBase().get() + numSingleTables()); - return table - singleTablesBase().get(); - } - - size_t twoTableIndexOf(TwoLookupsHuffmanTable* table) { - MOZ_ASSERT(twoTablesBase().get() <= table && - table < twoTablesBase().get() + numTwoTables()); - return table - twoTablesBase().get(); - } -}; - -// When creating HuffmanDictionaryForMetadata with -// HuffmanDictionaryForMetadata::create while decoding XDR, -// it can fail and in that case the newly created HuffmanDictionaryForMetadata -// instance is left with partially initialized payload, and then -// HuffmanDictionaryForMetadata destructor can call destructor for -// uninitialized memory. -// -// This class prevents it by calling destructors on already-initialized tables -// and resetting HuffmanDictionaryForMetadata instances fields so that it -// doesn't call destructors inside its destructor. -// -// Usage: -// UniquePtr newDict; -// AutoClearHuffmanDictionaryForMetadata autoClear; -// -// auto dict = HuffmanDictionaryForMetadata::create(...); -// if (!dict) { ... } -// -// autoClear.set(dict); -// newDict.reset(dict); -// -// // When initializing table, call one of: -// autoClear.addInitializedTable(); -// autoClear.addInitializedSingleTable(); -// autoClear.addInitializedTwoTable(); -// -// // Do any fallible operation, and return on failure. -// ... -// -// // When initialization finished. -// autoClear.reset(); -// -// return dict; -class MOZ_STACK_CLASS AutoClearHuffmanDictionaryForMetadata { - frontend::HuffmanDictionaryForMetadata* dictionary_; - - size_t numInitializedTables_ = 0; - size_t numInitializedSingleTables_ = 0; - size_t numInitializedTwoTables_ = 0; - - public: - AutoClearHuffmanDictionaryForMetadata() : dictionary_(nullptr) {} - - ~AutoClearHuffmanDictionaryForMetadata() { - if (dictionary_) { - dictionary_->clearFromIncompleteInitialization( - numInitializedTables_, numInitializedSingleTables_, - numInitializedTwoTables_); - } - } - - void set(frontend::HuffmanDictionaryForMetadata* dictionary) { - dictionary_ = dictionary; - } - - void reset() { dictionary_ = nullptr; } - - void addInitializedTable() { numInitializedTables_++; } - void addInitializedSingleTable() { numInitializedSingleTables_++; } - void addInitializedTwoTable() { numInitializedTwoTables_++; } -}; - -// A Huffman dictionary for the current file, used while reading the dictionary. -// When finished reading the dictionary, all data is moved to -// `HuffmanDictionaryForMetadata`. -// -// A Huffman dictionary consists in a (contiguous) set of Huffman tables -// to predict field values and list lengths. -// -// Each table can contain pointers to items allocated inside -// `TemporaryStorageItem`. -class HuffmanDictionary { - // While reading the Huffman prelude, whenever we first encounter a - // table with `Unreachable` status, we set its status with a `Initializing` - // to mark that we should not attempt to read/initialize it again. - // Once the table is initialized, it becomes `Ready`. - enum class TableStatus : uint8_t { - Unreachable, - Initializing, - Ready, - }; - - public: - HuffmanDictionary() = default; - ~HuffmanDictionary(); - - bool isUnreachable(TableIdentity i) const { - return status_[i.toIndex()] == TableStatus::Unreachable; - } - - bool isInitializing(TableIdentity i) const { - return status_[i.toIndex()] == TableStatus::Initializing; - } - - bool isReady(TableIdentity i) const { - return status_[i.toIndex()] == TableStatus::Ready; - } - - void setInitializing(TableIdentity i) { - status_[i.toIndex()] = TableStatus::Initializing; - } - - private: - void setReady(TableIdentity i) { status_[i.toIndex()] = TableStatus::Ready; } - - public: - GenericHuffmanTable& createTable(TableIdentity i) { - MOZ_ASSERT(isUnreachable(i) || isInitializing(i)); - - setReady(i); - - tableIndices_[i.toIndex()] = nextIndex_++; - - auto& t = table(i); - new (mozilla::KnownNotNull, &t) GenericHuffmanTable(); - - return t; - } - - const GenericHuffmanTable& getTable(TableIdentity i) const { - MOZ_ASSERT(isReady(i)); - return table(i); - } - - size_t numTables() const { return nextIndex_; } - - private: - // For the following purpose, tables are stored as an array of status - // and a uninitialized buffer to store an array of tables. - // - // * In most case a single BinAST file doesn't use all tables - // * GenericHuffmanTable constructor/destructor costs are not negligible, - // and we don't want to call them for unused tables - // * Initializing status for whether the table is used or not takes - // less time if they're stored in contiguous memory, instead of - // placed before each table (using `Variant` or `Maybe`) - // - // Some tables may be left Unreachable if they represent `(Interface, Field)` - // pairs or lists that actually do not show up in the file. - TableStatus status_[TableIdentity::Limit] = {TableStatus::Unreachable}; - - // Mapping from TableIdentity to the index into tables_. - uint16_t tableIndices_[TableIdentity::Limit] = {0}; - - // The next uninitialized table's index in tables_. - uint16_t nextIndex_ = 0; - - // Huffman tables for either: - // * `(Interface, Field)` pairs, used to decode the value of - // `Interface::Field`. - // * list lengths - // - // Tables in [0..nextIndex_] range are initialized. - // - // Semantically this is `GenericHuffmanTable tables_[TableIdentity::Limit]`, - // but items are constructed lazily. - alignas(GenericHuffmanTable) char tables_[sizeof(GenericHuffmanTable) * - TableIdentity::Limit]; - - GenericHuffmanTable& table(TableIdentity i) { - return tableAtIndex(tableIndices_[i.toIndex()]); - } - - const GenericHuffmanTable& table(TableIdentity i) const { - return tableAtIndex(tableIndices_[i.toIndex()]); - } - - GenericHuffmanTable& tableAtIndex(size_t i) { - return (reinterpret_cast(tables_))[i]; - } - - const GenericHuffmanTable& tableAtIndex(size_t i) const { - return (reinterpret_cast(tables_))[i]; - } - - friend class HuffmanDictionaryForMetadata; -}; - -/** - * A token reader implementing the "context" serialization format for BinAST. - * - * This serialization format, which is also supported by the reference - * implementation of the BinAST compression suite, is designed to be - * space- and time-efficient. - * - * As other token readers for the BinAST: - * - * - the reader does not support error recovery; - * - the reader does not support lookahead or pushback. - */ -class MOZ_STACK_CLASS BinASTTokenReaderContext : public BinASTTokenReaderBase { - using Base = BinASTTokenReaderBase; - - public: - class AutoList; - class AutoTaggedTuple; - - using CharSlice = BinaryASTSupport::CharSlice; - using RootContext = BinASTTokenReaderBase::RootContext; - using ListContext = BinASTTokenReaderBase::ListContext; - using FieldContext = BinASTTokenReaderBase::FieldContext; - using FieldOrRootContext = BinASTTokenReaderBase::FieldOrRootContext; - using FieldOrListContext = BinASTTokenReaderBase::FieldOrListContext; - using Chars = CharSlice; - - public: - /** - * Construct a token reader. - * - * Does NOT copy the buffer. - */ - BinASTTokenReaderContext(JSContext* cx, ErrorReporter* er, - const uint8_t* start, const size_t length); - - /** - * Construct a token reader. - * - * Does NOT copy the buffer. - */ - BinASTTokenReaderContext(JSContext* cx, ErrorReporter* er, - const Vector& chars); - - ~BinASTTokenReaderContext(); - - // {readByte, readBuf, readVarU32} are implemented both for uncompressed - // stream and brotli-compressed stream. - // - // Uncompressed variant is for reading the magic header, and compressed - // variant is for reading the remaining part. - // - // Once compressed variant is called, the underlying uncompressed stream is - // buffered and uncompressed variant cannot be called. - enum class Compression { No, Yes }; - - // Determine what to do if we reach the end of the file. - enum class EndOfFilePolicy { - // End of file was not expected, raise an error. - RaiseError, - // End of file is ok, read as many bytes as possible. - BestEffort - }; - - protected: - // A buffer of bits used to lookup data from the Huffman tables. - // It may contain up to 64 bits. - // - // To interact with the buffer, see methods - // - advanceBitBuffer() - // - getHuffmanLookup() - struct BitBuffer { - BitBuffer(); - - // Return the HuffmanLookup for the next lookup in a Huffman table. - // After calling this method, do not forget to call `advanceBitBuffer`. - // - // If `result.bitLength_ == 0`, you have reached the end of the stream. - template - MOZ_MUST_USE JS::Result getHuffmanLookup( - BinASTTokenReaderContext& owner); - - // Advance the bit buffer by `bitLength` bits. - template - void advanceBitBuffer(const uint8_t bitLength); - - // Returns the number of buffered but unused bytes. - size_t numUnusedBytes() const { return bitLength_ / 8; } - - // Release all buffer. - void flush() { bitLength_ = 0; } - - private: - // The contents of the buffer. - // - // - Bytes are added in the same order as the bytestream. - // - Individual bits within bytes are mirrored. - // - // In other words, if the byte stream starts with - // `0b_HGFE_DCBA`, `0b_PONM_LKJI`, `0b_0000_0000`, - // .... `0b_0000_0000`, `bits_` will hold - // `0b_0000_...0000__ABCD_EFGH__IJKL_MNOP`. - // - // Note: By opposition to `HuffmanKey` or `HuffmanLookup`, - // the highest bits are NOT guaranteed to be `0`. - uint64_t bits_; - - // The number of elements in `bits_`. - // - // Until we start lookup up into Huffman tables, `bitLength_ == 0`. - // Once we do, we refill the buffer before any lookup, i.e. - // `MAX_PREFIX_BIT_LENGTH = 32 <= bitLength <= BIT_BUFFER_SIZE = 64` - // until we reach the last few bytes of the stream, - // in which case `length` decreases monotonically to 0. - // - // If `bitLength_ < BIT_BUFFER_SIZE = 64`, some of the highest - // bits of `bits_` are unused. - uint8_t bitLength_; - } bitBuffer; - - // Returns true if the brotli stream finished. - bool isEOF() const; - - /** - * Read a single byte. - */ - template - MOZ_MUST_USE JS::Result readByte(); - - /** - * Read several bytes. - * - * If the tokenizer has previously been poisoned, return an error. - * If the end of file is reached, in the case of - * EndOfFilePolicy::RaiseError, raise an error. Otherwise, update - * `len` to indicate how many bytes have actually been read. - */ - template - MOZ_MUST_USE JS::Result readBuf(uint8_t* bytes, uint32_t& len); - - enum class FillResult { EndOfStream, Filled }; - - public: - /** - * Read the header of the file. - */ - MOZ_MUST_USE JS::Result readHeader(); - - /** - * Read the footer of the tree, that contains lazy functions. - */ - MOZ_MUST_USE JS::Result readTreeFooter(); - - private: - /** - * Stop reading bit stream and unget unused buffer. - */ - void flushBitStream(); - - public: - /** - * Read the string dictionary from the header of the file. - */ - MOZ_MUST_USE JS::Result readStringPrelude(); - - /** - * Read the huffman dictionary from the header of the file. - */ - MOZ_MUST_USE JS::Result readHuffmanPrelude(); - - // --- Primitive values. - // - // Note that the underlying format allows for a `null` value for primitive - // values. - // - // Reading will return an error either in case of I/O error or in case of - // a format problem. Reading if an exception in pending is an error and - // will cause assertion failures. Do NOT attempt to read once an exception - // has been cleared: the token reader does NOT support recovery, by design. - - /** - * Read a single `true | false` value. - */ - MOZ_MUST_USE JS::Result readBool(const FieldContext&); - - /** - * Read a single `number` value. - */ - MOZ_MUST_USE JS::Result readDouble(const FieldContext&); - - /** - * Read a single `string | null` value. - * - * Fails if that string is not valid UTF-8. - */ - MOZ_MUST_USE JS::Result readMaybeAtom(const FieldContext&); - MOZ_MUST_USE JS::Result readAtom(const FieldContext&); - - /** - * Read a single IdentifierName value. - */ - MOZ_MUST_USE JS::Result readMaybeIdentifierName(const FieldContext&); - MOZ_MUST_USE JS::Result readIdentifierName(const FieldContext&); - - /** - * Read a single PropertyKey value. - */ - MOZ_MUST_USE JS::Result readPropertyKey(const FieldContext&); - - /** - * Read a single `string | null` value. - * - * MAY check if that string is not valid UTF-8. - */ - MOZ_MUST_USE JS::Result readChars(Chars&, const FieldContext&); - - /** - * Read a single `BinASTVariant | null` value. - */ - MOZ_MUST_USE JS::Result readVariant(const ListContext&); - MOZ_MUST_USE JS::Result readVariant(const FieldContext&); - - /** - * Read over a single `[Skippable]` subtree value. - * - * This does *not* attempt to parse the subtree itself. Rather, the - * returned `SkippableSubTree` contains the necessary information - * to parse/tokenize the subtree at a later stage - */ - MOZ_MUST_USE JS::Result readSkippableSubTree( - const FieldContext&); - - /** - * Register lazy script for later modification. - */ - MOZ_MUST_USE JS::Result registerLazyScript(FunctionBox* lazy); - - // --- Composite values. - // - // The underlying format does NOT allows for a `null` composite value. - // - // Reading will return an error either in case of I/O error or in case of - // a format problem. Reading from a poisoned tokenizer is an error and - // will cause assertion failures. - - /** - * Start reading a list. - * - * @param length (OUT) The number of elements in the list. - * @param guard (OUT) A guard, ensuring that we read the list correctly. - * - * The `guard` is dedicated to ensuring that reading the list has consumed - * exactly all the bytes from that list. The `guard` MUST therefore be - * destroyed at the point where the caller has reached the end of the list. - * If the caller has consumed too few/too many bytes, this will be reported - * in the call go `guard.done()`. - */ - MOZ_MUST_USE JS::Result enterList(uint32_t& length, const ListContext&); - - /** - * Start reading a tagged tuple. - * - * @param tag (OUT) The tag of the tuple. - * @param fields Ignored, provided for API compatibility. - * @param guard (OUT) A guard, ensuring that we read the tagged tuple - * correctly. - * - * The `guard` is dedicated to ensuring that reading the list has consumed - * exactly all the bytes from that tuple. The `guard` MUST therefore be - * destroyed at the point where the caller has reached the end of the tuple. - * If the caller has consumed too few/too many bytes, this will be reported - * in the call go `guard.done()`. - * - * @return out If the header of the tuple is invalid. - */ - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag) { - // We're entering a monomorphic interface, so the tag is encoded as 0 bits. - MOZ_ASSERT(tag != BinASTKind::_Uninitialized); - return Ok(); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldOrRootContext&) { - return enterInterface(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldOrListContext&) { - return enterInterface(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const RootContext&) { - return enterInterface(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const ListContext&) { - return enterInterface(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldContext&) { - return enterInterface(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const FieldOrRootContext& context) { - return enterSum(tag, context); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const FieldOrListContext& context) { - return enterSum(tag, context); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const RootContext& context) { - return enterSum(tag, context); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const ListContext& context) { - return enterSum(tag, context); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const FieldContext& context) { - return enterSum(tag, context); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, - const FieldOrRootContext&); - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, - const FieldOrListContext&); - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const RootContext&); - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const ListContext&); - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const FieldContext&); - - /** - * Read a single unsigned long. - */ - MOZ_MUST_USE JS::Result readUnsignedLong(const FieldContext&); - MOZ_MUST_USE JS::Result readUnpackedLong(); - - private: - MOZ_MUST_USE JS::Result readTagFromTable( - const BinASTInterfaceAndField&); - - MOZ_MUST_USE JS::Result readFieldFromTable( - const BinASTInterfaceAndField&); - - /** - * Report an "invalid value error". - */ - MOZ_MUST_USE ErrorResult raiseInvalidValue(); - - /** - * Report a "value not in prelude". - */ - MOZ_MUST_USE ErrorResult raiseNotInPrelude(); - - private: - /** - * Read a single uint32_t. - */ - template - MOZ_MUST_USE JS::Result readVarU32(); - - template - MOZ_MUST_USE JS::Result handleEndOfStream(); - - template - MOZ_MUST_USE JS::Result readBufCompressedAux(uint8_t* bytes, - uint32_t& len); - - private: - enum class MetadataOwnership { Owned, Unowned }; - MetadataOwnership metadataOwned_ = MetadataOwnership::Owned; - BinASTSourceMetadataContext* metadata_; - - const uint8_t* posBeforeTree_; - - // Lazy script created while reading the tree. - // After reading tree, the start/end offset are set to correct value. - Vector lazyScripts_; - - public: - BinASTTokenReaderContext(const BinASTTokenReaderContext&) = delete; - BinASTTokenReaderContext(BinASTTokenReaderContext&&) = delete; - BinASTTokenReaderContext& operator=(BinASTTokenReaderContext&) = delete; - - public: - void traceMetadata(JSTracer* trc); - BinASTSourceMetadata* takeMetadata(); - MOZ_MUST_USE JS::Result initFromScriptSource(ScriptSource* scriptSource); - - protected: - friend class HuffmanPreludeReader; - - public: - // The following classes are used whenever we encounter a tuple/tagged - // tuple/list to make sure that: - // - // - if the construct "knows" its byte length, we have exactly consumed all - // the bytes (otherwise, this means that the file is corrupted, perhaps on - // purpose, so we need to reject the stream); - // - if the construct has a footer, once we are done reading it, we have - // reached the footer (this is to aid with debugging). - // - // In either case, the caller MUST call method `done()` of the guard once - // it is done reading the tuple/tagged tuple/list, to report any pending - // error. - - // Base class used by other Auto* classes. - class MOZ_STACK_CLASS AutoBase { - protected: - explicit AutoBase(BinASTTokenReaderContext& reader) -#ifdef DEBUG - : initialized_(false), - reader_(reader) -#endif - { - } - ~AutoBase() { - // By now, the `AutoBase` must have been deinitialized by calling - // `done()`. The only case in which we can accept not calling `done()` is - // if we have bailed out because of an error. - MOZ_ASSERT_IF(initialized_, reader_.hasRaisedError()); - } - - friend BinASTTokenReaderContext; - - public: - inline void init() { -#ifdef DEBUG - initialized_ = true; -#endif - } - - inline MOZ_MUST_USE JS::Result done() { -#ifdef DEBUG - initialized_ = false; -#endif - return Ok(); - } - - protected: -#ifdef DEBUG - bool initialized_; - BinASTTokenReaderContext& reader_; -#endif - }; - - // Guard class used to ensure that `enterList` is used properly. - class MOZ_STACK_CLASS AutoList : public AutoBase { - public: - explicit AutoList(BinASTTokenReaderContext& reader) : AutoBase(reader) {} - }; - - // Guard class used to ensure that `enterTaggedTuple` is used properly. - class MOZ_STACK_CLASS AutoTaggedTuple : public AutoBase { - public: - explicit AutoTaggedTuple(BinASTTokenReaderContext& reader) - : AutoBase(reader) {} - }; - - // Compare a `Chars` and a string literal (ONLY a string literal). - template - static bool equals(const Chars& left, const char (&right)[N]) { - MOZ_ASSERT(N > 0); - MOZ_ASSERT(right[N - 1] == 0); - if (left.byteLen_ + 1 /* implicit NUL */ != N) { - return false; - } - - if (!std::equal(left.start_, left.start_ + left.byteLen_, right)) { - return false; - } - - return true; - } -}; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTTokenReaderContext_h diff --git a/js/src/frontend/BinASTTokenReaderMultipart.cpp b/js/src/frontend/BinASTTokenReaderMultipart.cpp deleted file mode 100644 index 3b443f503b..0000000000 --- a/js/src/frontend/BinASTTokenReaderMultipart.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/BinASTTokenReaderMultipart.h" - -#include "mozilla/ArrayUtils.h" -#include "mozilla/Casting.h" -#include "mozilla/EndianUtils.h" -#include "mozilla/Maybe.h" -#include "mozilla/ScopeExit.h" - -#include - -#include "frontend/BinAST-macros.h" -#include "frontend/BinASTRuntimeSupport.h" -#include "frontend/BytecodeCompiler.h" // IsIdentifier - -#include "js/Result.h" - -namespace js::frontend { - -// The magic header, at the start of every binjs file. -const char MAGIC_HEADER[] = "BINJS"; -// The latest format version understood by this tokenizer. -const uint32_t MAGIC_FORMAT_VERSION = 1; - -// The headers at the start of each section of the binjs file. -const char SECTION_HEADER_GRAMMAR[] = "[GRAMMAR]"; -const char SECTION_HEADER_STRINGS[] = "[STRINGS]"; -const char SECTION_HEADER_TREE[] = "[TREE]"; - -// The (only) internal compression mechanism understood by this parser. -const char COMPRESSION_IDENTITY[] = "identity;"; - -// The maximal number of distinct strings that may be declared in a -// single file. -const uint32_t MAX_NUMBER_OF_STRINGS = 32768; - -using AutoList = BinASTTokenReaderMultipart::AutoList; -using AutoTaggedTuple = BinASTTokenReaderMultipart::AutoTaggedTuple; -using CharSlice = BinaryASTSupport::CharSlice; -using Chars = BinASTTokenReaderMultipart::Chars; - -BinASTTokenReaderMultipart::BinASTTokenReaderMultipart(JSContext* cx, - ErrorReporter* er, - const uint8_t* start, - const size_t length) - : BinASTTokenReaderBase(cx, er, start, length), - metadata_(nullptr), - posBeforeTree_(nullptr) { - MOZ_ASSERT(er); -} - -BinASTTokenReaderMultipart::~BinASTTokenReaderMultipart() { - if (metadata_ && metadataOwned_ == MetadataOwnership::Owned) { - UniqueBinASTSourceMetadataPtr ptr(metadata_); - } -} - -BinASTSourceMetadata* BinASTTokenReaderMultipart::takeMetadata() { - MOZ_ASSERT(metadataOwned_ == MetadataOwnership::Owned); - metadataOwned_ = MetadataOwnership::Unowned; - return metadata_; -} - -JS::Result BinASTTokenReaderMultipart::initFromScriptSource( - ScriptSource* scriptSource) { - metadata_ = scriptSource->binASTSourceMetadata()->asMultipart(); - metadataOwned_ = MetadataOwnership::Unowned; - - return Ok(); -} - -JS::Result BinASTTokenReaderMultipart::readHeader() { - // Check that we don't call this function twice. - MOZ_ASSERT(!posBeforeTree_); - - // Read global headers. - MOZ_TRY(readConst(MAGIC_HEADER)); - BINJS_MOZ_TRY_DECL(version, readInternalUint32()); - - // For the moment, MAGIC_FORMAT_VERSION is 0. Once we have a story - // on backwards compatibility of the binary container, we will - // probably want to change this to `if (version > MAGIC_FORMAT_VERSION)`. - if (version != MAGIC_FORMAT_VERSION) { - return raiseError("Format version not implemented"); - } - - // Start reading grammar. - MOZ_TRY(readConst(SECTION_HEADER_GRAMMAR)); - MOZ_TRY(readConst(COMPRESSION_IDENTITY)); // For the moment, we only support - // identity compression. - BINJS_MOZ_TRY_DECL(grammarByteLen, readInternalUint32()); - const auto posBeforeGrammar = current_; - - if (posBeforeGrammar + grammarByteLen > stop_ || - posBeforeGrammar + grammarByteLen < current_) { // Sanity check. - return raiseError("Invalid byte length in grammar table"); - } - - BINJS_MOZ_TRY_DECL(grammarNumberOfEntries, readInternalUint32()); - if (grammarNumberOfEntries > BINASTKIND_LIMIT) { // Sanity check. - return raiseError("Invalid number of entries in grammar table"); - } - - // This table maps BinASTKind index -> BinASTKind. - // Initialize and populate. - Vector grammarTable_(cx_); - if (!grammarTable_.reserve(grammarNumberOfEntries)) { - return raiseOOM(); - } - - for (uint32_t i = 0; i < grammarNumberOfEntries; ++i) { - BINJS_MOZ_TRY_DECL(byteLen, readInternalUint32()); - if (current_ + byteLen > stop_) { - return raiseError("Invalid byte length in grammar table"); - } - if (current_ + byteLen < current_) { // Overflow. - return raiseError("Invalid byte length in grammar table"); - } - CharSlice name((const char*)current_, byteLen); - current_ += byteLen; - - BINJS_MOZ_TRY_DECL(kind, cx_->runtime()->binast().binASTKind(cx_, name)); - if (!kind) { - return raiseError("Invalid entry in grammar table"); - } - - grammarTable_.infallibleAppend( - *kind); // We called `reserve` before the loop. - } - if (current_ != grammarByteLen + posBeforeGrammar) { - return raiseError( - "The length of the grammar table didn't match its contents."); - } - - // Start reading strings - MOZ_TRY(readConst(SECTION_HEADER_STRINGS)); - MOZ_TRY(readConst(COMPRESSION_IDENTITY)); // For the moment, we only support - // identity compression. - BINJS_MOZ_TRY_DECL(stringsByteLen, readInternalUint32()); - const auto posBeforeStrings = current_; - - if (posBeforeStrings + stringsByteLen > stop_ || - posBeforeStrings + stringsByteLen < current_) { // Sanity check. - return raiseError("Invalid byte length in strings table"); - } - - BINJS_MOZ_TRY_DECL(stringsNumberOfEntries, readInternalUint32()); - if (stringsNumberOfEntries > MAX_NUMBER_OF_STRINGS) { // Sanity check. - return raiseError("Too many entries in strings table"); - } - - BinASTSourceMetadataMultipart* metadata = - BinASTSourceMetadataMultipart::create(grammarTable_, - stringsNumberOfEntries); - if (!metadata) { - return raiseOOM(); - } - - // Free it if we don't make it out of here alive. Since we don't want to - // calloc(), we need to avoid marking atoms that might not be there. - auto se = mozilla::MakeScopeExit([metadata]() { js_free(metadata); }); - - RootedAtom atom(cx_); - for (uint32_t i = 0; i < stringsNumberOfEntries; ++i) { - BINJS_MOZ_TRY_DECL(byteLen, readInternalUint32()); - if (current_ + byteLen > stop_ || current_ + byteLen < current_) { - return raiseError("Invalid byte length in individual string"); - } - - // Check null string. - if (byteLen == 2 && *current_ == 255 && *(current_ + 1) == 0) { - atom = nullptr; - } else { - BINJS_TRY_VAR(atom, - AtomizeWTF8Chars(cx_, (const char*)current_, byteLen)); - } - - metadata->getAtom(i) = atom; - - // Populate `slicesTable_`: i => slice - new (&metadata->getSlice(i)) Chars((const char*)current_, byteLen); - - current_ += byteLen; - } - - if (posBeforeStrings + stringsByteLen != current_) { - return raiseError( - "The length of the strings table didn't match its contents."); - } - - MOZ_ASSERT(!metadata_); - se.release(); - metadata_ = metadata; - metadataOwned_ = MetadataOwnership::Owned; - - // Start reading AST. - MOZ_TRY(readConst(SECTION_HEADER_TREE)); - MOZ_TRY(readConst(COMPRESSION_IDENTITY)); // For the moment, we only support - // identity compression. - posBeforeTree_ = current_; - - BINJS_MOZ_TRY_DECL(treeByteLen, readInternalUint32()); - - if (posBeforeTree_ + treeByteLen > stop_ || - posBeforeTree_ + treeByteLen < posBeforeTree_) { // Sanity check. - return raiseError("Invalid byte length in tree table"); - } - - // At this stage, we're ready to start reading the tree. - return Ok(); -} - -void BinASTTokenReaderMultipart::traceMetadata(JSTracer* trc) { - if (metadata_) { - metadata_->trace(trc); - } -} - -JS::Result BinASTTokenReaderMultipart::readBool(const FieldContext&) { - updateLatestKnownGood(); - BINJS_MOZ_TRY_DECL(byte, readByte()); - - switch (byte) { - case 0: - return false; - case 1: - return true; - case 2: - return raiseError("Not implemented: null boolean value"); - default: - return raiseError("Invalid boolean value"); - } -} - -// Nullable doubles (little-endian) -// -// NULL_FLOAT_REPRESENTATION (signaling NaN) => null -// anything other 64 bit sequence => IEEE-764 64-bit floating point number -JS::Result BinASTTokenReaderMultipart::readDouble(const FieldContext&) { - updateLatestKnownGood(); - - uint8_t bytes[8]; - MOZ_ASSERT(sizeof(bytes) == sizeof(double)); - MOZ_TRY( - readBuf(reinterpret_cast(bytes), mozilla::ArrayLength(bytes))); - - // Decode little-endian. - const uint64_t asInt = mozilla::LittleEndian::readUint64(bytes); - - if (asInt == NULL_FLOAT_REPRESENTATION) { - return raiseError("Not implemented: null double value"); - } - - // Canonicalize NaN, just to make sure another form of signalling NaN - // doesn't slip past us. - return JS::CanonicalizeNaN(mozilla::BitwiseCast(asInt)); -} - -// A single atom is represented as an index into the table of strings. -JS::Result BinASTTokenReaderMultipart::readMaybeAtom( - const FieldContext&) { - updateLatestKnownGood(); - BINJS_MOZ_TRY_DECL(index, readInternalUint32()); - - if (index >= metadata_->numStrings()) { - return raiseError("Invalid index to strings table"); - } - return metadata_->getAtom(index); -} - -JS::Result BinASTTokenReaderMultipart::readAtom( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(maybe, readMaybeAtom(context)); - - if (!maybe) { - return raiseError("Empty string"); - } - - return maybe; -} - -JS::Result BinASTTokenReaderMultipart::readMaybeIdentifierName( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readMaybeAtom(context)); - if (result) { - if (!IsIdentifier(result)) { - return raiseError("Invalid identifier"); - } - } - return result; -} - -JS::Result BinASTTokenReaderMultipart::readIdentifierName( - const FieldContext& context) { - BINJS_MOZ_TRY_DECL(result, readAtom(context)); - if (!IsIdentifier(result)) { - return raiseError("Invalid identifier"); - } - return result; -} - -JS::Result BinASTTokenReaderMultipart::readPropertyKey( - const FieldContext& context) { - return readAtom(context); -} - -JS::Result BinASTTokenReaderMultipart::readChars(Chars& out, - const FieldContext&) { - updateLatestKnownGood(); - BINJS_MOZ_TRY_DECL(index, readInternalUint32()); - - if (index >= metadata_->numStrings()) { - return raiseError("Invalid index to strings table for string enum"); - } - - out = metadata_->getSlice(index); - return Ok(); -} - -JS::Result BinASTTokenReaderMultipart::readVariant() { - updateLatestKnownGood(); - BINJS_MOZ_TRY_DECL(index, readInternalUint32()); - - if (index >= metadata_->numStrings()) { - return raiseError("Invalid index to strings table for string enum"); - } - - auto variantsPtr = variantsTable_.lookupForAdd(index); - if (variantsPtr) { - return variantsPtr->value(); - } - - // Either we haven't cached the result yet or this is not a variant. - // Check in the slices table and, in case of success, cache the result. - - // Note that we stop parsing if we attempt to readVariant() with an - // ill-formed variant, so we don't run the risk of feching an ill-variant - // more than once. - Chars slice = metadata_->getSlice(index); // We have checked `index` above. - BINJS_MOZ_TRY_DECL(variant, - cx_->runtime()->binast().binASTVariant(cx_, slice)); - - if (!variant) { - return raiseError("Invalid string enum variant"); - } - - if (!variantsTable_.add(variantsPtr, index, *variant)) { - return raiseOOM(); - } - - return *variant; -} - -JS::Result -BinASTTokenReaderMultipart::readSkippableSubTree(const FieldContext&) { - updateLatestKnownGood(); - BINJS_MOZ_TRY_DECL(byteLen, readInternalUint32()); - - if (current_ + byteLen > stop_ || current_ + byteLen < current_) { - return raiseError("Invalid byte length in readSkippableSubTree"); - } - - const auto start = offset(); - - current_ += byteLen; - - return BinASTTokenReaderBase::SkippableSubTree(start, byteLen); -} - -// Tagged tuples: -// - uint32_t index in table [grammar]; -// - content (specified by the higher-level grammar); -JS::Result BinASTTokenReaderMultipart::enterTaggedTuple(BinASTKind& tag) { - BINJS_MOZ_TRY_DECL(index, readInternalUint32()); - if (index >= metadata_->numBinASTKinds()) { - return raiseError("Invalid index to grammar table"); - } - - tag = metadata_->getBinASTKind(index); - return Ok(); -} - -// List: -// -// - uint32_t number of items; -// - contents (specified by higher-level grammar); -// -// The total byte length of `number of items` + `contents` must be `byte -// length`. -JS::Result BinASTTokenReaderMultipart::enterList(uint32_t& items, - const ListContext&) { - MOZ_TRY_VAR(items, readInternalUint32()); - - return Ok(); -} - -void BinASTTokenReaderMultipart::AutoBase::init() { initialized_ = true; } - -BinASTTokenReaderMultipart::AutoBase::AutoBase( - BinASTTokenReaderMultipart& reader) - : initialized_(false), reader_(reader) {} - -BinASTTokenReaderMultipart::AutoBase::~AutoBase() { - // By now, the `AutoBase` must have been deinitialized by calling `done()`. - // The only case in which we can accept not calling `done()` is if we have - // bailed out because of an error. - MOZ_ASSERT_IF(initialized_, reader_.hasRaisedError()); -} - -BinASTTokenReaderMultipart::AutoList::AutoList( - BinASTTokenReaderMultipart& reader) - : AutoBase(reader) {} - -JS::Result BinASTTokenReaderMultipart::AutoList::done() { - MOZ_ASSERT(initialized_); - initialized_ = false; - if (reader_.hasRaisedError()) { - // Already errored, no need to check further. - return reader_.cx_->alreadyReportedError(); - } - - return Ok(); -} - -// Internal uint32_t -// -// Encoded as variable length number. - -MOZ_MUST_USE JS::Result -BinASTTokenReaderMultipart::readInternalUint32() { - uint32_t result = 0; - uint32_t shift = 0; - while (true) { - MOZ_ASSERT(shift < 32); - uint32_t byte; - MOZ_TRY_VAR(byte, readByte()); - - const uint32_t newResult = result | (byte >> 1) << shift; - if (newResult < result) { - return raiseError("Overflow during readInternalUint32"); - } - - result = newResult; - shift += 7; - - if ((byte & 1) == 0) { - return result; - } - - if (shift >= 32) { - return raiseError("Overflow during readInternalUint32"); - } - } -} - -BinASTTokenReaderMultipart::AutoTaggedTuple::AutoTaggedTuple( - BinASTTokenReaderMultipart& reader) - : AutoBase(reader) {} - -JS::Result BinASTTokenReaderMultipart::AutoTaggedTuple::done() { - MOZ_ASSERT(initialized_); - initialized_ = false; - if (reader_.hasRaisedError()) { - // Already errored, no need to check further. - return reader_.cx_->alreadyReportedError(); - } - - return Ok(); -} - -} // namespace js::frontend diff --git a/js/src/frontend/BinASTTokenReaderMultipart.h b/js/src/frontend/BinASTTokenReaderMultipart.h deleted file mode 100644 index cf28ac4905..0000000000 --- a/js/src/frontend/BinASTTokenReaderMultipart.h +++ /dev/null @@ -1,380 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_BinASTTokenReaderMultipart_h -#define frontend_BinASTTokenReaderMultipart_h - -#include "mozilla/Maybe.h" - -#include "frontend/BinASTRuntimeSupport.h" -#include "frontend/BinASTToken.h" -#include "frontend/BinASTTokenReaderBase.h" - -#include "js/Result.h" - -namespace js { -namespace frontend { - -/** - * A token reader implementing the "multipart" serialization format for BinAST. - * - * This serialization format, which is also supported by the reference - * implementation of the BinAST compression suite, is designed to be - * space- and time-efficient. - * - * As other token readers for the BinAST: - * - * - the reader does not support error recovery; - * - the reader does not support lookahead or pushback. - */ -class MOZ_STACK_CLASS BinASTTokenReaderMultipart - : public BinASTTokenReaderBase { - public: - class AutoList; - class AutoTaggedTuple; - - using CharSlice = BinaryASTSupport::CharSlice; - using RootContext = BinASTTokenReaderBase::RootContext; - using ListContext = BinASTTokenReaderBase::ListContext; - using FieldContext = BinASTTokenReaderBase::FieldContext; - using FieldOrRootContext = BinASTTokenReaderBase::FieldOrRootContext; - using FieldOrListContext = BinASTTokenReaderBase::FieldOrListContext; - using Chars = CharSlice; - - public: - /** - * Construct a token reader. - * - * Does NOT copy the buffer. - */ - BinASTTokenReaderMultipart(JSContext* cx, ErrorReporter* er, - const uint8_t* start, const size_t length); - - /** - * Construct a token reader. - * - * Does NOT copy the buffer. - */ - BinASTTokenReaderMultipart(JSContext* cx, ErrorReporter* er, - const Vector& chars); - - ~BinASTTokenReaderMultipart(); - - /** - * Read the header of the file. - */ - MOZ_MUST_USE JS::Result readHeader(); - - /** - * Read the footer of the tree, that multipart format doesn't have. - */ - MOZ_MUST_USE JS::Result readTreeFooter() { return Ok(); } - - // --- Primitive values. - // - // Note that the underlying format allows for a `null` value for primitive - // values. - // - // Reading will return an error either in case of I/O error or in case of - // a format problem. Reading if an exception in pending is an error and - // will cause assertion failures. Do NOT attempt to read once an exception - // has been cleared: the token reader does NOT support recovery, by design. - - /** - * Read a single `true | false` value. - */ - MOZ_MUST_USE JS::Result readBool(const FieldContext&); - - /** - * Read a single `number` value. - */ - MOZ_MUST_USE JS::Result readDouble(const FieldContext&); - - /** - * Read a single `string | null` value. - * - * Fails if that string is not valid UTF-8. - */ - MOZ_MUST_USE JS::Result readMaybeAtom(const FieldContext&); - MOZ_MUST_USE JS::Result readAtom(const FieldContext&); - - /** - * Read a single IdentifierName value. - */ - MOZ_MUST_USE JS::Result readMaybeIdentifierName(const FieldContext&); - MOZ_MUST_USE JS::Result readIdentifierName(const FieldContext&); - - /** - * Read a single PropertyKey value. - */ - MOZ_MUST_USE JS::Result readPropertyKey(const FieldContext&); - - /** - * Read a single `string | null` value. - * - * MAY check if that string is not valid UTF-8. - */ - MOZ_MUST_USE JS::Result readChars(Chars&, const FieldContext&); - - /** - * Read a single `BinASTVariant | null` value. - */ - private: - MOZ_MUST_USE JS::Result readVariant(); - - public: - MOZ_MUST_USE JS::Result readVariant( - const ListContext& context) { - return readVariant(); - } - MOZ_MUST_USE JS::Result readVariant( - const FieldContext& context) { - return readVariant(); - } - - /** - * Read over a single `[Skippable]` subtree value. - * - * This does *not* attempt to parse the subtree itself. Rather, the - * returned `SkippableSubTree` contains the necessary information - * to parse/tokenize the subtree at a later stage - */ - MOZ_MUST_USE JS::Result readSkippableSubTree( - const FieldContext&); - - /** - * Register lazy script for later modification. - * Not used in multipart format. - */ - MOZ_MUST_USE JS::Result registerLazyScript(FunctionBox* lazy) { - return Ok(); - } - - // --- Composite values. - // - // The underlying format does NOT allows for a `null` composite value. - // - // Reading will return an error either in case of I/O error or in case of - // a format problem. Reading from a poisoned tokenizer is an error and - // will cause assertion failures. - - /** - * Start reading a list. - * - * @param length (OUT) The number of elements in the list. - * @param guard (OUT) A guard, ensuring that we read the list correctly. - * - * The `guard` is dedicated to ensuring that reading the list has consumed - * exactly all the bytes from that list. The `guard` MUST therefore be - * destroyed at the point where the caller has reached the end of the list. - * If the caller has consumed too few/too many bytes, this will be reported - * in the call go `guard.done()`. - */ - MOZ_MUST_USE JS::Result enterList(uint32_t& length, const ListContext&); - - /** - * Start reading a tagged tuple. - * - * @param tag (OUT) The tag of the tuple. - * @param fields Ignored, provided for API compatibility. - * @param guard (OUT) A guard, ensuring that we read the tagged tuple - * correctly. - * - * The `guard` is dedicated to ensuring that reading the list has consumed - * exactly all the bytes from that tuple. The `guard` MUST therefore be - * destroyed at the point where the caller has reached the end of the tuple. - * If the caller has consumed too few/too many bytes, this will be reported - * in the call go `guard.done()`. - * - * @return out If the header of the tuple is invalid. - */ - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag); - - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag, - const FieldOrRootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag, - const FieldOrListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag, - const RootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag, - const ListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterTaggedTuple(BinASTKind& tag, - const FieldContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldOrRootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldOrListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const RootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const ListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterInterface(BinASTKind& tag, - const FieldContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, - const FieldOrRootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, - const FieldOrListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const RootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const ListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterSum(BinASTKind& tag, const FieldContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const FieldOrRootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface( - BinASTKind& tag, const FieldOrListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface(BinASTKind& tag, - const RootContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface(BinASTKind& tag, - const ListContext&) { - return enterTaggedTuple(tag); - } - MOZ_MUST_USE JS::Result enterOptionalInterface(BinASTKind& tag, - const FieldContext&) { - return enterTaggedTuple(tag); - } - - /** - * Read a single unsigned long. - */ - MOZ_MUST_USE JS::Result readUnsignedLong(const FieldContext&) { - return readInternalUint32(); - } - - private: - /** - * Read a single uint32_t. - */ - MOZ_MUST_USE JS::Result readInternalUint32(); - - private: - // A mapping string index => BinASTVariant as extracted from the [STRINGS] - // section of the file. Populated lazily. - js::HashMap, - SystemAllocPolicy> - variantsTable_; - - enum class MetadataOwnership { Owned, Unowned }; - MetadataOwnership metadataOwned_ = MetadataOwnership::Owned; - BinASTSourceMetadataMultipart* metadata_; - - const uint8_t* posBeforeTree_; - - BinASTTokenReaderMultipart(const BinASTTokenReaderMultipart&) = delete; - BinASTTokenReaderMultipart(BinASTTokenReaderMultipart&&) = delete; - BinASTTokenReaderMultipart& operator=(BinASTTokenReaderMultipart&) = delete; - - public: - void traceMetadata(JSTracer* trc); - BinASTSourceMetadata* takeMetadata(); - MOZ_MUST_USE JS::Result initFromScriptSource(ScriptSource* scriptSource); - - public: - // The following classes are used whenever we encounter a tuple/tagged - // tuple/list to make sure that: - // - // - if the construct "knows" its byte length, we have exactly consumed all - // the bytes (otherwise, this means that the file is corrupted, perhaps on - // purpose, so we need to reject the stream); - // - if the construct has a footer, once we are done reading it, we have - // reached the footer (this is to aid with debugging). - // - // In either case, the caller MUST call method `done()` of the guard once - // it is done reading the tuple/tagged tuple/list, to report any pending - // error. - - // Base class used by other Auto* classes. - class MOZ_STACK_CLASS AutoBase { - protected: - explicit AutoBase(BinASTTokenReaderMultipart& reader); - ~AutoBase(); - - friend BinASTTokenReaderMultipart; - - public: - void init(); - - protected: - // Set to `true` if `init()` has been called. Reset to `false` once - // all conditions have been checked. - bool initialized_; - BinASTTokenReaderMultipart& reader_; - }; - - // Guard class used to ensure that `enterList` is used properly. - class MOZ_STACK_CLASS AutoList : public AutoBase { - public: - explicit AutoList(BinASTTokenReaderMultipart& reader); - - // Check that we have properly read to the end of the list. - MOZ_MUST_USE JS::Result done(); - - protected: - friend BinASTTokenReaderMultipart; - }; - - // Guard class used to ensure that `enterTaggedTuple` is used properly. - class MOZ_STACK_CLASS AutoTaggedTuple : public AutoBase { - public: - explicit AutoTaggedTuple(BinASTTokenReaderMultipart& reader); - - // Check that we have properly read to the end of the tuple. - MOZ_MUST_USE JS::Result done(); - }; - - // Compare a `Chars` and a string literal (ONLY a string literal). - template - static bool equals(const Chars& left, const char (&right)[N]) { - MOZ_ASSERT(N > 0); - MOZ_ASSERT(right[N - 1] == 0); - if (left.byteLen_ + 1 /* implicit NUL */ != N) { - return false; - } - - if (!std::equal(left.start_, left.start_ + left.byteLen_, right)) { - return false; - } - - return true; - } -}; - -} // namespace frontend -} // namespace js - -#endif // frontend_BinASTTokenReaderMultipart_h diff --git a/js/src/frontend/BytecodeCompilation.h b/js/src/frontend/BytecodeCompilation.h index 7badbdc79b..f53d253ba5 100644 --- a/js/src/frontend/BytecodeCompilation.h +++ b/js/src/frontend/BytecodeCompilation.h @@ -15,20 +15,25 @@ #include "jstypes.h" // JS_PUBLIC_API -#include "frontend/CompilationInfo.h" -#include "frontend/ParseContext.h" // js::frontend::UsedNameTracker +#include "frontend/CompilationInfo.h" // CompilationInfo, CompilationGCOutput +#include "frontend/ParseContext.h" // js::frontend::UsedNameTracker #include "frontend/SharedContext.h" // js::frontend::Directives, js::frontend::{,Eval,Global}SharedContext #include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions #include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted #include "js/SourceText.h" // JS::SourceText +#include "js/UniquePtr.h" // js::UniquePtr #include "vm/JSScript.h" // js::{FunctionAsync,Generator}Kind, js::BaseScript, JSScript, js::ScriptSource, js::ScriptSourceObject #include "vm/Scope.h" // js::ScopeKind class JS_PUBLIC_API JSFunction; class JS_PUBLIC_API JSObject; +class JSObject; + namespace js { +class Scope; + namespace frontend { struct BytecodeEmitter; @@ -43,27 +48,56 @@ class ModuleCompiler; template class StandaloneFunctionCompiler; -extern JSScript* CompileGlobalScript(CompilationInfo& compilationInfo, - GlobalSharedContext& globalsc, - JS::SourceText& srcBuf); +extern bool CompileGlobalScriptToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + ScopeKind scopeKind); + +extern bool CompileGlobalScriptToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, ScopeKind scopeKind); + +extern UniquePtr CompileGlobalScriptToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind); + +extern UniquePtr CompileGlobalScriptToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind); + +extern bool InstantiateStencils(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput); + +extern JSScript* CompileGlobalScript(JSContext* cx, + const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, + ScopeKind scopeKind); + +extern JSScript* CompileGlobalScript(JSContext* cx, + const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, + ScopeKind scopeKind); + +extern JSScript* CompileEvalScript(JSContext* cx, + const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, + JS::Handle enclosingScope, + JS::Handle enclosingEnv); -extern JSScript* CompileGlobalScript(CompilationInfo& compilationInfo, - GlobalSharedContext& globalsc, - JS::SourceText& srcBuf); +extern void FillCompileOptionsForLazyFunction(JS::CompileOptions& options, + Handle lazy); -extern JSScript* CompileEvalScript(CompilationInfo& compilationInfo, - EvalSharedContext& evalsc, - JS::SourceText& srcBuf); +extern MOZ_MUST_USE bool CompileLazyFunctionToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::Handle lazy, const char16_t* units, size_t length); -extern MOZ_MUST_USE bool CompileLazyFunction(JSContext* cx, - JS::Handle lazy, - const char16_t* units, - size_t length); +extern MOZ_MUST_USE bool CompileLazyFunctionToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::Handle lazy, const mozilla::Utf8Unit* units, + size_t length); -extern MOZ_MUST_USE bool CompileLazyFunction(JSContext* cx, - JS::Handle lazy, - const mozilla::Utf8Unit* units, - size_t length); +extern bool InstantiateStencilsForDelazify(JSContext* cx, + CompilationInfo& compilationInfo); } // namespace frontend diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 7556368e52..79b981ff28 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -10,19 +10,21 @@ #include "mozilla/Utf8.h" // mozilla::Utf8Unit #include "builtin/ModuleObject.h" -#if defined(JS_BUILD_BINAST) -# include "frontend/BinASTParser.h" -#endif // JS_BUILD_BINAST #include "frontend/BytecodeCompilation.h" #include "frontend/BytecodeEmitter.h" #include "frontend/EitherParser.h" #include "frontend/ErrorReporter.h" #include "frontend/FoldConstants.h" +#ifdef JS_ENABLE_SMOOSH +# include "frontend/Frontend2.h" // Smoosh +#endif #include "frontend/ModuleSharedContext.h" #include "frontend/Parser.h" #include "js/SourceText.h" +#include "vm/FunctionFlags.h" // FunctionFlags #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind #include "vm/GlobalObject.h" +#include "vm/HelperThreadState.h" // ParseTask #include "vm/JSContext.h" #include "vm/JSScript.h" #include "vm/ModuleBuilder.h" // js::ModuleBuilder @@ -77,6 +79,7 @@ class MOZ_RAII AutoAssertReportedException { }; static bool EmplaceEmitter(CompilationInfo& compilationInfo, + CompilationState& compilationState, Maybe& emitter, const EitherParser& parser, SharedContext* sc); @@ -85,45 +88,54 @@ class MOZ_STACK_CLASS frontend::SourceAwareCompiler { protected: SourceText& sourceBuffer_; + frontend::CompilationState compilationState_; + Maybe> syntaxParser; Maybe> parser; using TokenStreamPosition = frontend::TokenStreamPosition; protected: - explicit SourceAwareCompiler(SourceText& sourceBuffer) - : sourceBuffer_(sourceBuffer) { + explicit SourceAwareCompiler(JSContext* cx, LifoAllocScope& allocScope, + const JS::ReadOnlyCompileOptions& options, + SourceText& sourceBuffer, + js::Scope* enclosingScope = nullptr, + JSObject* enclosingEnv = nullptr) + : sourceBuffer_(sourceBuffer), + compilationState_(cx, allocScope, options, enclosingScope, + enclosingEnv) { MOZ_ASSERT(sourceBuffer_.get() != nullptr); } // Call this before calling compile{Global,Eval}Script. - MOZ_MUST_USE bool createSourceAndParser(LifoAllocScope& allocScope, + MOZ_MUST_USE bool createSourceAndParser(JSContext* cx, CompilationInfo& compilationInfo); - void assertSourceAndParserCreated(CompilationInfo& compilationInfo) const { - MOZ_ASSERT(compilationInfo.sourceObject != nullptr); - MOZ_ASSERT(compilationInfo.sourceObject->source() != nullptr); + void assertSourceAndParserCreated(CompilationInput& compilationInput) const { + MOZ_ASSERT(compilationInput.source() != nullptr); MOZ_ASSERT(parser.isSome()); } - void assertSourceParserAndScriptCreated(CompilationInfo& compilationInfo) { - assertSourceAndParserCreated(compilationInfo); + void assertSourceParserAndScriptCreated(CompilationInput& compilationInput) { + assertSourceAndParserCreated(compilationInput); } MOZ_MUST_USE bool emplaceEmitter(CompilationInfo& compilationInfo, Maybe& emitter, SharedContext* sharedContext) { - return EmplaceEmitter(compilationInfo, emitter, EitherParser(parser.ptr()), - sharedContext); + return EmplaceEmitter(compilationInfo, compilationState_, emitter, + EitherParser(parser.ptr()), sharedContext); } - bool canHandleParseFailure(CompilationInfo& compilationInfo, - const Directives& newDirectives); + bool canHandleParseFailure(const Directives& newDirectives); void handleParseFailure(CompilationInfo& compilationInfo, const Directives& newDirectives, TokenStreamPosition& startPosition, CompilationInfo::RewindToken& startObj); + + public: + frontend::CompilationState& compilationState() { return compilationState_; }; }; template @@ -132,6 +144,7 @@ class MOZ_STACK_CLASS frontend::ScriptCompiler using Base = SourceAwareCompiler; protected: + using Base::compilationState_; using Base::parser; using Base::sourceBuffer_; @@ -143,11 +156,18 @@ class MOZ_STACK_CLASS frontend::ScriptCompiler using typename Base::TokenStreamPosition; public: - explicit ScriptCompiler(SourceText& srcBuf) : Base(srcBuf) {} + explicit ScriptCompiler(JSContext* cx, LifoAllocScope& allocScope, + const JS::ReadOnlyCompileOptions& options, + SourceText& sourceBuffer, + js::Scope* enclosingScope = nullptr, + JSObject* enclosingEnv = nullptr) + : Base(cx, allocScope, options, sourceBuffer, enclosingScope, + enclosingEnv) {} using Base::createSourceAndParser; - JSScript* compileScript(CompilationInfo& compilationInfo, SharedContext* sc); + bool compileScriptToStencil(JSContext* cx, CompilationInfo& compilationInfo, + SharedContext* sc); }; /* If we're on main thread, tell the Debugger about a newly compiled script. @@ -167,71 +187,250 @@ static void tellDebuggerAboutCompiledScript(JSContext* cx, bool hideScript, } } +#ifdef JS_ENABLE_SMOOSH +bool TrySmoosh(JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, bool* fallback) { + if (!cx->options().trySmoosh()) { + *fallback = true; + return true; + } + + bool unimplemented = false; + JSRuntime* rt = cx->runtime(); + bool result = Smoosh::compileGlobalScriptToStencil(cx, compilationInfo, + srcBuf, &unimplemented); + if (!unimplemented) { + *fallback = false; + + if (!compilationInfo.input.assignSource(cx, srcBuf)) { + return false; + } + + if (cx->options().trackNotImplemented()) { + rt->parserWatcherFile.put("1"); + } + return result; + } + *fallback = true; + + if (cx->options().trackNotImplemented()) { + rt->parserWatcherFile.put("0"); + } + fprintf(stderr, "Falling back!\n"); + + return true; +} + +bool TrySmoosh(JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, bool* fallback) { + *fallback = true; + return true; +} +#endif // JS_ENABLE_SMOOSH + template -static JSScript* CreateGlobalScript(CompilationInfo& compilationInfo, - GlobalSharedContext& globalsc, - JS::SourceText& srcBuf) { - AutoAssertReportedException assertException(compilationInfo.cx); +static bool CompileGlobalScriptToStencilImpl(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + ScopeKind scopeKind) { +#ifdef JS_ENABLE_SMOOSH + bool fallback = false; + if (!TrySmoosh(cx, compilationInfo, srcBuf, &fallback)) { + return false; + } + if (!fallback) { + return true; + } +#endif // JS_ENABLE_SMOOSH + + AutoAssertReportedException assertException(cx); + + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + frontend::ScriptCompiler compiler( + cx, allocScope, compilationInfo.input.options, srcBuf); + + if (!compiler.createSourceAndParser(cx, compilationInfo)) { + return false; + } - LifoAllocScope allocScope(&compilationInfo.cx->tempLifoAlloc()); - frontend::ScriptCompiler compiler(srcBuf); + SourceExtent extent = SourceExtent::makeGlobalExtent( + srcBuf.length(), compilationInfo.input.options.lineno, + compilationInfo.input.options.column); + frontend::GlobalSharedContext globalsc(cx, scopeKind, compilationInfo, + compiler.compilationState().directives, + extent); - if (!compiler.createSourceAndParser(allocScope, compilationInfo)) { + if (!compiler.compileScriptToStencil(cx, compilationInfo, &globalsc)) { + return false; + } + + assertException.reset(); + return true; +} + +bool frontend::CompileGlobalScriptToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + ScopeKind scopeKind) { + return CompileGlobalScriptToStencilImpl(cx, compilationInfo, srcBuf, + scopeKind); +} + +bool frontend::CompileGlobalScriptToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + ScopeKind scopeKind) { + return CompileGlobalScriptToStencilImpl(cx, compilationInfo, srcBuf, + scopeKind); +} + +template +static UniquePtr CompileGlobalScriptToStencilImpl( + JSContext* cx, const ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + Rooted> compilationInfo( + cx, js_new(cx, options)); + if (!compilationInfo) { + ReportOutOfMemory(cx); + return nullptr; + } + + if (!compilationInfo.get()->input.initForGlobal(cx)) { return nullptr; } - if (!compiler.compileScript(compilationInfo, &globalsc)) { + if (!CompileGlobalScriptToStencil(cx, *compilationInfo, srcBuf, scopeKind)) { return nullptr; } + return std::move(compilationInfo.get()); +} + +UniquePtr frontend::CompileGlobalScriptToStencil( + JSContext* cx, const ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + return CompileGlobalScriptToStencilImpl(cx, options, srcBuf, scopeKind); +} + +UniquePtr frontend::CompileGlobalScriptToStencil( + JSContext* cx, const ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + return CompileGlobalScriptToStencilImpl(cx, options, srcBuf, scopeKind); +} + +bool frontend::InstantiateStencils(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + { + AutoGeckoProfilerEntry pseudoFrame(cx, "stencil instantiate", + JS::ProfilingCategoryPair::JS_Parsing); + + if (!compilationInfo.instantiateStencils(cx, gcOutput)) { + return false; + } + } + + // Enqueue an off-thread source compression task after finishing parsing. + if (!cx->isHelperThreadContext()) { + if (!compilationInfo.input.source()->tryCompressOffThread(cx)) { + return false; + } + } + tellDebuggerAboutCompiledScript( - compilationInfo.cx, compilationInfo.options.hideScriptFromDebugger, - compilationInfo.script); + cx, compilationInfo.input.options.hideScriptFromDebugger, + gcOutput.script); - assertException.reset(); - return compilationInfo.script; + return true; } -JSScript* frontend::CompileGlobalScript(CompilationInfo& compilationInfo, - GlobalSharedContext& globalsc, - JS::SourceText& srcBuf) { - return CreateGlobalScript(compilationInfo, globalsc, srcBuf); +template +static JSScript* CompileGlobalScriptImpl( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + Rooted compilationInfo(cx, CompilationInfo(cx, options)); + if (options.selfHostingMode) { + if (!compilationInfo.get().input.initForSelfHostingGlobal(cx)) { + return nullptr; + } + } else { + if (!compilationInfo.get().input.initForGlobal(cx)) { + return nullptr; + } + } + + if (!CompileGlobalScriptToStencil(cx, compilationInfo.get(), srcBuf, + scopeKind)) { + return nullptr; + } + + frontend::CompilationGCOutput gcOutput(cx); + if (!InstantiateStencils(cx, compilationInfo.get(), gcOutput)) { + return nullptr; + } + + return gcOutput.script; +} + +JSScript* frontend::CompileGlobalScript( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + return CompileGlobalScriptImpl(cx, options, srcBuf, scopeKind); } -JSScript* frontend::CompileGlobalScript(CompilationInfo& compilationInfo, - GlobalSharedContext& globalsc, - JS::SourceText& srcBuf) { - return CreateGlobalScript(compilationInfo, globalsc, srcBuf); +JSScript* frontend::CompileGlobalScript( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, ScopeKind scopeKind) { + return CompileGlobalScriptImpl(cx, options, srcBuf, scopeKind); } template -static JSScript* CreateEvalScript(CompilationInfo& compilationInfo, - EvalSharedContext& evalsc, - SourceText& srcBuf) { - AutoAssertReportedException assertException(compilationInfo.cx); - LifoAllocScope allocScope(&compilationInfo.cx->tempLifoAlloc()); - - frontend::ScriptCompiler compiler(srcBuf); - if (!compiler.createSourceAndParser(allocScope, compilationInfo)) { +static JSScript* CompileEvalScriptImpl( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + SourceText& srcBuf, JS::Handle enclosingScope, + JS::Handle enclosingEnv) { + AutoAssertReportedException assertException(cx); + + Rooted compilationInfo(cx, CompilationInfo(cx, options)); + if (!compilationInfo.get().input.initForEval(cx, enclosingScope)) { return nullptr; } - if (!compiler.compileScript(compilationInfo, &evalsc)) { + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + + frontend::ScriptCompiler compiler(cx, allocScope, + compilationInfo.get().input.options, + srcBuf, enclosingScope, enclosingEnv); + if (!compiler.createSourceAndParser(cx, compilationInfo.get())) { return nullptr; } - tellDebuggerAboutCompiledScript( - compilationInfo.cx, compilationInfo.options.hideScriptFromDebugger, - compilationInfo.script); + uint32_t len = srcBuf.length(); + SourceExtent extent = SourceExtent::makeGlobalExtent( + len, compilationInfo.get().input.options.lineno, + compilationInfo.get().input.options.column); + frontend::EvalSharedContext evalsc(cx, compilationInfo.get(), + compiler.compilationState(), extent); + if (!compiler.compileScriptToStencil(cx, compilationInfo.get(), &evalsc)) { + return nullptr; + } + + frontend::CompilationGCOutput gcOutput(cx); + if (!InstantiateStencils(cx, compilationInfo.get(), gcOutput)) { + return nullptr; + } assertException.reset(); - return compilationInfo.script; + return gcOutput.script; } -JSScript* frontend::CompileEvalScript(CompilationInfo& compilationInfo, - EvalSharedContext& evalsc, - JS::SourceText& srcBuf) { - return CreateEvalScript(compilationInfo, evalsc, srcBuf); +JSScript* frontend::CompileEvalScript(JSContext* cx, + const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, + JS::Handle enclosingScope, + JS::Handle enclosingEnv) { + return CompileEvalScriptImpl(cx, options, srcBuf, enclosingScope, + enclosingEnv); } template @@ -240,14 +439,21 @@ class MOZ_STACK_CLASS frontend::ModuleCompiler final using Base = SourceAwareCompiler; using Base::assertSourceParserAndScriptCreated; + using Base::compilationState_; using Base::createSourceAndParser; using Base::emplaceEmitter; using Base::parser; public: - explicit ModuleCompiler(SourceText& srcBuf) : Base(srcBuf) {} - - ModuleObject* compile(CompilationInfo& compilationInfo); + explicit ModuleCompiler(JSContext* cx, LifoAllocScope& allocScope, + const JS::ReadOnlyCompileOptions& options, + SourceText& sourceBuffer, + js::Scope* enclosingScope = nullptr, + JSObject* enclosingEnv = nullptr) + : Base(cx, allocScope, options, sourceBuffer, enclosingScope, + enclosingEnv) {} + + bool compile(JSContext* cx, CompilationInfo& compilationInfo); }; template @@ -257,6 +463,7 @@ class MOZ_STACK_CLASS frontend::StandaloneFunctionCompiler final using Base::assertSourceAndParserCreated; using Base::canHandleParseFailure; + using Base::compilationState_; using Base::emplaceEmitter; using Base::handleParseFailure; using Base::parser; @@ -265,17 +472,23 @@ class MOZ_STACK_CLASS frontend::StandaloneFunctionCompiler final using typename Base::TokenStreamPosition; public: - explicit StandaloneFunctionCompiler(SourceText& srcBuf) - : Base(srcBuf) {} + explicit StandaloneFunctionCompiler(JSContext* cx, LifoAllocScope& allocScope, + const JS::ReadOnlyCompileOptions& options, + SourceText& sourceBuffer, + js::Scope* enclosingScope = nullptr, + JSObject* enclosingEnv = nullptr) + : Base(cx, allocScope, options, sourceBuffer, enclosingScope, + enclosingEnv) {} using Base::createSourceAndParser; - FunctionNode* parse(CompilationInfo& compilationInfo, - HandleScope enclosingScope, FunctionSyntaxKind syntaxKind, + FunctionNode* parse(JSContext* cx, CompilationInfo& compilationInfo, + FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, const Maybe& parameterListEnd); - JSFunction* compile(CompilationInfo& info, FunctionNode* parsedFunction); + bool compile(JSContext* cx, CompilationInfo& compilationInfo, + FunctionNode* parsedFunction, CompilationGCOutput& gcOutput); }; AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, @@ -317,7 +530,7 @@ AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, } frontendEvent_.emplace(TraceLogger_Frontend, errorReporter.getFilename(), - funbox->extent.lineno, funbox->extent.column); + funbox->extent().lineno, funbox->extent().column); frontendLog_.emplace(logger_, *frontendEvent_); typeLog_.emplace(logger_, id); } @@ -349,49 +562,50 @@ AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, #endif static bool CanLazilyParse(const CompilationInfo& compilationInfo) { - return !compilationInfo.options.discardSource && - !compilationInfo.options.sourceIsLazy && - !compilationInfo.options.forceFullParse(); + return !compilationInfo.input.options.discardSource && + !compilationInfo.input.options.sourceIsLazy && + !compilationInfo.input.options.forceFullParse(); } template bool frontend::SourceAwareCompiler::createSourceAndParser( - LifoAllocScope& allocScope, CompilationInfo& compilationInfo) { - if (!compilationInfo.assignSource(sourceBuffer_)) { + JSContext* cx, CompilationInfo& compilationInfo) { + if (!compilationInfo.input.assignSource(cx, sourceBuffer_)) { return false; } if (CanLazilyParse(compilationInfo)) { - syntaxParser.emplace(compilationInfo.cx, compilationInfo.options, + syntaxParser.emplace(cx, compilationInfo.input.options, sourceBuffer_.units(), sourceBuffer_.length(), - /* foldConstants = */ false, compilationInfo, nullptr, - nullptr); + /* foldConstants = */ false, compilationInfo, + compilationState_, nullptr, nullptr); if (!syntaxParser->checkOptions()) { return false; } } - parser.emplace(compilationInfo.cx, compilationInfo.options, - sourceBuffer_.units(), sourceBuffer_.length(), - /* foldConstants = */ true, compilationInfo, + parser.emplace(cx, compilationInfo.input.options, sourceBuffer_.units(), + sourceBuffer_.length(), + /* foldConstants = */ true, compilationInfo, compilationState_, syntaxParser.ptrOr(nullptr), nullptr); - parser->ss = compilationInfo.sourceObject->source(); + parser->ss = compilationInfo.input.source(); return parser->checkOptions(); } static bool EmplaceEmitter(CompilationInfo& compilationInfo, + CompilationState& compilationState, Maybe& emitter, const EitherParser& parser, SharedContext* sc) { BytecodeEmitter::EmitterMode emitterMode = sc->selfHosted() ? BytecodeEmitter::SelfHosting : BytecodeEmitter::Normal; emitter.emplace(/* parent = */ nullptr, parser, sc, compilationInfo, - emitterMode); + compilationState, emitterMode); return emitter->init(); } template bool frontend::SourceAwareCompiler::canHandleParseFailure( - CompilationInfo& compilationInfo, const Directives& newDirectives) { + const Directives& newDirectives) { // Try to reparse if no parse errors were thrown and the directives changed. // // NOTE: @@ -401,7 +615,7 @@ bool frontend::SourceAwareCompiler::canHandleParseFailure( // are present. We reparse in this case to display the error at the correct // source location. See |Parser::hasValidSimpleStrictParameterNames()|. return !parser->anyChars.hadError() && - compilationInfo.directives != newDirectives; + compilationState_.directives != newDirectives; } template @@ -409,27 +623,32 @@ void frontend::SourceAwareCompiler::handleParseFailure( CompilationInfo& compilationInfo, const Directives& newDirectives, TokenStreamPosition& startPosition, CompilationInfo::RewindToken& startObj) { - MOZ_ASSERT(canHandleParseFailure(compilationInfo, newDirectives)); + MOZ_ASSERT(canHandleParseFailure(newDirectives)); // Rewind to starting position to retry. parser->tokenStream.rewind(startPosition); compilationInfo.rewind(startObj); // Assignment must be monotonic to prevent reparsing iloops - MOZ_ASSERT_IF(compilationInfo.directives.strict(), newDirectives.strict()); - MOZ_ASSERT_IF(compilationInfo.directives.asmJS(), newDirectives.asmJS()); - compilationInfo.directives = newDirectives; + MOZ_ASSERT_IF(compilationState_.directives.strict(), newDirectives.strict()); + MOZ_ASSERT_IF(compilationState_.directives.asmJS(), newDirectives.asmJS()); + compilationState_.directives = newDirectives; } template -JSScript* frontend::ScriptCompiler::compileScript( - CompilationInfo& compilationInfo, SharedContext* sc) { - assertSourceParserAndScriptCreated(compilationInfo); +bool frontend::ScriptCompiler::compileScriptToStencil( + JSContext* cx, CompilationInfo& compilationInfo, SharedContext* sc) { + assertSourceParserAndScriptCreated(compilationInfo.input); - TokenStreamPosition startPosition(compilationInfo.keepAtoms, - parser->tokenStream); + TokenStreamPosition startPosition(parser->tokenStream); - JSContext* cx = compilationInfo.cx; + // Emplace the topLevel stencil + MOZ_ASSERT(compilationInfo.stencil.scriptData.length() == + CompilationInfo::TopLevelIndex); + if (!compilationInfo.stencil.scriptData.emplaceBack()) { + ReportOutOfMemory(cx); + return false; + } ParseNode* pn; { @@ -447,9 +666,8 @@ JSScript* frontend::ScriptCompiler::compileScript( // encountered: // - "use strict" doesn't require any special error reporting for scripts. // - "use asm" directives don't have an effect in global/eval contexts. - MOZ_ASSERT( - !canHandleParseFailure(compilationInfo, compilationInfo.directives)); - return nullptr; + MOZ_ASSERT(!canHandleParseFailure(compilationState_.directives)); + return false; } { @@ -459,94 +677,62 @@ JSScript* frontend::ScriptCompiler::compileScript( Maybe emitter; if (!emplaceEmitter(compilationInfo, emitter, sc)) { - return nullptr; + return false; } if (!emitter->emitScript(pn)) { - return nullptr; - } - - if (!compilationInfo.instantiateStencils()) { - return nullptr; + return false; } - - MOZ_ASSERT(compilationInfo.script); - } - - // We have just finished parsing the source. Inform the source so that we - // can compute statistics (e.g. how much time our functions remain lazy). - compilationInfo.sourceObject->source()->recordParseEnded(); - - // Enqueue an off-thread source compression task after finishing parsing. - if (!compilationInfo.sourceObject->source()->tryCompressOffThread(cx)) { - return nullptr; } MOZ_ASSERT_IF(!cx->isHelperThreadContext(), !cx->isExceptionPending()); - return compilationInfo.script; + return true; } template -ModuleObject* frontend::ModuleCompiler::compile( - CompilationInfo& compilationInfo) { - if (!createSourceAndParser(compilationInfo.allocScope, compilationInfo)) { - return nullptr; +bool frontend::ModuleCompiler::compile(JSContext* cx, + CompilationInfo& compilationInfo) { + if (!createSourceAndParser(cx, compilationInfo)) { + return false; } - JSContext* cx = compilationInfo.cx; - Rooted module(cx, ModuleObject::create(cx)); - if (!module) { - return nullptr; + // Emplace the topLevel stencil + MOZ_ASSERT(compilationInfo.stencil.scriptData.length() == + CompilationInfo::TopLevelIndex); + if (!compilationInfo.stencil.scriptData.emplaceBack()) { + ReportOutOfMemory(cx); + return false; } ModuleBuilder builder(cx, parser.ptr()); + StencilModuleMetadata& moduleMetadata = + compilationInfo.stencil.moduleMetadata; - RootedScope enclosingScope(cx, &cx->global()->emptyGlobalScope()); uint32_t len = this->sourceBuffer_.length(); SourceExtent extent = - SourceExtent::makeGlobalExtent(len, compilationInfo.options); - ModuleSharedContext modulesc(cx, module, compilationInfo, enclosingScope, - builder, extent); + SourceExtent::makeGlobalExtent(len, compilationInfo.input.options.lineno, + compilationInfo.input.options.column); + ModuleSharedContext modulesc(cx, compilationInfo, builder, extent); ParseNode* pn = parser->moduleBody(&modulesc); if (!pn) { - return nullptr; + return false; } Maybe emitter; if (!emplaceEmitter(compilationInfo, emitter, &modulesc)) { - return nullptr; + return false; } if (!emitter->emitScript(pn->as().body())) { - return nullptr; - } - - if (!compilationInfo.instantiateStencils()) { - return nullptr; - } - - MOZ_ASSERT(compilationInfo.script); - - if (!builder.initModule(module)) { - return nullptr; - } - - module->initScriptSlots(compilationInfo.script); - module->initStatusSlot(); - - if (!ModuleObject::createEnvironment(cx, module)) { - return nullptr; + return false; } - // Enqueue an off-thread source compression task after finishing parsing. - if (!compilationInfo.sourceObject->source()->tryCompressOffThread(cx)) { - return nullptr; - } + builder.finishFunctionDecls(moduleMetadata); MOZ_ASSERT_IF(!cx->isHelperThreadContext(), !cx->isExceptionPending()); - return module; + return true; } // Parse a standalone JS function, which might appear as the value of an @@ -554,13 +740,12 @@ ModuleObject* frontend::ModuleCompiler::compile( // constructor. template FunctionNode* frontend::StandaloneFunctionCompiler::parse( - CompilationInfo& compilationInfo, HandleScope enclosingScope, + JSContext* cx, CompilationInfo& compilationInfo, FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, const Maybe& parameterListEnd) { - assertSourceAndParserCreated(compilationInfo); + assertSourceAndParserCreated(compilationInfo.input); - TokenStreamPosition startPosition(compilationInfo.keepAtoms, - parser->tokenStream); + TokenStreamPosition startPosition(parser->tokenStream); CompilationInfo::RewindToken startObj = compilationInfo.getRewindToken(); // Speculatively parse using the default directives implied by the context. @@ -570,16 +755,16 @@ FunctionNode* frontend::StandaloneFunctionCompiler::parse( FunctionNode* fn; for (;;) { - Directives newDirectives = compilationInfo.directives; - fn = parser->standaloneFunction(enclosingScope, parameterListEnd, - syntaxKind, generatorKind, asyncKind, - compilationInfo.directives, &newDirectives); + Directives newDirectives = compilationState_.directives; + fn = parser->standaloneFunction(parameterListEnd, syntaxKind, generatorKind, + asyncKind, compilationState_.directives, + &newDirectives); if (fn) { break; } // Maybe we encountered a new directive. See if we can try again. - if (!canHandleParseFailure(compilationInfo, newDirectives)) { + if (!canHandleParseFailure(newDirectives)) { return nullptr; } @@ -591,311 +776,203 @@ FunctionNode* frontend::StandaloneFunctionCompiler::parse( // Compile a standalone JS function. template -JSFunction* frontend::StandaloneFunctionCompiler::compile( - CompilationInfo& compilationInfo, FunctionNode* parsedFunction) { +bool frontend::StandaloneFunctionCompiler::compile( + JSContext* cx, CompilationInfo& compilationInfo, + FunctionNode* parsedFunction, CompilationGCOutput& gcOutput) { FunctionBox* funbox = parsedFunction->funbox(); if (funbox->isInterpreted()) { - MOZ_ASSERT(funbox->function() == nullptr); + Maybe emitter; + if (!emplaceEmitter(compilationInfo, emitter, funbox)) { + return false; + } + + if (!emitter->emitFunctionScript(parsedFunction, TopLevelFunction::Yes)) { + return false; + } // The parser extent has stripped off the leading `function...` but // we want the SourceExtent used in the final standalone script to // start from the beginning of the buffer, and use the provided // line and column. - compilationInfo.topLevelExtent = + compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex].extent = SourceExtent{/* sourceStart = */ 0, sourceBuffer_.length(), - funbox->extent.toStringStart, - funbox->extent.toStringEnd, - compilationInfo.options.lineno, - compilationInfo.options.column}; - - Maybe emitter; - if (!emplaceEmitter(compilationInfo, emitter, funbox)) { - return nullptr; - } - - if (!emitter->emitFunctionScript(parsedFunction, TopLevelFunction::Yes)) { - return nullptr; - } + funbox->extent().toStringStart, + funbox->extent().toStringEnd, + compilationInfo.input.options.lineno, + compilationInfo.input.options.column}; } else { // The asm.js module was created by parser. Instantiation below will // allocate the JSFunction that wraps it. MOZ_ASSERT(funbox->isAsmJSModule()); - MOZ_ASSERT(compilationInfo.asmJS.has(FunctionIndex(funbox->index()))); - - compilationInfo.topLevelAsmJS = true; + MOZ_ASSERT(compilationInfo.stencil.asmJS.has(funbox->index())); + MOZ_ASSERT( + compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex] + .functionFlags.isAsmJSNative()); } - if (!compilationInfo.instantiateStencils()) { - return nullptr; + if (!compilationInfo.instantiateStencils(cx, gcOutput)) { + return false; } - MOZ_ASSERT(funbox->function()->hasBytecode() || - IsAsmJSModule(funbox->function())); +#ifdef DEBUG + JSFunction* fun = gcOutput.functions[CompilationInfo::TopLevelIndex]; + MOZ_ASSERT(fun->hasBytecode() || IsAsmJSModule(fun)); +#endif // Enqueue an off-thread source compression task after finishing parsing. - if (!compilationInfo.sourceObject->source()->tryCompressOffThread( - compilationInfo.cx)) { - return nullptr; - } - - return funbox->function(); -} - -ScriptSourceObject* frontend::CreateScriptSourceObject( - JSContext* cx, const ReadOnlyCompileOptions& options) { - ScriptSource* ss = cx->new_(); - if (!ss) { - return nullptr; - } - ScriptSourceHolder ssHolder(ss); - - if (!ss->initFromOptions(cx, options)) { - return nullptr; - } - - RootedScriptSourceObject sso(cx, ScriptSourceObject::create(cx, ss)); - if (!sso) { - return nullptr; - } - - // Off-thread compilations do all their GC heap allocation, including the - // SSO, in a temporary compartment. Hence, for the SSO to refer to the - // gc-heap-allocated values in |options|, it would need cross-compartment - // wrappers from the temporary compartment to the real compartment --- which - // would then be inappropriate once we merged the temporary and real - // compartments. - // - // Instead, we put off populating those SSO slots in off-thread compilations - // until after we've merged compartments. if (!cx->isHelperThreadContext()) { - if (!ScriptSourceObject::initFromOptions(cx, sso, options)) { - return nullptr; + if (!compilationInfo.input.source()->tryCompressOffThread(cx)) { + return false; } } - return sso; + return true; } -#if defined(JS_BUILD_BINAST) +template +static bool ParseModuleToStencilImpl(JSContext* cx, + CompilationInfo& compilationInfo, + SourceText& srcBuf) { + MOZ_ASSERT(srcBuf.get()); -template -static JSScript* CompileGlobalBinASTScriptImpl( - JSContext* cx, const ReadOnlyCompileOptions& options, const uint8_t* src, - size_t len, JS::BinASTFormat format, ScriptSourceObject** sourceObjectOut) { AutoAssertReportedException assertException(cx); LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options); - if (!compilationInfo.init(cx)) { - return nullptr; - } - - if (!compilationInfo.sourceObject->source()->setBinASTSourceCopy(cx, src, - len)) { - return nullptr; - } - - SourceExtent extent = SourceExtent::makeGlobalExtent(len); - extent.lineno = 0; - GlobalSharedContext globalsc(cx, ScopeKind::Global, compilationInfo, - compilationInfo.directives, extent); - - frontend::BinASTParser parser(cx, compilationInfo, options); - - // Metadata stores internal pointers, so we must use the same buffer every - // time, including for lazy parses - ScriptSource* ss = compilationInfo.sourceObject->source(); - BinASTSourceMetadata* metadata = nullptr; - auto parsed = - parser.parse(&globalsc, ss->binASTSource(), ss->length(), &metadata); - - if (parsed.isErr()) { - return nullptr; - } - - compilationInfo.sourceObject->source()->setBinASTSourceMetadata(metadata); - - BytecodeEmitter bce(nullptr, &parser, &globalsc, compilationInfo); - - if (!bce.init()) { - return nullptr; - } - - ParseNode* pn = parsed.unwrap(); - if (!bce.emitScript(pn)) { - return nullptr; - } - - if (!compilationInfo.instantiateStencils()) { - return nullptr; - } - - if (sourceObjectOut) { - *sourceObjectOut = compilationInfo.sourceObject; + ModuleCompiler compiler(cx, allocScope, compilationInfo.input.options, + srcBuf); + if (!compiler.compile(cx, compilationInfo)) { + return false; } - tellDebuggerAboutCompiledScript(cx, options.hideScriptFromDebugger, - compilationInfo.script); - assertException.reset(); - return compilationInfo.script; + return true; } -JSScript* frontend::CompileGlobalBinASTScript( - JSContext* cx, const ReadOnlyCompileOptions& options, const uint8_t* src, - size_t len, JS::BinASTFormat format, ScriptSourceObject** sourceObjectOut) { - if (format == JS::BinASTFormat::Multipart) { - return CompileGlobalBinASTScriptImpl( - cx, options, src, len, format, sourceObjectOut); - } - - MOZ_ASSERT(format == JS::BinASTFormat::Context); - return CompileGlobalBinASTScriptImpl( - cx, options, src, len, format, sourceObjectOut); +bool frontend::ParseModuleToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + SourceText& srcBuf) { + return ParseModuleToStencilImpl(cx, compilationInfo, srcBuf); } -#endif // JS_BUILD_BINAST +bool frontend::ParseModuleToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + SourceText& srcBuf) { + return ParseModuleToStencilImpl(cx, compilationInfo, srcBuf); +} template -static ModuleObject* InternalParseModule( - JSContext* cx, const ReadOnlyCompileOptions& optionsInput, - SourceText& srcBuf, ScriptSourceObject** sourceObjectOut) { - MOZ_ASSERT(srcBuf.get()); - MOZ_ASSERT_IF(sourceObjectOut, *sourceObjectOut == nullptr); - - AutoAssertReportedException assertException(cx); - - CompileOptions options(cx, optionsInput); - options.setForceStrictMode(); // ES6 10.2.1 Module code is always strict mode - // code. - options.setIsRunOnce(true); - options.allowHTMLComments = false; - - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options); - if (!compilationInfo.init(cx)) { +static UniquePtr ParseModuleToStencilImpl( + JSContext* cx, const ReadOnlyCompileOptions& options, + SourceText& srcBuf) { + Rooted> compilationInfo( + cx, js_new(cx, options)); + if (!compilationInfo) { + ReportOutOfMemory(cx); return nullptr; } - if (sourceObjectOut) { - *sourceObjectOut = compilationInfo.sourceObject; + if (!compilationInfo.get()->input.initForModule(cx)) { + return nullptr; } - ModuleCompiler compiler(srcBuf); - Rooted module(cx, compiler.compile(compilationInfo)); - if (!module) { + if (!ParseModuleToStencilImpl(cx, *compilationInfo, srcBuf)) { return nullptr; } - tellDebuggerAboutCompiledScript(cx, options.hideScriptFromDebugger, - compilationInfo.script); - - assertException.reset(); - return module; + return std::move(compilationInfo.get()); } -ModuleObject* frontend::ParseModule(JSContext* cx, - const ReadOnlyCompileOptions& optionsInput, - SourceText& srcBuf, - ScriptSourceObject** sourceObjectOut) { - return InternalParseModule(cx, optionsInput, srcBuf, sourceObjectOut); +UniquePtr frontend::ParseModuleToStencil( + JSContext* cx, const ReadOnlyCompileOptions& options, + SourceText& srcBuf) { + return ParseModuleToStencilImpl(cx, options, srcBuf); } -ModuleObject* frontend::ParseModule(JSContext* cx, - const ReadOnlyCompileOptions& optionsInput, - SourceText& srcBuf, - ScriptSourceObject** sourceObjectOut) { - return InternalParseModule(cx, optionsInput, srcBuf, sourceObjectOut); +UniquePtr frontend::ParseModuleToStencil( + JSContext* cx, const ReadOnlyCompileOptions& options, + SourceText& srcBuf) { + return ParseModuleToStencilImpl(cx, options, srcBuf); } template -static ModuleObject* CreateModule(JSContext* cx, - const JS::ReadOnlyCompileOptions& options, - SourceText& srcBuf) { +static ModuleObject* CompileModuleImpl( + JSContext* cx, const JS::ReadOnlyCompileOptions& optionsInput, + SourceText& srcBuf) { AutoAssertReportedException assertException(cx); if (!GlobalObject::ensureModulePrototypesCreated(cx, cx->global())) { return nullptr; } - RootedModuleObject module(cx, ParseModule(cx, options, srcBuf, nullptr)); - if (!module) { + CompileOptions options(cx, optionsInput); + options.setModule(); + + Rooted compilationInfo(cx, CompilationInfo(cx, options)); + if (!compilationInfo.get().input.initForModule(cx)) { + return nullptr; + } + + if (!ParseModuleToStencil(cx, compilationInfo.get(), srcBuf)) { return nullptr; } - // This happens in GlobalHelperThreadState::finishModuleParseTask() when a - // module is compiled off thread. - if (!ModuleObject::Freeze(cx, module)) { + CompilationGCOutput gcOutput(cx); + if (!InstantiateStencils(cx, compilationInfo.get(), gcOutput)) { return nullptr; } assertException.reset(); - return module; + return gcOutput.module; } ModuleObject* frontend::CompileModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options, SourceText& srcBuf) { - return CreateModule(cx, options, srcBuf); + return CompileModuleImpl(cx, options, srcBuf); } ModuleObject* frontend::CompileModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options, SourceText& srcBuf) { - return CreateModule(cx, options, srcBuf); + return CompileModuleImpl(cx, options, srcBuf); +} + +void frontend::FillCompileOptionsForLazyFunction(JS::CompileOptions& options, + JS::Handle lazy) { + options.setMutedErrors(lazy->mutedErrors()) + .setFileAndLine(lazy->filename(), lazy->lineno()) + .setColumn(lazy->column()) + .setScriptSourceOffset(lazy->sourceStart()) + .setNoScriptRval(false) + .setSelfHostingMode(false); } template -static bool CompileLazyFunctionImpl(JSContext* cx, Handle lazy, - const Unit* units, size_t length) { +static bool CompileLazyFunctionToStencilImpl(JSContext* cx, + CompilationInfo& compilationInfo, + Handle lazy, + const Unit* units, size_t length) { MOZ_ASSERT(cx->compartment() == lazy->compartment()); // We can only compile functions whose parents have previously been // compiled, because compilation requires full information about the // function's immediately enclosing scope. MOZ_ASSERT(lazy->isReadyForDelazification()); - MOZ_ASSERT(!lazy->isBinAST()); AutoAssertReportedException assertException(cx); - Rooted fun(cx, lazy->function()); - - JS::CompileOptions options(cx); - options.setMutedErrors(lazy->mutedErrors()) - .setFileAndLine(lazy->filename(), lazy->lineno()) - .setColumn(lazy->column()) - .setScriptSourceOffset(lazy->sourceStart()) - .setNoScriptRval(false) - .setSelfHostingMode(false); - // Update statistics to find out if we are delazifying just after having - // lazified. Note that we are interested in the delta between end of - // syntax parsing and start of full parsing, so we do this now rather than - // after parsing below. - if (!lazy->scriptSource()->parseEnded().IsNull()) { - const mozilla::TimeDuration delta = - ReallyNow() - lazy->scriptSource()->parseEnded(); - - // Differentiate between web-facing and privileged code, to aid - // with optimization. Due to the number of calls to this function, - // we use `cx->runningWithTrustedPrincipals`, which is fast but - // will classify addons alongside with web-facing code. - const int HISTOGRAM = - cx->runningWithTrustedPrincipals() - ? JS_TELEMETRY_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS - : JS_TELEMETRY_WEB_PARSER_COMPILE_LAZY_AFTER_MS; - cx->runtime()->addTelemetry(HISTOGRAM, delta.ToMilliseconds()); - } + Rooted fun(cx, lazy->function()); LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options, - fun->enclosingScope()); - compilationInfo.initFromLazy(lazy); + frontend::CompilationState compilationState( + cx, allocScope, compilationInfo.input.options, fun->enclosingScope()); - Parser parser(cx, options, units, length, - /* foldConstants = */ true, - compilationInfo, nullptr, lazy); + Parser parser( + cx, compilationInfo.input.options, units, length, + /* foldConstants = */ true, compilationInfo, compilationState, nullptr, + lazy); if (!parser.checkOptions()) { return false; } @@ -910,11 +987,9 @@ static bool CompileLazyFunctionImpl(JSContext* cx, Handle lazy, return false; } - mozilla::DebugOnly lazyFlags = - static_cast(lazy->immutableFlags()); - BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->funbox(), - compilationInfo, BytecodeEmitter::LazyFunction); + compilationInfo, compilationState, + BytecodeEmitter::LazyFunction); if (!bce.init(pn->pn_pos)) { return false; } @@ -923,111 +998,47 @@ static bool CompileLazyFunctionImpl(JSContext* cx, Handle lazy, return false; } - if (!compilationInfo.instantiateStencils()) { - return false; - } - - MOZ_ASSERT(lazyFlags == compilationInfo.script->immutableFlags()); - MOZ_ASSERT(compilationInfo.script->outermostScope()->hasOnChain( - ScopeKind::NonSyntactic) == - compilationInfo.script->immutableFlags().hasFlag( - JSScript::ImmutableFlags::HasNonSyntacticScope)); - assertException.reset(); return true; } -bool frontend::CompileLazyFunction(JSContext* cx, Handle lazy, - const char16_t* units, size_t length) { - return CompileLazyFunctionImpl(cx, lazy, units, length); +MOZ_MUST_USE bool frontend::CompileLazyFunctionToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::Handle lazy, const char16_t* units, size_t length) { + return CompileLazyFunctionToStencilImpl(cx, compilationInfo, lazy, units, + length); } -bool frontend::CompileLazyFunction(JSContext* cx, Handle lazy, - const Utf8Unit* units, size_t length) { - return CompileLazyFunctionImpl(cx, lazy, units, length); +MOZ_MUST_USE bool frontend::CompileLazyFunctionToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::Handle lazy, const mozilla::Utf8Unit* units, + size_t length) { + return CompileLazyFunctionToStencilImpl(cx, compilationInfo, lazy, units, + length); } -#ifdef JS_BUILD_BINAST - -template -static bool CompileLazyBinASTFunctionImpl(JSContext* cx, - Handle lazy, - const uint8_t* buf, size_t length) { - MOZ_ASSERT(cx->compartment() == lazy->compartment()); - - // We can only compile functions whose parents have previously been - // compiled, because compilation requires full information about the - // function's immediately enclosing scope. - MOZ_ASSERT(lazy->isReadyForDelazification()); - MOZ_ASSERT(lazy->isBinAST()); - +bool frontend::InstantiateStencilsForDelazify( + JSContext* cx, CompilationInfo& compilationInfo) { AutoAssertReportedException assertException(cx); - Rooted fun(cx, lazy->function()); - - mozilla::DebugOnly lazyIsLikelyConstructorWrapper = - lazy->isLikelyConstructorWrapper(); - - CompileOptions options(cx); - options.setMutedErrors(lazy->mutedErrors()) - .setFileAndLine(lazy->filename(), lazy->lineno()) - .setColumn(lazy->column()) - .setScriptSourceOffset(lazy->sourceStart()) - .setNoScriptRval(false) - .setSelfHostingMode(false); - - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options); - compilationInfo.initFromLazy(lazy); - - frontend::BinASTParser parser(cx, compilationInfo, options, lazy); - - auto parsed = - parser.parseLazyFunction(lazy->scriptSource(), lazy->sourceStart()); - - if (parsed.isErr()) { - return false; - } - - FunctionNode* pn = parsed.unwrap(); - - BytecodeEmitter bce(nullptr, &parser, pn->funbox(), compilationInfo, - BytecodeEmitter::LazyFunction); - - if (!bce.init(pn->pn_pos)) { - return false; - } - if (!bce.emitFunctionScript(pn, TopLevelFunction::Yes)) { - return false; - } + mozilla::DebugOnly lazyFlags = + static_cast(compilationInfo.input.lazy->immutableFlags()); - if (!compilationInfo.instantiateStencils()) { + CompilationGCOutput gcOutput(cx); + if (!compilationInfo.instantiateStencils(cx, gcOutput)) { return false; } - // This value *must* not change after the lazy function is first created. - MOZ_ASSERT(lazyIsLikelyConstructorWrapper == - compilationInfo.script->isLikelyConstructorWrapper()); + MOZ_ASSERT(lazyFlags == gcOutput.script->immutableFlags()); + MOZ_ASSERT( + gcOutput.script->outermostScope()->hasOnChain(ScopeKind::NonSyntactic) == + gcOutput.script->immutableFlags().hasFlag( + JSScript::ImmutableFlags::HasNonSyntacticScope)); assertException.reset(); return true; } -bool frontend::CompileLazyBinASTFunction(JSContext* cx, - Handle lazy, - const uint8_t* buf, size_t length) { - if (lazy->scriptSource()->binASTSourceMetadata()->isMultipart()) { - return CompileLazyBinASTFunctionImpl( - cx, lazy, buf, length); - } - - MOZ_ASSERT(lazy->scriptSource()->binASTSourceMetadata()->isContext()); - return CompileLazyBinASTFunctionImpl(cx, lazy, buf, - length); -} - -#endif // JS_BUILD_BINAST - static JSFunction* CompileStandaloneFunction( JSContext* cx, const JS::ReadOnlyCompileOptions& options, JS::SourceText& srcBuf, const Maybe& parameterListEnd, @@ -1035,48 +1046,50 @@ static JSFunction* CompileStandaloneFunction( FunctionAsyncKind asyncKind, HandleScope enclosingScope = nullptr) { AutoAssertReportedException assertException(cx); - LifoAllocScope allocScope(&cx->tempLifoAlloc()); - CompilationInfo compilationInfo(cx, allocScope, options, enclosingScope); - if (!compilationInfo.init(cx)) { - return nullptr; + RootedScope scope(cx, enclosingScope); + if (!scope) { + scope = &cx->global()->emptyGlobalScope(); } - StandaloneFunctionCompiler compiler(srcBuf); - if (!compiler.createSourceAndParser(allocScope, compilationInfo)) { + Rooted compilationInfo(cx, CompilationInfo(cx, options)); + if (!compilationInfo.get().input.initForStandaloneFunction(cx, scope)) { return nullptr; } - RootedScope scope(cx, enclosingScope); - if (!scope) { - scope = &cx->global()->emptyGlobalScope(); + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + StandaloneFunctionCompiler compiler( + cx, allocScope, compilationInfo.get().input.options, srcBuf, + enclosingScope); + if (!compiler.createSourceAndParser(cx, compilationInfo.get())) { + return nullptr; } FunctionNode* parsedFunction = - compiler.parse(compilationInfo, scope, syntaxKind, generatorKind, + compiler.parse(cx, compilationInfo.get(), syntaxKind, generatorKind, asyncKind, parameterListEnd); if (!parsedFunction) { return nullptr; } - RootedFunction fun(cx, compiler.compile(compilationInfo, parsedFunction)); - if (!fun) { + CompilationGCOutput gcOutput(cx); + if (!compiler.compile(cx, compilationInfo.get(), parsedFunction, gcOutput)) { return nullptr; } // Note: If AsmJS successfully compiles, the into.script will still be // nullptr. In this case we have compiled to a native function instead of an // interpreted script. - if (compilationInfo.script) { + if (gcOutput.script) { if (parameterListEnd) { - compilationInfo.sourceObject->source()->setParameterListEnd( + compilationInfo.get().input.source()->setParameterListEnd( *parameterListEnd); } tellDebuggerAboutCompiledScript(cx, options.hideScriptFromDebugger, - compilationInfo.script); + gcOutput.script); } assertException.reset(); - return fun; + return gcOutput.functions[CompilationInfo::TopLevelIndex]; } JSFunction* frontend::CompileStandaloneFunction( @@ -1116,7 +1129,21 @@ JSFunction* frontend::CompileStandaloneAsyncGenerator( FunctionAsyncKind::AsyncFunction); } -bool frontend::CompilationInfo::init(JSContext* cx) { - sourceObject = CreateScriptSourceObject(cx, options); - return !!sourceObject; +bool frontend::CompilationInput::initScriptSource(JSContext* cx) { + ScriptSource* ss = cx->new_(); + if (!ss) { + return false; + } + setSource(ss); + + return ss->initFromOptions(cx, options); +} + +void CompilationInput::trace(JSTracer* trc) { + atoms.trace(trc); + TraceNullableRoot(trc, &lazy, "compilation-input-lazy"); + source_.trace(trc); + TraceNullableRoot(trc, &enclosingScope, "compilation-input-enclosing-scope"); } + +void CompilationInfo::trace(JSTracer* trc) { input.trace(trc); } diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h index 09c00df1a4..0ae9906797 100644 --- a/js/src/frontend/BytecodeCompiler.h +++ b/js/src/frontend/BytecodeCompiler.h @@ -11,9 +11,9 @@ #include "NamespaceImports.h" #include "frontend/FunctionSyntaxKind.h" -#include "js/BinASTFormat.h" // JS::BinASTFormat -#include "js/CompileOptions.h" +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions #include "js/SourceText.h" +#include "js/UniquePtr.h" // js::UniquePtr #include "vm/Scope.h" #include "vm/TraceLogging.h" @@ -60,9 +60,9 @@ * * ParseContext.h: class ParseContext: Extremely complex class that serves a lot * of purposes, but it's a single class - essentially no derived classes - so - * it's a little easier to comprehend all at once. (SourceParseContext and - * BinASTParseContext do derive from ParseContext, but they do nothing except - * adjust the constructor's arguments). + * it's a little easier to comprehend all at once. (SourceParseContext does + * derive from ParseContext, but they does nothing except adjust the + * constructor's arguments). * Note it uses a thing called Nestable, which implements a stack of objects: * you can push (and pop) instances to a stack (linked list) as you parse * further into the parse tree. You may push to this stack via calling the @@ -103,22 +103,12 @@ class ScriptSourceObject; namespace frontend { +struct CompilationInfo; +struct CompilationGCOutput; class ErrorReporter; class FunctionBox; class ParseNode; - -#if defined(JS_BUILD_BINAST) - -JSScript* CompileGlobalBinASTScript( - JSContext* cx, const JS::ReadOnlyCompileOptions& options, - const uint8_t* src, size_t len, JS::BinASTFormat format, - ScriptSourceObject** sourceObjectOut = nullptr); - -MOZ_MUST_USE bool CompileLazyBinASTFunction(JSContext* cx, - Handle lazy, - const uint8_t* buf, size_t length); - -#endif // JS_BUILD_BINAST +class ParserAtom; // Compile a module of the given source using the given options. ModuleObject* CompileModule(JSContext* cx, @@ -130,14 +120,17 @@ ModuleObject* CompileModule(JSContext* cx, // Parse a module of the given source. This is an internal API; if you want to // compile a module as a user, use CompileModule above. -ModuleObject* ParseModule(JSContext* cx, - const JS::ReadOnlyCompileOptions& options, - JS::SourceText& srcBuf, - ScriptSourceObject** sourceObjectOut); -ModuleObject* ParseModule(JSContext* cx, - const JS::ReadOnlyCompileOptions& options, - JS::SourceText& srcBuf, - ScriptSourceObject** sourceObjectOut); +bool ParseModuleToStencil(JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf); +bool ParseModuleToStencil(JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf); + +UniquePtr ParseModuleToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf); +UniquePtr ParseModuleToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf); // // Compile a single function. The source in srcBuf must match the ECMA-262 @@ -176,9 +169,6 @@ MOZ_MUST_USE JSFunction* CompileStandaloneAsyncGenerator( const mozilla::Maybe& parameterListEnd, frontend::FunctionSyntaxKind syntaxKind); -ScriptSourceObject* CreateScriptSourceObject( - JSContext* cx, const JS::ReadOnlyCompileOptions& options); - /* * True if str consists of an IdentifierStart character, followed by one or * more IdentifierPart characters, i.e. it matches the IdentifierName production @@ -189,8 +179,10 @@ ScriptSourceObject* CreateScriptSourceObject( * Defined in TokenStream.cpp. */ bool IsIdentifier(JSLinearString* str); +bool IsIdentifier(const ParserAtom* atom); bool IsIdentifierNameOrPrivateName(JSLinearString* str); +bool IsIdentifierNameOrPrivateName(const ParserAtom* atom); /* * As above, but taking chars + length. @@ -202,6 +194,7 @@ bool IsIdentifierNameOrPrivateName(const Latin1Char* chars, size_t length); bool IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length); /* True if str is a keyword. Defined in TokenStream.cpp. */ +bool IsKeyword(const ParserAtom* atom); bool IsKeyword(JSLinearString* str); class MOZ_STACK_CLASS AutoFrontendTraceLog { diff --git a/js/src/frontend/BytecodeControlStructures.cpp b/js/src/frontend/BytecodeControlStructures.cpp index 8f901b2bb0..a3d6db86c2 100644 --- a/js/src/frontend/BytecodeControlStructures.cpp +++ b/js/src/frontend/BytecodeControlStructures.cpp @@ -27,10 +27,10 @@ bool BreakableControl::patchBreaks(BytecodeEmitter* bce) { return bce->emitJumpTargetAndPatch(breaks); } -LabelControl::LabelControl(BytecodeEmitter* bce, JSAtom* label, +LabelControl::LabelControl(BytecodeEmitter* bce, const ParserAtom* label, BytecodeOffset startOffset) : BreakableControl(bce, StatementKind::Label), - label_(bce->cx, label), + label_(label), startOffset_(startOffset) {} LoopControl::LoopControl(BytecodeEmitter* bce, StatementKind loopKind) diff --git a/js/src/frontend/BytecodeControlStructures.h b/js/src/frontend/BytecodeControlStructures.h index 0485c0936c..6141f85604 100644 --- a/js/src/frontend/BytecodeControlStructures.h +++ b/js/src/frontend/BytecodeControlStructures.h @@ -14,11 +14,10 @@ #include "ds/Nestable.h" // Nestable #include "frontend/BytecodeSection.h" // BytecodeOffset #include "frontend/JumpList.h" // JumpList, JumpTarget +#include "frontend/ParserAtom.h" // ParserAtom #include "frontend/SharedContext.h" // StatementKind, StatementKindIsLoop, StatementKindIsUnlabeledBreakTarget #include "frontend/TDZCheckCache.h" // TDZCheckCache -#include "gc/Rooting.h" // RootedAtom, HandleAtom #include "vm/StencilEnums.h" // TryNoteKind -#include "vm/StringType.h" // JSAtom namespace js { namespace frontend { @@ -69,15 +68,16 @@ inline bool NestableControl::is() const { } class LabelControl : public BreakableControl { - RootedAtom label_; + const ParserAtom* label_; // The code offset when this was pushed. Used for effectfulness checking. BytecodeOffset startOffset_; public: - LabelControl(BytecodeEmitter* bce, JSAtom* label, BytecodeOffset startOffset); + LabelControl(BytecodeEmitter* bce, const ParserAtom* label, + BytecodeOffset startOffset); - HandleAtom label() const { return label_; } + const ParserAtom* label() const { return label_; } BytecodeOffset startOffset() const { return startOffset_; } }; diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 259959e710..cca59f42e9 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -23,8 +23,8 @@ #include "jstypes.h" // JS_BIT -#include "ds/Nestable.h" // Nestable -#include "frontend/AbstractScopePtr.h" +#include "ds/Nestable.h" // Nestable +#include "frontend/AbstractScopePtr.h" // ScopeIndex #include "frontend/BytecodeControlStructures.h" // NestableControl, BreakableControl, LabelControl, LoopControl, TryFinallyControl #include "frontend/CallOrNewEmitter.h" // CallOrNewEmitter #include "frontend/CForEmitter.h" // CForEmitter @@ -41,11 +41,13 @@ #include "frontend/LabelEmitter.h" // LabelEmitter #include "frontend/LexicalScopeEmitter.h" // LexicalScopeEmitter #include "frontend/ModuleSharedContext.h" // ModuleSharedContext +#include "frontend/NameAnalysisTypes.h" // PrivateNameKind #include "frontend/NameFunctions.h" // NameFunctions #include "frontend/NameOpEmitter.h" // NameOpEmitter #include "frontend/ObjectEmitter.h" // PropertyEmitter, ObjectEmitter, ClassEmitter #include "frontend/ParseNode.h" // ParseNodeKind, ParseNode and subclasses #include "frontend/Parser.h" // Parser +#include "frontend/ParserAtom.h" // ParserAtomsTable #include "frontend/PropOpEmitter.h" // PropOpEmitter #include "frontend/SourceNotes.h" // SrcNote, SrcNoteType, SrcNoteWriter #include "frontend/SwitchEmitter.h" // SwitchEmitter @@ -53,6 +55,8 @@ #include "frontend/TryEmitter.h" // TryEmitter #include "frontend/WhileEmitter.h" // WhileEmitter #include "js/CompileOptions.h" // TransitiveCompileOptions, CompileOptions +#include "js/friend/StackLimits.h" // CheckRecursionLimit +#include "util/StringBuffer.h" // StringBuffer #include "vm/AsyncFunctionResolveKind.h" // AsyncFunctionResolveKind #include "vm/BytecodeUtil.h" // JOF_*, IsArgOp, IsLocalOp, SET_UINT24, SET_ICINDEX, BytecodeFallsThrough, BytecodeIsJumpTarget #include "vm/FunctionPrefixKind.h" // FunctionPrefixKind @@ -60,7 +64,7 @@ #include "vm/JSAtom.h" // JSAtom, js_*_str #include "vm/JSContext.h" // JSContext #include "vm/JSFunction.h" // JSFunction, -#include "vm/JSScript.h" // JSScript, ScriptSourceObject, FieldInitializers, BaseScript +#include "vm/JSScript.h" // JSScript, ScriptSourceObject, MemberInitializers, BaseScript #include "vm/Opcodes.h" // JSOp, JSOpLength_* #include "vm/SharedStencil.h" // ScopeNote #include "vm/ThrowMsgKind.h" // ThrowMsgKind @@ -95,15 +99,31 @@ static bool ParseNodeRequiresSpecialLineNumberNotes(ParseNode* pn) { kind == ParseNodeKind::Function; } +static bool NeedsFieldInitializer(ParseNode* member, bool isStatic) { + return member->is() && + member->as().isStatic() == isStatic; +} + +static bool NeedsMethodInitializer(ParseNode* member, bool isStatic) { + if (isStatic) { + return false; + } + return member->is() && + member->as().name().isKind(ParseNodeKind::PrivateName) && + !member->as().isStatic(); +} + BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode) : sc(sc), cx(sc->cx_), parent(parent), - bytecodeSection_(cx, sc->extent.lineno), + bytecodeSection_(cx, sc->extent().lineno), perScriptData_(cx, compilationInfo), compilationInfo(compilationInfo), + compilationState(compilationState), emitterMode(emitterMode) { if (IsTypeInferenceEnabled() && sc->isFunctionBox()) { // Functions have IC entries for type monitoring |this| and arguments. @@ -114,8 +134,10 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc, BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, BCEParserHandle* handle, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode) - : BytecodeEmitter(parent, sc, compilationInfo, emitterMode) { + : BytecodeEmitter(parent, sc, compilationInfo, compilationState, + emitterMode) { parser = handle; instrumentationKinds = parser->options().instrumentationKinds; } @@ -123,8 +145,10 @@ BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, const EitherParser& parser, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode) - : BytecodeEmitter(parent, sc, compilationInfo, emitterMode) { + : BytecodeEmitter(parent, sc, compilationInfo, compilationState, + emitterMode) { ep_.emplace(parser); this->parser = ep_.ptr(); instrumentationKinds = this->parser->options().instrumentationKinds; @@ -152,17 +176,17 @@ T* BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const { return NestableControl::findNearest(innermostNestableControl, predicate); } -NameLocation BytecodeEmitter::lookupName(JSAtom* name) { +NameLocation BytecodeEmitter::lookupName(const ParserAtom* name) { return innermostEmitterScope()->lookup(this, name); } Maybe BytecodeEmitter::locationOfNameBoundInScope( - JSAtom* name, EmitterScope* target) { + const ParserAtom* name, EmitterScope* target) { return innermostEmitterScope()->locationBoundInScope(name, target); } Maybe BytecodeEmitter::locationOfNameBoundInFunctionScope( - JSAtom* name, EmitterScope* source) { + const ParserAtom* name, EmitterScope* source) { EmitterScope* funScope = source; while (!funScope->scope(this).is()) { funScope = funScope->enclosingInFrame(); @@ -342,7 +366,7 @@ bool BytecodeEmitter::emitJumpTargetOp(JSOp op, BytecodeOffset* off) { uint32_t numEntries = bytecodeSection().numICEntries(); size_t n = GetOpLength(op) - 1; - MOZ_ASSERT(GetOpLength(op) >= 1 + UINT32_INDEX_LEN); + MOZ_ASSERT(GetOpLength(op) >= 1 + ICINDEX_LEN); if (!emitN(op, n, off)) { return false; @@ -506,6 +530,10 @@ bool BytecodeEmitter::emitCheckIsObj(CheckIsObjectKind kind) { return emit2(JSOp::CheckIsObj, uint8_t(kind)); } +bool BytecodeEmitter::emitBuiltinObject(BuiltinObjectKind kind) { + return emit2(JSOp::BuiltinObject, uint8_t(kind)); +} + /* Updates line number notes, not column notes. */ bool BytecodeEmitter::updateLineNumberNotes(uint32_t offset) { if (skipLocationSrcNotes()) { @@ -684,7 +712,7 @@ bool NonLocalExitControl::leaveScope(EmitterScope* es) { // As we pop each scope due to the non-local jump, emit notes that // record the extent of the enclosing scope. These notes will have // their ends recorded in ~NonLocalExitControl(). - uint32_t enclosingScopeIndex = ScopeNote::NoScopeIndex; + GCThingIndex enclosingScopeIndex = ScopeNote::NoScopeIndex; if (es->enclosingInFrame()) { enclosingScopeIndex = es->enclosingInFrame()->index(); } @@ -857,10 +885,14 @@ AbstractScopePtr BytecodeEmitter::innermostScope() const { return innermostEmitterScope()->scope(this); } -bool BytecodeEmitter::emitIndexOp(JSOp op, uint32_t index) { +ScopeIndex BytecodeEmitter::innermostScopeIndex() const { + return *innermostEmitterScope()->scopeIndex(this); +} + +bool BytecodeEmitter::emitGCIndexOp(JSOp op, GCThingIndex index) { MOZ_ASSERT(checkStrictOrSloppy(op)); - constexpr size_t OpLength = 1 + UINT32_INDEX_LEN; + constexpr size_t OpLength = 1 + GCTHING_INDEX_LEN; MOZ_ASSERT(GetOpLength(op) == OpLength); BytecodeOffset offset; @@ -870,12 +902,12 @@ bool BytecodeEmitter::emitIndexOp(JSOp op, uint32_t index) { jsbytecode* code = bytecodeSection().code(offset); code[0] = jsbytecode(op); - SET_UINT32_INDEX(code, index); + SET_GCTHING_INDEX(code, index); bytecodeSection().updateDepth(offset); return true; } -bool BytecodeEmitter::emitAtomOp(JSOp op, JSAtom* atom, +bool BytecodeEmitter::emitAtomOp(JSOp op, const ParserAtom* atom, ShouldInstrument shouldInstrument) { MOZ_ASSERT(atom); @@ -884,14 +916,14 @@ bool BytecodeEmitter::emitAtomOp(JSOp op, JSAtom* atom, // It's safe to emit .this lookups though because |with| objects skip // those. MOZ_ASSERT_IF(op == JSOp::GetName || op == JSOp::GetGName, - atom != cx->names().dotGenerator); + atom != cx->parserNames().dotGenerator); - if (op == JSOp::GetProp && atom == cx->names().length) { + if (op == JSOp::GetProp && atom == cx->parserNames().length) { /* Specialize length accesses for the interpreter. */ op = JSOp::Length; } - uint32_t index; + GCThingIndex index; if (!makeAtomIndex(atom, &index)) { return false; } @@ -899,7 +931,7 @@ bool BytecodeEmitter::emitAtomOp(JSOp op, JSAtom* atom, return emitAtomOp(op, index, shouldInstrument); } -bool BytecodeEmitter::emitAtomOp(JSOp op, uint32_t atomIndex, +bool BytecodeEmitter::emitAtomOp(JSOp op, GCThingIndex atomIndex, ShouldInstrument shouldInstrument) { MOZ_ASSERT(JOF_OPTYPE(op) == JOF_ATOM); @@ -908,29 +940,29 @@ bool BytecodeEmitter::emitAtomOp(JSOp op, uint32_t atomIndex, return false; } - return emitIndexOp(op, atomIndex); + return emitGCIndexOp(op, atomIndex); } -bool BytecodeEmitter::emitInternedScopeOp(uint32_t index, JSOp op) { +bool BytecodeEmitter::emitInternedScopeOp(GCThingIndex index, JSOp op) { MOZ_ASSERT(JOF_OPTYPE(op) == JOF_SCOPE); MOZ_ASSERT(index < perScriptData().gcThingList().length()); - return emitIndexOp(op, index); + return emitGCIndexOp(op, index); } -bool BytecodeEmitter::emitInternedObjectOp(uint32_t index, JSOp op) { +bool BytecodeEmitter::emitInternedObjectOp(GCThingIndex index, JSOp op) { MOZ_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT); MOZ_ASSERT(index < perScriptData().gcThingList().length()); - return emitIndexOp(op, index); + return emitGCIndexOp(op, index); } -bool BytecodeEmitter::emitObjectPairOp(uint32_t index1, uint32_t index2, +bool BytecodeEmitter::emitObjectPairOp(GCThingIndex index1, GCThingIndex index2, JSOp op) { MOZ_ASSERT(index1 + 1 == index2, "object pair indices must be adjacent"); return emitInternedObjectOp(index1, op); } -bool BytecodeEmitter::emitRegExp(uint32_t index) { - return emitIndexOp(JSOp::RegExp, index); +bool BytecodeEmitter::emitRegExp(GCThingIndex index) { + return emitGCIndexOp(JSOp::RegExp, index); } bool BytecodeEmitter::emitLocalOp(JSOp op, uint32_t slot) { @@ -1614,54 +1646,61 @@ void BytecodeEmitter::reportError(const Maybe& maybeOffset, va_end(args); } -bool BytecodeEmitter::iteratorResultShape(uint32_t* shape) { +bool BytecodeEmitter::iteratorResultShape(GCThingIndex* shape) { // Use |NoValues| to keep the flags consistent with their usage for normal // object literal creation, where |NoValues| is always used in conjunction // with |NewObject|. ObjLiteralFlags flags{ObjLiteralFlag::NoValues}; - ObjLiteralCreationData data(cx); + ObjLiteralIndex objIndex(compilationInfo.stencil.objLiteralData.length()); + if (!compilationInfo.stencil.objLiteralData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData.back(); + data.writer().beginObject(flags); - for (auto name : {&JSAtomState::value, &JSAtomState::done}) { - HandlePropertyName propName = cx->names().*name; + using WellKnownName = js::frontend::WellKnownParserAtoms; + for (auto name : {&WellKnownName::value, &WellKnownName::done}) { + const ParserAtom* propName = cx->parserNames().*name; uint32_t propNameIndex = 0; - if (!data.addAtom(propName, &propNameIndex)) { + if (!data.addAtom(cx, propName, &propNameIndex)) { return false; } data.writer().setPropName(propNameIndex); - if (!data.writer().propWithUndefinedValue()) { + if (!data.writer().propWithUndefinedValue(cx)) { return false; } } - return perScriptData().gcThingList().append(std::move(data), shape); + return perScriptData().gcThingList().append(objIndex, shape); } bool BytecodeEmitter::emitPrepareIteratorResult() { - uint32_t shape; + GCThingIndex shape; if (!iteratorResultShape(&shape)) { return false; } - return emitIndexOp(JSOp::NewObject, shape); + return emitGCIndexOp(JSOp::NewObject, shape); } bool BytecodeEmitter::emitFinishIteratorResult(bool done) { - if (!emitAtomOp(JSOp::InitProp, cx->names().value)) { + if (!emitAtomOp(JSOp::InitProp, cx->parserNames().value)) { return false; } if (!emit1(done ? JSOp::True : JSOp::False)) { return false; } - if (!emitAtomOp(JSOp::InitProp, cx->names().done)) { + if (!emitAtomOp(JSOp::InitProp, cx->parserNames().done)) { return false; } return true; } -bool BytecodeEmitter::emitGetNameAtLocation(Handle name, +bool BytecodeEmitter::emitGetNameAtLocation(const ParserAtom* name, const NameLocation& loc) { NameOpEmitter noe(this, name, loc, NameOpEmitter::Kind::Get); if (!noe.emitGet()) { @@ -1672,11 +1711,28 @@ bool BytecodeEmitter::emitGetNameAtLocation(Handle name, } bool BytecodeEmitter::emitGetName(NameNode* name) { - RootedAtom nameAtom(cx, name->name()); + MOZ_ASSERT(name->isKind(ParseNodeKind::Name)); + + const ParserAtom* nameAtom = name->name(); return emitGetName(nameAtom); } -bool BytecodeEmitter::emitTDZCheckIfNeeded(HandleAtom name, +bool BytecodeEmitter::emitGetPrivateName(NameNode* name) { + MOZ_ASSERT(name->isKind(ParseNodeKind::PrivateName)); + return emitGetPrivateName(name->name()); +} + +bool BytecodeEmitter::emitGetPrivateName(const ParserAtom* nameAtom) { + // The parser ensures the private name is present on the environment chain. + NameLocation location = lookupName(nameAtom); + MOZ_ASSERT(location.kind() == NameLocation::Kind::FrameSlot || + location.kind() == NameLocation::Kind::EnvironmentCoordinate || + location.kind() == NameLocation::Kind::Dynamic); + + return emitGetNameAtLocation(nameAtom, location); +} + +bool BytecodeEmitter::emitTDZCheckIfNeeded(const ParserAtom* name, const NameLocation& loc, ValueIsOnStack isOnStack) { // Dynamic accesses have TDZ checks built into their VM code and should @@ -1824,7 +1880,7 @@ bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec) { ParseNodeKind kind = incDec->getKind(); NameNode* name = &incDec->kid()->as(); - RootedAtom nameAtom(cx, name->atom()); + const ParserAtom* nameAtom = name->atom(); NameOpEmitter noe(this, nameAtom, kind == ParseNodeKind::PostIncrementExpr ? NameOpEmitter::Kind::PostIncrement @@ -1842,8 +1898,9 @@ bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec) { bool BytecodeEmitter::emitElemOpBase(JSOp op, ShouldInstrument shouldInstrument) { + GCThingIndex unused; if (shouldInstrument != ShouldInstrument::No && - !emitInstrumentationForOpcode(op, 0)) { + !emitInstrumentationForOpcode(op, unused)) { return false; } @@ -1901,6 +1958,7 @@ bool BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem, bool isSuper, bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec) { PropertyByValue* elemExpr = &incDec->kid()->as(); bool isSuper = elemExpr->isSuper(); + bool isPrivate = elemExpr->key().isKind(ParseNodeKind::PrivateName); ParseNodeKind kind = incDec->getKind(); ElemOpEmitter eoe( this, @@ -1911,7 +1969,8 @@ bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec) { : kind == ParseNodeKind::PostDecrementExpr ? ElemOpEmitter::Kind::PostDecrement : ElemOpEmitter::Kind::PreDecrement, - isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other); + isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) { // [stack] # if Super // [stack] THIS KEY @@ -2251,7 +2310,7 @@ bool BytecodeEmitter::emitSetThis(BinaryNode* setThisNode) { MOZ_ASSERT(setThisNode->isKind(ParseNodeKind::SetThis)); MOZ_ASSERT(setThisNode->left()->isKind(ParseNodeKind::Name)); - RootedAtom name(cx, setThisNode->left()->as().name()); + const ParserAtom* name = setThisNode->left()->as().name(); // The 'this' binding is not lexical, but due to super() semantics this // initialization needs to be treated as a lexical one. @@ -2301,7 +2360,7 @@ bool BytecodeEmitter::emitSetThis(BinaryNode* setThisNode) { return false; } - if (!emitInitializeInstanceFields()) { + if (!emitInitializeInstanceMembers()) { return false; } @@ -2418,13 +2477,13 @@ bool BytecodeEmitter::emitScript(ParseNode* body) { return false; } - if (!NameFunctions(cx, body)) { + if (!NameFunctions(cx, compilationInfo, body)) { return false; } // Create a Stencil and convert it into a JSScript. - compilationInfo.topLevelExtent = sc->extent; - return intoScriptStencil(compilationInfo.topLevel.address()); + return intoScriptStencil( + &compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex]); } js::UniquePtr BytecodeEmitter::createImmutableScriptData( @@ -2435,7 +2494,7 @@ js::UniquePtr BytecodeEmitter::createImmutableScriptData( } bool isFunction = sc->isFunctionBox(); - uint16_t funLength = isFunction ? sc->asFunctionBox()->length : 0; + uint16_t funLength = isFunction ? sc->asFunctionBox()->length() : 0; return ImmutableScriptData::new_( cx, mainOffset(), maxFixedSlots, nslots, bodyScopeIndex, @@ -2498,12 +2557,12 @@ bool BytecodeEmitter::emitFunctionScript(FunctionNode* funNode, } if (isTopLevel == TopLevelFunction::Yes) { - if (!NameFunctions(cx, funNode)) { + if (!NameFunctions(cx, compilationInfo, funNode)) { return false; } } - return fse.intoStencil(isTopLevel); + return fse.intoStencil(); } bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target, @@ -2568,9 +2627,12 @@ bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target, case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &target->as(); bool isSuper = elem->isSuper(); - ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment, - isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter eoe( + this, ElemOpEmitter::Kind::SimpleAssignment, + isSuper ? ElemOpEmitter::ObjKind::Super + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitElemObjAndKey(elem, isSuper, eoe)) { // [stack] # if Super // [stack] THIS KEY @@ -2634,7 +2696,7 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring( } else { switch (target->getKind()) { case ParseNodeKind::Name: { - RootedAtom name(cx, target->as().name()); + const ParserAtom* name = target->as().name(); NameLocation loc = lookupName(name); NameOpEmitter::Kind kind; switch (flav) { @@ -2711,9 +2773,12 @@ bool BytecodeEmitter::emitSetOrInitializeDestructuring( // [stack] OBJ KEY VAL PropertyByValue* elem = &target->as(); bool isSuper = elem->isSuper(); - ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment, - isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter eoe( + this, ElemOpEmitter::Kind::SimpleAssignment, + isSuper ? ElemOpEmitter::ObjKind::Super + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!eoe.skipObjAndKeyAndRhs()) { return false; } @@ -2878,7 +2943,7 @@ bool BytecodeEmitter::emitIteratorCloseInScope( // Step 4. // // Get the "return" method. - if (!emitAtomOp(JSOp::CallProp, cx->names().return_)) { + if (!emitAtomOp(JSOp::CallProp, cx->parserNames().return_)) { // [stack] ... ITER RET return false; } @@ -3035,7 +3100,7 @@ bool BytecodeEmitter::emitDefault(ParseNode* defaultExpr, ParseNode* pattern) { } bool BytecodeEmitter::emitAnonymousFunctionWithName(ParseNode* node, - HandleAtom name) { + const ParserAtom* name) { MOZ_ASSERT(node->isDirectRHSAnonFunction()); if (node->is()) { @@ -3079,7 +3144,7 @@ bool BytecodeEmitter::emitAnonymousFunctionWithComputedName( return emitClass(&node->as(), ClassNameKind::ComputedName); } -bool BytecodeEmitter::setFunName(FunctionBox* funbox, JSAtom* name) { +bool BytecodeEmitter::setFunName(FunctionBox* funbox, const ParserAtom* name) { // The inferred name may already be set if this function is an interpreted // lazy function and we OOM'ed after we set the inferred name the first // time. @@ -3098,7 +3163,7 @@ bool BytecodeEmitter::emitInitializer(ParseNode* initializer, ParseNode* pattern) { if (initializer->isDirectRHSAnonFunction()) { MOZ_ASSERT(!pattern->isInParens()); - RootedAtom name(cx, pattern->as().name()); + const ParserAtom* name = pattern->as().name(); if (!emitAnonymousFunctionWithName(initializer, name)) { return false; } @@ -3410,7 +3475,7 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern, // [stack] ... OBJ NEXT ITER LREF* RESULT RESULT return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().done)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().done)) { // [stack] ... OBJ NEXT ITER LREF* RESULT DONE return false; } @@ -3448,7 +3513,7 @@ bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern, return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] ... OBJ NEXT ITER DONE LREF* VALUE return false; } @@ -3638,7 +3703,7 @@ bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern, bool needsGetElem = true; if (member->isKind(ParseNodeKind::MutateProto)) { - if (!emitAtomOp(JSOp::GetProp, cx->names().proto)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().proto)) { // [stack] ... SET? RHS LREF* PROP return false; } @@ -3776,7 +3841,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) { } } - RootedAtom pnatom(cx); + const ParserAtom* pnatom = nullptr; for (ParseNode* member : pattern->contents()) { if (member->isKind(ParseNodeKind::Spread)) { MOZ_ASSERT(!member->pn_next, "unexpected trailing element after spread"); @@ -3785,7 +3850,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) { bool isIndex = false; if (member->isKind(ParseNodeKind::MutateProto)) { - pnatom.set(cx->names().proto); + pnatom = cx->parserNames().proto; } else { ParseNode* key = member->as().left(); if (key->isKind(ParseNodeKind::NumberExpr)) { @@ -3800,7 +3865,7 @@ bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) { isIndex = true; } else if (key->isKind(ParseNodeKind::ObjectPropertyName) || key->isKind(ParseNodeKind::StringExpr)) { - pnatom.set(key->as().atom()); + pnatom = key->as().atom(); } else { // Otherwise this is a computed property name which needs to // be added dynamically. @@ -3846,7 +3911,7 @@ bool BytecodeEmitter::emitTemplateString(ListNode* templateString) { // Skip empty strings. These are very common: a template string like // `${a}${b}` has three empty strings and without this optimization // we'd emit four JSOp::Add operations instead of just one. - if (isString && item->as().atom()->empty()) { + if (isString && item->as().atom()->length() == 0) { continue; } @@ -3882,7 +3947,7 @@ bool BytecodeEmitter::emitTemplateString(ListNode* templateString) { if (!pushedString) { // All strings were empty, this can happen for something like `${""}`. // Just push an empty string. - if (!emitAtomOp(JSOp::String, cx->names().empty)) { + if (!emitAtomOp(JSOp::String, cx->parserNames().empty)) { return false; } } @@ -3946,7 +4011,7 @@ bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl, return true; } - RootedAtom nameAtom(cx, decl->name()); + const ParserAtom* nameAtom = decl->name(); NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { // [stack] ENV? @@ -3989,7 +4054,7 @@ bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl, } bool BytecodeEmitter::emitAssignmentRhs(ParseNode* rhs, - HandleAtom anonFunctionName) { + const ParserAtom* anonFunctionName) { if (rhs->isDirectRHSAnonFunction()) { if (anonFunctionName) { return emitAnonymousFunctionWithName(rhs, anonFunctionName); @@ -4061,7 +4126,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs, lhs->isKind(ParseNodeKind::ElemExpr)); // |name| is used within NameOpEmitter, so its lifetime must surpass |noe|. - RootedAtom name(cx); + const ParserAtom* name = nullptr; Maybe noe; Maybe poe; @@ -4082,7 +4147,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs, // implemented via a property or elem assignment (where we are now), and // rhs->isDirectRHSAnonFunction() is set - so we'll assign the name of the // function. - RootedAtom anonFunctionName(cx); + const ParserAtom* anonFunctionName = nullptr; switch (lhs->getKind()) { case ParseNodeKind::Name: { @@ -4105,7 +4170,7 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs, if (!poe->prepareForObj()) { return false; } - anonFunctionName = &prop->name(); + anonFunctionName = prop->name(); if (isSuper) { UnaryNode* base = &prop->expression().as(); if (!emitGetThisForSuperBase(base)) { @@ -4126,12 +4191,14 @@ bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs, case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &lhs->as(); bool isSuper = elem->isSuper(); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); eoe.emplace(this, isCompound ? ElemOpEmitter::Kind::CompoundAssignment : isInit ? ElemOpEmitter::Kind::PropInit : ElemOpEmitter::Kind::SimpleAssignment, isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitElemObjAndKey(elem, isSuper, *eoe)) { // [stack] # if Super // [stack] THIS KEY @@ -4328,7 +4395,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) { ParseNode* rhs = node->right(); // |name| is used within NameOpEmitter, so its lifetime must surpass |noe|. - RootedAtom name(cx); + const ParserAtom* name = nullptr; // Select the appropriate emitter based on the left-hand side. Maybe noe; @@ -4404,10 +4471,11 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) { case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &lhs->as(); bool isSuper = elem->isSuper(); - + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); eoe.emplace(this, ElemOpEmitter::Kind::CompoundAssignment, isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitElemObjAndKey(elem, isSuper, *eoe)) { // [stack] # if Super @@ -4539,7 +4607,7 @@ bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) { } bool BytecodeEmitter::emitCallSiteObjectArray(ListNode* cookedOrRaw, - uint32_t* arrayIndex) { + GCThingIndex* arrayIndex) { uint32_t count = cookedOrRaw->count(); ParseNode* pn = cookedOrRaw->head(); @@ -4552,7 +4620,13 @@ bool BytecodeEmitter::emitCallSiteObjectArray(ListNode* cookedOrRaw, MOZ_ASSERT(cookedOrRaw->isKind(ParseNodeKind::ArrayExpr)); } - ObjLiteralCreationData data(cx); + ObjLiteralIndex objIndex(compilationInfo.stencil.objLiteralData.length()); + if (!compilationInfo.stencil.objLiteralData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData.back(); + ObjLiteralFlags flags(ObjLiteralFlag::Array); data.writer().beginObject(flags); data.writer().beginDenseArrayElements(); @@ -4568,16 +4642,16 @@ bool BytecodeEmitter::emitCallSiteObjectArray(ListNode* cookedOrRaw, } MOZ_ASSERT(idx == count); - return perScriptData().gcThingList().append(std::move(data), arrayIndex); + return perScriptData().gcThingList().append(objIndex, arrayIndex); } bool BytecodeEmitter::emitCallSiteObject(CallSiteNode* callSiteObj) { - uint32_t cookedIndex; + GCThingIndex cookedIndex; if (!emitCallSiteObjectArray(callSiteObj, &cookedIndex)) { return false; } - uint32_t rawIndex; + GCThingIndex rawIndex; if (!emitCallSiteObjectArray(callSiteObj->rawNodes(), &rawIndex)) { return false; } @@ -4941,7 +5015,7 @@ bool BytecodeEmitter::emitCopyDataProperties(CopyOption option) { // [stack] TARGET SOURCE SET argc = 3; - if (!emitAtomOp(JSOp::GetIntrinsic, cx->names().CopyDataProperties)) { + if (!emitAtomOp(JSOp::GetIntrinsic, cx->parserNames().CopyDataProperties)) { // [stack] TARGET SOURCE SET COPYDATAPROPERTIES return false; } @@ -4951,7 +5025,7 @@ bool BytecodeEmitter::emitCopyDataProperties(CopyOption option) { argc = 2; if (!emitAtomOp(JSOp::GetIntrinsic, - cx->names().CopyDataPropertiesUnfiltered)) { + cx->parserNames().CopyDataPropertiesUnfiltered)) { // [stack] TARGET SOURCE COPYDATAPROPERTIES return false; } @@ -4993,11 +5067,11 @@ bool BytecodeEmitter::emitCopyDataProperties(CopyOption option) { } bool BytecodeEmitter::emitBigIntOp(BigIntLiteral* bigint) { - uint32_t index; + GCThingIndex index; if (!perScriptData().gcThingList().append(bigint, &index)) { return false; } - return emitIndexOp(JSOp::BigInt, index); + return emitGCIndexOp(JSOp::BigInt, index); } bool BytecodeEmitter::emitIterator() { @@ -5030,7 +5104,7 @@ bool BytecodeEmitter::emitIterator() { // [stack] ITER ITER return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().next)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().next)) { // [stack] ITER NEXT return false; } @@ -5103,7 +5177,7 @@ bool BytecodeEmitter::emitAsyncIterator() { // [stack] ITER ITER return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().next)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().next)) { // [stack] ITER SYNCNEXT return false; } @@ -5140,7 +5214,7 @@ bool BytecodeEmitter::emitAsyncIterator() { // [stack] ITER ITER return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().next)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().next)) { // [stack] ITER NEXT return false; } @@ -5180,7 +5254,7 @@ bool BytecodeEmitter::emitSpread(bool allowSelfHosted) { // [stack] NEXT ITER ARR I RESULT RESULT return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().done)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().done)) { // [stack] NEXT ITER ARR I RESULT DONE return false; } @@ -5190,7 +5264,7 @@ bool BytecodeEmitter::emitSpread(bool allowSelfHosted) { } // Emit code to assign result.value to the iteration variable. - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] NEXT ITER ARR I VALUE return false; } @@ -5272,7 +5346,7 @@ bool BytecodeEmitter::emitInitializeForInOrOfTarget(TernaryNode* forHead) { } if (nameNode) { - RootedAtom nameAtom(cx, nameNode->name()); + const ParserAtom* nameAtom = nameNode->name(); NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { return false; @@ -5328,16 +5402,8 @@ bool BytecodeEmitter::emitForOf(ForNode* forOfLoop, // Certain builtins (e.g. Array.from) are implemented in self-hosting // as for-of loops. - bool allowSelfHostedIter = false; - if (emitterMode == BytecodeEmitter::SelfHosting && - forHeadExpr->isKind(ParseNodeKind::CallExpr) && - forHeadExpr->as().left()->isName( - cx->names().allowContentIter)) { - allowSelfHostedIter = true; - } - - ForOfEmitter forOf(this, headLexicalEmitterScope, allowSelfHostedIter, - iterKind); + ForOfEmitter forOf(this, headLexicalEmitterScope, + allowSelfHostedIter(forHeadExpr), iterKind); if (!forOf.emitIterated()) { // [stack] @@ -5418,7 +5484,7 @@ bool BytecodeEmitter::emitForIn(ForNode* forInLoop, return false; } - RootedAtom nameAtom(cx, nameNode->name()); + const ParserAtom* nameAtom = nameNode->name(); NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { return false; @@ -5638,7 +5704,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction( // Set the |wasEmitted| flag in the funbox once the function has been // emitted. Function definitions that need hoisting to the top of the // function will be seen by emitFunction in two places. - if (funbox->wasEmitted) { + if (funbox->wasEmitted()) { if (!fe.emitAgain()) { // [stack] return false; @@ -5651,16 +5717,15 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction( // Compute the field initializers data and update the funbox. // // NOTE: For a lazy function, this will be applied to any existing function - // in FunctionBox::finish(). + // in UpdateEmittedInnerFunctions(). if (classContentsIfConstructor) { - MOZ_ASSERT(funbox->fieldInitializers.isNothing(), - "FieldInitializers should only be set once"); - funbox->fieldInitializers = setupFieldInitializers( - classContentsIfConstructor, FieldPlacement::Instance); - if (!funbox->fieldInitializers) { + mozilla::Maybe memberInitializers = + setupMemberInitializers(classContentsIfConstructor, + FieldPlacement::Instance); + if (!memberInitializers) { ReportAllocationOverflow(cx); - return false; } + funbox->setMemberInitializers(*memberInitializers); } // A function is a run-once lambda if the following all hold: @@ -5675,7 +5740,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction( // NOTE: This is a heuristic and through trick such as `fun.caller` it may // still be run more than once. The VM must accomodate this. // NOTE: For a lazy function, this will be applied to any existing function - // in FunctionBox::finish(). + // in UpdateEmittedInnerFunctions(). bool isRunOnceLambda = emittingRunOnceLambda && !funbox->shouldSuppressRunOnce(); funbox->setTreatAsRunOnce(isRunOnceLambda); @@ -5688,7 +5753,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction( // // NOTE: This heuristic is arbitrary, but some debugger tests rely on the // current behaviour and need to be updated if the condiditons change. - funbox->isSingleton = checkRunOnceContext(); + funbox->setIsSingleton(checkRunOnceContext()); if (!funbox->emitBytecode) { return fe.emitLazy(); @@ -5700,13 +5765,8 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction( return false; } - EmitterMode nestedMode = emitterMode; - if (nestedMode == BytecodeEmitter::LazyFunction) { - MOZ_ASSERT(compilationInfo.sourceObject->source()->hasBinASTSource()); - nestedMode = BytecodeEmitter::Normal; - } - - BytecodeEmitter bce2(this, parser, funbox, compilationInfo, nestedMode); + BytecodeEmitter bce2(this, parser, funbox, compilationInfo, + compilationState, emitterMode); if (!bce2.init(funNode->pn_pos)) { return false; } @@ -5802,7 +5862,7 @@ bool BytecodeEmitter::emitWhile(BinaryNode* whileNode) { return true; } -bool BytecodeEmitter::emitBreak(PropertyName* label) { +bool BytecodeEmitter::emitBreak(const ParserName* label) { BreakableControl* target; if (label) { // Any statement with the matching label may be the break target. @@ -5820,7 +5880,7 @@ bool BytecodeEmitter::emitBreak(PropertyName* label) { return emitGoto(target, &target->breaks, GotoKind::Break); } -bool BytecodeEmitter::emitContinue(PropertyName* label) { +bool BytecodeEmitter::emitContinue(const ParserName* label) { LoopControl* target = nullptr; if (label) { // Find the loop statement enclosed by the matching label. @@ -5840,7 +5900,7 @@ bool BytecodeEmitter::emitContinue(PropertyName* label) { bool BytecodeEmitter::emitGetFunctionThis(NameNode* thisName) { MOZ_ASSERT(sc->hasFunctionThisBinding()); - MOZ_ASSERT(thisName->isName(cx->names().dotThis)); + MOZ_ASSERT(thisName->isName(cx->parserNames().dotThis)); return emitGetFunctionThis(Some(thisName->pn_pos.begin)); } @@ -5853,7 +5913,7 @@ bool BytecodeEmitter::emitGetFunctionThis( } } - if (!emitGetName(cx->names().dotThis)) { + if (!emitGetName(cx->parserNames().dotThis)) { // [stack] THIS return false; } @@ -5892,8 +5952,8 @@ bool BytecodeEmitter::emitThisLiteral(ThisLiteral* pn) { } bool BytecodeEmitter::emitCheckDerivedClassConstructorReturn() { - MOZ_ASSERT(lookupName(cx->names().dotThis).hasKnownSlot()); - if (!emitGetName(cx->names().dotThis)) { + MOZ_ASSERT(lookupName(cx->parserNames().dotThis).hasKnownSlot()); + if (!emitGetName(cx->parserNames().dotThis)) { return false; } if (!emit1(JSOp::CheckReturn)) { @@ -5995,7 +6055,7 @@ bool BytecodeEmitter::emitReturn(UnaryNode* returnNode) { // We know that .generator is on the function scope, as we just exited // all nested scopes. NameLocation loc = *locationOfNameBoundInFunctionScope( - cx->names().dotGenerator, varEmitterScope); + cx->parserNames().dotGenerator, varEmitterScope); // Resolve the return value before emitting the final yield. if (sc->asFunctionBox()->needsPromiseResult()) { @@ -6003,7 +6063,7 @@ bool BytecodeEmitter::emitReturn(UnaryNode* returnNode) { // [stack] RVAL return false; } - if (!emitGetNameAtLocation(cx->names().dotGenerator, loc)) { + if (!emitGetNameAtLocation(cx->parserNames().dotGenerator, loc)) { // [stack] RVAL GEN return false; } @@ -6018,7 +6078,7 @@ bool BytecodeEmitter::emitReturn(UnaryNode* returnNode) { } } - if (!emitGetNameAtLocation(cx->names().dotGenerator, loc)) { + if (!emitGetNameAtLocation(cx->parserNames().dotGenerator, loc)) { return false; } if (!emitYieldOp(JSOp::FinalYieldRval)) { @@ -6045,8 +6105,8 @@ bool BytecodeEmitter::emitReturn(UnaryNode* returnNode) { bool BytecodeEmitter::emitGetDotGeneratorInScope(EmitterScope& currentScope) { NameLocation loc = *locationOfNameBoundInFunctionScope( - cx->names().dotGenerator, ¤tScope); - return emitGetNameAtLocation(cx->names().dotGenerator, loc); + cx->parserNames().dotGenerator, ¤tScope); + return emitGetNameAtLocation(cx->parserNames().dotGenerator, loc); } bool BytecodeEmitter::emitInitialYield(UnaryNode* yieldNode) { @@ -6338,7 +6398,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // [stack] NEXT ITER RECEIVED ITER ITER return false; } - if (!emitAtomOp(JSOp::CallProp, cx->names().throw_)) { + if (!emitAtomOp(JSOp::CallProp, cx->parserNames().throw_)) { // [stack] NEXT ITER RECEIVED ITER THROW return false; } @@ -6402,7 +6462,8 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // // If the iterator does not have a "throw" method, it calls IteratorClose // and then throws a TypeError. - if (!emitIteratorCloseInInnermostScope(iterKind)) { + if (!emitIteratorCloseInInnermostScope(iterKind, CompletionKind::Normal, + allowSelfHostedIter(iter))) { // [stack] NEXT ITER RECEIVED ITER return false; } @@ -6445,7 +6506,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // [stack] NEXT ITER RECEIVED ITER ITER return false; } - if (!emitAtomOp(JSOp::CallProp, cx->names().return_)) { + if (!emitAtomOp(JSOp::CallProp, cx->parserNames().return_)) { // [stack] NEXT ITER RECEIVED ITER RET return false; } @@ -6475,7 +6536,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { return false; } if (needsIteratorResult) { - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] NEXT ITER RET ITER VAL return false; } @@ -6508,7 +6569,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // [stack] NEXT ITER RESULT RESULT return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().done)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().done)) { // [stack] NEXT ITER RESULT DONE return false; } @@ -6518,7 +6579,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { } // Step 7.c.viii.1. - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] NEXT ITER VALUE return false; } @@ -6609,7 +6670,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // [stack] NEXT ITER RESULT RESULT return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().done)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().done)) { // [stack] NEXT ITER RESULT DONE return false; } @@ -6626,7 +6687,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { return false; } if (iterKind == IteratorKind::Async) { - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] NEXT ITER RESULT return false; } @@ -6674,7 +6735,7 @@ bool BytecodeEmitter::emitYieldStar(ParseNode* iter) { // [stack] RESULT return false; } - if (!emitAtomOp(JSOp::GetProp, cx->names().value)) { + if (!emitAtomOp(JSOp::GetProp, cx->parserNames().value)) { // [stack] VALUE return false; } @@ -6805,9 +6866,13 @@ bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) { PropertyByValue* elemExpr = &deleteNode->kid()->as(); bool isSuper = elemExpr->isSuper(); + DebugOnly isPrivate = + elemExpr->key().isKind(ParseNodeKind::PrivateName); + MOZ_ASSERT(!isPrivate); ElemOpEmitter eoe( this, ElemOpEmitter::Kind::Delete, - isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other); + isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other, + NameVisibility::Public); // Can't delete a private name. if (isSuper) { // The expression |delete super[foo];| has to evaluate |super[foo]|, // which could throw if |this| hasn't yet been set by a |super(...)| @@ -6958,7 +7023,7 @@ bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr, MOZ_ASSERT_IF(elemExpr->is(), !elemExpr->as().isSuper()); ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Delete, - ElemOpEmitter::ObjKind::Other); + ElemOpEmitter::ObjKind::Other, NameVisibility::Public); if (!eoe.prepareForObj()) { // [stack] @@ -6998,14 +7063,15 @@ bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr, return true; } -static const char* SelfHostedCallFunctionName(JSAtom* name, JSContext* cx) { - if (name == cx->names().callFunction) { +static const char* SelfHostedCallFunctionName(const ParserAtom* name, + JSContext* cx) { + if (name == cx->parserNames().callFunction) { return "callFunction"; } - if (name == cx->names().callContentFunction) { + if (name == cx->parserNames().callContentFunction) { return "callContentFunction"; } - if (name == cx->names().constructContentFunction) { + if (name == cx->parserNames().constructContentFunction) { return "constructContentFunction"; } @@ -7039,11 +7105,11 @@ bool BytecodeEmitter::emitSelfHostedCallFunction(CallNode* callNode) { } bool constructing = - calleeNode->name() == cx->names().constructContentFunction; + calleeNode->name() == cx->parserNames().constructContentFunction; ParseNode* funNode = argsList->head(); if (constructing) { callOp = JSOp::New; - } else if (funNode->isName(cx->names().std_Function_apply)) { + } else if (funNode->isName(cx->parserNames().std_Function_apply)) { callOp = JSOp::FunApply; } @@ -7053,7 +7119,7 @@ bool BytecodeEmitter::emitSelfHostedCallFunction(CallNode* callNode) { #ifdef DEBUG if (emitterMode == BytecodeEmitter::SelfHosting && - calleeNode->name() == cx->names().callFunction) { + calleeNode->name() == cx->parserNames().callFunction) { if (!emit1(JSOp::DebugCheckSelfHosted)) { return false; } @@ -7119,7 +7185,7 @@ bool BytecodeEmitter::emitSelfHostedResumeGenerator(BinaryNode* callNode) { ParseNode* kindNode = valNode->pn_next; MOZ_ASSERT(kindNode->isKind(ParseNodeKind::StringExpr)); GeneratorResumeKind kind = - AtomToResumeKind(cx, kindNode->as().atom()); + ParserAtomToResumeKind(cx, kindNode->as().atom()); MOZ_ASSERT(!kindNode->pn_next); if (!emitPushResumeKind(kind)) { @@ -7254,6 +7320,71 @@ bool BytecodeEmitter::emitSelfHostedToNumeric(BinaryNode* callNode) { return emit1(JSOp::ToNumeric); } +bool BytecodeEmitter::emitSelfHostedToString(BinaryNode* callNode) { + ListNode* argsList = &callNode->right()->as(); + + if (argsList->count() != 1) { + reportNeedMoreArgsError(callNode, "ToString", "1", "", argsList); + return false; + } + + ParseNode* argNode = argsList->head(); + + if (!emitTree(argNode)) { + return false; + } + + return emit1(JSOp::ToString); +} + +bool BytecodeEmitter::emitSelfHostedGetBuiltinConstructorOrPrototype( + BinaryNode* callNode, bool isConstructor) { + ListNode* argsList = &callNode->right()->as(); + + if (argsList->count() != 1) { + const char* name = + isConstructor ? "GetBuiltinConstructor" : "GetBuiltinPrototype"; + reportNeedMoreArgsError(callNode, name, "1", "", argsList); + return false; + } + + ParseNode* argNode = argsList->head(); + + if (!argNode->isKind(ParseNodeKind::StringExpr)) { + reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name", + "not a string constant"); + return false; + } + + const ParserAtom* name = argNode->as().atom(); + + BuiltinObjectKind kind; + if (isConstructor) { + kind = BuiltinConstructorForName(cx, name); + } else { + kind = BuiltinPrototypeForName(cx, name); + } + + if (kind == BuiltinObjectKind::None) { + reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name", + "not a valid built-in"); + return false; + } + + return emitBuiltinObject(kind); +} + +bool BytecodeEmitter::emitSelfHostedGetBuiltinConstructor( + BinaryNode* callNode) { + return emitSelfHostedGetBuiltinConstructorOrPrototype( + callNode, /* isConstructor = */ true); +} + +bool BytecodeEmitter::emitSelfHostedGetBuiltinPrototype(BinaryNode* callNode) { + return emitSelfHostedGetBuiltinConstructorOrPrototype( + callNode, /* isConstructor = */ false); +} + #ifdef DEBUG bool BytecodeEmitter::checkSelfHostedUnsafeGetReservedSlot( BinaryNode* callNode) { @@ -7277,6 +7408,29 @@ bool BytecodeEmitter::checkSelfHostedUnsafeGetReservedSlot( return true; } + +bool BytecodeEmitter::checkSelfHostedUnsafeSetReservedSlot( + BinaryNode* callNode) { + ListNode* argsList = &callNode->right()->as(); + + if (argsList->count() != 3) { + reportNeedMoreArgsError(callNode, "UnsafeSetReservedSlot", "3", "", + argsList); + return false; + } + + ParseNode* objNode = argsList->head(); + ParseNode* slotNode = objNode->pn_next; + + // Ensure that the slot argument is fixed, this is required by the JITs. + if (!slotNode->isKind(ParseNodeKind::NumberExpr)) { + reportError(callNode, JSMSG_UNEXPECTED_TYPE, "slot argument", + "not a constant"); + return false; + } + + return true; +} #endif bool BytecodeEmitter::isRestParameter(ParseNode* expr) { @@ -7290,25 +7444,19 @@ bool BytecodeEmitter::isRestParameter(ParseNode* expr) { } if (!expr->isKind(ParseNodeKind::Name)) { - if (emitterMode == BytecodeEmitter::SelfHosting && - expr->isKind(ParseNodeKind::CallExpr)) { - BinaryNode* callNode = &expr->as(); - ParseNode* calleeNode = callNode->left(); - if (calleeNode->isName(cx->names().allowContentIter)) { - return isRestParameter(callNode->right()->as().head()); - } - } - return false; + return allowSelfHostedIter(expr) && + isRestParameter( + expr->as().right()->as().head()); } - JSAtom* name = expr->as().name(); + const ParserAtom* name = expr->as().name(); Maybe paramLoc = locationOfNameBoundInFunctionScope(name); if (paramLoc && lookupName(name) == *paramLoc) { - FunctionScope::Data* bindings = funbox->functionScopeBindings(); + ParserFunctionScopeData* bindings = funbox->functionScopeBindings(); if (bindings->nonPositionalFormalStart > 0) { // |paramName| can be nullptr when the rest destructuring syntax is // used: `function f(...[]) {}`. - JSAtom* paramName = + const ParserAtom* paramName = bindings->trailingNames[bindings->nonPositionalFormalStart - 1] .name(); return paramName && name == paramName; @@ -7336,7 +7484,7 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee, switch (ParseNodeKind kind = callee->getKind()) { case ParseNodeKind::Name: { - RootedAtom nameAtom(cx, callee->as().name()); + const ParserAtom* nameAtom = callee->as().name(); if (!cone.emitNameCallee(nameAtom)) { // [stack] CALLEE THIS return false; @@ -7372,8 +7520,8 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee, case ParseNodeKind::OptionalElemExpr: { OptionalPropertyByValue* elem = &callee->as(); bool isSuper = false; - - ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper, isPrivate); if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) { // [stack] CALLEE THIS return false; @@ -7383,8 +7531,8 @@ bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee, case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &callee->as(); bool isSuper = elem->isSuper(); - - ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper, isPrivate); if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) { // [stack] CALLEE THIS return false; @@ -7432,7 +7580,7 @@ bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, ParseNode* call, CallOrNewEmitter& cone) { switch (callee->getKind()) { case ParseNodeKind::Name: { - RootedAtom nameAtom(cx, callee->as().name()); + const ParserAtom* nameAtom = callee->as().name(); if (!cone.emitNameCallee(nameAtom)) { // [stack] CALLEE THIS return false; @@ -7471,8 +7619,8 @@ bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, ParseNode* call, MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting); PropertyByValue* elem = &callee->as(); bool isSuper = elem->isSuper(); - - ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper, isPrivate); if (!emitElemObjAndKey(elem, isSuper, eoe)) { // [stack] # if Super // [stack] THIS? THIS KEY @@ -7727,45 +7875,60 @@ bool BytecodeEmitter::emitCallOrNew( // Calls to "forceInterpreter", "callFunction", // "callContentFunction", or "resumeGenerator" in self-hosted // code generate inline bytecode. - PropertyName* calleeName = calleeNode->as().name(); - if (calleeName == cx->names().callFunction || - calleeName == cx->names().callContentFunction || - calleeName == cx->names().constructContentFunction) { + const ParserName* calleeName = calleeNode->as().name(); + if (calleeName == cx->parserNames().callFunction || + calleeName == cx->parserNames().callContentFunction || + calleeName == cx->parserNames().constructContentFunction) { return emitSelfHostedCallFunction(callNode); } - if (calleeName == cx->names().resumeGenerator) { + if (calleeName == cx->parserNames().resumeGenerator) { return emitSelfHostedResumeGenerator(callNode); } - if (calleeName == cx->names().forceInterpreter) { + if (calleeName == cx->parserNames().forceInterpreter) { return emitSelfHostedForceInterpreter(); } - if (calleeName == cx->names().allowContentIter) { + if (calleeName == cx->parserNames().allowContentIter) { return emitSelfHostedAllowContentIter(callNode); } - if (calleeName == cx->names().defineDataPropertyIntrinsic && + if (calleeName == cx->parserNames().defineDataPropertyIntrinsic && argsList->count() == 3) { return emitSelfHostedDefineDataProperty(callNode); } - if (calleeName == cx->names().hasOwn) { + if (calleeName == cx->parserNames().hasOwn) { return emitSelfHostedHasOwn(callNode); } - if (calleeName == cx->names().getPropertySuper) { + if (calleeName == cx->parserNames().getPropertySuper) { return emitSelfHostedGetPropertySuper(callNode); } - if (calleeName == cx->names().ToNumeric) { + if (calleeName == cx->parserNames().ToNumeric) { return emitSelfHostedToNumeric(callNode); } + if (calleeName == cx->parserNames().ToString) { + return emitSelfHostedToString(callNode); + } + if (calleeName == cx->parserNames().GetBuiltinConstructor) { + return emitSelfHostedGetBuiltinConstructor(callNode); + } + if (calleeName == cx->parserNames().GetBuiltinPrototype) { + return emitSelfHostedGetBuiltinPrototype(callNode); + } #ifdef DEBUG - if (calleeName == cx->names().UnsafeGetReservedSlot || - calleeName == cx->names().UnsafeGetObjectFromReservedSlot || - calleeName == cx->names().UnsafeGetInt32FromReservedSlot || - calleeName == cx->names().UnsafeGetStringFromReservedSlot || - calleeName == cx->names().UnsafeGetBooleanFromReservedSlot) { + if (calleeName == cx->parserNames().UnsafeGetReservedSlot || + calleeName == cx->parserNames().UnsafeGetObjectFromReservedSlot || + calleeName == cx->parserNames().UnsafeGetInt32FromReservedSlot || + calleeName == cx->parserNames().UnsafeGetStringFromReservedSlot || + calleeName == cx->parserNames().UnsafeGetBooleanFromReservedSlot) { // Make sure that this call is correct, but don't emit any special code. if (!checkSelfHostedUnsafeGetReservedSlot(callNode)) { return false; } } + if (calleeName == cx->parserNames().UnsafeSetReservedSlot) { + // Make sure that this call is correct, but don't emit any special code. + if (!checkSelfHostedUnsafeSetReservedSlot(callNode)) { + return false; + } + } #endif // Fall through } @@ -7900,8 +8063,10 @@ bool BytecodeEmitter::emitOptionalTree( case ParseNodeKind::OptionalElemExpr: { OptionalPropertyByValue* elem = &pn->as(); bool isSuper = false; - ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get, - ElemOpEmitter::ObjKind::Other); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter eoe( + this, ElemOpEmitter::Kind::Get, ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) { return false; @@ -7911,9 +8076,12 @@ bool BytecodeEmitter::emitOptionalTree( case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &pn->as(); bool isSuper = elem->isSuper(); - ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get, - isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter eoe( + this, ElemOpEmitter::Kind::Get, + isSuper ? ElemOpEmitter::ObjKind::Super + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) { return false; @@ -7935,6 +8103,7 @@ bool BytecodeEmitter::emitOptionalTree( // https://tc39.es/ecma262/#sec-primary-expression bool isPrimaryExpression = kind == ParseNodeKind::ThisExpr || kind == ParseNodeKind::Name || + kind == ParseNodeKind::PrivateName || kind == ParseNodeKind::NullExpr || kind == ParseNodeKind::TrueExpr || kind == ParseNodeKind::FalseExpr || kind == ParseNodeKind::NumberExpr || @@ -8218,7 +8387,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitIncOrDec(UnaryNode* incDec) { // the comment on emitSwitch. MOZ_NEVER_INLINE bool BytecodeEmitter::emitLabeledStatement( const LabeledStatement* labeledStmt) { - RootedAtom name(cx, labeledStmt->label()); + const ParserAtom* name = labeledStmt->label(); LabelEmitter label(this); label.emitLabel(name); @@ -8297,6 +8466,11 @@ void BytecodeEmitter::isPropertyListObjLiteralCompatible(ListNode* obj, keysOK = false; break; } + + // BigIntExprs should have been lowered to computed names at parse + // time, and so should be excluded above. + MOZ_ASSERT(!key->isKind(ParseNodeKind::BigIntExpr)); + // Numeric keys OK as long as they are integers and in range. if (key->isKind(ParseNodeKind::NumberExpr)) { double numValue = key->as().value(); @@ -8310,11 +8484,6 @@ void BytecodeEmitter::isPropertyListObjLiteralCompatible(ListNode* obj, break; } } - // BigInt keys aren't yet supported. - if (key->isKind(ParseNodeKind::BigIntExpr)) { - keysOK = false; - break; - } MOZ_ASSERT(key->isKind(ParseNodeKind::ObjectPropertyName) || key->isKind(ParseNodeKind::StringExpr) || @@ -8368,10 +8537,9 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, // is created elsewhere. ClassField* field = &propdef->as(); if (field->name().getKind() == ParseNodeKind::ComputedName) { - auto fieldKeysName = field->isStatic() - ? &JSAtomState::dotStaticFieldKeys - : &JSAtomState::dotFieldKeys; - HandlePropertyName fieldKeys = cx->names().*fieldKeysName; + const ParserName* fieldKeys = field->isStatic() + ? cx->parserNames().dotStaticFieldKeys + : cx->parserNames().dotFieldKeys; if (!emitGetName(fieldKeys)) { // [stack] CTOR? OBJ ARRAY return false; @@ -8462,6 +8630,13 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, ParseNode* propVal = prop->right(); AccessorType accessorType; if (prop->is()) { + if (!prop->as().isStatic() && + key->isKind(ParseNodeKind::PrivateName)) { + // Private instance methods are separately added to the .initializers + // array. + continue; + } + accessorType = prop->as().accessorType(); } else if (prop->is()) { accessorType = prop->as().accessorType(); @@ -8476,18 +8651,8 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, if (key->isKind(ParseNodeKind::NumberExpr)) { MOZ_ASSERT(accessorType == AccessorType::None); - RootedAtom keyAtom(cx, key->as().toAtom(cx)); - if (!keyAtom) { - return false; - } - if (!emitAnonymousFunctionWithName(propVal, keyAtom)) { - // [stack] CTOR? OBJ CTOR? KEY VAL - return false; - } - } else if (key->isKind(ParseNodeKind::BigIntExpr)) { - MOZ_ASSERT(accessorType == AccessorType::None); - - RootedAtom keyAtom(cx, key->as().toAtom(cx)); + const ParserAtom* keyAtom = + key->as().toAtom(cx, compilationInfo); if (!keyAtom) { return false; } @@ -8499,13 +8664,23 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, key->isKind(ParseNodeKind::StringExpr)) { MOZ_ASSERT(accessorType == AccessorType::None); - RootedAtom keyAtom(cx, key->as().atom()); + const ParserAtom* keyAtom = key->as().atom(); if (!emitAnonymousFunctionWithName(propVal, keyAtom)) { // [stack] CTOR? OBJ CTOR? VAL return false; } } else { - MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName)); + MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName) || + key->isKind(ParseNodeKind::BigIntExpr)); + + // If a function name is a BigInt, then treat it as a computed name + // equivalent to `[ToString(B)]` for some big-int value `B`. + if (key->isKind(ParseNodeKind::BigIntExpr)) { + MOZ_ASSERT(accessorType == AccessorType::None); + if (!emit1(JSOp::ToString)) { + return false; + } + } FunctionPrefixKind prefix = accessorType == AccessorType::None ? FunctionPrefixKind::None @@ -8566,27 +8741,8 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, return false; } - switch (accessorType) { - case AccessorType::None: - if (!pe.emitInitIndexProp()) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Getter: - if (!pe.emitInitIndexGetter()) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Setter: - if (!pe.emitInitIndexSetter()) { - // [stack] CTOR? OBJ - return false; - } - break; - default: - MOZ_CRASH("Invalid op"); + if (!pe.emitInitIndexOrComputed(accessorType)) { + return false; } continue; @@ -8598,7 +8754,7 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, // emitClass took care of constructor already. if (type == ClassBody && - key->as().atom() == cx->names().constructor && + key->as().atom() == cx->parserNames().constructor && !propdef->as().isStatic()) { continue; } @@ -8607,39 +8763,23 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, // [stack] CTOR? OBJ CTOR? return false; } + if (!emitValue()) { // [stack] CTOR? OBJ CTOR? VAL return false; } - RootedAtom keyAtom(cx, key->as().atom()); - switch (accessorType) { - case AccessorType::None: - if (!pe.emitInitProp(keyAtom)) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Getter: - if (!pe.emitInitGetter(keyAtom)) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Setter: - if (!pe.emitInitSetter(keyAtom)) { - // [stack] CTOR? OBJ - return false; - } - break; - default: - MOZ_CRASH("Invalid op"); + const ParserAtom* keyAtom = key->as().atom(); + + if (!pe.emitInit(accessorType, keyAtom)) { + return false; } continue; } - MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName)); + MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName) || + key->isKind(ParseNodeKind::PrivateName)); // [stack] CTOR? OBJ @@ -8647,9 +8787,16 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, // [stack] CTOR? OBJ CTOR? return false; } - if (!emitTree(key->as().kid())) { - // [stack] CTOR? OBJ CTOR? KEY - return false; + if (key->is()) { + if (!emitGetPrivateName(&key->as())) { + // [stack] CTOR? OBJ CTOR? KEY + return false; + } + } else { + if (!emitTree(key->as().kid())) { + // [stack] CTOR? OBJ CTOR? KEY + return false; + } } if (!pe.prepareForComputedPropValue()) { // [stack] CTOR? OBJ CTOR? KEY @@ -8660,27 +8807,24 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, return false; } - switch (accessorType) { - case AccessorType::None: - if (!pe.emitInitComputedProp()) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Getter: - if (!pe.emitInitComputedGetter()) { - // [stack] CTOR? OBJ - return false; - } - break; - case AccessorType::Setter: - if (!pe.emitInitComputedSetter()) { - // [stack] CTOR? OBJ - return false; - } - break; - default: - MOZ_CRASH("Invalid op"); + if (!pe.emitInitIndexOrComputed(accessorType)) { + return false; + } + + if (key->isKind(ParseNodeKind::PrivateName) && + key->as().privateNameKind() == PrivateNameKind::Setter) { + if (!emitGetPrivateName(&key->as())) { + // [stack] THIS NAME + return false; + } + if (!emitAtomOp(JSOp::GetIntrinsic, cx->parserNames().NoPrivateGetter)) { + // [stack] THIS NAME FUN + return false; + } + if (!emit1(JSOp::InitHiddenElemGetter)) { + // [stack] THIS + return false; + } } } @@ -8689,7 +8833,13 @@ bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe, bool BytecodeEmitter::emitPropertyListObjLiteral(ListNode* obj, ObjLiteralFlags flags) { - ObjLiteralCreationData data(cx); + ObjLiteralIndex objIndex(compilationInfo.stencil.objLiteralData.length()); + if (!compilationInfo.stencil.objLiteralData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData.back(); + data.writer().beginObject(flags); bool noValues = flags.contains(ObjLiteralFlag::NoValues); bool singleton = flags.contains(ObjLiteralFlag::Singleton); @@ -8700,7 +8850,7 @@ bool BytecodeEmitter::emitPropertyListObjLiteral(ListNode* obj, if (key->is()) { uint32_t propNameIndex = 0; - if (!data.addAtom(key->as().atom(), &propNameIndex)) { + if (!data.addAtom(cx, key->as().atom(), &propNameIndex)) { return false; } data.writer().setPropName(propNameIndex); @@ -8716,7 +8866,7 @@ bool BytecodeEmitter::emitPropertyListObjLiteral(ListNode* obj, } if (noValues) { - if (!data.writer().propWithUndefinedValue()) { + if (!data.writer().propWithUndefinedValue(cx)) { return false; } } else { @@ -8727,17 +8877,20 @@ bool BytecodeEmitter::emitPropertyListObjLiteral(ListNode* obj, } } - uint32_t gcThingIndex = 0; - if (!perScriptData().gcThingList().append(std::move(data), &gcThingIndex)) { + GCThingIndex index; + if (!perScriptData().gcThingList().append(objIndex, &index)) { return false; } bool isInnerSingleton = flags.contains(ObjLiteralFlag::IsInnerSingleton); + // JSOp::Object may only be used by (top-level) run-once scripts. + MOZ_ASSERT_IF(singleton, compilationInfo.input.options.isRunOnce); + JSOp op = singleton ? JSOp::Object : isInnerSingleton ? JSOp::NewObjectWithGroup : JSOp::NewObject; - if (!emitIndexOp(op, gcThingIndex)) { + if (!emitGCIndexOp(op, index)) { // [stack] OBJ return false; } @@ -8752,7 +8905,13 @@ bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral( // with |NewObject|. ObjLiteralFlags flags{ObjLiteralFlag::NoValues}; - ObjLiteralCreationData data(cx); + ObjLiteralIndex objIndex(compilationInfo.stencil.objLiteralData.length()); + if (!compilationInfo.stencil.objLiteralData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData.back(); + data.writer().beginObject(flags); for (ParseNode* member : pattern->contents()) { @@ -8761,27 +8920,27 @@ bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral( break; } - JSAtom* atom; + const ParserAtom* atom = nullptr; if (member->isKind(ParseNodeKind::MutateProto)) { - atom = cx->names().proto; + atom = cx->parserNames().proto; } else { ParseNode* key = member->as().left(); atom = key->as().atom(); } uint32_t propNameIndex = 0; - if (!data.addAtom(atom, &propNameIndex)) { + if (!data.addAtom(cx, atom, &propNameIndex)) { return false; } data.writer().setPropName(propNameIndex); - if (!data.writer().propWithUndefinedValue()) { + if (!data.writer().propWithUndefinedValue(cx)) { return false; } } - uint32_t gcThingIndex = 0; - if (!perScriptData().gcThingList().append(std::move(data), &gcThingIndex)) { + GCThingIndex index; + if (!perScriptData().gcThingList().append(objIndex, &index)) { return false; } @@ -8790,7 +8949,7 @@ bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral( // the user, so it's safe to bake the object into the bytecode. But first we // need to make sure this won't interfere with XDR, cf. the // `RealmBehaviors::singletonsAsTemplates_` flag. - if (!emitIndexOp(JSOp::NewObject, gcThingIndex)) { + if (!emitGCIndexOp(JSOp::NewObject, index)) { // [stack] OBJ return false; } @@ -8799,28 +8958,33 @@ bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral( } bool BytecodeEmitter::emitObjLiteralArray(ParseNode* arrayHead, bool isCow) { - ObjLiteralCreationData data(cx); + ObjLiteralIndex objIndex(compilationInfo.stencil.objLiteralData.length()); + if (!compilationInfo.stencil.objLiteralData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData.back(); + ObjLiteralFlags flags(ObjLiteralFlag::Array); if (isCow) { flags += ObjLiteralFlag::ArrayCOW; } data.writer().beginObject(flags); - uint32_t index = 0; data.writer().beginDenseArrayElements(); - for (ParseNode* elem = arrayHead; elem; elem = elem->pn_next, index++) { + for (ParseNode* elem = arrayHead; elem; elem = elem->pn_next) { if (!emitObjLiteralValue(&data, elem)) { return false; } } - uint32_t gcThingIndex = 0; - if (!perScriptData().gcThingList().append(std::move(data), &gcThingIndex)) { + GCThingIndex index; + if (!perScriptData().gcThingList().append(objIndex, &index)) { return false; } JSOp op = isCow ? JSOp::NewArrayCopyOnWrite : JSOp::Object; - if (!emitIndexOp(op, gcThingIndex)) { + if (!emitGCIndexOp(op, index)) { // [stack] OBJ return false; } @@ -8838,7 +9002,7 @@ bool BytecodeEmitter::isRHSObjLiteralCompatible(ParseNode* value) { value->isKind(ParseNodeKind::TemplateStringExpr); } -bool BytecodeEmitter::emitObjLiteralValue(ObjLiteralCreationData* data, +bool BytecodeEmitter::emitObjLiteralValue(ObjLiteralStencil* data, ParseNode* value) { MOZ_ASSERT(isRHSObjLiteralCompatible(value)); if (value->isKind(ParseNodeKind::NumberExpr)) { @@ -8850,32 +9014,32 @@ bool BytecodeEmitter::emitObjLiteralValue(ObjLiteralCreationData* data, } else { v.setDouble(numValue); } - if (!data->writer().propWithConstNumericValue(v)) { + if (!data->writer().propWithConstNumericValue(cx, v)) { return false; } } else if (value->isKind(ParseNodeKind::TrueExpr)) { - if (!data->writer().propWithTrueValue()) { + if (!data->writer().propWithTrueValue(cx)) { return false; } } else if (value->isKind(ParseNodeKind::FalseExpr)) { - if (!data->writer().propWithFalseValue()) { + if (!data->writer().propWithFalseValue(cx)) { return false; } } else if (value->isKind(ParseNodeKind::NullExpr)) { - if (!data->writer().propWithNullValue()) { + if (!data->writer().propWithNullValue(cx)) { return false; } } else if (value->isKind(ParseNodeKind::RawUndefinedExpr)) { - if (!data->writer().propWithUndefinedValue()) { + if (!data->writer().propWithUndefinedValue(cx)) { return false; } } else if (value->isKind(ParseNodeKind::StringExpr) || value->isKind(ParseNodeKind::TemplateStringExpr)) { uint32_t valueAtomIndex = 0; - if (!data->addAtom(value->as().atom(), &valueAtomIndex)) { + if (!data->addAtom(cx, value->as().atom(), &valueAtomIndex)) { return false; } - if (!data->writer().propWithAtomValue(valueAtomIndex)) { + if (!data->writer().propWithAtomValue(cx, valueAtomIndex)) { return false; } } else { @@ -8884,22 +9048,26 @@ bool BytecodeEmitter::emitObjLiteralValue(ObjLiteralCreationData* data, return true; } -mozilla::Maybe BytecodeEmitter::setupFieldInitializers( +mozilla::Maybe BytecodeEmitter::setupMemberInitializers( ListNode* classMembers, FieldPlacement placement) { bool isStatic = placement == FieldPlacement::Static; - auto isClassField = [isStatic](ParseNode* propdef) { - return propdef->is() && - propdef->as().isStatic() == isStatic; - }; - size_t numFields = - std::count_if(classMembers->contents().begin(), - classMembers->contents().end(), isClassField); + size_t numFields = std::count_if( + classMembers->contents().begin(), classMembers->contents().end(), + [&isStatic](ParseNode* member) { + return NeedsFieldInitializer(member, isStatic); + }); + size_t numPrivateMethods = std::count_if( + classMembers->contents().begin(), classMembers->contents().end(), + [&isStatic](ParseNode* member) { + return NeedsMethodInitializer(member, isStatic); + }); + // If there are more initializers than can be represented, return invalid. - if (numFields > FieldInitializers::MaxInitializers) { + if (numFields + numPrivateMethods > MemberInitializers::MaxInitializers) { return Nothing(); } - return Some(FieldInitializers(numFields)); + return Some(MemberInitializers(numFields + numPrivateMethods)); } // Purpose of .fieldKeys: @@ -8942,9 +9110,8 @@ bool BytecodeEmitter::emitCreateFieldKeys(ListNode* obj, return true; } - auto fieldKeysName = - isStatic ? &JSAtomState::dotStaticFieldKeys : &JSAtomState::dotFieldKeys; - HandlePropertyName fieldKeys = cx->names().*fieldKeysName; + const ParserName* fieldKeys = isStatic ? cx->parserNames().dotStaticFieldKeys + : cx->parserNames().dotFieldKeys; NameOpEmitter noe(this, fieldKeys, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { return false; @@ -8968,34 +9135,42 @@ bool BytecodeEmitter::emitCreateFieldKeys(ListNode* obj, return true; } -bool BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, - ListNode* obj, - FieldPlacement placement) { +bool BytecodeEmitter::emitCreateMemberInitializers(ClassEmitter& ce, + ListNode* obj, + FieldPlacement placement) { // FieldPlacement::Instance // [stack] HOMEOBJ HERITAGE? // // FieldPlacement::Static // [stack] CTOR HOMEOBJ - mozilla::Maybe fieldInitializers = - setupFieldInitializers(obj, placement); - if (!fieldInitializers) { + mozilla::Maybe memberInitializers = + setupMemberInitializers(obj, placement); + if (!memberInitializers) { ReportAllocationOverflow(cx); return false; } - size_t numFields = fieldInitializers->numFieldInitializers; - if (numFields == 0) { + size_t numInitializers = memberInitializers->numMemberInitializers; + if (numInitializers == 0) { return true; } bool isStatic = placement == FieldPlacement::Static; - if (!ce.prepareForFieldInitializers(numFields, isStatic)) { + if (!ce.prepareForMemberInitializers(numInitializers, isStatic)) { // [stack] HOMEOBJ HERITAGE? ARRAY // or: // [stack] CTOR HOMEOBJ ARRAY return false; } + // Private methods could be used in the field initializers, + // so we stamp them onto the instance first. + // Static private methods aren't implemented, so skip this step + // if emitting static initializers. + if (!isStatic && !emitPrivateMethodInitializers(ce, obj)) { + return false; + } + for (ParseNode* propdef : obj->contents()) { if (!propdef->is()) { continue; @@ -9005,7 +9180,8 @@ bool BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, } FunctionNode* initializer = propdef->as().initializer(); - if (!ce.prepareForFieldInitializer()) { + + if (!ce.prepareForMemberInitializer()) { return false; } if (!emitTree(initializer)) { @@ -9016,14 +9192,14 @@ bool BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, } if (initializer->funbox()->needsHomeObject()) { MOZ_ASSERT(initializer->funbox()->allowSuperProperty()); - if (!ce.emitFieldInitializerHomeObject(isStatic)) { + if (!ce.emitMemberInitializerHomeObject(isStatic)) { // [stack] HOMEOBJ HERITAGE? ARRAY LAMBDA // or: // [stack] CTOR HOMEOBJ ARRAY LAMBDA return false; } } - if (!ce.emitStoreFieldInitializer()) { + if (!ce.emitStoreMemberInitializer()) { // [stack] HOMEOBJ HERITAGE? ARRAY // or: // [stack] CTOR HOMEOBJ ARRAY @@ -9031,7 +9207,7 @@ bool BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, } } - if (!ce.emitFieldInitializersEnd()) { + if (!ce.emitMemberInitializersEnd()) { // [stack] HOMEOBJ HERITAGE? // or: // [stack] CTOR HOMEOBJ @@ -9041,7 +9217,220 @@ bool BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, return true; } -const FieldInitializers& BytecodeEmitter::findFieldInitializersForCall() { +bool BytecodeEmitter::emitPrivateMethodInitializers(ClassEmitter& ce, + ListNode* obj) { + for (ParseNode* propdef : obj->contents()) { + if (!propdef->is() || propdef->as().isStatic()) { + continue; + } + ParseNode* propName = &propdef->as().name(); + if (!propName->isKind(ParseNodeKind::PrivateName)) { + continue; + } + + if (!ce.prepareForMemberInitializer()) { + // [stack] HOMEOBJ HERITAGE? ARRAY + // or: + // [stack] CTOR HOMEOBJ ARRAY + return false; + } + + // Synthesize a name for the lexical variable that will store the + // private method body. + StringBuffer storedMethodName(cx); + if (!storedMethodName.append(propName->as().atom())) { + return false; + } + AccessorType accessorType = propdef->as().accessorType(); + switch (accessorType) { + case AccessorType::None: + if (!storedMethodName.append(".method")) { + return false; + } + break; + case AccessorType::Getter: + if (!storedMethodName.append(".getter")) { + return false; + } + break; + case AccessorType::Setter: + if (!storedMethodName.append(".setter")) { + return false; + } + break; + default: + MOZ_CRASH("Invalid private method accessor type"); + } + const ParserAtom* storedMethodAtom = + storedMethodName.finishParserAtom(compilationInfo); + + // Emit the private method body and store it as a lexical var. + if (!emitFunction(&propdef->as().method())) { + // [stack] HOMEOBJ HERITAGE? ARRAY METHOD + // or: + // [stack] CTOR HOMEOBJ ARRAY METHOD + return false; + } + // The private method body needs to access the home object, + // and the CE knows where that is on the stack. + if (!ce.emitMemberInitializerHomeObject(false)) { + // [stack] HOMEOBJ HERITAGE? ARRAY METHOD + // or: + // [stack] CTOR HOMEOBJ ARRAY METHOD + return false; + } + if (!emitLexicalInitialization(storedMethodAtom)) { + // [stack] HOMEOBJ HERITAGE? ARRAY METHOD + // or: + // [stack] CTOR HOMEOBJ ARRAY METHOD + return false; + } + if (!emit1(JSOp::Pop)) { + // [stack] HOMEOBJ HERITAGE? ARRAY + // or: + // [stack] CTOR HOMEOBJ ARRAY + return false; + } + + if (!emitPrivateMethodInitializer(ce, propdef, propName, storedMethodAtom, + accessorType)) { + // [stack] HOMEOBJ HERITAGE? ARRAY + // or: + // [stack] CTOR HOMEOBJ ARRAY + return false; + } + + // Store the emitted initializer function into the .initializers array. + if (!ce.emitStoreMemberInitializer()) { + // [stack] HOMEOBJ HERITAGE? ARRAY + // or: + // [stack] CTOR HOMEOBJ ARRAY + return false; + } + } + + return true; +} + +bool BytecodeEmitter::emitPrivateMethodInitializer( + ClassEmitter& ce, ParseNode* prop, ParseNode* propName, + const ParserAtom* storedMethodAtom, AccessorType accessorType) { + // Emit the synthesized initializer function. + FunctionNode* funNode = prop->as().initializerIfPrivate(); + if (!funNode) { + return false; + } + FunctionBox* funbox = funNode->funbox(); + FunctionEmitter fe(this, funbox, funNode->syntaxKind(), + FunctionEmitter::IsHoisted::No); + if (!fe.prepareForNonLazy()) { + // [stack] + return false; + } + + BytecodeEmitter bce2(this, parser, funbox, compilationInfo, compilationState, + emitterMode); + if (!bce2.init(funNode->pn_pos)) { + return false; + } + ListNode* paramsBody = &funNode->body()->as(); + FunctionScriptEmitter fse(&bce2, funbox, Nothing(), Nothing()); + if (!fse.prepareForParameters()) { + // [stack] + return false; + } + if (!bce2.emitFunctionFormalParameters(paramsBody)) { + // [stack] + return false; + } + if (!fse.prepareForBody()) { + // [stack] + return false; + } + + if (!bce2.emit1(JSOp::FunctionThis)) { + // [stack] THIS + return false; + } + if (!bce2.emitGetPrivateName(&propName->as())) { + // [stack] THIS NAME + return false; + } + if (!bce2.emitGetName(storedMethodAtom)) { + // [stack] THIS NAME METHOD + return false; + } + + PrivateNameKind kind = propName->as().privateNameKind(); + switch (kind) { + case PrivateNameKind::Method: + if (!bce2.emit1(JSOp::InitLockedElem)) { + // [stack] THIS + return false; + } + break; + case PrivateNameKind::Setter: + if (!bce2.emit1(JSOp::InitHiddenElemSetter)) { + // [stack] THIS + return false; + } + if (!bce2.emitGetPrivateName(&propName->as())) { + // [stack] THIS NAME + return false; + } + if (!bce2.emitAtomOp(JSOp::GetIntrinsic, + cx->parserNames().NoPrivateGetter)) { + // [stack] THIS NAME FUN + return false; + } + if (!bce2.emit1(JSOp::InitHiddenElemGetter)) { + // [stack] THIS + return false; + } + break; + case PrivateNameKind::Getter: + case PrivateNameKind::GetterSetter: + if (accessorType == AccessorType::Getter) { + if (!bce2.emit1(JSOp::InitHiddenElemGetter)) { + // [stack] THIS + return false; + } + } else { + if (!bce2.emit1(JSOp::InitHiddenElemSetter)) { + // [stack] THIS + return false; + } + } + break; + default: + MOZ_CRASH("Invalid op"); + } + + // Pop remaining THIS. + if (!bce2.emit1(JSOp::Pop)) { + // [stack] + return false; + } + + if (!fse.emitEndBody()) { + // [stack] + return false; + } + if (!fse.intoStencil()) { + return false; + } + + if (!fe.emitNonLazyEnd()) { + // [stack] HOMEOBJ HERITAGE? ARRAY FUN + // or: + // [stack] CTOR HOMEOBJ ARRAY FUN + return false; + } + + return true; +} + +const MemberInitializers& BytecodeEmitter::findMemberInitializersForCall() { for (BytecodeEmitter* current = this; current; current = current->parent) { if (current->sc->isFunctionBox()) { FunctionBox* funbox = current->sc->asFunctionBox(); @@ -9054,30 +9443,31 @@ const FieldInitializers& BytecodeEmitter::findFieldInitializersForCall() { // expect fields in the first place. MOZ_RELEASE_ASSERT(funbox->isClassConstructor()); - MOZ_ASSERT(funbox->fieldInitializers->valid); - return *funbox->fieldInitializers; + MOZ_ASSERT(funbox->memberInitializers().valid); + return funbox->memberInitializers(); } } - MOZ_RELEASE_ASSERT(compilationInfo.scopeContext.fieldInitializers); - return *compilationInfo.scopeContext.fieldInitializers; + MOZ_RELEASE_ASSERT(compilationState.scopeContext.memberInitializers); + return *compilationState.scopeContext.memberInitializers; } -bool BytecodeEmitter::emitInitializeInstanceFields() { - const FieldInitializers& fieldInitializers = findFieldInitializersForCall(); - size_t numFields = fieldInitializers.numFieldInitializers; +bool BytecodeEmitter::emitInitializeInstanceMembers() { + const MemberInitializers& memberInitializers = + findMemberInitializersForCall(); + size_t numInitializers = memberInitializers.numMemberInitializers; - if (numFields == 0) { + if (numInitializers == 0) { return true; } - if (!emitGetName(cx->names().dotInitializers)) { + if (!emitGetName(cx->parserNames().dotInitializers)) { // [stack] ARRAY return false; } - for (size_t fieldIndex = 0; fieldIndex < numFields; fieldIndex++) { - if (fieldIndex < numFields - 1) { + for (size_t index = 0; index < numInitializers; index++) { + if (index < numInitializers - 1) { // We Dup to keep the array around (it is consumed in the bytecode // below) for next iterations of this loop, except for the last // iteration, which avoids an extra Pop at the end of the loop. @@ -9087,7 +9477,7 @@ bool BytecodeEmitter::emitInitializeInstanceFields() { } } - if (!emitNumberOp(fieldIndex)) { + if (!emitNumberOp(index)) { // [stack] ARRAY? ARRAY INDEX return false; } @@ -9101,7 +9491,7 @@ bool BytecodeEmitter::emitInitializeInstanceFields() { } // This is guaranteed to run after super(), so we don't need TDZ checks. - if (!emitGetName(cx->names().dotThis)) { + if (!emitGetName(cx->parserNames().dotThis)) { // [stack] ARRAY? FUNC THIS return false; } @@ -9132,7 +9522,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) { return true; } - if (!emitGetName(cx->names().dotStaticInitializers)) { + if (!emitGetName(cx->parserNames().dotStaticInitializers)) { // [stack] CTOR ARRAY return false; } @@ -9180,7 +9570,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) { // Overwrite |.staticInitializers| and |.staticFieldKeys| with undefined to // avoid keeping the arrays alive indefinitely. - auto clearStaticFieldSlot = [&](HandlePropertyName name) { + auto clearStaticFieldSlot = [&](const ParserName* name) { NameOpEmitter noe(this, name, NameOpEmitter::Kind::SimpleAssignment); if (!noe.prepareForRhs()) { // [stack] ENV? VAL? @@ -9205,7 +9595,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) { return true; }; - if (!clearStaticFieldSlot(cx->names().dotStaticInitializers)) { + if (!clearStaticFieldSlot(cx->parserNames().dotStaticInitializers)) { return false; } @@ -9218,7 +9608,7 @@ bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) { if (std::any_of(classMembers->contents().begin(), classMembers->contents().end(), isStaticFieldWithComputedName)) { - if (!clearStaticFieldSlot(cx->names().dotStaticFieldKeys)) { + if (!clearStaticFieldSlot(cx->parserNames().dotStaticFieldKeys)) { return false; } } @@ -9233,12 +9623,12 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitObject(ListNode* objNode, bool isSingletonContext = !objNode->hasNonConstInitializer() && objNode->head() && checkSingletonContext(); - // Note: this method uses the ObjLiteralWriter and emits - // ObjLiteralCreationData objects into the GCThingList, which will evaluate - // them into real GC objects during JSScript::fullyInitFromEmitter. - // Eventually we want OBJLITERAL to be a real opcode, but for now, - // performance constraints limit us to evaluating object literals at the end - // of parse, when we're allowed to allocate GC things. + // Note: this method uses the ObjLiteralWriter and emits ObjLiteralStencil + // objects into the GCThingList, which will evaluate them into real GC objects + // during JSScript::fullyInitFromEmitter. Eventually we want OBJLITERAL to be + // a real opcode, but for now, performance constraints limit us to evaluating + // object literals at the end of parse, when we're allowed to allocate GC + // things. // // There are three cases here, in descending order of preference: // @@ -9424,7 +9814,7 @@ bool BytecodeEmitter::emitArray(ParseNode* arrayHead, uint32_t count, return false; } - bool allowSelfHostedIter = false; + bool allowSelfHostedIterFlag = false; if (elem->isKind(ParseNodeKind::Elision)) { if (!emit1(JSOp::Hole)) { return false; @@ -9434,12 +9824,7 @@ bool BytecodeEmitter::emitArray(ParseNode* arrayHead, uint32_t count, if (elem->isKind(ParseNodeKind::Spread)) { expr = elem->as().kid(); - if (emitterMode == BytecodeEmitter::SelfHosting && - expr->isKind(ParseNodeKind::CallExpr) && - expr->as().left()->isName( - cx->names().allowContentIter)) { - allowSelfHostedIter = true; - } + allowSelfHostedIterFlag = allowSelfHostedIter(expr); } else { expr = elem; } @@ -9461,7 +9846,7 @@ bool BytecodeEmitter::emitArray(ParseNode* arrayHead, uint32_t count, // [stack] NEXT ITER ARRAY INDEX return false; } - if (!emitSpread(allowSelfHostedIter)) { + if (!emitSpread(allowSelfHostedIterFlag)) { // [stack] ARRAY INDEX return false; } @@ -9590,7 +9975,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) { return false; } } else { - RootedAtom paramName(cx, bindingElement->as().name()); + const ParserName* paramName = bindingElement->as().name(); if (!fpe.emitRest(paramName)) { // [stack] return false; @@ -9649,7 +10034,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) { // [stack] return false; } - RootedAtom paramName(cx, bindingElement->as().name()); + const ParserAtom* paramName = bindingElement->as().name(); if (!fpe.emitDefaultEnd(paramName)) { // [stack] return false; @@ -9658,7 +10043,7 @@ bool BytecodeEmitter::emitFunctionFormalParameters(ListNode* paramsBody) { continue; } - RootedAtom paramName(cx, bindingElement->as().name()); + const ParserAtom* paramName = bindingElement->as().name(); if (!fpe.emitSimple(paramName)) { // [stack] return false; @@ -9673,36 +10058,36 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() { // [stack] - auto emitInitializeFunctionSpecialName = - [](BytecodeEmitter* bce, HandlePropertyName name, JSOp op) { - // A special name must be slotful, either on the frame or on the - // call environment. - MOZ_ASSERT(bce->lookupName(name).hasKnownSlot()); + auto emitInitializeFunctionSpecialName = [](BytecodeEmitter* bce, + const ParserName* name, JSOp op) { + // A special name must be slotful, either on the frame or on the + // call environment. + MOZ_ASSERT(bce->lookupName(name).hasKnownSlot()); - NameOpEmitter noe(bce, name, NameOpEmitter::Kind::Initialize); - if (!noe.prepareForRhs()) { - // [stack] - return false; - } - if (!bce->emit1(op)) { - // [stack] THIS/ARGUMENTS - return false; - } - if (!noe.emitAssignment()) { - // [stack] THIS/ARGUMENTS - return false; - } - if (!bce->emit1(JSOp::Pop)) { - // [stack] - return false; - } + NameOpEmitter noe(bce, name, NameOpEmitter::Kind::Initialize); + if (!noe.prepareForRhs()) { + // [stack] + return false; + } + if (!bce->emit1(op)) { + // [stack] THIS/ARGUMENTS + return false; + } + if (!noe.emitAssignment()) { + // [stack] THIS/ARGUMENTS + return false; + } + if (!bce->emit1(JSOp::Pop)) { + // [stack] + return false; + } - return true; - }; + return true; + }; // Do nothing if the function doesn't have an arguments binding. if (funbox->argumentsHasVarBinding()) { - if (!emitInitializeFunctionSpecialName(this, cx->names().arguments, + if (!emitInitializeFunctionSpecialName(this, cx->parserNames().arguments, JSOp::Arguments)) { // [stack] return false; @@ -9713,7 +10098,7 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() { // happens for instance if it doesn't use this/eval or if it's an // arrow function). if (funbox->functionHasThisBinding()) { - if (!emitInitializeFunctionSpecialName(this, cx->names().dotThis, + if (!emitInitializeFunctionSpecialName(this, cx->parserNames().dotThis, JSOp::FunctionThis)) { return false; } @@ -9721,7 +10106,7 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() { // Do nothing if the function doesn't implicitly return a promise result. if (funbox->needsPromiseResult()) { - if (!emitInitializeFunctionSpecialName(this, cx->names().dotGenerator, + if (!emitInitializeFunctionSpecialName(this, cx->parserNames().dotGenerator, JSOp::Generator)) { // [stack] return false; @@ -9731,11 +10116,10 @@ bool BytecodeEmitter::emitInitializeFunctionSpecialNames() { } bool BytecodeEmitter::emitLexicalInitialization(NameNode* name) { - RootedAtom nameAtom(cx, name->name()); - return emitLexicalInitialization(nameAtom); + return emitLexicalInitialization(name->name()); } -bool BytecodeEmitter::emitLexicalInitialization(Handle name) { +bool BytecodeEmitter::emitLexicalInitialization(const ParserAtom* name) { NameOpEmitter noe(this, name, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { return false; @@ -9766,7 +10150,7 @@ static MOZ_ALWAYS_INLINE ParseNode* FindConstructor(JSContext* cx, if (!method.isStatic() && (methodName.isKind(ParseNodeKind::ObjectPropertyName) || methodName.isKind(ParseNodeKind::StringExpr)) && - methodName.as().atom() == cx->names().constructor) { + methodName.as().atom() == cx->parserNames().constructor) { return classElement; } } @@ -9774,14 +10158,66 @@ static MOZ_ALWAYS_INLINE ParseNode* FindConstructor(JSContext* cx, return nullptr; } +template +bool BytecodeEmitter::emitNewPrivateNames(ListNode* classMembers) { + for (ParseNode* classElement : classMembers->contents()) { + if (!classElement->is()) { + continue; + } + + ParseNode* elementName = &classElement->as().name(); + if (!elementName->isKind(ParseNodeKind::PrivateName)) { + continue; + } + + const ParserAtom* privateName = elementName->as().name(); + + // TODO: Add a new bytecode to create private names. + if (!emitAtomOp(JSOp::GetIntrinsic, cx->parserNames().NewPrivateName)) { + // [stack] HERITAGE NEWPRIVATENAME + return false; + } + + // Push `undefined` as `this` parameter for call. + if (!emit1(JSOp::Undefined)) { + // [stack] HERITAGE NEWPRIVATENAME UNDEFINED + return false; + } + + if (!emitAtomOp(JSOp::String, privateName)) { + // [stack] HERITAGE NEWPRIVATENAME UNDEFINED NAME + return false; + } + + int argc = 1; + if (!emitCall(JSOp::Call, argc)) { + // [stack] HERITAGE PRIVATENAME + return false; + } + + // Add a binding for #name => privatename + if (!emitLexicalInitialization(privateName)) { + // [stack] HERITAGE PRIVATENAME + return false; + } + + // Pop Private name off the stack. + if (!emit1(JSOp::Pop)) { + // [stack] HERITAGE + return false; + } + } + return true; +} + // This follows ES6 14.5.14 (ClassDefinitionEvaluation) and ES6 14.5.15 // (BindingClassDeclarationEvaluation). bool BytecodeEmitter::emitClass( ClassNode* classNode, ClassNameKind nameKind /* = ClassNameKind::BindingName */, - HandleAtom nameForAnonymousClass /* = nullptr */) { + const ParserAtom* nameForAnonymousClass /* = nullptr */) { MOZ_ASSERT((nameKind == ClassNameKind::InferredName) == - (nameForAnonymousClass != nullptr)); + bool(nameForAnonymousClass)); ParseNode* heritageExpression = classNode->heritage(); ListNode* classMembers = classNode->memberList(); @@ -9793,7 +10229,7 @@ bool BytecodeEmitter::emitClass( // [stack] NAME ClassEmitter ce(this); - RootedAtom innerName(cx); + const ParserAtom* innerName = nullptr; ClassEmitter::Kind kind = ClassEmitter::Kind::Expression; if (ClassNames* names = classNode->names()) { MOZ_ASSERT(nameKind == ClassNameKind::BindingName); @@ -9814,12 +10250,7 @@ bool BytecodeEmitter::emitClass( } } - // This is kind of silly. In order to the get the home object defined on - // the constructor, we have to make it second, but we want the prototype - // on top for EmitPropertyList, because we expect static properties to be - // rarer. The result is a few more swaps than we would like. Such is life. bool isDerived = !!heritageExpression; - bool hasNameOnStack = nameKind == ClassNameKind::ComputedName; if (isDerived) { if (!updateSourceCoordNotes(classNode->pn_pos.begin)) { return false; @@ -9831,6 +10262,27 @@ bool BytecodeEmitter::emitClass( // [stack] HERITAGE return false; } + } + + // The class body scope holds any private names. Those mustn't be visible in + // the heritage expression and hence the scope must be emitted after the + // heritage expression. + if (LexicalScopeNode* bodyScopeBindings = classNode->bodyScopeBindings()) { + if (!ce.emitBodyScope(bodyScopeBindings->scopeBindings())) { + // [stack] HERITAGE + return false; + } + + if (!emitNewPrivateNames(classMembers)) { + return false; + } + if (!emitNewPrivateNames(classMembers)) { + return false; + } + } + + bool hasNameOnStack = nameKind == ClassNameKind::ComputedName; + if (isDerived) { if (!ce.emitDerivedClass(innerName, nameForAnonymousClass, hasNameOnStack)) { // [stack] HERITAGE HOMEOBJ @@ -9857,19 +10309,19 @@ bool BytecodeEmitter::emitClass( MOZ_ASSERT(!constructorScope->isEmptyScope()); MOZ_ASSERT(constructorScope->scopeBindings()->length == 1); MOZ_ASSERT(constructorScope->scopeBindings()->trailingNames[0].name() == - cx->names().dotInitializers); + cx->parserNames().dotInitializers); - auto isInstanceField = [](ParseNode* propdef) { - return propdef->is() && - !propdef->as().isStatic(); + auto needsInitializer = [](ParseNode* propdef) { + return NeedsFieldInitializer(propdef, false) || + NeedsMethodInitializer(propdef, false); }; // As an optimization omit the |.initializers| binding when no instance - // fields are present. - bool hasInstanceFields = + // fields or private methods are present. + bool needsInitializers = std::any_of(classMembers->contents().begin(), - classMembers->contents().end(), isInstanceField); - if (hasInstanceFields) { + classMembers->contents().end(), needsInitializer); + if (needsInitializers) { lse.emplace(this); if (!lse->emitScope(ScopeKind::Lexical, constructorScope->scopeBindings())) { @@ -9877,8 +10329,8 @@ bool BytecodeEmitter::emitClass( } // Any class with field initializers will have a constructor - if (!emitCreateFieldInitializers(ce, classMembers, - FieldPlacement::Instance)) { + if (!emitCreateMemberInitializers(ce, classMembers, + FieldPlacement::Instance)) { return false; } } @@ -9923,7 +10375,7 @@ bool BytecodeEmitter::emitClass( return false; } - if (!emitCreateFieldInitializers(ce, classMembers, FieldPlacement::Static)) { + if (!emitCreateMemberInitializers(ce, classMembers, FieldPlacement::Static)) { return false; } @@ -9964,8 +10416,7 @@ bool BytecodeEmitter::emitExportDefault(BinaryNode* exportNode) { if (valueNode->isDirectRHSAnonFunction()) { MOZ_ASSERT(exportNode->right()); - HandlePropertyName name = cx->names().default_; - if (!emitAnonymousFunctionWithName(valueNode, name)) { + if (!emitAnonymousFunctionWithName(valueNode, cx->parserNames().default_)) { return false; } } else { @@ -10029,7 +10480,8 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitInstrumentationSlow( } // [stack] CALLBACK UNDEFINED - JSAtom* atom = RealmInstrumentation::getInstrumentationKindName(cx, kind); + const ParserAtom* atom = RealmInstrumentation::getInstrumentationKindName( + cx, compilationInfo, kind); if (!atom) { return false; } @@ -10080,7 +10532,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitInstrumentationSlow( } MOZ_NEVER_INLINE bool BytecodeEmitter::emitInstrumentationForOpcodeSlow( - JSOp op, uint32_t atomIndex) { + JSOp op, GCThingIndex atomIndex) { MOZ_ASSERT(instrumentationKinds); switch (op) { @@ -10477,9 +10929,12 @@ bool BytecodeEmitter::emitTree( case ParseNodeKind::ElemExpr: { PropertyByValue* elem = &pn->as(); bool isSuper = elem->isSuper(); - ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get, - isSuper ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + bool isPrivate = elem->key().isKind(ParseNodeKind::PrivateName); + ElemOpEmitter eoe( + this, ElemOpEmitter::Kind::Get, + isSuper ? ElemOpEmitter::ObjKind::Super + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); if (!emitElemObjAndKey(elem, isSuper, eoe)) { // [stack] # if Super // [stack] THIS KEY @@ -10568,6 +11023,12 @@ bool BytecodeEmitter::emitTree( } break; + case ParseNodeKind::PrivateName: + if (!emitGetPrivateName(&pn->as())) { + return false; + } + break; + case ParseNodeKind::TemplateStringListExpr: if (!emitTemplateString(&pn->as())) { return false; @@ -10594,7 +11055,7 @@ bool BytecodeEmitter::emitTree( break; case ParseNodeKind::RegExpExpr: { - uint32_t index; + GCThingIndex index; if (!perScriptData().gcThingList().append(&pn->as(), &index)) { return false; @@ -10778,45 +11239,36 @@ bool BytecodeEmitter::newSrcNoteOperand(ptrdiff_t operand) { return SrcNoteWriter::writeOperand(operand, allocator); } -bool BytecodeEmitter::intoScriptStencil(ScriptStencil* stencil) { - using ImmutableFlags = ImmutableScriptFlagsEnum; - +bool BytecodeEmitter::intoScriptStencil(ScriptStencil* script) { js::UniquePtr immutableScriptData = createImmutableScriptData(cx); if (!immutableScriptData) { return false; } - stencil->immutableFlags = sc->immutableFlags(); - MOZ_ASSERT(outermostScope().hasOnChain(ScopeKind::NonSyntactic) == sc->hasNonSyntacticScope()); - stencil->gcThings = perScriptData().gcThingList().stealGCThings(); + script->gcThings = perScriptData().gcThingList().stealGCThings(); // Hand over the ImmutableScriptData instance generated by BCE. - stencil->immutableScriptData = std::move(immutableScriptData); + script->immutableScriptData = std::move(immutableScriptData); // Update flags specific to functions. if (sc->isFunctionBox()) { FunctionBox* funbox = sc->asFunctionBox(); - stencil->functionIndex.emplace(funbox->index()); - stencil->fieldInitializers = funbox->fieldInitializers; - - // Set flags that don't have direct flag representation within the - // FunctionBox. - stencil->immutableFlags.setFlag(ImmutableFlags::HasMappedArgsObj, - funbox->hasMappedArgsObj()); - - // While IsLikelyConstructorWrapper is required to be the same between - // syntax and normal parsing, BinAST cannot ensure this. Work around this by - // using the existing value if this is delazification. - if (emitterMode != BytecodeEmitter::LazyFunction) { - stencil->immutableFlags.setFlag( - ImmutableFlags::IsLikelyConstructorWrapper, - funbox->isLikelyConstructorWrapper()); - } - } /* isFunctionBox */ + funbox->copyScriptFields(*script); + MOZ_ASSERT(script->isFunction()); + } else { + sc->copyScriptFields(*script); + } return true; } + +bool BytecodeEmitter::allowSelfHostedIter(ParseNode* parseNode) { + return emitterMode == BytecodeEmitter::SelfHosting && + parseNode->isKind(ParseNodeKind::CallExpr) && + parseNode->as().left()->isName( + cx->parserNames().allowContentIter); +} diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index a520029717..7e46392956 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -19,7 +19,7 @@ #include "jsapi.h" // CompletionKind -#include "frontend/AbstractScopePtr.h" +#include "frontend/AbstractScopePtr.h" // ScopeIndex #include "frontend/BCEParserHandle.h" // BCEParserHandle #include "frontend/BytecodeControlStructures.h" // NestableControl #include "frontend/BytecodeOffset.h" // BytecodeOffset @@ -40,6 +40,7 @@ #include "frontend/ValueUsage.h" // ValueUsage #include "js/RootingAPI.h" // JS::Rooted, JS::Handle #include "js/TypeDecls.h" // jsbytecode +#include "vm/BuiltinObjectKind.h" // BuiltinObjectKind #include "vm/BytecodeUtil.h" // JSOp #include "vm/CheckIsObjectKind.h" // CheckIsObjectKind #include "vm/FunctionPrefixKind.h" // FunctionPrefixKind @@ -47,10 +48,12 @@ #include "vm/Instrumentation.h" // InstrumentationKind #include "vm/Iteration.h" // IteratorKind #include "vm/JSFunction.h" // JSFunction -#include "vm/JSScript.h" // JSScript, BaseScript, FieldInitializers -#include "vm/Runtime.h" // ReportOutOfMemory -#include "vm/StencilEnums.h" // TryNoteKind -#include "vm/StringType.h" // JSAtom +#include "vm/JSScript.h" // JSScript, BaseScript, MemberInitializers +#include "vm/Runtime.h" // ReportOutOfMemory +#include "vm/SharedStencil.h" // GCThingIndex +#include "vm/StencilEnums.h" // TryNoteKind +#include "vm/StringType.h" // JSAtom +#include "vm/ThrowMsgKind.h" // ThrowMsgKind, ThrowCondition namespace js { namespace frontend { @@ -102,11 +105,12 @@ struct MOZ_STACK_CLASS BytecodeEmitter { BCEParserHandle* parser = nullptr; CompilationInfo& compilationInfo; + CompilationState& compilationState; uint32_t maxFixedSlots = 0; /* maximum number of fixed frame slots so far */ - uint32_t bodyScopeIndex = - UINT32_MAX; /* index into scopeList of the body scope */ + // Index into scopeList of the body scope. + GCThingIndex bodyScopeIndex = ScopeNote::NoScopeIndex; EmitterScope* varEmitterScope = nullptr; NestableControl* innermostNestableControl = nullptr; @@ -166,7 +170,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter { private: // Internal constructor, for delegation use only. BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc, - CompilationInfo& compilationInfo, EmitterMode emitterMode); + CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode); void initFromBodyPosition(TokenPos bodyPosition); @@ -182,19 +187,22 @@ struct MOZ_STACK_CLASS BytecodeEmitter { public: BytecodeEmitter(BytecodeEmitter* parent, BCEParserHandle* handle, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode = Normal); BytecodeEmitter(BytecodeEmitter* parent, const EitherParser& parser, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode = Normal); template BytecodeEmitter(BytecodeEmitter* parent, Parser* parser, SharedContext* sc, CompilationInfo& compilationInfo, + CompilationState& compilationState, EmitterMode emitterMode = Normal) : BytecodeEmitter(parent, EitherParser(parser), sc, compilationInfo, - emitterMode) {} + compilationState, emitterMode) {} MOZ_MUST_USE bool init(); MOZ_MUST_USE bool init(TokenPos bodyPosition); @@ -205,22 +213,22 @@ struct MOZ_STACK_CLASS BytecodeEmitter { template bool */> T* findInnermostNestableControl(Predicate predicate) const; - NameLocation lookupName(JSAtom* name); + NameLocation lookupName(const ParserAtom* name); // To implement Annex B and the formal parameter defaults scope semantics // requires accessing names that would otherwise be shadowed. This method // returns the access location of a name that is known to be bound in a // target scope. - mozilla::Maybe locationOfNameBoundInScope(JSAtom* name, - EmitterScope* target); + mozilla::Maybe locationOfNameBoundInScope( + const ParserAtom* name, EmitterScope* target); // Get the location of a name known to be bound in the function scope, // starting at the source scope. mozilla::Maybe locationOfNameBoundInFunctionScope( - JSAtom* name, EmitterScope* source); + const ParserAtom* name, EmitterScope* source); mozilla::Maybe locationOfNameBoundInFunctionScope( - JSAtom* name) { + const ParserAtom* name) { return locationOfNameBoundInFunctionScope(name, innermostEmitterScope()); } @@ -234,25 +242,25 @@ struct MOZ_STACK_CLASS BytecodeEmitter { return perScriptData().gcThingList().firstScope(); } AbstractScopePtr innermostScope() const; - AbstractScopePtr bodyScope() const { - return perScriptData().gcThingList().getScope(bodyScopeIndex); - } + ScopeIndex innermostScopeIndex() const; - MOZ_ALWAYS_INLINE - MOZ_MUST_USE bool makeAtomIndex(JSAtom* atom, uint32_t* indexp) { + MOZ_ALWAYS_INLINE MOZ_MUST_USE bool makeAtomIndex(const ParserAtom* atom, + GCThingIndex* indexp) { MOZ_ASSERT(perScriptData().atomIndices()); AtomIndexMap::AddPtr p = perScriptData().atomIndices()->lookupForAdd(atom); if (p) { - *indexp = p->value(); + *indexp = GCThingIndex(p->value()); return true; } - uint32_t index; + GCThingIndex index; if (!perScriptData().gcThingList().append(atom, &index)) { return false; } - if (!perScriptData().atomIndices()->add(p, atom, index)) { + // `atomIndices()` uses uint32_t instead of GCThingIndex, because + // GCThingIndex isn't trivial type. + if (!perScriptData().atomIndices()->add(p, atom, index.index)) { ReportOutOfMemory(cx); return false; } @@ -299,7 +307,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter { unsigned errorNumber, ...); // Fill in a ScriptStencil using this BCE data. - bool intoScriptStencil(ScriptStencil* stencil); + bool intoScriptStencil(ScriptStencil* script); // If pn contains a useful expression, return true with *answer set to true. // If pn contains a useless expression, return true with *answer set to @@ -401,6 +409,9 @@ struct MOZ_STACK_CLASS BytecodeEmitter { // Helper to emit JSOp::CheckIsObj. MOZ_MUST_USE bool emitCheckIsObj(CheckIsObjectKind kind); + // Helper to emit JSOp::BuiltinObject. + MOZ_MUST_USE bool emitBuiltinObject(BuiltinObjectKind kind); + // Push whether the value atop of the stack is non-undefined and non-null. MOZ_MUST_USE bool emitPushNotUndefinedOrNull(); @@ -446,23 +457,24 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitGoto(NestableControl* target, JumpList* jumplist, GotoKind kind); - MOZ_MUST_USE bool emitIndexOp(JSOp op, uint32_t index); + MOZ_MUST_USE bool emitGCIndexOp(JSOp op, GCThingIndex index); MOZ_MUST_USE bool emitAtomOp( - JSOp op, JSAtom* atom, + JSOp op, const ParserAtom* atom, ShouldInstrument shouldInstrument = ShouldInstrument::No); MOZ_MUST_USE bool emitAtomOp( - JSOp op, uint32_t atomIndex, + JSOp op, GCThingIndex atomIndex, ShouldInstrument shouldInstrument = ShouldInstrument::No); MOZ_MUST_USE bool emitArrayLiteral(ListNode* array); MOZ_MUST_USE bool emitArray(ParseNode* arrayHead, uint32_t count, bool isInner = false); - MOZ_MUST_USE bool emitInternedScopeOp(uint32_t index, JSOp op); - MOZ_MUST_USE bool emitInternedObjectOp(uint32_t index, JSOp op); - MOZ_MUST_USE bool emitObjectPairOp(uint32_t index1, uint32_t index2, JSOp op); - MOZ_MUST_USE bool emitRegExp(uint32_t index); + MOZ_MUST_USE bool emitInternedScopeOp(GCThingIndex index, JSOp op); + MOZ_MUST_USE bool emitInternedObjectOp(GCThingIndex index, JSOp op); + MOZ_MUST_USE bool emitObjectPairOp(GCThingIndex index1, GCThingIndex index2, + JSOp op); + MOZ_MUST_USE bool emitRegExp(GCThingIndex index); MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction( FunctionNode* funNode, bool needsProto = false, @@ -493,20 +505,27 @@ struct MOZ_STACK_CLASS BytecodeEmitter { // Is a field value OBJLITERAL-compatible? MOZ_MUST_USE bool isRHSObjLiteralCompatible(ParseNode* value); - MOZ_MUST_USE bool emitObjLiteralValue(ObjLiteralCreationData* data, + MOZ_MUST_USE bool emitObjLiteralValue(ObjLiteralStencil* data, ParseNode* value); enum class FieldPlacement { Instance, Static }; - mozilla::Maybe setupFieldInitializers( + mozilla::Maybe setupMemberInitializers( ListNode* classMembers, FieldPlacement placement); MOZ_MUST_USE bool emitCreateFieldKeys(ListNode* obj, FieldPlacement placement); - MOZ_MUST_USE bool emitCreateFieldInitializers(ClassEmitter& ce, ListNode* obj, - FieldPlacement placement); - const FieldInitializers& findFieldInitializersForCall(); - MOZ_MUST_USE bool emitInitializeInstanceFields(); + MOZ_MUST_USE bool emitCreateMemberInitializers(ClassEmitter& ce, + ListNode* obj, + FieldPlacement placement); + const MemberInitializers& findMemberInitializersForCall(); + MOZ_MUST_USE bool emitInitializeInstanceMembers(); MOZ_MUST_USE bool emitInitializeStaticFields(ListNode* classMembers); + MOZ_MUST_USE bool emitPrivateMethodInitializers(ClassEmitter& ce, + ListNode* obj); + MOZ_MUST_USE bool emitPrivateMethodInitializer( + ClassEmitter& ce, ParseNode* prop, ParseNode* propName, + const ParserAtom* storedMethodAtom, AccessorType accessorType); + // To catch accidental misuse, emitUint16Operand/emit3 assert that they are // not used to unconditionally emit JSOp::GetLocal. Variable access should // instead be emitted using EmitVarOp. In special cases, when the caller @@ -517,21 +536,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitArgOp(JSOp op, uint16_t slot); MOZ_MUST_USE bool emitEnvCoordOp(JSOp op, EnvironmentCoordinate ec); - MOZ_MUST_USE bool emitGetNameAtLocation(Handle name, + MOZ_MUST_USE bool emitGetNameAtLocation(const ParserAtom* name, const NameLocation& loc); - MOZ_MUST_USE bool emitGetNameAtLocation(ImmutablePropertyNamePtr name, - const NameLocation& loc) { - return emitGetNameAtLocation(name.toHandle(), loc); - } - MOZ_MUST_USE bool emitGetName(Handle name) { - return emitGetNameAtLocation(name, lookupName(name)); - } - MOZ_MUST_USE bool emitGetName(ImmutablePropertyNamePtr name) { + MOZ_MUST_USE bool emitGetName(const ParserAtom* name) { return emitGetNameAtLocation(name, lookupName(name)); } MOZ_MUST_USE bool emitGetName(NameNode* name); + MOZ_MUST_USE bool emitGetPrivateName(NameNode* name); + MOZ_MUST_USE bool emitGetPrivateName(const ParserAtom* name); - MOZ_MUST_USE bool emitTDZCheckIfNeeded(HandleAtom name, + MOZ_MUST_USE bool emitTDZCheckIfNeeded(const ParserAtom* name, const NameLocation& loc, ValueIsOnStack isOnStack); @@ -541,12 +555,12 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitSingleDeclaration(ListNode* declList, NameNode* decl, ParseNode* initializer); MOZ_MUST_USE bool emitAssignmentRhs(ParseNode* rhs, - HandleAtom anonFunctionName); + const ParserAtom* anonFunctionName); MOZ_MUST_USE bool emitAssignmentRhs(uint8_t offset); MOZ_MUST_USE bool emitPrepareIteratorResult(); MOZ_MUST_USE bool emitFinishIteratorResult(bool done); - MOZ_MUST_USE bool iteratorResultShape(uint32_t* shape); + MOZ_MUST_USE bool iteratorResultShape(GCThingIndex* shape); MOZ_MUST_USE bool emitGetDotGeneratorInInnermostScope() { return emitGetDotGeneratorInScope(*innermostEmitterScope()); @@ -676,16 +690,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitDefault(ParseNode* defaultExpr, ParseNode* pattern); MOZ_MUST_USE bool emitAnonymousFunctionWithName(ParseNode* node, - JS::Handle name); + const ParserAtom* name); MOZ_MUST_USE bool emitAnonymousFunctionWithComputedName( ParseNode* node, FunctionPrefixKind prefixKind); - MOZ_MUST_USE bool setFunName(FunctionBox* fun, JSAtom* name); + MOZ_MUST_USE bool setFunName(FunctionBox* fun, const ParserAtom* name); MOZ_MUST_USE bool emitInitializer(ParseNode* initializer, ParseNode* pattern); MOZ_MUST_USE bool emitCallSiteObjectArray(ListNode* cookedOrRaw, - uint32_t* arrayIndex); + GCThingIndex* arrayIndex); MOZ_MUST_USE bool emitCallSiteObject(CallSiteNode* callSiteObj); MOZ_MUST_USE bool emitTemplateString(ListNode* templateString); MOZ_MUST_USE bool emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs, @@ -757,8 +771,12 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitSelfHostedGetPropertySuper(BinaryNode* callNode); MOZ_MUST_USE bool emitSelfHostedHasOwn(BinaryNode* callNode); MOZ_MUST_USE bool emitSelfHostedToNumeric(BinaryNode* callNode); + MOZ_MUST_USE bool emitSelfHostedToString(BinaryNode* callNode); + MOZ_MUST_USE bool emitSelfHostedGetBuiltinConstructor(BinaryNode* callNode); + MOZ_MUST_USE bool emitSelfHostedGetBuiltinPrototype(BinaryNode* callNode); #ifdef DEBUG MOZ_MUST_USE bool checkSelfHostedUnsafeGetReservedSlot(BinaryNode* callNode); + MOZ_MUST_USE bool checkSelfHostedUnsafeSetReservedSlot(BinaryNode* callNode); #endif MOZ_MUST_USE bool emitDo(BinaryNode* doNode); @@ -775,13 +793,13 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitInitializeForInOrOfTarget(TernaryNode* forHead); - MOZ_MUST_USE bool emitBreak(PropertyName* label); - MOZ_MUST_USE bool emitContinue(PropertyName* label); + MOZ_MUST_USE bool emitBreak(const ParserName* label); + MOZ_MUST_USE bool emitContinue(const ParserName* label); MOZ_MUST_USE bool emitFunctionFormalParameters(ListNode* paramsBody); MOZ_MUST_USE bool emitInitializeFunctionSpecialNames(); MOZ_MUST_USE bool emitLexicalInitialization(NameNode* name); - MOZ_MUST_USE bool emitLexicalInitialization(Handle name); + MOZ_MUST_USE bool emitLexicalInitialization(const ParserAtom* name); // Emit bytecode for the spread operator. // @@ -806,7 +824,8 @@ struct MOZ_STACK_CLASS BytecodeEmitter { MOZ_MUST_USE bool emitClass( ClassNode* classNode, ClassNameKind nameKind = ClassNameKind::BindingName, - JS::Handle nameForAnonymousClass = nullptr); + const ParserAtom* nameForAnonymousClass = nullptr); + MOZ_MUST_USE bool emitSuperElemOperands( PropertyByValue* elem, EmitElemOption opts = EmitElemOption::Get); MOZ_MUST_USE bool emitSuperGetElem(PropertyByValue* elem, @@ -828,13 +847,23 @@ struct MOZ_STACK_CLASS BytecodeEmitter { emit1(JSOp::RetRval); } + MOZ_MUST_USE bool emitCheckPrivateField(ThrowCondition throwCondition, + ThrowMsgKind msgKind) { + return emit3(JSOp::CheckPrivateField, uint8_t(throwCondition), + uint8_t(msgKind)); + } + + template + MOZ_MUST_USE bool emitNewPrivateNames(ListNode* classMembers); + MOZ_MUST_USE bool emitInstrumentation(InstrumentationKind kind, uint32_t npopped = 0) { return MOZ_LIKELY(!instrumentationKinds) || emitInstrumentationSlow(kind, std::function()); } - MOZ_MUST_USE bool emitInstrumentationForOpcode(JSOp op, uint32_t atomIndex) { + MOZ_MUST_USE bool emitInstrumentationForOpcode(JSOp op, + GCThingIndex atomIndex) { return MOZ_LIKELY(!instrumentationKinds) || emitInstrumentationForOpcodeSlow(op, atomIndex); } @@ -847,7 +876,12 @@ struct MOZ_STACK_CLASS BytecodeEmitter { InstrumentationKind kind, const std::function& pushOperandsCallback); MOZ_MUST_USE bool emitInstrumentationForOpcodeSlow(JSOp op, - uint32_t atomIndex); + GCThingIndex atomIndex); + + MOZ_MUST_USE bool allowSelfHostedIter(ParseNode* parseNode); + + MOZ_MUST_USE bool emitSelfHostedGetBuiltinConstructorOrPrototype( + BinaryNode* callNode, bool isConstructor); }; class MOZ_RAII AutoCheckUnstableEmitterScope { diff --git a/js/src/frontend/BytecodeSection.cpp b/js/src/frontend/BytecodeSection.cpp index 8afc9dc0e8..b1e2e14cb5 100644 --- a/js/src/frontend/BytecodeSection.cpp +++ b/js/src/frontend/BytecodeSection.cpp @@ -7,37 +7,53 @@ #include "mozilla/Assertions.h" // MOZ_ASSERT #include "mozilla/ReverseIterator.h" // mozilla::Reversed +#include "frontend/AbstractScopePtr.h" // ScopeIndex #include "frontend/CompilationInfo.h" #include "frontend/SharedContext.h" // FunctionBox -#include "frontend/Stencil.h" // ScopeCreationData #include "vm/BytecodeUtil.h" // INDEX_LIMIT, StackUses, StackDefs #include "vm/GlobalObject.h" #include "vm/JSContext.h" // JSContext #include "vm/RegExpObject.h" // RegexpObject +#include "vm/Scope.h" // GlobalScope using namespace js; using namespace js::frontend; -bool GCThingList::append(FunctionBox* funbox, uint32_t* index) { +bool GCThingList::append(FunctionBox* funbox, GCThingIndex* index) { // Append the function to the vector and return the index in *index. - *index = vector.length(); + *index = GCThingIndex(vector.length()); - // To avoid circular include issues, funbox can't return a FunctionIndex, so - // instead it returns a size_t, which we wrap in FunctionIndex here to - // disambiguate the variant. - return vector.append(mozilla::AsVariant(FunctionIndex(funbox->index()))); + if (!vector.append(mozilla::AsVariant(funbox->index()))) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } AbstractScopePtr GCThingList::getScope(size_t index) const { const ScriptThingVariant& elem = vector[index]; if (elem.is()) { - return AbstractScopePtr(&compilationInfo.cx->global()->emptyGlobalScope()); + // The empty enclosing scope should be stored by + // CompilationInput::initForSelfHostingGlobal. + MOZ_ASSERT(compilationInfo.input.enclosingScope); + MOZ_ASSERT( + !compilationInfo.input.enclosingScope->as().hasBindings()); + return AbstractScopePtr(compilationInfo.input.enclosingScope); } return AbstractScopePtr(compilationInfo, elem.as()); } +mozilla::Maybe GCThingList::getScopeIndex(size_t index) const { + const ScriptThingVariant& elem = vector[index]; + if (elem.is()) { + return mozilla::Nothing(); + } + return mozilla::Some(vector[index].as()); +} + bool js::frontend::EmitScriptThingsVector(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput, const ScriptThingsVector& objects, mozilla::Span output) { MOZ_ASSERT(objects.length() <= INDEX_LIMIT); @@ -46,12 +62,17 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, struct Matcher { JSContext* cx; CompilationInfo& compilationInfo; + CompilationGCOutput& gcOutput; uint32_t i; mozilla::Span& output; bool operator()(const ScriptAtom& data) { - JSAtom* atom = data; - output[i] = JS::GCCellPtr(atom); + auto maybeAtom = data->toJSAtom(cx, compilationInfo); + if (maybeAtom.isErr()) { + return false; + } + MOZ_ASSERT(maybeAtom.unwrap()); + output[i] = JS::GCCellPtr(maybeAtom.unwrap()); return true; } @@ -61,7 +82,7 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, } bool operator()(const BigIntIndex& index) { - BigIntCreationData& data = compilationInfo.bigIntData[index]; + BigIntStencil& data = compilationInfo.stencil.bigIntData[index]; BigInt* bi = data.createBigInt(cx); if (!bi) { return false; @@ -71,7 +92,7 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, } bool operator()(const RegExpIndex& rindex) { - RegExpCreationData& data = compilationInfo.regExpData[rindex]; + RegExpStencil& data = compilationInfo.stencil.regExpData[rindex]; RegExpObject* regexp = data.createRegExp(cx); if (!regexp) { return false; @@ -80,8 +101,9 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, return true; } - bool operator()(const ObjLiteralCreationData& data) { - JSObject* obj = data.create(cx); + bool operator()(const ObjLiteralIndex& index) { + ObjLiteralStencil& data = compilationInfo.stencil.objLiteralData[index]; + JSObject* obj = data.create(cx, compilationInfo); if (!obj) { return false; } @@ -90,23 +112,12 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, } bool operator()(const ScopeIndex& index) { - MutableHandle data = - compilationInfo.scopeCreationData[index]; - Scope* scope = data.get().createScope(cx); - if (!scope) { - return false; - } - - output[i] = JS::GCCellPtr(scope); + output[i] = JS::GCCellPtr(gcOutput.scopes[index].get()); return true; } bool operator()(const FunctionIndex& index) { - // We should have already converted this data to a JSFunction as part - // of publishDeferredFunctions, which currently happens before BCE begins. - // Once we can do LazyScriptCreationData::create without referencing the - // functionbox, then we should be able to do JSFunction allocation here. - output[i] = JS::GCCellPtr(compilationInfo.functions[index]); + output[i] = JS::GCCellPtr(gcOutput.functions[index]); return true; } @@ -118,7 +129,7 @@ bool js::frontend::EmitScriptThingsVector(JSContext* cx, }; for (uint32_t i = 0; i < objects.length(); i++) { - Matcher m{cx, compilationInfo, i, output}; + Matcher m{cx, compilationInfo, gcOutput, i, output}; if (!objects[i].match(m)) { return false; } @@ -139,7 +150,7 @@ bool CGTryNoteList::append(TryNoteKind kind, uint32_t stackDepth, return list.append(note); } -bool CGScopeNoteList::append(uint32_t scopeIndex, BytecodeOffset offset, +bool CGScopeNoteList::append(GCThingIndex scopeIndex, BytecodeOffset offset, uint32_t parent) { ScopeNote note; note.index = scopeIndex; @@ -165,8 +176,9 @@ void CGScopeNoteList::recordEndImpl(uint32_t index, uint32_t offset) { list[index].length = offset - list[index].start; } -JSObject* ObjLiteralCreationData::create(JSContext* cx) const { - return InterpretObjLiteral(cx, atoms_, writer_); +JSObject* ObjLiteralStencil::create(JSContext* cx, + CompilationInfo& compilationInfo) const { + return InterpretObjLiteral(cx, compilationInfo, atoms_, writer_); } BytecodeSection::BytecodeSection(JSContext* cx, uint32_t lineNum) diff --git a/js/src/frontend/BytecodeSection.h b/js/src/frontend/BytecodeSection.h index 46c8998ebd..5d2797a10a 100644 --- a/js/src/frontend/BytecodeSection.h +++ b/js/src/frontend/BytecodeSection.h @@ -15,12 +15,12 @@ #include "jstypes.h" // JS_PUBLIC_API #include "NamespaceImports.h" // ValueVector -#include "frontend/AbstractScopePtr.h" // AbstractScopePtr +#include "frontend/AbstractScopePtr.h" // AbstractScopePtr, ScopeIndex #include "frontend/BytecodeOffset.h" // BytecodeOffset -#include "frontend/CompilationInfo.h" // CompilationInfo +#include "frontend/CompilationInfo.h" // CompilationInfo, CompilationGCOutput #include "frontend/JumpList.h" // JumpTarget #include "frontend/NameCollections.h" // AtomIndexMap, PooledMapPtr -#include "frontend/ObjLiteral.h" // ObjLiteralCreationData +#include "frontend/ObjLiteral.h" // ObjLiteralStencil #include "frontend/ParseNode.h" // BigIntLiteral #include "frontend/SourceNotes.h" // SrcNote #include "frontend/Stencil.h" // Stencils @@ -32,7 +32,7 @@ #include "js/Value.h" // JS::Vector #include "js/Vector.h" // Vector #include "vm/Opcodes.h" // JSOpLength_JumpTarget -#include "vm/SharedStencil.h" // TryNote, ScopeNote +#include "vm/SharedStencil.h" // TryNote, ScopeNote, GCThingIndex #include "vm/StencilEnums.h" // TryNoteKind namespace js { @@ -44,22 +44,28 @@ namespace frontend { class FunctionBox; struct MOZ_STACK_CLASS GCThingList { + JSContext* cx; CompilationInfo& compilationInfo; ScriptThingsVector vector; // Index of the first scope in the vector. - mozilla::Maybe firstScopeIndex; + mozilla::Maybe firstScopeIndex; explicit GCThingList(JSContext* cx, CompilationInfo& compilationInfo) - : compilationInfo(compilationInfo), vector(cx) {} + : cx(cx), compilationInfo(compilationInfo) {} - MOZ_MUST_USE bool append(JSAtom* atom, uint32_t* index) { - *index = vector.length(); - return vector.append(mozilla::AsVariant(std::move(atom))); + MOZ_MUST_USE bool append(const ParserAtom* atom, GCThingIndex* index) { + *index = GCThingIndex(vector.length()); + if (!vector.append(mozilla::AsVariant(std::move(atom)))) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } - MOZ_MUST_USE bool append(ScopeIndex scope, uint32_t* index) { - *index = vector.length(); + MOZ_MUST_USE bool append(ScopeIndex scope, GCThingIndex* index) { + *index = GCThingIndex(vector.length()); if (!vector.append(mozilla::AsVariant(scope))) { + js::ReportOutOfMemory(cx); return false; } if (!firstScopeIndex) { @@ -67,24 +73,37 @@ struct MOZ_STACK_CLASS GCThingList { } return true; } - MOZ_MUST_USE bool append(BigIntLiteral* literal, uint32_t* index) { - *index = vector.length(); - return vector.append(mozilla::AsVariant(literal->index())); + MOZ_MUST_USE bool append(BigIntLiteral* literal, GCThingIndex* index) { + *index = GCThingIndex(vector.length()); + if (!vector.append(mozilla::AsVariant(literal->index()))) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } - MOZ_MUST_USE bool append(RegExpLiteral* literal, uint32_t* index) { - *index = vector.length(); - return vector.append(mozilla::AsVariant(literal->index())); + MOZ_MUST_USE bool append(RegExpLiteral* literal, GCThingIndex* index) { + *index = GCThingIndex(vector.length()); + if (!vector.append(mozilla::AsVariant(literal->index()))) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } - MOZ_MUST_USE bool append(ObjLiteralCreationData&& objlit, uint32_t* index) { - *index = vector.length(); - return vector.append(mozilla::AsVariant(std::move(objlit))); + MOZ_MUST_USE bool append(ObjLiteralIndex objlit, GCThingIndex* index) { + *index = GCThingIndex(vector.length()); + if (!vector.append(mozilla::AsVariant(objlit))) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } - MOZ_MUST_USE bool append(FunctionBox* funbox, uint32_t* index); + MOZ_MUST_USE bool append(FunctionBox* funbox, GCThingIndex* index); - MOZ_MUST_USE bool appendEmptyGlobalScope(uint32_t* index) { - *index = vector.length(); + MOZ_MUST_USE bool appendEmptyGlobalScope(GCThingIndex* index) { + *index = GCThingIndex(vector.length()); EmptyGlobalScopeType emptyGlobalScope; if (!vector.append(mozilla::AsVariant(emptyGlobalScope))) { + js::ReportOutOfMemory(cx); return false; } if (!firstScopeIndex) { @@ -99,6 +118,10 @@ struct MOZ_STACK_CLASS GCThingList { AbstractScopePtr getScope(size_t index) const; + // Index of scope within CompilationInfo or Nothing is the scope is + // EmptyGlobalScopeType. + mozilla::Maybe getScopeIndex(size_t index) const; + AbstractScopePtr firstScope() const { MOZ_ASSERT(firstScopeIndex.isSome()); return getScope(*firstScopeIndex); @@ -109,6 +132,7 @@ struct MOZ_STACK_CLASS GCThingList { MOZ_MUST_USE bool EmitScriptThingsVector(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput, const ScriptThingsVector& objects, mozilla::Span output); @@ -128,7 +152,7 @@ struct CGScopeNoteList { Vector list; explicit CGScopeNoteList(JSContext* cx) : list(cx) {} - MOZ_MUST_USE bool append(uint32_t scopeIndex, BytecodeOffset offset, + MOZ_MUST_USE bool append(GCThingIndex scopeIndex, BytecodeOffset offset, uint32_t parent); void recordEnd(uint32_t index, BytecodeOffset offset); void recordEndFunctionBodyVar(uint32_t index); diff --git a/js/src/frontend/CallOrNewEmitter.cpp b/js/src/frontend/CallOrNewEmitter.cpp index 707e5ba651..09e7a06040 100644 --- a/js/src/frontend/CallOrNewEmitter.cpp +++ b/js/src/frontend/CallOrNewEmitter.cpp @@ -36,7 +36,7 @@ CallOrNewEmitter::CallOrNewEmitter(BytecodeEmitter* bce, JSOp op, MOZ_ASSERT(isCall() || isNew() || isSuperCall()); } -bool CallOrNewEmitter::emitNameCallee(Handle name) { +bool CallOrNewEmitter::emitNameCallee(const ParserAtom* name) { MOZ_ASSERT(state_ == State::Start); NameOpEmitter noe( @@ -65,13 +65,14 @@ MOZ_MUST_USE PropOpEmitter& CallOrNewEmitter::prepareForPropCallee( } MOZ_MUST_USE ElemOpEmitter& CallOrNewEmitter::prepareForElemCallee( - bool isSuperElem) { + bool isSuperElem, bool isPrivate) { MOZ_ASSERT(state_ == State::Start); eoe_.emplace(bce_, isCall() ? ElemOpEmitter::Kind::Call : ElemOpEmitter::Kind::Get, isSuperElem ? ElemOpEmitter::ObjKind::Super - : ElemOpEmitter::ObjKind::Other); + : ElemOpEmitter::ObjKind::Other, + isPrivate ? NameVisibility::Private : NameVisibility::Public); state_ = State::ElemCallee; return *eoe_; diff --git a/js/src/frontend/CallOrNewEmitter.h b/js/src/frontend/CallOrNewEmitter.h index 0b280e1db3..a4afb333c7 100644 --- a/js/src/frontend/CallOrNewEmitter.h +++ b/js/src/frontend/CallOrNewEmitter.h @@ -288,9 +288,10 @@ class MOZ_STACK_CLASS CallOrNewEmitter { } public: - MOZ_MUST_USE bool emitNameCallee(Handle name); + MOZ_MUST_USE bool emitNameCallee(const ParserAtom* name); MOZ_MUST_USE PropOpEmitter& prepareForPropCallee(bool isSuperProp); - MOZ_MUST_USE ElemOpEmitter& prepareForElemCallee(bool isSuperElem); + MOZ_MUST_USE ElemOpEmitter& prepareForElemCallee(bool isSuperElem, + bool isPrivateElem); MOZ_MUST_USE bool prepareForFunctionCallee(); MOZ_MUST_USE bool emitSuperCallee(); MOZ_MUST_USE bool prepareForOtherCallee(); diff --git a/js/src/frontend/CompilationInfo.h b/js/src/frontend/CompilationInfo.h index 36b5d481b0..d125af9981 100644 --- a/js/src/frontend/CompilationInfo.h +++ b/js/src/frontend/CompilationInfo.h @@ -9,7 +9,9 @@ #include "mozilla/RefPtr.h" #include "mozilla/Variant.h" +#include "builtin/ModuleObject.h" #include "ds/LifoAlloc.h" +#include "frontend/ParserAtom.h" #include "frontend/SharedContext.h" #include "frontend/Stencil.h" #include "frontend/UsedNameTracker.h" @@ -20,10 +22,16 @@ #include "js/SourceText.h" #include "js/Vector.h" #include "js/WasmModule.h" +#include "vm/GlobalObject.h" // GlobalObject #include "vm/JSContext.h" +#include "vm/JSFunction.h" // JSFunction +#include "vm/JSScript.h" // SourceExtent #include "vm/Realm.h" namespace js { + +class JSONPrinter; + namespace frontend { // ScopeContext hold information derivied from the scope and environment chains @@ -44,139 +52,357 @@ struct ScopeContext { // scope. bool inWith = false; + // Somewhere on the scope chain this parse is embedded within a class scope. + bool inClass = false; + // Class field initializer info if we are nested within a class constructor. // We may be an combination of arrow and eval context within the constructor. - mozilla::Maybe fieldInitializers = {}; - - explicit ScopeContext(Scope* scope, JSObject* enclosingEnv = nullptr) { + mozilla::Maybe memberInitializers = {}; + + // If this eval is in response to Debugger.Frame.eval, we may have an + // incomplete scope chain. In order to determine a better 'this' binding, as + // well as to ensure we can provide better static error semantics for private + // names, we use the environment chain to attempt to find a more effective + // scope than the enclosing scope. + // If there is no more effective scope, this will just be the scope given in + // the constructor. + JS::Rooted effectiveScope; + + explicit ScopeContext(JSContext* cx, Scope* scope, + JSObject* enclosingEnv = nullptr) + : effectiveScope(cx, determineEffectiveScope(scope, enclosingEnv)) { computeAllowSyntax(scope); - computeThisBinding(scope, enclosingEnv); + computeThisBinding(effectiveScope); computeInWith(scope); computeExternalInitializers(scope); + computeInClass(scope); } private: void computeAllowSyntax(Scope* scope); - void computeThisBinding(Scope* scope, JSObject* environment = nullptr); + void computeThisBinding(Scope* scope); void computeInWith(Scope* scope); void computeExternalInitializers(Scope* scope); + void computeInClass(Scope* scope); + + static Scope* determineEffectiveScope(Scope* scope, JSObject* environment); }; -// CompilationInfo owns a number of pieces of information about script -// compilation as well as controls the lifetime of parse nodes and other data by -// controling the mark and reset of the LifoAlloc. -struct MOZ_RAII CompilationInfo : public JS::CustomAutoRooter { - JSContext* cx; +// Input of the compilation, including source and enclosing context. +struct CompilationInput { const JS::ReadOnlyCompileOptions& options; + // Atoms lowered into or converted from CompilationStencil.parserAtoms. + // + // This field is here instead of in CompilationGCOutput because atoms lowered + // from JSAtom is part of input (enclosing scope bindings, lazy function name, + // etc), and having 2 vectors in both input/output is error prone. + JS::GCVector atoms; + + BaseScript* lazy = nullptr; + + ScriptSourceHolder source_; + + // * If we're compiling standalone function, the non-null enclosing scope of + // the function + // * If we're compiling eval, the non-null enclosing scope of the `eval`. + // * If we're compiling module, null that means empty global scope + // (See EmitterScope::checkEnvironmentChainLength) + // * If we're compiling self-hosted JS, an empty global scope. + // This scope is also used for EmptyGlobalScopeType in + // CompilationStencil.gcThings. + // See the comment in initForSelfHostingGlobal. + // * Null otherwise + Scope* enclosingScope = nullptr; + + explicit CompilationInput(const JS::ReadOnlyCompileOptions& options) + : options(options) {} + + private: + bool initScriptSource(JSContext* cx); + + public: + bool initForGlobal(JSContext* cx) { return initScriptSource(cx); } + + bool initForSelfHostingGlobal(JSContext* cx) { + if (!initScriptSource(cx)) { + return false; + } + + // This enclosing scope is also recorded as EmptyGlobalScopeType in + // CompilationStencil.gcThings even though corresponding ScopeStencil + // isn't generated. + // + // Store the enclosing scope here in order to access it from + // inner scopes' ScopeStencil::enclosing. + enclosingScope = &cx->global()->emptyGlobalScope(); + return true; + } + + bool initForStandaloneFunction(JSContext* cx, + HandleScope functionEnclosingScope) { + if (!initScriptSource(cx)) { + return false; + } + enclosingScope = functionEnclosingScope; + return true; + } + + bool initForEval(JSContext* cx, HandleScope evalEnclosingScope) { + if (!initScriptSource(cx)) { + return false; + } + enclosingScope = evalEnclosingScope; + return true; + } + + bool initForModule(JSContext* cx) { + if (!initScriptSource(cx)) { + return false; + } + // The `enclosingScope` is the emptyGlobalScope. + return true; + } + + void initFromLazy(BaseScript* lazyScript) { + lazy = lazyScript; + enclosingScope = lazy->function()->enclosingScope(); + } + + ScriptSource* source() { return source_.get(); } + + private: + void setSource(ScriptSource* ss) { return source_.reset(ss); } + + public: + template + MOZ_MUST_USE bool assignSource(JSContext* cx, + JS::SourceText& sourceBuffer) { + return source()->assignSource(cx, options, sourceBuffer); + } + + void trace(JSTracer* trc); +} JS_HAZ_GC_POINTER; + +struct MOZ_RAII CompilationState { // Until we have dealt with Atoms in the front end, we need to hold // onto them. - AutoKeepAtoms keepAtoms; - Directives directives; ScopeContext scopeContext; - // List of function contexts for GC tracing. These are allocated in the - // LifoAlloc and still require tracing. - FunctionBox* traceListHead = nullptr; - - // The resulting outermost script for the compilation powered - // by this CompilationInfo. - JS::Rooted script; - JS::Rooted lazy; - UsedNameTracker usedNames; LifoAllocScope& allocScope; - // Hold onto the RegExpCreationData and BigIntCreationData that are allocated - // during parse to ensure correct destruction. - Vector regExpData; - Vector bigIntData; + CompilationState(JSContext* cx, LifoAllocScope& alloc, + const JS::ReadOnlyCompileOptions& options, + Scope* enclosingScope = nullptr, + JSObject* enclosingEnv = nullptr) + : directives(options.forceStrictMode()), + scopeContext(cx, enclosingScope, enclosingEnv), + usedNames(cx), + allocScope(alloc) {} +}; - // A Rooted vector to handle tracing of JSFunction* - // and Atoms within. - JS::RootedVector functions; - JS::RootedVector funcData; +// The top level struct of stencil. +struct CompilationStencil { + // Hold onto the RegExpStencil, BigIntStencil, and ObjLiteralStencil that are + // allocated during parse to ensure correct destruction. + Vector regExpData; + Vector bigIntData; + Vector objLiteralData; - // Stencil for top-level script. This includes standalone functions and - // functions being delazified. - JS::Rooted topLevel; - SourceExtent topLevelExtent = {}; - bool topLevelAsmJS = false; + // Stencil for all function and non-function scripts. The TopLevelIndex is + // reserved for the top-level script. This top-level may or may not be a + // function. + Vector scriptData; // A rooted list of scopes created during this parse. // - // To ensure that ScopeCreationData's destructors fire, and thus our HeapPtr - // barriers, we store the scopeCreationData at this level so that they + // To ensure that ScopeStencil's destructors fire, and thus our HeapPtr + // barriers, we store the scopeData at this level so that they // can be safely destroyed, rather than LifoAllocing them with the rest of // the parser data structures. // // References to scopes are controlled via AbstractScopePtr, which holds onto // an index (and CompilationInfo reference). - JS::RootedVector scopeCreationData; + Vector scopeData; + + // Module metadata if this is a module compile. + StencilModuleMetadata moduleMetadata; // AsmJS modules generated by parsing. - HashMap> asmJS; + HashMap, + mozilla::DefaultHasher, js::SystemAllocPolicy> + asmJS; + + // Table of parser atoms for this compilation. + ParserAtomsTable parserAtoms; + + explicit CompilationStencil(JSRuntime* rt) : parserAtoms(rt) {} +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(js::JSONPrinter& json); +#endif +}; + +// The output of GC allocation from stencil. +struct MOZ_RAII CompilationGCOutput { + // The resulting outermost script for the compilation powered + // by this CompilationInfo. + JS::Rooted script; + + // The resulting module object if there is one. + JS::Rooted module; + + // A Rooted vector to handle tracing of JSFunction* and Atoms within. + // + // If the top level script isn't a function, the item at TopLevelIndex is + // nullptr. + JS::RootedVector functions; + + // References to scopes are controlled via AbstractScopePtr, which holds onto + // an index (and CompilationInfo reference). + JS::RootedVector scopes; + + // The result ScriptSourceObject. This is unused in delazifying parses. JS::Rooted sourceObject; + explicit CompilationGCOutput(JSContext* cx) + : script(cx), module(cx), functions(cx), scopes(cx), sourceObject(cx) {} +}; + +class ScriptStencilIterable { + public: + class ScriptAndFunction { + public: + ScriptStencil& script; + HandleFunction function; + FunctionIndex functionIndex; + + ScriptAndFunction() = delete; + ScriptAndFunction(ScriptStencil& script, HandleFunction function, + FunctionIndex functionIndex) + : script(script), function(function), functionIndex(functionIndex) {} + }; + + class Iterator { + size_t index_ = 0; + CompilationStencil& stencil_; + CompilationGCOutput& gcOutput_; + + Iterator(CompilationStencil& stencil, CompilationGCOutput& gcOutput, + size_t index) + : index_(index), stencil_(stencil), gcOutput_(gcOutput) { + skipNonFunctions(); + } + + public: + explicit Iterator(CompilationStencil& stencil, + CompilationGCOutput& gcOutput) + : stencil_(stencil), gcOutput_(gcOutput) { + skipNonFunctions(); + } + + Iterator operator++() { + next(); + skipNonFunctions(); + return *this; + } + + void next() { + MOZ_ASSERT(index_ < stencil_.scriptData.length()); + index_++; + } + + void skipNonFunctions() { + size_t length = stencil_.scriptData.length(); + while (index_ < length) { + if (stencil_.scriptData[index_].isFunction()) { + return; + } + + index_++; + } + } + + bool operator!=(const Iterator& other) const { + return index_ != other.index_; + } + + ScriptAndFunction operator*() { + ScriptStencil& script = stencil_.scriptData[index_]; + + FunctionIndex functionIndex = FunctionIndex(index_); + return ScriptAndFunction(script, gcOutput_.functions[functionIndex], + functionIndex); + } + + static Iterator end(CompilationStencil& stencil, + CompilationGCOutput& gcOutput) { + return Iterator(stencil, gcOutput, stencil.scriptData.length()); + } + }; + + CompilationStencil& stencil_; + CompilationGCOutput& gcOutput_; + + explicit ScriptStencilIterable(CompilationStencil& stencil, + CompilationGCOutput& gcOutput) + : stencil_(stencil), gcOutput_(gcOutput) {} + + Iterator begin() const { return Iterator(stencil_, gcOutput_); } + + Iterator end() const { return Iterator::end(stencil_, gcOutput_); } +}; + +// Input and output of compilation to stencil. +struct CompilationInfo { + static constexpr FunctionIndex TopLevelIndex = FunctionIndex(0); + + CompilationInput input; + CompilationStencil stencil; + // Track the state of key allocations and roll them back as parts of parsing // get retried. This ensures iteration during stencil instantiation does not // encounter discarded frontend state. struct RewindToken { - FunctionBox* funbox = nullptr; + size_t scriptDataLength = 0; + size_t asmJSCount = 0; }; RewindToken getRewindToken(); void rewind(const RewindToken& pos); // Construct a CompilationInfo - CompilationInfo(JSContext* cx, LifoAllocScope& alloc, - const JS::ReadOnlyCompileOptions& options, - Scope* enclosingScope = nullptr, - JSObject* enclosingEnv = nullptr) - : JS::CustomAutoRooter(cx), - cx(cx), - options(options), - keepAtoms(cx), - directives(options.forceStrictMode()), - scopeContext(enclosingScope, enclosingEnv), - script(cx), - lazy(cx), - usedNames(cx), - allocScope(alloc), - regExpData(cx), - bigIntData(cx), - functions(cx), - funcData(cx), - topLevel(cx), - scopeCreationData(cx), - asmJS(cx), - sourceObject(cx) {} - - bool init(JSContext* cx); - - void initFromLazy(BaseScript* lazy) { - this->lazy = lazy; - this->sourceObject = lazy->sourceObject(); - } + CompilationInfo(JSContext* cx, const JS::ReadOnlyCompileOptions& options) + : input(options), stencil(cx->runtime()) {} - template - MOZ_MUST_USE bool assignSource(JS::SourceText& sourceBuffer) { - return sourceObject->source()->assignSource(cx, options, sourceBuffer); - } + MOZ_MUST_USE bool instantiateStencils(JSContext* cx, + CompilationGCOutput& gcOutput); - MOZ_MUST_USE bool instantiateStencils(); + JSAtom* liftParserAtomToJSAtom(JSContext* cx, const ParserAtom* parserAtom) { + return parserAtom->toJSAtom(cx, *this).unwrapOr(nullptr); + } + const ParserAtom* lowerJSAtomToParserAtom(JSContext* cx, JSAtom* atom) { + auto result = stencil.parserAtoms.internJSAtom(cx, *this, atom); + return result.unwrapOr(nullptr); + } - void trace(JSTracer* trc) final; + // Move constructor is necessary to use Rooted. + CompilationInfo(CompilationInfo&&) = default; - // To avoid any misuses, make sure this is neither copyable, - // movable or assignable. + // To avoid any misuses, make sure this is neither copyable or assignable. CompilationInfo(const CompilationInfo&) = delete; - CompilationInfo(CompilationInfo&&) = delete; CompilationInfo& operator=(const CompilationInfo&) = delete; CompilationInfo& operator=(CompilationInfo&&) = delete; + + ScriptStencilIterable functionScriptStencils(CompilationGCOutput& gcOutput) { + return ScriptStencilIterable(stencil, gcOutput); + } + + void trace(JSTracer* trc); }; } // namespace frontend diff --git a/js/src/frontend/EitherParser.h b/js/src/frontend/EitherParser.h index 4d1412eb0b..6b878afa02 100644 --- a/js/src/frontend/EitherParser.h +++ b/js/src/frontend/EitherParser.h @@ -11,7 +11,6 @@ #define frontend_EitherParser_h #include "mozilla/Attributes.h" -#include "mozilla/Move.h" #include "mozilla/Tuple.h" #include "mozilla/Utf8.h" #include "mozilla/Variant.h" @@ -148,6 +147,15 @@ class EitherParser : public BCEParserHandle { matcher{offset, line, column}; return parser.match(std::move(matcher)); } + + JSAtom* liftParserAtomToJSAtom(const ParserAtom* parserAtom) { + ParserSharedBase& base = parser.match(detail::ParserSharedBaseMatcher()); + return base.liftParserAtomToJSAtom(parserAtom); + } + const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom) { + ParserSharedBase& base = parser.match(detail::ParserSharedBaseMatcher()); + return base.lowerJSAtomToParserAtom(atom); + } }; } /* namespace frontend */ diff --git a/js/src/frontend/ElemOpEmitter.cpp b/js/src/frontend/ElemOpEmitter.cpp index 808ed3f453..6aead813a6 100644 --- a/js/src/frontend/ElemOpEmitter.cpp +++ b/js/src/frontend/ElemOpEmitter.cpp @@ -12,8 +12,13 @@ using namespace js; using namespace js::frontend; -ElemOpEmitter::ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind) - : bce_(bce), kind_(kind), objKind_(objKind) {} +ElemOpEmitter::ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind, + NameVisibility visibility) + : bce_(bce), kind_(kind), objKind_(objKind), visibility_(visibility) { + // Can't access private names of super! + MOZ_ASSERT_IF(visibility == NameVisibility::Private, + objKind != ObjKind::Super); +} bool ElemOpEmitter::prepareForObj() { MOZ_ASSERT(state_ == State::Start); @@ -49,6 +54,59 @@ bool ElemOpEmitter::prepareForKey() { return true; } +bool ElemOpEmitter::emitPrivateGuard() { + MOZ_ASSERT(state_ == State::Key || state_ == State::Rhs); + + if (!isPrivate()) { + return true; + } + + if (isPropInit()) { + // [stack] OBJ KEY + if (!bce_->emitCheckPrivateField(ThrowCondition::ThrowHas, + ThrowMsgKind::PrivateDoubleInit)) { + // [stack] OBJ KEY BOOL + return false; + } + } else { + if (!bce_->emitCheckPrivateField(ThrowCondition::ThrowHasNot, + isPrivateGet() + ? ThrowMsgKind::MissingPrivateOnGet + : ThrowMsgKind::MissingPrivateOnSet)) { + // [stack] OBJ KEY BOOL + return false; + } + } + + // CheckPrivate leaves the result of the HasOwnCheck on the stack. Pop it off. + return bce_->emit1(JSOp::Pop); + // [stack] OBJ KEY +} + +bool ElemOpEmitter::emitPrivateGuardForAssignment() { + if (!isPrivate()) { + return true; + } + + // [stack] OBJ KEY RHS + if (!bce_->emitUnpickN(2)) { + // [stack] RHS OBJ KEY + return false; + } + + if (!emitPrivateGuard()) { + // [stack] RHS OBJ KEY + return false; + } + + if (!bce_->emitPickN(2)) { + // [stack] OBJ KEY RHS + return false; + } + + return true; +} + bool ElemOpEmitter::emitGet() { MOZ_ASSERT(state_ == State::Key); @@ -61,6 +119,11 @@ bool ElemOpEmitter::emitGet() { return false; } } + + if (!emitPrivateGuard()) { + return false; + } + if (isSuper()) { if (!bce_->emitSuperBase()) { // [stack] THIS? THIS KEY SUPERBASE @@ -147,6 +210,7 @@ bool ElemOpEmitter::skipObjAndKeyAndRhs() { bool ElemOpEmitter::emitDelete() { MOZ_ASSERT(state_ == State::Key); MOZ_ASSERT(isDelete()); + MOZ_ASSERT(!isPrivate()); if (isSuper()) { if (!bce_->emit1(JSOp::ToPropertyKey)) { @@ -171,6 +235,7 @@ bool ElemOpEmitter::emitDelete() { return false; } } else { + MOZ_ASSERT(!isPrivate()); JSOp op = bce_->sc->strict() ? JSOp::StrictDelElem : JSOp::DelElem; if (!bce_->emitElemOpBase(op)) { // SUCCEEDED @@ -190,12 +255,15 @@ bool ElemOpEmitter::emitAssignment() { MOZ_ASSERT_IF(isPropInit(), !isSuper()); - JSOp setOp = isPropInit() - ? JSOp::InitElem - : isSuper() ? bce_->sc->strict() ? JSOp::StrictSetElemSuper - : JSOp::SetElemSuper - : bce_->sc->strict() ? JSOp::StrictSetElem - : JSOp::SetElem; + if (!emitPrivateGuardForAssignment()) { + return false; + } + + JSOp setOp = isPropInit() ? JSOp::InitElem + : isSuper() ? bce_->sc->strict() ? JSOp::StrictSetElemSuper + : JSOp::SetElemSuper + : bce_->sc->strict() ? JSOp::StrictSetElem + : JSOp::SetElem; if (!bce_->emitElemOpBase(setOp, ShouldInstrument::Yes)) { // [stack] ELEM return false; diff --git a/js/src/frontend/ElemOpEmitter.h b/js/src/frontend/ElemOpEmitter.h index f58bc0e73a..4f96b35bd5 100644 --- a/js/src/frontend/ElemOpEmitter.h +++ b/js/src/frontend/ElemOpEmitter.h @@ -6,6 +6,7 @@ #define frontend_ElemOpEmitter_h #include "mozilla/Attributes.h" +#include "frontend/Token.h" namespace js { namespace frontend { @@ -136,6 +137,7 @@ class MOZ_STACK_CLASS ElemOpEmitter { Kind kind_; ObjKind objKind_; + NameVisibility visibility_ = NameVisibility::Public; #ifdef DEBUG // The state of this emitter. @@ -149,8 +151,6 @@ class MOZ_STACK_CLASS ElemOpEmitter { // | | // +-------------------------------------------------------+ | // | | - // | | - // | | // | [Get] | // | [Call] | // | emitGet +-----+ | @@ -210,7 +210,8 @@ class MOZ_STACK_CLASS ElemOpEmitter { #endif public: - ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind); + ElemOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind, + NameVisibility visibility); private: MOZ_MUST_USE bool isCall() const { return kind_ == Kind::Call; } @@ -219,8 +220,14 @@ class MOZ_STACK_CLASS ElemOpEmitter { return kind_ == Kind::SimpleAssignment; } + bool isPrivate() { return visibility_ == NameVisibility::Private; } + MOZ_MUST_USE bool isPropInit() const { return kind_ == Kind::PropInit; } + MOZ_MUST_USE bool isPrivateGet() const { + return visibility_ == NameVisibility::Private && kind_ == Kind::Get; + } + MOZ_MUST_USE bool isDelete() const { return kind_ == Kind::Delete; } MOZ_MUST_USE bool isCompoundAssignment() const { @@ -257,9 +264,15 @@ class MOZ_STACK_CLASS ElemOpEmitter { MOZ_MUST_USE bool emitAssignment(); MOZ_MUST_USE bool emitIncDec(); + + private: + // When we have private names, we may need to emit a CheckPrivateField + // op to potentially throw errors where required. + MOZ_MUST_USE bool emitPrivateGuard(); + MOZ_MUST_USE bool emitPrivateGuardForAssignment(); }; } /* namespace frontend */ -} /* namespace js */ +} // namespace js #endif /* frontend_ElemOpEmitter_h */ diff --git a/js/src/frontend/EmitterScope.cpp b/js/src/frontend/EmitterScope.cpp index cc8eb1ba23..6b941acf7e 100644 --- a/js/src/frontend/EmitterScope.cpp +++ b/js/src/frontend/EmitterScope.cpp @@ -32,7 +32,7 @@ bool EmitterScope::ensureCache(BytecodeEmitter* bce) { } bool EmitterScope::checkSlotLimits(BytecodeEmitter* bce, - const BindingIter& bi) { + const ParserBindingIter& bi) { if (bi.nextFrameSlot() >= LOCALNO_LIMIT || bi.nextEnvironmentSlot() >= ENVCOORD_SLOT_LIMIT) { bce->reportError(nullptr, JSMSG_TOO_MANY_LOCALS); @@ -45,8 +45,17 @@ bool EmitterScope::checkEnvironmentChainLength(BytecodeEmitter* bce) { uint32_t hops; if (EmitterScope* emitterScope = enclosing(&bce)) { hops = emitterScope->environmentChainLength_; + } else if (bce->compilationInfo.input.enclosingScope) { + hops = bce->compilationInfo.input.enclosingScope->environmentChainLength(); } else { - hops = bce->sc->compilationEnclosingScope()->environmentChainLength(); + // If we're compiling module, enclosingScope is nullptr and it means empty + // global scope. + // See also the assertion in CompilationInfo::instantiateStencils. + // + // Global script also uses enclosingScope == nullptr, but it shouldn't call + // checkEnvironmentChainLength. + MOZ_ASSERT(bce->sc->isModule()); + hops = ModuleScope::EnclosingEnvironmentChainLength; } if (hops >= ENVCOORD_HOPS_LIMIT - 1) { @@ -59,7 +68,7 @@ bool EmitterScope::checkEnvironmentChainLength(BytecodeEmitter* bce) { } void EmitterScope::updateFrameFixedSlots(BytecodeEmitter* bce, - const BindingIter& bi) { + const ParserBindingIter& bi) { nextFrameSlot_ = bi.nextFrameSlot(); if (nextFrameSlot_ > bce->maxFixedSlots) { bce->maxFixedSlots = nextFrameSlot_; @@ -70,7 +79,7 @@ void EmitterScope::updateFrameFixedSlots(BytecodeEmitter* bce, bce->maxFixedSlots == 0); } -bool EmitterScope::putNameInCache(BytecodeEmitter* bce, JSAtom* name, +bool EmitterScope::putNameInCache(BytecodeEmitter* bce, const ParserAtom* name, NameLocation loc) { NameLocationMap& cache = *nameCache_; NameLocationMap::AddPtr p = cache.lookupForAdd(name); @@ -83,7 +92,7 @@ bool EmitterScope::putNameInCache(BytecodeEmitter* bce, JSAtom* name, } Maybe EmitterScope::lookupInCache(BytecodeEmitter* bce, - JSAtom* name) { + const ParserAtom* name) { if (NameLocationMap::Ptr p = nameCache_->lookup(name)) { return Some(p->value().wrapped); } @@ -109,20 +118,26 @@ EmitterScope* EmitterScope::enclosing(BytecodeEmitter** bce) const { return nullptr; } -AbstractScopePtr EmitterScope::enclosingScope(BytecodeEmitter* bce) const { +mozilla::Maybe EmitterScope::enclosingScopeIndex( + BytecodeEmitter* bce) const { if (EmitterScope* es = enclosing(&bce)) { - return es->scope(bce); + // NOTE: A value of Nothing for the ScopeIndex will occur when the enclosing + // scope is the empty-global-scope. This is only allowed for self-hosting + // code. + MOZ_ASSERT_IF(es->scopeIndex(bce).isNothing(), + bce->emitterMode == BytecodeEmitter::SelfHosting); + return es->scopeIndex(bce); } // The enclosing script is already compiled or the current script is the // global script. - return AbstractScopePtr(bce->sc->compilationEnclosingScope()); + return mozilla::Nothing(); } /* static */ -bool EmitterScope::nameCanBeFree(BytecodeEmitter* bce, JSAtom* name) { +bool EmitterScope::nameCanBeFree(BytecodeEmitter* bce, const ParserAtom* name) { // '.generator' cannot be accessed by name. - return name != bce->cx->names().dotGenerator; + return name != bce->cx->parserNames().dotGenerator; } #ifdef DEBUG @@ -160,6 +175,10 @@ static bool NameIsOnEnvironment(Scope* scope, JSAtom* name) { /* static */ NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope, uint8_t hops) { + MOZ_ASSERT(scope); + // TODO-Stencil + // This needs to be handled properly by snapshotting enclosing scopes. + for (ScopeIter si(scope); si; si++) { MOZ_ASSERT(NameIsOnEnvironment(si.scope(), name)); @@ -203,6 +222,7 @@ NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope, case ScopeKind::SimpleCatch: case ScopeKind::Catch: case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: if (hasEnv) { for (BindingIter bi(si.scope()); bi; bi++) { if (bi.name() != name) { @@ -275,7 +295,8 @@ NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope, MOZ_CRASH("Malformed scope chain"); } -NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce, JSAtom* name) { +NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce, + const ParserAtom* name) { Maybe loc; uint8_t hops = hasEnvironment() ? 1 : 0; DebugOnly inCurrentScript = enclosingInFrame(); @@ -304,9 +325,25 @@ NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce, JSAtom* name) { // If the name is not found in the current compilation, walk the Scope // chain encompassing the compilation. if (!loc) { + // TODO-Stencil + // Here, we convert our name into a JSAtom*, and hard-crash on failure + // to allocate. This conversion should not be required as we should be + // able to iterate up snapshotted scope chains that use parser atoms. + // + // This will be fixed when parser scopes are snapshotted, and + // `searchInEnclosingScope` changes to accepting a `const ParserAtom*` + // instead of a `JSAtom*`. + // + // See bug 1660275. + AutoEnterOOMUnsafeRegion oomUnsafe; + JSAtom* jsname = bce->compilationInfo.liftParserAtomToJSAtom(bce->cx, name); + if (!jsname) { + oomUnsafe.crash("EmitterScope::searchAndCache"); + } + inCurrentScript = false; loc = Some(searchInEnclosingScope( - name, bce->sc->compilationEnclosingScope(), hops)); + jsname, bce->compilationInfo.input.enclosingScope, hops)); } // Each script has its own frame. A free name that is accessed @@ -325,10 +362,15 @@ NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce, JSAtom* name) { } bool EmitterScope::internEmptyGlobalScopeAsBody(BytecodeEmitter* bce) { + // Only the self-hosted top-level script uses this. If this changes, you must + // update ScopeStencil::enclosing. + MOZ_ASSERT(bce->emitterMode == BytecodeEmitter::SelfHosting); + Scope* scope = &bce->cx->global()->emptyGlobalScope(); hasEnvironment_ = scope->hasEnvironment(); - bce->bodyScopeIndex = bce->perScriptData().gcThingList().length(); + bce->bodyScopeIndex = + GCThingIndex(bce->perScriptData().gcThingList().length()); return bce->perScriptData().gcThingList().appendEmptyGlobalScope( &scopeIndex_); } @@ -336,22 +378,22 @@ bool EmitterScope::internEmptyGlobalScopeAsBody(BytecodeEmitter* bce) { template bool EmitterScope::internScopeCreationData(BytecodeEmitter* bce, ScopeCreator createScope) { - Rooted enclosing(bce->cx, enclosingScope(bce)); ScopeIndex index; - if (!createScope(bce->cx, enclosing, &index)) { + if (!createScope(bce->cx, enclosingScopeIndex(bce), &index)) { return false; } - auto scope = bce->compilationInfo.scopeCreationData[index.index]; - hasEnvironment_ = scope.get().hasEnvironment(); + ScopeStencil& scope = bce->compilationInfo.stencil.scopeData[index.index]; + hasEnvironment_ = scope.hasEnvironment(); return bce->perScriptData().gcThingList().append(index, &scopeIndex_); } template bool EmitterScope::internBodyScopeCreationData(BytecodeEmitter* bce, ScopeCreator createScope) { - MOZ_ASSERT(bce->bodyScopeIndex == UINT32_MAX, + MOZ_ASSERT(bce->bodyScopeIndex == ScopeNote::NoScopeIndex, "There can be only one body scope"); - bce->bodyScopeIndex = bce->perScriptData().gcThingList().length(); + bce->bodyScopeIndex = + GCThingIndex(bce->perScriptData().gcThingList().length()); return internScopeCreationData(bce, createScope); } @@ -399,7 +441,7 @@ void EmitterScope::dump(BytecodeEmitter* bce) { for (NameLocationMap::Range r = nameCache_->all(); !r.empty(); r.popFront()) { const NameLocation& l = r.front().value(); - UniqueChars bytes = AtomToPrintableString(bce->cx, r.front().key()); + UniqueChars bytes = ParserAtomToPrintableString(bce->cx, r.front().key()); if (!bytes) { return; } @@ -447,7 +489,7 @@ void EmitterScope::dump(BytecodeEmitter* bce) { } bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind, - Handle bindings) { + ParserLexicalScopeData* bindings) { MOZ_ASSERT(kind != ScopeKind::NamedLambda && kind != ScopeKind::StrictNamedLambda); MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck()); @@ -459,7 +501,7 @@ bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind, // Resolve bindings. TDZCheckCache* tdzCache = bce->innermostTDZCheckCache; uint32_t firstFrameSlot = frameSlotStart(); - BindingIter bi(*bindings, firstFrameSlot, /* isNamedLambda = */ false); + ParserBindingIter bi(*bindings, firstFrameSlot, /* isNamedLambda = */ false); for (; bi; bi++) { if (!checkSlotLimits(bce, bi)) { return false; @@ -478,10 +520,11 @@ bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind, updateFrameFixedSlots(bce, bi); auto createScope = [kind, bindings, firstFrameSlot, bce]( - JSContext* cx, Handle enclosing, + JSContext* cx, mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create(cx, bce->compilationInfo, kind, bindings, - firstFrameSlot, enclosing, index); + return ScopeStencil::createForLexicalScope(cx, bce->compilationInfo.stencil, + kind, bindings, firstFrameSlot, + enclosing, index); }; if (!internScopeCreationData(bce, createScope)) { return false; @@ -519,8 +562,8 @@ bool EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox) { return false; } - BindingIter bi(*funbox->namedLambdaBindings(), LOCALNO_LIMIT, - /* isNamedLambda = */ true); + ParserBindingIter bi(*funbox->namedLambdaBindings(), LOCALNO_LIMIT, + /* isNamedLambda = */ true); MOZ_ASSERT(bi.kind() == BindingKind::NamedLambdaCallee); // The lambda name, if not closed over, is accessed via JSOp::Callee and @@ -537,11 +580,11 @@ bool EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox) { funbox->strict() ? ScopeKind::StrictNamedLambda : ScopeKind::NamedLambda; auto createScope = [funbox, scopeKind, bce]( - JSContext* cx, Handle enclosing, + JSContext* cx, mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create(cx, bce->compilationInfo, scopeKind, - funbox->namedLambdaBindings(), - LOCALNO_LIMIT, enclosing, index); + return ScopeStencil::createForLexicalScope( + cx, bce->compilationInfo.stencil, scopeKind, + funbox->namedLambdaBindings(), LOCALNO_LIMIT, enclosing, index); }; if (!internScopeCreationData(bce, createScope)) { return false; @@ -567,7 +610,7 @@ bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) { if (bindings) { NameLocationMap& cache = *nameCache_; - BindingIter bi(*bindings, funbox->hasParameterExprs); + ParserBindingIter bi(*bindings, funbox->hasParameterExprs); for (; bi; bi++) { if (!checkSlotLimits(bce, bi)) { return false; @@ -609,7 +652,7 @@ bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) { // bindings and have TDZ. if (funbox->hasParameterExprs && nextFrameSlot_) { uint32_t paramFrameSlotEnd = 0; - for (BindingIter bi(*bindings, true); bi; bi++) { + for (ParserBindingIter bi(*bindings, true); bi; bi++) { if (!BindingKindIsLexical(bi.kind())) { break; } @@ -627,13 +670,13 @@ bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) { } auto createScope = [funbox, bce](JSContext* cx, - Handle enclosing, + mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create( - cx, bce->compilationInfo, funbox->functionScopeBindings(), + return ScopeStencil::createForFunctionScope( + cx, bce->compilationInfo.stencil, funbox->functionScopeBindings(), funbox->hasParameterExprs, - funbox->needsCallObjectRegardlessOfBindings(), funbox, enclosing, - index); + funbox->needsCallObjectRegardlessOfBindings(), funbox->index(), + funbox->isArrow(), enclosing, index); }; if (!internBodyScopeCreationData(bce, createScope)) { return false; @@ -660,7 +703,7 @@ bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, // Resolve body-level bindings, if there are any. uint32_t firstFrameSlot = frameSlotStart(); if (auto bindings = funbox->extraVarScopeBindings()) { - BindingIter bi(*bindings, firstFrameSlot); + ParserBindingIter bi(*bindings, firstFrameSlot); for (; bi; bi++) { if (!checkSlotLimits(bce, bi)) { return false; @@ -687,10 +730,10 @@ bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, // Create and intern the VM scope. auto createScope = [funbox, firstFrameSlot, bce]( - JSContext* cx, Handle enclosing, + JSContext* cx, mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create( - cx, bce->compilationInfo, ScopeKind::FunctionBodyVar, + return ScopeStencil::createForVarScope( + cx, bce->compilationInfo.stencil, ScopeKind::FunctionBodyVar, funbox->extraVarScopeBindings(), firstFrameSlot, funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(), enclosing, index); @@ -713,13 +756,13 @@ bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce, return checkEnvironmentChainLength(bce); } -class DynamicBindingIter : public BindingIter { +class DynamicBindingIter : public ParserBindingIter { public: explicit DynamicBindingIter(GlobalSharedContext* sc) - : BindingIter(*sc->bindings) {} + : ParserBindingIter(*sc->bindings) {} explicit DynamicBindingIter(EvalSharedContext* sc) - : BindingIter(*sc->bindings, /* strict = */ false) { + : ParserBindingIter(*sc->bindings, /* strict = */ false) { MOZ_ASSERT(!sc->strict()); } @@ -741,6 +784,11 @@ bool EmitterScope::enterGlobal(BytecodeEmitter* bce, GlobalSharedContext* globalsc) { MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck()); + // TODO-Stencil + // This is another snapshot-sensitive location. + // The incoming atoms from the global scope object should be snapshotted. + // For now, converting them to ParserAtoms here individually. + bce->setVarEmitterScope(this); if (!ensureCache(bce)) { @@ -761,19 +809,20 @@ bool EmitterScope::enterGlobal(BytecodeEmitter* bce, } auto createScope = [globalsc, bce](JSContext* cx, - Handle enclosing, + mozilla::Maybe enclosing, ScopeIndex* index) { - MOZ_ASSERT(!enclosing.get()); - return ScopeCreationData::create(cx, bce->compilationInfo, - globalsc->scopeKind(), globalsc->bindings, - index); + MOZ_ASSERT(enclosing.isNothing()); + return ScopeStencil::createForGlobalScope(cx, bce->compilationInfo.stencil, + globalsc->scopeKind(), + globalsc->bindings, index); }; if (!internBodyScopeCreationData(bce, createScope)) { return false; } // See: JSScript::outermostScope. - MOZ_ASSERT(bce->bodyScopeIndex == 0, "Global scope must be index 0"); + MOZ_ASSERT(bce->bodyScopeIndex == GCThingIndex::outermostScopeIndex(), + "Global scope must be index 0"); // Resolve binding names and emit Def{Var,Let,Const} prologue ops. if (globalsc->bindings) { @@ -784,7 +833,7 @@ bool EmitterScope::enterGlobal(BytecodeEmitter* bce, for (DynamicBindingIter bi(globalsc); bi; bi++) { NameLocation loc = NameLocation::fromBinding(bi.kind(), bi.location()); - JSAtom* name = bi.name(); + const ParserAtom* name = bi.name(); if (!putNameInCache(bce, name, loc)) { return false; } @@ -828,12 +877,13 @@ bool EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext* evalsc) { // Create the `var` scope. Note that there is also a lexical scope, created // separately in emitScript(). auto createScope = [evalsc, bce](JSContext* cx, - Handle enclosing, + mozilla::Maybe enclosing, ScopeIndex* index) { ScopeKind scopeKind = evalsc->strict() ? ScopeKind::StrictEval : ScopeKind::Eval; - return ScopeCreationData::create(cx, bce->compilationInfo, scopeKind, - evalsc->bindings, enclosing, index); + return ScopeStencil::createForEvalScope(cx, bce->compilationInfo.stencil, + scopeKind, evalsc->bindings, + enclosing, index); }; if (!internBodyScopeCreationData(bce, createScope)) { return false; @@ -894,8 +944,8 @@ bool EmitterScope::enterModule(BytecodeEmitter* bce, // Resolve body-level bindings, if there are any. TDZCheckCache* tdzCache = bce->innermostTDZCheckCache; Maybe firstLexicalFrameSlot; - if (ModuleScope::Data* bindings = modulesc->bindings) { - BindingIter bi(*bindings); + if (ParserModuleScopeData* bindings = modulesc->bindings) { + ParserBindingIter bi(*bindings); for (; bi; bi++) { if (!checkSlotLimits(bce, bi)) { return false; @@ -936,11 +986,10 @@ bool EmitterScope::enterModule(BytecodeEmitter* bce, // Create and intern the VM scope creation data. auto createScope = [modulesc, bce](JSContext* cx, - Handle enclosing, + mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create(cx, bce->compilationInfo, - modulesc->bindings, modulesc->module(), - enclosing, index); + return ScopeStencil::createForModuleScope( + cx, bce->compilationInfo.stencil, modulesc->bindings, enclosing, index); }; if (!internBodyScopeCreationData(bce, createScope)) { return false; @@ -959,10 +1008,10 @@ bool EmitterScope::enterWith(BytecodeEmitter* bce) { // 'with' make all accesses dynamic and unanalyzable. fallbackFreeNameLocation_ = Some(NameLocation::Dynamic()); - auto createScope = [bce](JSContext* cx, Handle enclosing, + auto createScope = [bce](JSContext* cx, mozilla::Maybe enclosing, ScopeIndex* index) { - return ScopeCreationData::create(cx, bce->compilationInfo, enclosing, - index); + return ScopeStencil::createForWithScope(cx, bce->compilationInfo.stencil, + enclosing, index); }; if (!internScopeCreationData(bce, createScope)) { return false; @@ -994,6 +1043,7 @@ bool EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal) { case ScopeKind::SimpleCatch: case ScopeKind::Catch: case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: if (!bce->emit1(hasEnvironment() ? JSOp::PopLexicalEnv : JSOp::DebugLeaveLexicalEnv)) { return false; @@ -1046,14 +1096,20 @@ AbstractScopePtr EmitterScope::scope(const BytecodeEmitter* bce) const { return bce->perScriptData().gcThingList().getScope(index()); } -NameLocation EmitterScope::lookup(BytecodeEmitter* bce, JSAtom* name) { +mozilla::Maybe EmitterScope::scopeIndex( + const BytecodeEmitter* bce) const { + return bce->perScriptData().gcThingList().getScopeIndex(index()); +} + +NameLocation EmitterScope::lookup(BytecodeEmitter* bce, + const ParserAtom* name) { if (Maybe loc = lookupInCache(bce, name)) { return *loc; } return searchAndCache(bce, name); } -Maybe EmitterScope::locationBoundInScope(JSAtom* name, +Maybe EmitterScope::locationBoundInScope(const ParserAtom* name, EmitterScope* target) { // The target scope must be an intra-frame enclosing scope of this // one. Count the number of extra hops to reach it. diff --git a/js/src/frontend/EmitterScope.h b/js/src/frontend/EmitterScope.h index 8cb636f930..da19cf9bf6 100644 --- a/js/src/frontend/EmitterScope.h +++ b/js/src/frontend/EmitterScope.h @@ -17,6 +17,7 @@ #include "frontend/ParseContext.h" #include "frontend/SharedContext.h" #include "js/TypeDecls.h" +#include "vm/SharedStencil.h" // GCThingIndex namespace js { @@ -54,7 +55,7 @@ class EmitterScope : public Nestable { // The index in the BytecodeEmitter's interned scope vector, otherwise // ScopeNote::NoScopeIndex. - uint32_t scopeIndex_; + GCThingIndex scopeIndex_; // If kind is Lexical, Catch, or With, the index in the BytecodeEmitter's // block scope note list. Otherwise ScopeNote::NoScopeNote. @@ -63,27 +64,27 @@ class EmitterScope : public Nestable { MOZ_MUST_USE bool ensureCache(BytecodeEmitter* bce); MOZ_MUST_USE bool checkSlotLimits(BytecodeEmitter* bce, - const BindingIter& bi); + const ParserBindingIter& bi); MOZ_MUST_USE bool checkEnvironmentChainLength(BytecodeEmitter* bce); - void updateFrameFixedSlots(BytecodeEmitter* bce, const BindingIter& bi); + void updateFrameFixedSlots(BytecodeEmitter* bce, const ParserBindingIter& bi); - MOZ_MUST_USE bool putNameInCache(BytecodeEmitter* bce, JSAtom* name, + MOZ_MUST_USE bool putNameInCache(BytecodeEmitter* bce, const ParserAtom* name, NameLocation loc); mozilla::Maybe lookupInCache(BytecodeEmitter* bce, - JSAtom* name); + const ParserAtom* name); EmitterScope* enclosing(BytecodeEmitter** bce) const; - AbstractScopePtr enclosingScope(BytecodeEmitter* bce) const; + mozilla::Maybe enclosingScopeIndex(BytecodeEmitter* bce) const; - static bool nameCanBeFree(BytecodeEmitter* bce, JSAtom* name); + static bool nameCanBeFree(BytecodeEmitter* bce, const ParserAtom* name); static NameLocation searchInEnclosingScope(JSAtom* name, Scope* scope, uint8_t hops); - NameLocation searchAndCache(BytecodeEmitter* bce, JSAtom* name); + NameLocation searchAndCache(BytecodeEmitter* bce, const ParserAtom* name); MOZ_MUST_USE bool internEmptyGlobalScopeAsBody(BytecodeEmitter* bce); @@ -106,7 +107,7 @@ class EmitterScope : public Nestable { void dump(BytecodeEmitter* bce); MOZ_MUST_USE bool enterLexical(BytecodeEmitter* bce, ScopeKind kind, - Handle bindings); + ParserLexicalScopeData* bindings); MOZ_MUST_USE bool enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox); MOZ_MUST_USE bool enterFunction(BytecodeEmitter* bce, FunctionBox* funbox); MOZ_MUST_USE bool enterFunctionExtraBodyVar(BytecodeEmitter* bce, @@ -121,7 +122,7 @@ class EmitterScope : public Nestable { MOZ_MUST_USE bool leave(BytecodeEmitter* bce, bool nonLocal = false); - uint32_t index() const { + GCThingIndex index() const { MOZ_ASSERT(scopeIndex_ != ScopeNote::NoScopeIndex, "Did you forget to intern a Scope?"); return scopeIndex_; @@ -130,6 +131,7 @@ class EmitterScope : public Nestable { uint32_t noteIndex() const { return noteIndex_; } AbstractScopePtr scope(const BytecodeEmitter* bce) const; + mozilla::Maybe scopeIndex(const BytecodeEmitter* bce) const; bool hasEnvironment() const { return hasEnvironment_; } @@ -148,9 +150,9 @@ class EmitterScope : public Nestable { return Nestable::enclosing(); } - NameLocation lookup(BytecodeEmitter* bce, JSAtom* name); + NameLocation lookup(BytecodeEmitter* bce, const ParserAtom* name); - mozilla::Maybe locationBoundInScope(JSAtom* name, + mozilla::Maybe locationBoundInScope(const ParserAtom* name, EmitterScope* target); }; diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp index d3b4227dec..9ae3d77516 100644 --- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -5,6 +5,7 @@ #include "frontend/FoldConstants.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/Range.h" #include "jslibmath.h" #include "jsnum.h" @@ -13,6 +14,8 @@ #include "frontend/ParseNodeVisitor.h" #include "frontend/Parser.h" #include "js/Conversions.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit +#include "js/Vector.h" #include "vm/StringType.h" using namespace js; @@ -26,6 +29,12 @@ using mozilla::IsNegative; using mozilla::NegativeInfinity; using mozilla::PositiveInfinity; +struct FoldInfo { + JSContext* cx; + CompilationInfo& compilationInfo; + FullParseHandler* handler; +}; + // Don't use ReplaceNode directly, because we want the constant folder to keep // the attributes isInParens and isDirectRHSAnonFunction of the old node being // replaced. @@ -445,19 +454,18 @@ static bool ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, * Fold from one constant type to another. * XXX handles only strings and numbers for now */ -static bool FoldType(JSContext* cx, FullParseHandler* handler, ParseNode** pnp, - ParseNodeKind kind) { +static bool FoldType(FoldInfo info, ParseNode** pnp, ParseNodeKind kind) { const ParseNode* pn = *pnp; if (!pn->isKind(kind)) { switch (kind) { case ParseNodeKind::NumberExpr: if (pn->isKind(ParseNodeKind::StringExpr)) { double d; - if (!StringToNumber(cx, pn->as().atom(), &d)) { + if (!pn->as().atom()->toNumber(info.cx, &d)) { return false; } - if (!TryReplaceNode(pnp, - handler->newNumber(d, NoDecimal, pn->pn_pos))) { + if (!TryReplaceNode( + pnp, info.handler->newNumber(d, NoDecimal, pn->pn_pos))) { return false; } } @@ -465,12 +473,13 @@ static bool FoldType(JSContext* cx, FullParseHandler* handler, ParseNode** pnp, case ParseNodeKind::StringExpr: if (pn->isKind(ParseNodeKind::NumberExpr)) { - JSAtom* atom = pn->as().toAtom(cx); + const ParserAtom* atom = + pn->as().toAtom(info.cx, info.compilationInfo); if (!atom) { return false; } - if (!TryReplaceNode(pnp, - handler->newStringLiteral(atom, pn->pn_pos))) { + if (!TryReplaceNode( + pnp, info.handler->newStringLiteral(atom, pn->pn_pos))) { return false; } } @@ -540,8 +549,7 @@ static Truthiness Boolish(ParseNode* pn) { } } -static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool SimplifyCondition(FoldInfo info, ParseNode** nodePtr) { // Conditions fold like any other expression, but then they sometimes can be // further folded to constants. *nodePtr should already have been // constant-folded. @@ -553,8 +561,8 @@ static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler, // that appears on a method list corrupts the method list. However, // methods are M's in statements of the form 'this.foo = M;', which we // never fold, so we're okay. - if (!TryReplaceNode( - nodePtr, handler->newBooleanLiteral(t == Truthy, node->pn_pos))) { + if (!TryReplaceNode(nodePtr, info.handler->newBooleanLiteral( + t == Truthy, node->pn_pos))) { return false; } } @@ -562,33 +570,32 @@ static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldTypeOfExpr(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldTypeOfExpr(FoldInfo info, ParseNode** nodePtr) { UnaryNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::TypeOfExpr)); ParseNode* expr = node->kid(); // Constant-fold the entire |typeof| if given a constant with known type. - RootedPropertyName result(cx); + const ParserName* result = nullptr; if (expr->isKind(ParseNodeKind::StringExpr) || expr->isKind(ParseNodeKind::TemplateStringExpr)) { - result = cx->names().string; + result = info.cx->parserNames().string; } else if (expr->isKind(ParseNodeKind::NumberExpr)) { - result = cx->names().number; + result = info.cx->parserNames().number; } else if (expr->isKind(ParseNodeKind::BigIntExpr)) { - result = cx->names().bigint; + result = info.cx->parserNames().bigint; } else if (expr->isKind(ParseNodeKind::NullExpr)) { - result = cx->names().object; + result = info.cx->parserNames().object; } else if (expr->isKind(ParseNodeKind::TrueExpr) || expr->isKind(ParseNodeKind::FalseExpr)) { - result = cx->names().boolean; + result = info.cx->parserNames().boolean; } else if (expr->is()) { - result = cx->names().function; + result = info.cx->parserNames().function; } if (result) { if (!TryReplaceNode(nodePtr, - handler->newStringLiteral(result, node->pn_pos))) { + info.handler->newStringLiteral(result, node->pn_pos))) { return false; } } @@ -596,8 +603,7 @@ static bool FoldTypeOfExpr(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldDeleteExpr(FoldInfo info, ParseNode** nodePtr) { UnaryNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteExpr)); @@ -607,7 +613,7 @@ static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler, // For effectless expressions, eliminate the expression evaluation. if (IsEffectless(expr)) { if (!TryReplaceNode(nodePtr, - handler->newBooleanLiteral(true, node->pn_pos))) { + info.handler->newBooleanLiteral(true, node->pn_pos))) { return false; } } @@ -615,8 +621,7 @@ static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldDeleteElement(FoldInfo info, ParseNode** nodePtr) { UnaryNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteElemExpr)); ParseNode* expr = node->kid(); @@ -632,7 +637,7 @@ static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler, if (expr->isKind(ParseNodeKind::DotExpr)) { // newDelete will detect and use DeletePropExpr if (!TryReplaceNode(nodePtr, - handler->newDelete(node->pn_pos.begin, expr))) { + info.handler->newDelete(node->pn_pos.begin, expr))) { return false; } MOZ_ASSERT((*nodePtr)->getKind() == ParseNodeKind::DeletePropExpr); @@ -641,12 +646,11 @@ static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldNot(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldNot(FoldInfo info, ParseNode** nodePtr) { UnaryNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::NotExpr)); - if (!SimplifyCondition(cx, handler, node->unsafeKidReference())) { + if (!SimplifyCondition(info, node->unsafeKidReference())) { return false; } @@ -656,8 +660,8 @@ static bool FoldNot(JSContext* cx, FullParseHandler* handler, expr->isKind(ParseNodeKind::FalseExpr)) { bool newval = !expr->isKind(ParseNodeKind::TrueExpr); - if (!TryReplaceNode(nodePtr, - handler->newBooleanLiteral(newval, node->pn_pos))) { + if (!TryReplaceNode( + nodePtr, info.handler->newBooleanLiteral(newval, node->pn_pos))) { return false; } } @@ -665,8 +669,7 @@ static bool FoldNot(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldUnaryArithmetic(FoldInfo info, ParseNode** nodePtr) { UnaryNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::BitNotExpr) || node->isKind(ParseNodeKind::PosExpr) || @@ -691,7 +694,7 @@ static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler, } if (!TryReplaceNode(nodePtr, - handler->newNumber(d, NoDecimal, node->pn_pos))) { + info.handler->newNumber(d, NoDecimal, node->pn_pos))) { return false; } } @@ -699,7 +702,7 @@ static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldAndOrCoalesce(JSContext* cx, ParseNode** nodePtr) { +static bool FoldAndOrCoalesce(FoldInfo info, ParseNode** nodePtr) { ListNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::AndExpr) || @@ -776,10 +779,9 @@ static bool FoldAndOrCoalesce(JSContext* cx, ParseNode** nodePtr) { return true; } -static bool Fold(JSContext* cx, FullParseHandler* handler, ParseNode** pnp); +static bool Fold(FoldInfo info, ParseNode** pnp); -static bool FoldConditional(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldConditional(FoldInfo info, ParseNode** nodePtr) { ParseNode** nextNode = nodePtr; do { @@ -793,15 +795,15 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler, MOZ_ASSERT(node->isKind(ParseNodeKind::ConditionalExpr)); ParseNode** expr = node->unsafeKid1Reference(); - if (!Fold(cx, handler, expr)) { + if (!Fold(info, expr)) { return false; } - if (!SimplifyCondition(cx, handler, expr)) { + if (!SimplifyCondition(info, expr)) { return false; } ParseNode** ifTruthy = node->unsafeKid2Reference(); - if (!Fold(cx, handler, ifTruthy)) { + if (!Fold(info, ifTruthy)) { return false; } @@ -818,7 +820,7 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler, MOZ_ASSERT((*ifFalsy)->is()); nextNode = ifFalsy; } else { - if (!Fold(cx, handler, ifFalsy)) { + if (!Fold(info, ifFalsy)) { return false; } } @@ -844,8 +846,7 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldIf(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldIf(FoldInfo info, ParseNode** nodePtr) { ParseNode** nextNode = nodePtr; do { @@ -858,15 +859,15 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler, MOZ_ASSERT(node->isKind(ParseNodeKind::IfStmt)); ParseNode** expr = node->unsafeKid1Reference(); - if (!Fold(cx, handler, expr)) { + if (!Fold(info, expr)) { return false; } - if (!SimplifyCondition(cx, handler, expr)) { + if (!SimplifyCondition(info, expr)) { return false; } ParseNode** consequent = node->unsafeKid2Reference(); - if (!Fold(cx, handler, consequent)) { + if (!Fold(info, consequent)) { return false; } @@ -881,7 +882,7 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler, MOZ_ASSERT((*alternative)->is()); nextNode = alternative; } else { - if (!Fold(cx, handler, alternative)) { + if (!Fold(info, alternative)) { return false; } } @@ -911,7 +912,8 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler, // A declaration that hoists outside the discarded arm prevents the // |if| from being folded away. bool containsHoistedDecls; - if (!ContainsHoistedDeclaration(cx, discarded, &containsHoistedDecls)) { + if (!ContainsHoistedDeclaration(info.cx, discarded, + &containsHoistedDecls)) { return false; } @@ -926,7 +928,8 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler, // If there's no replacement node, we have a constantly-false |if| // with no |else|. Replace the entire thing with an empty // statement list. - if (!TryReplaceNode(nodePtr, handler->newStatementList(node->pn_pos))) { + if (!TryReplaceNode(nodePtr, + info.handler->newStatementList(node->pn_pos))) { return false; } } else { @@ -975,8 +978,7 @@ static double ComputeBinary(ParseNodeKind kind, double left, double right) { return int32_t((kind == ParseNodeKind::LshExpr) ? uint32_t(i) << j : i >> j); } -static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldBinaryArithmetic(FoldInfo info, ParseNode** nodePtr) { ListNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::SubExpr) || node->isKind(ParseNodeKind::MulExpr) || @@ -990,7 +992,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler, // Fold each operand to a number if possible. ParseNode** listp = node->unsafeHeadReference(); for (; *listp; listp = &(*listp)->pn_next) { - if (!FoldType(cx, handler, listp, ParseNodeKind::NumberExpr)) { + if (!FoldType(info, listp, ParseNodeKind::NumberExpr)) { return false; } } @@ -1014,7 +1016,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler, (*next)->as().value()); TokenPos pos((*elem)->pn_pos.begin, (*next)->pn_pos.end); - if (!TryReplaceNode(elem, handler->newNumber(d, NoDecimal, pos))) { + if (!TryReplaceNode(elem, info.handler->newNumber(d, NoDecimal, pos))) { return false; } @@ -1036,8 +1038,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler, return true; } -static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldExponentiation(FoldInfo info, ParseNode** nodePtr) { ListNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::PowExpr)); MOZ_ASSERT(node->count() >= 2); @@ -1045,7 +1046,7 @@ static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler, // Fold each operand, ideally into a number. ParseNode** listp = node->unsafeHeadReference(); for (; *listp; listp = &(*listp)->pn_next) { - if (!FoldType(cx, handler, listp, ParseNodeKind::NumberExpr)) { + if (!FoldType(info, listp, ParseNodeKind::NumberExpr)) { return false; } } @@ -1071,31 +1072,31 @@ static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler, double d1 = base->as().value(); double d2 = exponent->as().value(); - return TryReplaceNode( - nodePtr, handler->newNumber(ecmaPow(d1, d2), NoDecimal, node->pn_pos)); + return TryReplaceNode(nodePtr, info.handler->newNumber( + ecmaPow(d1, d2), NoDecimal, node->pn_pos)); } -static bool FoldElement(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldElement(FoldInfo info, ParseNode** nodePtr) { PropertyByValue* elem = &(*nodePtr)->as(); ParseNode* expr = &elem->expression(); ParseNode* key = &elem->key(); - PropertyName* name = nullptr; + const ParserName* name = nullptr; if (key->isKind(ParseNodeKind::StringExpr)) { - JSAtom* atom = key->as().atom(); + const ParserAtom* atom = key->as().atom(); uint32_t index; if (atom->isIndex(&index)) { // Optimization 1: We have something like expr["100"]. This is // equivalent to expr[100] which is faster. - if (!TryReplaceNode(elem->unsafeRightReference(), - handler->newNumber(index, NoDecimal, key->pn_pos))) { + if (!TryReplaceNode( + elem->unsafeRightReference(), + info.handler->newNumber(index, NoDecimal, key->pn_pos))) { return false; } key = &elem->key(); } else { - name = atom->asPropertyName(); + name = atom->asName(); } } else if (key->isKind(ParseNodeKind::NumberExpr)) { auto* numeric = &key->as(); @@ -1104,11 +1105,11 @@ static bool FoldElement(JSContext* cx, FullParseHandler* handler, // Optimization 2: We have something like expr[3.14]. The number // isn't an array index, so it converts to a string ("3.14"), // enabling optimization 3 below. - JSAtom* atom = numeric->toAtom(cx); + const ParserAtom* atom = numeric->toAtom(info.cx, info.compilationInfo); if (!atom) { return false; } - name = atom->asPropertyName(); + name = atom->asName(); } } @@ -1120,20 +1121,19 @@ static bool FoldElement(JSContext* cx, FullParseHandler* handler, // Optimization 3: We have expr["foo"] where foo is not an index. Convert // to a property access (like expr.foo) that optimizes better downstream. - NameNode* propertyNameExpr = handler->newPropertyName(name, key->pn_pos); + NameNode* propertyNameExpr = info.handler->newPropertyName(name, key->pn_pos); if (!propertyNameExpr) { return false; } - if (!TryReplaceNode(nodePtr, - handler->newPropertyAccess(expr, propertyNameExpr))) { + if (!TryReplaceNode( + nodePtr, info.handler->newPropertyAccess(expr, propertyNameExpr))) { return false; } return true; } -static bool FoldAdd(JSContext* cx, FullParseHandler* handler, - ParseNode** nodePtr) { +static bool FoldAdd(FoldInfo info, ParseNode** nodePtr) { ListNode* node = &(*nodePtr)->as(); MOZ_ASSERT(node->isKind(ParseNodeKind::AddExpr)); @@ -1157,8 +1157,8 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, double right = (*next)->as().value(); TokenPos pos((*current)->pn_pos.begin, (*next)->pn_pos.end); - if (!TryReplaceNode(current, - handler->newNumber(left + right, NoDecimal, pos))) { + if (!TryReplaceNode( + current, info.handler->newNumber(left + right, NoDecimal, pos))) { return false; } @@ -1180,7 +1180,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, // the list: (x + 1 + "2" !== x + "12") when x is a number. if ((*current)->isKind(ParseNodeKind::NumberExpr) && (*next)->isKind(ParseNodeKind::StringExpr)) { - if (!FoldType(cx, handler, current, ParseNodeKind::StringExpr)) { + if (!FoldType(info, current, ParseNodeKind::StringExpr)) { return false; } next = &(*current)->pn_next; @@ -1202,19 +1202,20 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, break; } - RootedString combination(cx); - RootedString tmp(cx); + Vector accum(info.cx); do { - // Create a rope of the current string and all succeeding - // constants that we can convert to strings, then atomize it - // and replace them all with that fresh string. + // Create a vector of all the folded strings and concatenate them. MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr)); - combination = (*current)->as().atom(); + accum.clear(); + const ParserAtom* atom = (*current)->as().atom(); + if (!accum.append(atom)) { + return false; + } do { // Try folding the next operand to a string. - if (!FoldType(cx, handler, next, ParseNodeKind::StringExpr)) { + if (!FoldType(info, next, ParseNodeKind::StringExpr)) { return false; } @@ -1223,10 +1224,9 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, break; } - // Add this string to the combination and remove the node. - tmp = (*next)->as().atom(); - combination = ConcatStrings(cx, combination, tmp); - if (!combination) { + // Add this string to the accumulator and remove the node. + const ParserAtom* nextAtom = (*next)->as().atom(); + if (!accum.append(nextAtom)) { return false; } @@ -1236,13 +1236,22 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, node->unsafeDecrementCount(); } while (*next); - // Replace |current|'s string with the entire combination. - MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr)); - combination = AtomizeString(cx, combination); - if (!combination) { - return false; + // Replace with concatenation if we multiple nodes. + if (accum.length() > 1) { + // Construct the concatenated atom. + const ParserAtom* combination = + info.compilationInfo.stencil.parserAtoms + .concatAtoms(info.cx, + mozilla::Range(accum.begin(), accum.length())) + .unwrapOr(nullptr); + if (!combination) { + return false; + } + + // Replace |current|'s string with the entire combination. + MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr)); + (*current)->as().setAtom(combination); } - (*current)->as().setAtom(&combination->asAtom()); // If we're out of nodes, we're done. if (!*next) { @@ -1262,7 +1271,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, do { current = next; - if (!FoldType(cx, handler, current, ParseNodeKind::StringExpr)) { + if (!FoldType(info, current, ParseNodeKind::StringExpr)) { return false; } next = &(*current)->pn_next; @@ -1287,99 +1296,106 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler, class FoldVisitor : public RewritingParseNodeVisitor { using Base = RewritingParseNodeVisitor; + JSContext* cx; + CompilationInfo& compilationInfo; FullParseHandler* handler; + FoldInfo info() const { return FoldInfo{cx, compilationInfo, handler}; } + public: - explicit FoldVisitor(JSContext* cx, FullParseHandler* handler) - : RewritingParseNodeVisitor(cx), handler(handler) {} + explicit FoldVisitor(JSContext* cx, CompilationInfo& compilationInfo, + FullParseHandler* handler) + : RewritingParseNodeVisitor(cx), + cx(cx), + compilationInfo(compilationInfo), + handler(handler) {} bool visitElemExpr(ParseNode*& pn) { - return Base::visitElemExpr(pn) && FoldElement(cx_, handler, &pn); + return Base::visitElemExpr(pn) && FoldElement(info(), &pn); } bool visitTypeOfExpr(ParseNode*& pn) { - return Base::visitTypeOfExpr(pn) && FoldTypeOfExpr(cx_, handler, &pn); + return Base::visitTypeOfExpr(pn) && FoldTypeOfExpr(info(), &pn); } bool visitDeleteExpr(ParseNode*& pn) { - return Base::visitDeleteExpr(pn) && FoldDeleteExpr(cx_, handler, &pn); + return Base::visitDeleteExpr(pn) && FoldDeleteExpr(info(), &pn); } bool visitDeleteElemExpr(ParseNode*& pn) { - return Base::visitDeleteElemExpr(pn) && - FoldDeleteElement(cx_, handler, &pn); + return Base::visitDeleteElemExpr(pn) && FoldDeleteElement(info(), &pn); } bool visitNotExpr(ParseNode*& pn) { - return Base::visitNotExpr(pn) && FoldNot(cx_, handler, &pn); + return Base::visitNotExpr(pn) && FoldNot(info(), &pn); } bool visitBitNotExpr(ParseNode*& pn) { - return Base::visitBitNotExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn); + return Base::visitBitNotExpr(pn) && FoldUnaryArithmetic(info(), &pn); } bool visitPosExpr(ParseNode*& pn) { - return Base::visitPosExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn); + return Base::visitPosExpr(pn) && FoldUnaryArithmetic(info(), &pn); } bool visitNegExpr(ParseNode*& pn) { - return Base::visitNegExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn); + return Base::visitNegExpr(pn) && FoldUnaryArithmetic(info(), &pn); } bool visitPowExpr(ParseNode*& pn) { - return Base::visitPowExpr(pn) && FoldExponentiation(cx_, handler, &pn); + return Base::visitPowExpr(pn) && FoldExponentiation(info(), &pn); } bool visitMulExpr(ParseNode*& pn) { - return Base::visitMulExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitMulExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitDivExpr(ParseNode*& pn) { - return Base::visitDivExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitDivExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitModExpr(ParseNode*& pn) { - return Base::visitModExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitModExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitAddExpr(ParseNode*& pn) { - return Base::visitAddExpr(pn) && FoldAdd(cx_, handler, &pn); + return Base::visitAddExpr(pn) && FoldAdd(info(), &pn); } bool visitSubExpr(ParseNode*& pn) { - return Base::visitSubExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitSubExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitLshExpr(ParseNode*& pn) { - return Base::visitLshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitLshExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitRshExpr(ParseNode*& pn) { - return Base::visitRshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitRshExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitUrshExpr(ParseNode*& pn) { - return Base::visitUrshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn); + return Base::visitUrshExpr(pn) && FoldBinaryArithmetic(info(), &pn); } bool visitAndExpr(ParseNode*& pn) { // Note that this does result in the unfortunate fact that dead arms of this // node get constant folded. The same goes for visitOr and visitCoalesce. - return Base::visitAndExpr(pn) && FoldAndOrCoalesce(cx_, &pn); + return Base::visitAndExpr(pn) && FoldAndOrCoalesce(info(), &pn); } bool visitOrExpr(ParseNode*& pn) { - return Base::visitOrExpr(pn) && FoldAndOrCoalesce(cx_, &pn); + return Base::visitOrExpr(pn) && FoldAndOrCoalesce(info(), &pn); } bool visitCoalesceExpr(ParseNode*& pn) { - return Base::visitCoalesceExpr(pn) && FoldAndOrCoalesce(cx_, &pn); + return Base::visitCoalesceExpr(pn) && FoldAndOrCoalesce(info(), &pn); } bool visitConditionalExpr(ParseNode*& pn) { // Don't call base-class visitConditional because FoldConditional processes // pn's child nodes specially to save stack space. - return FoldConditional(cx_, handler, &pn); + return FoldConditional(info(), &pn); } private: @@ -1444,7 +1460,7 @@ class FoldVisitor : public RewritingParseNodeVisitor { bool visitIfStmt(ParseNode*& pn) { // Don't call base-class visitIf because FoldIf processes pn's child nodes // specially to save stack space. - return FoldIf(cx_, handler, &pn); + return FoldIf(info(), &pn); } bool visitForStmt(ParseNode*& pn) { @@ -1457,7 +1473,7 @@ class FoldVisitor : public RewritingParseNodeVisitor { TernaryNode& head = stmt.left()->as(); ParseNode** test = head.unsafeKid2Reference(); if (*test) { - if (!SimplifyCondition(cx_, handler, test)) { + if (!SimplifyCondition(info(), test)) { return false; } if ((*test)->isKind(ParseNodeKind::TrueExpr)) { @@ -1472,13 +1488,13 @@ class FoldVisitor : public RewritingParseNodeVisitor { bool visitWhileStmt(ParseNode*& pn) { BinaryNode& node = pn->as(); return Base::visitWhileStmt(pn) && - SimplifyCondition(cx_, handler, node.unsafeLeftReference()); + SimplifyCondition(info(), node.unsafeLeftReference()); } bool visitDoWhileStmt(ParseNode*& pn) { BinaryNode& node = pn->as(); return Base::visitDoWhileStmt(pn) && - SimplifyCondition(cx_, handler, node.unsafeRightReference()); + SimplifyCondition(info(), node.unsafeRightReference()); } bool visitFunction(ParseNode*& pn) { @@ -1537,15 +1553,19 @@ class FoldVisitor : public RewritingParseNodeVisitor { } }; -bool Fold(JSContext* cx, FullParseHandler* handler, ParseNode** pnp) { - FoldVisitor visitor(cx, handler); +static bool Fold(JSContext* cx, CompilationInfo& compilationInfo, + FullParseHandler* handler, ParseNode** pnp) { + FoldVisitor visitor(cx, compilationInfo, handler); return visitor.visit(*pnp); } +static bool Fold(FoldInfo info, ParseNode** pnp) { + return Fold(info.cx, info.compilationInfo, info.handler, pnp); +} -bool frontend::FoldConstants(JSContext* cx, ParseNode** pnp, - FullParseHandler* handler) { +bool frontend::FoldConstants(JSContext* cx, CompilationInfo& compilationInfo, + ParseNode** pnp, FullParseHandler* handler) { AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx), TraceLogger_BytecodeFoldConstants); - return Fold(cx, handler, pnp); + return Fold(cx, compilationInfo, handler, pnp); } diff --git a/js/src/frontend/FoldConstants.h b/js/src/frontend/FoldConstants.h index 7882ca91f7..bcb67c0076 100644 --- a/js/src/frontend/FoldConstants.h +++ b/js/src/frontend/FoldConstants.h @@ -10,6 +10,8 @@ namespace js { namespace frontend { +struct CompilationInfo; + class FullParseHandler; template class PerHandlerParser; @@ -29,12 +31,15 @@ class PerHandlerParser; // if (!FoldConstants(cx, &pn, parser)) { // return false; // } -extern MOZ_MUST_USE bool FoldConstants(JSContext* cx, ParseNode** pnp, - FullParseHandler* parser); +extern MOZ_MUST_USE bool FoldConstants(JSContext* cx, + CompilationInfo& compilationInfo, + ParseNode** pnp, + FullParseHandler* handler); inline MOZ_MUST_USE bool FoldConstants(JSContext* cx, + CompilationInfo& compilationInfo, typename SyntaxParseHandler::Node* pnp, - SyntaxParseHandler* parser) { + SyntaxParseHandler* handler) { return true; } diff --git a/js/src/frontend/ForOfEmitter.cpp b/js/src/frontend/ForOfEmitter.cpp index 4d561ba7f4..23175f4bd3 100644 --- a/js/src/frontend/ForOfEmitter.cpp +++ b/js/src/frontend/ForOfEmitter.cpp @@ -118,7 +118,7 @@ bool ForOfEmitter::emitInitialize(const Maybe& forPos) { // [stack] NEXT ITER RESULT RESULT return false; } - if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->names().done)) { + if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->parserNames().done)) { // [stack] NEXT ITER RESULT DONE return false; } @@ -135,7 +135,7 @@ bool ForOfEmitter::emitInitialize(const Maybe& forPos) { // // Note that ES 13.7.5.13, step 5.c says getting result.value does not // call IteratorClose, so start TryNoteKind::ForOfIterClose after the GetProp. - if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->names().value)) { + if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->parserNames().value)) { // [stack] NEXT ITER VALUE return false; } diff --git a/js/src/frontend/Frontend2.cpp b/js/src/frontend/Frontend2.cpp new file mode 100644 index 0000000000..17d602a02e --- /dev/null +++ b/js/src/frontend/Frontend2.cpp @@ -0,0 +1,668 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "frontend/Frontend2.h" + +#include "mozilla/Maybe.h" // mozilla::Maybe +#include "mozilla/OperatorNewExtensions.h" // mozilla::KnownNotNull +#include "mozilla/Range.h" // mozilla::Range +#include "mozilla/Span.h" // mozilla::{Span, Span} +#include "mozilla/Variant.h" // mozilla::AsVariant + +#include // size_t +#include // uint8_t, uint32_t + +#include "jsapi.h" + +#include "frontend/AbstractScopePtr.h" // ScopeIndex +#include "frontend/BytecodeSection.h" // EmitScriptThingsVector +#include "frontend/CompilationInfo.h" // CompilationInfo +#include "frontend/Parser.h" // NewEmptyLexicalScopeData, NewEmptyGlobalScopeData, NewEmptyVarScopeData, NewEmptyFunctionScopeData +#include "frontend/ParserAtom.h" // ParserAtomsTable +#include "frontend/smoosh_generated.h" // CVec, Smoosh*, smoosh_* +#include "frontend/SourceNotes.h" // SrcNote +#include "frontend/Stencil.h" // ScopeStencil, RegExpIndex, FunctionIndex, NullScriptThing +#include "frontend/TokenStream.h" // TokenStreamAnyChars +#include "irregexp/RegExpAPI.h" // irregexp::CheckPatternSyntax +#include "js/CharacterEncoding.h" // JS::UTF8Chars, UTF8CharsToNewTwoByteCharsZ +#include "js/GCAPI.h" // JS::AutoCheckCannotGC +#include "js/HeapAPI.h" // JS::GCCellPtr +#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags +#include "js/RootingAPI.h" // JS::MutableHandle +#include "js/UniquePtr.h" // js::UniquePtr +#include "js/Utility.h" // JS::UniqueTwoByteChars, StringBufferArena +#include "vm/JSScript.h" // JSScript +#include "vm/ScopeKind.h" // ScopeKind +#include "vm/SharedStencil.h" // ImmutableScriptData, ScopeNote, TryNote, GCThingIndex + +using mozilla::Utf8Unit; + +using namespace js::gc; +using namespace js::frontend; +using namespace js; + +namespace js { + +namespace frontend { + +// Given the result of SmooshMonkey's parser, Convert the list of atoms into +// the list of ParserAtoms. +bool ConvertAtoms(JSContext* cx, const SmooshResult& result, + CompilationInfo& compilationInfo, + Vector& allAtoms) { + size_t numAtoms = result.all_atoms_len; + + if (!allAtoms.reserve(numAtoms)) { + return false; + } + + for (size_t i = 0; i < numAtoms; i++) { + auto s = reinterpret_cast( + smoosh_get_atom_at(result, i)); + auto len = smoosh_get_atom_len_at(result, i); + const ParserAtom* atom = + compilationInfo.stencil.parserAtoms.internUtf8(cx, s, len) + .unwrapOr(nullptr); + if (!atom) { + return false; + } + allAtoms.infallibleAppend(atom); + } + + return true; +} + +void CopyBindingNames(JSContext* cx, CVec& from, + Vector& allAtoms, + ParserBindingName* to) { + // We're setting trailing array's content before setting its length. + JS::AutoCheckCannotGC nogc(cx); + + size_t numBindings = from.len; + for (size_t i = 0; i < numBindings; i++) { + SmooshBindingName& name = from.data[i]; + new (mozilla::KnownNotNull, &to[i]) ParserBindingName( + allAtoms[name.name], name.is_closed_over, name.is_top_level_function); + } +} + +void CopyBindingNames(JSContext* cx, CVec>& from, + Vector& allAtoms, + ParserBindingName* to) { + // We're setting trailing array's content before setting its length. + JS::AutoCheckCannotGC nogc(cx); + + size_t numBindings = from.len; + for (size_t i = 0; i < numBindings; i++) { + COption& maybeName = from.data[i]; + if (maybeName.IsSome()) { + SmooshBindingName& name = maybeName.AsSome(); + new (mozilla::KnownNotNull, &to[i]) ParserBindingName( + allAtoms[name.name], name.is_closed_over, name.is_top_level_function); + } else { + new (mozilla::KnownNotNull, &to[i]) + ParserBindingName(nullptr, false, false); + } + } +} + +// Given the result of SmooshMonkey's parser, convert a list of scope data +// into a list of ScopeStencil. +bool ConvertScopeStencil(JSContext* cx, const SmooshResult& result, + Vector& allAtoms, + CompilationInfo& compilationInfo, LifoAlloc& alloc) { + for (size_t i = 0; i < result.scopes.len; i++) { + SmooshScopeData& scopeData = result.scopes.data[i]; + ScopeIndex index; + + switch (scopeData.tag) { + case SmooshScopeData::Tag::Global: { + auto& global = scopeData.AsGlobal(); + + size_t numBindings = global.bindings.len; + ParserGlobalScopeData* data = + NewEmptyGlobalScopeData(cx, alloc, numBindings); + if (!data) { + return false; + } + + CopyBindingNames(cx, global.bindings, allAtoms, + data->trailingNames.start()); + + data->letStart = global.let_start; + data->constStart = global.const_start; + data->length = numBindings; + + if (!ScopeStencil::createForGlobalScope( + cx, compilationInfo.stencil, ScopeKind::Global, data, &index)) { + return false; + } + break; + } + case SmooshScopeData::Tag::Var: { + auto& var = scopeData.AsVar(); + + size_t numBindings = var.bindings.len; + + ParserVarScopeData* data = NewEmptyVarScopeData(cx, alloc, numBindings); + ; + if (!data) { + return false; + } + + CopyBindingNames(cx, var.bindings, allAtoms, + data->trailingNames.start()); + + // NOTE: data->nextFrameSlot is set in ScopeStencil::createForVarScope. + + data->length = numBindings; + + uint32_t firstFrameSlot = var.first_frame_slot; + ScopeIndex enclosingIndex(var.enclosing); + if (!ScopeStencil::createForVarScope( + cx, compilationInfo.stencil, ScopeKind::FunctionBodyVar, data, + firstFrameSlot, var.function_has_extensible_scope, + mozilla::Some(enclosingIndex), &index)) { + return false; + } + break; + } + case SmooshScopeData::Tag::Lexical: { + auto& lexical = scopeData.AsLexical(); + + size_t numBindings = lexical.bindings.len; + ParserLexicalScopeData* data = + NewEmptyLexicalScopeData(cx, alloc, numBindings); + if (!data) { + return false; + } + + CopyBindingNames(cx, lexical.bindings, allAtoms, + data->trailingNames.start()); + + // NOTE: data->nextFrameSlot is set in + // ScopeStencil::createForLexicalScope. + + data->constStart = lexical.const_start; + data->length = numBindings; + + uint32_t firstFrameSlot = lexical.first_frame_slot; + ScopeIndex enclosingIndex(lexical.enclosing); + if (!ScopeStencil::createForLexicalScope( + cx, compilationInfo.stencil, ScopeKind::Lexical, data, + firstFrameSlot, mozilla::Some(enclosingIndex), &index)) { + return false; + } + break; + } + case SmooshScopeData::Tag::Function: { + auto& function = scopeData.AsFunction(); + + size_t numBindings = function.bindings.len; + ParserFunctionScopeData* data = + NewEmptyFunctionScopeData(cx, alloc, numBindings); + if (!data) { + return false; + } + + CopyBindingNames(cx, function.bindings, allAtoms, + data->trailingNames.start()); + + // NOTE: data->nextFrameSlot is set in + // ScopeStencil::createForFunctionScope. + + data->hasParameterExprs = function.has_parameter_exprs; + data->nonPositionalFormalStart = function.non_positional_formal_start; + data->varStart = function.var_start; + data->length = numBindings; + + bool hasParameterExprs = function.has_parameter_exprs; + bool needsEnvironment = function.non_positional_formal_start; + FunctionIndex functionIndex = + FunctionIndex(function.function_index + 1); + bool isArrow = function.is_arrow; + + ScopeIndex enclosingIndex(function.enclosing); + if (!ScopeStencil::createForFunctionScope( + cx, compilationInfo.stencil, data, hasParameterExprs, + needsEnvironment, functionIndex, isArrow, + mozilla::Some(enclosingIndex), &index)) { + return false; + } + break; + } + } + + // `ConvertGCThings` depends on this condition. + MOZ_ASSERT(index == i); + } + + return true; +} + +// Given the result of SmooshMonkey's parser, convert a list of RegExp data +// into a list of RegExpStencil. +bool ConvertRegExpData(JSContext* cx, const SmooshResult& result, + CompilationInfo& compilationInfo) { + for (size_t i = 0; i < result.regexps.len; i++) { + SmooshRegExpItem& item = result.regexps.data[i]; + auto s = smoosh_get_slice_at(result, item.pattern); + auto len = smoosh_get_slice_len_at(result, item.pattern); + + JS::RegExpFlags::Flag flags = JS::RegExpFlag::NoFlags; + if (item.global) { + flags |= JS::RegExpFlag::Global; + } + if (item.ignore_case) { + flags |= JS::RegExpFlag::IgnoreCase; + } + if (item.multi_line) { + flags |= JS::RegExpFlag::Multiline; + } + if (item.dot_all) { + flags |= JS::RegExpFlag::DotAll; + } + if (item.sticky) { + flags |= JS::RegExpFlag::Sticky; + } + if (item.unicode) { + flags |= JS::RegExpFlag::Unicode; + } + + // FIXME: This check should be done at parse time. + size_t length; + JS::UniqueTwoByteChars pattern( + UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(s, len), &length, + StringBufferArena) + .get()); + if (!pattern) { + return false; + } + + mozilla::Range range(pattern.get(), length); + + TokenStreamAnyChars ts(cx, compilationInfo.input.options, + /* smg = */ nullptr); + + // See Parser::newRegExp. + + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + if (!irregexp::CheckPatternSyntax(cx, ts, range, flags)) { + return false; + } + + RegExpIndex index(compilationInfo.stencil.regExpData.length()); + if (!compilationInfo.stencil.regExpData.emplaceBack()) { + js::ReportOutOfMemory(cx); + return false; + } + + if (!compilationInfo.stencil.regExpData[index].init( + cx, range, JS::RegExpFlags(flags))) { + return false; + } + + // `ConvertGCThings` depends on this condition. + MOZ_ASSERT(index.index == i); + } + + return true; +} + +// Convert SmooshImmutableScriptData into ImmutableScriptData. +UniquePtr ConvertImmutableScriptData( + JSContext* cx, const SmooshImmutableScriptData& smooshScriptData, + bool isFunction) { + Vector scopeNotes; + if (!scopeNotes.resize(smooshScriptData.scope_notes.len)) { + return nullptr; + } + for (size_t i = 0; i < smooshScriptData.scope_notes.len; i++) { + SmooshScopeNote& scopeNote = smooshScriptData.scope_notes.data[i]; + scopeNotes[i].index = GCThingIndex(scopeNote.index); + scopeNotes[i].start = scopeNote.start; + scopeNotes[i].length = scopeNote.length; + scopeNotes[i].parent = scopeNote.parent; + } + + return ImmutableScriptData::new_( + cx, smooshScriptData.main_offset, smooshScriptData.nfixed, + smooshScriptData.nslots, GCThingIndex(smooshScriptData.body_scope_index), + smooshScriptData.num_ic_entries, smooshScriptData.num_bytecode_type_sets, + isFunction, smooshScriptData.fun_length, + mozilla::Span(smooshScriptData.bytecode.data, + smooshScriptData.bytecode.len), + mozilla::Span(), mozilla::Span(), + scopeNotes, mozilla::Span()); +} + +// Given the result of SmooshMonkey's parser, convert a list of GC things +// used by a script into ScriptThingsVector. +bool ConvertGCThings(JSContext* cx, const SmooshResult& result, + const SmooshScriptStencil& smooshScript, + Vector& allAtoms, + ScriptStencil& script) { + auto& gcThings = script.gcThings; + + size_t ngcthings = smooshScript.gcthings.len; + if (!gcThings.reserve(ngcthings)) { + js::ReportOutOfMemory(cx); + return false; + } + + for (size_t i = 0; i < ngcthings; i++) { + SmooshGCThing& item = smooshScript.gcthings.data[i]; + + switch (item.tag) { + case SmooshGCThing::Tag::Null: { + gcThings.infallibleAppend(NullScriptThing()); + break; + } + case SmooshGCThing::Tag::Atom: { + gcThings.infallibleAppend(mozilla::AsVariant(allAtoms[item.AsAtom()])); + break; + } + case SmooshGCThing::Tag::Function: { + gcThings.infallibleAppend( + mozilla::AsVariant(FunctionIndex(item.AsFunction() + 1))); + break; + } + case SmooshGCThing::Tag::Scope: { + gcThings.infallibleAppend( + mozilla::AsVariant(ScopeIndex(item.AsScope()))); + break; + } + case SmooshGCThing::Tag::RegExp: { + gcThings.infallibleAppend( + mozilla::AsVariant(RegExpIndex(item.AsRegExp()))); + break; + } + } + } + + return true; +} + +// Given the result of SmooshMonkey's parser, convert a specific script +// or function to a StencilScript, given a fixed set of source atoms. +// +// The StencilScript would then be in charge of handling the lifetime and +// (until GC things gets removed from stencil) tracing API of the GC. +bool ConvertScriptStencil(JSContext* cx, const SmooshResult& result, + const SmooshScriptStencil& smooshScript, + Vector& allAtoms, + CompilationInfo& compilationInfo, + ScriptStencil& script) { + using ImmutableFlags = js::ImmutableScriptFlagsEnum; + + const JS::ReadOnlyCompileOptions& options = compilationInfo.input.options; + + script.immutableFlags = smooshScript.immutable_flags; + + // FIXME: The following flags should be set in jsparagus. + script.immutableFlags.setFlag(ImmutableFlags::SelfHosted, + options.selfHostingMode); + script.immutableFlags.setFlag(ImmutableFlags::ForceStrict, + options.forceStrictMode()); + script.immutableFlags.setFlag(ImmutableFlags::HasNonSyntacticScope, + options.nonSyntacticScope); + + if (&smooshScript == &result.top_level_script) { + script.immutableFlags.setFlag(ImmutableFlags::TreatAsRunOnce, + options.isRunOnce); + script.immutableFlags.setFlag(ImmutableFlags::NoScriptRval, + options.noScriptRval); + } + + bool isFunction = script.immutableFlags.hasFlag(ImmutableFlags::IsFunction); + + if (smooshScript.immutable_script_data.IsSome()) { + auto index = smooshScript.immutable_script_data.AsSome(); + auto immutableScriptData = ConvertImmutableScriptData( + cx, result.script_data_list.data[index], isFunction); + if (!immutableScriptData) { + return false; + } + script.immutableScriptData = std::move(immutableScriptData); + } + + script.extent.sourceStart = smooshScript.extent.source_start; + script.extent.sourceEnd = smooshScript.extent.source_end; + script.extent.toStringStart = smooshScript.extent.to_string_start; + script.extent.toStringEnd = smooshScript.extent.to_string_end; + script.extent.lineno = smooshScript.extent.lineno; + script.extent.column = smooshScript.extent.column; + + if (isFunction) { + if (smooshScript.fun_name.IsSome()) { + script.functionAtom = allAtoms[smooshScript.fun_name.AsSome()]; + } + script.functionFlags = FunctionFlags(smooshScript.fun_flags); + script.nargs = smooshScript.fun_nargs; + if (smooshScript.lazy_function_enclosing_scope_index.IsSome()) { + script.lazyFunctionEnclosingScopeIndex_ = mozilla::Some(ScopeIndex( + smooshScript.lazy_function_enclosing_scope_index.AsSome())); + } + script.isStandaloneFunction = smooshScript.is_standalone_function; + script.wasFunctionEmitted = smooshScript.was_function_emitted; + script.isSingletonFunction = smooshScript.is_singleton_function; + } + + if (!ConvertGCThings(cx, result, smooshScript, allAtoms, script)) { + return false; + } + + return true; +} + +// Free given SmooshResult on leaving scope. +class AutoFreeSmooshResult { + SmooshResult* result_; + + public: + AutoFreeSmooshResult() = delete; + + explicit AutoFreeSmooshResult(SmooshResult* result) : result_(result) {} + ~AutoFreeSmooshResult() { + if (result_) { + smoosh_free(*result_); + } + } +}; + +// Free given SmooshParseResult on leaving scope. +class AutoFreeSmooshParseResult { + SmooshParseResult* result_; + + public: + AutoFreeSmooshParseResult() = delete; + + explicit AutoFreeSmooshParseResult(SmooshParseResult* result) + : result_(result) {} + ~AutoFreeSmooshParseResult() { + if (result_) { + smoosh_free_parse_result(*result_); + } + } +}; + +void InitSmoosh() { smoosh_init(); } + +void ReportSmooshCompileError(JSContext* cx, ErrorMetadata&& metadata, + int errorNumber, ...) { + va_list args; + va_start(args, errorNumber); + ReportCompileErrorUTF8(cx, std::move(metadata), /* notes = */ nullptr, + errorNumber, &args); + va_end(args); +} + +/* static */ +bool Smoosh::compileGlobalScriptToStencil(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + bool* unimplemented) { + // FIXME: check info members and return with *unimplemented = true + // if any field doesn't match to smoosh_run. + + auto bytes = reinterpret_cast(srcBuf.get()); + size_t length = srcBuf.length(); + + const auto& options = compilationInfo.input.options; + SmooshCompileOptions compileOptions; + compileOptions.no_script_rval = options.noScriptRval; + + SmooshResult result = smoosh_run(bytes, length, &compileOptions); + AutoFreeSmooshResult afsr(&result); + + if (result.error.data) { + *unimplemented = false; + ErrorMetadata metadata; + metadata.filename = ""; + metadata.lineNumber = 1; + metadata.columnNumber = 0; + metadata.isMuted = false; + ReportSmooshCompileError(cx, std::move(metadata), + JSMSG_SMOOSH_COMPILE_ERROR, + reinterpret_cast(result.error.data)); + return false; + } + + if (result.unimplemented) { + *unimplemented = true; + return false; + } + + *unimplemented = false; + + Vector allAtoms(cx); + if (!ConvertAtoms(cx, result, compilationInfo, allAtoms)) { + return false; + } + + LifoAllocScope allocScope(&cx->tempLifoAlloc()); + auto& alloc = allocScope.alloc(); + if (!ConvertScopeStencil(cx, result, allAtoms, compilationInfo, alloc)) { + return false; + } + + if (!ConvertRegExpData(cx, result, compilationInfo)) { + return false; + } + + if (!compilationInfo.stencil.scriptData.reserve(result.functions.len + 1)) { + js::ReportOutOfMemory(cx); + return false; + } + + compilationInfo.stencil.scriptData.infallibleEmplaceBack(); + + if (!ConvertScriptStencil( + cx, result, result.top_level_script, allAtoms, compilationInfo, + compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex])) { + return false; + } + + for (size_t i = 0; i < result.functions.len; i++) { + compilationInfo.stencil.scriptData.infallibleEmplaceBack(); + + if (!ConvertScriptStencil(cx, result, result.functions.data[i], allAtoms, + compilationInfo, + compilationInfo.stencil.scriptData[i + 1])) { + return false; + } + } + + return true; +} + +/* static */ +UniquePtr Smoosh::compileGlobalScriptToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, bool* unimplemented) { + Rooted> compilationInfo( + cx, js_new(cx, options)); + if (!compilationInfo) { + ReportOutOfMemory(cx); + return nullptr; + } + + if (!compilationInfo.get()->input.initForGlobal(cx)) { + return nullptr; + } + + if (!compileGlobalScriptToStencil(cx, *compilationInfo.get().get(), srcBuf, + unimplemented)) { + return nullptr; + } + + return std::move(compilationInfo.get()); +} + +/* static */ +bool Smoosh::compileGlobalScript(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + CompilationGCOutput& gcOutput, + bool* unimplemented) { + if (!compileGlobalScriptToStencil(cx, compilationInfo, srcBuf, + unimplemented)) { + return false; + } + + if (!compilationInfo.instantiateStencils(cx, gcOutput)) { + return false; + } + +#if defined(DEBUG) || defined(JS_JITSPEW) + Sprinter sprinter(cx); + if (!sprinter.init()) { + return false; + } + if (!Disassemble(cx, gcOutput.script, true, &sprinter, + DisassembleSkeptically::Yes)) { + return false; + } + printf("%s\n", sprinter.string()); + if (!Disassemble(cx, gcOutput.script, true, &sprinter, + DisassembleSkeptically::No)) { + return false; + } + // (don't bother printing it) +#endif + + return true; +} + +bool SmooshParseScript(JSContext* cx, const uint8_t* bytes, size_t length) { + SmooshParseResult result = smoosh_test_parse_script(bytes, length); + AutoFreeSmooshParseResult afspr(&result); + if (result.error.data) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, + result.unimplemented ? JSMSG_SMOOSH_UNIMPLEMENTED + : JSMSG_SMOOSH_COMPILE_ERROR, + reinterpret_cast(result.error.data)); + return false; + } + + return true; +} + +bool SmooshParseModule(JSContext* cx, const uint8_t* bytes, size_t length) { + SmooshParseResult result = smoosh_test_parse_module(bytes, length); + AutoFreeSmooshParseResult afspr(&result); + if (result.error.data) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, + result.unimplemented ? JSMSG_SMOOSH_UNIMPLEMENTED + : JSMSG_SMOOSH_COMPILE_ERROR, + reinterpret_cast(result.error.data)); + return false; + } + + return true; +} + +} // namespace frontend + +} // namespace js diff --git a/js/src/frontend/Frontend2.h b/js/src/frontend/Frontend2.h new file mode 100644 index 0000000000..e28866571a --- /dev/null +++ b/js/src/frontend/Frontend2.h @@ -0,0 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 frontend_Frontend2_h +#define frontend_Frontend2_h + +#include "mozilla/Utf8.h" // mozilla::Utf8Unit + +#include // size_t +#include // uint8_t + +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions +#include "js/RootingAPI.h" // JS::Handle +#include "js/SourceText.h" // JS::SourceText +#include "js/UniquePtr.h" // js::UniquePtr +#include "vm/JSScript.h" // JSScript + +struct JSContext; + +struct SmooshResult; + +namespace js { + +class ScriptSourceObject; + +namespace frontend { + +struct CompilationInfo; +struct CompilationGCOutput; +struct CompilationState; + +// This is declarated as a class mostly to solve dependency around `friend` +// declarations in the simple way. +class Smoosh { + public: + static bool compileGlobalScript(JSContext* cx, + CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, + CompilationGCOutput& gcOutput, + bool* unimplemented); + + static bool compileGlobalScriptToStencil( + JSContext* cx, CompilationInfo& compilationInfo, + JS::SourceText& srcBuf, bool* unimplemented); + + static UniquePtr compileGlobalScriptToStencil( + JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JS::SourceText& srcBuf, bool* unimplemented); +}; + +// Initialize SmooshMonkey globals, such as the logging system. +void InitSmoosh(); + +// Use the SmooshMonkey frontend to parse and free the generated AST. Returns +// true if no error were detected while parsing. +MOZ_MUST_USE bool SmooshParseScript(JSContext* cx, const uint8_t* bytes, + size_t length); +MOZ_MUST_USE bool SmooshParseModule(JSContext* cx, const uint8_t* bytes, + size_t length); + +} // namespace frontend + +} // namespace js + +#endif /* frontend_Frontend2_h */ diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index b5e81abaf8..c963081ea1 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -6,12 +6,14 @@ #define frontend_FullParseHandler_h #include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" // mozilla::Maybe #include "mozilla/PodOperations.h" #include // std::nullptr_t #include #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind +#include "frontend/NameAnalysisTypes.h" // PrivateNameKind #include "frontend/ParseNode.h" #include "frontend/SharedContext.h" #include "frontend/Stencil.h" @@ -28,8 +30,6 @@ class TokenStreamAnyChars; enum class SourceKind { // We are parsing from a text source (Parser.h) Text, - // We are parsing from a binary source (BinASTParser.h) - Binary, }; // Parse handler used when generating a full parse tree for all code which the @@ -49,6 +49,9 @@ class FullParseHandler { * - lazyOuterFunction_ holds the lazyScript for this current parse * - lazyInnerFunctionIndex is used as we skip over inner functions * (see skipLazyInnerFunction), + * + * TODO-Stencil: We probably need to snapshot the atoms from the + * lazyOuterFunction here. */ const Rooted lazyOuterFunction_; size_t lazyInnerFunctionIndex; @@ -131,14 +134,15 @@ class FullParseHandler { FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) #undef DECLARE_AS - // The FullParseHandler may be used to create nodes for text sources - // (from Parser.h) or for binary sources (from BinASTParser.h). In the latter - // case, some common assumptions on offsets are incorrect, e.g. in `a + b`, - // `a`, `b` and `+` may be stored in any order. We use `sourceKind()` - // to determine whether we need to check these assumptions. + // The FullParseHandler may be used to create nodes for text sources (from + // Parser.h). With previous binary source formats, some common assumptions on + // offsets are incorrect, e.g. in `a + b`, `a`, `b` and `+` may be stored in + // any order. We use `sourceKind()` to determine whether we need to check + // these assumptions. SourceKind sourceKind() const { return sourceKind_; } - NameNodeType newName(PropertyName* name, const TokenPos& pos, JSContext* cx) { + NameNodeType newName(const ParserName* name, const TokenPos& pos, + JSContext* cx) { return new_(ParseNodeKind::Name, name, pos); } @@ -147,30 +151,46 @@ class FullParseHandler { return new_(ParseNodeKind::ComputedName, pos, expr); } - NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { + UnaryNodeType newSyntheticComputedName(Node expr, uint32_t begin, + uint32_t end) { + TokenPos pos(begin, end); + UnaryNode* node = new_(ParseNodeKind::ComputedName, pos, expr); + if (!node) { + return nullptr; + } + node->setSyntheticComputedName(); + return node; + } + + NameNodeType newObjectLiteralPropertyName(const ParserAtom* atom, + const TokenPos& pos) { return new_(ParseNodeKind::ObjectPropertyName, atom, pos); } + NameNodeType newPrivateName(const ParserAtom* atom, const TokenPos& pos) { + return new_(ParseNodeKind::PrivateName, atom, pos); + } + NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return new_(value, decimalPoint, pos); } - BigIntLiteralType newBigInt(BigIntIndex index, - CompilationInfo& compilationInfo, + BigIntLiteralType newBigInt(BigIntIndex index, CompilationStencil& stencil, const TokenPos& pos) { - return new_(index, compilationInfo, pos); + return new_(index, stencil, pos); } BooleanLiteralType newBooleanLiteral(bool cond, const TokenPos& pos) { return new_(cond, pos); } - NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newStringLiteral(const ParserAtom* atom, const TokenPos& pos) { return new_(ParseNodeKind::StringExpr, atom, pos); } - NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newTemplateStringLiteral(const ParserAtom* atom, + const TokenPos& pos) { return new_(ParseNodeKind::TemplateStringExpr, atom, pos); } @@ -304,7 +324,6 @@ class FullParseHandler { return false; } addList(/* list = */ literal, /* kid = */ elision); - literal->setHasArrayHoleOrSpread(); literal->setHasNonConstInitializer(); return true; } @@ -318,7 +337,6 @@ class FullParseHandler { return false; } addList(/* list = */ literal, /* kid = */ spread); - literal->setHasArrayHoleOrSpread(); literal->setHasNonConstInitializer(); return true; } @@ -470,15 +488,18 @@ class FullParseHandler { return true; } - MOZ_MUST_USE ClassMethod* newClassMethodDefinition(Node key, - FunctionNodeType funNode, - AccessorType atype, - bool isStatic) { + MOZ_MUST_USE ClassMethod* newClassMethodDefinition( + Node key, FunctionNodeType funNode, AccessorType atype, bool isStatic, + mozilla::Maybe initializerIfPrivate) { MOZ_ASSERT(isUsableAsObjectPropertyName(key)); checkAndSetIsDirectRHSAnonFunction(funNode); - return new_(key, funNode, atype, isStatic); + if (initializerIfPrivate.isSome()) { + return new_(key, funNode, atype, isStatic, + initializerIfPrivate.value()); + } + return new_(key, funNode, atype, isStatic, nullptr); } MOZ_MUST_USE ClassField* newClassFieldDefinition(Node name, @@ -719,12 +740,12 @@ class FullParseHandler { return new_(expr, body, begin); } - ContinueStatementType newContinueStatement(PropertyName* label, + ContinueStatementType newContinueStatement(const ParserName* label, const TokenPos& pos) { return new_(label, pos); } - BreakStatementType newBreakStatement(PropertyName* label, + BreakStatementType newBreakStatement(const ParserName* label, const TokenPos& pos) { return new_(label, pos); } @@ -744,7 +765,7 @@ class FullParseHandler { TokenPos(begin, body->pn_pos.end), expr, body); } - LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, + LabeledStatementType newLabeledStatement(const ParserName* label, Node stmt, uint32_t begin) { return new_(label, stmt, begin); } @@ -764,7 +785,7 @@ class FullParseHandler { return new_(pos); } - NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) { + NameNodeType newPropertyName(const ParserName* name, const TokenPos& pos) { return new_(ParseNodeKind::PropertyNameExpr, name, pos); } @@ -856,7 +877,8 @@ class FullParseHandler { return new_(pos); } - LexicalScopeNodeType newLexicalScope(LexicalScope::Data* bindings, Node body, + LexicalScopeNodeType newLexicalScope(ParserLexicalScopeData* bindings, + Node body, ScopeKind kind = ScopeKind::Lexical) { return new_(bindings, body, kind); } @@ -919,7 +941,8 @@ class FullParseHandler { node->isKind(ParseNodeKind::BigIntExpr) || node->isKind(ParseNodeKind::ObjectPropertyName) || node->isKind(ParseNodeKind::StringExpr) || - node->isKind(ParseNodeKind::ComputedName); + node->isKind(ParseNodeKind::ComputedName) || + node->isKind(ParseNodeKind::PrivateName); } AssignmentNodeType finishInitializerAssignment(NameNodeType nameNode, @@ -1014,28 +1037,46 @@ class FullParseHandler { bool isArgumentsName(Node node, JSContext* cx) { return node->isKind(ParseNodeKind::Name) && - node->as().atom() == cx->names().arguments; + node->as().atom() == cx->parserNames().arguments; } bool isEvalName(Node node, JSContext* cx) { return node->isKind(ParseNodeKind::Name) && - node->as().atom() == cx->names().eval; + node->as().atom() == cx->parserNames().eval; } bool isAsyncKeyword(Node node, JSContext* cx) { return node->isKind(ParseNodeKind::Name) && node->pn_pos.begin + strlen("async") == node->pn_pos.end && - node->as().atom() == cx->names().async; + node->as().atom() == cx->parserNames().async; } - PropertyName* maybeDottedProperty(Node pn) { - return pn->is() ? &pn->as().name() + bool isPrivateName(Node node) { + return node->isKind(ParseNodeKind::PrivateName); + } + + bool isPrivateField(Node node) { + if (node->isKind(ParseNodeKind::ElemExpr) || + node->isKind(ParseNodeKind::OptionalElemExpr)) { + PropertyByValueBase& pbv = node->as(); + if (isPrivateName(&pbv.key())) { + return true; + } + } + if (node->isKind(ParseNodeKind::OptionalChain)) { + return isPrivateField(node->as().kid()); + } + return false; + } + + const ParserName* maybeDottedProperty(Node pn) { + return pn->is() ? pn->as().name() : nullptr; } - JSAtom* isStringExprStatement(Node pn, TokenPos* pos) { + const ParserAtom* isStringExprStatement(Node pn, TokenPos* pos) { if (pn->is()) { UnaryNode* unary = &pn->as(); - if (JSAtom* atom = unary->isStringExprStatement()) { + if (const ParserAtom* atom = unary->isStringExprStatement()) { *pos = unary->kid()->pn_pos; return atom; } @@ -1065,6 +1106,11 @@ class FullParseHandler { MOZ_ASSERT_IF(cell, cell->as()->isAtom()); return static_cast(cell); } + + void setPrivateNameKind(Node node, PrivateNameKind kind) { + MOZ_ASSERT(node->is()); + node->as().setPrivateNameKind(kind); + } }; inline bool FullParseHandler::setLastFunctionFormalParameterDefault( diff --git a/js/src/frontend/FunctionEmitter.cpp b/js/src/frontend/FunctionEmitter.cpp index eb2c3c9d45..37bd08e524 100644 --- a/js/src/frontend/FunctionEmitter.cpp +++ b/js/src/frontend/FunctionEmitter.cpp @@ -17,6 +17,7 @@ #include "frontend/SharedContext.h" // SharedContext #include "vm/AsyncFunctionResolveKind.h" // AsyncFunctionResolveKind #include "vm/JSScript.h" // JSScript +#include "vm/ModuleBuilder.h" // ModuleBuilder #include "vm/Opcodes.h" // JSOp #include "vm/Scope.h" // BindingKind #include "wasm/AsmJS.h" // IsAsmJSModule @@ -32,7 +33,7 @@ FunctionEmitter::FunctionEmitter(BytecodeEmitter* bce, FunctionBox* funbox, IsHoisted isHoisted) : bce_(bce), funbox_(funbox), - name_(bce_->cx, funbox_->explicitName()), + name_(funbox_->explicitName()), syntaxKind_(syntaxKind), isHoisted_(isHoisted) {} @@ -41,11 +42,11 @@ bool FunctionEmitter::prepareForNonLazy() { MOZ_ASSERT(funbox_->isInterpreted()); MOZ_ASSERT(funbox_->emitBytecode); - MOZ_ASSERT(!funbox_->wasEmitted); + MOZ_ASSERT(!funbox_->wasEmitted()); // [stack] - funbox_->wasEmitted = true; + funbox_->setWasEmitted(true); #ifdef DEBUG state_ = State::NonLazy; @@ -74,15 +75,15 @@ bool FunctionEmitter::emitLazy() { MOZ_ASSERT(funbox_->isInterpreted()); MOZ_ASSERT(!funbox_->emitBytecode); - MOZ_ASSERT(!funbox_->wasEmitted); + MOZ_ASSERT(!funbox_->wasEmitted()); // [stack] - funbox_->wasEmitted = true; + funbox_->setWasEmitted(true); // Prepare to update the inner lazy script now that it's parent is fully - // compiled. These updates will be applied in FunctionBox::finish(). - funbox_->setEnclosingScopeForInnerLazyFunction(bce_->innermostScope()); + // compiled. These updates will be applied in UpdateEmittedInnerFunctions(). + funbox_->setEnclosingScopeForInnerLazyFunction(bce_->innermostScopeIndex()); if (!emitFunction()) { // [stack] FUN? @@ -97,7 +98,7 @@ bool FunctionEmitter::emitLazy() { bool FunctionEmitter::emitAgain() { MOZ_ASSERT(state_ == State::Start); - MOZ_ASSERT(funbox_->wasEmitted); + MOZ_ASSERT(funbox_->wasEmitted()); // [stack] @@ -166,12 +167,12 @@ bool FunctionEmitter::emitAgain() { bool FunctionEmitter::emitAsmJSModule() { MOZ_ASSERT(state_ == State::Start); - MOZ_ASSERT(!funbox_->wasEmitted); + MOZ_ASSERT(!funbox_->wasEmitted()); MOZ_ASSERT(funbox_->isAsmJSModule()); // [stack] - funbox_->wasEmitted = true; + funbox_->setWasEmitted(true); if (!emitFunction()) { // [stack] @@ -186,7 +187,7 @@ bool FunctionEmitter::emitAsmJSModule() { bool FunctionEmitter::emitFunction() { // Make the function object a literal in the outer script's pool. - uint32_t index; + GCThingIndex index; if (!bce_->perScriptData().gcThingList().append(funbox_, &index)) { return false; } @@ -221,7 +222,7 @@ bool FunctionEmitter::emitFunction() { // [stack] } -bool FunctionEmitter::emitNonHoisted(unsigned index) { +bool FunctionEmitter::emitNonHoisted(GCThingIndex index) { // Non-hoisted functions simply emit their respective op. // [stack] @@ -239,7 +240,7 @@ bool FunctionEmitter::emitNonHoisted(unsigned index) { if (syntaxKind_ == FunctionSyntaxKind::DerivedClassConstructor) { // [stack] PROTO - if (!bce_->emitIndexOp(JSOp::FunWithProto, index)) { + if (!bce_->emitGCIndexOp(JSOp::FunWithProto, index)) { // [stack] FUN return false; } @@ -250,7 +251,7 @@ bool FunctionEmitter::emitNonHoisted(unsigned index) { // constructor. Emit the single instruction (without location info). JSOp op = syntaxKind_ == FunctionSyntaxKind::Arrow ? JSOp::LambdaArrow : JSOp::Lambda; - if (!bce_->emitIndexOp(op, index)) { + if (!bce_->emitGCIndexOp(op, index)) { // [stack] FUN return false; } @@ -258,7 +259,7 @@ bool FunctionEmitter::emitNonHoisted(unsigned index) { return true; } -bool FunctionEmitter::emitHoisted(unsigned index) { +bool FunctionEmitter::emitHoisted(GCThingIndex index) { MOZ_ASSERT(syntaxKind_ == FunctionSyntaxKind::Statement); // [stack] @@ -272,7 +273,7 @@ bool FunctionEmitter::emitHoisted(unsigned index) { return false; } - if (!bce_->emitIndexOp(JSOp::Lambda, index)) { + if (!bce_->emitGCIndexOp(JSOp::Lambda, index)) { // [stack] FUN return false; } @@ -290,26 +291,21 @@ bool FunctionEmitter::emitHoisted(unsigned index) { return true; } -bool FunctionEmitter::emitTopLevelFunction(unsigned index) { +bool FunctionEmitter::emitTopLevelFunction(GCThingIndex index) { // [stack] if (bce_->sc->isModuleContext()) { // For modules, we record the function and instantiate the binding // during ModuleInstantiate(), before the script is run. - - JS::Rooted module(bce_->cx, - bce_->sc->asModuleContext()->module()); - if (!module->noteFunctionDeclaration(bce_->cx, name_, index)) { - return false; - } - return true; + return bce_->sc->asModuleContext()->builder.noteFunctionDeclaration( + bce_->cx, index); } MOZ_ASSERT(bce_->sc->isGlobalContext() || bce_->sc->isEvalContext()); MOZ_ASSERT(syntaxKind_ == FunctionSyntaxKind::Statement); MOZ_ASSERT(bce_->inPrologue()); - if (!bce_->emitIndexOp(JSOp::Lambda, index)) { + if (!bce_->emitGCIndexOp(JSOp::Lambda, index)) { // [stack] FUN return false; } @@ -441,7 +437,7 @@ bool FunctionScriptEmitter::prepareForBody() { if (funbox_->isClassConstructor()) { if (!funbox_->isDerivedClassConstructor()) { - if (!bce_->emitInitializeInstanceFields()) { + if (!bce_->emitInitializeInstanceMembers()) { // [stack] return false; } @@ -517,8 +513,9 @@ bool FunctionScriptEmitter::emitExtraBodyVarScope() { // // function f(x, y = 42) { var y; } // - JS::Rooted name(bce_->cx); - for (BindingIter bi(*funbox_->functionScopeBindings(), true); bi; bi++) { + const ParserAtom* name = nullptr; + for (ParserBindingIter bi(*funbox_->functionScopeBindings(), true); bi; + bi++) { name = bi.name(); // There may not be a var binding of the same name. @@ -530,8 +527,8 @@ bool FunctionScriptEmitter::emitExtraBodyVarScope() { // The '.this' and '.generator' function special // bindings should never appear in the extra var // scope. 'arguments', however, may. - MOZ_ASSERT(name != bce_->cx->names().dotThis && - name != bce_->cx->names().dotGenerator); + MOZ_ASSERT(name != bce_->cx->parserNames().dotThis && + name != bce_->cx->parserNames().dotGenerator); NameOpEmitter noe(bce_, name, NameOpEmitter::Kind::Initialize); if (!noe.prepareForRhs()) { @@ -697,16 +694,10 @@ bool FunctionScriptEmitter::emitEndBody() { return true; } -bool FunctionScriptEmitter::intoStencil(TopLevelFunction isTopLevel) { +bool FunctionScriptEmitter::intoStencil() { MOZ_ASSERT(state_ == State::EndBody); - // If this function is the top-level of the compile, store directly into the - // CompilationInfo like all other top-level scripts. - ScriptStencil* stencilPtr = isTopLevel == TopLevelFunction::Yes - ? bce_->compilationInfo.topLevel.address() - : funbox_->functionStencil().address(); - - if (!bce_->intoScriptStencil(stencilPtr)) { + if (!bce_->intoScriptStencil(&funbox_->functionStencil())) { return false; } @@ -723,7 +714,7 @@ FunctionParamsEmitter::FunctionParamsEmitter(BytecodeEmitter* bce, funbox_(funbox), functionEmitterScope_(bce_->innermostEmitterScope()) {} -bool FunctionParamsEmitter::emitSimple(JS::Handle paramName) { +bool FunctionParamsEmitter::emitSimple(const ParserAtom* paramName) { MOZ_ASSERT(state_ == State::Start); // [stack] @@ -760,7 +751,7 @@ bool FunctionParamsEmitter::prepareForDefault() { return true; } -bool FunctionParamsEmitter::emitDefaultEnd(JS::Handle paramName) { +bool FunctionParamsEmitter::emitDefaultEnd(const ParserAtom* paramName) { MOZ_ASSERT(state_ == State::Default); // [stack] DEFAULT @@ -866,7 +857,7 @@ bool FunctionParamsEmitter::emitDestructuringDefaultEnd() { return true; } -bool FunctionParamsEmitter::emitRest(JS::Handle paramName) { +bool FunctionParamsEmitter::emitRest(const ParserAtom* paramName) { MOZ_ASSERT(state_ == State::Start); // [stack] @@ -957,7 +948,7 @@ bool FunctionParamsEmitter::emitRestArray() { return true; } -bool FunctionParamsEmitter::emitAssignment(JS::Handle paramName) { +bool FunctionParamsEmitter::emitAssignment(const ParserAtom* paramName) { // [stack] ARG NameLocation paramLoc = diff --git a/js/src/frontend/FunctionEmitter.h b/js/src/frontend/FunctionEmitter.h index f353eb22be..2cc1854a92 100644 --- a/js/src/frontend/FunctionEmitter.h +++ b/js/src/frontend/FunctionEmitter.h @@ -19,6 +19,7 @@ #include "vm/BytecodeUtil.h" // JSOp #include "vm/JSAtom.h" // JSAtom #include "vm/JSFunction.h" // JSFunction +#include "vm/SharedStencil.h" // GCThingIndex namespace js { namespace frontend { @@ -69,7 +70,7 @@ class MOZ_STACK_CLASS FunctionEmitter { FunctionBox* funbox_; // Function's explicit name. - JS::Rooted name_; + const ParserAtom* name_; FunctionSyntaxKind syntaxKind_; IsHoisted isHoisted_; @@ -134,9 +135,9 @@ class MOZ_STACK_CLASS FunctionEmitter { // Helper methods used by emitFunction for each case. // `index` is the object index of the function. - MOZ_MUST_USE bool emitNonHoisted(unsigned index); - MOZ_MUST_USE bool emitHoisted(unsigned index); - MOZ_MUST_USE bool emitTopLevelFunction(unsigned index); + MOZ_MUST_USE bool emitNonHoisted(GCThingIndex index); + MOZ_MUST_USE bool emitHoisted(GCThingIndex index); + MOZ_MUST_USE bool emitTopLevelFunction(GCThingIndex index); MOZ_MUST_USE bool emitNewTargetForArrow(); }; @@ -247,7 +248,7 @@ class MOZ_STACK_CLASS FunctionScriptEmitter { MOZ_MUST_USE bool emitEndBody(); // Generate the ScriptStencil using the bytecode emitter data. - MOZ_MUST_USE bool intoStencil(TopLevelFunction isTopLevel); + MOZ_MUST_USE bool intoStencil(); private: MOZ_MUST_USE bool emitExtraBodyVarScope(); @@ -407,10 +408,10 @@ class MOZ_STACK_CLASS FunctionParamsEmitter { // paramName is used only when there's at least one expression in the // paramerters (funbox_->hasParameterExprs == true). - MOZ_MUST_USE bool emitSimple(JS::Handle paramName); + MOZ_MUST_USE bool emitSimple(const ParserAtom* paramName); MOZ_MUST_USE bool prepareForDefault(); - MOZ_MUST_USE bool emitDefaultEnd(JS::Handle paramName); + MOZ_MUST_USE bool emitDefaultEnd(const ParserAtom* paramName); MOZ_MUST_USE bool prepareForDestructuring(); MOZ_MUST_USE bool emitDestructuringEnd(); @@ -419,7 +420,7 @@ class MOZ_STACK_CLASS FunctionParamsEmitter { MOZ_MUST_USE bool prepareForDestructuringDefault(); MOZ_MUST_USE bool emitDestructuringDefaultEnd(); - MOZ_MUST_USE bool emitRest(JS::Handle paramName); + MOZ_MUST_USE bool emitRest(const ParserAtom* paramName); MOZ_MUST_USE bool prepareForDestructuringRest(); MOZ_MUST_USE bool emitDestructuringRestEnd(); @@ -430,7 +431,7 @@ class MOZ_STACK_CLASS FunctionParamsEmitter { MOZ_MUST_USE bool emitRestArray(); - MOZ_MUST_USE bool emitAssignment(JS::Handle paramName); + MOZ_MUST_USE bool emitAssignment(const ParserAtom* paramName); }; } /* namespace frontend */ diff --git a/js/src/frontend/LabelEmitter.cpp b/js/src/frontend/LabelEmitter.cpp index 75ee93bcdf..e8b0294e71 100644 --- a/js/src/frontend/LabelEmitter.cpp +++ b/js/src/frontend/LabelEmitter.cpp @@ -11,7 +11,7 @@ using namespace js; using namespace js::frontend; -void LabelEmitter::emitLabel(HandleAtom name) { +void LabelEmitter::emitLabel(const ParserAtom* name) { MOZ_ASSERT(state_ == State::Start); controlInfo_.emplace(bce_, name, bce_->bytecodeSection().offset()); diff --git a/js/src/frontend/LabelEmitter.h b/js/src/frontend/LabelEmitter.h index fac1eeea33..444b1ab950 100644 --- a/js/src/frontend/LabelEmitter.h +++ b/js/src/frontend/LabelEmitter.h @@ -58,7 +58,7 @@ class MOZ_STACK_CLASS LabelEmitter { public: explicit LabelEmitter(BytecodeEmitter* bce) : bce_(bce) {} - void emitLabel(HandleAtom name); + void emitLabel(const ParserAtom* name); MOZ_MUST_USE bool emitEnd(); }; diff --git a/js/src/frontend/LexicalScopeEmitter.cpp b/js/src/frontend/LexicalScopeEmitter.cpp index 4d9c6d49d6..3b8c25b4c1 100644 --- a/js/src/frontend/LexicalScopeEmitter.cpp +++ b/js/src/frontend/LexicalScopeEmitter.cpp @@ -12,7 +12,7 @@ using namespace js::frontend; LexicalScopeEmitter::LexicalScopeEmitter(BytecodeEmitter* bce) : bce_(bce) {} bool LexicalScopeEmitter::emitScope(ScopeKind kind, - JS::Handle bindings) { + ParserLexicalScopeData* bindings) { MOZ_ASSERT(state_ == State::Start); MOZ_ASSERT(bindings); diff --git a/js/src/frontend/LexicalScopeEmitter.h b/js/src/frontend/LexicalScopeEmitter.h index 64ae54b407..5a4e637c1b 100644 --- a/js/src/frontend/LexicalScopeEmitter.h +++ b/js/src/frontend/LexicalScopeEmitter.h @@ -81,8 +81,7 @@ class MOZ_STACK_CLASS LexicalScopeEmitter { // Returns the scope object for non-empty scope. const EmitterScope& emitterScope() const { return *emitterScope_; } - MOZ_MUST_USE bool emitScope(ScopeKind kind, - JS::Handle bindings); + MOZ_MUST_USE bool emitScope(ScopeKind kind, ParserLexicalScopeData* bindings); MOZ_MUST_USE bool emitEmptyScope(); MOZ_MUST_USE bool emitEnd(); diff --git a/js/src/frontend/ModuleSharedContext.h b/js/src/frontend/ModuleSharedContext.h index d01b0cc6de..09821e49a8 100644 --- a/js/src/frontend/ModuleSharedContext.h +++ b/js/src/frontend/ModuleSharedContext.h @@ -20,19 +20,12 @@ class ModuleBuilder; namespace frontend { class MOZ_STACK_CLASS ModuleSharedContext : public SharedContext { - JS::Rooted module_; - JS::Rooted enclosingScope_; - public: - JS::Rooted bindings; + ParserModuleScopeData* bindings; ModuleBuilder& builder; - ModuleSharedContext(JSContext* cx, ModuleObject* module, - CompilationInfo& compilationInfo, Scope* enclosingScope, + ModuleSharedContext(JSContext* cx, CompilationInfo& compilationInfo, ModuleBuilder& builder, SourceExtent extent); - - JS::Handle module() const { return module_; } - Scope* compilationEnclosingScope() const override { return enclosingScope_; } }; inline ModuleSharedContext* SharedContext::asModuleContext() { diff --git a/js/src/frontend/NameAnalysisTypes.h b/js/src/frontend/NameAnalysisTypes.h index ea81fd8ca4..42822edcff 100644 --- a/js/src/frontend/NameAnalysisTypes.h +++ b/js/src/frontend/NameAnalysisTypes.h @@ -7,6 +7,7 @@ #include +#include "frontend/ParserAtom.h" #include "vm/BytecodeUtil.h" #include "vm/Scope.h" @@ -82,7 +83,8 @@ enum class DeclarationKind : uint8_t { SloppyLexicalFunction, VarForAnnexBLexicalFunction, SimpleCatchParameter, - CatchParameter + CatchParameter, + PrivateName, }; static inline BindingKind DeclarationKindToBindingKind(DeclarationKind kind) { @@ -107,6 +109,7 @@ static inline BindingKind DeclarationKindToBindingKind(DeclarationKind kind) { return BindingKind::Let; case DeclarationKind::Const: + case DeclarationKind::PrivateName: return BindingKind::Const; case DeclarationKind::Import: @@ -120,6 +123,16 @@ static inline bool DeclarationKindIsLexical(DeclarationKind kind) { return BindingKindIsLexical(DeclarationKindToBindingKind(kind)); } +// Used in Parser and BytecodeEmitter to track the kind of a private name. +enum class PrivateNameKind : uint8_t { + None, + Field, + Method, + Getter, + Setter, + GetterSetter, +}; + // Used in Parser to track declared names. class DeclaredNameInfo { uint32_t pos_; @@ -130,9 +143,14 @@ class DeclaredNameInfo { // (i.e., a 'var' declared name in a non-var scope). bool closedOver_; + PrivateNameKind privateNameKind_; + public: explicit DeclaredNameInfo(DeclarationKind kind, uint32_t pos) - : pos_(pos), kind_(kind), closedOver_(false) {} + : pos_(pos), + kind_(kind), + closedOver_(false), + privateNameKind_(PrivateNameKind::None) {} // Needed for InlineMap. DeclaredNameInfo() = default; @@ -148,6 +166,12 @@ class DeclaredNameInfo { void setClosedOver() { closedOver_ = true; } bool closedOver() const { return closedOver_; } + + void setPrivateNameKind(PrivateNameKind privateNameKind) { + privateNameKind_ = privateNameKind; + } + + PrivateNameKind privateNameKind() const { return privateNameKind_; } }; // Used in BytecodeEmitter to map names to locations. @@ -328,7 +352,7 @@ class NameLocation { }; // These types are declared here for BaseScript::CreateLazy. -using AtomVector = Vector; +using AtomVector = Vector; class FunctionBox; // FunctionBoxes stored in this type are required to be rooted diff --git a/js/src/frontend/NameCollections.h b/js/src/frontend/NameCollections.h index 7900b48413..41acf156e4 100644 --- a/js/src/frontend/NameCollections.h +++ b/js/src/frontend/NameCollections.h @@ -132,7 +132,7 @@ struct RecyclableAtomMapValueWrapper { const Wrapped* operator->() const { return &wrapped; } }; -struct NameMapHasher : public DefaultHasher { +struct NameMapHasher : public DefaultHasher { static inline HashNumber hash(const Lookup& l) { // Name maps use the atom's precomputed hash code, which is based on // the atom's contents rather than its pointer value. This is necessary @@ -145,11 +145,12 @@ struct NameMapHasher : public DefaultHasher { template using RecyclableNameMap = - InlineMap, 24, + InlineMap, 24, NameMapHasher, SystemAllocPolicy>; using DeclaredNameMap = RecyclableNameMap; using NameLocationMap = RecyclableNameMap; +// Cannot use GCThingIndex here because it's not trivial type. using AtomIndexMap = RecyclableNameMap; template diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp index 5ba608552f..3e71e0f6a6 100644 --- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -9,6 +9,7 @@ #include "mozilla/Sprintf.h" #include "frontend/BytecodeCompiler.h" +#include "frontend/CompilationInfo.h" #include "frontend/ParseNode.h" #include "frontend/ParseNodeVisitor.h" #include "frontend/SharedContext.h" @@ -26,7 +27,8 @@ class NameResolver : public ParseNodeVisitor { static const size_t MaxParents = 100; - RootedAtom prefix_; + CompilationInfo& compilationInfo_; + const ParserAtom* prefix_; // Number of nodes in the parents array. size_t nparents_; @@ -55,7 +57,7 @@ class NameResolver : public ParseNodeVisitor { * given code like a["b c"], the front end will produce a ParseNodeKind::Dot * with a ParseNodeKind::Name child whose name contains spaces. */ - bool appendPropertyReference(JSAtom* name) { + bool appendPropertyReference(const ParserAtom* name) { if (IsIdentifier(name)) { return buf_.append('.') && buf_.append(name); } @@ -216,31 +218,32 @@ class NameResolver : public ParseNodeVisitor { * assign to the function's displayAtom field. */ MOZ_MUST_USE bool resolveFun(FunctionNode* funNode, - MutableHandleAtom retAtom) { + const ParserAtom** retId) { MOZ_ASSERT(funNode != nullptr); + FunctionBox* funbox = funNode->funbox(); MOZ_ASSERT(buf_.empty()); auto resetBuf = mozilla::MakeScopeExit([&] { buf_.clear(); }); - retAtom.set(nullptr); + *retId = nullptr; // If the function already has a name, use that. - if (funbox->displayAtom() != nullptr) { - if (prefix_ == nullptr) { - retAtom.set(funbox->displayAtom()); + if (funbox->displayAtom()) { + if (!prefix_) { + *retId = funbox->displayAtom(); return true; } if (!buf_.append(prefix_) || !buf_.append('/') || !buf_.append(funbox->displayAtom())) { return false; } - retAtom.set(buf_.finishAtom()); - return !!retAtom; + *retId = buf_.finishParserAtom(compilationInfo_); + return !!*retId; } // If a prefix is specified, then it is a form of namespace. - if (prefix_ != nullptr) { + if (prefix_) { if (!buf_.append(prefix_) || !buf_.append('/')) { return false; } @@ -310,15 +313,15 @@ class NameResolver : public ParseNodeVisitor { return true; } - retAtom.set(buf_.finishAtom()); - if (!retAtom) { + *retId = buf_.finishParserAtom(compilationInfo_); + if (!*retId) { return false; } // Skip assigning the guessed name if the function has a (dynamically) // computed inferred name. if (!funNode->isDirectRHSAnonFunction()) { - funbox->setGuessedAtom(retAtom); + funbox->setGuessedAtom(*retId); } return true; } @@ -335,8 +338,8 @@ class NameResolver : public ParseNodeVisitor { public: MOZ_MUST_USE bool visitFunction(FunctionNode* pn) { - RootedAtom savedPrefix(cx_, prefix_); - RootedAtom newPrefix(cx_); + const ParserAtom* savedPrefix = prefix_; + const ParserAtom* newPrefix = nullptr; if (!resolveFun(pn, &newPrefix)) { return false; } @@ -435,8 +438,12 @@ class NameResolver : public ParseNodeVisitor { return internalVisitSpecList(pn); } - explicit NameResolver(JSContext* cx) - : ParseNodeVisitor(cx), prefix_(cx), nparents_(0), buf_(cx) {} + explicit NameResolver(JSContext* cx, CompilationInfo& compilationInfo) + : ParseNodeVisitor(cx), + compilationInfo_(compilationInfo), + prefix_(nullptr), + nparents_(0), + buf_(cx) {} /* * Resolve names for all anonymous functions in the given ParseNode tree. @@ -467,9 +474,10 @@ class NameResolver : public ParseNodeVisitor { } /* anonymous namespace */ -bool frontend::NameFunctions(JSContext* cx, ParseNode* pn) { +bool frontend::NameFunctions(JSContext* cx, CompilationInfo& compilationInfo, + ParseNode* pn) { AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx), TraceLogger_BytecodeNameFunctions); - NameResolver nr(cx); + NameResolver nr(cx, compilationInfo); return nr.visit(pn); } diff --git a/js/src/frontend/NameFunctions.h b/js/src/frontend/NameFunctions.h index 3f2ec35ab2..148b0bc842 100644 --- a/js/src/frontend/NameFunctions.h +++ b/js/src/frontend/NameFunctions.h @@ -13,8 +13,10 @@ namespace js { namespace frontend { class ParseNode; +struct CompilationInfo; -MOZ_MUST_USE bool NameFunctions(JSContext* cx, ParseNode* pn); +MOZ_MUST_USE bool NameFunctions(JSContext* cx, CompilationInfo& compilationInfo, + ParseNode* pn); } /* namespace frontend */ } /* namespace js */ diff --git a/js/src/frontend/NameOpEmitter.cpp b/js/src/frontend/NameOpEmitter.cpp index 7cb88ef58f..41e4ed7a00 100644 --- a/js/src/frontend/NameOpEmitter.cpp +++ b/js/src/frontend/NameOpEmitter.cpp @@ -15,11 +15,11 @@ using namespace js; using namespace js::frontend; -NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, Handle name, +NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name, Kind kind) : bce_(bce), kind_(kind), name_(name), loc_(bce_->lookupName(name_)) {} -NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, Handle name, +NameOpEmitter::NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name, const NameLocation& loc, Kind kind) : bce_(bce), kind_(kind), name_(name), loc_(loc) {} diff --git a/js/src/frontend/NameOpEmitter.h b/js/src/frontend/NameOpEmitter.h index c2e7b7be79..40e5fa96ff 100644 --- a/js/src/frontend/NameOpEmitter.h +++ b/js/src/frontend/NameOpEmitter.h @@ -11,6 +11,7 @@ #include "frontend/NameAnalysisTypes.h" #include "js/TypeDecls.h" +#include "vm/SharedStencil.h" // GCThingIndex namespace js { namespace frontend { @@ -77,9 +78,9 @@ class MOZ_STACK_CLASS NameOpEmitter { bool emittedBindOp_ = false; - Handle name_; + const ParserAtom* name_; - uint32_t atomIndex_; + GCThingIndex atomIndex_; NameLocation loc_; @@ -130,8 +131,8 @@ class MOZ_STACK_CLASS NameOpEmitter { #endif public: - NameOpEmitter(BytecodeEmitter* bce, Handle name, Kind kind); - NameOpEmitter(BytecodeEmitter* bce, Handle name, + NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name, Kind kind); + NameOpEmitter(BytecodeEmitter* bce, const ParserAtom* name, const NameLocation& loc, Kind kind); private: diff --git a/js/src/frontend/ObjLiteral.cpp b/js/src/frontend/ObjLiteral.cpp index 0959be9d60..c8a8e4e02c 100644 --- a/js/src/frontend/ObjLiteral.cpp +++ b/js/src/frontend/ObjLiteral.cpp @@ -3,11 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "frontend/ObjLiteral.h" + #include "mozilla/DebugOnly.h" + +#include "frontend/CompilationInfo.h" // frontend::CompilationInfo +#include "frontend/ParserAtom.h" // frontend::ParserAtom, frontend::ParserAtomTable #include "js/RootingAPI.h" #include "vm/JSAtom.h" #include "vm/JSObject.h" +#include "vm/JSONPrinter.h" // js::JSONPrinter #include "vm/ObjectGroup.h" +#include "vm/Printer.h" // js::Fprinter #include "gc/ObjectKind-inl.h" #include "vm/JSAtom-inl.h" @@ -15,30 +21,48 @@ namespace js { -static JS::Value InterpretObjLiteralValue(const ObjLiteralAtomVector& atoms, - const ObjLiteralInsn& insn) { +static bool InterpretObjLiteralValue(JSContext* cx, + const ObjLiteralAtomVector& atoms, + frontend::CompilationInfo& compilationInfo, + const ObjLiteralInsn& insn, + JS::Value* valOut) { switch (insn.getOp()) { case ObjLiteralOpcode::ConstValue: - return insn.getConstValue(); + *valOut = insn.getConstValue(); + return true; case ObjLiteralOpcode::ConstAtom: { uint32_t index = insn.getAtomIndex(); - return StringValue(atoms[index]); + // TODO-Stencil + // This needs to be coalesced to wherever jsatom creation is eventually + // Seems like InterpretLiteralObj would be called from main-thread + // stencil instantiation. + JSAtom* jsatom = compilationInfo.liftParserAtomToJSAtom(cx, atoms[index]); + if (!jsatom) { + return false; + } + *valOut = StringValue(jsatom); + return true; } case ObjLiteralOpcode::Null: - return NullValue(); + *valOut = NullValue(); + return true; case ObjLiteralOpcode::Undefined: - return UndefinedValue(); + *valOut = UndefinedValue(); + return true; case ObjLiteralOpcode::True: - return BooleanValue(true); + *valOut = BooleanValue(true); + return true; case ObjLiteralOpcode::False: - return BooleanValue(false); + *valOut = BooleanValue(false); + return true; default: MOZ_CRASH("Unexpected object-literal instruction opcode"); } } static JSObject* InterpretObjLiteralObj( - JSContext* cx, const ObjLiteralAtomVector& atoms, + JSContext* cx, frontend::CompilationInfo& compilationInfo, + const ObjLiteralAtomVector& atoms, const mozilla::Span literalInsns, ObjLiteralFlags flags) { bool specificGroup = flags.contains(ObjLiteralFlag::SpecificGroup); bool singleton = flags.contains(ObjLiteralFlag::Singleton); @@ -57,12 +81,24 @@ static JSObject* InterpretObjLiteralObj( if (insn.getKey().isArrayIndex()) { propId = INT_TO_JSID(insn.getKey().getArrayIndex()); } else { - propId = AtomToId(atoms[insn.getKey().getAtomIndex()]); + // TODO-Stencil + // Just a note, but it seems like this is an OK place to convert atoms + // since the other GC allocations in the function (properties vector, + // etc.) would need to be addressed. + const frontend::ParserAtom* atom = atoms[insn.getKey().getAtomIndex()]; + JSAtom* jsatom = compilationInfo.liftParserAtomToJSAtom(cx, atom); + if (!jsatom) { + return nullptr; + } + propId = AtomToId(jsatom); } JS::Value propVal; if (!noValues) { - propVal = InterpretObjLiteralValue(atoms, insn); + if (!InterpretObjLiteralValue(cx, atoms, compilationInfo, insn, + &propVal)) { + return nullptr; + } } if (!properties.emplaceBack(propId, propVal)) { @@ -81,7 +117,8 @@ static JSObject* InterpretObjLiteralObj( } static JSObject* InterpretObjLiteralArray( - JSContext* cx, const ObjLiteralAtomVector& atoms, + JSContext* cx, frontend::CompilationInfo& compilationInfo, + const ObjLiteralAtomVector& atoms, const mozilla::Span literalInsns, ObjLiteralFlags flags) { bool isCow = flags.contains(ObjLiteralFlag::ArrayCOW); ObjLiteralReader reader(literalInsns); @@ -92,7 +129,10 @@ static JSObject* InterpretObjLiteralArray( while (reader.readInsn(&insn)) { MOZ_ASSERT(insn.isValid()); - JS::Value propVal = InterpretObjLiteralValue(atoms, insn); + JS::Value propVal; + if (!InterpretObjLiteralValue(cx, atoms, compilationInfo, insn, &propVal)) { + return nullptr; + } if (!elements.append(propVal)) { return nullptr; } @@ -111,12 +151,146 @@ static JSObject* InterpretObjLiteralArray( return result; } -JSObject* InterpretObjLiteral(JSContext* cx, const ObjLiteralAtomVector& atoms, +JSObject* InterpretObjLiteral(JSContext* cx, + frontend::CompilationInfo& compilationInfo, + const ObjLiteralAtomVector& atoms, const mozilla::Span literalInsns, ObjLiteralFlags flags) { return flags.contains(ObjLiteralFlag::Array) - ? InterpretObjLiteralArray(cx, atoms, literalInsns, flags) - : InterpretObjLiteralObj(cx, atoms, literalInsns, flags); + ? InterpretObjLiteralArray(cx, compilationInfo, atoms, + literalInsns, flags) + : InterpretObjLiteralObj(cx, compilationInfo, atoms, literalInsns, + flags); +} + +#if defined(DEBUG) || defined(JS_JITSPEW) + +static void DumpObjLiteralFlagsItems(js::JSONPrinter& json, + ObjLiteralFlags flags) { + if (flags.contains(ObjLiteralFlag::Array)) { + json.value("Array"); + flags -= ObjLiteralFlag::Array; + } + if (flags.contains(ObjLiteralFlag::SpecificGroup)) { + json.value("SpecificGroup"); + flags -= ObjLiteralFlag::SpecificGroup; + } + if (flags.contains(ObjLiteralFlag::Singleton)) { + json.value("Singleton"); + flags -= ObjLiteralFlag::Singleton; + } + if (flags.contains(ObjLiteralFlag::ArrayCOW)) { + json.value("ArrayCOW"); + flags -= ObjLiteralFlag::ArrayCOW; + } + if (flags.contains(ObjLiteralFlag::NoValues)) { + json.value("NoValues"); + flags -= ObjLiteralFlag::NoValues; + } + if (flags.contains(ObjLiteralFlag::IsInnerSingleton)) { + json.value("IsInnerSingleton"); + flags -= ObjLiteralFlag::IsInnerSingleton; + } + + if (!flags.isEmpty()) { + json.value("Unknown(%x)", flags.serialize()); + } +} + +void ObjLiteralWriter::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void ObjLiteralWriter::dump(js::JSONPrinter& json) { + json.beginObject(); + dumpFields(json); + json.endObject(); +} + +void ObjLiteralWriter::dumpFields(js::JSONPrinter& json) { + json.beginListProperty("flags"); + DumpObjLiteralFlagsItems(json, flags_); + json.endList(); + + json.beginListProperty("code"); + ObjLiteralReader reader(getCode()); + ObjLiteralInsn insn; + while (reader.readInsn(&insn)) { + json.beginObject(); + + if (insn.getKey().isNone()) { + json.nullProperty("key"); + } else if (insn.getKey().isAtomIndex()) { + uint32_t index = insn.getKey().getAtomIndex(); + json.formatProperty("key", "ConstAtom(%u)", index); + } else if (insn.getKey().isArrayIndex()) { + uint32_t index = insn.getKey().getArrayIndex(); + json.formatProperty("key", "ArrayIndex(%u)", index); + } + + switch (insn.getOp()) { + case ObjLiteralOpcode::ConstValue: { + const Value& v = insn.getConstValue(); + json.formatProperty("op", "ConstValue(%f)", v.toNumber()); + break; + } + case ObjLiteralOpcode::ConstAtom: { + uint32_t index = insn.getAtomIndex(); + json.formatProperty("op", "ConstAtom(%u)", index); + break; + } + case ObjLiteralOpcode::Null: + json.property("op", "Null"); + break; + case ObjLiteralOpcode::Undefined: + json.property("op", "Undefined"); + break; + case ObjLiteralOpcode::True: + json.property("op", "True"); + break; + case ObjLiteralOpcode::False: + json.property("op", "False"); + break; + default: + json.formatProperty("op", "Invalid(%x)", uint8_t(insn.getOp())); + break; + } + + json.endObject(); + } + json.endList(); } +void ObjLiteralStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void ObjLiteralStencil::dump(js::JSONPrinter& json) { + json.beginObject(); + dumpFields(json); + json.endObject(); +} + +void ObjLiteralStencil::dumpFields(js::JSONPrinter& json) { + writer_.dumpFields(json); + + json.beginListProperty("atoms"); + for (auto& atom : atoms_) { + if (atom) { + GenericPrinter& out = json.beginString(); + atom->dumpCharsNoQuote(out); + json.endString(); + } else { + json.nullValue(); + } + } + json.endList(); +} + +#endif // defined(DEBUG) || defined(JS_JITSPEW) + } // namespace js diff --git a/js/src/frontend/ObjLiteral.h b/js/src/frontend/ObjLiteral.h index c4672fb894..b703da738d 100644 --- a/js/src/frontend/ObjLiteral.h +++ b/js/src/frontend/ObjLiteral.h @@ -9,6 +9,7 @@ #include "mozilla/EnumSet.h" #include "mozilla/Span.h" +#include "frontend/ParserAtom.h" #include "js/AllocPolicy.h" #include "js/GCPolicyAPI.h" #include "js/Value.h" @@ -136,6 +137,12 @@ namespace js { +class JSONPrinter; + +namespace frontend { +struct CompilationInfo; +} + // Object-literal instruction opcodes. An object literal is constructed by a // straight-line sequence of these ops, each adding one property to the // object. @@ -250,16 +257,17 @@ struct ObjLiteralWriterBase { static const int OP_SHIFT = 24; protected: - Vector code_; + Vector code_; public: - explicit ObjLiteralWriterBase(JSContext* cx) : code_(cx) {} + ObjLiteralWriterBase() = default; uint32_t curOffset() const { return code_.length(); } - MOZ_MUST_USE bool prepareBytes(size_t len, uint8_t** p) { + MOZ_MUST_USE bool prepareBytes(JSContext* cx, size_t len, uint8_t** p) { size_t offset = code_.length(); if (!code_.growByUninitialized(len)) { + js::ReportOutOfMemory(cx); return false; } *p = &code_[offset]; @@ -267,9 +275,9 @@ struct ObjLiteralWriterBase { } template - MOZ_MUST_USE bool pushRawData(T data) { + MOZ_MUST_USE bool pushRawData(JSContext* cx, T data) { uint8_t* p = nullptr; - if (!prepareBytes(sizeof(T), &p)) { + if (!prepareBytes(cx, sizeof(T), &p)) { return false; } mozilla::NativeEndian::copyAndSwapToLittleEndian(reinterpret_cast(p), @@ -277,22 +285,23 @@ struct ObjLiteralWriterBase { return true; } - MOZ_MUST_USE bool pushOpAndName(ObjLiteralOpcode op, ObjLiteralKey key) { + MOZ_MUST_USE bool pushOpAndName(JSContext* cx, ObjLiteralOpcode op, + ObjLiteralKey key) { uint32_t data = (key.rawIndex() & ATOM_INDEX_MASK) | (key.isArrayIndex() ? INDEXED_PROP : 0) | (static_cast(op) << OP_SHIFT); - return pushRawData(data); + return pushRawData(cx, data); } - MOZ_MUST_USE bool pushValueArg(const JS::Value& value) { + MOZ_MUST_USE bool pushValueArg(JSContext* cx, const JS::Value& value) { MOZ_ASSERT(value.isNumber() || value.isNullOrUndefined() || value.isBoolean()); uint64_t data = value.asRawBits(); - return pushRawData(data); + return pushRawData(cx, data); } - MOZ_MUST_USE bool pushAtomArg(uint32_t atomIndex) { - return pushRawData(atomIndex); + MOZ_MUST_USE bool pushAtomArg(JSContext* cx, uint32_t atomIndex) { + return pushRawData(cx, atomIndex); } }; @@ -303,8 +312,7 @@ struct ObjLiteralWriterBase { // within the writer. struct ObjLiteralWriter : private ObjLiteralWriterBase { public: - explicit ObjLiteralWriter(JSContext* cx) - : ObjLiteralWriterBase(cx), flags_() {} + ObjLiteralWriter() = default; void clear() { code_.clear(); } @@ -332,32 +340,39 @@ struct ObjLiteralWriter : private ObjLiteralWriterBase { nextKey_ = ObjLiteralKey::none(); } - MOZ_MUST_USE bool propWithConstNumericValue(const JS::Value& value) { + MOZ_MUST_USE bool propWithConstNumericValue(JSContext* cx, + const JS::Value& value) { MOZ_ASSERT(value.isNumber()); - return pushOpAndName(ObjLiteralOpcode::ConstValue, nextKey_) && - pushValueArg(value); + return pushOpAndName(cx, ObjLiteralOpcode::ConstValue, nextKey_) && + pushValueArg(cx, value); } - MOZ_MUST_USE bool propWithAtomValue(uint32_t value) { - return pushOpAndName(ObjLiteralOpcode::ConstAtom, nextKey_) && - pushAtomArg(value); + MOZ_MUST_USE bool propWithAtomValue(JSContext* cx, uint32_t value) { + return pushOpAndName(cx, ObjLiteralOpcode::ConstAtom, nextKey_) && + pushAtomArg(cx, value); } - MOZ_MUST_USE bool propWithNullValue() { - return pushOpAndName(ObjLiteralOpcode::Null, nextKey_); + MOZ_MUST_USE bool propWithNullValue(JSContext* cx) { + return pushOpAndName(cx, ObjLiteralOpcode::Null, nextKey_); } - MOZ_MUST_USE bool propWithUndefinedValue() { - return pushOpAndName(ObjLiteralOpcode::Undefined, nextKey_); + MOZ_MUST_USE bool propWithUndefinedValue(JSContext* cx) { + return pushOpAndName(cx, ObjLiteralOpcode::Undefined, nextKey_); } - MOZ_MUST_USE bool propWithTrueValue() { - return pushOpAndName(ObjLiteralOpcode::True, nextKey_); + MOZ_MUST_USE bool propWithTrueValue(JSContext* cx) { + return pushOpAndName(cx, ObjLiteralOpcode::True, nextKey_); } - MOZ_MUST_USE bool propWithFalseValue() { - return pushOpAndName(ObjLiteralOpcode::False, nextKey_); + MOZ_MUST_USE bool propWithFalseValue(JSContext* cx) { + return pushOpAndName(cx, ObjLiteralOpcode::False, nextKey_); } static bool arrayIndexInRange(int32_t i) { return i >= 0 && static_cast(i) <= ATOM_INDEX_MASK; } +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); + void dumpFields(JSONPrinter& json); +#endif + private: ObjLiteralFlags flags_; ObjLiteralKey nextKey_; @@ -533,34 +548,50 @@ struct ObjLiteralReader : private ObjLiteralReaderBase { } }; -typedef Vector ObjLiteralAtomVector; +typedef Vector + ObjLiteralAtomVector; -JSObject* InterpretObjLiteral(JSContext* cx, const ObjLiteralAtomVector& atoms, +JSObject* InterpretObjLiteral(JSContext* cx, + frontend::CompilationInfo& compilationInfo, + const ObjLiteralAtomVector& atoms, const mozilla::Span insns, ObjLiteralFlags flags); inline JSObject* InterpretObjLiteral(JSContext* cx, + frontend::CompilationInfo& compilationInfo, const ObjLiteralAtomVector& atoms, const ObjLiteralWriter& writer) { - return InterpretObjLiteral(cx, atoms, writer.getCode(), writer.getFlags()); + return InterpretObjLiteral(cx, compilationInfo, atoms, writer.getCode(), + writer.getFlags()); } -class ObjLiteralCreationData { +class ObjLiteralStencil { private: ObjLiteralWriter writer_; ObjLiteralAtomVector atoms_; public: - explicit ObjLiteralCreationData(JSContext* cx) : writer_(cx), atoms_(cx) {} + ObjLiteralStencil() = default; ObjLiteralWriter& writer() { return writer_; } - bool addAtom(JSAtom* atom, uint32_t* index) { + bool addAtom(JSContext* cx, const frontend::ParserAtom* atom, + uint32_t* index) { *index = atoms_.length(); - return atoms_.append(atom); + if (!atoms_.append(atom)) { + js::ReportOutOfMemory(cx); + return false; + } + return true; } - JSObject* create(JSContext* cx) const; + JSObject* create(JSContext* cx, frontend::CompilationInfo& info) const; + +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); + void dumpFields(JSONPrinter& json); +#endif }; } // namespace js diff --git a/js/src/frontend/ObjectEmitter.cpp b/js/src/frontend/ObjectEmitter.cpp index bc18adeaf2..8b1c1275f7 100644 --- a/js/src/frontend/ObjectEmitter.cpp +++ b/js/src/frontend/ObjectEmitter.cpp @@ -8,6 +8,7 @@ #include "frontend/BytecodeEmitter.h" // BytecodeEmitter #include "frontend/IfEmitter.h" // IfEmitter +#include "frontend/ParseNode.h" // AccessorType #include "frontend/SharedContext.h" // SharedContext #include "gc/AllocKind.h" // AllocKind #include "js/Id.h" // jsid @@ -18,7 +19,8 @@ #include "vm/NativeObject.h" // NativeDefineDataProperty #include "vm/ObjectGroup.h" // TenuredObject #include "vm/Opcodes.h" // JSOp -#include "vm/Runtime.h" // JSAtomState (cx->names()) +#include "vm/Runtime.h" // cx->parserNames() +#include "vm/SharedStencil.h" // GCThingIndex #include "gc/ObjectKind-inl.h" // GetGCObjectKind #include "vm/JSAtom-inl.h" // AtomToId @@ -259,51 +261,39 @@ bool PropertyEmitter::emitInitHomeObject() { return true; } -bool PropertyEmitter::emitInitProp(JS::Handle key) { - return emitInit(isClass_ ? JSOp::InitHiddenProp : JSOp::InitProp, key); -} - -bool PropertyEmitter::emitInitGetter(JS::Handle key) { - return emitInit(isClass_ ? JSOp::InitHiddenPropGetter : JSOp::InitPropGetter, - key); -} - -bool PropertyEmitter::emitInitSetter(JS::Handle key) { - return emitInit(isClass_ ? JSOp::InitHiddenPropSetter : JSOp::InitPropSetter, - key); -} - -bool PropertyEmitter::emitInitIndexProp() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElem - : JSOp::InitElem); -} - -bool PropertyEmitter::emitInitIndexGetter() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemGetter - : JSOp::InitElemGetter); -} - -bool PropertyEmitter::emitInitIndexSetter() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemSetter - : JSOp::InitElemSetter); -} - -bool PropertyEmitter::emitInitComputedProp() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElem - : JSOp::InitElem); -} - -bool PropertyEmitter::emitInitComputedGetter() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemGetter - : JSOp::InitElemGetter); +bool PropertyEmitter::emitInit(AccessorType accessorType, + const ParserAtom* key) { + switch (accessorType) { + case AccessorType::None: + return emitInit(isClass_ ? JSOp::InitHiddenProp : JSOp::InitProp, key); + case AccessorType::Getter: + return emitInit( + isClass_ ? JSOp::InitHiddenPropGetter : JSOp::InitPropGetter, key); + case AccessorType::Setter: + return emitInit( + isClass_ ? JSOp::InitHiddenPropSetter : JSOp::InitPropSetter, key); + default: + MOZ_CRASH("Invalid op"); + } } -bool PropertyEmitter::emitInitComputedSetter() { - return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemSetter - : JSOp::InitElemSetter); +bool PropertyEmitter::emitInitIndexOrComputed(AccessorType accessorType) { + switch (accessorType) { + case AccessorType::None: + return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElem + : JSOp::InitElem); + case AccessorType::Getter: + return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemGetter + : JSOp::InitElemGetter); + case AccessorType::Setter: + return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemSetter + : JSOp::InitElemSetter); + default: + MOZ_CRASH("Invalid op"); + } } -bool PropertyEmitter::emitInit(JSOp op, JS::Handle key) { +bool PropertyEmitter::emitInit(JSOp op, const ParserAtom* key) { MOZ_ASSERT(propertyState_ == PropertyState::PropValue || propertyState_ == PropertyState::InitHomeObj); @@ -431,12 +421,12 @@ void AutoSaveLocalStrictMode::restore() { ClassEmitter::ClassEmitter(BytecodeEmitter* bce) : PropertyEmitter(bce), strictMode_(bce->sc), - name_(bce->cx), - nameForAnonymousClass_(bce->cx) { + name_(nullptr), + nameForAnonymousClass_(nullptr) { isClass_ = true; } -bool ClassEmitter::emitScope(JS::Handle scopeBindings) { +bool ClassEmitter::emitScope(ParserLexicalScopeData* scopeBindings) { MOZ_ASSERT(propertyState_ == PropertyState::Start); MOZ_ASSERT(classState_ == ClassState::Start); @@ -454,12 +444,32 @@ bool ClassEmitter::emitScope(JS::Handle scopeBindings) { return true; } -bool ClassEmitter::emitClass(JS::Handle name, - JS::Handle nameForAnonymousClass, - bool hasNameOnStack) { +bool ClassEmitter::emitBodyScope(ParserLexicalScopeData* scopeBindings) { MOZ_ASSERT(propertyState_ == PropertyState::Start); MOZ_ASSERT(classState_ == ClassState::Start || classState_ == ClassState::Scope); + + bodyTdzCache_.emplace(bce_); + + bodyScope_.emplace(bce_); + if (!bodyScope_->enterLexical(bce_, ScopeKind::ClassBody, scopeBindings)) { + return false; + } + +#ifdef DEBUG + classState_ = ClassState::BodyScope; +#endif + + return true; +} + +bool ClassEmitter::emitClass(const ParserAtom* name, + const ParserAtom* nameForAnonymousClass, + bool hasNameOnStack) { + MOZ_ASSERT(propertyState_ == PropertyState::Start); + MOZ_ASSERT(classState_ == ClassState::Start || + classState_ == ClassState::Scope || + classState_ == ClassState::BodyScope); MOZ_ASSERT_IF(nameForAnonymousClass || hasNameOnStack, !name); MOZ_ASSERT(!(nameForAnonymousClass && hasNameOnStack)); @@ -481,16 +491,17 @@ bool ClassEmitter::emitClass(JS::Handle name, return true; } -bool ClassEmitter::emitDerivedClass(JS::Handle name, - JS::Handle nameForAnonymousClass, +bool ClassEmitter::emitDerivedClass(const ParserAtom* name, + const ParserAtom* nameForAnonymousClass, bool hasNameOnStack) { MOZ_ASSERT(propertyState_ == PropertyState::Start); MOZ_ASSERT(classState_ == ClassState::Start || - classState_ == ClassState::Scope); + classState_ == ClassState::Scope || + classState_ == ClassState::BodyScope); MOZ_ASSERT_IF(nameForAnonymousClass || hasNameOnStack, !name); MOZ_ASSERT(!nameForAnonymousClass || !hasNameOnStack); - // [stack] + // [stack] HERITAGE name_ = name; nameForAnonymousClass_ = nameForAnonymousClass; @@ -527,7 +538,7 @@ bool ClassEmitter::emitDerivedClass(JS::Handle name, // [stack] HERITAGE HERITAGE return false; } - if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->names().prototype)) { + if (!bce_->emitAtomOp(JSOp::GetProp, bce_->cx->parserNames().prototype)) { // [stack] HERITAGE PROTO return false; } @@ -540,7 +551,7 @@ bool ClassEmitter::emitDerivedClass(JS::Handle name, // [stack] return false; } - if (!bce_->emit1(JSOp::FunctionProto)) { + if (!bce_->emitBuiltinObject(BuiltinObjectKind::FunctionPrototype)) { // [stack] PROTO return false; } @@ -572,7 +583,7 @@ bool ClassEmitter::emitDerivedClass(JS::Handle name, bool ClassEmitter::emitInitConstructor(bool needsHomeObject) { MOZ_ASSERT(propertyState_ == PropertyState::Start); MOZ_ASSERT(classState_ == ClassState::Class || - classState_ == ClassState::InstanceFieldInitializersEnd); + classState_ == ClassState::InstanceMemberInitializersEnd); // [stack] HOMEOBJ CTOR @@ -603,16 +614,16 @@ bool ClassEmitter::emitInitDefaultConstructor(uint32_t classStart, MOZ_ASSERT(propertyState_ == PropertyState::Start); MOZ_ASSERT(classState_ == ClassState::Class); - RootedAtom className(bce_->cx, name_); + const ParserAtom* className = name_; if (!className) { if (nameForAnonymousClass_) { className = nameForAnonymousClass_; } else { - className = bce_->cx->names().empty; + className = bce_->cx->parserNames().empty; } } - uint32_t atomIndex; + GCThingIndex atomIndex; if (!bce_->makeAtomIndex(className, &atomIndex)) { return false; } @@ -671,11 +682,13 @@ bool ClassEmitter::initProtoAndCtor() { // [stack] NAME? CTOR HOMEOBJ CTOR HOMEOBJ return false; } - if (!bce_->emitAtomOp(JSOp::InitLockedProp, bce_->cx->names().prototype)) { + if (!bce_->emitAtomOp(JSOp::InitLockedProp, + bce_->cx->parserNames().prototype)) { // [stack] NAME? CTOR HOMEOBJ CTOR return false; } - if (!bce_->emitAtomOp(JSOp::InitHiddenProp, bce_->cx->names().constructor)) { + if (!bce_->emitAtomOp(JSOp::InitHiddenProp, + bce_->cx->parserNames().constructor)) { // [stack] NAME? CTOR HOMEOBJ return false; } @@ -683,54 +696,54 @@ bool ClassEmitter::initProtoAndCtor() { return true; } -bool ClassEmitter::prepareForFieldInitializers(size_t numFields, - bool isStatic) { +bool ClassEmitter::prepareForMemberInitializers(size_t numInitializers, + bool isStatic) { MOZ_ASSERT_IF(!isStatic, classState_ == ClassState::Class); MOZ_ASSERT_IF(isStatic, classState_ == ClassState::InitConstructor); - MOZ_ASSERT(fieldState_ == FieldState::Start); + MOZ_ASSERT(memberState_ == MemberState::Start); // .initializers is a variable that stores an array of lambdas containing // code (the initializer) for each field. Upon an object's construction, // these lambdas will be called, defining the values. - auto initializersName = isStatic ? &JSAtomState::dotStaticInitializers - : &JSAtomState::dotInitializers; - HandlePropertyName initializers = bce_->cx->names().*initializersName; + const ParserName* initializers = + isStatic ? bce_->cx->parserNames().dotStaticInitializers + : bce_->cx->parserNames().dotInitializers; initializersAssignment_.emplace(bce_, initializers, NameOpEmitter::Kind::Initialize); if (!initializersAssignment_->prepareForRhs()) { return false; } - if (!bce_->emitUint32Operand(JSOp::NewArray, numFields)) { + if (!bce_->emitUint32Operand(JSOp::NewArray, numInitializers)) { // [stack] ARRAY return false; } - fieldIndex_ = 0; + initializerIndex_ = 0; #ifdef DEBUG if (isStatic) { - classState_ = ClassState::StaticFieldInitializers; + classState_ = ClassState::StaticMemberInitializers; } else { - classState_ = ClassState::InstanceFieldInitializers; + classState_ = ClassState::InstanceMemberInitializers; } - numFields_ = numFields; + numInitializers_ = numInitializers; #endif return true; } -bool ClassEmitter::prepareForFieldInitializer() { - MOZ_ASSERT(classState_ == ClassState::InstanceFieldInitializers || - classState_ == ClassState::StaticFieldInitializers); - MOZ_ASSERT(fieldState_ == FieldState::Start); +bool ClassEmitter::prepareForMemberInitializer() { + MOZ_ASSERT(classState_ == ClassState::InstanceMemberInitializers || + classState_ == ClassState::StaticMemberInitializers); + MOZ_ASSERT(memberState_ == MemberState::Start); #ifdef DEBUG - fieldState_ = FieldState::Initializer; + memberState_ = MemberState::Initializer; #endif return true; } -bool ClassEmitter::emitFieldInitializerHomeObject(bool isStatic) { - MOZ_ASSERT(fieldState_ == FieldState::Initializer); +bool ClassEmitter::emitMemberInitializerHomeObject(bool isStatic) { + MOZ_ASSERT(memberState_ == MemberState::Initializer); // [stack] OBJ HERITAGE? ARRAY METHOD // or: // [stack] CTOR HOMEOBJ ARRAY METHOD @@ -754,36 +767,36 @@ bool ClassEmitter::emitFieldInitializerHomeObject(bool isStatic) { } #ifdef DEBUG - fieldState_ = FieldState::InitializerWithHomeObject; + memberState_ = MemberState::InitializerWithHomeObject; #endif return true; } -bool ClassEmitter::emitStoreFieldInitializer() { - MOZ_ASSERT(fieldState_ == FieldState::Initializer || - fieldState_ == FieldState::InitializerWithHomeObject); - MOZ_ASSERT(fieldIndex_ < numFields_); +bool ClassEmitter::emitStoreMemberInitializer() { + MOZ_ASSERT(memberState_ == MemberState::Initializer || + memberState_ == MemberState::InitializerWithHomeObject); + MOZ_ASSERT(initializerIndex_ < numInitializers_); // [stack] HOMEOBJ HERITAGE? ARRAY METHOD - if (!bce_->emitUint32Operand(JSOp::InitElemArray, fieldIndex_)) { + if (!bce_->emitUint32Operand(JSOp::InitElemArray, initializerIndex_)) { // [stack] HOMEOBJ HERITAGE? ARRAY return false; } - fieldIndex_++; + initializerIndex_++; #ifdef DEBUG - fieldState_ = FieldState::Start; + memberState_ = MemberState::Start; #endif return true; } -bool ClassEmitter::emitFieldInitializersEnd() { +bool ClassEmitter::emitMemberInitializersEnd() { MOZ_ASSERT(propertyState_ == PropertyState::Start || propertyState_ == PropertyState::Init); - MOZ_ASSERT(classState_ == ClassState::InstanceFieldInitializers || - classState_ == ClassState::StaticFieldInitializers); - MOZ_ASSERT(fieldState_ == FieldState::Start); - MOZ_ASSERT(fieldIndex_ == numFields_); + MOZ_ASSERT(classState_ == ClassState::InstanceMemberInitializers || + classState_ == ClassState::StaticMemberInitializers); + MOZ_ASSERT(memberState_ == MemberState::Start); + MOZ_ASSERT(initializerIndex_ == numInitializers_); if (!initializersAssignment_->emitAssignment()) { // [stack] HOMEOBJ HERITAGE? ARRAY @@ -797,10 +810,10 @@ bool ClassEmitter::emitFieldInitializersEnd() { } #ifdef DEBUG - if (classState_ == ClassState::InstanceFieldInitializers) { - classState_ = ClassState::InstanceFieldInitializersEnd; + if (classState_ == ClassState::InstanceMemberInitializers) { + classState_ = ClassState::InstanceMemberInitializersEnd; } else { - classState_ = ClassState::StaticFieldInitializersEnd; + classState_ = ClassState::StaticMemberInitializersEnd; } #endif return true; @@ -810,8 +823,8 @@ bool ClassEmitter::emitBinding() { MOZ_ASSERT(propertyState_ == PropertyState::Start || propertyState_ == PropertyState::Init); MOZ_ASSERT(classState_ == ClassState::InitConstructor || - classState_ == ClassState::InstanceFieldInitializersEnd || - classState_ == ClassState::StaticFieldInitializersEnd); + classState_ == ClassState::InstanceMemberInitializersEnd || + classState_ == ClassState::StaticMemberInitializersEnd); // [stack] CTOR HOMEOBJ if (!bce_->emit1(JSOp::Pop)) { @@ -840,6 +853,16 @@ bool ClassEmitter::emitEnd(Kind kind) { MOZ_ASSERT(classState_ == ClassState::BoundName); // [stack] CTOR + if (bodyScope_.isSome()) { + MOZ_ASSERT(bodyTdzCache_.isSome()); + + if (!bodyScope_->leave(bce_)) { + return false; + } + bodyScope_.reset(); + bodyTdzCache_.reset(); + } + if (innerScope_.isSome()) { MOZ_ASSERT(tdzCache_.isSome()); diff --git a/js/src/frontend/ObjectEmitter.h b/js/src/frontend/ObjectEmitter.h index dd19b5a05b..2d3d3bf315 100644 --- a/js/src/frontend/ObjectEmitter.h +++ b/js/src/frontend/ObjectEmitter.h @@ -14,13 +14,11 @@ #include "frontend/BytecodeOffset.h" // BytecodeOffset #include "frontend/EmitterScope.h" // EmitterScope #include "frontend/NameOpEmitter.h" // NameOpEmitter -#include "frontend/ObjLiteral.h" // ObjLiteralWriter, ObjLiteralCreationData -#include "frontend/TDZCheckCache.h" // TDZCheckCache -#include "js/RootingAPI.h" // JS::Handle, JS::Rooted -#include "vm/BytecodeUtil.h" // JSOp -#include "vm/JSAtom.h" // JSAtom -#include "vm/NativeObject.h" // PlainObject -#include "vm/Scope.h" // LexicalScope +#include "frontend/ParseNode.h" // AccessorType +#include "frontend/TDZCheckCache.h" // TDZCheckCache +#include "vm/BytecodeUtil.h" // JSOp +#include "vm/NativeObject.h" // PlainObject +#include "vm/Scope.h" // LexicalScope namespace js { @@ -81,9 +79,7 @@ class MOZ_STACK_CLASS PropertyEmitter { // | | | // | +-------------------------------------- + | // | | | - // | | emitInitProp | - // | | emitInitGetter | - // | | emitInitSetter | + // | | emitInit | // | +------------------------------------------------------>+ // | ^ // | [index property/method/accessor] | @@ -108,9 +104,7 @@ class MOZ_STACK_CLASS PropertyEmitter { // | | | // | +--------------------------------------------------+ | // | | | - // | | emitInitIndexProp | - // | | emitInitIndexGetter | - // | | emitInitIndexSetter | + // | | emitInitIndexOrComputed | // | +---------------------------------------------------->+ // | | // | [computed property/method/accessor] | @@ -135,9 +129,7 @@ class MOZ_STACK_CLASS PropertyEmitter { // | | | // | +--------------------------------------------------+ | // | | | - // | | emitInitComputedProp | - // | | emitInitComputedGetter | - // | | emitInitComputedSetter | + // | | emitInitIndexOrComputed | // | +---------------------------------------------------->+ // | ^ // | | @@ -184,9 +176,8 @@ class MOZ_STACK_CLASS PropertyEmitter { // After calling prepareForSpreadOperand. SpreadOperand, - // After calling one of emitInitProp, emitInitGetter, emitInitSetter, - // emitInitIndexOrComputedProp, emitInitIndexOrComputedGetter, - // emitInitIndexOrComputedSetter, emitMutateProto, or emitSpread. + // After calling one of emitInit, emitInitIndexOrComputed, emitMutateProto, + // or emitSpread. Init, }; PropertyState propertyState_ = PropertyState::Start; @@ -240,17 +231,9 @@ class MOZ_STACK_CLASS PropertyEmitter { // @param key // Property key - MOZ_MUST_USE bool emitInitProp(JS::Handle key); - MOZ_MUST_USE bool emitInitGetter(JS::Handle key); - MOZ_MUST_USE bool emitInitSetter(JS::Handle key); + MOZ_MUST_USE bool emitInit(AccessorType accessorType, const ParserAtom* key); - MOZ_MUST_USE bool emitInitIndexProp(); - MOZ_MUST_USE bool emitInitIndexGetter(); - MOZ_MUST_USE bool emitInitIndexSetter(); - - MOZ_MUST_USE bool emitInitComputedProp(); - MOZ_MUST_USE bool emitInitComputedGetter(); - MOZ_MUST_USE bool emitInitComputedSetter(); + MOZ_MUST_USE bool emitInitIndexOrComputed(AccessorType accessorType); private: MOZ_MUST_USE MOZ_ALWAYS_INLINE bool prepareForProp( @@ -260,7 +243,7 @@ class MOZ_STACK_CLASS PropertyEmitter { // Opcode for initializing property // @param key // Atom of the property if the property key is not computed - MOZ_MUST_USE bool emitInit(JSOp op, JS::Handle key); + MOZ_MUST_USE bool emitInit(JSOp op, const ParserAtom* key); MOZ_MUST_USE bool emitInitIndexOrComputed(JSOp op); MOZ_MUST_USE bool emitPopClassConstructor(); @@ -489,12 +472,12 @@ class MOZ_RAII AutoSaveLocalStrictMode { // emit(Y); // ce.emitDerivedClass(atom_of_X, nullptr, false); // -// ce.prepareForFieldInitializers(fields.length()); +// ce.prepareForMemberInitializers(fields.length()); // for (auto field : fields) { // emit(field.initializer_method()); -// ce.emitStoreFieldInitializer(); +// ce.emitStoreMemberInitializer(); // } -// ce.emitFieldInitializersEnd(); +// ce.emitMemberInitializersEnd(); // // emit(function_for_constructor); // ce.emitInitConstructor(/* needsHomeObject = */ false); @@ -502,15 +485,15 @@ class MOZ_RAII AutoSaveLocalStrictMode { // // `class X { field0 = super.method(); ... }` // // after emitClass/emitDerivedClass -// ce.prepareForFieldInitializers(1); +// ce.prepareForMemberInitializers(1); // for (auto field : fields) { // emit(field.initializer_method()); // if (field.initializer_contains_super_or_eval()) { -// ce.emitFieldInitializerHomeObject(); +// ce.emitMemberInitializerHomeObject(); // } -// ce.emitStoreFieldInitializer(); +// ce.emitStoreMemberInitializer(); // } -// ce.emitFieldInitializersEnd(); +// ce.emitMemberInitializersEnd(); // // `m() {}` in class // // after emitInitConstructor/emitInitDefaultConstructor @@ -616,6 +599,8 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { mozilla::Maybe tdzCache_; mozilla::Maybe innerScope_; + mozilla::Maybe bodyTdzCache_; + mozilla::Maybe bodyScope_; AutoSaveLocalStrictMode strictMode_; #ifdef DEBUG @@ -623,14 +608,14 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // // clang-format off // +-------+ - // | Start |-+------------------------>+-+ - // +-------+ | ^ | - // | [has scope] | | - // | emitScope +-------+ | | - // +-------------->| Scope |-+ | - // +-------+ | - // | - // +-----------------------------------+ + // | Start |-+------------------------>+--+------------------------------>+--+ + // +-------+ | ^ | ^ | + // | [has scope] | | [has body scope] | | + // | emitScope +-------+ | | emitBodyScope +-----------+ | | + // +-------------->| Scope |-+ +---------------->| BodyScope |-+ | + // +-------+ +-----------+ | + // | + // +-----------------------------------------------------------------------+ // | // | emitClass +-------+ // +-+----------------->+->| Class |-+ @@ -641,18 +626,18 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // +-------------------------------+ // | // | - // | prepareForFieldInitializers(isStatic = false) + // | prepareForMemberInitializers(isStatic = false) // +---------------+ // | | - // | +--------v------------------+ - // | | InstanceFieldInitializers | - // | +---------------------------+ + // | +--------v-------------------+ + // | | InstanceMemberInitializers | + // | +----------------------------+ // | | - // | emitFieldInitializersEnd + // | emitMemberInitializersEnd // | | - // | +--------v---------------------+ - // | | InstanceFieldInitializersEnd | - // | +------------------------------+ + // | +--------v----------------------+ + // | | InstanceMemberInitializersEnd | + // | +-------------------------------+ // | | // +<--------------+ // | @@ -664,18 +649,18 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // | // +-----------------------------------------------------+ // | - // | prepareForFieldInitializers(isStatic = true) + // | prepareForMemberInitializers(isStatic = true) // +---------------+ // | | - // | +--------v----------------+ - // | | StaticFieldInitializers | - // | +-------------------------+ + // | +--------v-----------------+ + // | | StaticMemberInitializers | + // | +--------------------------+ // | | - // | | emitFieldInitializersEnd + // | | emitMemberInitializersEnd // | | - // | +--------v-------------------+ - // | | StaticFieldInitializersEnd | - // | +----------------------------+ + // | +--------v--------------------+ + // | | StaticMemberInitializersEnd | + // | +-----------------------------+ // | | // +<--------------+ // | @@ -700,23 +685,26 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // After calling emitScope. Scope, + // After calling emitBodyScope. + BodyScope, + // After calling emitClass or emitDerivedClass. Class, // After calling emitInitConstructor or emitInitDefaultConstructor. InitConstructor, - // After calling prepareForFieldInitializers(isStatic = false). - InstanceFieldInitializers, + // After calling prepareForMemberInitializers(isStatic = false). + InstanceMemberInitializers, - // After calling emitFieldInitializersEnd. - InstanceFieldInitializersEnd, + // After calling emitMemberInitializersEnd. + InstanceMemberInitializersEnd, - // After calling prepareForFieldInitializers(isStatic = true). - StaticFieldInitializers, + // After calling prepareForMemberInitializers(isStatic = true). + StaticMemberInitializers, - // After calling emitFieldInitializersEnd. - StaticFieldInitializersEnd, + // After calling emitMemberInitializersEnd. + StaticMemberInitializersEnd, // After calling emitBinding. BoundName, @@ -726,7 +714,7 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { }; ClassState classState_ = ClassState::Start; - // The state of the fields emitter. + // The state of the members emitter. // // clang-format off // @@ -734,45 +722,46 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // | Start +<-----------------------------+ // +-------+ | // | | - // | prepareForFieldInitializer | emitStoreFieldInitializer + // | prepareForMemberInitializer | emitStoreMemberInitializer // v | // +-------------+ | // | Initializer +------------------------->+ // +-------------+ | // | | - // | emitFieldInitializerHomeObject | + // | emitMemberInitializerHomeObject | // v | // +---------------------------+ | // | InitializerWithHomeObject +------------+ // +---------------------------+ // // clang-format on - enum class FieldState { - // After calling prepareForFieldInitializers - // and 0 or more calls to emitStoreFieldInitializer. + enum class MemberState { + // After calling prepareForMemberInitializers + // and 0 or more calls to emitStoreMemberInitializer. Start, - // After calling prepareForFieldInitializer + // After calling prepareForMemberInitializer Initializer, - // After calling emitFieldInitializerHomeObject + // After calling emitMemberInitializerHomeObject InitializerWithHomeObject, }; - FieldState fieldState_ = FieldState::Start; + MemberState memberState_ = MemberState::Start; - size_t numFields_ = 0; + size_t numInitializers_ = 0; #endif - JS::Rooted name_; - JS::Rooted nameForAnonymousClass_; + const ParserAtom* name_; + const ParserAtom* nameForAnonymousClass_; bool hasNameOnStack_ = false; mozilla::Maybe initializersAssignment_; - size_t fieldIndex_ = 0; + size_t initializerIndex_ = 0; public: explicit ClassEmitter(BytecodeEmitter* bce); - bool emitScope(JS::Handle scopeBindings); + bool emitScope(ParserLexicalScopeData* scopeBindings); + bool emitBodyScope(ParserLexicalScopeData* scopeBindings); // @param name // Name of the class (nullptr if this is anonymous class) @@ -780,11 +769,11 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { // Statically inferred name of the class (only for anonymous classes) // @param hasNameOnStack // If true the name is on the stack (only for anonymous classes) - MOZ_MUST_USE bool emitClass(JS::Handle name, - JS::Handle nameForAnonymousClass, + MOZ_MUST_USE bool emitClass(const ParserAtom* name, + const ParserAtom* nameForAnonymousClass, bool hasNameOnStack); - MOZ_MUST_USE bool emitDerivedClass(JS::Handle name, - JS::Handle nameForAnonymousClass, + MOZ_MUST_USE bool emitDerivedClass(const ParserAtom* name, + const ParserAtom* nameForAnonymousClass, bool hasNameOnStack); // @param needsHomeObject @@ -803,12 +792,12 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter { MOZ_MUST_USE bool emitInitDefaultConstructor(uint32_t classStart, uint32_t classEnd); - MOZ_MUST_USE bool prepareForFieldInitializers(size_t numFields, - bool isStatic); - MOZ_MUST_USE bool prepareForFieldInitializer(); - MOZ_MUST_USE bool emitFieldInitializerHomeObject(bool isStatic); - MOZ_MUST_USE bool emitStoreFieldInitializer(); - MOZ_MUST_USE bool emitFieldInitializersEnd(); + MOZ_MUST_USE bool prepareForMemberInitializers(size_t numInitializers, + bool isStatic); + MOZ_MUST_USE bool prepareForMemberInitializer(); + MOZ_MUST_USE bool emitMemberInitializerHomeObject(bool isStatic); + MOZ_MUST_USE bool emitStoreMemberInitializer(); + MOZ_MUST_USE bool emitMemberInitializersEnd(); MOZ_MUST_USE bool emitBinding(); diff --git a/js/src/frontend/ParseContext-inl.h b/js/src/frontend/ParseContext-inl.h index 56431f6634..4a5f46f1fa 100644 --- a/js/src/frontend/ParseContext-inl.h +++ b/js/src/frontend/ParseContext-inl.h @@ -61,7 +61,7 @@ inline ParseContext::VarScope::VarScope(JSContext* cx, ParseContext* pc, } inline JS::Result -ParseContext::checkBreakStatement(PropertyName* label) { +ParseContext::checkBreakStatement(const ParserName* label) { // Labeled 'break' statements target the nearest labeled statements (could // be any kind) with the same label. Unlabeled 'break' statements target // the innermost loop or switch statement. @@ -89,7 +89,7 @@ ParseContext::checkBreakStatement(PropertyName* label) { } inline JS::Result -ParseContext::checkContinueStatement(PropertyName* label) { +ParseContext::checkContinueStatement(const ParserName* label) { // Labeled 'continue' statements target the nearest labeled loop // statements with the same label. Unlabeled 'continue' statements target // the innermost loop statement. diff --git a/js/src/frontend/ParseContext.cpp b/js/src/frontend/ParseContext.cpp index 42b485fc78..40935d1b99 100644 --- a/js/src/frontend/ParseContext.cpp +++ b/js/src/frontend/ParseContext.cpp @@ -42,6 +42,8 @@ const char* DeclarationKindString(DeclarationKind kind) { case DeclarationKind::SimpleCatchParameter: case DeclarationKind::CatchParameter: return "catch parameter"; + case DeclarationKind::PrivateName: + return "private name"; } MOZ_CRASH("Bad DeclarationKind"); @@ -58,14 +60,28 @@ bool DeclarationKindIsParameter(DeclarationKind kind) { kind == DeclarationKind::FormalParameter; } -bool UsedNameTracker::noteUse(JSContext* cx, JSAtom* name, uint32_t scriptId, - uint32_t scopeId) { +bool UsedNameTracker::noteUse(JSContext* cx, const ParserAtom* name, + NameVisibility visibility, uint32_t scriptId, + uint32_t scopeId, + mozilla::Maybe tokenPosition) { if (UsedNameMap::AddPtr p = map_.lookupForAdd(name)) { + p->value().maybeUpdatePos(tokenPosition); + if (!p->value().noteUsedInScope(scriptId, scopeId)) { return false; } } else { - UsedNameInfo info(cx); + // We need a token position precisely where we have private visibility. + MOZ_ASSERT(tokenPosition.isSome() == + (visibility == NameVisibility::Private)); + + if (visibility == NameVisibility::Private) { + // We have seen at least one private name + hasPrivateNames_ = true; + } + + UsedNameInfo info(cx, visibility, tokenPosition); + if (!info.noteUsedInScope(scriptId, scopeId)) { return false; } @@ -77,6 +93,61 @@ bool UsedNameTracker::noteUse(JSContext* cx, JSAtom* name, uint32_t scriptId, return true; } +bool UsedNameTracker::getUnboundPrivateNames( + Vector& unboundPrivateNames) { + // We never saw any private names, so can just return early + if (!hasPrivateNames_) { + return true; + } + + for (auto iter = map_.iter(); !iter.done(); iter.next()) { + // Don't care about public; + if (iter.get().value().isPublic()) { + continue; + } + + // empty list means all bound + if (iter.get().value().empty()) { + continue; + } + + if (!unboundPrivateNames.emplaceBack(iter.get().key(), + *iter.get().value().pos())) { + return false; + } + } + + // Return a sorted list in ascendng order of position. + auto comparePosition = [](const auto& a, const auto& b) { + return a.position < b.position; + }; + std::sort(unboundPrivateNames.begin(), unboundPrivateNames.end(), + comparePosition); + + return true; +} + +bool UsedNameTracker::hasUnboundPrivateNames( + JSContext* cx, mozilla::Maybe& maybeUnboundName) { + // We never saw any private names, so can just return early + if (!hasPrivateNames_) { + return true; + } + + Vector unboundPrivateNames(cx); + if (!getUnboundPrivateNames(unboundPrivateNames)) { + return false; + } + + if (unboundPrivateNames.empty()) { + return true; + } + + // GetUnboundPrivateNames returns the list sorted. + maybeUnboundName.emplace(unboundPrivateNames[0]); + return true; +} + void UsedNameTracker::UsedNameInfo::resetToScope(uint32_t scriptId, uint32_t scopeId) { while (!uses_.empty()) { @@ -105,7 +176,7 @@ void ParseContext::Scope::dump(ParseContext* pc) { fprintf(stdout, "\n decls:\n"); for (DeclaredNameMap::Range r = declared_->all(); !r.empty(); r.popFront()) { - UniqueChars bytes = AtomToPrintableString(cx, r.front().key()); + UniqueChars bytes = QuoteString(cx, r.front().key()); if (!bytes) { return; } @@ -139,12 +210,16 @@ bool ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes( if (this == &pc->varScope()) { // Base case: actually declare the Annex B vars and mark applicable // function boxes as Annex B. - RootedPropertyName name(pc->sc()->cx_); Maybe redeclaredKind; uint32_t unused; for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) { - if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) { - name = funbox->explicitName()->asPropertyName(); + bool annexBApplies; + if (!pc->computeAnnexBAppliesToLexicalFunctionInInnermostScope( + funbox, &annexBApplies)) { + return false; + } + if (annexBApplies) { + const ParserName* name = funbox->explicitName()->asName(); if (!pc->tryDeclareVar( name, DeclarationKind::VarForAnnexBLexicalFunction, DeclaredNameInfo::npos, &redeclaredKind, &unused)) { @@ -159,7 +234,12 @@ bool ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes( // Inner scope case: propagate still applicable function boxes to the // enclosing scope. for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) { - if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) { + bool annexBApplies; + if (!pc->computeAnnexBAppliesToLexicalFunctionInInnermostScope( + funbox, &annexBApplies)) { + return false; + } + if (annexBApplies) { if (!enclosing()->addPossibleAnnexBFunctionBox(pc, funbox)) { return false; } @@ -186,7 +266,7 @@ bool ParseContext::Scope::addCatchParameters(ParseContext* pc, DeclarationKind kind = r.front().value()->kind(); uint32_t pos = r.front().value()->pos(); MOZ_ASSERT(DeclarationKindIsCatchParameter(kind)); - JSAtom* name = r.front().key(); + const ParserAtom* name = r.front().key(); AddDeclaredNamePtr p = lookupDeclaredNameForAdd(name); MOZ_ASSERT(!p); if (!addDeclaredName(pc, p, name, kind, pos)) { @@ -218,7 +298,7 @@ void ParseContext::Scope::removeCatchParameters(ParseContext* pc, ParseContext::ParseContext(JSContext* cx, ParseContext*& parent, SharedContext* sc, ErrorReporter& errorReporter, - CompilationInfo& compilationInfo, + CompilationState& compilationState, Directives* newDirectives, bool isFull) : Nestable(&parent), traceLog_(sc->cx_, @@ -235,13 +315,13 @@ ParseContext::ParseContext(JSContext* cx, ParseContext*& parent, newDirectives(newDirectives), lastYieldOffset(NoYieldOffset), lastAwaitOffset(NoAwaitOffset), - scriptId_(compilationInfo.usedNames.nextScriptId()), + scriptId_(compilationState.usedNames.nextScriptId()), superScopeNeedsHomeObject_(false) { if (isFunctionBox()) { if (functionBox()->isNamedLambda()) { - namedLambdaScope_.emplace(cx, parent, compilationInfo.usedNames); + namedLambdaScope_.emplace(cx, parent, compilationState.usedNames); } - functionScope_.emplace(cx, parent, compilationInfo.usedNames); + functionScope_.emplace(cx, parent, compilationState.usedNames); } } @@ -288,13 +368,17 @@ bool ParseContext::init() { return true; } -bool ParseContext::annexBAppliesToLexicalFunctionInInnermostScope( - FunctionBox* funbox) { +bool ParseContext::computeAnnexBAppliesToLexicalFunctionInInnermostScope( + FunctionBox* funbox, bool* annexBApplies) { MOZ_ASSERT(!sc()->strict()); - RootedPropertyName name(sc()->cx_, funbox->explicitName()->asPropertyName()); - Maybe redeclaredKind = isVarRedeclaredInInnermostScope( - name, DeclarationKind::VarForAnnexBLexicalFunction); + const ParserName* name = funbox->explicitName()->asName(); + Maybe redeclaredKind; + if (!isVarRedeclaredInInnermostScope( + name, DeclarationKind::VarForAnnexBLexicalFunction, + &redeclaredKind)) { + return false; + } if (!redeclaredKind && isFunctionBox()) { Scope& funScope = functionScope(); @@ -317,31 +401,40 @@ bool ParseContext::annexBAppliesToLexicalFunctionInInnermostScope( // If an early error would have occurred already, this function should not // exhibit Annex B.3.3 semantics. - return !redeclaredKind; + *annexBApplies = !redeclaredKind; + return true; } -Maybe ParseContext::isVarRedeclaredInInnermostScope( - HandlePropertyName name, DeclarationKind kind) { - Maybe redeclaredKind; +bool ParseContext::isVarRedeclaredInInnermostScope( + const ParserName* name, DeclarationKind kind, + mozilla::Maybe* out) { uint32_t unused; - MOZ_ALWAYS_TRUE(tryDeclareVarHelper( - name, kind, DeclaredNameInfo::npos, &redeclaredKind, &unused)); - return redeclaredKind; + return tryDeclareVarHelper( + name, kind, DeclaredNameInfo::npos, out, &unused); } -Maybe ParseContext::isVarRedeclaredInEval( - HandlePropertyName name, DeclarationKind kind) { +bool ParseContext::isVarRedeclaredInEval(const ParserName* name, + DeclarationKind kind, + Maybe* out) { + MOZ_ASSERT(out); MOZ_ASSERT(DeclarationKindIsVar(kind)); MOZ_ASSERT(sc()->isEvalContext()); + // TODO-Stencil: After scope snapshotting, this can be done away with. + auto mbNameAtom = name->toJSAtom(sc()->cx_, sc()->compilationInfo()); + if (mbNameAtom.isErr()) { + return false; + } + JSAtom* nameAtom = mbNameAtom.unwrap(); + // In the case of eval, we also need to check enclosing VM scopes to see // if the var declaration is allowed in the context. - js::Scope* enclosingScope = sc()->compilationEnclosingScope(); + js::Scope* enclosingScope = sc()->compilationInfo().input.enclosingScope; js::Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope); MOZ_ASSERT(varScope); for (ScopeIter si(enclosingScope); si; si++) { for (js::BindingIter bi(si.scope()); bi; bi++) { - if (bi.name() != name) { + if (bi.name() != nameAtom) { continue; } @@ -351,15 +444,17 @@ Maybe ParseContext::isVarRedeclaredInEval( // catch parameters with var declarations. bool annexB35Allowance = si.kind() == ScopeKind::SimpleCatch; if (!annexB35Allowance) { - return Some(ScopeKindIsCatch(si.kind()) + *out = Some(ScopeKindIsCatch(si.kind()) ? DeclarationKind::CatchParameter : DeclarationKind::Let); + return true; } break; } case BindingKind::Const: - return Some(DeclarationKind::Const); + *out = Some(DeclarationKind::Const); + return true; case BindingKind::Import: case BindingKind::FormalParameter: @@ -374,10 +469,11 @@ Maybe ParseContext::isVarRedeclaredInEval( } } - return Nothing(); + *out = Nothing(); + return true; } -bool ParseContext::tryDeclareVar(HandlePropertyName name, DeclarationKind kind, +bool ParseContext::tryDeclareVar(const ParserName* name, DeclarationKind kind, uint32_t beginPos, Maybe* redeclaredKind, uint32_t* prevPos) { @@ -386,7 +482,7 @@ bool ParseContext::tryDeclareVar(HandlePropertyName name, DeclarationKind kind, } template -bool ParseContext::tryDeclareVarHelper(HandlePropertyName name, +bool ParseContext::tryDeclareVarHelper(const ParserName* name, DeclarationKind kind, uint32_t beginPos, Maybe* redeclaredKind, uint32_t* prevPos) { @@ -456,7 +552,9 @@ bool ParseContext::tryDeclareVarHelper(HandlePropertyName name, if (!sc()->strict() && sc()->isEvalContext() && (dryRunOption == NotDryRun || innermostScope() == &varScope())) { - *redeclaredKind = isVarRedeclaredInEval(name, kind); + if (!isVarRedeclaredInEval(name, kind, redeclaredKind)) { + return false; + } // We don't have position information at runtime. *prevPos = DeclaredNameInfo::npos; } @@ -465,7 +563,7 @@ bool ParseContext::tryDeclareVarHelper(HandlePropertyName name, } bool ParseContext::hasUsedName(const UsedNameTracker& usedNames, - HandlePropertyName name) { + const ParserName* name) { if (auto p = usedNames.lookup(name)) { return p->value().isUsedInScript(scriptId()); } @@ -473,9 +571,9 @@ bool ParseContext::hasUsedName(const UsedNameTracker& usedNames, } bool ParseContext::hasUsedFunctionSpecialName(const UsedNameTracker& usedNames, - HandlePropertyName name) { - MOZ_ASSERT(name == sc()->cx_->names().arguments || - name == sc()->cx_->names().dotThis); + const ParserName* name) { + MOZ_ASSERT(name == sc()->cx_->parserNames().arguments || + name == sc()->cx_->parserNames().dotThis); return hasUsedName(usedNames, name) || functionBox()->bindingsAccessedDynamically(); } @@ -491,7 +589,7 @@ bool ParseContext::declareFunctionThis(const UsedNameTracker& usedNames, // Derived class constructors emit JSOp::CheckReturn, which requires // '.this' to be bound. FunctionBox* funbox = functionBox(); - HandlePropertyName dotThis = sc()->cx_->names().dotThis; + const ParserName* dotThis = sc()->cx_->parserNames().dotThis; bool declareThis; if (canSkipLazyClosedOverBindings) { @@ -525,7 +623,7 @@ bool ParseContext::declareFunctionArgumentsObject( bool hasExtraBodyVarScope = &funScope != &_varScope; // Time to implement the odd semantics of 'arguments'. - HandlePropertyName argumentsName = sc()->cx_->names().arguments; + const ParserName* argumentsName = sc()->cx_->parserNames().arguments; bool tryDeclareArguments; if (canSkipLazyClosedOverBindings) { @@ -589,7 +687,7 @@ bool ParseContext::declareDotGeneratorName() { // The special '.generator' binding must be on the function scope, as // generators expect to find it on the CallObject. ParseContext::Scope& funScope = functionScope(); - HandlePropertyName dotGenerator = sc()->cx_->names().dotGenerator; + const ParserName* dotGenerator = sc()->cx_->parserNames().dotGenerator; AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotGenerator); if (!p && !funScope.addDeclaredName(this, p, dotGenerator, DeclarationKind::Var, diff --git a/js/src/frontend/ParseContext.h b/js/src/frontend/ParseContext.h index 15e2a9c77a..db3ac47e6b 100644 --- a/js/src/frontend/ParseContext.h +++ b/js/src/frontend/ParseContext.h @@ -67,13 +67,13 @@ class ParseContext : public Nestable { }; class LabelStatement : public Statement { - RootedAtom label_; + const ParserAtom* label_; public: - LabelStatement(ParseContext* pc, JSAtom* label) - : Statement(pc, StatementKind::Label), label_(pc->sc_->cx_, label) {} + LabelStatement(ParseContext* pc, const ParserAtom* label) + : Statement(pc, StatementKind::Label), label_(label) {} - HandleAtom label() const { return label_; } + const ParserAtom* label() const { return label_; } }; struct ClassStatement : public Statement { @@ -138,17 +138,17 @@ class ParseContext : public Nestable { bool isEmpty() const { return declared_->all().empty(); } - DeclaredNamePtr lookupDeclaredName(JSAtom* name) { + DeclaredNamePtr lookupDeclaredName(const ParserAtom* name) { return declared_->lookup(name); } - AddDeclaredNamePtr lookupDeclaredNameForAdd(JSAtom* name) { + AddDeclaredNamePtr lookupDeclaredNameForAdd(const ParserAtom* name) { return declared_->lookupForAdd(name); } MOZ_MUST_USE bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p, - JSAtom* name, DeclarationKind kind, - uint32_t pos) { + const ParserAtom* name, + DeclarationKind kind, uint32_t pos) { return maybeReportOOM( pc, declared_->add(p, name, DeclaredNameInfo(kind, pos))); } @@ -210,7 +210,7 @@ class ParseContext : public Nestable { explicit operator bool() const { return !done(); } - JSAtom* name() { + const ParserAtom* name() { MOZ_ASSERT(!done()); return declaredRange_.front().key(); } @@ -328,7 +328,7 @@ class ParseContext : public Nestable { public: ParseContext(JSContext* cx, ParseContext*& parent, SharedContext* sc, - ErrorReporter& errorReporter, CompilationInfo& compilationInfo, + ErrorReporter& errorReporter, CompilationState& compilationState, Directives* newDirectives, bool isFull); MOZ_MUST_USE bool init(); @@ -400,14 +400,14 @@ class ParseContext : public Nestable { // Return Err(true) if we have encountered at least one loop, // Err(false) otherwise. MOZ_MUST_USE inline JS::Result checkBreakStatement( - PropertyName* label); + const ParserName* label); enum class ContinueStatementError { NotInALoop, LabelNotFound, }; MOZ_MUST_USE inline JS::Result - checkContinueStatement(PropertyName* label); + checkContinueStatement(const ParserName* label); // True if we are at the topmost level of a entire script or function body. // For example, while parsing this code we would encounter f1 and f2 at @@ -476,16 +476,17 @@ class ParseContext : public Nestable { uint32_t scriptId() const { return scriptId_; } - bool annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox); + bool computeAnnexBAppliesToLexicalFunctionInInnermostScope( + FunctionBox* funbox, bool* annexBApplies); - bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, + bool tryDeclareVar(const ParserName* name, DeclarationKind kind, uint32_t beginPos, mozilla::Maybe* redeclaredKind, uint32_t* prevPos); - bool hasUsedName(const UsedNameTracker& usedNames, HandlePropertyName name); + bool hasUsedName(const UsedNameTracker& usedNames, const ParserName* name); bool hasUsedFunctionSpecialName(const UsedNameTracker& usedNames, - HandlePropertyName name); + const ParserName* name); bool declareFunctionThis(const UsedNameTracker& usedNames, bool canSkipLazyClosedOverBindings); @@ -494,14 +495,17 @@ class ParseContext : public Nestable { bool declareDotGeneratorName(); private: - mozilla::Maybe isVarRedeclaredInInnermostScope( - HandlePropertyName name, DeclarationKind kind); - mozilla::Maybe isVarRedeclaredInEval(HandlePropertyName name, - DeclarationKind kind); + MOZ_MUST_USE bool isVarRedeclaredInInnermostScope( + const ParserName* name, DeclarationKind kind, + mozilla::Maybe* out); + + MOZ_MUST_USE bool isVarRedeclaredInEval(const ParserName* name, + DeclarationKind kind, + mozilla::Maybe* out); enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly }; template - bool tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind, + bool tryDeclareVarHelper(const ParserName* name, DeclarationKind kind, uint32_t beginPos, mozilla::Maybe* redeclaredKind, uint32_t* prevPos); diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp index 6bd4b68c15..9573ccf50e 100644 --- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -197,12 +197,23 @@ void RegExpLiteral::dumpImpl(GenericPrinter& out, int indent) { out.printf("(%s)", parseNodeNames[getKindAsIndex()]); } +static void DumpCharsNoNewline(const ParserAtom* atom, + js::GenericPrinter& out) { + if (atom->hasLatin1Chars()) { + out.put("[Latin 1]"); + JSString::dumpChars(atom->latin1Chars(), atom->length(), out); + } else { + out.put("[2 byte]"); + JSString::dumpChars(atom->twoByteChars(), atom->length(), out); + } +} + void LoopControlStatement::dumpImpl(GenericPrinter& out, int indent) { const char* name = parseNodeNames[getKindAsIndex()]; out.printf("(%s", name); if (label()) { out.printf(" "); - label()->dumpCharsNoNewline(out); + DumpCharsNoNewline(label(), out); } out.printf(")"); } @@ -306,7 +317,7 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) { case ParseNodeKind::StringExpr: case ParseNodeKind::TemplateStringExpr: case ParseNodeKind::ObjectPropertyName: - atom()->dumpCharsNoNewline(out); + DumpCharsNoNewline(atom(), out); return; case ParseNodeKind::Name: @@ -316,11 +327,10 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) { if (!atom()) { out.put("#"); } else { - JS::AutoCheckCannotGC nogc; if (atom()->hasLatin1Chars()) { - DumpName(out, atom()->latin1Chars(nogc), atom()->length()); + DumpName(out, atom()->latin1Chars(), atom()->length()); } else { - DumpName(out, atom()->twoByteChars(nogc), atom()->length()); + DumpName(out, atom()->twoByteChars(), atom()->length()); } } return; @@ -341,7 +351,7 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) { void LabeledStatement::dumpImpl(GenericPrinter& out, int indent) { const char* name = parseNodeNames[getKindAsIndex()]; out.printf("(%s ", name); - atom()->dumpCharsNoNewline(out); + DumpCharsNoNewline(atom(), out); out.printf(" "); indent += strlen(name) + atom()->length() + 3; DumpParseTree(statement(), out, indent); @@ -353,14 +363,13 @@ void LexicalScopeNode::dumpImpl(GenericPrinter& out, int indent) { out.printf("(%s [", name); int nameIndent = indent + strlen(name) + 3; if (!isEmptyScope()) { - LexicalScope::Data* bindings = scopeBindings(); + ParserScopeData* bindings = scopeBindings(); for (uint32_t i = 0; i < bindings->length; i++) { - JSAtom* name = bindings->trailingNames[i].name(); - JS::AutoCheckCannotGC nogc; + const ParserAtom* name = bindings->trailingNames[i].name(); if (name->hasLatin1Chars()) { - DumpName(out, name->latin1Chars(nogc), name->length()); + DumpName(out, name->latin1Chars(), name->length()); } else { - DumpName(out, name->twoByteChars(nogc), name->length()); + DumpName(out, name->twoByteChars(), name->length()); } if (i < bindings->length - 1) { IndentNewLine(out, nameIndent); @@ -376,34 +385,25 @@ void LexicalScopeNode::dumpImpl(GenericPrinter& out, int indent) { #endif BigInt* BigIntLiteral::create(JSContext* cx) { - return compilationInfo_.bigIntData[index_].createBigInt(cx); + return stencil_.bigIntData[index_].createBigInt(cx); } -bool BigIntLiteral::isZero() { - return compilationInfo_.bigIntData[index_].isZero(); -} - -JSAtom* BigIntLiteral::toAtom(JSContext* cx) { - RootedBigInt bi(cx, create(cx)); - if (!bi) { - return nullptr; - } - return BigIntToAtom(cx, bi); -} +bool BigIntLiteral::isZero() { return stencil_.bigIntData[index_].isZero(); } -JSAtom* NumericLiteral::toAtom(JSContext* cx) const { - return NumberToAtom(cx, value()); +const ParserAtom* NumericLiteral::toAtom( + JSContext* cx, CompilationInfo& compilationInfo) const { + return NumberToParserAtom(cx, compilationInfo, value()); } -RegExpObject* RegExpCreationData::createRegExp(JSContext* cx) const { +RegExpObject* RegExpStencil::createRegExp(JSContext* cx) const { MOZ_ASSERT(buf_); return RegExpObject::createSyntaxChecked(cx, buf_.get(), length_, flags_, TenuredObject); } RegExpObject* RegExpLiteral::create(JSContext* cx, - CompilationInfo& compilationInfo) const { - return compilationInfo.regExpData[index_].createRegExp(cx); + CompilationStencil& stencil) const { + return stencil.regExpData[index_].createRegExp(cx); } bool js::frontend::IsAnonymousFunctionDefinition(ParseNode* pn) { diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index 481c2f38bc..838eaa9d58 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -12,7 +12,11 @@ #include #include +#include "jstypes.h" // js::Bit + #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind +#include "frontend/NameAnalysisTypes.h" // PrivateNameKind +#include "frontend/ParserAtom.h" #include "frontend/Stencil.h" #include "frontend/Token.h" #include "js/RootingAPI.h" @@ -33,16 +37,9 @@ // // - This bulk-deallocation DOES NOT run destructors. // -// - Instances of `LexicalScope::Data` MUST BE allocated as instances of -// `ParseNode`, in the same `LifoAlloc`. They are bulk-deallocated alongside -// the rest of the tree. -// -// - Instances of `JSAtom` used throughout the tree (including instances of -// `PropertyName`) MUST be kept alive by the parser. This is done through an -// instance of `AutoKeepAtoms` held by the parser. -// -// - Once the parser is deallocated, the `JSAtom` instances MAY be -// garbage-collected. +// - Instances of `ParserScopeData` MUST BE allocated as +// instances of `ParseNode`, in the same `LifoAlloc`. They are bulk- +// deallocated alongside the rest of the tree. struct JSContext; @@ -59,11 +56,18 @@ class RegExpObject; namespace frontend { class ParseContext; -struct CompilationInfo; +struct CompilationStencil; class ParserSharedBase; class FullParseHandler; + class FunctionBox; +// This typedef unfortunately needs to be replicated here. +using ParserBindingName = AbstractBindingName; + +template +using ParserScopeData = typename Scope::template AbstractData; + #define FOR_EACH_PARSE_NODE_KIND(F) \ F(EmptyStmt, NullaryNode) \ F(ExpressionStmt, UnaryNode) \ @@ -304,6 +308,7 @@ inline bool IsTypeofKind(ParseNodeKind kind) { * ClassMethod (ClassMethod) * name: propertyName * method: methodDefinition + * initializerIfPrivate: initializer to stamp private method onto instance * Module (ModuleNode) * body: statement list of the module * @@ -485,6 +490,7 @@ inline bool IsTypeofKind(ParseNodeKind kind) { * * CallExpr: Call expr without jump * PropertyNameExpr (NameNode) * atom: property name being accessed + * privateNameKind: kind of the name if private * DotExpr (PropertyAccess) * left: MEMBER expr to left of '.' * right: PropertyName to right of '.' @@ -557,7 +563,7 @@ inline bool IsTypeofKind(ParseNodeKind kind) { * NumberExpr (NumericLiteral) * value: double value of numeric literal * BigIntExpr (BigIntLiteral) - * compilationInfo: script compilation struct + * stencil: script compilation struct that has |bigIntData| vector * index: index into the script compilation's |bigIntData| vector * TrueExpr, FalseExpr (BooleanLiteral) * NullExpr (NullLiteral) @@ -676,6 +682,17 @@ class ParseNode { * ParseNodeKind::PropertyDefinition of property, * that needs SetFunctionName. */ + protected: + // Used by ComputedName to indicate if the ComputedName is a + // a synthetic construct. This allows us to avoid needing to + // compute ToString on uncommon property values such as BigInt. + // Instead we parse as though they were computed names. + // + // We need this bit to distinguish a synthetic computed name like + // this however to undo this transformation in Reflect.parse and + // name guessing. + bool pn_synthetic_computed : 1; + ParseNode(const ParseNode& other) = delete; void operator=(const ParseNode& other) = delete; @@ -684,6 +701,7 @@ class ParseNode { : pn_type(kind), pn_parens(false), pn_rhs_anon_fun(false), + pn_synthetic_computed(false), pn_pos(0, 0), pn_next(nullptr) { JS_PARSE_NODE_ASSERT(ParseNodeKind::Start <= kind); @@ -694,6 +712,7 @@ class ParseNode { : pn_type(kind), pn_parens(false), pn_rhs_anon_fun(false), + pn_synthetic_computed(false), pn_pos(pos), pn_next(nullptr) { JS_PARSE_NODE_ASSERT(ParseNodeKind::Start <= kind); @@ -742,7 +761,7 @@ class ParseNode { return ParseNodeKind::BinOpFirst <= kind && kind <= ParseNodeKind::BinOpLast; } - inline bool isName(PropertyName* name) const; + inline bool isName(const ParserName* name) const; /* Boolean attributes. */ bool isInParens() const { return pn_parens; } @@ -845,10 +864,11 @@ class NullaryNode : public ParseNode { }; class NameNode : public ParseNode { - JSAtom* atom_; /* lexical name or label atom */ + const ParserAtom* atom_; /* lexical name or label atom */ + PrivateNameKind privateNameKind_ = PrivateNameKind::None; public: - NameNode(ParseNodeKind kind, JSAtom* atom, const TokenPos& pos) + NameNode(ParseNodeKind kind, const ParserAtom* atom, const TokenPos& pos) : ParseNode(kind, pos), atom_(atom) { MOZ_ASSERT(is()); } @@ -868,17 +888,24 @@ class NameNode : public ParseNode { void dumpImpl(GenericPrinter& out, int indent); #endif - JSAtom* atom() const { return atom_; } + const ParserAtom* atom() const { return atom_; } + + const ParserName* name() const { + MOZ_ASSERT(isKind(ParseNodeKind::Name) || + isKind(ParseNodeKind::PrivateName)); + return atom()->asName(); + } + + void setAtom(const ParserAtom* atom) { atom_ = atom; } - PropertyName* name() const { - MOZ_ASSERT(isKind(ParseNodeKind::Name)); - return atom()->asPropertyName(); + void setPrivateNameKind(PrivateNameKind privateNameKind) { + privateNameKind_ = privateNameKind; } - void setAtom(JSAtom* atom) { atom_ = atom; } + PrivateNameKind privateNameKind() { return privateNameKind_; } }; -inline bool ParseNode::isName(PropertyName* name) const { +inline bool ParseNode::isName(const ParserName* name) const { return getKind() == ParseNodeKind::Name && as().name() == name; } @@ -927,7 +954,7 @@ class UnaryNode : public ParseNode { * or escaped newlines, say). This member function returns true for such * nodes; we use it to determine the extent of the prologue. */ - JSAtom* isStringExprStatement() const { + const ParserAtom* isStringExprStatement() const { if (isKind(ParseNodeKind::ExpressionStmt)) { if (kid()->isKind(ParseNodeKind::StringExpr) && !kid()->isInParens()) { return kid()->as().atom(); @@ -938,6 +965,12 @@ class UnaryNode : public ParseNode { // Methods used by FoldConstants.cpp. ParseNode** unsafeKidReference() { return &kid_; } + + void setSyntheticComputedName() { pn_synthetic_computed = true; } + bool isSyntheticComputedName() { + MOZ_ASSERT(isKind(ParseNodeKind::ComputedName)); + return pn_synthetic_computed; + } }; class BinaryNode : public ParseNode { @@ -1107,12 +1140,7 @@ class ListNode : public ParseNode { // xflags bits. // Statement list has top-level function statements. - static constexpr uint32_t hasTopLevelFunctionDeclarationsBit = 0x01; - - // One or more of - // * array has holes - // * array has spread node - static constexpr uint32_t hasArrayHoleOrSpreadBit = 0x02; + static constexpr uint32_t hasTopLevelFunctionDeclarationsBit = Bit(0); // Array/Object/Class initializer has non-constants. // * array has holes @@ -1125,10 +1153,10 @@ class ListNode : public ParseNode { // * object/class spread property // * object/class has method // * object/class has computed property - static constexpr uint32_t hasNonConstInitializerBit = 0x04; + static constexpr uint32_t hasNonConstInitializerBit = Bit(1); // Flag set by the emitter after emitting top-level function statements. - static constexpr uint32_t emittedTopLevelFunctionDeclarationsBit = 0x08; + static constexpr uint32_t emittedTopLevelFunctionDeclarationsBit = Bit(2); public: ListNode(ParseNodeKind kind, const TokenPos& pos) : ParseNode(kind, pos) { @@ -1204,11 +1232,6 @@ class ListNode : public ParseNode { return xflags & emittedTopLevelFunctionDeclarationsBit; } - MOZ_MUST_USE bool hasArrayHoleOrSpread() const { - MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr)); - return xflags & hasArrayHoleOrSpreadBit; - } - MOZ_MUST_USE bool hasNonConstInitializer() const { MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr) || isKind(ParseNodeKind::ObjectExpr)); @@ -1226,11 +1249,6 @@ class ListNode : public ParseNode { xflags |= emittedTopLevelFunctionDeclarationsBit; } - void setHasArrayHoleOrSpread() { - MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr)); - xflags |= hasArrayHoleOrSpreadBit; - } - void setHasNonConstInitializer() { MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr) || isKind(ParseNodeKind::ObjectExpr)); @@ -1554,18 +1572,19 @@ class NumericLiteral : public ParseNode { void setDecimalPoint(DecimalPoint d) { decimalPoint_ = d; } // Return the decimal string representation of this numeric literal. - JSAtom* toAtom(JSContext* cx) const; + const ParserAtom* toAtom(JSContext* cx, + CompilationInfo& compilationInfo) const; }; class BigIntLiteral : public ParseNode { - CompilationInfo& compilationInfo_; + CompilationStencil& stencil_; BigIntIndex index_; public: - BigIntLiteral(BigIntIndex index, CompilationInfo& compilationInfo, + BigIntLiteral(BigIntIndex index, CompilationStencil& stencil, const TokenPos& pos) : ParseNode(ParseNodeKind::BigIntExpr, pos), - compilationInfo_(compilationInfo), + stencil_(stencil), index_(index) {} static bool test(const ParseNode& node) { @@ -1588,19 +1607,16 @@ class BigIntLiteral : public ParseNode { // Create a BigInt value of this BigInt literal. BigInt* create(JSContext* cx); - // Return the decimal string representation of this BigInt literal. - JSAtom* toAtom(JSContext* cx); - bool isZero(); }; class LexicalScopeNode : public ParseNode { - LexicalScope::Data* bindings; + ParserScopeData* bindings; ParseNode* body; ScopeKind kind_; public: - LexicalScopeNode(LexicalScope::Data* bindings, ParseNode* body, + LexicalScopeNode(ParserScopeData* bindings, ParseNode* body, ScopeKind kind = ScopeKind::Lexical) : ParseNode(ParseNodeKind::LexicalScope, body->pn_pos), bindings(bindings), @@ -1622,11 +1638,9 @@ class LexicalScopeNode : public ParseNode { void dumpImpl(GenericPrinter& out, int indent); #endif - Handle scopeBindings() const { + ParserScopeData* scopeBindings() const { MOZ_ASSERT(!isEmptyScope()); - // Bindings' GC safety depend on the presence of an AutoKeepAtoms that - // the rest of the frontend also depends on. - return Handle::fromMarkedLocation(&bindings); + return bindings; } ParseNode* scopeBody() const { return body; } @@ -1642,12 +1656,12 @@ class LabeledStatement : public NameNode { ParseNode* statement_; public: - LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin) + LabeledStatement(const ParserName* label, ParseNode* stmt, uint32_t begin) : NameNode(ParseNodeKind::LabelStmt, label, TokenPos(begin, stmt->pn_pos.end)), statement_(stmt) {} - PropertyName* label() const { return atom()->asPropertyName(); } + const ParserName* label() const { return atom()->asName(); } ParseNode* statement() const { return statement_; } @@ -1693,10 +1707,10 @@ class CaseClause : public BinaryNode { }; class LoopControlStatement : public ParseNode { - PropertyName* label_; /* target of break/continue statement */ + const ParserName* label_; /* target of break/continue statement */ protected: - LoopControlStatement(ParseNodeKind kind, PropertyName* label, + LoopControlStatement(ParseNodeKind kind, const ParserName* label, const TokenPos& pos) : ParseNode(kind, pos), label_(label) { MOZ_ASSERT(kind == ParseNodeKind::BreakStmt || @@ -1706,7 +1720,7 @@ class LoopControlStatement : public ParseNode { public: /* Label associated with this break/continue statement, if any. */ - PropertyName* label() const { return label_; } + const ParserName* label() const { return label_; } #ifdef DEBUG void dumpImpl(GenericPrinter& out, int indent); @@ -1727,7 +1741,7 @@ class LoopControlStatement : public ParseNode { class BreakStatement : public LoopControlStatement { public: - BreakStatement(PropertyName* label, const TokenPos& pos) + BreakStatement(const ParserName* label, const TokenPos& pos) : LoopControlStatement(ParseNodeKind::BreakStmt, label, pos) {} static bool test(const ParseNode& node) { @@ -1739,7 +1753,7 @@ class BreakStatement : public LoopControlStatement { class ContinueStatement : public LoopControlStatement { public: - ContinueStatement(PropertyName* label, const TokenPos& pos) + ContinueStatement(const ParserName* label, const TokenPos& pos) : LoopControlStatement(ParseNodeKind::ContinueStmt, label, pos) {} static bool test(const ParseNode& node) { @@ -1874,7 +1888,7 @@ class RegExpLiteral : public ParseNode { : ParseNode(ParseNodeKind::RegExpExpr, pos), index_(dataIndex) {} // Create a RegExp object of this RegExp literal. - RegExpObject* create(JSContext* cx, CompilationInfo& compilationInfo) const; + RegExpObject* create(JSContext* cx, CompilationStencil& stencil) const; #ifdef DEBUG void dumpImpl(GenericPrinter& out, int indent); @@ -1927,8 +1941,8 @@ class PropertyAccessBase : public BinaryNode { void setExpression(ParseNode* pn) { *unsafeLeftReference() = pn; } - PropertyName& name() const { - return *right()->as().atom()->asPropertyName(); + const ParserName* name() const { + return right()->as().atom()->asName(); } }; @@ -2069,6 +2083,7 @@ class CallNode : public BinaryNode { class ClassMethod : public BinaryNode { bool isStatic_; AccessorType accessorType_; + FunctionNode* initializerIfPrivate_; public: /* @@ -2076,11 +2091,12 @@ class ClassMethod : public BinaryNode { * so explicitly define the beginning and end here. */ ClassMethod(ParseNode* name, ParseNode* body, AccessorType accessorType, - bool isStatic) + bool isStatic, FunctionNode* initializerIfPrivate) : BinaryNode(ParseNodeKind::ClassMethod, TokenPos(name->pn_pos.begin, body->pn_pos.end), name, body), isStatic_(isStatic), - accessorType_(accessorType) {} + accessorType_(accessorType), + initializerIfPrivate_(initializerIfPrivate) {} static bool test(const ParseNode& node) { bool match = node.isKind(ParseNodeKind::ClassMethod); @@ -2095,6 +2111,8 @@ class ClassMethod : public BinaryNode { bool isStatic() const { return isStatic_; } AccessorType accessorType() const { return accessorType_; } + + FunctionNode* initializerIfPrivate() const { return initializerIfPrivate_; } }; class ClassField : public BinaryNode { @@ -2216,6 +2234,15 @@ class ClassNames : public BinaryNode { }; class ClassNode : public TernaryNode { + private: + LexicalScopeNode* innerScope() const { + return &kid3()->as(); + } + + LexicalScopeNode* bodyScope() const { + return &innerScope()->scopeBody()->as(); + } + public: ClassNode(ParseNode* names, ParseNode* heritage, LexicalScopeNode* memberBlock, const TokenPos& pos) @@ -2237,14 +2264,18 @@ class ClassNode : public TernaryNode { ParseNode* heritage() const { return kid2(); } ListNode* memberList() const { - ListNode* list = - &kid3()->as().scopeBody()->as(); + ListNode* list = &bodyScope()->scopeBody()->as(); MOZ_ASSERT(list->isKind(ParseNodeKind::ClassMemberList)); return list; } LexicalScopeNode* scopeBindings() const { - LexicalScopeNode* scope = &kid3()->as(); + LexicalScopeNode* scope = innerScope(); + return scope->isEmptyScope() ? nullptr : scope; + } + + LexicalScopeNode* bodyScopeBindings() const { + LexicalScopeNode* scope = bodyScope(); return scope->isEmptyScope() ? nullptr : scope; } }; diff --git a/js/src/frontend/ParseNodeVisitor.h b/js/src/frontend/ParseNodeVisitor.h index 4540956398..2ee8f150e8 100644 --- a/js/src/frontend/ParseNodeVisitor.h +++ b/js/src/frontend/ParseNodeVisitor.h @@ -11,6 +11,7 @@ #include "jsfriendapi.h" #include "frontend/ParseNode.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit namespace js { namespace frontend { diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 96d1c8a95a..2e7256f455 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -45,7 +45,8 @@ #include "frontend/ParseNodeVerify.h" #include "frontend/TokenStream.h" #include "irregexp/RegExpAPI.h" -#include "js/RegExpFlags.h" // JS::RegExpFlags +#include "js/RegExpFlags.h" // JS::RegExpFlags +#include "util/StringBuffer.h" // StringBuffer #include "vm/BigIntType.h" #include "vm/BytecodeUtil.h" #include "vm/FunctionFlags.h" // js::FunctionFlags @@ -85,7 +86,7 @@ using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr; using BindingIter = ParseContext::Scope::BindingIter; using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr; -using BindingNameVector = Vector; +using ParserBindingNameVector = Vector; template static inline void PropagateTransitiveParseFlags(const T* inner, U* outer) { @@ -143,13 +144,16 @@ bool GeneralParser::mustMatchTokenInternal( } ParserSharedBase::ParserSharedBase(JSContext* cx, - CompilationInfo& compilationInfo, Kind kind) + CompilationInfo& compilationInfo, + CompilationState& compilationState, + Kind kind) : JS::CustomAutoRooter(cx), cx_(cx), - alloc_(compilationInfo.allocScope.alloc()), + alloc_(compilationState.allocScope.alloc()), compilationInfo_(compilationInfo), + compilationState_(compilationState), pc_(nullptr), - usedNames_(compilationInfo.usedNames) { + usedNames_(compilationState.usedNames) { cx->frontendCollectionPool().addActiveCompilation(); } @@ -158,8 +162,10 @@ ParserSharedBase::~ParserSharedBase() { } ParserBase::ParserBase(JSContext* cx, const ReadOnlyCompileOptions& options, - bool foldConstants, CompilationInfo& compilationInfo) - : ParserSharedBase(cx, compilationInfo, ParserSharedBase::Kind::Parser), + bool foldConstants, CompilationInfo& compilationInfo, + CompilationState& compilationState) + : ParserSharedBase(cx, compilationInfo, compilationState, + ParserSharedBase::Kind::Parser), anyChars(cx, options, this), ss(nullptr), foldConstants_(foldConstants), @@ -184,19 +190,20 @@ ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_); } template PerHandlerParser::PerHandlerParser( JSContext* cx, const ReadOnlyCompileOptions& options, bool foldConstants, - CompilationInfo& compilationInfo, BaseScript* lazyOuterFunction, - void* internalSyntaxParser) - : ParserBase(cx, options, foldConstants, compilationInfo), - handler_(cx, compilationInfo.allocScope.alloc(), lazyOuterFunction), + CompilationInfo& compilationInfo, CompilationState& compilationState, + BaseScript* lazyOuterFunction, void* internalSyntaxParser) + : ParserBase(cx, options, foldConstants, compilationInfo, compilationState), + handler_(cx, compilationState.allocScope.alloc(), lazyOuterFunction), internalSyntaxParser_(internalSyntaxParser) {} template GeneralParser::GeneralParser( JSContext* cx, const ReadOnlyCompileOptions& options, const Unit* units, size_t length, bool foldConstants, CompilationInfo& compilationInfo, - SyntaxParser* syntaxParser, BaseScript* lazyOuterFunction) - : Base(cx, options, foldConstants, compilationInfo, syntaxParser, - lazyOuterFunction), + CompilationState& compilationState, SyntaxParser* syntaxParser, + BaseScript* lazyOuterFunction) + : Base(cx, options, foldConstants, compilationInfo, compilationState, + syntaxParser, lazyOuterFunction), tokenStream(cx, &compilationInfo, options, units, length) {} template @@ -243,60 +250,19 @@ inline void GeneralParser::setInParametersOfAsyncFunction( template FunctionBox* PerHandlerParser::newFunctionBox( - FunctionNodeType funNode, JSFunction* fun, uint32_t toStringStart, - Directives inheritedDirectives, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind) { - MOZ_ASSERT(funNode); - MOZ_ASSERT(fun); - - size_t index = this->getCompilationInfo().funcData.length(); - if (!this->getCompilationInfo().functions.emplaceBack(fun)) { - return nullptr; - } - if (!this->getCompilationInfo().funcData.emplaceBack(cx_)) { - return nullptr; - } - - // This source extent will be further filled in during the remainder of parse. - SourceExtent extent; - extent.toStringStart = toStringStart; - - /* - * We use JSContext.tempLifoAlloc to allocate parsed objects and place them - * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc - * arenas containing the entries must be alive until we are done with - * scanning, parsing and code generation for the whole script or top-level - * function. - */ - FunctionBox* funbox = alloc_.new_( - cx_, compilationInfo_.traceListHead, extent, this->getCompilationInfo(), - inheritedDirectives, generatorKind, asyncKind, fun->displayAtom(), - fun->flags(), index); - if (!funbox) { - ReportOutOfMemory(cx_); - return nullptr; - } - - compilationInfo_.traceListHead = funbox; - handler_.setFunctionBox(funNode, funbox); - - return funbox; -} - -template -FunctionBox* PerHandlerParser::newFunctionBox( - FunctionNodeType funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, Directives inheritedDirectives, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind) { + FunctionNodeType funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, + TopLevelFunction isTopLevel) { MOZ_ASSERT(funNode); - CompilationInfo& compilationInfo = this->getCompilationInfo(); + FunctionIndex index = + FunctionIndex(compilationInfo_.stencil.scriptData.length()); + MOZ_ASSERT_IF(isTopLevel == TopLevelFunction::Yes, + index == CompilationInfo::TopLevelIndex); - size_t index = compilationInfo.funcData.length(); - if (!compilationInfo.functions.emplaceBack(nullptr)) { - return nullptr; - } - if (!compilationInfo.funcData.emplaceBack(cx_)) { + if (!compilationInfo_.stencil.scriptData.emplaceBack()) { + js::ReportOutOfMemory(cx_); return nullptr; } @@ -312,25 +278,18 @@ FunctionBox* PerHandlerParser::newFunctionBox( * function. */ FunctionBox* funbox = alloc_.new_( - cx_, compilationInfo.traceListHead, extent, compilationInfo, - inheritedDirectives, generatorKind, asyncKind, explicitName, flags, - index); - + cx_, extent, compilationInfo_, compilationState_, inheritedDirectives, + generatorKind, asyncKind, explicitName, flags, index, isTopLevel); if (!funbox) { ReportOutOfMemory(cx_); return nullptr; } - compilationInfo.traceListHead = funbox; handler_.setFunctionBox(funNode, funbox); return funbox; } -void CompilationInfo::trace(JSTracer* trc) { - FunctionBox::TraceList(trc, traceListHead); -} - bool ParserBase::setSourceMapInfo() { // If support for source pragmas have been fully disabled, we can skip // processing of all of these values. @@ -385,8 +344,8 @@ template typename ParseHandler::ListNodeType GeneralParser::parse() { MOZ_ASSERT(checkOptionsCalled_); - SourceExtent extent = - SourceExtent::makeGlobalExtent(/* len = */ 0, options()); + SourceExtent extent = SourceExtent::makeGlobalExtent( + /* len = */ 0, options().lineno, options().column); Directives directives(options().forceStrictMode()); GlobalSharedContext globalsc(cx_, ScopeKind::Global, this->getCompilationInfo(), directives, extent); @@ -423,7 +382,7 @@ typename ParseHandler::ListNodeType GeneralParser::parse() { // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } @@ -437,10 +396,11 @@ typename ParseHandler::ListNodeType GeneralParser::parse() { * Strict mode forbids introducing new definitions for 'eval', 'arguments', * 'let', 'static', 'yield', or for any strict mode reserved word. */ -bool ParserBase::isValidStrictBinding(PropertyName* name) { +bool ParserBase::isValidStrictBinding(const ParserName* name) { TokenKind tt = ReservedWordTokenKind(name); if (tt == TokenKind::Name) { - return name != cx_->names().eval && name != cx_->names().arguments; + return name != cx_->parserNames().eval && + name != cx_->parserNames().arguments; } return tt != TokenKind::Let && tt != TokenKind::Static && tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt); @@ -458,9 +418,9 @@ bool ParserBase::hasValidSimpleStrictParameterNames() { return false; } - for (auto* name : pc_->positionalFormalParameterNames()) { + for (auto name : pc_->positionalFormalParameterNames()) { MOZ_ASSERT(name); - if (!isValidStrictBinding(name->asPropertyName())) { + if (!isValidStrictBinding(name->asName())) { return false; } } @@ -496,9 +456,9 @@ void GeneralParser::reportMissingClosing( template void GeneralParser::reportRedeclaration( - HandlePropertyName name, DeclarationKind prevKind, TokenPos pos, + const ParserName* name, DeclarationKind prevKind, TokenPos pos, uint32_t prevPos) { - UniqueChars bytes = AtomToPrintableString(cx_, name); + UniqueChars bytes = ParserAtomToPrintableString(cx_, name); if (!bytes) { return; } @@ -545,7 +505,7 @@ void GeneralParser::reportRedeclaration( // forbid duplicates.) template bool GeneralParser::notePositionalFormalParameter( - FunctionNodeType funNode, HandlePropertyName name, uint32_t beginPos, + FunctionNodeType funNode, const ParserName* name, uint32_t beginPos, bool disallowDuplicateParams, bool* duplicatedParam) { if (AddDeclaredNamePtr p = pc_->functionScope().lookupDeclaredNameForAdd(name)) { @@ -559,7 +519,7 @@ bool GeneralParser::notePositionalFormalParameter( // In such cases, report will queue up the potential error and return // 'true'. if (pc_->sc()->strict()) { - UniqueChars bytes = AtomToPrintableString(cx_, name); + UniqueChars bytes = ParserAtomToPrintableString(cx_, name); if (!bytes) { return false; } @@ -594,7 +554,7 @@ template bool PerHandlerParser::noteDestructuredPositionalFormalParameter( FunctionNodeType funNode, Node destruct) { // Append an empty name to the positional formals vector to keep track of - // argument slots when making FunctionScope::Data. + // argument slots when making ParserFunctionScopeData. if (!pc_->positionalFormalParameterNames().append(nullptr)) { ReportOutOfMemory(cx_); return false; @@ -605,8 +565,9 @@ bool PerHandlerParser::noteDestructuredPositionalFormalParameter( } template -bool GeneralParser::noteDeclaredName( - HandlePropertyName name, DeclarationKind kind, TokenPos pos) { +bool GeneralParser::noteDeclaredName(const ParserName* name, + DeclarationKind kind, + TokenPos pos) { // The asm.js validator does all its own symbol-table management so, as an // optimization, avoid doing any work here. if (pc_->useAsmOrInsideUseAsm()) { @@ -669,7 +630,8 @@ bool GeneralParser::noteDeclaredName( break; } - case DeclarationKind::LexicalFunction: { + case DeclarationKind::LexicalFunction: + case DeclarationKind::PrivateName: { ParseContext::Scope* scope = pc_->innermostScope(); AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name); if (p) { @@ -716,7 +678,7 @@ bool GeneralParser::noteDeclaredName( // The BoundNames of LexicalDeclaration and ForDeclaration must not // contain 'let'. (CatchParameter is the only lexical binding form // without this restriction.) - if (name == cx_->names().let) { + if (name == cx_->parserNames().let) { errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET); return false; } @@ -738,7 +700,7 @@ bool GeneralParser::noteDeclaredName( case DeclarationKind::Import: // Module code is always strict, so 'let' is always a keyword and never a // name. - MOZ_ASSERT(name != cx_->names().let); + MOZ_ASSERT(name != cx_->parserNames().let); [[fallthrough]]; case DeclarationKind::SimpleCatchParameter: @@ -780,7 +742,62 @@ bool GeneralParser::noteDeclaredName( return true; } -bool ParserBase::noteUsedNameInternal(HandlePropertyName name) { +template +bool GeneralParser::noteDeclaredPrivateName( + Node nameNode, const ParserName* name, PropertyType propType, + TokenPos pos) { + ParseContext::Scope* scope = pc_->innermostScope(); + AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name); + + PrivateNameKind kind; + switch (propType) { + case PropertyType::Field: + kind = PrivateNameKind::Field; + break; + case PropertyType::Method: + case PropertyType::GeneratorMethod: + case PropertyType::AsyncMethod: + case PropertyType::AsyncGeneratorMethod: + kind = PrivateNameKind::Method; + break; + case PropertyType::Getter: + kind = PrivateNameKind::Getter; + break; + case PropertyType::Setter: + kind = PrivateNameKind::Setter; + break; + default: + kind = PrivateNameKind::None; + } + + if (p) { + PrivateNameKind prevKind = p->value()->privateNameKind(); + if ((prevKind == PrivateNameKind::Getter && + kind == PrivateNameKind::Setter) || + (prevKind == PrivateNameKind::Setter && + kind == PrivateNameKind::Getter)) { + p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter); + handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter); + return true; + } + + reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos()); + return false; + } + + if (!scope->addDeclaredName(pc_, p, name, DeclarationKind::PrivateName, + pos.begin)) { + return false; + } + scope->lookupDeclaredName(name)->value()->setPrivateNameKind(kind); + handler_.setPrivateNameKind(nameNode, kind); + + return true; +} + +bool ParserBase::noteUsedNameInternal(const ParserName* name, + NameVisibility visibility, + mozilla::Maybe tokenPosition) { // The asm.js validator does all its own symbol-table management so, as an // optimization, avoid doing any work here. if (pc_->useAsmOrInsideUseAsm()) { @@ -791,12 +808,18 @@ bool ParserBase::noteUsedNameInternal(HandlePropertyName name) { // to know if they are closed over. So no need to track used name at the // global scope. It is not incorrect to track them, this is an // optimization. + // + // As an exception however, we continue to track private name references, + // as the used names tracker is used to provide early errors for undeclared + // private name references ParseContext::Scope* scope = pc_->innermostScope(); - if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope()) { + if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() && + visibility == NameVisibility::Public) { return true; } - return usedNames_.noteUse(cx_, name, pc_->scriptId(), scope->id()); + return usedNames_.noteUse(cx_, name, visibility, pc_->scriptId(), scope->id(), + tokenPosition); } template @@ -812,7 +835,17 @@ bool PerHandlerParser:: // Scopes are nullptr-delimited in the BaseScript closed over bindings // array. while (JSAtom* name = handler_.nextLazyClosedOverBinding()) { - scope.lookupDeclaredName(name)->value()->setClosedOver(); + // TODO-Stencil + // After closed-over-bindings are snapshotted in the handler, + // remove this. + auto mbNameId = compilationInfo_.stencil.parserAtoms.internJSAtom( + cx_, this->getCompilationInfo(), name); + if (mbNameId.isErr()) { + return false; + } + const ParserName* nameId = mbNameId.unwrap()->asName(); + + scope.lookupDeclaredName(nameId)->value()->setClosedOver(); } return true; } @@ -868,11 +901,11 @@ bool Parser::checkStatementsEOF() { return true; } -template -typename Scope::Data* NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, - uint32_t numBindings) { - using Data = typename Scope::Data; - size_t allocSize = SizeOfData(numBindings); +template +ParserScopeData* NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, + uint32_t numBindings) { + using Data = ParserScopeData; + size_t allocSize = SizeOfScopeData(numBindings); auto* bindings = alloc.newWithSize(allocSize, numBindings); if (!bindings) { ReportOutOfMemory(cx); @@ -883,19 +916,19 @@ typename Scope::Data* NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, namespace detail { template -static MOZ_ALWAYS_INLINE BindingName* InitializeIndexedBindings( - Data* data, BindingName* start, BindingName* cursor) { +static MOZ_ALWAYS_INLINE ParserBindingName* InitializeIndexedBindings( + Data* data, ParserBindingName* start, ParserBindingName* cursor) { return cursor; } template -static MOZ_ALWAYS_INLINE BindingName* InitializeIndexedBindings( - Data* data, BindingName* start, BindingName* cursor, - UnsignedInteger Data::*field, const BindingNameVector& bindings, +static MOZ_ALWAYS_INLINE ParserBindingName* InitializeIndexedBindings( + Data* data, ParserBindingName* start, ParserBindingName* cursor, + UnsignedInteger Data::*field, const ParserBindingNameVector& bindings, Step&&... step) { data->*field = AssertedCast(PointerRangeSize(start, cursor)); - BindingName* newCursor = + ParserBindingName* newCursor = std::uninitialized_copy(bindings.begin(), bindings.end(), cursor); return InitializeIndexedBindings(data, start, newCursor, @@ -910,20 +943,20 @@ static MOZ_ALWAYS_INLINE BindingName* InitializeIndexedBindings( // First, |firstBindings| are added to |data->trailingNames|. Then any "steps" // present are performed first to last. Each step is 1) a pointer to a member // of |data| to be set to the current number of bindings added, and 2) a vector -// of |BindingName|s to then copy into |data->trailingNames|. (Thus each +// of |ParserBindingName|s to then copy into |data->trailingNames|. (Thus each // |data| member field indicates where the corresponding vector's names start.) template static MOZ_ALWAYS_INLINE void InitializeBindingData( - Data* data, uint32_t count, const BindingNameVector& firstBindings, + Data* data, uint32_t count, const ParserBindingNameVector& firstBindings, Step&&... step) { MOZ_ASSERT(data->length == 0, "data shouldn't be filled yet"); - BindingName* start = data->trailingNames.start(); - BindingName* cursor = std::uninitialized_copy(firstBindings.begin(), - firstBindings.end(), start); + ParserBindingName* start = data->trailingNames.start(); + ParserBindingName* cursor = std::uninitialized_copy( + firstBindings.begin(), firstBindings.end(), start); #ifdef DEBUG - BindingName* end = + ParserBindingName* end = #endif detail::InitializeIndexedBindings(data, start, cursor, std::forward(step)...); @@ -932,13 +965,13 @@ static MOZ_ALWAYS_INLINE void InitializeBindingData( data->length = count; } -Maybe NewGlobalScopeData(JSContext* cx, - ParseContext::Scope& scope, - LifoAlloc& alloc, - ParseContext* pc) { - BindingNameVector vars(cx); - BindingNameVector lets(cx); - BindingNameVector consts(cx); +Maybe NewGlobalScopeData(JSContext* cx, + ParseContext::Scope& scope, + LifoAlloc& alloc, + ParseContext* pc) { + ParserBindingNameVector vars(cx); + ParserBindingNameVector lets(cx); + ParserBindingNameVector consts(cx); bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver(); for (BindingIter bi = scope.bindings(pc); bi; bi++) { @@ -948,21 +981,22 @@ Maybe NewGlobalScopeData(JSContext* cx, case BindingKind::Var: { bool isTopLevelFunction = bi.declarationKind() == DeclarationKind::BodyLevelFunction; - BindingName binding(bi.name(), closedOver, isTopLevelFunction); + + ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction); if (!vars.append(binding)) { return Nothing(); } break; } case BindingKind::Let: { - BindingName binding(bi.name(), closedOver); + ParserBindingName binding(bi.name(), closedOver); if (!lets.append(binding)) { return Nothing(); } break; } case BindingKind::Const: { - BindingName binding(bi.name(), closedOver); + ParserBindingName binding(bi.name(), closedOver); if (!consts.append(binding)) { return Nothing(); } @@ -973,7 +1007,7 @@ Maybe NewGlobalScopeData(JSContext* cx, } } - GlobalScope::Data* bindings = nullptr; + ParserGlobalScopeData* bindings = nullptr; uint32_t numBindings = vars.length() + lets.length() + consts.length(); if (numBindings > 0) { @@ -984,32 +1018,33 @@ Maybe NewGlobalScopeData(JSContext* cx, // The ordering here is important. See comments in GlobalScope. InitializeBindingData(bindings, numBindings, vars, - &GlobalScope::Data::letStart, lets, - &GlobalScope::Data::constStart, consts); + &ParserGlobalScopeData::letStart, lets, + &ParserGlobalScopeData::constStart, consts); } return Some(bindings); } -Maybe ParserBase::newGlobalScopeData( +Maybe ParserBase::newGlobalScopeData( ParseContext::Scope& scope) { return NewGlobalScopeData(cx_, scope, alloc_, pc_); } -Maybe NewModuleScopeData(JSContext* cx, - ParseContext::Scope& scope, - LifoAlloc& alloc, - ParseContext* pc) { - BindingNameVector imports(cx); - BindingNameVector vars(cx); - BindingNameVector lets(cx); - BindingNameVector consts(cx); +Maybe NewModuleScopeData(JSContext* cx, + ParseContext::Scope& scope, + LifoAlloc& alloc, + ParseContext* pc) { + ParserBindingNameVector imports(cx); + ParserBindingNameVector vars(cx); + ParserBindingNameVector lets(cx); + ParserBindingNameVector consts(cx); bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver(); for (BindingIter bi = scope.bindings(pc); bi; bi++) { // Imports are indirect bindings and must not be given known slots. - BindingName binding(bi.name(), (allBindingsClosedOver || bi.closedOver()) && - bi.kind() != BindingKind::Import); + ParserBindingName binding(bi.name(), + (allBindingsClosedOver || bi.closedOver()) && + bi.kind() != BindingKind::Import); switch (bi.kind()) { case BindingKind::Import: if (!imports.append(binding)) { @@ -1036,7 +1071,7 @@ Maybe NewModuleScopeData(JSContext* cx, } } - ModuleScope::Data* bindings = nullptr; + ParserModuleScopeData* bindings = nullptr; uint32_t numBindings = imports.length() + vars.length() + lets.length() + consts.length(); @@ -1048,23 +1083,24 @@ Maybe NewModuleScopeData(JSContext* cx, // The ordering here is important. See comments in ModuleScope. InitializeBindingData(bindings, numBindings, imports, - &ModuleScope::Data::varStart, vars, - &ModuleScope::Data::letStart, lets, - &ModuleScope::Data::constStart, consts); + &ParserModuleScopeData::varStart, vars, + &ParserModuleScopeData::letStart, lets, + &ParserModuleScopeData::constStart, consts); } return Some(bindings); } -Maybe ParserBase::newModuleScopeData( +Maybe ParserBase::newModuleScopeData( ParseContext::Scope& scope) { return NewModuleScopeData(cx_, scope, alloc_, pc_); } -Maybe NewEvalScopeData(JSContext* cx, - ParseContext::Scope& scope, - LifoAlloc& alloc, ParseContext* pc) { - BindingNameVector vars(cx); +Maybe NewEvalScopeData(JSContext* cx, + ParseContext::Scope& scope, + LifoAlloc& alloc, + ParseContext* pc) { + ParserBindingNameVector vars(cx); for (BindingIter bi = scope.bindings(pc); bi; bi++) { // Eval scopes only contain 'var' bindings. Make all bindings aliased @@ -1072,13 +1108,14 @@ Maybe NewEvalScopeData(JSContext* cx, MOZ_ASSERT(bi.kind() == BindingKind::Var); bool isTopLevelFunction = bi.declarationKind() == DeclarationKind::BodyLevelFunction; - BindingName binding(bi.name(), true, isTopLevelFunction); + + ParserBindingName binding(bi.name(), true, isTopLevelFunction); if (!vars.append(binding)) { return Nothing(); } } - EvalScope::Data* bindings = nullptr; + ParserEvalScopeData* bindings = nullptr; uint32_t numBindings = vars.length(); if (numBindings > 0) { @@ -1093,19 +1130,19 @@ Maybe NewEvalScopeData(JSContext* cx, return Some(bindings); } -Maybe ParserBase::newEvalScopeData( +Maybe ParserBase::newEvalScopeData( ParseContext::Scope& scope) { return NewEvalScopeData(cx_, scope, alloc_, pc_); } -Maybe NewFunctionScopeData(JSContext* cx, - ParseContext::Scope& scope, - bool hasParameterExprs, - LifoAlloc& alloc, - ParseContext* pc) { - BindingNameVector positionalFormals(cx); - BindingNameVector formals(cx); - BindingNameVector vars(cx); +Maybe NewFunctionScopeData(JSContext* cx, + ParseContext::Scope& scope, + bool hasParameterExprs, + LifoAlloc& alloc, + ParseContext* pc) { + ParserBindingNameVector positionalFormals(cx); + ParserBindingNameVector formals(cx); + ParserBindingNameVector vars(cx); bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver(); bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters; @@ -1113,9 +1150,9 @@ Maybe NewFunctionScopeData(JSContext* cx, // Positional parameter names must be added in order of appearance as they are // referenced using argument slots. for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) { - JSAtom* name = pc->positionalFormalParameterNames()[i]; + const ParserAtom* name = pc->positionalFormalParameterNames()[i]; - BindingName bindName; + ParserBindingName bindName; if (name) { DeclaredNamePtr p = scope.lookupDeclaredName(name); @@ -1138,7 +1175,7 @@ Maybe NewFunctionScopeData(JSContext* cx, } } - bindName = BindingName(name, closedOver); + bindName = ParserBindingName(name, closedOver); } if (!positionalFormals.append(bindName)) { @@ -1147,7 +1184,8 @@ Maybe NewFunctionScopeData(JSContext* cx, } for (BindingIter bi = scope.bindings(pc); bi; bi++) { - BindingName binding(bi.name(), allBindingsClosedOver || bi.closedOver()); + ParserBindingName binding(bi.name(), + allBindingsClosedOver || bi.closedOver()); switch (bi.kind()) { case BindingKind::FormalParameter: // Positional parameter names are already handled above. @@ -1172,7 +1210,7 @@ Maybe NewFunctionScopeData(JSContext* cx, } } - FunctionScope::Data* bindings = nullptr; + ParserFunctionScopeData* bindings = nullptr; uint32_t numBindings = positionalFormals.length() + formals.length() + vars.length(); @@ -1184,8 +1222,8 @@ Maybe NewFunctionScopeData(JSContext* cx, // The ordering here is important. See comments in FunctionScope. InitializeBindingData(bindings, numBindings, positionalFormals, - &FunctionScope::Data::nonPositionalFormalStart, - formals, &FunctionScope::Data::varStart, vars); + &ParserFunctionScopeData::nonPositionalFormalStart, + formals, &ParserFunctionScopeData::varStart, vars); } return Some(bindings); @@ -1214,28 +1252,29 @@ bool FunctionScopeHasClosedOverBindings(ParseContext* pc) { return false; } -Maybe ParserBase::newFunctionScopeData( +Maybe ParserBase::newFunctionScopeData( ParseContext::Scope& scope, bool hasParameterExprs) { return NewFunctionScopeData(cx_, scope, hasParameterExprs, alloc_, pc_); } -Maybe NewVarScopeData(JSContext* cx, - ParseContext::Scope& scope, - LifoAlloc& alloc, ParseContext* pc) { - BindingNameVector vars(cx); +Maybe NewVarScopeData(JSContext* cx, + ParseContext::Scope& scope, + LifoAlloc& alloc, ParseContext* pc) { + ParserBindingNameVector vars(cx); bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver(); for (BindingIter bi = scope.bindings(pc); bi; bi++) { if (bi.kind() == BindingKind::Var) { - BindingName binding(bi.name(), allBindingsClosedOver || bi.closedOver()); + ParserBindingName binding(bi.name(), + allBindingsClosedOver || bi.closedOver()); if (!vars.append(binding)) { return Nothing(); } } } - VarScope::Data* bindings = nullptr; + ParserVarScopeData* bindings = nullptr; uint32_t numBindings = vars.length(); if (numBindings > 0) { @@ -1262,21 +1301,23 @@ static bool VarScopeHasBindings(ParseContext* pc) { return false; } -Maybe ParserBase::newVarScopeData(ParseContext::Scope& scope) { +Maybe ParserBase::newVarScopeData( + ParseContext::Scope& scope) { return NewVarScopeData(cx_, scope, alloc_, pc_); } -Maybe NewLexicalScopeData(JSContext* cx, - ParseContext::Scope& scope, - LifoAlloc& alloc, - ParseContext* pc) { - BindingNameVector lets(cx); - BindingNameVector consts(cx); +Maybe NewLexicalScopeData(JSContext* cx, + ParseContext::Scope& scope, + LifoAlloc& alloc, + ParseContext* pc) { + ParserBindingNameVector lets(cx); + ParserBindingNameVector consts(cx); bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver(); for (BindingIter bi = scope.bindings(pc); bi; bi++) { - BindingName binding(bi.name(), allBindingsClosedOver || bi.closedOver()); + ParserBindingName binding(bi.name(), + allBindingsClosedOver || bi.closedOver()); switch (bi.kind()) { case BindingKind::Let: if (!lets.append(binding)) { @@ -1293,7 +1334,7 @@ Maybe NewLexicalScopeData(JSContext* cx, } } - LexicalScope::Data* bindings = nullptr; + ParserLexicalScopeData* bindings = nullptr; uint32_t numBindings = lets.length() + consts.length(); if (numBindings > 0) { @@ -1304,7 +1345,7 @@ Maybe NewLexicalScopeData(JSContext* cx, // The ordering here is important. See comments in LexicalScope. InitializeBindingData(bindings, numBindings, lets, - &LexicalScope::Data::constStart, consts); + &ParserLexicalScopeData::constStart, consts); } return Some(bindings); @@ -1334,7 +1375,7 @@ bool LexicalScopeHasClosedOverBindings(ParseContext* pc, return false; } -Maybe ParserBase::newLexicalScopeData( +Maybe ParserBase::newLexicalScopeData( ParseContext::Scope& scope) { return NewLexicalScopeData(cx_, scope, alloc_, pc_); } @@ -1357,7 +1398,7 @@ LexicalScopeNode* PerHandlerParser::finishLexicalScope( return nullptr; } - Maybe bindings = newLexicalScopeData(scope); + Maybe bindings = newLexicalScopeData(scope); if (!bindings) { return nullptr; } @@ -1365,6 +1406,89 @@ LexicalScopeNode* PerHandlerParser::finishLexicalScope( return handler_.newLexicalScope(*bindings, body, kind); } +template +bool PerHandlerParser::checkForUndefinedPrivateFields( + EvalSharedContext* evalSc) { + if (handler_.canSkipLazyClosedOverBindings()) { + // We're delazifying -- so we already checked private names during first + // parse. + return true; + } + + Vector unboundPrivateNames(cx_); + if (!this->compilationState_.usedNames.getUnboundPrivateNames( + unboundPrivateNames)) { + return false; + } + + // No unbound names, let's get out of here! + if (unboundPrivateNames.empty()) { + return true; + } + + // It is an early error if there's private name references unbound, + // unless it's an eval, in which case we need to check the scope + // chain. + if (!evalSc) { + // The unbound private names are sorted, so just grab the first one. + UnboundPrivateName minimum = unboundPrivateNames[0]; + UniqueChars str = ParserAtomToPrintableString(cx_, minimum.atom); + if (!str) { + return false; + } + + errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get()); + return false; + } + + // For the given private name, search the enclosing scope chain + // to see if there's an associated binding, and if not, issue an error. + auto verifyPrivateName = [](JSContext* cx, auto* parser, + HandleScope enclosingScope, + UnboundPrivateName unboundName) { + // Walk the enclosing scope chain looking for this private name; + for (ScopeIter si(enclosingScope); si; si++) { + // Private names are only found within class body scopes. + if (si.scope()->kind() != ScopeKind::ClassBody) { + continue; + } + + // Look for a matching binding. + for (js::BindingIter bi(si.scope()); bi; bi++) { + if (unboundName.atom->equalsJSAtom(bi.name())) { + // Awesome. We found it, we're done here! + return true; + } + } + } + + // Didn't find a matching binding, so issue an error. + UniqueChars str = ParserAtomToPrintableString(cx, unboundName.atom); + if (!str) { + return false; + } + parser->errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL, + str.get()); + return false; + }; + + // It's important that the unbound private names are sorted, as we + // want our errors to always be issued to the first textually. + for (UnboundPrivateName unboundName : unboundPrivateNames) { + // If the enclosingScope is non-syntactic, then we are in a + // Debugger.Frame.prototype.eval call. In order to find the declared private + // names, we must use the effective scope that was determined when creating + // the scopeContext. + if (!verifyPrivateName(cx_, this, + compilationState_.scopeContext.effectiveScope, + unboundName)) { + return false; + } + } + + return true; +} + template LexicalScopeNode* Parser::evalBody( EvalSharedContext* evalsc) { @@ -1395,6 +1519,11 @@ LexicalScopeNode* Parser::evalBody( return nullptr; } + // Private names not lexically defined must trigger a syntax error. + if (!checkForUndefinedPrivateFields(evalsc)) { + return nullptr; + } + body = finishLexicalScope(lexicalScope, list); if (!body) { return nullptr; @@ -1403,12 +1532,12 @@ LexicalScopeNode* Parser::evalBody( #ifdef DEBUG if (evalpc.superScopeNeedsHomeObject() && - evalsc->compilationEnclosingScope()) { + this->getCompilationInfo().input.enclosingScope) { // If superScopeNeedsHomeObject_ is set and we are an entry-point // ParseContext, then we must be emitting an eval script, and the // outer function must already be marked as needing a home object // since it contains an eval. - ScopeIter si(evalsc->compilationEnclosingScope()); + ScopeIter si(this->getCompilationInfo().input.enclosingScope); for (; si; si++) { if (si.kind() == ScopeKind::Function) { JSFunction* fun = si.scope()->as().canonicalFunction(); @@ -1434,7 +1563,7 @@ LexicalScopeNode* Parser::evalBody( // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } @@ -1451,7 +1580,7 @@ LexicalScopeNode* Parser::evalBody( return nullptr; } - Maybe bindings = newEvalScopeData(pc_->varScope()); + Maybe bindings = newEvalScopeData(pc_->varScope()); if (!bindings) { return nullptr; } @@ -1486,11 +1615,15 @@ ListNode* Parser::globalBody( return null(); } + if (!checkForUndefinedPrivateFields()) { + return null(); + } + ParseNode* node = body; // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } @@ -1507,7 +1640,7 @@ ListNode* Parser::globalBody( return nullptr; } - Maybe bindings = newGlobalScopeData(pc_->varScope()); + Maybe bindings = newGlobalScopeData(pc_->varScope()); if (!bindings) { return nullptr; } @@ -1555,18 +1688,22 @@ ModuleNode* Parser::moduleBody( return null(); } - if (!modulesc->builder.buildTables()) { + // Generate the Import/Export tables and store in CompilationInfo. + if (!modulesc->builder.buildTables( + this->compilationInfo_.stencil.moduleMetadata)) { return null(); } // Check exported local bindings exist and mark them as closed over. - for (auto entry : modulesc->builder.localExportEntries()) { - JSAtom* name = entry->localName(); - MOZ_ASSERT(name); + StencilModuleMetadata& moduleMetadata = + this->compilationInfo_.stencil.moduleMetadata; + for (auto entry : moduleMetadata.localExportEntries) { + const ParserAtom* nameId = entry.localName; + MOZ_ASSERT(nameId); - DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(name); + DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(nameId); if (!p) { - UniqueChars str = AtomToPrintableString(cx_, name); + UniqueChars str = ParserAtomToPrintableString(cx_, nameId); if (!str) { return null(); } @@ -1578,6 +1715,17 @@ ModuleNode* Parser::moduleBody( p->value()->setClosedOver(); } + // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as + // closed-over. We do not know until module linking if this will be used. + if (!noteDeclaredName(cx_->parserNames().starNamespaceStar, + DeclarationKind::Const, pos())) { + return nullptr; + } + modulepc.varScope() + .lookupDeclaredName(cx_->parserNames().starNamespaceStar) + ->value() + ->setClosedOver(); + if (!CheckParseTree(cx_, alloc_, stmtList)) { return null(); } @@ -1586,7 +1734,7 @@ ModuleNode* Parser::moduleBody( // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } @@ -1596,11 +1744,17 @@ ModuleNode* Parser::moduleBody( return null(); } + // Private names not lexically defined must trigger a syntax error. + if (!checkForUndefinedPrivateFields()) { + return null(); + } + if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) { return null(); } - Maybe bindings = newModuleScopeData(modulepc.varScope()); + Maybe bindings = + newModuleScopeData(modulepc.varScope()); if (!bindings) { return nullptr; } @@ -1618,7 +1772,7 @@ SyntaxParseHandler::ModuleNodeType Parser::moduleBody( template typename ParseHandler::NameNodeType -PerHandlerParser::newInternalDotName(HandlePropertyName name) { +PerHandlerParser::newInternalDotName(const ParserName* name) { NameNodeType nameNode = newName(name); if (!nameNode) { return null(); @@ -1632,13 +1786,13 @@ PerHandlerParser::newInternalDotName(HandlePropertyName name) { template typename ParseHandler::NameNodeType PerHandlerParser::newThisName() { - return newInternalDotName(cx_->names().dotThis); + return newInternalDotName(cx_->parserNames().dotThis); } template typename ParseHandler::NameNodeType PerHandlerParser::newDotGeneratorName() { - return newInternalDotName(cx_->names().dotGenerator); + return newInternalDotName(cx_->parserNames().dotGenerator); } template @@ -1690,6 +1844,7 @@ bool PerHandlerParser::finishFunction( } FunctionBox* funbox = pc_->functionBox(); + ScriptStencil& script = funbox->functionStencil(); if (funbox->isInterpreted()) { // BCE will need to generate bytecode for this. @@ -1699,11 +1854,11 @@ bool PerHandlerParser::finishFunction( bool hasParameterExprs = funbox->hasParameterExprs; if (hasParameterExprs) { - Maybe bindings = newVarScopeData(pc_->varScope()); + Maybe bindings = newVarScopeData(pc_->varScope()); if (!bindings) { return false; } - funbox->extraVarScopeBindings().set(*bindings); + funbox->setExtraVarScopeBindings(*bindings); MOZ_ASSERT(bool(*bindings) == VarScopeHasBindings(pc_)); MOZ_ASSERT_IF(!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(), @@ -1711,23 +1866,26 @@ bool PerHandlerParser::finishFunction( } { - Maybe bindings = + Maybe bindings = newFunctionScopeData(pc_->functionScope(), hasParameterExprs); if (!bindings) { return false; } - funbox->functionScopeBindings().set(*bindings); + funbox->setFunctionScopeBindings(*bindings); } if (funbox->isNamedLambda() && !isStandaloneFunction) { - Maybe bindings = + Maybe bindings = newLexicalScopeData(pc_->namedLambdaScope()); if (!bindings) { return false; } - funbox->namedLambdaBindings().set(*bindings); + funbox->setNamedLambdaBindings(*bindings); } + funbox->finishScriptFlags(); + funbox->copyFunctionFields(script); + return true; } @@ -1744,22 +1902,18 @@ bool PerHandlerParser::finishFunction( } FunctionBox* funbox = pc_->functionBox(); - ScriptStencil& stencil = funbox->functionStencil().get(); + ScriptStencil& script = funbox->functionStencil(); - // Compute the flags for the BaseScript. - using ImmutableFlags = ImmutableScriptFlagsEnum; - stencil.immutableFlags = funbox->immutableFlags(); - stencil.immutableFlags.setFlag(ImmutableFlags::HasMappedArgsObj, - funbox->hasMappedArgsObj()); - stencil.immutableFlags.setFlag(ImmutableFlags::IsLikelyConstructorWrapper, - funbox->isLikelyConstructorWrapper()); + funbox->finishScriptFlags(); + funbox->copyFunctionFields(script); + funbox->copyScriptFields(script); // Elide nullptr sentinels from end of binding list. These are inserted for // each scope regardless of if any bindings are actually closed over. { - AtomVector& COB = pc_->closedOverBindingsForLazy(); - while (!COB.empty() && (COB.back() == nullptr)) { - COB.popBack(); + AtomVector& closedOver = pc_->closedOverBindingsForLazy(); + while (!closedOver.empty() && !closedOver.back()) { + closedOver.popBack(); } } @@ -1772,8 +1926,9 @@ bool PerHandlerParser::finishFunction( return false; } - ScriptThingsVector& gcthings = stencil.gcThings; + ScriptThingsVector& gcthings = script.gcThings; if (!gcthings.reserve(ngcthings.value())) { + js::ReportOutOfMemory(cx_); return false; } @@ -1800,204 +1955,6 @@ bool PerHandlerParser::finishFunction( return true; } -static bool CreateLazyScript(JSContext* cx, CompilationInfo& compilationInfo, - FunctionBox* funbox) { - RootedFunction function(cx, funbox->function()); - - ScriptStencil& stencil = funbox->functionStencil().get(); - const ScriptThingsVector& gcthings = stencil.gcThings; - - Rooted lazy( - cx, BaseScript::CreateRawLazy(cx, gcthings.length(), function, - compilationInfo.sourceObject, - funbox->extent, stencil.immutableFlags)); - if (!lazy) { - return false; - } - - if (!EmitScriptThingsVector(cx, compilationInfo, gcthings, - lazy->gcthingsForInit())) { - return false; - } - - function->initScript(lazy); - - return true; -} - -// Instantiate JSFunctions for each FunctionBox. -static bool InstantiateFunctions(JSContext* cx, - CompilationInfo& compilationInfo, - FunctionBox* listHead) { - for (FunctionBox* funbox = listHead; funbox; funbox = funbox->traceLink()) { - if (funbox->hasFunction()) { - continue; - } - - RootedFunction fun(cx, funbox->createFunction(cx)); - if (!fun) { - return false; - } - funbox->initializeFunction(fun); - } - - return true; -} - -// JSFunctions have a default ObjectGroup when they are created. Once their -// enclosing script is compiled, we have more precise heuristic information and -// now compute their final group. These functions have not been exposed to -// script before this point. -static bool SetTypeForExposedFunctions(JSContext* cx, FunctionBox* listHead) { - for (FunctionBox* funbox = listHead; funbox; funbox = funbox->traceLink()) { - if (!funbox->isInterpreted()) { - continue; - } - - // If the function was not referenced by enclosing script's bytecode, we do - // not generate a BaseScript for it. For example, `(function(){});`. - if (!funbox->wasEmitted && !funbox->isStandalone) { - continue; - } - - RootedFunction fun(cx, funbox->function()); - if (!JSFunction::setTypeForScriptedFunction(cx, fun, funbox->isSingleton)) { - return false; - } - } - - return true; -} - -// Instantiate js::BaseScripts from ScriptStencils for inner functions of the -// compilation. Note that standalone functions and functions being delazified -// are handled below with other top-levels. -static bool InstantiateScriptStencils(JSContext* cx, - CompilationInfo& compilationInfo, - FunctionBox* listHead) { - for (FunctionBox* funbox = listHead; funbox; funbox = funbox->traceLink()) { - if (funbox->emitBytecode) { - // If the function was not referenced by enclosing script's bytecode, we - // do not generate a BaseScript for it. For example, `(function(){});`. - if (!funbox->wasEmitted) { - continue; - } - - RootedScript script(cx, - JSScript::fromStencil(cx, compilationInfo, - funbox->functionStencil().get(), - funbox->extent)); - if (!script) { - return false; - } - } else if (funbox->isAsmJSModule()) { - MOZ_ASSERT(funbox->function()->isAsmJSNative()); - } else if (funbox->function()->isIncomplete()) { - // Lazy functions are generally only allocated in the initial parse. The - // exception to this is BinAST which does not allocate lazy functions - // inside lazy functions until delazification occurs. - MOZ_ASSERT(compilationInfo.lazy == nullptr || - compilationInfo.lazy->isBinAST()); - - if (!CreateLazyScript(cx, compilationInfo, funbox)) { - return false; - } - } - } - - return true; -} - -// Instantiate the Stencil for the top-level script of the compilation. This -// includes standalone functions and functions being delazified. -static bool InstantiateTopLevel(JSContext* cx, - CompilationInfo& compilationInfo) { - ScriptStencil& stencil = compilationInfo.topLevel.get(); - - // Top-level asm.js does not generate a JSScript. - if (compilationInfo.topLevelAsmJS) { - return true; - } - - MOZ_ASSERT(stencil.immutableScriptData); - - if (compilationInfo.lazy) { - compilationInfo.script = JSScript::CastFromLazy(compilationInfo.lazy); - return JSScript::fullyInitFromStencil(cx, compilationInfo, - compilationInfo.script, stencil); - } - - compilationInfo.script = JSScript::fromStencil( - cx, compilationInfo, stencil, compilationInfo.topLevelExtent); - return !!compilationInfo.script; -} - -// When a function is first referenced by enclosing script's bytecode, we need -// to update it with information determined by the BytecodeEmitter. This applies -// to both initial and delazification parses. The functions being update may or -// may not have bytecode at this point. -static void UpdateEmittedInnerFunctions(FunctionBox* listHead) { - for (FunctionBox* funbox = listHead; funbox; funbox = funbox->traceLink()) { - if (!funbox->wasEmitted) { - continue; - } - - funbox->finish(); - } -} - -// During initial parse we must link lazy-functions-inside-lazy-functions to -// their enclosing script. -static void LinkEnclosingLazyScript(FunctionBox* listHead) { - for (FunctionBox* funbox = listHead; funbox; funbox = funbox->traceLink()) { - if (!funbox->isInterpreted()) { - continue; - } - - if (funbox->emitBytecode) { - continue; - } - - BaseScript* script = funbox->function()->baseScript(); - MOZ_ASSERT(!script->hasBytecode()); - - for (auto inner : script->gcthings()) { - if (!inner.is()) { - continue; - } - inner.as().as().setEnclosingLazyScript(script); - } - } -} - -bool CompilationInfo::instantiateStencils() { - if (!InstantiateFunctions(cx, *this, traceListHead)) { - return false; - } - - if (!SetTypeForExposedFunctions(cx, traceListHead)) { - return false; - } - - if (!InstantiateScriptStencils(cx, *this, traceListHead)) { - return false; - } - - if (!InstantiateTopLevel(cx, *this)) { - return false; - } - - // Must be infallible from here forward. - - UpdateEmittedInnerFunctions(traceListHead); - - if (lazy == nullptr) { - LinkEnclosingLazyScript(traceListHead); - } - - return true; -} - static YieldHandling GetYieldHandling(GeneratorKind generatorKind) { if (generatorKind == GeneratorKind::NotGenerator) { return YieldIsName; @@ -2075,10 +2032,9 @@ FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind, template FunctionNode* Parser::standaloneFunction( - HandleScope enclosingScope, const Maybe& parameterListEnd, - FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind, Directives inheritedDirectives, - Directives* newDirectives) { + const Maybe& parameterListEnd, FunctionSyntaxKind syntaxKind, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, + Directives inheritedDirectives, Directives* newDirectives) { MOZ_ASSERT(checkOptionsCalled_); // Skip prelude. TokenKind tt; @@ -2104,7 +2060,7 @@ FunctionNode* Parser::standaloneFunction( } // Skip function name, if present. - RootedAtom explicitName(cx_); + const ParserAtom* explicitName = nullptr; if (TokenKindIsPossibleIdentifierName(tt)) { explicitName = anyChars.currentName(); } else { @@ -2125,23 +2081,18 @@ FunctionNode* Parser::standaloneFunction( bool isSelfHosting = options().selfHostingMode; FunctionFlags flags = InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting); - FunctionBox* funbox = - newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0, - inheritedDirectives, generatorKind, asyncKind); + FunctionBox* funbox = newFunctionBox( + funNode, explicitName, flags, /* toStringStart = */ 0, + inheritedDirectives, generatorKind, asyncKind, TopLevelFunction::Yes); if (!funbox) { return null(); } // Function is not syntactically part of another script. - funbox->isStandalone = true; + funbox->setIsStandalone(true); - // Standalone functions are always scoped to the global. Note: HTML form event - // handlers are standalone functions, but have a non-syntactic global scope - // chain here. - MOZ_ASSERT(enclosingScope->is()); - - funbox->initWithEnclosingScope(this->compilationInfo_.scopeContext, - enclosingScope, flags, syntaxKind); + funbox->initStandalone(this->compilationState_.scopeContext, flags, + syntaxKind); SourceParseContext funpc(this, funbox, newDirectives); if (!funpc.init()) { @@ -2174,12 +2125,16 @@ FunctionNode* Parser::standaloneFunction( // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } funNode = &node->as(); + if (!checkForUndefinedPrivateFields(nullptr)) { + return null(); + } + if (!this->setSourceMapInfo()) { return null(); } @@ -2331,7 +2286,6 @@ bool GeneralParser::matchOrInsertSemicolon( bool ParserBase::leaveInnerFunction(ParseContext* outerpc) { MOZ_ASSERT(pc_ != outerpc); - // See: CompilationInfo::publishDeferredFunctions() MOZ_ASSERT_IF(outerpc->isFunctionBox(), outerpc->functionBox()->index() < pc_->functionBox()->index()); @@ -2363,22 +2317,20 @@ bool ParserBase::leaveInnerFunction(ParseContext* outerpc) { return true; } -JSAtom* ParserBase::prefixAccessorName(PropertyType propType, - HandleAtom propAtom) { - RootedAtom prefix(cx_); +const ParserAtom* ParserBase::prefixAccessorName(PropertyType propType, + const ParserAtom* propAtom) { + const ParserAtom* prefix = nullptr; if (propType == PropertyType::Setter) { - prefix = cx_->names().setPrefix; + prefix = cx_->parserNames().setPrefix; } else { MOZ_ASSERT(propType == PropertyType::Getter); - prefix = cx_->names().getPrefix; - } - - RootedString str(cx_, ConcatStrings(cx_, prefix, propAtom)); - if (!str) { - return nullptr; + prefix = cx_->parserNames().getPrefix; } - return AtomizeString(cx_, str); + const ParserAtom* atoms[2] = {prefix, propAtom}; + auto atomsRange = mozilla::Range(atoms, 2); + return compilationInfo_.stencil.parserAtoms.concatAtoms(cx_, atomsRange) + .unwrapOr(nullptr); } template @@ -2576,7 +2528,7 @@ bool GeneralParser::functionArguments( setFunctionStartAtCurrentToken(funbox); } - RootedPropertyName name(cx_, bindingIdentifier(yieldHandling)); + const ParserName* name = bindingIdentifier(yieldHandling); if (!name) { return false; } @@ -2636,7 +2588,7 @@ bool GeneralParser::functionArguments( // The Function.length property is the number of formals // before the first default argument. - funbox->length = positionalFormals.length() - 1; + funbox->setLength(positionalFormals.length() - 1); } funbox->hasParameterExprs = true; @@ -2690,7 +2642,7 @@ bool GeneralParser::functionArguments( } if (!hasDefault) { - funbox->length = positionalFormals.length() - hasRest; + funbox->setLength(positionalFormals.length() - hasRest); } funbox->setArgCount(positionalFormals.length()); @@ -2712,16 +2664,30 @@ bool Parser::skipLazyInnerFunction( // so we can skip over them after accounting for their free variables. RootedFunction fun(cx_, handler_.nextLazyInnerFunction()); - FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, - Directives(/* strict = */ false), - fun->generatorKind(), fun->asyncKind()); + + // TODO-Stencil: Consider for snapshotting. + const ParserAtom* displayAtom = nullptr; + if (fun->displayAtom()) { + displayAtom = + this->compilationInfo_.lowerJSAtomToParserAtom(cx_, fun->displayAtom()); + if (!displayAtom) { + return false; + } + } + + FunctionBox* funbox = + newFunctionBox(funNode, displayAtom, fun->flags(), toStringStart, + Directives(/* strict = */ false), fun->generatorKind(), + fun->asyncKind(), TopLevelFunction::No); if (!funbox) { return false; } + ScriptStencil& script = funbox->functionStencil(); funbox->initFromLazyFunction(fun); + funbox->copyFunctionFields(script); + funbox->copyScriptFields(script); - // See: CompilationInfo::publishDeferredFunctions() MOZ_ASSERT_IF(pc_->isFunctionBox(), pc_->functionBox()->index() < funbox->index()); @@ -2730,11 +2696,11 @@ bool Parser::skipLazyInnerFunction( // compilation. MOZ_ASSERT(fun->baseScript()->hasEnclosingScript()); MOZ_ASSERT_IF(fun->isClassConstructor(), - !fun->baseScript()->getFieldInitializers().valid); + !fun->baseScript()->getMemberInitializers().valid); PropagateTransitiveParseFlags(funbox, pc_->sc()); - if (!tokenStream.advance(funbox->extent.sourceEnd)) { + if (!tokenStream.advance(funbox->extent().sourceEnd)) { return false; } @@ -2845,9 +2811,9 @@ template typename ParseHandler::FunctionNodeType GeneralParser::functionDefinition( FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling, - YieldHandling yieldHandling, HandleAtom funName, FunctionSyntaxKind kind, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind, - bool tryAnnexB /* = false */) { + YieldHandling yieldHandling, const ParserAtom* funName, + FunctionSyntaxKind kind, GeneratorKind generatorKind, + FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) { MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName); // If we see any inner function, note it on our current context. The bytecode @@ -2881,7 +2847,7 @@ GeneralParser::functionDefinition( Directives directives(pc_); Directives newDirectives = directives; - Position start(this->compilationInfo_.keepAtoms, tokenStream); + Position start(tokenStream); CompilationInfo::RewindToken startObj = this->compilationInfo_.getRewindToken(); @@ -2921,12 +2887,11 @@ GeneralParser::functionDefinition( template bool Parser::advancePastSyntaxParsedFunction( - AutoKeepAtoms& keepAtoms, SyntaxParser* syntaxParser) { + SyntaxParser* syntaxParser) { MOZ_ASSERT(getSyntaxParser() == syntaxParser); // Advance this parser over tokens processed by the syntax parser. - Position currentSyntaxPosition(this->compilationInfo_.keepAtoms, - syntaxParser->tokenStream); + Position currentSyntaxPosition(syntaxParser->tokenStream); if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) { return false; } @@ -2938,7 +2903,7 @@ bool Parser::advancePastSyntaxParsedFunction( template bool Parser::trySyntaxParseInnerFunction( - FunctionNode** funNode, HandleAtom explicitName, FunctionFlags flags, + FunctionNode** funNode, const ParserAtom* explicitName, FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, @@ -2973,7 +2938,7 @@ bool Parser::trySyntaxParseInnerFunction( // var x = (y = z => 2) => q; // // ^ we first seek to here to syntax-parse this function // // ^ then we seek back to here to syntax-parse the outer function - Position currentPosition(this->compilationInfo_.keepAtoms, tokenStream); + Position currentPosition(tokenStream); if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) { return false; } @@ -2981,9 +2946,9 @@ bool Parser::trySyntaxParseInnerFunction( // Make a FunctionBox before we enter the syntax parser, because |pn| // still expects a FunctionBox to be attached to it during BCE, and // the syntax parser cannot attach one to it. - FunctionBox* funbox = - newFunctionBox(*funNode, explicitName, flags, toStringStart, - inheritedDirectives, generatorKind, asyncKind); + FunctionBox* funbox = newFunctionBox( + *funNode, explicitName, flags, toStringStart, inheritedDirectives, + generatorKind, asyncKind, TopLevelFunction::No); if (!funbox) { return false; } @@ -3008,8 +2973,7 @@ bool Parser::trySyntaxParseInnerFunction( return false; } - if (!advancePastSyntaxParsedFunction(this->compilationInfo_.keepAtoms, - syntaxParser)) { + if (!advancePastSyntaxParsedFunction(syntaxParser)) { return false; } @@ -3041,11 +3005,11 @@ bool Parser::trySyntaxParseInnerFunction( template bool Parser::trySyntaxParseInnerFunction( - FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, - FunctionSyntaxKind kind, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, - Directives* newDirectives) { + FunctionNodeType* funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, + YieldHandling yieldHandling, FunctionSyntaxKind kind, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, + Directives inheritedDirectives, Directives* newDirectives) { // This is already a syntax parser, so just parse the inner function. FunctionNodeType innerFunc = innerFunction(*funNode, pc_, explicitName, flags, toStringStart, @@ -3062,11 +3026,11 @@ bool Parser::trySyntaxParseInnerFunction( template inline bool GeneralParser::trySyntaxParseInnerFunction( - FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, - FunctionSyntaxKind kind, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, - Directives* newDirectives) { + FunctionNodeType* funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, + YieldHandling yieldHandling, FunctionSyntaxKind kind, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, + Directives inheritedDirectives, Directives* newDirectives) { return asFinalParser()->trySyntaxParseInnerFunction( funNode, explicitName, flags, toStringStart, inHandling, yieldHandling, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives, @@ -3105,9 +3069,9 @@ GeneralParser::innerFunctionForFunctionBox( template typename ParseHandler::FunctionNodeType GeneralParser::innerFunction( - FunctionNodeType funNode, ParseContext* outerpc, HandleAtom explicitName, - FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, - YieldHandling yieldHandling, FunctionSyntaxKind kind, + FunctionNodeType funNode, ParseContext* outerpc, + const ParserAtom* explicitName, FunctionFlags flags, uint32_t toStringStart, + InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives) { // Note that it is possible for outerpc != this->pc_, as we may be @@ -3115,9 +3079,9 @@ GeneralParser::innerFunction( // parser. In that case, outerpc is a SourceParseContext from the full parser // instead of the current top of the stack of the syntax parser. - FunctionBox* funbox = - newFunctionBox(funNode, explicitName, flags, toStringStart, - inheritedDirectives, generatorKind, asyncKind); + FunctionBox* funbox = newFunctionBox( + funNode, explicitName, flags, toStringStart, inheritedDirectives, + generatorKind, asyncKind, TopLevelFunction::No); if (!funbox) { return null(); } @@ -3147,7 +3111,7 @@ bool GeneralParser::appendToCallSiteObj( return false; } - JSAtom* atom = tokenStream.getRawTemplateStringAtom(); + const ParserAtom* atom = tokenStream.getRawTemplateStringAtom(); if (!atom) { return false; } @@ -3192,19 +3156,28 @@ FunctionNode* Parser::standaloneLazyFunction( return null(); } + // TODO-Stencil: Consider for snapshotting. + const ParserAtom* displayAtom = nullptr; + if (fun->displayAtom()) { + displayAtom = + this->compilationInfo_.lowerJSAtomToParserAtom(cx_, fun->displayAtom()); + if (!displayAtom) { + return null(); + } + } + Directives directives(strict); - FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, directives, - generatorKind, asyncKind); + FunctionBox* funbox = newFunctionBox(funNode, displayAtom, fun->flags(), + toStringStart, directives, generatorKind, + asyncKind, TopLevelFunction::Yes); if (!funbox) { return null(); } funbox->initFromLazyFunction(fun); - funbox->initWithEnclosingScope(this->getCompilationInfo().scopeContext, - fun->enclosingScope(), fun->flags(), - syntaxKind); + funbox->initStandalone(this->compilationState_.scopeContext, fun->flags(), + syntaxKind); if (fun->isClassConstructor()) { - funbox->fieldInitializers = - mozilla::Some(fun->baseScript()->getFieldInitializers()); + funbox->setMemberInitializers(fun->baseScript()->getMemberInitializers()); } Directives newDirectives = directives; @@ -3242,7 +3215,7 @@ FunctionNode* Parser::standaloneLazyFunction( // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. if (!pc_->useAsmOrInsideUseAsm()) { - if (!FoldConstants(cx_, &node, &handler_)) { + if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) { return null(); } } @@ -3269,7 +3242,7 @@ bool GeneralParser::functionFormalParametersAndBody( if (kind == FunctionSyntaxKind::ClassConstructor || kind == FunctionSyntaxKind::DerivedClassConstructor) { - if (!noteUsedName(cx_->names().dotInitializers)) { + if (!noteUsedName(cx_->parserNames().dotInitializers)) { return false; } } @@ -3367,7 +3340,7 @@ bool GeneralParser::functionFormalParametersAndBody( "strict mode should only change when a 'use strict' directive " "is present"); - PropertyName* propertyName = funbox->explicitName()->asPropertyName(); + const ParserName* propertyName = funbox->explicitName()->asName(); YieldHandling nameYieldHandling; if (kind == FunctionSyntaxKind::Expression) { // Named lambda has binding inside it. @@ -3474,14 +3447,14 @@ GeneralParser::functionStmt(uint32_t toStringStart, } } - RootedPropertyName name(cx_); + const ParserName* name = nullptr; if (TokenKindIsPossibleIdentifier(tt)) { name = bindingIdentifier(yieldHandling); if (!name) { return null(); } } else if (defaultHandling == AllowDefaultName) { - name = cx_->names().default_; + name = cx_->parserNames().default_; anyChars.ungetToken(); } else { /* Unnamed function expressions are forbidden in statement context. */ @@ -3554,7 +3527,7 @@ GeneralParser::functionExpr(uint32_t toStringStart, YieldHandling yieldHandling = GetYieldHandling(generatorKind); - RootedPropertyName name(cx_); + const ParserName* name = nullptr; if (TokenKindIsPossibleIdentifier(tt)) { name = bindingIdentifier(yieldHandling); if (!name) { @@ -3585,13 +3558,14 @@ GeneralParser::functionExpr(uint32_t toStringStart, * isEscapeFreeStringLiteral, below, checks whether the node itself could be * a directive. */ -static inline bool IsEscapeFreeStringLiteral(const TokenPos& pos, JSAtom* str) { +static inline bool IsEscapeFreeStringLiteral(const TokenPos& pos, + const ParserAtom* atom) { /* * If the string's length in the source code is its length as a value, * accounting for the quotes, then it must not contain any escape * sequences or line continuations. */ - return pos.begin + str->length() + 2 == pos.end; + return pos.begin + atom->length() + 2 == pos.end; } template @@ -3641,7 +3615,7 @@ bool Parser::asmJS(ListNodeType list) { // function from the beginning. Reparsing is triggered by marking that a // new directive has been encountered and returning 'false'. bool validated; - if (!CompileAsmJS(cx_, *this, list, &validated)) { + if (!CompileAsmJS(cx_, this->compilationInfo_, *this, list, &validated)) { return false; } if (!validated) { @@ -3680,7 +3654,7 @@ template bool GeneralParser::maybeParseDirective( ListNodeType list, Node possibleDirective, bool* cont) { TokenPos directivePos; - JSAtom* directive = + const ParserAtom* directive = handler_.isStringExprStatement(possibleDirective, &directivePos); *cont = !!directive; @@ -3689,7 +3663,7 @@ bool GeneralParser::maybeParseDirective( } if (IsEscapeFreeStringLiteral(directivePos, directive)) { - if (directive == cx_->names().useStrict) { + if (directive == cx_->parserNames().useStrict) { // Functions with non-simple parameter lists (destructuring, // default or rest parameters) must not contain a "use strict" // directive. @@ -3710,16 +3684,16 @@ bool GeneralParser::maybeParseDirective( // had "use strict"; pc_->sc()->setExplicitUseStrict(); if (!pc_->sc()->strict()) { - // We keep track of the one possible strict violation that could - // occur in the directive prologue -- octal escapes -- and + // We keep track of the possible strict violations that could occur in + // the directive prologue -- deprecated octal syntax -- and // complain now. - if (anyChars.sawOctalEscape()) { + if (anyChars.sawDeprecatedOctal()) { error(JSMSG_DEPRECATED_OCTAL); return false; } pc_->sc()->setStrictScript(); } - } else if (directive == cx_->names().useAsm) { + } else if (directive == cx_->parserNames().useAsm) { if (pc_->isFunctionBox()) { return asmJS(list); } @@ -3743,7 +3717,7 @@ GeneralParser::statementList(YieldHandling yieldHandling) { bool canHaveDirectives = pc_->atBodyLevel(); if (canHaveDirectives) { - anyChars.clearSawOctalEscape(); + anyChars.clearSawDeprecatedOctal(); } bool canHaveHashbangComment = pc_->atTopLevel(); @@ -3830,7 +3804,8 @@ typename ParseHandler::Node GeneralParser::condition( template bool GeneralParser::matchLabel( - YieldHandling yieldHandling, MutableHandle label) { + YieldHandling yieldHandling, const ParserName** labelOut) { + MOZ_ASSERT(labelOut != nullptr); TokenKind tt = TokenKind::Eof; if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) { return false; @@ -3839,12 +3814,12 @@ bool GeneralParser::matchLabel( if (TokenKindIsPossibleIdentifier(tt)) { tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp); - label.set(labelIdentifier(yieldHandling)); - if (!label) { + *labelOut = labelIdentifier(yieldHandling); + if (!*labelOut) { return false; } } else { - label.set(nullptr); + *labelOut = nullptr; } return true; } @@ -4008,7 +3983,7 @@ template typename ParseHandler::NameNodeType GeneralParser::bindingIdentifier( DeclarationKind kind, YieldHandling yieldHandling) { - RootedPropertyName name(cx_, bindingIdentifier(yieldHandling)); + const ParserName* name = bindingIdentifier(yieldHandling); if (!name) { return null(); } @@ -4058,7 +4033,7 @@ GeneralParser::objectBindingPattern( } Maybe declKind = Some(kind); - RootedAtom propAtom(cx_); + const ParserAtom* propAtom = nullptr; for (;;) { TokenKind tt; if (!tokenStream.peekToken(&tt)) { @@ -4497,7 +4472,7 @@ typename ParseHandler::Node GeneralParser::declarationName( return null(); } - RootedPropertyName name(cx_, bindingIdentifier(yieldHandling)); + const ParserName* name = bindingIdentifier(yieldHandling); if (!name) { return null(); } @@ -4691,7 +4666,7 @@ bool Parser::namedImportsOrNamespaceImport( return false; } - Rooted importName(cx_, anyChars.currentName()); + const ParserName* importName = anyChars.currentName(); TokenPos importNamePos = pos(); bool matched; @@ -4720,7 +4695,7 @@ bool Parser::namedImportsOrNamespaceImport( } } - RootedPropertyName bindingAtom(cx_, importedBinding()); + const ParserName* bindingAtom = importedBinding(); if (!bindingAtom) { return false; } @@ -4772,7 +4747,7 @@ bool Parser::namedImportsOrNamespaceImport( return false; } - NameNodeType importName = newName(cx_->names().star); + NameNodeType importName = newName(cx_->parserNames().star); if (!importName) { return false; } @@ -4781,7 +4756,7 @@ bool Parser::namedImportsOrNamespaceImport( // definitions that hold a module namespace object. They are treated // as const variables which are initialized during the // ModuleInstantiate step. - RootedPropertyName bindingName(cx_, importedBinding()); + const ParserName* bindingName = importedBinding(); if (!bindingName) { return false; } @@ -4844,12 +4819,12 @@ BinaryNode* Parser::importDeclaration() { // specifier to the list, with 'default' as the import name and // 'a' as the binding name. This is equivalent to // |import { default as a } from 'b'|. - NameNodeType importName = newName(cx_->names().default_); + NameNodeType importName = newName(cx_->parserNames().default_); if (!importName) { return null(); } - RootedPropertyName bindingAtom(cx_, importedBinding()); + const ParserName* bindingAtom = importedBinding(); if (!bindingAtom) { return null(); } @@ -4954,12 +4929,13 @@ GeneralParser::importDeclarationOrImportExpr( } template -bool Parser::checkExportedName(JSAtom* exportName) { +bool Parser::checkExportedName( + const ParserAtom* exportName) { if (!pc_->sc()->asModuleContext()->builder.hasExportedName(exportName)) { return true; } - UniqueChars str = AtomToPrintableString(cx_, exportName); + UniqueChars str = ParserAtomToPrintableString(cx_, exportName); if (!str) { return false; } @@ -4970,14 +4946,14 @@ bool Parser::checkExportedName(JSAtom* exportName) { template inline bool Parser::checkExportedName( - JSAtom* exportName) { + const ParserAtom* exportName) { MOZ_ALWAYS_FALSE(abortIfSyntaxParser()); return false; } template inline bool GeneralParser::checkExportedName( - JSAtom* exportName) { + const ParserAtom* exportName) { return asFinalParser()->checkExportedName(exportName); } @@ -5267,20 +5243,53 @@ GeneralParser::exportBatch(uint32_t begin) { MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul)); - ListNodeType kid = handler_.newList(ParseNodeKind::ExportSpecList, pos()); - if (!kid) { - return null(); - } + ListNodeType kid = handler_.newList(ParseNodeKind::ExportSpecList, pos()); + if (!kid) { + return null(); + } + + bool foundAs; + if (!tokenStream.matchToken(&foundAs, TokenKind::As)) { + return null(); + } + + if (foundAs) { + if (!mustMatchToken(TokenKindIsPossibleIdentifierName, + JSMSG_NO_EXPORT_NAME)) { + return null(); + } + + NameNodeType exportName = newName(anyChars.currentName()); + if (!exportName) { + return null(); + } + + if (!checkExportedNameForClause(exportName)) { + return null(); + } + + NameNodeType importName = newName(cx_->parserNames().star); + if (!importName) { + return null(); + } + + BinaryNodeType exportSpec = handler_.newExportSpec(importName, exportName); + if (!exportSpec) { + return null(); + } + + handler_.addList(kid, exportSpec); + } else { + // Handle the form |export *| by adding a special export batch + // specifier to the list. + NullaryNodeType exportSpec = handler_.newExportBatchSpec(pos()); + if (!exportSpec) { + return null(); + } - // Handle the form |export *| by adding a special export batch - // specifier to the list. - NullaryNodeType exportSpec = handler_.newExportBatchSpec(pos()); - if (!exportSpec) { - return null(); + handler_.addList(kid, exportSpec); } - handler_.addList(kid, exportSpec); - if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) { return null(); } @@ -5295,8 +5304,7 @@ bool Parser::checkLocalExportNames(ListNode* node) { ParseNode* name = next->as().left(); MOZ_ASSERT(name->isKind(ParseNodeKind::Name)); - RootedPropertyName ident(cx_, - name->as().atom()->asPropertyName()); + const ParserName* ident = name->as().atom()->asName(); if (!checkLocalExportName(ident, name->pn_pos.begin)) { return false; } @@ -5640,7 +5648,7 @@ GeneralParser::exportDefaultAssignExpr(uint32_t begin) { return null(); } - HandlePropertyName name = cx_->names().default_; + const ParserName* name = cx_->parserNames().default_; NameNodeType nameNode = newName(name); if (!nameNode) { return null(); @@ -5685,7 +5693,7 @@ GeneralParser::exportDefault(uint32_t begin) { return null(); } - if (!checkExportedName(cx_->names().default_)) { + if (!checkExportedName(cx_->parserNames().default_)) { return null(); } @@ -6483,7 +6491,7 @@ GeneralParser::continueStatement( MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue)); uint32_t begin = pos().begin; - RootedPropertyName label(cx_); + const ParserName* label = nullptr; if (!matchLabel(yieldHandling, &label)) { return null(); } @@ -6514,7 +6522,7 @@ GeneralParser::breakStatement(YieldHandling yieldHandling) { MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break)); uint32_t begin = pos().begin; - RootedPropertyName label(cx_); + const ParserName* label = nullptr; if (!matchLabel(yieldHandling, &label)) { return null(); } @@ -6709,7 +6717,7 @@ template typename ParseHandler::LabeledStatementType GeneralParser::labeledStatement( YieldHandling yieldHandling) { - RootedPropertyName label(cx_, labelIdentifier(yieldHandling)); + const ParserName* label = labelIdentifier(yieldHandling); if (!label) { return null(); } @@ -7040,8 +7048,8 @@ static AccessorType ToAccessorType(PropertyType propType) { template bool GeneralParser::classMember( YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt, - HandlePropertyName className, uint32_t classStartOffset, - HasHeritage hasHeritage, ClassFields& classFields, + const ParserName* className, uint32_t classStartOffset, + HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers, ListNodeType& classMembers, bool* done) { *done = false; @@ -7079,7 +7087,7 @@ bool GeneralParser::classMember( return false; } - RootedAtom propAtom(cx_); + const ParserAtom* propAtom = nullptr; PropertyType propType; Node propName = propertyOrMethodName(yieldHandling, PropertyNameInClass, /* maybeDecl = */ Nothing(), @@ -7090,29 +7098,41 @@ bool GeneralParser::classMember( if (propType == PropertyType::Field) { if (isStatic) { - if (propAtom == cx_->names().prototype) { + if (propAtom == cx_->parserNames().prototype) { errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); return false; } } - if (propAtom == cx_->names().constructor) { + if (propAtom == cx_->parserNames().constructor) { errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); return false; } + if (handler_.isPrivateName(propName)) { + if (propAtom == cx_->parserNames().hashConstructor) { + errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); + return false; + } + + const ParserName* privateName = propAtom->asName(); + if (!noteDeclaredPrivateName(propName, privateName, propType, pos())) { + return false; + } + } + if (!abortIfSyntaxParser()) { return false; } if (isStatic) { - classFields.staticFields++; + classInitializedMembers.staticFields++; } else { - classFields.instanceFields++; + classInitializedMembers.instanceFields++; } - FunctionNodeType initializer = - fieldInitializerOpt(propName, propAtom, classFields, isStatic); + FunctionNodeType initializer = fieldInitializerOpt( + propName, propAtom, classInitializedMembers, isStatic, hasHeritage); if (!initializer) { return false; } @@ -7139,7 +7159,7 @@ bool GeneralParser::classMember( return false; } - bool isConstructor = !isStatic && propAtom == cx_->names().constructor; + bool isConstructor = !isStatic && propAtom == cx_->parserNames().constructor; if (isConstructor) { if (propType != PropertyType::Method) { errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); @@ -7152,22 +7172,25 @@ bool GeneralParser::classMember( propType = hasHeritage == HasHeritage::Yes ? PropertyType::DerivedConstructor : PropertyType::Constructor; - } else if (isStatic && propAtom == cx_->names().prototype) { + } else if (isStatic && propAtom == cx_->parserNames().prototype) { errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); return false; } - RootedAtom funName(cx_); + const ParserAtom* funName = nullptr; switch (propType) { case PropertyType::Getter: - case PropertyType::Setter: - if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) { + case PropertyType::Setter: { + bool hasStaticName = + !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom; + if (hasStaticName) { funName = prefixAccessorName(propType, propAtom); if (!funName) { return false; } } break; + } case PropertyType::Constructor: case PropertyType::DerivedConstructor: funName = className; @@ -7204,8 +7227,8 @@ bool GeneralParser::classMember( return false; } - if (!noteDeclaredName(cx_->names().dotInitializers, DeclarationKind::Let, - pos())) { + if (!noteDeclaredName(cx_->parserNames().dotInitializers, + DeclarationKind::Let, pos())) { return false; } } @@ -7221,8 +7244,75 @@ bool GeneralParser::classMember( AccessorType atype = ToAccessorType(propType); - Node method = - handler_.newClassMethodDefinition(propName, funNode, atype, isStatic); + Maybe initializerIfPrivate = Nothing(); + if (handler_.isPrivateName(propName)) { + if (!options().privateClassMethods) { + // Private methods are not enabled. + errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); + return false; + } + + if (propAtom == cx_->parserNames().hashConstructor) { + // #constructor is an invalid private name. + errorAt(propNameOffset, JSMSG_BAD_METHOD_DEF); + return false; + } + + if (!abortIfSyntaxParser()) { + return false; + } + + const ParserName* privateName = propAtom->asName(); + if (!noteDeclaredPrivateName(propName, privateName, propType, pos())) { + return false; + } + + // Private non-static methods are stamped onto every instance using + // initializers. Private static methods are stored directly on the + // constructor during class evaluation; see + // BytecodeEmitter::emitPropertyList. + if (!isStatic) { + classInitializedMembers.privateMethods++; + + // Synthesize a name for the lexical variable that will store the + // private method body. + StringBuffer storedMethodName(cx_); + if (!storedMethodName.append(propAtom)) { + return false; + } + switch (atype) { + case AccessorType::None: + if (!storedMethodName.append(".method")) { + return false; + } + break; + case AccessorType::Getter: + if (!storedMethodName.append(".getter")) { + return false; + } + break; + case AccessorType::Setter: + if (!storedMethodName.append(".setter")) { + return false; + } + break; + default: + MOZ_CRASH("Invalid private method accessor type"); + } + const ParserAtom* storedMethodAtom = + storedMethodName.finishParserAtom(this->compilationInfo_); + const ParserName* storedMethodProp = storedMethodAtom->asName(); + if (!noteDeclaredName(storedMethodProp, DeclarationKind::Const, pos())) { + return false; + } + + initializerIfPrivate = + Some(privateMethodInitializer(propAtom, storedMethodAtom)); + } + } + + Node method = handler_.newClassMethodDefinition( + propName, funNode, atype, isStatic, initializerIfPrivate); if (!method) { return false; } @@ -7240,14 +7330,18 @@ bool GeneralParser::classMember( template bool GeneralParser::finishClassConstructor( - const ParseContext::ClassStatement& classStmt, HandlePropertyName className, + const ParseContext::ClassStatement& classStmt, const ParserName* className, HasHeritage hasHeritage, uint32_t classStartOffset, uint32_t classEndOffset, - const ClassFields& classFields, ListNodeType& classMembers) { + const ClassInitializedMembers& classInitializedMembers, + ListNodeType& classMembers) { // Fields cannot re-use the constructor obtained via JSOp::ClassConstructor or // JSOp::DerivedConstructor due to needing to emit calls to the field // initializers in the constructor. So, synthesize a new one. - size_t numFields = classFields.instanceFields; - if (classStmt.constructorBox == nullptr && numFields > 0) { + size_t numPrivateMethods = classInitializedMembers.privateMethods; + size_t numFields = classInitializedMembers.instanceFields; + + if (classStmt.constructorBox == nullptr && + numFields + numPrivateMethods > 0) { MOZ_ASSERT(!options().selfHostingMode); // Unconditionally create the scope here, because it's always the // constructor. @@ -7256,8 +7350,8 @@ bool GeneralParser::finishClassConstructor( return false; } - if (!noteDeclaredName(cx_->names().dotInitializers, DeclarationKind::Let, - pos())) { + if (!noteDeclaredName(cx_->parserNames().dotInitializers, + DeclarationKind::Let, pos())) { return false; } @@ -7272,14 +7366,14 @@ bool GeneralParser::finishClassConstructor( // Note: the *function* has the name of the class, but the *property* // containing the function has the name "constructor" - Node constructorNameNode = - handler_.newObjectLiteralPropertyName(cx_->names().constructor, pos()); + Node constructorNameNode = handler_.newObjectLiteralPropertyName( + cx_->parserNames().constructor, pos()); if (!constructorNameNode) { return false; } ClassMethodType method = handler_.newClassMethodDefinition( constructorNameNode, synthesizedCtor, AccessorType::None, - /* isStatic = */ false); + /* isStatic = */ false, Nothing()); if (!method) { return false; } @@ -7294,17 +7388,13 @@ bool GeneralParser::finishClassConstructor( } if (FunctionBox* ctorbox = classStmt.constructorBox) { - // The ctorbox must not have emitted a JSFunction yet since we are still - // updating it. - MOZ_ASSERT(!ctorbox->hasFunction()); - // Amend the toStringEnd offset for the constructor now that we've // finished parsing the class. - ctorbox->extent.toStringEnd = classEndOffset; + ctorbox->setCtorToStringEnd(classEndOffset); - if (numFields > 0) { + if (numFields + numPrivateMethods > 0) { // Field initialization need access to `this`. - ctorbox->setFunctionHasThisBinding(); + ctorbox->setCtorFunctionHasThisBinding(); } } @@ -7326,7 +7416,7 @@ GeneralParser::classDefinition( return null(); } - RootedPropertyName className(cx_); + const ParserName* className = nullptr; if (TokenKindIsPossibleIdentifier(tt)) { className = bindingIdentifier(yieldHandling); if (!className) { @@ -7334,7 +7424,7 @@ GeneralParser::classDefinition( } } else if (classContext == ClassStatement) { if (defaultHandling == AllowDefaultName) { - className = cx_->names().default_; + className = cx_->parserNames().default_; anyChars.ungetToken(); } else { // Class statements must have a bound name @@ -7351,6 +7441,8 @@ GeneralParser::classDefinition( // position in order to provide it for the nodes created later. TokenPos namePos = pos(); + bool isInClass = pc_->sc()->inClass(); + // Push a ParseContext::ClassStatement to keep track of the constructor // funbox. ParseContext::ClassStatement classStmt(pc_); @@ -7359,6 +7451,7 @@ GeneralParser::classDefinition( Node nameNode = null(); Node classHeritage = null(); LexicalScopeNodeType classBlock = null(); + LexicalScopeNodeType classBodyBlock = null(); uint32_t classEndOffset; { // A named class creates a new lexical scope with a const binding of the @@ -7389,49 +7482,65 @@ GeneralParser::classDefinition( return null(); } - ListNodeType classMembers = handler_.newClassMemberList(pos().begin); - if (!classMembers) { - return null(); - } + { + ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block); + ParseContext::Scope bodyScope(this); + if (!bodyScope.init(pc_)) { + return null(); + } - ClassFields classFields{}; - for (;;) { - bool done; - if (!classMember(yieldHandling, classStmt, className, classStartOffset, - hasHeritage, classFields, classMembers, &done)) { + ListNodeType classMembers = handler_.newClassMemberList(pos().begin); + if (!classMembers) { return null(); } - if (done) { - break; + + ClassInitializedMembers classInitializedMembers{}; + for (;;) { + bool done; + if (!classMember(yieldHandling, classStmt, className, classStartOffset, + hasHeritage, classInitializedMembers, classMembers, + &done)) { + return null(); + } + if (done) { + break; + } } - } - if (classFields.instanceFieldKeys > 0) { - if (!noteDeclaredName(cx_->names().dotFieldKeys, DeclarationKind::Let, - namePos)) { - return null(); + if (classInitializedMembers.instanceFieldKeys > 0) { + if (!noteDeclaredName(cx_->parserNames().dotFieldKeys, + DeclarationKind::Let, namePos)) { + return null(); + } + } + + if (classInitializedMembers.staticFields > 0) { + if (!noteDeclaredName(cx_->parserNames().dotStaticInitializers, + DeclarationKind::Let, namePos)) { + return null(); + } + } + + if (classInitializedMembers.staticFieldKeys > 0) { + if (!noteDeclaredName(cx_->parserNames().dotStaticFieldKeys, + DeclarationKind::Let, namePos)) { + return null(); + } } - } - if (classFields.staticFields > 0) { - if (!noteDeclaredName(cx_->names().dotStaticInitializers, - DeclarationKind::Let, namePos)) { + classEndOffset = pos().end; + if (!finishClassConstructor(classStmt, className, hasHeritage, + classStartOffset, classEndOffset, + classInitializedMembers, classMembers)) { return null(); } - } - if (classFields.staticFieldKeys > 0) { - if (!noteDeclaredName(cx_->names().dotStaticFieldKeys, - DeclarationKind::Let, namePos)) { + classBodyBlock = finishLexicalScope(bodyScope, classMembers); + if (!classBodyBlock) { return null(); } - } - classEndOffset = pos().end; - if (!finishClassConstructor(classStmt, className, hasHeritage, - classStartOffset, classEndOffset, classFields, - classMembers)) { - return null(); + // Pop the class body scope } if (className) { @@ -7446,7 +7555,7 @@ GeneralParser::classDefinition( } } - classBlock = finishLexicalScope(innerScope, classMembers); + classBlock = finishLexicalScope(innerScope, classBodyBlock); if (!classBlock) { return null(); } @@ -7473,8 +7582,26 @@ GeneralParser::classDefinition( return null(); } } - MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness)); + // We're leaving a class definition that was not itself nested within a class + if (!isInClass) { + mozilla::Maybe maybeUnboundName; + if (!this->compilationState_.usedNames.hasUnboundPrivateNames( + cx_, maybeUnboundName)) { + return null(); + } + if (maybeUnboundName) { + UniqueChars str = + ParserAtomToPrintableString(cx_, maybeUnboundName->atom); + if (!str) { + return null(); + } + + errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL, + str.get()); + return null(); + } + } return handler_.newClass(nameNode, classHeritage, classBlock, TokenPos(classStartOffset, classEndOffset)); @@ -7483,7 +7610,8 @@ GeneralParser::classDefinition( template typename ParseHandler::FunctionNodeType GeneralParser::synthesizeConstructor( - HandleAtom className, uint32_t classNameOffset, HasHeritage hasHeritage) { + const ParserAtom* className, uint32_t classNameOffset, + HasHeritage hasHeritage) { FunctionSyntaxKind functionSyntaxKind = hasHeritage == HasHeritage::Yes ? FunctionSyntaxKind::DerivedClassConstructor @@ -7502,9 +7630,10 @@ GeneralParser::synthesizeConstructor( // Create the FunctionBox and link it to the function object. Directives directives(true); - FunctionBox* funbox = newFunctionBox( - funNode, className, flags, classNameOffset, directives, - GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction); + FunctionBox* funbox = + newFunctionBox(funNode, className, flags, classNameOffset, directives, + GeneratorKind::NotGenerator, + FunctionAsyncKind::SyncFunction, TopLevelFunction::No); if (!funbox) { return null(); } @@ -7530,7 +7659,7 @@ GeneralParser::synthesizeConstructor( if (hasHeritage == HasHeritage::Yes) { // Synthesize the equivalent to `function f(...args)` funbox->setHasRest(); - if (!notePositionalFormalParameter(funNode, cx_->names().args, + if (!notePositionalFormalParameter(funNode, cx_->parserNames().args, synthesizedBodyPos.begin, /* disallowDuplicateParams = */ false, /* duplicatedParam = */ nullptr)) { @@ -7548,11 +7677,11 @@ GeneralParser::synthesizeConstructor( return null(); } - if (!noteUsedName(cx_->names().dotThis)) { + if (!noteUsedName(cx_->parserNames().dotThis)) { return null(); } - if (!noteUsedName(cx_->names().dotInitializers)) { + if (!noteUsedName(cx_->parserNames().dotInitializers)) { return null(); } @@ -7578,11 +7707,12 @@ GeneralParser::synthesizeConstructor( return null(); } - NameNodeType argsNameNode = newName(cx_->names().args, synthesizedBodyPos); + NameNodeType argsNameNode = + newName(cx_->parserNames().args, synthesizedBodyPos); if (!argsNameNode) { return null(); } - if (!noteUsedName(cx_->names().args)) { + if (!noteUsedName(cx_->parserNames().args)) { return null(); } @@ -7636,10 +7766,108 @@ GeneralParser::synthesizeConstructor( template typename ParseHandler::FunctionNodeType -GeneralParser::fieldInitializerOpt(Node propName, - HandleAtom propAtom, - ClassFields& classFields, - bool isStatic) { +GeneralParser::privateMethodInitializer( + const ParserAtom* propAtom, const ParserAtom* storedMethodAtom) { + // Synthesize an initializer function that the constructor can use to stamp a + // private method onto an instance object. + FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer; + FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction; + GeneratorKind generatorKind = GeneratorKind::NotGenerator; + bool isSelfHosting = options().selfHostingMode; + FunctionFlags flags = + InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting); + TokenPos firstTokenPos = pos(); + + FunctionNodeType funNode = handler_.newFunction(syntaxKind, firstTokenPos); + if (!funNode) { + return null(); + } + + Directives directives(true); + FunctionBox* funbox = + newFunctionBox(funNode, nullptr, flags, 0, directives, generatorKind, + asyncKind, TopLevelFunction::No); + if (!funbox) { + return null(); + } + funbox->initWithEnclosingParseContext(pc_, flags, syntaxKind); + + // Push a SourceParseContext on to the stack. + ParseContext* outerpc = pc_; + SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr); + if (!funpc.init()) { + return null(); + } + pc_->functionScope().useAsVarScope(pc_); + + // Add empty parameter list. + ListNodeType argsbody = + handler_.newList(ParseNodeKind::ParamsBody, firstTokenPos); + if (!argsbody) { + return null(); + } + handler_.setFunctionFormalParametersAndBody(funNode, argsbody); + setFunctionStartAtCurrentToken(funbox); + funbox->setArgCount(0); + funbox->usesThis = true; + + // Note both the stored private method body and it's private name as being + // used in the initializer. They will be emitted into the method body in the + // BCE. + const ParserName* storedMethodName = storedMethodAtom->asName(); + if (!noteUsedName(storedMethodName)) { + return null(); + } + const ParserName* privateName = propAtom->asName(); + NameNodeType privateNameNode = privateNameReference(privateName); + if (!privateNameNode) { + return null(); + } + + bool canSkipLazyClosedOverBindings = handler_.canSkipLazyClosedOverBindings(); + if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) { + return null(); + } + + // Unlike field initializers, private method initializers are not created with + // a body of synthesized AST nodes. Instead, the body is left empty and the + // initializer is synthesized at the bytecode level. + // See BytecodeEmitter::emitPrivateMethodInitializer. + ListNodeType stmtList = handler_.newStatementList(firstTokenPos); + if (!stmtList) { + return null(); + } + LexicalScopeNodeType initializerBody = + finishLexicalScope(pc_->varScope(), stmtList, ScopeKind::FunctionLexical); + if (!initializerBody) { + return null(); + } + handler_.setBeginPosition(initializerBody, stmtList); + handler_.setEndPosition(initializerBody, stmtList); + handler_.setFunctionBody(funNode, initializerBody); + + // Since the initializer doesn't correspond directly to any of the original + // source, set it's text position as being empty. + funbox->setStart(0, 0, 0); + funbox->setEnd(0); + + if (!finishFunction()) { + return null(); + } + + if (!leaveInnerFunction(outerpc)) { + return null(); + } + + return funNode; +} + +template +typename ParseHandler::FunctionNodeType +GeneralParser::fieldInitializerOpt( + Node propName, const ParserAtom* propAtom, + ClassInitializedMembers& classInitializedMembers, bool isStatic, + HasHeritage hasHeritage) { bool hasInitializer = false; if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign, TokenStream::SlashIsDiv)) { @@ -7675,7 +7903,7 @@ GeneralParser::fieldInitializerOpt(Node propName, Directives directives(true); FunctionBox* funbox = newFunctionBox(funNode, nullptr, flags, firstTokenPos.begin, directives, - generatorKind, asyncKind); + generatorKind, asyncKind, TopLevelFunction::No); if (!funbox) { return null(); } @@ -7757,9 +7985,9 @@ GeneralParser::fieldInitializerOpt(Node propName, // .fieldKeys means and its purpose. NameNodeType fieldKeysName; if (isStatic) { - fieldKeysName = newInternalDotName(cx_->names().dotStaticFieldKeys); + fieldKeysName = newInternalDotName(cx_->parserNames().dotStaticFieldKeys); } else { - fieldKeysName = newInternalDotName(cx_->names().dotFieldKeys); + fieldKeysName = newInternalDotName(cx_->parserNames().dotFieldKeys); } if (!fieldKeysName) { return null(); @@ -7767,9 +7995,9 @@ GeneralParser::fieldInitializerOpt(Node propName, double fieldKeyIndex; if (isStatic) { - fieldKeyIndex = classFields.staticFieldKeys++; + fieldKeyIndex = classInitializedMembers.staticFieldKeys++; } else { - fieldKeyIndex = classFields.instanceFieldKeys++; + fieldKeyIndex = classInitializedMembers.instanceFieldKeys++; } Node fieldKeyIndexNode = handler_.newNumber( fieldKeyIndex, DecimalPoint::NoDecimal, wholeInitializerPos); @@ -7788,6 +8016,27 @@ GeneralParser::fieldInitializerOpt(Node propName, if (!propAssignFieldAccess) { return null(); } + } else if (handler_.isPrivateName(propName)) { + // It would be nice if we could tweak this here such that only if + // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we + // emit InitElem -- this is an optimization to minimize HasOwn checks + // in InitElem for classes without heritage. + // + // Further tweaking would be to ultimately only do CheckPrivateField for the + // -first- field in a derived class, which would suffice to match the + // semantic check. + + const ParserName* privateName = propAtom->asName(); + NameNodeType privateNameNode = privateNameReference(privateName); + if (!privateNameNode) { + return null(); + } + + propAssignFieldAccess = handler_.newPropertyByValue( + propAssignThis, privateNameNode, wholeInitializerPos.end); + if (!propAssignFieldAccess) { + return null(); + } } else if (propAtom->isIndex(&indexValue)) { propAssignFieldAccess = handler_.newPropertyByValue( propAssignThis, propName, wholeInitializerPos.end); @@ -7795,8 +8044,8 @@ GeneralParser::fieldInitializerOpt(Node propName, return null(); } } else { - NameNodeType propAssignName = handler_.newPropertyName( - propAtom->asPropertyName(), wholeInitializerPos); + NameNodeType propAssignName = + handler_.newPropertyName(propAtom->asName(), wholeInitializerPos); if (!propAssignName) { return null(); } @@ -8163,7 +8412,7 @@ GeneralParser::statementListItem( // function in a default, not split up this way. case TokenKind::String: if (!canHaveDirectives && - anyChars.currentToken().atom() == cx_->names().useAsm) { + anyChars.currentToken().atom() == cx_->parserNames().useAsm) { if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) { return null(); } @@ -8676,7 +8925,7 @@ typename ParseHandler::Node GeneralParser::assignExpr( return null(); } if (endsExpr) { - Rooted name(cx_, identifierReference(yieldHandling)); + const ParserName* name = identifierReference(yieldHandling); if (!name) { return null(); } @@ -8723,7 +8972,7 @@ typename ParseHandler::Node GeneralParser::assignExpr( // Save the tokenizer state in case we find an arrow function and have to // rewind. - Position start(this->compilationInfo_.keepAtoms, tokenStream); + Position start(tokenStream); PossibleError possibleErrorInner(*this); Node lhs; @@ -8739,7 +8988,7 @@ typename ParseHandler::Node GeneralParser::assignExpr( MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync)); // Check yield validity here. - RootedPropertyName name(cx_, bindingIdentifier(yieldHandling)); + const ParserName* name = bindingIdentifier(yieldHandling); if (!name) { return null(); } @@ -9040,6 +9289,11 @@ typename ParseHandler::Node GeneralParser::optionalExpr( if (!nextMember) { return null(); } + } else if (tt == TokenKind::PrivateName) { + nextMember = memberPrivateAccess(lhs, OptionalKind::Optional); + if (!nextMember) { + return null(); + } } else if (tt == TokenKind::LeftBracket) { nextMember = memberElemAccess(lhs, yieldHandling, OptionalKind::Optional); @@ -9065,6 +9319,11 @@ typename ParseHandler::Node GeneralParser::optionalExpr( if (!nextMember) { return null(); } + } else if (tt == TokenKind::PrivateName) { + nextMember = memberPrivateAccess(lhs); + if (!nextMember) { + return null(); + } } else { error(JSMSG_NAME_AFTER_DOT); return null(); @@ -9170,8 +9429,10 @@ typename ParseHandler::Node GeneralParser::unaryExpr( return null(); } - // Per spec, deleting any unary expression is valid -- it simply - // returns true -- except for one case that is illegal in strict mode. + // Per spec, deleting most unary expressions is valid -- it simply + // returns true -- except for two cases: + // 1. `var x; ...; delete x` is a syntax error in strict mode. + // 2. Private fields cannot be deleted. if (handler_.isName(expr)) { if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) { return null(); @@ -9180,6 +9441,11 @@ typename ParseHandler::Node GeneralParser::unaryExpr( pc_->sc()->setBindingsAccessedDynamically(); } + if (handler_.isPrivateField(expr)) { + errorAt(exprOffset, JSMSG_PRIVATE_DELETE); + return null(); + } + return handler_.newDelete(begin, expr); } @@ -9452,6 +9718,11 @@ typename ParseHandler::Node GeneralParser::memberExpr( if (!nextMember) { return null(); } + } else if (tt == TokenKind::PrivateName) { + nextMember = memberPrivateAccess(lhs); + if (!nextMember) { + return null(); + } } else { error(JSMSG_NAME_AFTER_DOT); return null(); @@ -9480,7 +9751,7 @@ typename ParseHandler::Node GeneralParser::memberExpr( return null(); } - if (!noteUsedName(cx_->names().dotInitializers)) { + if (!noteUsedName(cx_->parserNames().dotInitializers)) { return null(); } } else { @@ -9510,22 +9781,36 @@ typename ParseHandler::Node GeneralParser::memberExpr( template inline typename ParseHandler::NameNodeType -PerHandlerParser::newName(PropertyName* name) { +PerHandlerParser::newName(const ParserName* name) { return newName(name, pos()); } template inline typename ParseHandler::NameNodeType -PerHandlerParser::newName(PropertyName* name, TokenPos pos) { +PerHandlerParser::newName(const ParserName* name, TokenPos pos) { return handler_.newName(name, pos, cx_); } +template +inline typename ParseHandler::NameNodeType +PerHandlerParser::newPrivateName(const ParserName* name) { + return newPrivateName(name, pos()); +} + +template +inline typename ParseHandler::NameNodeType +PerHandlerParser::newPrivateName(const ParserName* name, + TokenPos pos) { + return handler_.newPrivateName(name, pos); +} + template typename ParseHandler::Node GeneralParser::memberPropertyAccess( Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) { - MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type)); - PropertyName* field = anyChars.currentName(); + MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || + anyChars.currentToken().type == TokenKind::PrivateName); + const ParserName* field = anyChars.currentName(); if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) { error(JSMSG_BAD_SUPERPROP, "property"); return null(); @@ -9543,6 +9828,31 @@ GeneralParser::memberPropertyAccess( return handler_.newPropertyAccess(lhs, name); } +template +typename ParseHandler::Node +GeneralParser::memberPrivateAccess( + Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) { + MOZ_ASSERT(anyChars.currentToken().type == TokenKind::PrivateName); + + const ParserName* field = anyChars.currentName(); + // Cannot access private fields on super. + if (handler_.isSuperBase(lhs)) { + error(JSMSG_BAD_SUPERPRIVATE); + return null(); + } + + NameNodeType privateName = privateNameReference(field); + if (!privateName) { + return null(); + } + + if (optionalKind == OptionalKind::Optional) { + MOZ_ASSERT(!handler_.isSuperBase(lhs)); + return handler_.newOptionalPropertyByValue(lhs, privateName, pos().end); + } + return handler_.newPropertyByValue(lhs, privateName, pos().end); +} + template typename ParseHandler::Node GeneralParser::memberElemAccess( Node lhs, YieldHandling yieldHandling, @@ -9611,18 +9921,19 @@ typename ParseHandler::Node GeneralParser::memberCall( JSOp op = JSOp::Call; bool maybeAsyncArrow = false; - if (PropertyName* prop = handler_.maybeDottedProperty(lhs)) { + if (const ParserName* prop = handler_.maybeDottedProperty(lhs)) { // Use the JSOp::Fun{Apply,Call} optimizations given the right // syntax. - if (prop == cx_->names().apply) { + if (prop == cx_->parserNames().apply) { op = JSOp::FunApply; if (pc_->isFunctionBox()) { pc_->functionBox()->usesApply = true; } - } else if (prop == cx_->names().call) { + } else if (prop == cx_->parserNames().call) { op = JSOp::FunCall; } - } else if (tt == TokenKind::LeftParen) { + } else if (tt == TokenKind::LeftParen && + optionalKind == OptionalKind::NonOptional) { if (handler_.isAsyncKeyword(lhs, cx_)) { // |async (| can be the start of an async arrow // function, so we need to defer reporting possible @@ -9695,7 +10006,7 @@ typename ParseHandler::Node GeneralParser::memberCall( template bool GeneralParser::checkLabelOrIdentifierReference( - PropertyName* ident, uint32_t offset, YieldHandling yieldHandling, + const ParserName* ident, uint32_t offset, YieldHandling yieldHandling, TokenKind hint /* = TokenKind::Limit */) { TokenKind tt; if (hint == TokenKind::Limit) { @@ -9706,7 +10017,7 @@ bool GeneralParser::checkLabelOrIdentifierReference( tt = hint; } - if (!pc_->sc()->allowArguments() && ident == cx_->names().arguments) { + if (!pc_->sc()->allowArguments() && ident == cx_->parserNames().arguments) { error(JSMSG_BAD_ARGUMENTS); return false; } @@ -9773,17 +10084,17 @@ bool GeneralParser::checkLabelOrIdentifierReference( template bool GeneralParser::checkBindingIdentifier( - PropertyName* ident, uint32_t offset, YieldHandling yieldHandling, + const ParserName* ident, uint32_t offset, YieldHandling yieldHandling, TokenKind hint /* = TokenKind::Limit */) { if (pc_->sc()->strict()) { - if (ident == cx_->names().arguments) { + if (ident == cx_->parserNames().arguments) { if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) { return false; } return true; } - if (ident == cx_->names().eval) { + if (ident == cx_->parserNames().eval) { if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) { return false; } @@ -9795,21 +10106,21 @@ bool GeneralParser::checkBindingIdentifier( } template -PropertyName* GeneralParser::labelOrIdentifierReference( +const ParserName* GeneralParser::labelOrIdentifierReference( YieldHandling yieldHandling) { // ES 2017 draft 12.1.1. // StringValue of IdentifierName normalizes any Unicode escape sequences // in IdentifierName hence such escapes cannot be used to write an // Identifier whose code point sequence is the same as a ReservedWord. // - // Use PropertyName* instead of TokenKind to reflect the normalization. + // Use const ParserName* instead of TokenKind to reflect the normalization. // Unless the name contains escapes, we can reuse the current TokenKind // to determine if the name is a restricted identifier. TokenKind hint = !anyChars.currentNameHasEscapes() ? anyChars.currentToken().type : TokenKind::Limit; - RootedPropertyName ident(cx_, anyChars.currentName()); + const ParserName* ident = anyChars.currentName(); if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling, hint)) { return nullptr; @@ -9818,12 +10129,12 @@ PropertyName* GeneralParser::labelOrIdentifierReference( } template -PropertyName* GeneralParser::bindingIdentifier( +const ParserName* GeneralParser::bindingIdentifier( YieldHandling yieldHandling) { TokenKind hint = !anyChars.currentNameHasEscapes() ? anyChars.currentToken().type : TokenKind::Limit; - RootedPropertyName ident(cx_, anyChars.currentName()); + const ParserName* ident = anyChars.currentName(); if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) { return nullptr; } @@ -9832,8 +10143,7 @@ PropertyName* GeneralParser::bindingIdentifier( template typename ParseHandler::NameNodeType -PerHandlerParser::identifierReference( - Handle name) { +PerHandlerParser::identifierReference(const ParserName* name) { NameNodeType id = newName(name); if (!id) { return null(); @@ -9846,6 +10156,21 @@ PerHandlerParser::identifierReference( return id; } +template +typename ParseHandler::NameNodeType +PerHandlerParser::privateNameReference(const ParserName* name) { + NameNodeType id = newPrivateName(name); + if (!id) { + return null(); + } + + if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) { + return null(); + } + + return id; +} + template typename ParseHandler::NameNodeType PerHandlerParser::stringLiteral() { @@ -9884,22 +10209,29 @@ RegExpLiteral* Parser::newRegExp() { mozilla::Range range(chars.begin(), chars.length()); RegExpFlags flags = anyChars.currentToken().regExpFlags(); + uint32_t offset = anyChars.currentToken().pos.begin; + uint32_t line, column; + tokenStream.computeLineAndColumn(offset, &line, &column); + if (!handler_.canSkipRegexpSyntaxParse()) { // Verify that the Regexp will syntax parse when the time comes to // instantiate it. If we have already done a syntax parse, we can // skip this. LifoAllocScope allocScope(&cx_->tempLifoAlloc()); - if (!irregexp::CheckPatternSyntax(cx_, anyChars, range, flags)) { + if (!irregexp::CheckPatternSyntax(cx_, anyChars, range, flags, Some(line), + Some(column))) { return nullptr; } } - RegExpIndex index(this->getCompilationInfo().regExpData.length()); - if (!this->getCompilationInfo().regExpData.emplaceBack()) { + RegExpIndex index(this->getCompilationInfo().stencil.regExpData.length()); + if (!this->getCompilationInfo().stencil.regExpData.emplaceBack()) { + js::ReportOutOfMemory(cx_); return nullptr; } - if (!this->getCompilationInfo().regExpData[index].init(cx_, range, flags)) { + if (!this->getCompilationInfo().stencil.regExpData[index].init(cx_, range, + flags)) { return nullptr; } @@ -9915,10 +10247,15 @@ Parser::newRegExp() { const auto& chars = tokenStream.getCharBuffer(); RegExpFlags flags = anyChars.currentToken().regExpFlags(); + uint32_t offset = anyChars.currentToken().pos.begin; + uint32_t line, column; + tokenStream.computeLineAndColumn(offset, &line, &column); + mozilla::Range source(chars.begin(), chars.length()); { LifoAllocScope scopeAlloc(&alloc_); - if (!irregexp::CheckPatternSyntax(cx_, anyChars, source, flags)) { + if (!irregexp::CheckPatternSyntax(cx_, anyChars, source, flags, Some(line), + Some(column))) { return null(); } } @@ -9940,18 +10277,20 @@ BigIntLiteral* Parser::newBigInt() { // productions start with 0[bBoOxX], indicating binary/octal/hex. const auto& chars = tokenStream.getCharBuffer(); - BigIntIndex index(this->getCompilationInfo().bigIntData.length()); - if (!this->getCompilationInfo().bigIntData.emplaceBack()) { + BigIntIndex index(this->getCompilationInfo().stencil.bigIntData.length()); + if (!this->getCompilationInfo().stencil.bigIntData.emplaceBack()) { + js::ReportOutOfMemory(cx_); return null(); } - if (!this->getCompilationInfo().bigIntData[index].init(this->cx_, chars)) { + if (!this->getCompilationInfo().stencil.bigIntData[index].init(this->cx_, + chars)) { return null(); } // Should the operations below fail, the buffer held by data will // be cleaned up by the CompilationInfo destructor. - return handler_.newBigInt(index, this->getCompilationInfo(), pos()); + return handler_.newBigInt(index, this->getCompilationInfo().stencil, pos()); } template @@ -9968,19 +10307,6 @@ GeneralParser::newBigInt() { return asFinalParser()->newBigInt(); } -template -JSAtom* GeneralParser::bigIntAtom() { - // See newBigInt() for a description about |chars'| contents. - const auto& chars = tokenStream.getCharBuffer(); - mozilla::Range source(chars.begin(), chars.length()); - - RootedBigInt bi(cx_, js::ParseBigIntLiteral(cx_, source)); - if (!bi) { - return nullptr; - } - return BigIntToAtom(cx_, bi); -} - // |exprPossibleError| is the PossibleError state within |expr|, // |possibleError| is the surrounding PossibleError state. template @@ -10229,7 +10555,7 @@ template typename ParseHandler::Node GeneralParser::propertyName( YieldHandling yieldHandling, PropertyNameContext propertyNameContext, const Maybe& maybeDecl, ListNodeType propList, - MutableHandleAtom propAtom) { + const ParserAtom** propAtomOut) { // PropertyName[Yield, Await]: // LiteralPropertyName // ComputedPropertyName[?Yield, ?Await] @@ -10240,26 +10566,29 @@ typename ParseHandler::Node GeneralParser::propertyName( // NumericLiteral TokenKind ltok = anyChars.currentToken().type; - propAtom.set(nullptr); + *propAtomOut = nullptr; switch (ltok) { - case TokenKind::Number: - propAtom.set(NumberToAtom(cx_, anyChars.currentToken().number())); - if (!propAtom.get()) { + case TokenKind::Number: { + const ParserAtom* numAtom = NumberToParserAtom( + cx_, this->compilationInfo_, anyChars.currentToken().number()); + if (!numAtom) { return null(); } + *propAtomOut = numAtom; return newNumber(anyChars.currentToken()); + } - case TokenKind::BigInt: - propAtom.set(bigIntAtom()); - if (!propAtom.get()) { + case TokenKind::BigInt: { + Node biNode = newBigInt(); + if (!biNode) { return null(); } - return newBigInt(); - + return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end); + } case TokenKind::String: { - propAtom.set(anyChars.currentToken().atom()); + *propAtomOut = anyChars.currentToken().atom(); uint32_t index; - if (propAtom->isIndex(&index)) { + if ((*propAtomOut)->isIndex(&index)) { return handler_.newNumber(index, NoDecimal, pos()); } return stringLiteral(); @@ -10269,14 +10598,25 @@ typename ParseHandler::Node GeneralParser::propertyName( return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext, propList); + case TokenKind::PrivateName: { + if (propertyNameContext != PropertyNameContext::PropertyNameInClass) { + error(JSMSG_ILLEGAL_PRIVATE_FIELD); + return null(); + } + + const ParserName* propName = anyChars.currentName()->asName(); + *propAtomOut = propName; + return privateNameReference(propName); + } + default: { if (!TokenKindIsPossibleIdentifierName(ltok)) { error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok)); return null(); } - propAtom.set(anyChars.currentName()); - return handler_.newObjectLiteralPropertyName(propAtom, pos()); + *propAtomOut = anyChars.currentName(); + return handler_.newObjectLiteralPropertyName(*propAtomOut, pos()); } } } @@ -10285,7 +10625,8 @@ typename ParseHandler::Node GeneralParser::propertyName( static bool TokenKindCanStartPropertyName(TokenKind tt) { return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String || tt == TokenKind::Number || tt == TokenKind::LeftBracket || - tt == TokenKind::Mul || tt == TokenKind::BigInt; + tt == TokenKind::Mul || tt == TokenKind::BigInt || + tt == TokenKind::PrivateName; } template @@ -10293,7 +10634,7 @@ typename ParseHandler::Node GeneralParser::propertyOrMethodName( YieldHandling yieldHandling, PropertyNameContext propertyNameContext, const Maybe& maybeDecl, ListNodeType propList, - PropertyType* propType, MutableHandleAtom propAtom) { + PropertyType* propType, const ParserAtom** propAtomOut) { // We're parsing an object literal, class, or destructuring pattern; // propertyNameContext tells which one. This method parses any of the // following, storing the corresponding PropertyType in `*propType` to tell @@ -10377,7 +10718,7 @@ GeneralParser::propertyOrMethodName( } Node propName = propertyName(yieldHandling, propertyNameContext, maybeDecl, - propList, propAtom); + propList, propAtomOut); if (!propName) { return null(); } @@ -10491,7 +10832,7 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, bool seenPrototypeMutation = false; bool seenCoverInitializedName = false; Maybe declKind = Nothing(); - RootedAtom propAtom(cx_); + const ParserAtom* propAtom = nullptr; for (;;) { TokenKind tt; if (!tokenStream.peekToken(&tt)) { @@ -10553,7 +10894,7 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, return null(); } - if (propAtom == cx_->names().proto) { + if (propAtom == cx_->parserNames().proto) { if (seenPrototypeMutation) { // Directly report the error when we're definitely not // in a destructuring context. @@ -10593,7 +10934,7 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, * for |({x: x, y: y} = o)|, and |var o = {x, y}| as * initializer shorthand for |var o = {x: x, y: y}|. */ - Rooted name(cx_, identifierReference(yieldHandling)); + const ParserName* name = identifierReference(yieldHandling); if (!name) { return null(); } @@ -10616,7 +10957,7 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, * Support, e.g., |({x=1, y=2} = o)| as destructuring * shorthand with default values, as per ES6 12.14.5 */ - Rooted name(cx_, identifierReference(yieldHandling)); + const ParserName* name = identifierReference(yieldHandling); if (!name) { return null(); } @@ -10674,8 +11015,10 @@ GeneralParser::objectLiteral(YieldHandling yieldHandling, return null(); } } else { - RootedAtom funName(cx_); - if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) { + const ParserAtom* funName = nullptr; + bool hasStaticName = + !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom; + if (hasStaticName) { funName = propAtom; if (propType == PropertyType::Getter || @@ -10736,7 +11079,7 @@ template typename ParseHandler::FunctionNodeType GeneralParser::methodDefinition(uint32_t toStringStart, PropertyType propType, - HandleAtom funName) { + const ParserAtom* funName) { FunctionSyntaxKind syntaxKind; switch (propType) { case PropertyType::Getter: @@ -10980,7 +11323,7 @@ typename ParseHandler::Node GeneralParser::primaryExpr( } } - Rooted name(cx_, identifierReference(yieldHandling)); + const ParserName* name = identifierReference(yieldHandling); if (!name) { return null(); } @@ -11104,11 +11447,18 @@ template class Parser; template class Parser; CompilationInfo::RewindToken CompilationInfo::getRewindToken() { - return RewindToken{traceListHead}; + return RewindToken{stencil.scriptData.length(), stencil.asmJS.count()}; } void CompilationInfo::rewind(const CompilationInfo::RewindToken& pos) { - traceListHead = pos.funbox; + if (stencil.asmJS.count() != pos.asmJSCount) { + for (size_t i = pos.scriptDataLength; i < stencil.scriptData.length(); + i++) { + stencil.asmJS.remove(FunctionIndex(i)); + } + MOZ_ASSERT(stencil.asmJS.count() == pos.asmJSCount); + } + stencil.scriptData.shrinkTo(pos.scriptDataLength); } } // namespace js::frontend diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index ed6243af3c..83845588fa 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -208,7 +208,7 @@ class SourceParseContext : public ParseContext { SourceParseContext(GeneralParser* prs, SharedContext* sc, Directives* newDirectives) : ParseContext(prs->cx_, prs->pc_, sc, prs->tokenStream, - prs->getCompilationInfo(), newDirectives, + prs->compilationState_, newDirectives, std::is_same_v) {} }; @@ -243,9 +243,10 @@ class AutoInParametersOfAsyncFunction; class MOZ_STACK_CLASS ParserSharedBase : public JS::CustomAutoRooter { public: - enum class Kind { Parser, BinASTParser }; + enum class Kind { Parser }; - ParserSharedBase(JSContext* cx, CompilationInfo& compilationInfo, Kind kind); + ParserSharedBase(JSContext* cx, CompilationInfo& compilationInfo, + CompilationState& compilationState, Kind kind); ~ParserSharedBase(); public: @@ -256,6 +257,8 @@ class MOZ_STACK_CLASS ParserSharedBase : public JS::CustomAutoRooter { // Information for parsing with a lifetime longer than the parser itself. CompilationInfo& compilationInfo_; + CompilationState& compilationState_; + // innermost parse context (stack-allocated) ParseContext* pc_; @@ -264,6 +267,13 @@ class MOZ_STACK_CLASS ParserSharedBase : public JS::CustomAutoRooter { public: CompilationInfo& getCompilationInfo() { return compilationInfo_; } + + JSAtom* liftParserAtomToJSAtom(const ParserAtom* parserAtom) { + return compilationInfo_.liftParserAtomToJSAtom(cx_, parserAtom); + } + const ParserAtom* lowerJSAtomToParserAtom(JSAtom* atom) { + return compilationInfo_.lowerJSAtomToParserAtom(cx_, atom); + } }; class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, @@ -308,7 +318,8 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, friend class AutoInParametersOfAsyncFunction; ParserBase(JSContext* cx, const JS::ReadOnlyCompileOptions& options, - bool foldConstants, CompilationInfo& compilationInfo); + bool foldConstants, CompilationInfo& compilationInfo, + CompilationState& compilationState); ~ParserBase(); bool checkOptions(); @@ -359,7 +370,7 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, public: bool isUnexpectedEOF() const { return isUnexpectedEOF_; } - bool isValidStrictBinding(PropertyName* name); + bool isValidStrictBinding(const ParserName* name); bool hasValidSimpleStrictParameterNames(); @@ -367,7 +378,7 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, * Create a new function object given a name (which is optional if this is * a function expression). */ - JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind, + JSFunction* newFunction(const ParserAtom* atom, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind); @@ -377,29 +388,31 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, class Mark { friend class ParserBase; LifoAlloc::Mark mark; - FunctionBox* traceListHead; + CompilationInfo::RewindToken token; }; Mark mark() const { Mark m; m.mark = alloc_.mark(); - m.traceListHead = compilationInfo_.traceListHead; + m.token = compilationInfo_.getRewindToken(); return m; } void release(Mark m) { alloc_.release(m.mark); - compilationInfo_.traceListHead = m.traceListHead; + compilationInfo_.rewind(m.token); } public: - mozilla::Maybe newGlobalScopeData( + mozilla::Maybe newGlobalScopeData( ParseContext::Scope& scope); - mozilla::Maybe newModuleScopeData( + mozilla::Maybe newModuleScopeData( ParseContext::Scope& scope); - mozilla::Maybe newEvalScopeData(ParseContext::Scope& scope); - mozilla::Maybe newFunctionScopeData( + mozilla::Maybe newEvalScopeData( + ParseContext::Scope& scope); + mozilla::Maybe newFunctionScopeData( ParseContext::Scope& scope, bool hasParameterExprs); - mozilla::Maybe newVarScopeData(ParseContext::Scope& scope); - mozilla::Maybe newLexicalScopeData( + mozilla::Maybe newVarScopeData( + ParseContext::Scope& scope); + mozilla::Maybe newLexicalScopeData( ParseContext::Scope& scope); protected: @@ -411,13 +424,15 @@ class MOZ_STACK_CLASS ParserBase : public ParserSharedBase, // modifier TokenStream::SlashIsDiv, continues a LexicalDeclaration. bool nextTokenContinuesLetDeclaration(TokenKind next); - bool noteUsedNameInternal(HandlePropertyName name); + bool noteUsedNameInternal(const ParserName* name, NameVisibility visibility, + mozilla::Maybe tokenPosition); bool checkAndMarkSuperScope(); bool leaveInnerFunction(ParseContext* outerpc); - JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom); + const ParserAtom* prefixAccessorName(PropertyType propType, + const ParserAtom* propAtom); MOZ_MUST_USE bool setSourceMapInfo(); @@ -463,16 +478,19 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase { // are less likely to select this overload. PerHandlerParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options, bool foldConstants, CompilationInfo& compilationInfo, + CompilationState& compilationState, BaseScript* lazyOuterFunction, void* internalSyntaxParser); protected: template PerHandlerParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options, bool foldConstants, CompilationInfo& compilationInfo, + CompilationState& compilationState, GeneralParser* syntaxParser, BaseScript* lazyOuterFunction) : PerHandlerParser(cx, options, foldConstants, compilationInfo, - lazyOuterFunction, static_cast(syntaxParser)) {} + compilationState, lazyOuterFunction, + static_cast(syntaxParser)) {} static typename ParseHandler::NullNode null() { return ParseHandler::null(); } @@ -483,32 +501,41 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase { bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode, Node destruct); - bool noteUsedName(HandlePropertyName name) { + bool noteUsedName( + const ParserName* name, + NameVisibility visibility = NameVisibility::Public, + mozilla::Maybe tokenPosition = mozilla::Nothing()) { // If the we are delazifying, the BaseScript already has all the closed-over // info for bindings and there's no need to track used names. if (handler_.canSkipLazyClosedOverBindings()) { return true; } - return ParserBase::noteUsedNameInternal(name); + return ParserBase::noteUsedNameInternal(name, visibility, tokenPosition); } // Required on Scope exit. bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope); + bool checkForUndefinedPrivateFields(EvalSharedContext* evalSc = nullptr); + bool finishFunctionScopes(bool isStandaloneFunction); LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope, Node body, ScopeKind kind = ScopeKind::Lexical); bool finishFunction(bool isStandaloneFunction = false); - inline NameNodeType newName(PropertyName* name); - inline NameNodeType newName(PropertyName* name, TokenPos pos); + inline NameNodeType newName(const ParserName* name); + inline NameNodeType newName(const ParserName* name, TokenPos pos); + + inline NameNodeType newPrivateName(const ParserName* name); + inline NameNodeType newPrivateName(const ParserName* name, TokenPos pos); - NameNodeType newInternalDotName(HandlePropertyName name); + NameNodeType newInternalDotName(const ParserName* name); NameNodeType newThisName(); NameNodeType newDotGeneratorName(); - NameNodeType identifierReference(Handle name); + NameNodeType identifierReference(const ParserName* name); + NameNodeType privateNameReference(const ParserName* name); Node noSubstitutionTaggedTemplate(); @@ -544,7 +571,7 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase { inline void clearAbortedSyntaxParse(); public: - NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) { + NameNodeType newPropertyName(const ParserName* key, const TokenPos& pos) { return handler_.newPropertyName(key, pos); } @@ -552,16 +579,13 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase { return handler_.newPropertyAccess(expr, key); } - FunctionBox* newFunctionBox(FunctionNodeType funNode, JSFunction* fun, - uint32_t toStringStart, Directives directives, - GeneratorKind generatorKind, - FunctionAsyncKind asyncKind); - - FunctionBox* newFunctionBox(FunctionNodeType funNode, HandleAtom explicitName, + FunctionBox* newFunctionBox(FunctionNodeType funNode, + const ParserAtom* explicitName, FunctionFlags flags, uint32_t toStringStart, Directives directives, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind); + FunctionAsyncKind asyncKind, + TopLevelFunction isTopLevel); public: // ErrorReportMixin. @@ -687,6 +711,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { #if DEBUG using Base::checkOptionsCalled_; #endif + using Base::checkForUndefinedPrivateFields; using Base::finishFunctionScopes; using Base::finishLexicalScope; using Base::foldConstants_; @@ -755,6 +780,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { using Base::noteDestructuredPositionalFormalParameter; using Base::noteUsedName; using Base::prefixAccessorName; + using Base::privateNameReference; using Base::processExport; using Base::processExportFrom; using Base::setFunctionEndFromCurrentToken; @@ -901,7 +927,8 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { public: GeneralParser(JSContext* cx, const JS::ReadOnlyCompileOptions& options, const Unit* units, size_t length, bool foldConstants, - CompilationInfo& compilationInfo, SyntaxParser* syntaxParser, + CompilationInfo& compilationInfo, + CompilationState& compilationState, SyntaxParser* syntaxParser, BaseScript* lazyOuterFunction); inline void setAwaitHandling(AwaitHandling awaitHandling); @@ -972,8 +999,8 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { ListNodeType nodeList, TokenKind* ttp); inline bool trySyntaxParseInnerFunction( - FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, InHandling inHandling, + FunctionNodeType* funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives); @@ -1178,7 +1205,8 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { BinaryNodeType importExpr(YieldHandling yieldHandling, bool allowCallSyntax); FunctionNodeType methodDefinition(uint32_t toStringStart, - PropertyType propType, HandleAtom funName); + PropertyType propType, + const ParserAtom* funName); /* * Additional JS parsers. @@ -1188,9 +1216,9 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { FunctionNodeType functionDefinition( FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling, - YieldHandling yieldHandling, HandleAtom name, FunctionSyntaxKind kind, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind, - bool tryAnnexB = false); + YieldHandling yieldHandling, const ParserAtom* name, + FunctionSyntaxKind kind, GeneratorKind generatorKind, + FunctionAsyncKind asyncKind, bool tryAnnexB = false); // Parse a function body. Pass StatementListBody if the body is a list of // statements; pass ExpressionBody if the body is a single expression. @@ -1213,7 +1241,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { YieldHandling yieldHandling, TokenKind tt); - inline bool checkExportedName(JSAtom* exportName); + inline bool checkExportedName(const ParserAtom* exportName); inline bool checkExportedNamesForArrayBinding(ListNodeType array); inline bool checkExportedNamesForObjectBinding(ListNodeType obj); inline bool checkExportedNamesForDeclaration(Node node); @@ -1226,7 +1254,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { ClassNodeType classDefinition(YieldHandling yieldHandling, ClassContext classContext, DefaultHandling defaultHandling); - struct ClassFields { + struct ClassInitializedMembers { // The number of instance class fields. size_t instanceFields = 0; @@ -1238,42 +1266,48 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { // The number of static class fields with computed property names. size_t staticFieldKeys = 0; + + // The number of instance class private methods. + size_t privateMethods = 0; }; - MOZ_MUST_USE bool classMember(YieldHandling yieldHandling, - const ParseContext::ClassStatement& classStmt, - HandlePropertyName className, - uint32_t classStartOffset, - HasHeritage hasHeritage, - ClassFields& classFields, - ListNodeType& classMembers, bool* done); + MOZ_MUST_USE bool classMember( + YieldHandling yieldHandling, + const ParseContext::ClassStatement& classStmt, + const ParserName* className, uint32_t classStartOffset, + HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers, + ListNodeType& classMembers, bool* done); MOZ_MUST_USE bool finishClassConstructor( const ParseContext::ClassStatement& classStmt, - HandlePropertyName className, HasHeritage hasHeritage, + const ParserName* className, HasHeritage hasHeritage, uint32_t classStartOffset, uint32_t classEndOffset, - const ClassFields& classFields, ListNodeType& classMembers); - - FunctionNodeType fieldInitializerOpt(Node name, HandleAtom atom, - ClassFields& classFields, bool isStatic); - FunctionNodeType synthesizeConstructor(HandleAtom className, + const ClassInitializedMembers& classInitializedMembers, + ListNodeType& classMembers); + + FunctionNodeType privateMethodInitializer(const ParserAtom* propAtom, + const ParserAtom* storedMethodAtom); + FunctionNodeType fieldInitializerOpt( + Node name, const ParserAtom* atom, + ClassInitializedMembers& classInitializedMembers, bool isStatic, + HasHeritage hasHeritage); + FunctionNodeType synthesizeConstructor(const ParserAtom* className, uint32_t classNameOffset, HasHeritage hasHeritage); - bool checkBindingIdentifier(PropertyName* ident, uint32_t offset, + bool checkBindingIdentifier(const ParserName* ident, uint32_t offset, YieldHandling yieldHandling, TokenKind hint = TokenKind::Limit); - PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling); + const ParserName* labelOrIdentifierReference(YieldHandling yieldHandling); - PropertyName* labelIdentifier(YieldHandling yieldHandling) { + const ParserName* labelIdentifier(YieldHandling yieldHandling) { return labelOrIdentifierReference(yieldHandling); } - PropertyName* identifierReference(YieldHandling yieldHandling) { + const ParserName* identifierReference(YieldHandling yieldHandling) { return labelOrIdentifierReference(yieldHandling); } - bool matchLabel(YieldHandling yieldHandling, - MutableHandle label); + bool matchLabel(YieldHandling yieldHandling, const ParserName** labelOut); // Indicate if the next token (tokenized with SlashIsRegExp) is |in| or |of|. // If so, consume it. @@ -1286,10 +1320,10 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { void reportMissingClosing(unsigned errorNumber, unsigned noteNumber, uint32_t openedPos); - void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, + void reportRedeclaration(const ParserName* name, DeclarationKind prevKind, TokenPos pos, uint32_t prevPos); bool notePositionalFormalParameter(FunctionNodeType funNode, - HandlePropertyName name, uint32_t beginPos, + const ParserName* name, uint32_t beginPos, bool disallowDuplicateParams, bool* duplicatedParam); @@ -1301,12 +1335,12 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { Node propertyName(YieldHandling yieldHandling, PropertyNameContext propertyNameContext, const mozilla::Maybe& maybeDecl, - ListNodeType propList, MutableHandleAtom propAtom); + ListNodeType propList, const ParserAtom** propAtomOut); Node propertyOrMethodName(YieldHandling yieldHandling, PropertyNameContext propertyNameContext, const mozilla::Maybe& maybeDecl, ListNodeType propList, PropertyType* propType, - MutableHandleAtom propAtom); + const ParserAtom** propAtomOut); UnaryNodeType computedPropertyName( YieldHandling yieldHandling, const mozilla::Maybe& maybeDecl, @@ -1349,14 +1383,14 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { inline BigIntLiteralType newBigInt(); - JSAtom* bigIntAtom(); - enum class OptionalKind { NonOptional = 0, Optional, }; Node memberPropertyAccess( Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional); + Node memberPrivateAccess( + Node lhs, OptionalKind optionalKind = OptionalKind::NonOptional); Node memberElemAccess(Node lhs, YieldHandling yieldHandling, OptionalKind optionalKind = OptionalKind::NonOptional); Node memberSuperCall(Node lhs, YieldHandling yieldHandling); @@ -1368,17 +1402,18 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { // Match the current token against the BindingIdentifier production with // the given Yield parameter. If there is no match, report a syntax // error. - PropertyName* bindingIdentifier(YieldHandling yieldHandling); + const ParserName* bindingIdentifier(YieldHandling yieldHandling); - bool checkLabelOrIdentifierReference(PropertyName* ident, uint32_t offset, + bool checkLabelOrIdentifierReference(const ParserName* ident, uint32_t offset, YieldHandling yieldHandling, TokenKind hint = TokenKind::Limit); ListNodeType statementList(YieldHandling yieldHandling); MOZ_MUST_USE FunctionNodeType innerFunction( - FunctionNodeType funNode, ParseContext* outerpc, HandleAtom explicitName, - FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, + FunctionNodeType funNode, ParseContext* outerpc, + const ParserAtom* explicitName, FunctionFlags flags, + uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives); @@ -1395,9 +1430,12 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser { // next token could be a RegExp literal beginning a new ExpressionStatement. bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp); - bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind, + bool noteDeclaredName(const ParserName* name, DeclarationKind kind, TokenPos pos); + bool noteDeclaredPrivateName(Node nameNode, const ParserName* name, + PropertyType propType, TokenPos pos); + private: inline bool asmJS(ListNodeType list); }; @@ -1468,6 +1506,7 @@ class MOZ_STACK_CLASS Parser final #if DEBUG using Base::checkOptionsCalled_; #endif + using Base::checkForUndefinedPrivateFields; using Base::finishFunctionScopes; using Base::functionFormalParametersAndBody; using Base::handler_; @@ -1498,7 +1537,7 @@ class MOZ_STACK_CLASS Parser final // |using| the whole thing into existence because of the visibility // distinction, so we instead must manually delegate the required overload. - PropertyName* bindingIdentifier(YieldHandling yieldHandling) { + const ParserName* bindingIdentifier(YieldHandling yieldHandling) { return Base::bindingIdentifier(yieldHandling); } @@ -1515,7 +1554,7 @@ class MOZ_STACK_CLASS Parser final inline BinaryNodeType importDeclaration(); inline bool checkLocalExportNames(ListNodeType node); - inline bool checkExportedName(JSAtom* exportName); + inline bool checkExportedName(const ParserAtom* exportName); inline bool checkExportedNamesForArrayBinding(ListNodeType array); inline bool checkExportedNamesForObjectBinding(ListNodeType obj); inline bool checkExportedNamesForDeclaration(Node node); @@ -1525,8 +1564,8 @@ class MOZ_STACK_CLASS Parser final inline bool checkExportedNameForClause(NameNodeType nameNode); bool trySyntaxParseInnerFunction( - FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, InHandling inHandling, + FunctionNodeType* funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives); @@ -1611,6 +1650,7 @@ class MOZ_STACK_CLASS Parser final #if DEBUG using Base::checkOptionsCalled_; #endif + using Base::checkForUndefinedPrivateFields; using Base::cx_; using Base::finishFunctionScopes; using Base::finishLexicalScope; @@ -1641,7 +1681,7 @@ class MOZ_STACK_CLASS Parser final // |using| the whole thing into existence because of the visibility // distinction, so we instead must manually delegate the required overload. - PropertyName* bindingIdentifier(YieldHandling yieldHandling) { + const ParserName* bindingIdentifier(YieldHandling yieldHandling) { return Base::bindingIdentifier(yieldHandling); } @@ -1661,7 +1701,7 @@ class MOZ_STACK_CLASS Parser final BinaryNodeType importDeclaration(); bool checkLocalExportNames(ListNodeType node); - bool checkExportedName(JSAtom* exportName); + bool checkExportedName(const ParserAtom* exportName); bool checkExportedNamesForArrayBinding(ListNodeType array); bool checkExportedNamesForObjectBinding(ListNodeType obj); bool checkExportedNamesForDeclaration(Node node); @@ -1671,14 +1711,13 @@ class MOZ_STACK_CLASS Parser final inline bool checkExportedNameForClause(NameNodeType nameNode); bool trySyntaxParseInnerFunction( - FunctionNodeType* funNode, HandleAtom explicitName, FunctionFlags flags, - uint32_t toStringStart, InHandling inHandling, + FunctionNodeType* funNode, const ParserAtom* explicitName, + FunctionFlags flags, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives); - MOZ_MUST_USE bool advancePastSyntaxParsedFunction(AutoKeepAtoms& keepAtoms, - SyntaxParser* syntaxParser); + MOZ_MUST_USE bool advancePastSyntaxParsedFunction(SyntaxParser* syntaxParser); bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart, FunctionSyntaxKind kind, bool tryAnnexB); @@ -1702,7 +1741,6 @@ class MOZ_STACK_CLASS Parser final // Parse a function, used for the Function, GeneratorFunction, and // AsyncFunction constructors. FunctionNodeType standaloneFunction( - HandleScope enclosingScope, const mozilla::Maybe& parameterListEnd, FunctionSyntaxKind syntaxKind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, Directives inheritedDirectives, @@ -1715,9 +1753,9 @@ class MOZ_STACK_CLASS Parser final bool namedImportsOrNamespaceImport(TokenKind tt, ListNodeType importSpecSet); - PropertyName* importedBinding() { return bindingIdentifier(YieldIsName); } + const ParserName* importedBinding() { return bindingIdentifier(YieldIsName); } - bool checkLocalExportName(PropertyName* ident, uint32_t offset) { + bool checkLocalExportName(const ParserName* ident, uint32_t offset) { return checkLabelOrIdentifierReference(ident, offset, YieldIsName); } @@ -1814,26 +1852,29 @@ class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction { } }; -template -extern typename Scope::Data* NewEmptyBindingData(JSContext* cx, - LifoAlloc& alloc, - uint32_t numBindings); +template +extern ParserScopeData* NewEmptyBindingData(JSContext* cx, + LifoAlloc& alloc, + uint32_t numBindings); + +mozilla::Maybe NewGlobalScopeData( + JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, + ParseContext* pc); -mozilla::Maybe NewGlobalScopeData( +mozilla::Maybe NewEvalScopeData( JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc); -mozilla::Maybe NewEvalScopeData(JSContext* context, - ParseContext::Scope& scope, - LifoAlloc& alloc, - ParseContext* pc); -mozilla::Maybe NewFunctionScopeData( + +mozilla::Maybe NewFunctionScopeData( JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc); -mozilla::Maybe NewVarScopeData(JSContext* context, - ParseContext::Scope& scope, - LifoAlloc& alloc, - ParseContext* pc); -mozilla::Maybe NewLexicalScopeData( + +mozilla::Maybe NewVarScopeData(JSContext* context, + ParseContext::Scope& scope, + LifoAlloc& alloc, + ParseContext* pc); + +mozilla::Maybe NewLexicalScopeData( JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc); diff --git a/js/src/frontend/ParserAtom.cpp b/js/src/frontend/ParserAtom.cpp new file mode 100644 index 0000000000..a9e68228ab --- /dev/null +++ b/js/src/frontend/ParserAtom.cpp @@ -0,0 +1,613 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "frontend/ParserAtom.h" + +#include + +#include "jsnum.h" + +#include "frontend/CompilationInfo.h" +#include "frontend/NameCollections.h" +#include "vm/JSContext.h" +#include "vm/Printer.h" +#include "vm/Runtime.h" +#include "vm/StringType.h" + +using namespace js; +using namespace js::frontend; + +namespace js { + +// Iterates over a sequence of ParserAtoms and yield their sequence of +// characters in order. This simulates concatenation of atoms. The underlying +// ParserAtoms may be a mix of Latin1 and char16_t atoms. +template <> +class InflatedChar16Sequence { + private: + const ParserAtom** cur_ = nullptr; + const ParserAtom** lim_ = nullptr; + size_t index_ = 0; + + void settle() { + // Check if we are out-of-bounds for current ParserAtom. + auto outOfBounds = [this]() { return index_ >= (*cur_)->length(); }; + + while (hasMore() && outOfBounds()) { + // Advance to start of next ParserAtom. + cur_++; + index_ = 0; + } + } + + public: + explicit InflatedChar16Sequence( + const mozilla::Range& atoms) + : cur_(atoms.begin().get()), lim_(atoms.end().get()) { + settle(); + } + + bool hasMore() { return cur_ < lim_; } + + char16_t next() { + MOZ_ASSERT(hasMore()); + char16_t ch = (*cur_)->hasLatin1Chars() ? (*cur_)->latin1Chars()[index_] + : (*cur_)->twoByteChars()[index_]; + index_++; + settle(); + return ch; + } + + HashNumber computeHash() const { + auto copy = *this; + HashNumber hash = 0; + + while (copy.hasMore()) { + hash = mozilla::AddToHash(hash, copy.next()); + } + return hash; + } +}; + +} // namespace js + +namespace js { +namespace frontend { + +static JS::OOM PARSER_ATOMS_OOM; + +static JSAtom* GetWellKnownAtom(JSContext* cx, WellKnownAtomId kind) { +#define ASSERT_OFFSET_(idpart, id, text) \ + static_assert(offsetof(JSAtomState, id) == \ + int32_t(WellKnownAtomId::id) * \ + sizeof(js::ImmutablePropertyNamePtr)); + FOR_EACH_COMMON_PROPERTYNAME(ASSERT_OFFSET_); +#undef ASSERT_OFFSET_ + +#define ASSERT_OFFSET_(name, clasp) \ + static_assert(offsetof(JSAtomState, name) == \ + int32_t(WellKnownAtomId::name) * \ + sizeof(js::ImmutablePropertyNamePtr)); + JS_FOR_EACH_PROTOTYPE(ASSERT_OFFSET_); +#undef ASSERT_OFFSET_ + + static_assert(int32_t(WellKnownAtomId::abort) == 0, + "Unexpected order of WellKnownAtom"); + + return (&cx->names().abort)[int32_t(kind)]; +} + +mozilla::GenericErrorResult RaiseParserAtomsOOMError(JSContext* cx) { + js::ReportOutOfMemory(cx); + return mozilla::Err(PARSER_ATOMS_OOM); +} + +template +/* static */ JS::Result, OOM> +ParserAtomEntry::allocate(JSContext* cx, InflatedChar16Sequence seq, + uint32_t length, HashNumber hash) { + constexpr size_t HeaderSize = sizeof(ParserAtomEntry); + uint8_t* raw = cx->pod_malloc(HeaderSize + (sizeof(CharT) * length)); + if (!raw) { + return RaiseParserAtomsOOMError(cx); + } + + constexpr bool hasTwoByteChars = (sizeof(CharT) == 2); + static_assert(sizeof(CharT) == 1 || sizeof(CharT) == 2, + "CharT should be 1 or 2 byte type"); + UniquePtr entry( + new (raw) ParserAtomEntry(length, hash, hasTwoByteChars)); + CharT* entryBuf = entry->chars(); + drainChar16Seq(entryBuf, seq, length); + return entry; +} + +bool ParserAtomEntry::equalsJSAtom(JSAtom* other) const { + // Compare hashes and lengths first. + if (hash_ != other->hash() || length_ != other->length()) { + return false; + } + + JS::AutoCheckCannotGC nogc; + + if (hasTwoByteChars()) { + // Compare heap-allocated 16-bit chars to atom. + return other->hasLatin1Chars() + ? EqualChars(twoByteChars(), other->latin1Chars(nogc), length_) + : EqualChars(twoByteChars(), other->twoByteChars(nogc), length_); + } + + MOZ_ASSERT(hasLatin1Chars()); + return other->hasLatin1Chars() + ? EqualChars(latin1Chars(), other->latin1Chars(nogc), length_) + : EqualChars(latin1Chars(), other->twoByteChars(nogc), length_); +} + +template +UniqueChars ToPrintableStringImpl(JSContext* cx, mozilla::Range str) { + Sprinter sprinter(cx); + if (!sprinter.init()) { + return nullptr; + } + if (!QuoteString(&sprinter, str)) { + return nullptr; + } + return sprinter.release(); +} + +UniqueChars ParserAtomToPrintableString(JSContext* cx, const ParserAtom* atom) { + size_t length = atom->length(); + + return atom->hasLatin1Chars() + ? ToPrintableStringImpl( + cx, mozilla::Range(atom->latin1Chars(), length)) + : ToPrintableStringImpl( + cx, mozilla::Range(atom->twoByteChars(), length)); +} + +bool ParserAtomEntry::isIndex(uint32_t* indexp) const { + size_t len = length(); + if (len == 0 || len > UINT32_CHAR_BUFFER_LENGTH) { + return false; + } + if (hasLatin1Chars()) { + return mozilla::IsAsciiDigit(*latin1Chars()) && + js::CheckStringIsIndex(latin1Chars(), len, indexp); + } + return mozilla::IsAsciiDigit(*twoByteChars()) && + js::CheckStringIsIndex(twoByteChars(), len, indexp); +} + +JS::Result ParserAtomEntry::toJSAtom( + JSContext* cx, CompilationInfo& compilationInfo) const { + switch (atomIndexKind_) { + case AtomIndexKind::AtomIndex: + return compilationInfo.input.atoms[atomIndex_]; + + case AtomIndexKind::WellKnown: + return GetWellKnownAtom(cx, WellKnownAtomId(atomIndex_)); + + case AtomIndexKind::Static1: { + char16_t ch = static_cast(atomIndex_); + return cx->staticStrings().getUnit(ch); + } + + case AtomIndexKind::Static2: + return cx->staticStrings().getLength2FromIndex(atomIndex_); + + case AtomIndexKind::Unresolved: + break; + } + + JSAtom* atom; + if (hasLatin1Chars()) { + atom = AtomizeChars(cx, latin1Chars(), length()); + } else { + atom = AtomizeChars(cx, twoByteChars(), length()); + } + if (!atom) { + return RaiseParserAtomsOOMError(cx); + } + auto index = compilationInfo.input.atoms.length(); + if (!compilationInfo.input.atoms.append(atom)) { + return RaiseParserAtomsOOMError(cx); + } + + const_cast(this)->setAtomIndex(AtomIndex(index)); + + return atom; +} + +bool ParserAtomEntry::toNumber(JSContext* cx, double* result) const { + return hasLatin1Chars() ? CharsToNumber(cx, latin1Chars(), length(), result) + : CharsToNumber(cx, twoByteChars(), length(), result); +} + +#if defined(DEBUG) || defined(JS_JITSPEW) +void ParserAtomEntry::dump() const { + js::Fprinter out(stderr); + out.put("\""); + dumpCharsNoQuote(out); + out.put("\"\n"); +} + +void ParserAtomEntry::dumpCharsNoQuote(js::GenericPrinter& out) const { + if (hasLatin1Chars()) { + JSString::dumpCharsNoQuote(latin1Chars(), length(), out); + } else { + JSString::dumpCharsNoQuote(twoByteChars(), length(), out); + } +} +#endif + +ParserAtomsTable::ParserAtomsTable(JSRuntime* rt) + : wellKnownTable_(*rt->commonParserNames) {} + +JS::Result ParserAtomsTable::addEntry( + JSContext* cx, EntrySet::AddPtr& addPtr, UniquePtr entry) { + ParserAtomEntry* entryPtr = entry.get(); + MOZ_ASSERT(!addPtr); + if (!entrySet_.add(addPtr, std::move(entry))) { + return RaiseParserAtomsOOMError(cx); + } + return entryPtr->asAtom(); +} + +JS::Result ParserAtomsTable::internLatin1Seq( + JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, + const Latin1Char* latin1Ptr, uint32_t length) { + MOZ_ASSERT(!addPtr); + + InflatedChar16Sequence seq(latin1Ptr, length); + + UniquePtr entry; + MOZ_TRY_VAR(entry, + ParserAtomEntry::allocate(cx, seq, length, hash)); + return addEntry(cx, addPtr, std::move(entry)); +} + +template +JS::Result ParserAtomsTable::internChar16Seq( + JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, + InflatedChar16Sequence seq, uint32_t length) { + MOZ_ASSERT(!addPtr); + + UniquePtr entry; + MOZ_TRY_VAR(entry, + ParserAtomEntry::allocate(cx, seq, length, hash)); + return addEntry(cx, addPtr, std::move(entry)); +} + +static const uint16_t MAX_LATIN1_CHAR = 0xff; + +JS::Result ParserAtomsTable::internAscii( + JSContext* cx, const char* asciiPtr, uint32_t length) { + // ASCII strings are strict subsets of Latin1 strings. + const Latin1Char* latin1Ptr = reinterpret_cast(asciiPtr); + return internLatin1(cx, latin1Ptr, length); +} + +JS::Result ParserAtomsTable::internLatin1( + JSContext* cx, const Latin1Char* latin1Ptr, uint32_t length) { + // Check for tiny strings which are abundant in minified code. + if (const ParserAtom* tiny = wellKnownTable_.lookupTiny(latin1Ptr, length)) { + return tiny; + } + + // Check for well-known atom. + InflatedChar16Sequence seq(latin1Ptr, length); + SpecificParserAtomLookup lookup(seq); + if (const ParserAtom* wk = wellKnownTable_.lookupChar16Seq(lookup)) { + return wk; + } + + // Check for existing atom. + auto addPtr = entrySet_.lookupForAdd(lookup); + if (addPtr) { + return (*addPtr)->asAtom(); + } + + return internLatin1Seq(cx, addPtr, lookup.hash(), latin1Ptr, length); +} + +JS::Result ParserAtomsTable::internUtf8( + JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte) { + // Check for tiny strings which are abundant in minified code. + // NOTE: The tiny atoms are all ASCII-only so we can directly look at the + // UTF-8 data without worrying about surrogates. + if (const ParserAtom* tiny = wellKnownTable_.lookupTiny( + reinterpret_cast(utf8Ptr), nbyte)) { + return tiny; + } + + // If source text is ASCII, then the length of the target char buffer + // is the same as the length of the UTF8 input. Convert it to a Latin1 + // encoded string on the heap. + UTF8Chars utf8(utf8Ptr, nbyte); + JS::SmallestEncoding minEncoding = FindSmallestEncoding(utf8); + if (minEncoding == JS::SmallestEncoding::ASCII) { + // As ascii strings are a subset of Latin1 strings, and each encoding + // unit is the same size, we can reliably cast this `Utf8Unit*` + // to a `Latin1Char*`. + const Latin1Char* latin1Ptr = reinterpret_cast(utf8Ptr); + return internLatin1(cx, latin1Ptr, nbyte); + } + + // Check for existing. + // NOTE: Well-known are all ASCII so have been handled above. + InflatedChar16Sequence seq(utf8Ptr, nbyte); + SpecificParserAtomLookup lookup(seq); + MOZ_ASSERT(wellKnownTable_.lookupChar16Seq(lookup) == nullptr); + EntrySet::AddPtr addPtr = entrySet_.lookupForAdd(lookup); + if (addPtr) { + return (*addPtr)->asAtom(); + } + + // Compute length in code-points. + uint32_t length = 0; + InflatedChar16Sequence seqCopy = seq; + while (seqCopy.hasMore()) { + mozilla::Unused << seqCopy.next(); + length += 1; + } + + // Otherwise, add new entry. + bool wide = (minEncoding == JS::SmallestEncoding::UTF16); + return wide + ? internChar16Seq(cx, addPtr, lookup.hash(), seq, length) + : internChar16Seq(cx, addPtr, lookup.hash(), seq, + length); +} + +JS::Result ParserAtomsTable::internChar16( + JSContext* cx, const char16_t* char16Ptr, uint32_t length) { + // Check for tiny strings which are abundant in minified code. + if (const ParserAtom* tiny = wellKnownTable_.lookupTiny(char16Ptr, length)) { + return tiny; + } + + // Check against well-known. + InflatedChar16Sequence seq(char16Ptr, length); + SpecificParserAtomLookup lookup(seq); + if (const ParserAtom* wk = wellKnownTable_.lookupChar16Seq(lookup)) { + return wk; + } + + // Check for existing atom. + EntrySet::AddPtr addPtr = entrySet_.lookupForAdd(lookup); + if (addPtr) { + return (*addPtr)->asAtom(); + } + + // Compute the target encoding. + // NOTE: Length in code-points will be same, even if we deflate to Latin1. + bool wide = false; + InflatedChar16Sequence seqCopy = seq; + while (seqCopy.hasMore()) { + char16_t ch = seqCopy.next(); + if (ch > MAX_LATIN1_CHAR) { + wide = true; + break; + } + } + + // Otherwise, add new entry. + return wide + ? internChar16Seq(cx, addPtr, lookup.hash(), seq, length) + : internChar16Seq(cx, addPtr, lookup.hash(), seq, + length); +} + +JS::Result ParserAtomsTable::internJSAtom( + JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom) { + const ParserAtom* id; + { + JS::AutoCheckCannotGC nogc; + + auto result = + atom->hasLatin1Chars() + ? internLatin1(cx, atom->latin1Chars(nogc), atom->length()) + : internChar16(cx, atom->twoByteChars(nogc), atom->length()); + if (result.isErr()) { + return result; + } + id = result.unwrap(); + } + + if (id->atomIndexKind_ == ParserAtomEntry::AtomIndexKind::Unresolved) { + MOZ_ASSERT(id->equalsJSAtom(atom)); + + auto index = AtomIndex(compilationInfo.input.atoms.length()); + if (!compilationInfo.input.atoms.append(atom)) { + return RaiseParserAtomsOOMError(cx); + } + + const_cast(id)->setAtomIndex(AtomIndex(index)); + } + + // We should (infallibly) map back to the same JSAtom. + MOZ_ASSERT(id->toJSAtom(cx, compilationInfo).unwrap() == atom); + + return id; +} + +JS::Result ParserAtomsTable::concatAtoms( + JSContext* cx, mozilla::Range atoms) { + MOZ_ASSERT(atoms.length() >= 2, + "concatAtoms should only be used for multiple inputs"); + + // Compute final length and encoding. + bool catLatin1 = true; + uint32_t catLen = 0; + for (const ParserAtom* atom : atoms) { + if (atom->hasTwoByteChars()) { + catLatin1 = false; + } + // Overflow check here, length + if (atom->length() >= (ParserAtomEntry::MAX_LENGTH - catLen)) { + return RaiseParserAtomsOOMError(cx); + } + catLen += atom->length(); + } + + // Short Latin1 strings must check for both Tiny and WellKnown atoms so simple + // concatenate onto stack and use `internLatin1`. + if (catLatin1 && (catLen <= WellKnownParserAtoms::MaxWellKnownLength)) { + Latin1Char buf[WellKnownParserAtoms::MaxWellKnownLength]; + size_t offset = 0; + for (const ParserAtom* atom : atoms) { + mozilla::PodCopy(buf + offset, atom->latin1Chars(), atom->length()); + offset += atom->length(); + } + return internLatin1(cx, buf, catLen); + } + + // NOTE: We have ruled out Tiny and WellKnown atoms and can ignore below. + + InflatedChar16Sequence seq(atoms); + SpecificParserAtomLookup lookup(seq); + + // Check for existing atom. + auto addPtr = entrySet_.lookupForAdd(lookup); + if (addPtr) { + return (*addPtr)->asAtom(); + } + + // Otherwise, add new entry. + return catLatin1 ? internChar16Seq(cx, addPtr, lookup.hash(), seq, + catLen) + : internChar16Seq(cx, addPtr, lookup.hash(), seq, + catLen); +} + +template +const ParserAtom* WellKnownParserAtoms::lookupChar16Seq( + const SpecificParserAtomLookup& lookup) const { + EntrySet::Ptr get = wellKnownSet_.readonlyThreadsafeLookup(lookup); + if (get) { + return get->get()->asAtom(); + } + return nullptr; +} + +bool WellKnownParserAtoms::initSingle(JSContext* cx, const ParserName** name, + const char* str, WellKnownAtomId kind) { + MOZ_ASSERT(name != nullptr); + + unsigned int len = strlen(str); + + // Well-known atoms are all currently ASCII with length <= MaxWellKnownLength. + MOZ_ASSERT(len <= MaxWellKnownLength); + MOZ_ASSERT(FindSmallestEncoding(UTF8Chars(str, len)) == + JS::SmallestEncoding::ASCII); + + // Strings matched by lookupTiny are stored in static table and aliases should + // only be added using initTinyStringAlias. + MOZ_ASSERT(lookupTiny(str, len) == nullptr, + "Well-known atom matches a tiny StaticString. Did you add it to " + "the wrong CommonPropertyNames.h list?"); + + InflatedChar16Sequence seq( + reinterpret_cast(str), len); + SpecificParserAtomLookup lookup(seq); + HashNumber hash = lookup.hash(); + + auto maybeEntry = ParserAtomEntry::allocate(cx, seq, len, hash); + if (maybeEntry.isErr()) { + return false; + } + UniquePtr entry = maybeEntry.unwrap(); + entry->setWellKnownAtomId(kind); + + // Save name for returning after moving entry into set. + const ParserName* nm = entry.get()->asName(); + if (!wellKnownSet_.putNew(lookup, std::move(entry))) { + js::ReportOutOfMemory(cx); + return false; + } + + *name = nm; + return true; +} + +bool WellKnownParserAtoms::initTinyStringAlias(JSContext* cx, + const ParserName** name, + const char* str) { + MOZ_ASSERT(name != nullptr); + + unsigned int len = strlen(str); + + // Well-known atoms are all currently ASCII with length <= MaxWellKnownLength. + MOZ_ASSERT(len <= MaxWellKnownLength); + MOZ_ASSERT(FindSmallestEncoding(UTF8Chars(str, len)) == + JS::SmallestEncoding::ASCII); + + // NOTE: If this assert fails, you may need to change which list is it belongs + // to in CommonPropertyNames.h. + const ParserAtom* tiny = lookupTiny(str, len); + MOZ_ASSERT(tiny, "Tiny common name was not found"); + + // Set alias to existing atom. + *name = tiny->asName(); + return true; +} + +bool WellKnownParserAtoms::init(JSContext* cx) { + // NOTE: Well-known tiny strings (with length <= 2) are stored in the + // WellKnownParserAtoms_ROM table. This uses static constexpr initialization + // so we don't need to do anything here. + + // Tiny strings with a common name need a named alias to an entry in the + // WellKnownParserAtoms_ROM. +#define COMMON_NAME_INIT_(idpart, id, text) \ + if (!initTinyStringAlias(cx, &(id), text)) { \ + return false; \ + } + FOR_EACH_TINY_PROPERTYNAME(COMMON_NAME_INIT_) +#undef COMMON_NAME_INIT_ + + // Initialize well-known ParserAtoms that use hash set lookup. These also + // point the compile-time names to the own atoms. +#define COMMON_NAME_INIT_(idpart, id, text) \ + if (!initSingle(cx, &(id), text, WellKnownAtomId::id)) { \ + return false; \ + } + FOR_EACH_NONTINY_COMMON_PROPERTYNAME(COMMON_NAME_INIT_) +#undef COMMON_NAME_INIT_ +#define COMMON_NAME_INIT_(name, clasp) \ + if (!initSingle(cx, &(name), #name, WellKnownAtomId::name)) { \ + return false; \ + } + JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INIT_) +#undef COMMON_NAME_INIT_ + + return true; +} + +} /* namespace frontend */ +} /* namespace js */ + +bool JSRuntime::initializeParserAtoms(JSContext* cx) { + MOZ_ASSERT(!commonParserNames); + + if (parentRuntime) { + commonParserNames = parentRuntime->commonParserNames; + return true; + } + + UniquePtr names( + js_new()); + if (!names || !names->init(cx)) { + return false; + } + + commonParserNames = names.release(); + return true; +} + +void JSRuntime::finishParserAtoms() { + if (!parentRuntime) { + js_delete(commonParserNames.ref()); + } +} diff --git a/js/src/frontend/ParserAtom.h b/js/src/frontend/ParserAtom.h new file mode 100644 index 0000000000..f4ca539e23 --- /dev/null +++ b/js/src/frontend/ParserAtom.h @@ -0,0 +1,523 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 frontend_ParserAtom_h +#define frontend_ParserAtom_h + +#include "mozilla/DebugOnly.h" // mozilla::DebugOnly +#include "mozilla/HashFunctions.h" // HashString +#include "mozilla/Range.h" // mozilla::Range +#include "mozilla/Variant.h" // mozilla::Variant + +#include "ds/LifoAlloc.h" // LifoAlloc +#include "frontend/TypedIndex.h" // TypedIndex +#include "js/HashTable.h" // HashSet +#include "js/UniquePtr.h" // js::UniquePtr +#include "js/Vector.h" // Vector +#include "vm/CommonPropertyNames.h" +#include "vm/StringType.h" // CompareChars, StringEqualsAscii + +namespace js { +namespace frontend { + +struct CompilationInfo; +class ParserAtom; +class ParserName; + +template +class SpecificParserAtomLookup; + +class ParserAtomsTable; + +mozilla::GenericErrorResult RaiseParserAtomsOOMError(JSContext* cx); + +// An index into CompilationInfo.atoms. +// This is local to the current compilation. +using AtomIndex = TypedIndex; + +// An index to map WellKnownParserAtoms to cx->names(). +// This is consistent across multiple compilation. +// +// GetWellKnownAtom in ParserAtom.cpp relies on the fact that +// JSAtomState fields and this enum variants use the same order. +enum class WellKnownAtomId : uint32_t { +#define ENUM_ENTRY_(idpart, id, text) id, + FOR_EACH_COMMON_PROPERTYNAME(ENUM_ENTRY_) +#undef ENUM_ENTRY_ + +#define ENUM_ENTRY_(name, clasp) name, + JS_FOR_EACH_PROTOTYPE(ENUM_ENTRY_) +#undef ENUM_ENTRY_ +}; + +// These types correspond into indices in the StaticStrings arrays. +enum class StaticParserString1 : uint8_t; +enum class StaticParserString2 : uint16_t; + +/** + * A ParserAtomEntry is an in-parser representation of an interned atomic + * string. It mostly mirrors the information carried by a JSAtom*. + * + * The atom contents are stored in one of two locations: + * 1. Inline Latin1Char storage (immediately after the ParserAtomEntry memory). + * 2. Inline char16_t storage (immediately after the ParserAtomEntry memory). + */ +class alignas(alignof(uint32_t)) ParserAtomEntry { + friend class ParserAtomsTable; + friend class WellKnownParserAtoms; + friend class WellKnownParserAtoms_ROM; + + static const uint16_t MAX_LATIN1_CHAR = 0xff; + + // Helper routine to read some sequence of two-byte chars, and write them + // into a target buffer of a particular character width. + // + // The characters in the sequence must have been verified prior + template + static void drainChar16Seq(CharT* buf, InflatedChar16Sequence seq, + uint32_t length) { + static_assert( + std::is_same_v || std::is_same_v, + "Invalid target buffer type."); + CharT* cur = buf; + while (seq.hasMore()) { + char16_t ch = seq.next(); + if constexpr (std::is_same_v) { + MOZ_ASSERT(ch <= MAX_LATIN1_CHAR); + } + MOZ_ASSERT(cur < (buf + length)); + *cur = ch; + cur++; + } + } + + private: + // The JSAtom-compatible hash of the string. + HashNumber hash_ = 0; + + // The length of the buffer in chars_. + uint32_t length_ = 0; + + // Mapping into from ParserAtoms to JSAtoms. + enum class AtomIndexKind : uint8_t { + Unresolved, // Not yet resolved + AtomIndex, // Index into CompilationInfo atoms map + WellKnown, // WellKnownAtomId to index into cx->names() set + Static1, // Index into StaticStrings length-1 set + Static2, // Index into StaticStrings length-2 set + }; + uint32_t atomIndex_ = 0; + AtomIndexKind atomIndexKind_ = AtomIndexKind::Unresolved; + + // Encoding type. + bool hasTwoByteChars_ = false; + + // End of fields. + + static const uint32_t MAX_LENGTH = JSString::MAX_LENGTH; + + ParserAtomEntry(uint32_t length, HashNumber hash, bool hasTwoByteChars) + : hash_(hash), length_(length), hasTwoByteChars_(hasTwoByteChars) {} + + protected: + // The constexpr constructor is used by StaticParserAtomEntry. + constexpr ParserAtomEntry() = default; + + public: + // ParserAtomEntries may own their content buffers in variant_, and thus + // cannot be copy-constructed - as a new chars would need to be allocated. + ParserAtomEntry(const ParserAtomEntry&) = delete; + ParserAtomEntry(ParserAtomEntry&& other) = delete; + + template + static JS::Result, OOM> allocate( + JSContext* cx, InflatedChar16Sequence seq, uint32_t length, + HashNumber hash); + + ParserAtom* asAtom() { return reinterpret_cast(this); } + const ParserAtom* asAtom() const { + return reinterpret_cast(this); + } + + inline ParserName* asName(); + inline const ParserName* asName() const; + + bool hasLatin1Chars() const { return !hasTwoByteChars_; } + bool hasTwoByteChars() const { return hasTwoByteChars_; } + + template + const CharT* chars() const { + MOZ_ASSERT(sizeof(CharT) == (hasTwoByteChars() ? 2 : 1)); + return reinterpret_cast(this + 1); + } + + template + CharT* chars() { + MOZ_ASSERT(sizeof(CharT) == (hasTwoByteChars() ? 2 : 1)); + return reinterpret_cast(this + 1); + } + + const Latin1Char* latin1Chars() const { return chars(); } + const char16_t* twoByteChars() const { return chars(); } + mozilla::Range latin1Range() const { + return mozilla::Range(latin1Chars(), length_); + } + mozilla::Range twoByteRange() const { + return mozilla::Range(twoByteChars(), length_); + } + + bool isIndex(uint32_t* indexp) const; + bool isIndex() const { + uint32_t index; + return isIndex(&index); + } + + HashNumber hash() const { return hash_; } + uint32_t length() const { return length_; } + + bool equalsJSAtom(JSAtom* other) const; + + template + bool equalsSeq(HashNumber hash, InflatedChar16Sequence seq) const; + + private: + void setAtomIndex(AtomIndex index) { + atomIndex_ = index; + atomIndexKind_ = AtomIndexKind::AtomIndex; + } + constexpr void setWellKnownAtomId(WellKnownAtomId kind) { + atomIndex_ = static_cast(kind); + atomIndexKind_ = AtomIndexKind::WellKnown; + } + constexpr void setStaticParserString1(StaticParserString1 s) { + atomIndex_ = static_cast(s); + atomIndexKind_ = AtomIndexKind::Static1; + } + constexpr void setStaticParserString2(StaticParserString2 s) { + atomIndex_ = static_cast(s); + atomIndexKind_ = AtomIndexKind::Static2; + } + constexpr void setHashAndLength(HashNumber hash, uint32_t length, + bool hasTwoByteChars = false) { + hash_ = hash; + length_ = length; + hasTwoByteChars_ = hasTwoByteChars; + } + + public: + // Convert this entry to a js-atom. The first time this method is called + // the entry will cache the JSAtom pointer to return later. + JS::Result toJSAtom(JSContext* cx, + CompilationInfo& compilationInfo) const; + + // Convert this entry to a number. + bool toNumber(JSContext* cx, double* result) const; + +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump() const; + void dumpCharsNoQuote(js::GenericPrinter& out) const; +#endif +}; + +class ParserAtom : public ParserAtomEntry { + ParserAtom() = delete; + ParserAtom(const ParserAtom&) = delete; +}; + +class ParserName : public ParserAtom { + ParserName() = delete; + ParserName(const ParserName&) = delete; +}; + +UniqueChars ParserAtomToPrintableString(JSContext* cx, const ParserAtom* atom); + +inline ParserName* ParserAtomEntry::asName() { + MOZ_ASSERT(!isIndex()); + return static_cast(this); +} +inline const ParserName* ParserAtomEntry::asName() const { + MOZ_ASSERT(!isIndex()); + return static_cast(this); +} + +// A ParserAtomEntry with explicit inline storage. This is compatible with +// constexpr to have builtin atoms. Care must be taken to ensure these atoms are +// unique. +template +class StaticParserAtomEntry : public ParserAtomEntry { + alignas(alignof(ParserAtomEntry)) char storage_[Length] = {}; + + public: + constexpr StaticParserAtomEntry() = default; + + constexpr char* storage() { + static_assert( + offsetof(StaticParserAtomEntry, storage_) == sizeof(ParserAtomEntry), + "StaticParserAtomEntry storage should follow ParserAtomEntry"); + return storage_; + } +}; + +template <> +class StaticParserAtomEntry<0> : public ParserAtomEntry { + public: + constexpr StaticParserAtomEntry() = default; +}; + +/** + * A lookup structure that allows for querying ParserAtoms in + * a hashtable using a flexible input type that supports string + * representations of various forms. + */ +class ParserAtomLookup { + protected: + HashNumber hash_; + + ParserAtomLookup(HashNumber hash) : hash_(hash) {} + + public: + HashNumber hash() const { return hash_; } + + virtual bool equalsEntry(const ParserAtomEntry* entry) const = 0; +}; + +struct ParserAtomLookupHasher { + using Lookup = ParserAtomLookup; + + static inline HashNumber hash(const Lookup& l) { return l.hash(); } + static inline bool match(const UniquePtr& entry, + const Lookup& l) { + return l.equalsEntry(entry.get()); + } +}; + +class WellKnownParserAtoms_ROM { + public: + static const size_t ASCII_STATIC_LIMIT = 128U; + static const size_t NUM_SMALL_CHARS = StaticStrings::NUM_SMALL_CHARS; + static const size_t NUM_LENGTH2_ENTRIES = NUM_SMALL_CHARS * NUM_SMALL_CHARS; + + StaticParserAtomEntry<0> emptyAtom; + StaticParserAtomEntry<1> length1Table[ASCII_STATIC_LIMIT]; + StaticParserAtomEntry<2> length2Table[NUM_LENGTH2_ENTRIES]; + + constexpr WellKnownParserAtoms_ROM() { + // Empty atom + emptyAtom.setHashAndLength(mozilla::HashString(u""), 0); + emptyAtom.setWellKnownAtomId(WellKnownAtomId::empty); + + // Length-1 static atoms + for (size_t i = 0; i < ASCII_STATIC_LIMIT; ++i) { + constexpr size_t len = 1; + char16_t buf[] = {static_cast(i), + /* null-terminator */ 0}; + length1Table[i].setHashAndLength(mozilla::HashString(buf), len); + length1Table[i].setStaticParserString1(StaticParserString1(i)); + length1Table[i].storage()[0] = buf[0]; + } + + // Length-2 static atoms + for (size_t i = 0; i < NUM_LENGTH2_ENTRIES; ++i) { + constexpr size_t len = 2; + char16_t buf[] = {StaticStrings::fromSmallChar(i >> 6), + StaticStrings::fromSmallChar(i & 0x003F), + /* null-terminator */ 0}; + length2Table[i].setHashAndLength(mozilla::HashString(buf), len); + length2Table[i].setStaticParserString2(StaticParserString2(i)); + length2Table[i].storage()[0] = buf[0]; + length2Table[i].storage()[1] = buf[1]; + } + } + + // Fast-path tiny strings since they are abundant in minified code. + template + const ParserAtom* lookupTiny(CharsT chars, size_t length) const { + static_assert(std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v, + "This assert mostly explicitly documents the calling types, " + "and forces that to be updated if new types show up."); + switch (length) { + case 0: + return emptyAtom.asAtom(); + + case 1: { + if (char16_t(chars[0]) < ASCII_STATIC_LIMIT) { + size_t index = static_cast(chars[0]); + return length1Table[index].asAtom(); + } + break; + } + + case 2: + if (StaticStrings::fitsInSmallChar(chars[0]) && + StaticStrings::fitsInSmallChar(chars[1])) { + size_t index = StaticStrings::getLength2Index(chars[0], chars[1]); + return length2Table[index].asAtom(); + } + break; + } + + // No match on tiny Atoms + return nullptr; + } +}; + +/** + * WellKnownParserAtoms reserves a set of common ParserAtoms on the JSRuntime + * in a read-only format to be used by parser. These reserved atoms can be + * translated to equivalent JSAtoms in constant time. + * + * The common-names set allows the parser to lookup up specific atoms in + * constant time. + * + * We also reserve tiny (length 1/2) parser-atoms for fast lookup similar to + * the js::StaticStrings mechanism. This speeds up parsing minified code. + */ +class WellKnownParserAtoms { + public: + /* Various built-in or commonly-used names. */ +#define PROPERTYNAME_FIELD_(idpart, id, text) const ParserName* id{}; + FOR_EACH_COMMON_PROPERTYNAME(PROPERTYNAME_FIELD_) +#undef PROPERTYNAME_FIELD_ + +#define PROPERTYNAME_FIELD_(name, clasp) const ParserName* name{}; + JS_FOR_EACH_PROTOTYPE(PROPERTYNAME_FIELD_) +#undef PROPERTYNAME_FIELD_ + + // Common tiny strings (such as identifiers in minified code) have ParserAtoms + // generated into constexpr tables. + static constexpr WellKnownParserAtoms_ROM rom_ = {}; + + // Common property and prototype names are tracked in a hash table. This table + // is does not key for any items already in a direct-indexing table above. + using EntrySet = HashSet, ParserAtomLookupHasher, + js::SystemAllocPolicy>; + EntrySet wellKnownSet_; + + bool initTinyStringAlias(JSContext* cx, const ParserName** name, + const char* str); + bool initSingle(JSContext* cx, const ParserName** name, const char* str, + WellKnownAtomId kind); + + public: + WellKnownParserAtoms() = default; + + bool init(JSContext* cx); + + // Maximum length of any well known atoms. This can be increased if needed. + static constexpr size_t MaxWellKnownLength = 32; + + template + const ParserAtom* lookupChar16Seq( + const SpecificParserAtomLookup& lookup) const; + + template + const ParserAtom* lookupTiny(CharsT chars, size_t length) const { + return rom_.lookupTiny(chars, length); + } +}; + +/** + * A ParserAtomsTable owns and manages the vector of ParserAtom entries + * associated with a given compile session. + */ +class ParserAtomsTable { + private: + using EntrySet = HashSet, ParserAtomLookupHasher, + js::SystemAllocPolicy>; + EntrySet entrySet_; + const WellKnownParserAtoms& wellKnownTable_; + + public: + explicit ParserAtomsTable(JSRuntime* rt); + + private: + // Internal APIs for interning to the table after well-known atoms cases have + // been tested. + JS::Result addEntry(JSContext* cx, + EntrySet::AddPtr& addPtr, + UniquePtr entry); + JS::Result internLatin1Seq( + JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, + const Latin1Char* latin1Ptr, uint32_t length); + template + JS::Result internChar16Seq( + JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, + InflatedChar16Sequence seq, uint32_t length); + + public: + JS::Result internAscii(JSContext* cx, + const char* asciiPtr, + uint32_t length); + + JS::Result internLatin1( + JSContext* cx, const JS::Latin1Char* latin1Ptr, uint32_t length); + + JS::Result internUtf8( + JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte); + + JS::Result internChar16(JSContext* cx, + const char16_t* char16Ptr, + uint32_t length); + + JS::Result internJSAtom( + JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom); + + JS::Result concatAtoms( + JSContext* cx, mozilla::Range atoms); +}; + +template +class SpecificParserAtomLookup : public ParserAtomLookup { + // The sequence of characters to look up. + InflatedChar16Sequence seq_; + + public: + explicit SpecificParserAtomLookup(const InflatedChar16Sequence& seq) + : SpecificParserAtomLookup(seq, seq.computeHash()) {} + + SpecificParserAtomLookup(const InflatedChar16Sequence& seq, + HashNumber hash) + : ParserAtomLookup(hash), seq_(seq) { + MOZ_ASSERT(seq_.computeHash() == hash); + } + + virtual bool equalsEntry(const ParserAtomEntry* entry) const override { + return entry->equalsSeq(hash_, seq_); + } +}; + +template +inline bool ParserAtomEntry::equalsSeq( + HashNumber hash, InflatedChar16Sequence seq) const { + // Compare hashes first. + if (hash_ != hash) { + return false; + } + + if (hasTwoByteChars()) { + const char16_t* chars = twoByteChars(); + for (uint32_t i = 0; i < length_; i++) { + if (!seq.hasMore() || chars[i] != seq.next()) { + return false; + } + } + } else { + const Latin1Char* chars = latin1Chars(); + for (uint32_t i = 0; i < length_; i++) { + if (!seq.hasMore() || char16_t(chars[i]) != seq.next()) { + return false; + } + } + } + return !seq.hasMore(); +} + +} /* namespace frontend */ +} /* namespace js */ + +#endif // frontend_ParserAtom_h diff --git a/js/src/frontend/PropOpEmitter.cpp b/js/src/frontend/PropOpEmitter.cpp index 56041f7d25..1d0b6699f0 100644 --- a/js/src/frontend/PropOpEmitter.cpp +++ b/js/src/frontend/PropOpEmitter.cpp @@ -16,11 +16,11 @@ using namespace js::frontend; PropOpEmitter::PropOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind) : bce_(bce), kind_(kind), objKind_(objKind) {} -bool PropOpEmitter::prepareAtomIndex(JSAtom* prop) { +bool PropOpEmitter::prepareAtomIndex(const ParserAtom* prop) { if (!bce_->makeAtomIndex(prop, &propAtomIndex_)) { return false; } - isLength_ = prop == bce_->cx->names().length; + isLength_ = prop == bce_->cx->parserNames().length; return true; } @@ -34,7 +34,7 @@ bool PropOpEmitter::prepareForObj() { return true; } -bool PropOpEmitter::emitGet(JSAtom* prop) { +bool PropOpEmitter::emitGet(const ParserAtom* prop) { MOZ_ASSERT(state_ == State::Obj); if (!prepareAtomIndex(prop)) { @@ -132,7 +132,7 @@ bool PropOpEmitter::skipObjAndRhs() { return true; } -bool PropOpEmitter::emitDelete(JSAtom* prop) { +bool PropOpEmitter::emitDelete(const ParserAtom* prop) { MOZ_ASSERT_IF(!isSuper(), state_ == State::Obj); MOZ_ASSERT_IF(isSuper(), state_ == State::Start); MOZ_ASSERT(isDelete()); @@ -172,7 +172,7 @@ bool PropOpEmitter::emitDelete(JSAtom* prop) { return true; } -bool PropOpEmitter::emitAssignment(JSAtom* prop) { +bool PropOpEmitter::emitAssignment(const ParserAtom* prop) { MOZ_ASSERT(isSimpleAssignment() || isPropInit() || isCompoundAssignment()); MOZ_ASSERT(state_ == State::Rhs); @@ -200,7 +200,7 @@ bool PropOpEmitter::emitAssignment(JSAtom* prop) { return true; } -bool PropOpEmitter::emitIncDec(JSAtom* prop) { +bool PropOpEmitter::emitIncDec(const ParserAtom* prop) { MOZ_ASSERT(state_ == State::Obj); MOZ_ASSERT(isIncDec()); diff --git a/js/src/frontend/PropOpEmitter.h b/js/src/frontend/PropOpEmitter.h index c1424adc16..cd3fe45cf5 100644 --- a/js/src/frontend/PropOpEmitter.h +++ b/js/src/frontend/PropOpEmitter.h @@ -10,11 +10,13 @@ #include #include "js/TypeDecls.h" +#include "vm/SharedStencil.h" // GCThingIndex namespace js { namespace frontend { struct BytecodeEmitter; +class ParserAtom; // Class for emitting bytecode for property operation. // @@ -122,7 +124,7 @@ class MOZ_STACK_CLASS PropOpEmitter { ObjKind objKind_; // The index for the property name's atom. - uint32_t propAtomIndex_ = 0; + GCThingIndex propAtomIndex_; // Whether the property name is `length` or not. bool isLength_ = false; @@ -229,22 +231,22 @@ class MOZ_STACK_CLASS PropOpEmitter { return kind_ == Kind::PostIncrement || kind_ == Kind::PreIncrement; } - MOZ_MUST_USE bool prepareAtomIndex(JSAtom* prop); + MOZ_MUST_USE bool prepareAtomIndex(const ParserAtom* prop); public: MOZ_MUST_USE bool prepareForObj(); - MOZ_MUST_USE bool emitGet(JSAtom* prop); + MOZ_MUST_USE bool emitGet(const ParserAtom* prop); MOZ_MUST_USE bool prepareForRhs(); MOZ_MUST_USE bool skipObjAndRhs(); - MOZ_MUST_USE bool emitDelete(JSAtom* prop); + MOZ_MUST_USE bool emitDelete(const ParserAtom* prop); // `prop` can be nullptr for CompoundAssignment. - MOZ_MUST_USE bool emitAssignment(JSAtom* prop); + MOZ_MUST_USE bool emitAssignment(const ParserAtom* prop); - MOZ_MUST_USE bool emitIncDec(JSAtom* prop); + MOZ_MUST_USE bool emitIncDec(const ParserAtom* prop); }; } /* namespace frontend */ diff --git a/js/src/frontend/SharedContext-inl.h b/js/src/frontend/SharedContext-inl.h index b65633dbf0..27e7ab29c4 100644 --- a/js/src/frontend/SharedContext-inl.h +++ b/js/src/frontend/SharedContext-inl.h @@ -14,6 +14,15 @@ namespace frontend { inline Directives::Directives(ParseContext* parent) : strict_(parent->sc()->strict()), asmJS_(parent->useAsmOrInsideUseAsm()) {} +inline JSAtom* SharedContext::liftParserAtomToJSAtom(JSContext* cx, + const ParserAtom* atomId) { + return compilationInfo_.liftParserAtomToJSAtom(cx, atomId); +} +inline const ParserAtom* SharedContext::lowerJSAtomToParserAtom(JSContext* cx, + JSAtom* atom) { + return compilationInfo_.lowerJSAtomToParserAtom(cx, atom); +} + } // namespace frontend } // namespace js diff --git a/js/src/frontend/SharedContext.cpp b/js/src/frontend/SharedContext.cpp index 66605f0b31..8060a68b71 100644 --- a/js/src/frontend/SharedContext.cpp +++ b/js/src/frontend/SharedContext.cpp @@ -11,6 +11,7 @@ #include "frontend/ModuleSharedContext.h" #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind +#include "vm/StencilEnums.h" // ImmutableScriptFlagsEnum #include "wasm/AsmJS.h" #include "wasm/WasmModule.h" @@ -25,19 +26,21 @@ SharedContext::SharedContext(JSContext* cx, Kind kind, Directives directives, SourceExtent extent) : cx_(cx), compilationInfo_(compilationInfo), - extent(extent), + extent_(extent), allowNewTarget_(false), allowSuperProperty_(false), allowSuperCall_(false), allowArguments_(true), inWith_(false), + inClass_(false), localStrict(false), - hasExplicitUseStrict_(false) { + hasExplicitUseStrict_(false), + isScriptFieldCopiedToStencil(false) { // Compute the script kind "input" flags. if (kind == Kind::FunctionBox) { setFlag(ImmutableFlags::IsFunction); } else if (kind == Kind::Module) { - MOZ_ASSERT(!compilationInfo.options.nonSyntacticScope); + MOZ_ASSERT(!compilationInfo.input.options.nonSyntacticScope); setFlag(ImmutableFlags::IsModule); } else if (kind == Kind::Eval) { setFlag(ImmutableFlags::IsForEval); @@ -46,7 +49,7 @@ SharedContext::SharedContext(JSContext* cx, Kind kind, } // Note: This is a mix of transitive and non-transitive options. - const JS::ReadOnlyCompileOptions& options = compilationInfo.options; + const JS::ReadOnlyCompileOptions& options = compilationInfo.input.options; // Initialize the transitive "input" flags. These are applied to all // SharedContext in this compilation and generally cannot be determined from @@ -93,40 +96,9 @@ void ScopeContext::computeAllowSyntax(Scope* scope) { } } -void ScopeContext::computeThisBinding(Scope* scope, JSObject* environment) { - // If the scope-chain is non-syntactic, we may still determine a more precise - // effective-scope to use instead. - Scope* effectiveScope = scope; - - // If this eval is in response to Debugger.Frame.eval, we may have been - // passed an incomplete scope chain. In order to better determine the 'this' - // binding type, we traverse the environment chain, looking for a CallObject - // and recompute the binding type based on its body scope. - // - // NOTE: A non-debug eval in a non-syntactic environment will also trigger - // this code. In that case, we should still compute the same binding type. - if (environment && scope->hasOnChain(ScopeKind::NonSyntactic)) { - JSObject* env = environment; - while (env) { - // Look at target of any DebugEnvironmentProxy, but be sure to use - // enclosingEnvironment() of the proxy itself. - JSObject* unwrapped = env; - if (env->is()) { - unwrapped = &env->as().environment(); - } - - if (unwrapped->is()) { - JSFunction* callee = &unwrapped->as().callee(); - effectiveScope = callee->nonLazyScript()->bodyScope(); - break; - } - - env = env->enclosingEnvironment(); - } - } - +void ScopeContext::computeThisBinding(Scope* scope) { // Inspect the scope-chain. - for (ScopeIter si(effectiveScope); si; si++) { + for (ScopeIter si(scope); si; si++) { if (si.kind() == ScopeKind::Module) { thisBinding = ThisBinding::Module; return; @@ -165,6 +137,15 @@ void ScopeContext::computeInWith(Scope* scope) { } } +void ScopeContext::computeInClass(Scope* scope) { + for (ScopeIter si(scope); si; si++) { + if (si.kind() == ScopeKind::ClassBody) { + inClass = true; + break; + } + } +} + void ScopeContext::computeExternalInitializers(Scope* scope) { for (ScopeIter si(scope); si; si++) { if (si.scope()->is()) { @@ -177,9 +158,9 @@ void ScopeContext::computeExternalInitializers(Scope* scope) { } if (fun->isClassConstructor()) { - fieldInitializers = - mozilla::Some(fun->baseScript()->getFieldInitializers()); - MOZ_ASSERT(fieldInitializers->valid); + memberInitializers = + mozilla::Some(fun->baseScript()->getMemberInitializers()); + MOZ_ASSERT(memberInitializers->valid); } break; @@ -187,100 +168,97 @@ void ScopeContext::computeExternalInitializers(Scope* scope) { } } +/* static */ +Scope* ScopeContext::determineEffectiveScope(Scope* scope, + JSObject* environment) { + // If the scope-chain is non-syntactic, we may still determine a more precise + // effective-scope to use instead. + if (environment && scope->hasOnChain(ScopeKind::NonSyntactic)) { + JSObject* env = environment; + while (env) { + // Look at target of any DebugEnvironmentProxy, but be sure to use + // enclosingEnvironment() of the proxy itself. + JSObject* unwrapped = env; + if (env->is()) { + unwrapped = &env->as().environment(); + } + + if (unwrapped->is()) { + JSFunction* callee = &unwrapped->as().callee(); + return callee->nonLazyScript()->bodyScope(); + } + + env = env->enclosingEnvironment(); + } + } + + return scope; +} + +GlobalSharedContext::GlobalSharedContext(JSContext* cx, ScopeKind scopeKind, + CompilationInfo& compilationInfo, + Directives directives, + SourceExtent extent) + : SharedContext(cx, Kind::Global, compilationInfo, directives, extent), + scopeKind_(scopeKind), + bindings(nullptr) { + MOZ_ASSERT(scopeKind == ScopeKind::Global || + scopeKind == ScopeKind::NonSyntactic); + MOZ_ASSERT(thisBinding_ == ThisBinding::Global); +} + EvalSharedContext::EvalSharedContext(JSContext* cx, CompilationInfo& compilationInfo, - Scope* enclosingScope, - Directives directives, SourceExtent extent) - : SharedContext(cx, Kind::Eval, compilationInfo, directives, extent), - enclosingScope_(cx, enclosingScope), - bindings(cx) { + CompilationState& compilationState, + SourceExtent extent) + : SharedContext(cx, Kind::Eval, compilationInfo, + compilationState.directives, extent), + bindings(nullptr) { // Eval inherits syntax and binding rules from enclosing environment. - allowNewTarget_ = compilationInfo.scopeContext.allowNewTarget; - allowSuperProperty_ = compilationInfo.scopeContext.allowSuperProperty; - allowSuperCall_ = compilationInfo.scopeContext.allowSuperCall; - allowArguments_ = compilationInfo.scopeContext.allowArguments; - thisBinding_ = compilationInfo.scopeContext.thisBinding; - inWith_ = compilationInfo.scopeContext.inWith; + allowNewTarget_ = compilationState.scopeContext.allowNewTarget; + allowSuperProperty_ = compilationState.scopeContext.allowSuperProperty; + allowSuperCall_ = compilationState.scopeContext.allowSuperCall; + allowArguments_ = compilationState.scopeContext.allowArguments; + thisBinding_ = compilationState.scopeContext.thisBinding; + inWith_ = compilationState.scopeContext.inWith; } -#ifdef DEBUG -bool FunctionBox::atomsAreKept() { return cx_->zone()->hasKeptAtoms(); } -#endif - -FunctionBox::FunctionBox(JSContext* cx, FunctionBox* traceListHead, - SourceExtent extent, CompilationInfo& compilationInfo, +FunctionBox::FunctionBox(JSContext* cx, SourceExtent extent, + CompilationInfo& compilationInfo, + CompilationState& compilationState, Directives directives, GeneratorKind generatorKind, - FunctionAsyncKind asyncKind, JSAtom* atom, - FunctionFlags flags, size_t index) + FunctionAsyncKind asyncKind, const ParserAtom* atom, + FunctionFlags flags, FunctionIndex index, + TopLevelFunction isTopLevel) : SharedContext(cx, Kind::FunctionBox, compilationInfo, directives, extent), - traceLink_(traceListHead), atom_(atom), funcDataIndex_(index), - flags_(flags), + flags_(FunctionFlags::clearMutableflags(flags)), + isTopLevel_(isTopLevel), emitBytecode(false), - isStandalone(false), - wasEmitted(false), - isSingleton(false), + isStandalone_(false), + wasEmitted_(false), + isSingleton_(false), isAnnexB(false), useAsm(false), - isAsmJSModule_(false), hasParameterExprs(false), hasDestructuringArgs(false), hasDuplicateParameters(false), hasExprBody_(false), usesApply(false), usesThis(false), - usesReturn(false) { + usesReturn(false), + isFunctionFieldCopiedToStencil(false) { setFlag(ImmutableFlags::IsGenerator, generatorKind == GeneratorKind::Generator); setFlag(ImmutableFlags::IsAsync, asyncKind == FunctionAsyncKind::AsyncFunction); } -JSFunction* FunctionBox::createFunction(JSContext* cx) { - RootedObject proto(cx); - if (!GetFunctionPrototype(cx, generatorKind(), asyncKind(), &proto)) { - return nullptr; - } - - RootedAtom atom(cx, displayAtom()); - gc::AllocKind allocKind = flags_.isExtended() - ? gc::AllocKind::FUNCTION_EXTENDED - : gc::AllocKind::FUNCTION; - - JSNative maybeNative = isAsmJSModule() ? InstantiateAsmJS : nullptr; - - RootedFunction fun( - cx, NewFunctionWithProto(cx, maybeNative, nargs_, flags_, nullptr, atom, - proto, allocKind, TenuredObject)); - if (!fun) { - return nullptr; - } - - if (isAsmJSModule()) { - RefPtr asmJS = - compilationInfo_.asmJS.lookup(FunctionIndex(index()))->value(); - - JSObject* moduleObj = asmJS->createObjectForAsmJS(cx); - if (!moduleObj) { - return nullptr; - } - - fun->setExtendedSlot(FunctionExtended::ASMJS_MODULE_SLOT, - ObjectValue(*moduleObj)); - } - - return fun; -} - -bool FunctionBox::hasFunction() const { - return compilationInfo_.functions[funcDataIndex_] != nullptr; -} - void FunctionBox::initFromLazyFunction(JSFunction* fun) { BaseScript* lazy = fun->baseScript(); immutableFlags_ = lazy->immutableFlags(); - extent = lazy->extent(); + extent_ = lazy->extent(); } void FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing, @@ -333,15 +311,20 @@ void FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing, inWith_ = enclosing->findInnermostStatement(isWith); } -} -void FunctionBox::initWithEnclosingScope(ScopeContext& scopeContext, - Scope* enclosingScope, - FunctionFlags flags, - FunctionSyntaxKind kind) { - MOZ_ASSERT(enclosingScope); - enclosingScope_ = AbstractScopePtr(enclosingScope); + if (sc->inClass()) { + inClass_ = true; + } else { + auto isClass = [](ParseContext::Statement* stmt) { + return stmt->kind() == StatementKind::Class; + }; + + inClass_ = enclosing->findInnermostStatement(isClass); + } +} +void FunctionBox::initStandalone(ScopeContext& scopeContext, + FunctionFlags flags, FunctionSyntaxKind kind) { if (flags.isArrow()) { allowNewTarget_ = scopeContext.allowNewTarget; allowSuperProperty_ = scopeContext.allowSuperProperty; @@ -367,22 +350,24 @@ void FunctionBox::initWithEnclosingScope(ScopeContext& scopeContext, } inWith_ = scopeContext.inWith; + inClass_ = scopeContext.inClass; } -void FunctionBox::setEnclosingScopeForInnerLazyFunction( - const AbstractScopePtr& enclosingScope) { +void FunctionBox::setEnclosingScopeForInnerLazyFunction(ScopeIndex scopeIndex) { // For lazy functions inside a function which is being compiled, we cache // the incomplete scope object while compiling, and store it to the // BaseScript once the enclosing script successfully finishes compilation // in FunctionBox::finish. - MOZ_ASSERT(!enclosingScope_); - enclosingScope_ = enclosingScope; + MOZ_ASSERT(enclosingScopeIndex_.isNothing()); + enclosingScopeIndex_ = mozilla::Some(scopeIndex); + if (isFunctionFieldCopiedToStencil) { + copyUpdatedEnclosingScopeIndex(); + } } bool FunctionBox::setAsmJSModule(const JS::WasmModule* module) { - isAsmJSModule_ = true; + MOZ_ASSERT(!isFunctionFieldCopiedToStencil); - MOZ_ASSERT(!hasFunction()); MOZ_ASSERT(flags_.kind() == FunctionFlags::NormalFunction); // Update flags we will use to allocate the JSFunction. @@ -390,81 +375,107 @@ bool FunctionBox::setAsmJSModule(const JS::WasmModule* module) { flags_.setIsExtended(); flags_.setKind(FunctionFlags::AsmJS); - return compilationInfo_.asmJS.putNew(FunctionIndex(index()), module); + if (!compilationInfo_.stencil.asmJS.putNew(index(), module)) { + js::ReportOutOfMemory(cx_); + return false; + } + return true; } -void FunctionBox::finish() { - if (emitBytecode || isAsmJSModule()) { - // Non-lazy inner functions don't use the enclosingScope_ field. - MOZ_ASSERT(!enclosingScope_); - } else { - // Apply updates from FunctionEmitter::emitLazy(). - BaseScript* script = function()->baseScript(); +ModuleSharedContext::ModuleSharedContext(JSContext* cx, + CompilationInfo& compilationInfo, + ModuleBuilder& builder, + SourceExtent extent) + : SharedContext(cx, Kind::Module, compilationInfo, Directives(true), + extent), + bindings(nullptr), + builder(builder) { + thisBinding_ = ThisBinding::Module; + setFlag(ImmutableFlags::HasModuleGoal); +} - script->setEnclosingScope(enclosingScope_.getExistingScope()); - script->initTreatAsRunOnce(treatAsRunOnce()); +ScriptStencil& FunctionBox::functionStencil() const { + return compilationInfo_.stencil.scriptData[funcDataIndex_]; +} - if (fieldInitializers) { - script->setFieldInitializers(*fieldInitializers); - } - } +void SharedContext::copyScriptFields(ScriptStencil& script) { + MOZ_ASSERT(!isScriptFieldCopiedToStencil); - // Inferred and Guessed names are computed by BytecodeEmitter and so may need - // to be applied to existing JSFunctions during delazification. - if (function()->displayAtom() == nullptr) { - if (hasInferredName()) { - function()->setInferredName(atom_); - } + script.immutableFlags = immutableFlags_; + script.extent = extent_; - if (hasGuessedAtom()) { - function()->setGuessedAtom(atom_); - } - } + isScriptFieldCopiedToStencil = true; } -/* static */ -void FunctionBox::TraceList(JSTracer* trc, FunctionBox* listHead) { - for (FunctionBox* node = listHead; node; node = node->traceLink_) { - node->trace(trc); - } +void FunctionBox::finishScriptFlags() { + MOZ_ASSERT(!isScriptFieldCopiedToStencil); + + using ImmutableFlags = ImmutableScriptFlagsEnum; + immutableFlags_.setFlag(ImmutableFlags::HasMappedArgsObj, hasMappedArgsObj()); + immutableFlags_.setFlag(ImmutableFlags::IsLikelyConstructorWrapper, + isLikelyConstructorWrapper()); } -void FunctionBox::trace(JSTracer* trc) { - if (enclosingScope_) { - enclosingScope_.trace(trc); - } - if (atom_) { - TraceRoot(trc, &atom_, "funbox-atom"); - } +void FunctionBox::copyScriptFields(ScriptStencil& script) { + MOZ_ASSERT(&script == &functionStencil()); + MOZ_ASSERT(!isAsmJSModule()); + + SharedContext::copyScriptFields(script); + + script.memberInitializers = memberInitializers_; + + isScriptFieldCopiedToStencil = true; } -JSFunction* FunctionBox::function() const { - return compilationInfo_.functions[funcDataIndex_]; +void FunctionBox::copyFunctionFields(ScriptStencil& script) { + MOZ_ASSERT(&script == &functionStencil()); + MOZ_ASSERT(!isFunctionFieldCopiedToStencil); + + script.functionAtom = atom_; + script.functionFlags = flags_; + script.nargs = nargs_; + script.lazyFunctionEnclosingScopeIndex_ = enclosingScopeIndex_; + script.isStandaloneFunction = isStandalone_; + script.wasFunctionEmitted = wasEmitted_; + script.isSingletonFunction = isSingleton_; + + isFunctionFieldCopiedToStencil = true; } -void FunctionBox::clobberFunction(JSFunction* function) { - compilationInfo_.functions[funcDataIndex_].set(function); - // After clobbering, these flags need to be updated - setIsInterpreted(function->isInterpreted()); +void FunctionBox::copyUpdatedImmutableFlags() { + ScriptStencil& script = functionStencil(); + script.immutableFlags = immutableFlags_; } -ModuleSharedContext::ModuleSharedContext(JSContext* cx, ModuleObject* module, - CompilationInfo& compilationInfo, - Scope* enclosingScope, - ModuleBuilder& builder, - SourceExtent extent) - : SharedContext(cx, Kind::Module, compilationInfo, Directives(true), - extent), - module_(cx, module), - enclosingScope_(cx, enclosingScope), - bindings(cx), - builder(builder) { - thisBinding_ = ThisBinding::Module; - setFlag(ImmutableFlags::HasModuleGoal); +void FunctionBox::copyUpdatedExtent() { + ScriptStencil& script = functionStencil(); + script.extent = extent_; +} + +void FunctionBox::copyUpdatedMemberInitializers() { + ScriptStencil& script = functionStencil(); + script.memberInitializers = memberInitializers_; +} + +void FunctionBox::copyUpdatedEnclosingScopeIndex() { + ScriptStencil& script = functionStencil(); + script.lazyFunctionEnclosingScopeIndex_ = enclosingScopeIndex_; +} + +void FunctionBox::copyUpdatedAtomAndFlags() { + ScriptStencil& script = functionStencil(); + script.functionAtom = atom_; + script.functionFlags = flags_; +} + +void FunctionBox::copyUpdatedWasEmitted() { + ScriptStencil& script = functionStencil(); + script.wasFunctionEmitted = wasEmitted_; } -MutableHandle FunctionBox::functionStencil() const { - return compilationInfo_.funcData[funcDataIndex_]; +void FunctionBox::copyUpdatedIsSingleton() { + ScriptStencil& script = functionStencil(); + script.isSingletonFunction = isSingleton_; } } // namespace frontend diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index fb8240091a..86d3594580 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -11,10 +11,10 @@ #include "jstypes.h" -#include "frontend/AbstractScopePtr.h" +#include "frontend/AbstractScopePtr.h" // ScopeIndex #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind #include "frontend/ParseNode.h" -#include "frontend/Stencil.h" +#include "frontend/Stencil.h" // FunctionIndex #include "js/WasmModule.h" // JS::WasmModule #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind @@ -26,7 +26,10 @@ namespace js { namespace frontend { +struct CompilationInfo; +struct CompilationState; class ParseContext; +class ScriptStencil; struct ScopeContext; enum class StatementKind : uint8_t { @@ -104,14 +107,36 @@ class GlobalSharedContext; class EvalSharedContext; class ModuleSharedContext; -#define FLAG_GETTER_SETTER(enumName, enumEntry, lowerName, name) \ - public: \ - bool lowerName() const { return hasFlag(enumName::enumEntry); } \ - void set##name() { setFlag(enumName::enumEntry); } \ +using ParserBindingName = AbstractBindingName; +using ParserBindingIter = AbstractBindingIter; + +using BaseParserScopeData = AbstractBaseScopeData; + +template +using ParserScopeData = typename Scope::template AbstractData; + +using ParserGlobalScopeData = ParserScopeData; +using ParserEvalScopeData = ParserScopeData; +using ParserLexicalScopeData = ParserScopeData; +using ParserFunctionScopeData = ParserScopeData; +using ParserModuleScopeData = ParserScopeData; +using ParserVarScopeData = ParserScopeData; + +#define FLAG_GETTER(enumName, enumEntry, lowerName, name) \ + public: \ + bool lowerName() const { return hasFlag(enumName::enumEntry); } + +#define FLAG_SETTER(enumName, enumEntry, lowerName, name) \ + public: \ + void set##name() { setFlag(enumName::enumEntry); } \ void set##name(bool b) { setFlag(enumName::enumEntry, b); } #define IMMUTABLE_FLAG_GETTER_SETTER(lowerName, name) \ - FLAG_GETTER_SETTER(ImmutableFlags, name, lowerName, name) + FLAG_GETTER(ImmutableFlags, name, lowerName, name) \ + FLAG_SETTER(ImmutableFlags, name, lowerName, name) + +#define IMMUTABLE_FLAG_GETTER(lowerName, name) \ + FLAG_GETTER(ImmutableFlags, name, lowerName, name) /* * The struct SharedContext is part of the current parser context (see @@ -128,10 +153,11 @@ class SharedContext { // See: BaseScript::immutableFlags_ ImmutableScriptFlags immutableFlags_ = {}; - public: // The location of this script in the source. Note that the value here differs // from the final BaseScript for the case of standalone functions. - SourceExtent extent = {}; + // This field is copied to ScriptStencil, and shouldn't be modified after the + // copy. + SourceExtent extent_ = {}; protected: // See: ThisBinding @@ -144,6 +170,7 @@ class SharedContext { bool allowSuperCall_ : 1; bool allowArguments_ : 1; bool inWith_ : 1; + bool inClass_ : 1; // See `strict()` below. bool localStrict : 1; @@ -151,6 +178,15 @@ class SharedContext { // True if "use strict"; appears in the body instead of being inherited. bool hasExplicitUseStrict_ : 1; + // Tracks if script-related fields are already copied to ScriptStencil. + // + // If this field is true, those fileds shouldn't be modified. + // + // For FunctionBox, some fields are allowed to be modified, but the + // modification should be synced with ScriptStencil by + // FunctionBox::copyUpdated* methods. + bool isScriptFieldCopiedToStencil : 1; + // End of fields. enum class Kind : uint8_t { FunctionBox, Global, Eval, Module }; @@ -162,6 +198,7 @@ class SharedContext { return immutableFlags_.hasFlag(flag); } void setFlag(ImmutableFlags flag, bool b = true) { + MOZ_ASSERT(!isScriptFieldCopiedToStencil); immutableFlags_.setFlag(flag, b); } @@ -169,10 +206,6 @@ class SharedContext { SharedContext(JSContext* cx, Kind kind, CompilationInfo& compilationInfo, Directives directives, SourceExtent extent); - // If this is the outermost SharedContext, the Scope that encloses - // it. Otherwise nullptr. - virtual Scope* compilationEnclosingScope() const = 0; - IMMUTABLE_FLAG_GETTER_SETTER(isForEval, IsForEval) IMMUTABLE_FLAG_GETTER_SETTER(isModule, IsModule) IMMUTABLE_FLAG_GETTER_SETTER(isFunction, IsFunction) @@ -180,7 +213,7 @@ class SharedContext { IMMUTABLE_FLAG_GETTER_SETTER(forceStrict, ForceStrict) IMMUTABLE_FLAG_GETTER_SETTER(hasNonSyntacticScope, HasNonSyntacticScope) IMMUTABLE_FLAG_GETTER_SETTER(noScriptRval, NoScriptRval) - IMMUTABLE_FLAG_GETTER_SETTER(treatAsRunOnce, TreatAsRunOnce) + IMMUTABLE_FLAG_GETTER(treatAsRunOnce, TreatAsRunOnce) // Strict: custom logic below IMMUTABLE_FLAG_GETTER_SETTER(hasModuleGoal, HasModuleGoal) IMMUTABLE_FLAG_GETTER_SETTER(hasInnerFunctions, HasInnerFunctions) @@ -189,6 +222,8 @@ class SharedContext { BindingsAccessedDynamically) IMMUTABLE_FLAG_GETTER_SETTER(hasCallSiteObj, HasCallSiteObj) + const SourceExtent& extent() const { return extent_; } + bool isFunctionBox() const { return isFunction(); } inline FunctionBox* asFunctionBox(); bool isModuleContext() const { return isModule(); } @@ -219,6 +254,7 @@ class SharedContext { bool allowSuperCall() const { return allowSuperCall_; } bool allowArguments() const { return allowArguments_; } bool inWith() const { return inWith_; } + bool inClass() const { return inClass_; } bool hasExplicitUseStrict() const { return hasExplicitUseStrict_; } void setExplicitUseStrict() { hasExplicitUseStrict_ = true; } @@ -238,26 +274,23 @@ class SharedContext { localStrict = strict; return retVal; } + + inline JSAtom* liftParserAtomToJSAtom(JSContext* cx, + const ParserAtom* atomId); + inline const ParserAtom* lowerJSAtomToParserAtom(JSContext* cx, JSAtom* atom); + + void copyScriptFields(ScriptStencil& script); }; class MOZ_STACK_CLASS GlobalSharedContext : public SharedContext { ScopeKind scopeKind_; public: - Rooted bindings; + ParserGlobalScopeData* bindings; GlobalSharedContext(JSContext* cx, ScopeKind scopeKind, CompilationInfo& compilationInfo, Directives directives, - SourceExtent extent) - : SharedContext(cx, Kind::Global, compilationInfo, directives, extent), - scopeKind_(scopeKind), - bindings(cx) { - MOZ_ASSERT(scopeKind == ScopeKind::Global || - scopeKind == ScopeKind::NonSyntactic); - MOZ_ASSERT(thisBinding_ == ThisBinding::Global); - } - - Scope* compilationEnclosingScope() const override { return nullptr; } + SourceExtent extent); ScopeKind scopeKind() const { return scopeKind_; } }; @@ -268,16 +301,11 @@ inline GlobalSharedContext* SharedContext::asGlobalContext() { } class MOZ_STACK_CLASS EvalSharedContext : public SharedContext { - RootedScope enclosingScope_; - public: - Rooted bindings; + ParserEvalScopeData* bindings; EvalSharedContext(JSContext* cx, CompilationInfo& compilationInfo, - Scope* enclosingScope, Directives directives, - SourceExtent extent); - - Scope* compilationEnclosingScope() const override { return enclosingScope_; } + CompilationState& compilationState, SourceExtent extent); }; inline EvalSharedContext* SharedContext::asEvalContext() { @@ -295,47 +323,59 @@ class FunctionBox : public SharedContext { // list represented by |traceLink_|. FunctionBox* traceLink_ = nullptr; - // This field is used for two purposes: - // * If this FunctionBox refers to the function being compiled, this field - // holds its enclosing scope, used for compilation. - // * If this FunctionBox refers to a lazy child of the function being - // compiled, this field holds the child's immediately enclosing scope. - // Once compilation succeeds, we will store it in the child's - // BaseScript. (Debugger may become confused if lazy scripts refer to - // partially initialized enclosing scopes, so we must avoid storing the - // scope in the BaseScript until compilation has completed - // successfully.) - AbstractScopePtr enclosingScope_ = {}; + // If this FunctionBox refers to a lazy child of the function being + // compiled, this field holds the child's immediately enclosing scope's index. + // Once compilation succeeds, we will store the scope pointed by this in the + // child's BaseScript. (Debugger may become confused if lazy scripts refer to + // partially initialized enclosing scopes, so we must avoid storing the + // scope in the BaseScript until compilation has completed + // successfully.) + // This is copied to ScriptStencil. + // Any update after the copy should be synced to the ScriptStencil. + mozilla::Maybe enclosingScopeIndex_; // Names from the named lambda scope, if a named lambda. - LexicalScope::Data* namedLambdaBindings_ = nullptr; + ParserLexicalScopeData* namedLambdaBindings_ = nullptr; // Names from the function scope. - FunctionScope::Data* functionScopeBindings_ = nullptr; + ParserFunctionScopeData* functionScopeBindings_ = nullptr; // Names from the extra 'var' scope of the function, if the parameter list // has expressions. - VarScope::Data* extraVarScopeBindings_ = nullptr; + ParserVarScopeData* extraVarScopeBindings_ = nullptr; // The explicit or implicit name of the function. The FunctionFlags indicate // the kind of name. - JSAtom* atom_ = nullptr; + // This is copied to ScriptStencil. + // Any update after the copy should be synced to the ScriptStencil. + const ParserAtom* atom_ = nullptr; + + // Index into CompilationInfo::{funcData, functions}. + FunctionIndex funcDataIndex_ = FunctionIndex(-1); + + // See: FunctionFlags + // This is copied to ScriptStencil. + // Any update after the copy should be synced to the ScriptStencil. + FunctionFlags flags_ = {}; - // Index into CompilationInfo::funcData, which contains the function - // information, either a JSFunction* (for a FunctionBox representing a real - // function) or a ScriptStencilBase. - size_t funcDataIndex_ = (size_t)(-1); + // See: ImmutableScriptData::funLength + uint16_t length_ = 0; + + // JSFunction::nargs_ + // This field is copied to ScriptStencil, and shouldn't be modified after the + // copy. + uint16_t nargs_ = 0; + + // See: PrivateScriptData::memberInitializers_ + // This field is copied to ScriptStencil, and shouldn't be modified after the + // copy. + mozilla::Maybe memberInitializers_ = {}; public: // Back pointer used by asm.js for error messages. FunctionNode* functionNode = nullptr; - // See: PrivateScriptData::fieldInitializers_ - mozilla::Maybe fieldInitializers = {}; - - FunctionFlags flags_ = {}; // See: FunctionFlags - uint16_t length = 0; // See: ImmutableScriptData::funLength - uint16_t nargs_ = 0; // JSFunction::nargs_ + TopLevelFunction isTopLevel_ = TopLevelFunction::No; // True if bytecode will be emitted for this function in the current // compilation. @@ -343,23 +383,23 @@ class FunctionBox : public SharedContext { // This function is a standalone function that is not syntactically part of // another script. Eg. Created by `new Function("")`. - bool isStandalone : 1; + bool isStandalone_ : 1; // This is set by the BytecodeEmitter of the enclosing script when a reference // to this function is generated. This is also used to determine a hoisted // function already is referenced by the bytecode. - bool wasEmitted : 1; + bool wasEmitted_ : 1; // This function should be marked as a singleton. It is expected to be defined // at most once. This is a heuristic only and does not affect correctness. - bool isSingleton : 1; + bool isSingleton_ : 1; // Need to emit a synthesized Annex B assignment bool isAnnexB : 1; - // Track if we saw "use asm" and if we successfully validated. + // Track if we saw "use asm". + // If we successfully validated it, `flags_` is seto to `AsmJS` kind. bool useAsm : 1; - bool isAsmJSModule_ : 1; // Analysis of parameter list bool hasParameterExprs : 1; @@ -374,72 +414,77 @@ class FunctionBox : public SharedContext { bool usesThis : 1; // Contains 'this' bool usesReturn : 1; // Contains a 'return' statement + // Tracks if function-related fields are already copied to ScriptStencil. + // If this field is true, modification to those fields should be synced with + // ScriptStencil by copyUpdated* methods. + bool isFunctionFieldCopiedToStencil : 1; + // End of fields. - FunctionBox(JSContext* cx, FunctionBox* traceListHead, SourceExtent extent, - CompilationInfo& compilationInfo, Directives directives, + FunctionBox(JSContext* cx, SourceExtent extent, + CompilationInfo& compilationInfo, + CompilationState& compilationState, Directives directives, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, - JSAtom* explicitName, FunctionFlags flags, size_t index); - - JSFunction* createFunction(JSContext* cx); + const ParserAtom* atom, FunctionFlags flags, FunctionIndex index, + TopLevelFunction isTopLevel); - MutableHandle functionStencil() const; + ScriptStencil& functionStencil() const; - bool hasFunctionStencil() const; - bool hasFunction() const; - -#ifdef DEBUG - bool atomsAreKept(); -#endif - - MutableHandle namedLambdaBindings() { - MOZ_ASSERT(atomsAreKept()); - return MutableHandle::fromMarkedLocation( - &namedLambdaBindings_); + ParserLexicalScopeData* namedLambdaBindings() { return namedLambdaBindings_; } + void setNamedLambdaBindings(ParserLexicalScopeData* bindings) { + namedLambdaBindings_ = bindings; } - MutableHandle functionScopeBindings() { - MOZ_ASSERT(atomsAreKept()); - return MutableHandle::fromMarkedLocation( - &functionScopeBindings_); + ParserFunctionScopeData* functionScopeBindings() { + return functionScopeBindings_; + } + void setFunctionScopeBindings(ParserFunctionScopeData* bindings) { + functionScopeBindings_ = bindings; } - MutableHandle extraVarScopeBindings() { - MOZ_ASSERT(atomsAreKept()); - return MutableHandle::fromMarkedLocation( - &extraVarScopeBindings_); + ParserVarScopeData* extraVarScopeBindings() { return extraVarScopeBindings_; } + void setExtraVarScopeBindings(ParserVarScopeData* bindings) { + extraVarScopeBindings_ = bindings; } void initFromLazyFunction(JSFunction* fun); - void initWithEnclosingScope(ScopeContext& scopeContext, Scope* enclosingScope, - FunctionFlags flags, FunctionSyntaxKind kind); + void initStandalone(ScopeContext& scopeContext, FunctionFlags flags, + FunctionSyntaxKind kind); void initWithEnclosingParseContext(ParseContext* enclosing, FunctionFlags flags, FunctionSyntaxKind kind); - void setEnclosingScopeForInnerLazyFunction( - const AbstractScopePtr& enclosingScope); - void finish(); + void setEnclosingScopeForInnerLazyFunction(ScopeIndex scopeIndex); - JSFunction* function() const; - - // Initialize FunctionBox with a deferred allocation Function - void initializeFunction(JSFunction* fun) { clobberFunction(fun); } + bool isStandalone() const { return isStandalone_; } + void setIsStandalone(bool isStandalone) { + MOZ_ASSERT(!isFunctionFieldCopiedToStencil); + isStandalone_ = isStandalone; + } - MOZ_MUST_USE bool setAsmJSModule(const JS::WasmModule* module); - bool isAsmJSModule() { return isAsmJSModule_; } + bool wasEmitted() const { return wasEmitted_; } + void setWasEmitted(bool wasEmitted) { + wasEmitted_ = wasEmitted; + if (isFunctionFieldCopiedToStencil) { + copyUpdatedWasEmitted(); + } + } - void clobberFunction(JSFunction* function); + bool isSingleton() const { return isSingleton_; } + void setIsSingleton(bool isSingleton) { + isSingleton_ = isSingleton; + if (isFunctionFieldCopiedToStencil) { + copyUpdatedIsSingleton(); + } + } - Scope* compilationEnclosingScope() const override { - // This is used when emitting code for the current FunctionBox and therefore - // the enclosingScope_ must have be set correctly during initalization. + MOZ_MUST_USE bool setAsmJSModule(const JS::WasmModule* module); + bool isAsmJSModule() const { return flags_.isAsmJSNative(); } - MOZ_ASSERT(enclosingScope_); - return enclosingScope_.scope(); - } + bool hasEnclosingScopeIndex() const { return enclosingScopeIndex_.isSome(); } + ScopeIndex getEnclosingScopeIndex() const { return *enclosingScopeIndex_; } IMMUTABLE_FLAG_GETTER_SETTER(isAsync, IsAsync) IMMUTABLE_FLAG_GETTER_SETTER(isGenerator, IsGenerator) @@ -510,30 +555,33 @@ class FunctionBox : public SharedContext { bool isClassConstructor() const { return flags_.isClassConstructor(); } bool isInterpreted() const { return flags_.hasBaseScript(); } - void setIsInterpreted(bool interpreted) { - flags_.setFlags(FunctionFlags::BASESCRIPT, interpreted); - } FunctionFlags::FunctionKind kind() { return flags_.kind(); } bool hasInferredName() const { return flags_.hasInferredName(); } bool hasGuessedAtom() const { return flags_.hasGuessedAtom(); } - JSAtom* displayAtom() const { return atom_; } - JSAtom* explicitName() const { + const ParserAtom* displayAtom() const { return atom_; } + const ParserAtom* explicitName() const { return (hasInferredName() || hasGuessedAtom()) ? nullptr : atom_; } // NOTE: We propagate to any existing functions for now. This handles both the // delazification case where functions already exist, and also handles // code-coverage which is not yet deferred. - void setInferredName(JSAtom* atom) { + void setInferredName(const ParserAtom* atom) { atom_ = atom; flags_.setInferredName(); + if (isFunctionFieldCopiedToStencil) { + copyUpdatedAtomAndFlags(); + } } - void setGuessedAtom(JSAtom* atom) { + void setGuessedAtom(const ParserAtom* atom) { atom_ = atom; flags_.setGuessedAtom(); + if (isFunctionFieldCopiedToStencil) { + copyUpdatedAtomAndFlags(); + } } void setAlwaysNeedsArgsObj() { @@ -565,6 +613,13 @@ class FunctionBox : public SharedContext { setFlag(ImmutableFlags::IsFieldInitializer); } + void setTreatAsRunOnce(bool treatAsRunOnce) { + immutableFlags_.setFlag(ImmutableFlags::TreatAsRunOnce, treatAsRunOnce); + if (isScriptFieldCopiedToStencil) { + copyUpdatedImmutableFlags(); + } + } + bool hasSimpleParameterList() const { return !hasRest() && !hasParameterExprs && !hasDestructuringArgs; } @@ -590,30 +645,96 @@ class FunctionBox : public SharedContext { bool useAsmOrInsideUseAsm() const { return useAsm; } void setStart(uint32_t offset, uint32_t line, uint32_t column) { - extent.sourceStart = offset; - extent.lineno = line; - extent.column = column; + MOZ_ASSERT(!isScriptFieldCopiedToStencil); + extent_.sourceStart = offset; + extent_.lineno = line; + extent_.column = column; } void setEnd(uint32_t end) { + MOZ_ASSERT(!isScriptFieldCopiedToStencil); // For all functions except class constructors, the buffer and // toString ending positions are the same. Class constructors override // the toString ending position with the end of the class definition. - extent.sourceEnd = end; - extent.toStringEnd = end; + extent_.sourceEnd = end; + extent_.toStringEnd = end; } - void setArgCount(uint16_t args) { nargs_ = args; } + void setCtorToStringEnd(uint32_t end) { + extent_.toStringEnd = end; + if (isScriptFieldCopiedToStencil) { + copyUpdatedExtent(); + } + } - size_t nargs() { return nargs_; } + void setCtorFunctionHasThisBinding() { + immutableFlags_.setFlag(ImmutableFlags::FunctionHasThisBinding, true); + if (isScriptFieldCopiedToStencil) { + copyUpdatedImmutableFlags(); + } + } - size_t index() { return funcDataIndex_; } + uint16_t length() { return length_; } + void setLength(uint16_t length) { length_ = length; } - void trace(JSTracer* trc); + void setArgCount(uint16_t args) { + MOZ_ASSERT(!isFunctionFieldCopiedToStencil); + nargs_ = args; + } - static void TraceList(JSTracer* trc, FunctionBox* listHead); + size_t nargs() { return nargs_; } + + bool hasMemberInitializers() const { return memberInitializers_.isSome(); } + const MemberInitializers& memberInitializers() const { + return *memberInitializers_; + } + void setMemberInitializers(MemberInitializers memberInitializers) { + MOZ_ASSERT(memberInitializers_.isNothing()); + memberInitializers_ = mozilla::Some(memberInitializers); + if (isScriptFieldCopiedToStencil) { + copyUpdatedMemberInitializers(); + } + } + + FunctionIndex index() { return funcDataIndex_; } FunctionBox* traceLink() { return traceLink_; } + + void finishScriptFlags(); + void copyScriptFields(ScriptStencil& script); + void copyFunctionFields(ScriptStencil& script); + + // * setTreatAsRunOnce can be called to a lazy function, while emitting + // enclosing script + // * setCtorFunctionHasThisBinding can be called to a class constructor + // with a lazy function, while parsing enclosing class + void copyUpdatedImmutableFlags(); + + // * setCtorToStringEnd bcan be called to a class constructor with a lazy + // function, while parsing enclosing class + void copyUpdatedExtent(); + + // * setMemberInitializers can be called to a class constructor with a lazy + // function, while emitting enclosing script + void copyUpdatedMemberInitializers(); + + // * setEnclosingScopeForInnerLazyFunction can be called to a lazy function, + // while emitting enclosing script + void copyUpdatedEnclosingScopeIndex(); + + // * setInferredName can be called to a lazy function, while emitting + // enclosing script + // * setGuessedAtom can be called to both lazy/non-lazy functions, + // while running NameFunctions + void copyUpdatedAtomAndFlags(); + + // * setWasEmitted can be called to a lazy function, while emitting + // enclosing script + void copyUpdatedWasEmitted(); + + // * setIsSingleton can be called to a lazy function, while emitting + // enclosing script + void copyUpdatedIsSingleton(); }; #undef FLAG_GETTER_SETTER diff --git a/js/src/frontend/Stencil.cpp b/js/src/frontend/Stencil.cpp index d88286dcca..14fa7f1963 100644 --- a/js/src/frontend/Stencil.cpp +++ b/js/src/frontend/Stencil.cpp @@ -4,68 +4,51 @@ #include "frontend/Stencil.h" -#include "frontend/CompilationInfo.h" +#include "mozilla/RefPtr.h" // RefPtr + +#include "frontend/AbstractScopePtr.h" // ScopeIndex +#include "frontend/BytecodeSection.h" // EmitScriptThingsVector +#include "frontend/CompilationInfo.h" // CompilationInfo #include "frontend/SharedContext.h" -#include "js/TracingAPI.h" +#include "gc/AllocKind.h" // gc::AllocKind +#include "js/CallArgs.h" // JSNative +#include "js/RootingAPI.h" // Rooted +#include "js/Value.h" // ObjectValue +#include "js/WasmModule.h" // JS::WasmModule #include "vm/EnvironmentObject.h" -#include "vm/JSContext.h" -#include "vm/Scope.h" -#include "vm/StringType.h" +#include "vm/GeneratorAndAsyncKind.h" // GeneratorKind, FunctionAsyncKind +#include "vm/JSContext.h" // JSContext +#include "vm/JSFunction.h" // JSFunction, GetFunctionPrototype, NewFunctionWithProto +#include "vm/JSObject.h" // JSObject +#include "vm/JSONPrinter.h" // js::JSONPrinter +#include "vm/JSScript.h" // BaseScript, JSScript +#include "vm/ObjectGroup.h" // TenuredObject +#include "vm/Printer.h" // js::Fprinter +#include "vm/Scope.h" // Scope, ScopeKindString +#include "vm/StencilEnums.h" // ImmutableScriptFlagsEnum +#include "vm/StringType.h" // JSAtom, js::CopyChars +#include "wasm/AsmJS.h" // InstantiateAsmJS +#include "wasm/WasmModule.h" // wasm::Module using namespace js; using namespace js::frontend; -bool frontend::RegExpCreationData::init(JSContext* cx, JSAtom* pattern, - JS::RegExpFlags flags) { - length_ = pattern->length(); - buf_ = cx->make_pod_array(length_); - if (!buf_) { - return false; +AbstractScopePtr ScopeStencil::enclosing(CompilationInfo& compilationInfo) { + if (enclosing_) { + return AbstractScopePtr(compilationInfo, *enclosing_); } - js::CopyChars(buf_.get(), *pattern); - flags_ = flags; - return true; -} - -bool frontend::EnvironmentShapeCreationData::createShape( - JSContext* cx, MutableHandleShape shape) { - struct Matcher { - JSContext* cx; - MutableHandleShape& shape; - - bool operator()(CreateEnvShapeData& data) { - shape.set(CreateEnvironmentShape(cx, data.freshBi, data.cls, - data.nextEnvironmentSlot, - data.baseShapeFlags)); - return shape; - } - - bool operator()(EmptyEnvShapeData& data) { - shape.set(EmptyEnvironmentShape(cx, data.cls, JSSLOT_FREE(data.cls), - data.baseShapeFlags)); - return shape; - } - - bool operator()(mozilla::Nothing&) { - shape.set(nullptr); - return true; - } - }; - Matcher m{cx, shape}; - return data_.match(m); + return AbstractScopePtr(compilationInfo.input.enclosingScope); } -Scope* ScopeCreationData::createScope(JSContext* cx) { - // If we've already created a scope, best just return it. - if (scope_) { - return scope_; - } - +Scope* ScopeStencil::createScope(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { Scope* scope = nullptr; switch (kind()) { case ScopeKind::Function: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::Lexical: @@ -73,95 +56,48 @@ Scope* ScopeCreationData::createScope(JSContext* cx) { case ScopeKind::Catch: case ScopeKind::NamedLambda: case ScopeKind::StrictNamedLambda: - case ScopeKind::FunctionLexical: { - scope = createSpecificScope(cx); + case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: { + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::FunctionBodyVar: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::Global: case ScopeKind::NonSyntactic: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::Eval: case ScopeKind::StrictEval: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::Module: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } case ScopeKind::With: { - scope = createSpecificScope(cx); + scope = createSpecificScope( + cx, compilationInfo, gcOutput); break; } - default: { + case ScopeKind::WasmFunction: + case ScopeKind::WasmInstance: { MOZ_CRASH("Unexpected deferred type"); } } return scope; } -void ScopeCreationData::trace(JSTracer* trc) { - if (enclosing_) { - enclosing_.trace(trc); - } - - environmentShape_.trace(trc); - - if (scope_) { - TraceEdge(trc, &scope_, "ScopeCreationData Scope"); - } - if (funbox_) { - funbox_->trace(trc); - } - - // Trace Datas - if (data_) { - switch (kind()) { - case ScopeKind::Function: { - data().trace(trc); - break; - } - case ScopeKind::Lexical: - case ScopeKind::SimpleCatch: - case ScopeKind::Catch: - case ScopeKind::NamedLambda: - case ScopeKind::StrictNamedLambda: - case ScopeKind::FunctionLexical: { - data().trace(trc); - break; - } - case ScopeKind::FunctionBodyVar: { - data().trace(trc); - break; - } - case ScopeKind::Global: - case ScopeKind::NonSyntactic: { - data().trace(trc); - break; - } - case ScopeKind::Eval: - case ScopeKind::StrictEval: { - data().trace(trc); - break; - } - case ScopeKind::Module: { - data().trace(trc); - break; - } - case ScopeKind::With: - default: - MOZ_CRASH("Unexpected data type"); - } - } -} - -uint32_t ScopeCreationData::nextFrameSlot() const { +uint32_t ScopeStencil::nextFrameSlot() const { switch (kind()) { case ScopeKind::Function: return nextFrameSlot(); @@ -171,6 +107,7 @@ uint32_t ScopeCreationData::nextFrameSlot() const { case ScopeKind::SimpleCatch: case ScopeKind::Catch: case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: return nextFrameSlot(); case ScopeKind::NamedLambda: case ScopeKind::StrictNamedLambda: @@ -195,14 +132,1132 @@ uint32_t ScopeCreationData::nextFrameSlot() const { MOZ_CRASH("Not an enclosing intra-frame scope"); } -bool ScopeCreationData::isArrow() const { return funbox_->isArrow(); } +static bool CreateLazyScript(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput, + ScriptStencil& script, HandleFunction function) { + const ScriptThingsVector& gcthings = script.gcThings; + + Rooted lazy( + cx, BaseScript::CreateRawLazy(cx, gcthings.length(), function, + gcOutput.sourceObject, script.extent, + script.immutableFlags)); + if (!lazy) { + return false; + } + + if (!EmitScriptThingsVector(cx, compilationInfo, gcOutput, gcthings, + lazy->gcthingsForInit())) { + return false; + } + + function->initScript(lazy); + + return true; +} + +static JSFunction* CreateFunction(JSContext* cx, + CompilationInfo& compilationInfo, + ScriptStencil& script, + FunctionIndex functionIndex) { + GeneratorKind generatorKind = + script.immutableFlags.hasFlag(ImmutableScriptFlagsEnum::IsGenerator) + ? GeneratorKind::Generator + : GeneratorKind::NotGenerator; + FunctionAsyncKind asyncKind = + script.immutableFlags.hasFlag(ImmutableScriptFlagsEnum::IsAsync) + ? FunctionAsyncKind::AsyncFunction + : FunctionAsyncKind::SyncFunction; + + // Determine the new function's proto. This must be done for singleton + // functions. + RootedObject proto(cx); + if (!GetFunctionPrototype(cx, generatorKind, asyncKind, &proto)) { + return nullptr; + } + + gc::AllocKind allocKind = script.functionFlags.isExtended() + ? gc::AllocKind::FUNCTION_EXTENDED + : gc::AllocKind::FUNCTION; + bool isAsmJS = script.functionFlags.isAsmJSNative(); + + JSNative maybeNative = isAsmJS ? InstantiateAsmJS : nullptr; -void ScriptStencil::trace(JSTracer* trc) { - for (ScriptThingVariant& thing : gcThings) { - if (thing.is()) { - JSAtom* atom = thing.as(); - TraceRoot(trc, &atom, "script-atom"); - MOZ_ASSERT(atom == thing.as(), "Atoms should be unmovable"); + RootedAtom displayAtom(cx); + if (script.functionAtom) { + displayAtom.set( + compilationInfo.liftParserAtomToJSAtom(cx, script.functionAtom)); + if (!displayAtom) { + return nullptr; } } + RootedFunction fun( + cx, NewFunctionWithProto(cx, maybeNative, script.nargs, + script.functionFlags, nullptr, displayAtom, + proto, allocKind, TenuredObject)); + if (!fun) { + return nullptr; + } + + if (isAsmJS) { + RefPtr asmJS = + compilationInfo.stencil.asmJS.lookup(functionIndex)->value(); + + JSObject* moduleObj = asmJS->createObjectForAsmJS(cx); + if (!moduleObj) { + return nullptr; + } + + fun->setExtendedSlot(FunctionExtended::ASMJS_MODULE_SLOT, + ObjectValue(*moduleObj)); + } + + return fun; +} + +static bool InstantiateScriptSourceObject(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + MOZ_ASSERT(compilationInfo.input.source()); + + gcOutput.sourceObject = + ScriptSourceObject::create(cx, compilationInfo.input.source()); + if (!gcOutput.sourceObject) { + return false; + } + + // Off-thread compilations do all their GC heap allocation, including the + // SSO, in a temporary compartment. Hence, for the SSO to refer to the + // gc-heap-allocated values in |options|, it would need cross-compartment + // wrappers from the temporary compartment to the real compartment --- which + // would then be inappropriate once we merged the temporary and real + // compartments. + // + // Instead, we put off populating those SSO slots in off-thread compilations + // until after we've merged compartments. + if (!cx->isHelperThreadContext()) { + if (!ScriptSourceObject::initFromOptions(cx, gcOutput.sourceObject, + compilationInfo.input.options)) { + return false; + } + } + + return true; +} + +// Instantiate ModuleObject if this is a module compile. +static bool MaybeInstantiateModule(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + if (compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex] + .isModule()) { + gcOutput.module = ModuleObject::create(cx); + if (!gcOutput.module) { + return false; + } + + if (!compilationInfo.stencil.moduleMetadata.initModule(cx, compilationInfo, + gcOutput.module)) { + return false; + } + } + + return true; +} + +// Instantiate JSFunctions for each FunctionBox. +static bool InstantiateFunctions(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + for (auto item : compilationInfo.functionScriptStencils(gcOutput)) { + auto& scriptStencil = item.script; + auto functionIndex = item.functionIndex; + + MOZ_ASSERT(!item.function); + + RootedFunction fun( + cx, CreateFunction(cx, compilationInfo, scriptStencil, functionIndex)); + if (!fun) { + return false; + } + gcOutput.functions[functionIndex].set(fun); + } + + return true; +} + +// Instantiate Scope for each ScopeStencil. +// +// This should be called after InstantiateFunctions, given FunctionScope needs +// associated JSFunction pointer, and also should be called before +// InstantiateScriptStencils, given JSScript needs Scope pointer in gc things. +static bool InstantiateScopes(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + // While allocating Scope object from ScopeStencil, Scope object for the + // enclosing Scope should already be allocated. + // + // Enclosing scope of ScopeStencil can be either ScopeStencil or Scope* + // pointer, capsulated by AbstractScopePtr. + // + // If the enclosing scope is ScopeStencil, it's guaranteed to be earlier + // element in compilationInfo.scopeData, because AbstractScopePtr holds index + // into it, and newly created ScopeStencil is pushed back to the vector. + + if (!gcOutput.scopes.reserve(compilationInfo.stencil.scopeData.length())) { + return false; + } + + for (auto& scd : compilationInfo.stencil.scopeData) { + Scope* scope = scd.createScope(cx, compilationInfo, gcOutput); + if (!scope) { + return false; + } + gcOutput.scopes.infallibleAppend(scope); + } + + return true; +} + +// JSFunctions have a default ObjectGroup when they are created. Once their +// enclosing script is compiled, we have more precise heuristic information and +// now compute their final group. These functions have not been exposed to +// script before this point. +// +// As well, anonymous functions may have either an "inferred" or a "guessed" +// name assigned to them. This name isn't known until the enclosing function is +// compiled so we must update it here. +static bool SetTypeAndNameForExposedFunctions(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + for (auto item : compilationInfo.functionScriptStencils(gcOutput)) { + auto& scriptStencil = item.script; + auto& fun = item.function; + if (!scriptStencil.functionFlags.hasBaseScript()) { + continue; + } + + // If the function was not referenced by enclosing script's bytecode, we do + // not generate a BaseScript for it. For example, `(function(){});`. + if (!scriptStencil.wasFunctionEmitted && + !scriptStencil.isStandaloneFunction) { + continue; + } + + if (!JSFunction::setTypeForScriptedFunction( + cx, fun, scriptStencil.isSingletonFunction)) { + return false; + } + + // Inferred and Guessed names are computed by BytecodeEmitter and so may + // need to be applied to existing JSFunctions during delazification. + if (fun->displayAtom() == nullptr) { + JSAtom* funcAtom = nullptr; + if (scriptStencil.functionFlags.hasInferredName() || + scriptStencil.functionFlags.hasGuessedAtom()) { + funcAtom = compilationInfo.liftParserAtomToJSAtom( + cx, scriptStencil.functionAtom); + if (!funcAtom) { + return false; + } + } + if (scriptStencil.functionFlags.hasInferredName()) { + fun->setInferredName(funcAtom); + } + + if (scriptStencil.functionFlags.hasGuessedAtom()) { + fun->setGuessedAtom(funcAtom); + } + } + } + + return true; +} + +// Instantiate js::BaseScripts from ScriptStencils for inner functions of the +// compilation. Note that standalone functions and functions being delazified +// are handled below with other top-levels. +static bool InstantiateScriptStencils(JSContext* cx, + CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + for (auto item : compilationInfo.functionScriptStencils(gcOutput)) { + auto& scriptStencil = item.script; + auto& fun = item.function; + if (scriptStencil.immutableScriptData) { + // If the function was not referenced by enclosing script's bytecode, we + // do not generate a BaseScript for it. For example, `(function(){});`. + if (!scriptStencil.wasFunctionEmitted) { + continue; + } + + RootedScript script(cx, + JSScript::fromStencil(cx, compilationInfo, gcOutput, + scriptStencil, fun)); + if (!script) { + return false; + } + } else if (scriptStencil.functionFlags.isAsmJSNative()) { + MOZ_ASSERT(fun->isAsmJSNative()); + } else if (fun->isIncomplete()) { + // Lazy functions are generally only allocated in the initial parse. + MOZ_ASSERT(compilationInfo.input.lazy == nullptr); + + if (!CreateLazyScript(cx, compilationInfo, gcOutput, scriptStencil, + fun)) { + return false; + } + } + } + + return true; +} + +// Instantiate the Stencil for the top-level script of the compilation. This +// includes standalone functions and functions being delazified. +static bool InstantiateTopLevel(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + ScriptStencil& script = + compilationInfo.stencil.scriptData[CompilationInfo::TopLevelIndex]; + RootedFunction fun(cx); + if (script.isFunction()) { + fun = gcOutput.functions[CompilationInfo::TopLevelIndex]; + } + + // Top-level asm.js does not generate a JSScript. + if (script.functionFlags.isAsmJSNative()) { + return true; + } + + MOZ_ASSERT(script.immutableScriptData); + + if (compilationInfo.input.lazy) { + gcOutput.script = JSScript::CastFromLazy(compilationInfo.input.lazy); + return JSScript::fullyInitFromStencil(cx, compilationInfo, gcOutput, + gcOutput.script, script, fun); + } + + gcOutput.script = + JSScript::fromStencil(cx, compilationInfo, gcOutput, script, fun); + if (!gcOutput.script) { + return false; + } + + // Finish initializing the ModuleObject if needed. + if (script.isModule()) { + gcOutput.module->initScriptSlots(gcOutput.script); + gcOutput.module->initStatusSlot(); + + if (!ModuleObject::createEnvironment(cx, gcOutput.module)) { + return false; + } + + // Off-thread compilation with parseGlobal will freeze the module object + // in GlobalHelperThreadState::finishModuleParseTask instead + if (!cx->isHelperThreadContext()) { + if (!ModuleObject::Freeze(cx, gcOutput.module)) { + return false; + } + } + } + + return true; +} + +// When a function is first referenced by enclosing script's bytecode, we need +// to update it with information determined by the BytecodeEmitter. This applies +// to both initial and delazification parses. The functions being update may or +// may not have bytecode at this point. +static void UpdateEmittedInnerFunctions(CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + for (auto item : compilationInfo.functionScriptStencils(gcOutput)) { + auto& scriptStencil = item.script; + auto& fun = item.function; + if (!scriptStencil.wasFunctionEmitted) { + continue; + } + + if (scriptStencil.functionFlags.isAsmJSNative() || + fun->baseScript()->hasBytecode()) { + // Non-lazy inner functions don't use the enclosingScope_ field. + MOZ_ASSERT(scriptStencil.lazyFunctionEnclosingScopeIndex_.isNothing()); + } else { + // Apply updates from FunctionEmitter::emitLazy(). + BaseScript* script = fun->baseScript(); + + ScopeIndex index = *scriptStencil.lazyFunctionEnclosingScopeIndex_; + Scope* scope = gcOutput.scopes[index].get(); + script->setEnclosingScope(scope); + script->initTreatAsRunOnce(scriptStencil.immutableFlags.hasFlag( + ImmutableScriptFlagsEnum::TreatAsRunOnce)); + + if (scriptStencil.memberInitializers) { + script->setMemberInitializers(*scriptStencil.memberInitializers); + } + } + } +} + +// During initial parse we must link lazy-functions-inside-lazy-functions to +// their enclosing script. +static void LinkEnclosingLazyScript(CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + for (auto item : compilationInfo.functionScriptStencils(gcOutput)) { + auto& scriptStencil = item.script; + auto& fun = item.function; + if (!scriptStencil.functionFlags.hasBaseScript()) { + continue; + } + + if (fun->baseScript()->hasBytecode()) { + continue; + } + + BaseScript* script = fun->baseScript(); + MOZ_ASSERT(!script->hasBytecode()); + + for (auto inner : script->gcthings()) { + if (!inner.is()) { + continue; + } + inner.as().as().setEnclosingLazyScript(script); + } + } +} + +// When delazifying, use the existing JSFunctions. The initial and delazifying +// parse are required to generate the same sequence of functions for lazy +// parsing to work at all. +static void FunctionsFromExistingLazy(CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput) { + MOZ_ASSERT(compilationInfo.input.lazy); + + size_t idx = 0; + gcOutput.functions[idx++].set(compilationInfo.input.lazy->function()); + + for (JS::GCCellPtr elem : compilationInfo.input.lazy->gcthings()) { + if (!elem.is()) { + continue; + } + gcOutput.functions[idx++].set(&elem.as().as()); + } + + MOZ_ASSERT(idx == gcOutput.functions.length()); +} + +bool CompilationInfo::instantiateStencils(JSContext* cx, + CompilationGCOutput& gcOutput) { + if (!gcOutput.functions.resize(stencil.scriptData.length())) { + return false; + } + + if (stencil.scriptData[CompilationInfo::TopLevelIndex].isModule()) { + MOZ_ASSERT(input.enclosingScope == nullptr); + input.enclosingScope = &cx->global()->emptyGlobalScope(); + MOZ_ASSERT(input.enclosingScope->environmentChainLength() == + ModuleScope::EnclosingEnvironmentChainLength); + } + + if (input.lazy) { + FunctionsFromExistingLazy(*this, gcOutput); + } else { + if (!InstantiateScriptSourceObject(cx, *this, gcOutput)) { + return false; + } + + if (!MaybeInstantiateModule(cx, *this, gcOutput)) { + return false; + } + + if (!InstantiateFunctions(cx, *this, gcOutput)) { + return false; + } + } + + if (!InstantiateScopes(cx, *this, gcOutput)) { + return false; + } + + if (!SetTypeAndNameForExposedFunctions(cx, *this, gcOutput)) { + return false; + } + + if (!InstantiateScriptStencils(cx, *this, gcOutput)) { + return false; + } + + if (!InstantiateTopLevel(cx, *this, gcOutput)) { + return false; + } + + // Must be infallible from here forward. + + UpdateEmittedInnerFunctions(*this, gcOutput); + + if (input.lazy == nullptr) { + LinkEnclosingLazyScript(*this, gcOutput); + } + + return true; +} + +#if defined(DEBUG) || defined(JS_JITSPEW) + +void RegExpStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); } + +void RegExpStencil::dump(js::JSONPrinter& json) { + GenericPrinter& out = json.beginString(); + + out.put("/"); + for (size_t i = 0; i < length_; i++) { + char16_t c = buf_[i]; + if (c == '\n') { + out.put("\\n"); + } else if (c == '\t') { + out.put("\\t"); + } else if (c >= 32 && c < 127) { + out.putChar(char(buf_[i])); + } else if (c <= 255) { + out.printf("\\x%02x", unsigned(c)); + } else { + out.printf("\\u%04x", unsigned(c)); + } + } + out.put("/"); + + if (flags_.global()) { + out.put("g"); + } + if (flags_.ignoreCase()) { + out.put("i"); + } + if (flags_.multiline()) { + out.put("m"); + } + if (flags_.dotAll()) { + out.put("s"); + } + if (flags_.unicode()) { + out.put("u"); + } + if (flags_.sticky()) { + out.put("y"); + } + + json.endString(); +} + +void BigIntStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void BigIntStencil::dump(js::JSONPrinter& json) { + GenericPrinter& out = json.beginString(); + + for (size_t i = 0; i < length_; i++) { + out.putChar(char(buf_[i])); + } + + json.endString(); +} + +void ScopeStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void ScopeStencil::dump(js::JSONPrinter& json) { + json.beginObject(); + dumpFields(json); + json.endObject(); +} + +void ScopeStencil::dumpFields(js::JSONPrinter& json) { + if (enclosing_) { + json.formatProperty("enclosing", "Some(ScopeIndex(%zu))", + size_t(*enclosing_)); + } else { + json.property("enclosing", "Nothing"); + } + + json.property("kind", ScopeKindString(kind_)); + + json.property("firstFrameSlot", firstFrameSlot_); + + if (numEnvironmentSlots_) { + json.formatProperty("numEnvironmentSlots", "Some(%zu)", + size_t(*numEnvironmentSlots_)); + } else { + json.property("numEnvironmentSlots", "Nothing"); + } + + if (kind_ == ScopeKind::Function) { + if (functionIndex_.isSome()) { + json.formatProperty("functionIndex", "FunctionIndex(%zu)", + size_t(*functionIndex_)); + } else { + json.property("functionIndex", "Nothing"); + } + + json.boolProperty("isArrow", isArrow_); + } + + json.beginObjectProperty("data"); + + AbstractTrailingNamesArray* trailingNames = nullptr; + uint32_t length = 0; + + switch (kind_) { + case ScopeKind::Function: { + auto* data = static_cast(data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + json.property("hasParameterExprs", data->hasParameterExprs); + json.property("nonPositionalFormalStart", data->nonPositionalFormalStart); + json.property("varStart", data->varStart); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::FunctionBodyVar: { + auto* data = static_cast(data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::Lexical: + case ScopeKind::SimpleCatch: + case ScopeKind::Catch: + case ScopeKind::NamedLambda: + case ScopeKind::StrictNamedLambda: + case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: { + auto* data = static_cast(data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + json.property("constStart", data->constStart); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::With: { + break; + } + + case ScopeKind::Eval: + case ScopeKind::StrictEval: { + auto* data = static_cast(data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::Global: + case ScopeKind::NonSyntactic: { + auto* data = static_cast(data_.get()); + json.property("letStart", data->letStart); + json.property("constStart", data->constStart); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::Module: { + auto* data = static_cast(data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + json.property("varStart", data->varStart); + json.property("letStart", data->letStart); + json.property("constStart", data->constStart); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::WasmInstance: { + auto* data = + static_cast*>( + data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + json.property("globalsStart", data->globalsStart); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + case ScopeKind::WasmFunction: { + auto* data = + static_cast*>( + data_.get()); + json.property("nextFrameSlot", data->nextFrameSlot); + + trailingNames = &data->trailingNames; + length = data->length; + break; + } + + default: { + MOZ_CRASH("Unexpected ScopeKind"); + break; + } + } + + if (trailingNames) { + json.beginListProperty("trailingNames"); + for (size_t i = 0; i < length; i++) { + auto& name = (*trailingNames)[i]; + json.beginObject(); + + json.boolProperty("closedOver", name.closedOver()); + + json.boolProperty("isTopLevelFunction", name.isTopLevelFunction()); + + GenericPrinter& out = json.beginStringProperty("name"); + name.name()->dumpCharsNoQuote(out); + json.endStringProperty(); + + json.endObject(); + } + json.endList(); + } + + json.endObject(); +} + +static void DumpModuleEntryVectorItems( + js::JSONPrinter& json, const StencilModuleMetadata::EntryVector& entries) { + for (const auto& entry : entries) { + json.beginObject(); + if (entry.specifier) { + GenericPrinter& out = json.beginStringProperty("specifier"); + entry.specifier->dumpCharsNoQuote(out); + json.endStringProperty(); + } + if (entry.localName) { + GenericPrinter& out = json.beginStringProperty("localName"); + entry.localName->dumpCharsNoQuote(out); + json.endStringProperty(); + } + if (entry.importName) { + GenericPrinter& out = json.beginStringProperty("importName"); + entry.importName->dumpCharsNoQuote(out); + json.endStringProperty(); + } + if (entry.exportName) { + GenericPrinter& out = json.beginStringProperty("exportName"); + entry.exportName->dumpCharsNoQuote(out); + json.endStringProperty(); + } + json.endObject(); + } +} + +void StencilModuleMetadata::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void StencilModuleMetadata::dump(js::JSONPrinter& json) { + json.beginObject(); + dumpFields(json); + json.endObject(); +} + +void StencilModuleMetadata::dumpFields(js::JSONPrinter& json) { + json.beginListProperty("requestedModules"); + DumpModuleEntryVectorItems(json, requestedModules); + json.endList(); + + json.beginListProperty("importEntries"); + DumpModuleEntryVectorItems(json, importEntries); + json.endList(); + + json.beginListProperty("localExportEntries"); + DumpModuleEntryVectorItems(json, localExportEntries); + json.endList(); + + json.beginListProperty("indirectExportEntries"); + DumpModuleEntryVectorItems(json, indirectExportEntries); + json.endList(); + + json.beginListProperty("starExportEntries"); + DumpModuleEntryVectorItems(json, starExportEntries); + json.endList(); + + json.beginListProperty("functionDecls"); + for (auto& index : functionDecls) { + json.value("FunctionIndex(%zu)", size_t(index)); + } + json.endList(); +} + +static void DumpImmutableScriptFlags(js::JSONPrinter& json, + ImmutableScriptFlags immutableFlags) { + for (uint32_t i = 1; i; i = i << 1) { + if (uint32_t(immutableFlags) & i) { + switch (ImmutableScriptFlagsEnum(i)) { + case ImmutableScriptFlagsEnum::IsForEval: + json.value("IsForEval"); + break; + case ImmutableScriptFlagsEnum::IsModule: + json.value("IsModule"); + break; + case ImmutableScriptFlagsEnum::IsFunction: + json.value("IsFunction"); + break; + case ImmutableScriptFlagsEnum::SelfHosted: + json.value("SelfHosted"); + break; + case ImmutableScriptFlagsEnum::ForceStrict: + json.value("ForceStrict"); + break; + case ImmutableScriptFlagsEnum::HasNonSyntacticScope: + json.value("HasNonSyntacticScope"); + break; + case ImmutableScriptFlagsEnum::NoScriptRval: + json.value("NoScriptRval"); + break; + case ImmutableScriptFlagsEnum::TreatAsRunOnce: + json.value("TreatAsRunOnce"); + break; + case ImmutableScriptFlagsEnum::Strict: + json.value("Strict"); + break; + case ImmutableScriptFlagsEnum::HasModuleGoal: + json.value("HasModuleGoal"); + break; + case ImmutableScriptFlagsEnum::HasInnerFunctions: + json.value("HasInnerFunctions"); + break; + case ImmutableScriptFlagsEnum::HasDirectEval: + json.value("HasDirectEval"); + break; + case ImmutableScriptFlagsEnum::BindingsAccessedDynamically: + json.value("BindingsAccessedDynamically"); + break; + case ImmutableScriptFlagsEnum::HasCallSiteObj: + json.value("HasCallSiteObj"); + break; + case ImmutableScriptFlagsEnum::IsAsync: + json.value("IsAsync"); + break; + case ImmutableScriptFlagsEnum::IsGenerator: + json.value("IsGenerator"); + break; + case ImmutableScriptFlagsEnum::FunHasExtensibleScope: + json.value("FunHasExtensibleScope"); + break; + case ImmutableScriptFlagsEnum::FunctionHasThisBinding: + json.value("FunctionHasThisBinding"); + break; + case ImmutableScriptFlagsEnum::NeedsHomeObject: + json.value("NeedsHomeObject"); + break; + case ImmutableScriptFlagsEnum::IsDerivedClassConstructor: + json.value("IsDerivedClassConstructor"); + break; + case ImmutableScriptFlagsEnum::IsFieldInitializer: + json.value("IsFieldInitializer"); + break; + case ImmutableScriptFlagsEnum::HasRest: + json.value("HasRest"); + break; + case ImmutableScriptFlagsEnum::NeedsFunctionEnvironmentObjects: + json.value("NeedsFunctionEnvironmentObjects"); + break; + case ImmutableScriptFlagsEnum::FunctionHasExtraBodyVarScope: + json.value("FunctionHasExtraBodyVarScope"); + break; + case ImmutableScriptFlagsEnum::ShouldDeclareArguments: + json.value("ShouldDeclareArguments"); + break; + case ImmutableScriptFlagsEnum::ArgumentsHasVarBinding: + json.value("ArgumentsHasVarBinding"); + break; + case ImmutableScriptFlagsEnum::AlwaysNeedsArgsObj: + json.value("AlwaysNeedsArgsObj"); + break; + case ImmutableScriptFlagsEnum::HasMappedArgsObj: + json.value("HasMappedArgsObj"); + break; + case ImmutableScriptFlagsEnum::IsLikelyConstructorWrapper: + json.value("IsLikelyConstructorWrapper"); + break; + default: + json.value("Unknown(%x)", i); + break; + } + } + } +} + +static void DumpFunctionFlagsItems(js::JSONPrinter& json, + FunctionFlags functionFlags) { + switch (functionFlags.kind()) { + case FunctionFlags::FunctionKind::NormalFunction: + json.value("NORMAL_KIND"); + break; + case FunctionFlags::FunctionKind::AsmJS: + json.value("ASMJS_KIND"); + break; + case FunctionFlags::FunctionKind::Wasm: + json.value("WASM_KIND"); + break; + case FunctionFlags::FunctionKind::Arrow: + json.value("ARROW_KIND"); + break; + case FunctionFlags::FunctionKind::Method: + json.value("METHOD_KIND"); + break; + case FunctionFlags::FunctionKind::ClassConstructor: + json.value("CLASSCONSTRUCTOR_KIND"); + break; + case FunctionFlags::FunctionKind::Getter: + json.value("GETTER_KIND"); + break; + case FunctionFlags::FunctionKind::Setter: + json.value("SETTER_KIND"); + break; + default: + json.value("Unknown(%x)", uint8_t(functionFlags.kind())); + break; + } + + static_assert(FunctionFlags::FUNCTION_KIND_MASK == 0x0007, + "FunctionKind should use the lowest 3 bits"); + for (uint16_t i = 1 << 3; i; i = i << 1) { + if (functionFlags.toRaw() & i) { + switch (FunctionFlags::Flags(i)) { + case FunctionFlags::Flags::EXTENDED: + json.value("EXTENDED"); + break; + case FunctionFlags::Flags::SELF_HOSTED: + json.value("SELF_HOSTED"); + break; + case FunctionFlags::Flags::BASESCRIPT: + json.value("BASESCRIPT"); + break; + case FunctionFlags::Flags::SELFHOSTLAZY: + json.value("SELFHOSTLAZY"); + break; + case FunctionFlags::Flags::CONSTRUCTOR: + json.value("CONSTRUCTOR"); + break; + case FunctionFlags::Flags::BOUND_FUN: + json.value("BOUND_FUN"); + break; + case FunctionFlags::Flags::LAMBDA: + json.value("LAMBDA"); + break; + case FunctionFlags::Flags::WASM_JIT_ENTRY: + json.value("WASM_JIT_ENTRY"); + break; + case FunctionFlags::Flags::HAS_INFERRED_NAME: + json.value("HAS_INFERRED_NAME"); + break; + case FunctionFlags::Flags::ATOM_EXTRA_FLAG: + json.value("ATOM_EXTRA_FLAG"); + break; + case FunctionFlags::Flags::RESOLVED_NAME: + json.value("RESOLVED_NAME"); + break; + case FunctionFlags::Flags::RESOLVED_LENGTH: + json.value("RESOLVED_LENGTH"); + break; + case FunctionFlags::Flags::NEW_SCRIPT_CLEARED: + json.value("NEW_SCRIPT_CLEARED"); + break; + default: + json.value("Unknown(%x)", i); + break; + } + } + } +} + +static void DumpScriptThing(js::JSONPrinter& json, ScriptThingVariant& thing) { + struct Matcher { + js::JSONPrinter& json; + + void operator()(ScriptAtom& data) { + json.beginObject(); + json.property("type", "ScriptAtom"); + const ParserAtom* atom = data; + GenericPrinter& out = json.beginStringProperty("value"); + atom->dumpCharsNoQuote(out); + json.endStringProperty(); + json.endObject(); + } + + void operator()(NullScriptThing& data) { json.nullValue(); } + + void operator()(BigIntIndex& index) { + json.value("BigIntIndex(%zu)", size_t(index)); + } + + void operator()(RegExpIndex& index) { + json.value("RegExpIndex(%zu)", size_t(index)); + } + + void operator()(ObjLiteralIndex& index) { + json.value("ObjLiteralIndex(%zu)", size_t(index)); + } + + void operator()(ScopeIndex& index) { + json.value("ScopeIndex(%zu)", size_t(index)); + } + + void operator()(FunctionIndex& index) { + json.value("FunctionIndex(%zu)", size_t(index)); + } + + void operator()(EmptyGlobalScopeType& emptyGlobalScope) { + json.value("EmptyGlobalScope"); + } + }; + + Matcher m{json}; + thing.match(m); +} + +void ScriptStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); +} + +void ScriptStencil::dump(js::JSONPrinter& json) { + json.beginObject(); + dumpFields(json); + json.endObject(); +} + +void ScriptStencil::dumpFields(js::JSONPrinter& json) { + json.beginListProperty("immutableFlags"); + DumpImmutableScriptFlags(json, immutableFlags); + json.endList(); + + if (memberInitializers) { + json.formatProperty("memberInitializers", "Some(%u)", + (*memberInitializers).numMemberInitializers); + } else { + json.property("memberInitializers", "Nothing"); + } + + json.beginListProperty("gcThings"); + for (auto& thing : gcThings) { + DumpScriptThing(json, thing); + } + json.endList(); + + if (immutableScriptData) { + json.formatProperty("immutableScriptData", "u8[%zu]", + immutableScriptData->immutableData().Length()); + } else { + json.nullProperty("immutableScriptData"); + } + + json.beginObjectProperty("extent"); + json.property("sourceStart", extent.sourceStart); + json.property("sourceEnd", extent.sourceEnd); + json.property("toStringStart", extent.toStringStart); + json.property("toStringEnd", extent.toStringEnd); + json.property("lineno", extent.lineno); + json.property("column", extent.column); + json.endObject(); + + if (isFunction()) { + if (functionAtom) { + GenericPrinter& out = json.beginStringProperty("functionAtom"); + functionAtom->dumpCharsNoQuote(out); + json.endStringProperty(); + } else { + json.nullProperty("functionAtom"); + } + + json.beginListProperty("functionFlags"); + DumpFunctionFlagsItems(json, functionFlags); + json.endList(); + + json.property("nargs", nargs); + + if (lazyFunctionEnclosingScopeIndex_) { + json.formatProperty("lazyFunctionEnclosingScopeIndex", + "Some(ScopeIndex(%zu))", + size_t(*lazyFunctionEnclosingScopeIndex_)); + } else { + json.property("lazyFunctionEnclosingScopeIndex", "Nothing"); + } + + json.boolProperty("isStandaloneFunction", isStandaloneFunction); + json.boolProperty("wasFunctionEmitted", wasFunctionEmitted); + json.boolProperty("isSingletonFunction", isSingletonFunction); + } +} + +void CompilationStencil::dump() { + js::Fprinter out(stderr); + js::JSONPrinter json(out); + dump(json); + out.put("\n"); +} + +void CompilationStencil::dump(js::JSONPrinter& json) { + json.beginObject(); + + // FIXME: dump asmJS + + json.beginListProperty("scriptData"); + for (auto& data : scriptData) { + data.dump(json); + } + json.endList(); + + json.beginListProperty("regExpData"); + for (auto& data : regExpData) { + data.dump(json); + } + json.endList(); + + json.beginListProperty("bigIntData"); + for (auto& data : bigIntData) { + data.dump(json); + } + json.endList(); + + json.beginListProperty("objLiteralData"); + for (auto& data : objLiteralData) { + data.dump(json); + } + json.endList(); + + json.beginListProperty("scopeData"); + for (auto& data : scopeData) { + data.dump(json); + } + json.endList(); + + if (scriptData[CompilationInfo::TopLevelIndex].isModule()) { + json.beginObjectProperty("moduleMetadata"); + moduleMetadata.dumpFields(json); + json.endObject(); + } + + json.endObject(); +} + +#endif // defined(DEBUG) || defined(JS_JITSPEW) \ No newline at end of file diff --git a/js/src/frontend/Stencil.h b/js/src/frontend/Stencil.h index 691b91e10d..507e4dec8f 100644 --- a/js/src/frontend/Stencil.h +++ b/js/src/frontend/Stencil.h @@ -5,46 +5,58 @@ #ifndef frontend_Stencil_h #define frontend_Stencil_h -#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_RELEASE_ASSERT -#include "mozilla/CheckedInt.h" // CheckedUint32 +#include "mozilla/Assertions.h" // MOZ_ASSERT #include "mozilla/Maybe.h" // mozilla::{Maybe, Nothing} #include "mozilla/Range.h" // mozilla::Range -#include "mozilla/Span.h" // mozilla::Span #include // char16_t, uint8_t, uint32_t #include // size_t #include "frontend/AbstractScopePtr.h" // AbstractScopePtr, ScopeIndex #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind -#include "frontend/NameAnalysisTypes.h" // AtomVector -#include "frontend/ObjLiteral.h" // ObjLiteralCreationData +#include "frontend/ObjLiteral.h" // ObjLiteralStencil #include "frontend/TypedIndex.h" // TypedIndex -#include "gc/Barrier.h" // HeapPtr, GCPtrAtom -#include "gc/Rooting.h" // HandleAtom, HandleModuleObject, HandleScriptSourceObject, MutableHandleScope -#include "js/GCVariant.h" // GC Support for mozilla::Variant -#include "js/RegExpFlags.h" // JS::RegExpFlags -#include "js/RootingAPI.h" // Handle -#include "js/TypeDecls.h" // JSContext,JSAtom,JSFunction -#include "js/UniquePtr.h" // js::UniquePtr -#include "js/Utility.h" // JS::FreePolicy, UniqueTwoByteChars -#include "js/Vector.h" // js::Vector -#include "util/Text.h" // DuplicateString -#include "vm/BigIntType.h" // ParseBigIntLiteral -#include "vm/FunctionFlags.h" // FunctionFlags -#include "vm/GeneratorAndAsyncKind.h" // GeneratorKind, FunctionAsyncKind -#include "vm/JSFunction.h" // FunctionFlags -#include "vm/JSScript.h" // GeneratorKind, FunctionAsyncKind, FieldInitializers -#include "vm/Runtime.h" // ReportOutOfMemory +#include "js/RegExpFlags.h" // JS::RegExpFlags +#include "js/RootingAPI.h" // Handle +#include "js/TypeDecls.h" // JSContext +#include "js/UniquePtr.h" // js::UniquePtr +#include "js/Utility.h" // UniqueTwoByteChars +#include "js/Vector.h" // js::Vector +#include "util/Text.h" // DuplicateString +#include "vm/BigIntType.h" // ParseBigIntLiteral +#include "vm/FunctionFlags.h" // FunctionFlags +#include "vm/GeneratorAndAsyncKind.h" // GeneratorKind, FunctionAsyncKind +#include "vm/JSScript.h" // MemberInitializers #include "vm/Scope.h" // BaseScopeData, FunctionScope, LexicalScope, VarScope, GlobalScope, EvalScope, ModuleScope #include "vm/ScopeKind.h" // ScopeKind -#include "vm/SharedStencil.h" // ImmutableScriptFlags +#include "vm/SharedStencil.h" // ImmutableScriptFlags, GCThingIndex +#include "vm/StencilEnums.h" // ImmutableScriptFlagsEnum -class JS_PUBLIC_API JSTracer; +namespace js { -namespace js::frontend { +class JSONPrinter; + +namespace frontend { struct CompilationInfo; -class FunctionBox; +struct CompilationStencil; +struct CompilationGCOutput; +class ScriptStencil; +class RegExpStencil; +class BigIntStencil; + +using BaseParserScopeData = AbstractBaseScopeData; + +template +using ParserScopeData = typename Scope::template AbstractData; +using ParserGlobalScopeData = ParserScopeData; +using ParserEvalScopeData = ParserScopeData; +using ParserLexicalScopeData = ParserScopeData; +using ParserFunctionScopeData = ParserScopeData; +using ParserModuleScopeData = ParserScopeData; +using ParserVarScopeData = ParserScopeData; + +using ParserBindingIter = AbstractBindingIter; // [SMDOC] Script Stencil (Frontend Representation) // @@ -55,16 +67,11 @@ class FunctionBox; // // Renaming to use the term stencil more broadly is still in progress. -// Arbitrary typename to disambiguate TypedIndexes; -class FunctionIndexType; - -// We need to be able to forward declare this type, so make a subclass -// rather than just using. -class FunctionIndex : public TypedIndex { - // Delegate constructors; - using Base = TypedIndex; - using Base::Base; -}; +// Typed indices for the different stencil elements in the compilation result. +using RegExpIndex = TypedIndex; +using BigIntIndex = TypedIndex; +using ObjLiteralIndex = TypedIndex; +using FunctionIndex = TypedIndex; FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind, GeneratorKind generatorKind, @@ -74,13 +81,13 @@ FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind, // This owns a set of characters, previously syntax checked as a RegExp. Used // to avoid allocating the RegExp on the GC heap during parsing. -class RegExpCreationData { - UniquePtr buf_; +class RegExpStencil { + UniqueTwoByteChars buf_; size_t length_ = 0; JS::RegExpFlags flags_; public: - RegExpCreationData() = default; + RegExpStencil() = default; MOZ_MUST_USE bool init(JSContext* cx, mozilla::Range range, JS::RegExpFlags flags) { @@ -93,22 +100,23 @@ class RegExpCreationData { return true; } - MOZ_MUST_USE bool init(JSContext* cx, JSAtom* pattern, JS::RegExpFlags flags); - RegExpObject* createRegExp(JSContext* cx) const; -}; -using RegExpIndex = TypedIndex; +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); +#endif +}; // This owns a set of characters guaranteed to parse into a BigInt via // ParseBigIntLiteral. Used to avoid allocating the BigInt on the // GC heap during parsing. -class BigIntCreationData { +class BigIntStencil { UniqueTwoByteChars buf_; size_t length_ = 0; public: - BigIntCreationData() = default; + BigIntStencil() = default; MOZ_MUST_USE bool init(JSContext* cx, const Vector& buf) { #ifdef DEBUG @@ -133,244 +141,371 @@ class BigIntCreationData { mozilla::Range source(buf_.get(), length_); return js::BigIntLiteralIsZero(source); } -}; - -using BigIntIndex = TypedIndex; - -class EnvironmentShapeCreationData { - // Data used to call CreateEnvShapeData - struct CreateEnvShapeData { - BindingIter freshBi; - const JSClass* cls; - uint32_t nextEnvironmentSlot; - uint32_t baseShapeFlags; - - void trace(JSTracer* trc) { freshBi.trace(trc); } - }; - - // Data used to call EmptyEnvironmentShape - struct EmptyEnvShapeData { - const JSClass* cls; - uint32_t baseShapeFlags; - void trace(JSTracer* trc){ - // Rather than having to expose this type as public to provide - // an IgnoreGCPolicy, just have an empty trace. - }; - }; - - // Three different paths to creating an environment shape: Either we produce - // nullptr directly (represented by storing Nothing in the variant), or we - // call CreateEnvironmentShape, or we call EmptyEnvironmentShape. - mozilla::Variant - data_ = mozilla::AsVariant(mozilla::Nothing()); - - public: - explicit operator bool() const { return !data_.is(); } - - // Setup for calling CreateEnvironmentShape - void set(const BindingIter& freshBi, const JSClass* cls, - uint32_t nextEnvironmentSlot, uint32_t baseShapeFlags) { - data_ = mozilla::AsVariant( - CreateEnvShapeData{freshBi, cls, nextEnvironmentSlot, baseShapeFlags}); - } - - // Setup for calling EmptyEnviornmentShape - void set(const JSClass* cls, uint32_t shapeFlags) { - data_ = mozilla::AsVariant(EmptyEnvShapeData{cls, shapeFlags}); - } - // Reifiy this into an actual shape. - MOZ_MUST_USE bool createShape(JSContext* cx, MutableHandleShape shape); - - void trace(JSTracer* trc) { - using DataGCPolicy = JS::GCPolicy; - DataGCPolicy::trace(trc, &data_, "data_"); - } +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); +#endif }; -class ScopeCreationData { - friend class js::AbstractScopePtr; - friend class js::GCMarker; - - // The enclosing scope if it exists - AbstractScopePtr enclosing_; +class ScopeStencil { + // The enclosing scope. If Nothing, then the enclosing scope of the + // compilation applies. + mozilla::Maybe enclosing_; // The kind determines data_. ScopeKind kind_; - // Data to reify an environment shape at creation time. - EnvironmentShapeCreationData environmentShape_; + // First frame slot to use, or LOCALNO_LIMIT if none are allowed. + uint32_t firstFrameSlot_; + + // If Some, then an environment Shape must be created. The shape itself may + // have no slots if the environment may be extensible later. + mozilla::Maybe numEnvironmentSlots_; - // Once we've produced a scope from a scope creation data, there may still be - // AbstractScopePtrs refering to this ScopeCreationData, and if reification is - // requested multiple times, we should return the same scope rather than - // creating multiple sopes. - // - // As well, any queries that require data() to answer must be redirected to - // the scope once the scope has been reified, as the ScopeCreationData loses - // ownership of the data on reification. - HeapPtr scope_ = {}; + // Canonical function if this is a FunctionScope. + mozilla::Maybe functionIndex_; - // For FunctionScopes we need the funbox; nullptr otherwise. - frontend::FunctionBox* funbox_ = nullptr; + // True if this is a FunctionScope for an arrow function. + bool isArrow_; - UniquePtr data_; + // The list of binding and scope-specific data. Note that the back pointers to + // the owning JSFunction / ModuleObject are not set until Stencils are + // converted to GC allocations. + js::UniquePtr data_; public: - ScopeCreationData( - JSContext* cx, ScopeKind kind, Handle enclosing, - Handle environmentShape, - UniquePtr data = {}, - frontend::FunctionBox* funbox = nullptr) + ScopeStencil(ScopeKind kind, mozilla::Maybe enclosing, + uint32_t firstFrameSlot, + mozilla::Maybe numEnvironmentSlots, + BaseParserScopeData* data = {}, + mozilla::Maybe functionIndex = mozilla::Nothing(), + bool isArrow = false) : enclosing_(enclosing), kind_(kind), - environmentShape_(environmentShape), // Copied - funbox_(funbox), - data_(std::move(data)) {} + firstFrameSlot_(firstFrameSlot), + numEnvironmentSlots_(numEnvironmentSlots), + functionIndex_(functionIndex), + isArrow_(isArrow), + data_(data) {} + + static bool createForFunctionScope(JSContext* cx, CompilationStencil& stencil, + ParserFunctionScopeData* dataArg, + bool hasParameterExprs, + bool needsEnvironment, + FunctionIndex functionIndex, bool isArrow, + mozilla::Maybe enclosing, + ScopeIndex* index); + + static bool createForLexicalScope(JSContext* cx, CompilationStencil& stencil, + ScopeKind kind, + ParserLexicalScopeData* dataArg, + uint32_t firstFrameSlot, + mozilla::Maybe enclosing, + ScopeIndex* index); + + static bool createForVarScope(JSContext* cx, + frontend::CompilationStencil& stencil, + ScopeKind kind, ParserVarScopeData* dataArg, + uint32_t firstFrameSlot, bool needsEnvironment, + mozilla::Maybe enclosing, + ScopeIndex* index); + + static bool createForGlobalScope(JSContext* cx, CompilationStencil& stencil, + ScopeKind kind, + ParserGlobalScopeData* dataArg, + ScopeIndex* index); + + static bool createForEvalScope(JSContext* cx, CompilationStencil& stencil, + ScopeKind kind, ParserEvalScopeData* dataArg, + mozilla::Maybe enclosing, + ScopeIndex* index); + + static bool createForModuleScope(JSContext* cx, CompilationStencil& stencil, + ParserModuleScopeData* dataArg, + mozilla::Maybe enclosing, + ScopeIndex* index); + + static bool createForWithScope(JSContext* cx, CompilationStencil& stencil, + mozilla::Maybe enclosing, + ScopeIndex* index); + + AbstractScopePtr enclosing(CompilationInfo& compilationInfo); ScopeKind kind() const { return kind_; } - AbstractScopePtr enclosing() { return enclosing_; } - bool getOrCreateEnclosingScope(JSContext* cx, MutableHandleScope scope) { - return enclosing_.getOrCreateScope(cx, scope); - } - - // FunctionScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - Handle dataArg, - bool hasParameterExprs, bool needsEnvironment, - frontend::FunctionBox* funbox, - Handle enclosing, ScopeIndex* index); - - // LexicalScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - ScopeKind kind, Handle dataArg, - uint32_t firstFrameSlot, - Handle enclosing, ScopeIndex* index); - // VarScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - ScopeKind kind, Handle dataArg, - uint32_t firstFrameSlot, bool needsEnvironment, - Handle enclosing, ScopeIndex* index); - - // GlobalScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - ScopeKind kind, Handle dataArg, - ScopeIndex* index); - - // EvalScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - ScopeKind kind, Handle dataArg, - Handle enclosing, ScopeIndex* index); - - // ModuleScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - Handle dataArg, - HandleModuleObject module, - Handle enclosing, ScopeIndex* index); - - // WithScope - static bool create(JSContext* cx, frontend::CompilationInfo& compilationInfo, - Handle enclosing, ScopeIndex* index); bool hasEnvironment() const { // Check if scope kind alone means we have an env shape, and // otherwise check if we have one created. - return Scope::hasEnvironment(kind(), !!environmentShape_); + bool hasEnvironmentShape = numEnvironmentSlots_.isSome(); + return Scope::hasEnvironment(kind(), hasEnvironmentShape); } - // Valid for functions; - bool isArrow() const; + bool isArrow() const { return isArrow_; } - bool hasScope() const { return scope_ != nullptr; } - - Scope* getScope() const { - MOZ_ASSERT(hasScope()); - return scope_; - } - - Scope* createScope(JSContext* cx); - - void trace(JSTracer* trc); + Scope* createScope(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput); uint32_t nextFrameSlot() const; +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); + void dumpFields(JSONPrinter& json); +#endif + private: // Non owning reference to data template - typename SpecificScopeType::Data& data() const { - MOZ_ASSERT(data_.get()); - return *static_cast(data_.get()); + typename SpecificScopeType::template AbstractData& data() + const { + using Data = + typename SpecificScopeType ::template AbstractData; + + MOZ_ASSERT(data_); + return *static_cast(data_.get()); } // Transfer ownership into a new UniquePtr. template - UniquePtr releaseData(); - - template - Scope* createSpecificScope(JSContext* cx); + UniquePtr createSpecificScopeData( + JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput); template uint32_t nextFrameSlot() const { - // If a scope has been allocated for the ScopeCreationData we no longer own - // data, so defer to scope - if (hasScope()) { - return getScope()->template as().nextFrameSlot(); - } + // If a scope has been allocated for the ScopeStencil we no longer own data, + // so defer to scope return data().nextFrameSlot; } + + template + MOZ_MUST_USE bool createSpecificShape(JSContext* cx, ScopeKind kind, + BaseScopeData* scopeData, + MutableHandleShape shape); + + template + Scope* createSpecificScope(JSContext* cx, CompilationInfo& compilationInfo, + CompilationGCOutput& gcOutput); }; +// As an alternative to a ScopeIndex (which references a ScopeStencil), we may +// instead refer to an existing scope from GlobalObject::emptyGlobalScope(). +// +// NOTE: This is only used for the self-hosting global. class EmptyGlobalScopeType {}; +// See JSOp::Lambda for interepretation of this index. +using FunctionDeclaration = GCThingIndex; +using FunctionDeclarationVector = + Vector; + +// Common type for ImportEntry / ExportEntry / ModuleRequest within frontend. We +// use a shared stencil class type to simplify serialization. +// +// https://tc39.es/ecma262/#importentry-record +// https://tc39.es/ecma262/#exportentry-record +// +// Note: We subdivide the spec's ExportEntry into ExportAs / ExportFrom forms +// for readability. +class StencilModuleEntry { + public: + // | ModuleRequest | ImportEntry | ExportAs | ExportFrom | + // |-----------------------------------------------------| + // specifier | required | required | nullptr | required | + // localName | null | required | required | nullptr | + // importName | null | required | nullptr | required | + // exportName | null | null | required | optional | + const ParserAtom* specifier = nullptr; + const ParserAtom* localName = nullptr; + const ParserAtom* importName = nullptr; + const ParserAtom* exportName = nullptr; + + // Location used for error messages. If this is for a module request entry + // then it is the module specifier string, otherwise the import/export spec + // that failed. Exports may not fill these fields if an error cannot be + // generated such as `export let x;`. + uint32_t lineno = 0; + uint32_t column = 0; + + private: + StencilModuleEntry(uint32_t lineno, uint32_t column) + : lineno(lineno), column(column) {} + + public: + static StencilModuleEntry moduleRequest(const ParserAtom* specifier, + uint32_t lineno, uint32_t column) { + MOZ_ASSERT(specifier); + StencilModuleEntry entry(lineno, column); + entry.specifier = specifier; + return entry; + } + + static StencilModuleEntry importEntry(const ParserAtom* specifier, + const ParserAtom* localName, + const ParserAtom* importName, + uint32_t lineno, uint32_t column) { + MOZ_ASSERT(specifier && localName && importName); + StencilModuleEntry entry(lineno, column); + entry.specifier = specifier; + entry.localName = localName; + entry.importName = importName; + return entry; + } + + static StencilModuleEntry exportAsEntry(const ParserAtom* localName, + const ParserAtom* exportName, + uint32_t lineno, uint32_t column) { + MOZ_ASSERT(localName && exportName); + StencilModuleEntry entry(lineno, column); + entry.localName = localName; + entry.exportName = exportName; + return entry; + } + + static StencilModuleEntry exportFromEntry(const ParserAtom* specifier, + const ParserAtom* importName, + const ParserAtom* exportName, + uint32_t lineno, uint32_t column) { + // NOTE: The `export * from "mod";` syntax generates nullptr exportName. + MOZ_ASSERT(specifier && importName); + StencilModuleEntry entry(lineno, column); + entry.specifier = specifier; + entry.importName = importName; + entry.exportName = exportName; + return entry; + } +}; + +// Metadata generated by parsing module scripts, including import/export tables. +class StencilModuleMetadata { + public: + using EntryVector = Vector; + + EntryVector requestedModules; + EntryVector importEntries; + EntryVector localExportEntries; + EntryVector indirectExportEntries; + EntryVector starExportEntries; + FunctionDeclarationVector functionDecls; + + StencilModuleMetadata() = default; + + bool initModule(JSContext* cx, CompilationInfo& compilationInfo, + JS::Handle module); + +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); + void dumpFields(JSONPrinter& json); +#endif +}; + // The lazy closed-over-binding info is represented by these types that will -// convert to a GCCellPtr(nullptr), GCCellPtr(JSAtom*). +// convert to a nullptr. class NullScriptThing {}; -using ScriptAtom = JSAtom*; + +using ScriptAtom = const ParserAtom*; // These types all end up being baked into GC things as part of stencil // instantiation. using ScriptThingVariant = - mozilla::Variant; + mozilla::Variant; // A vector of things destined to be converted to GC things. -using ScriptThingsVector = Vector; +using ScriptThingsVector = Vector; // Data generated by frontend that will be used to create a js::BaseScript. class ScriptStencil { public: - // See `BaseScript::functionOrGlobal_`. - mozilla::Maybe functionIndex; + // Fields for BaseScript. + // Used by: + // * Global script + // * Eval + // * Module + // * non-lazy Function (except asm.js module) + // * lazy Function (cannot be asm.js module) // See `BaseScript::immutableFlags_`. ImmutableScriptFlags immutableFlags; // See `BaseScript::data_`. - mozilla::Maybe fieldInitializers; + mozilla::Maybe memberInitializers; ScriptThingsVector gcThings; // See `BaseScript::sharedData_`. js::UniquePtr immutableScriptData = nullptr; - // End of fields. + // The location of this script in the source. + SourceExtent extent = {}; - explicit ScriptStencil(JSContext* cx) : gcThings(cx) {} + // Fields for JSFunction. + // Used by: + // * non-lazy Function + // * lazy Function + // * asm.js module - // This traces any JSAtoms in the gcThings array. This will be removed once - // atoms are deferred from parsing. - void trace(JSTracer* trc); -}; + // The explicit or implicit name of the function. The FunctionFlags indicate + // the kind of name. + const ParserAtom* functionAtom = nullptr; + + // See: `FunctionFlags`. + FunctionFlags functionFlags = {}; + + // See `JSFunction::nargs_`. + uint16_t nargs = 0; + + // If this ScriptStencil refers to a lazy child of the function being + // compiled, this field holds the child's immediately enclosing scope's index. + // Once compilation succeeds, we will store the scope pointed by this in the + // child's BaseScript. (Debugger may become confused if lazy scripts refer to + // partially initialized enclosing scopes, so we must avoid storing the + // scope in the BaseScript until compilation has completed + // successfully.) + mozilla::Maybe lazyFunctionEnclosingScopeIndex_; + + // This function is a standalone function that is not syntactically part of + // another script. Eg. Created by `new Function("")`. + bool isStandaloneFunction : 1; -} /* namespace js::frontend */ + // This is set by the BytecodeEmitter of the enclosing script when a reference + // to this function is generated. + bool wasFunctionEmitted : 1; -namespace JS { -template <> -struct GCPolicy { - static void trace(JSTracer* trc, js::frontend::ScopeCreationData** data, - const char* name) { - (*data)->trace(trc); + // This function should be marked as a singleton. It is expected to be defined + // at most once. This is a heuristic only and does not affect correctness. + bool isSingletonFunction : 1; + + // End of fields. + + ScriptStencil() + : isStandaloneFunction(false), + wasFunctionEmitted(false), + isSingletonFunction(false) {} + + bool isFunction() const { + bool result = functionFlags.toRaw() != 0x0000; + MOZ_ASSERT_IF( + result, functionFlags.isAsmJSNative() || functionFlags.hasBaseScript()); + return result; + } + + bool isModule() const { + bool result = immutableFlags.hasFlag(ImmutableScriptFlagsEnum::IsModule); + MOZ_ASSERT_IF(result, !isFunction()); + return result; } + +#if defined(DEBUG) || defined(JS_JITSPEW) + void dump(); + void dump(JSONPrinter& json); + void dumpFields(JSONPrinter& json); +#endif }; -} // namespace JS + +} /* namespace frontend */ +} /* namespace js */ + #endif /* frontend_Stencil_h */ diff --git a/js/src/frontend/SwitchEmitter.cpp b/js/src/frontend/SwitchEmitter.cpp index 86fce93fbf..0febc0ad90 100644 --- a/js/src/frontend/SwitchEmitter.cpp +++ b/js/src/frontend/SwitchEmitter.cpp @@ -120,7 +120,7 @@ bool SwitchEmitter::emitDiscriminant(const Maybe& switchPos) { return true; } -bool SwitchEmitter::emitLexical(Handle bindings) { +bool SwitchEmitter::emitLexical(ParserLexicalScopeData* bindings) { MOZ_ASSERT(state_ == State::Discriminant); MOZ_ASSERT(bindings); diff --git a/js/src/frontend/SwitchEmitter.h b/js/src/frontend/SwitchEmitter.h index d759847c1b..4c6b0f0382 100644 --- a/js/src/frontend/SwitchEmitter.h +++ b/js/src/frontend/SwitchEmitter.h @@ -439,7 +439,7 @@ class MOZ_STACK_CLASS SwitchEmitter { // `bindings` is a lexical scope for the entire switch, in case there's // let/const effectively directly under case or default blocks. - MOZ_MUST_USE bool emitLexical(Handle bindings); + MOZ_MUST_USE bool emitLexical(ParserLexicalScopeData* bindings); MOZ_MUST_USE bool emitCond(); MOZ_MUST_USE bool emitTable(const TableGenerator& tableGen); diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h index eafb29530f..bc13c00a9d 100644 --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -7,10 +7,12 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" // mozilla::Maybe #include #include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind +#include "frontend/NameAnalysisTypes.h" // PrivateNameKind #include "frontend/ParseNode.h" #include "frontend/TokenStream.h" #include "js/GCAnnotations.h" @@ -32,20 +34,9 @@ namespace frontend { // amounts of code that never executes (which happens often). class SyntaxParseHandler { // Remember the last encountered name or string literal during syntax parses. - JSAtom* lastAtom; + const ParserAtom* lastAtom; TokenPos lastStringPos; - // WARNING: Be careful about adding fields to this function, that might be - // GC things (like JSAtom*). The JS_HAZ_ROOTED causes the GC - // analysis to *ignore* anything that might be a rooting hazard in - // this class. The |lastAtom| field above is safe because - // SyntaxParseHandler only appears as a field in - // PerHandlerParser, and that class inherits - // from ParserBase which contains a reference to a CompilationInfo, - // which has an AutoKeepAtoms field that prevents atoms from being - // moved around while the AutoKeepAtoms lives -- which is longer - // than the lifetime of any of the parser classes. - public: enum Node { NodeFailure = 0, @@ -88,10 +79,16 @@ class SyntaxParseHandler { // contextual keyword. NodePotentialAsyncKeyword, + // Node representing private names. + NodePrivateName, + NodeDottedProperty, NodeOptionalDottedProperty, NodeElement, NodeOptionalElement, + // A distinct node for [PrivateName], to make detecting delete this.#x + // detectable in syntax parse + NodePrivateElement, // Destructuring target patterns can't be parenthesized: |([a]) = [3];| // must be a syntax error. (We can't use NodeGeneric instead of these @@ -144,7 +141,8 @@ class SyntaxParseHandler { } bool isPropertyAccess(Node node) { - return node == NodeDottedProperty || node == NodeElement; + return node == NodeDottedProperty || node == NodeElement || + node == NodePrivateElement; } bool isOptionalPropertyAccess(Node node) { @@ -181,15 +179,17 @@ class SyntaxParseHandler { FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) #undef DECLARE_AS - NameNodeType newName(PropertyName* name, const TokenPos& pos, JSContext* cx) { + NameNodeType newName(const ParserName* name, const TokenPos& pos, + JSContext* cx) { lastAtom = name; - if (name == cx->names().arguments) { + if (name == cx->parserNames().arguments) { return NodeArgumentsName; } - if (pos.begin + strlen("async") == pos.end && name == cx->names().async) { + if (pos.begin + strlen("async") == pos.end && + name == cx->parserNames().async) { return NodePotentialAsyncKeyword; } - if (name == cx->names().eval) { + if (name == cx->parserNames().eval) { return NodeEvalName; } return NodeName; @@ -199,10 +199,20 @@ class SyntaxParseHandler { return NodeGeneric; } - NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { + UnaryNodeType newSyntheticComputedName(Node expr, uint32_t start, + uint32_t end) { + return NodeGeneric; + } + + NameNodeType newObjectLiteralPropertyName(const ParserAtom* atom, + const TokenPos& pos) { return NodeName; } + NameNodeType newPrivateName(const ParserAtom* atom, const TokenPos& pos) { + return NodePrivateName; + } + NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return NodeGeneric; @@ -214,13 +224,14 @@ class SyntaxParseHandler { return NodeGeneric; } - NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newStringLiteral(const ParserAtom* atom, const TokenPos& pos) { lastAtom = atom; lastStringPos = pos; return NodeUnparenthesizedString; } - NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newTemplateStringLiteral(const ParserAtom* atom, + const TokenPos& pos) { return NodeGeneric; } @@ -351,9 +362,9 @@ class SyntaxParseHandler { AccessorType atype) { return true; } - MOZ_MUST_USE Node newClassMethodDefinition(Node key, FunctionNodeType funNode, - AccessorType atype, - bool isStatic) { + MOZ_MUST_USE Node newClassMethodDefinition( + Node key, FunctionNodeType funNode, AccessorType atype, bool isStatic, + mozilla::Maybe initializerIfPrivate) { return NodeGeneric; } MOZ_MUST_USE Node newClassFieldDefinition(Node name, @@ -442,11 +453,11 @@ class SyntaxParseHandler { CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; } - ContinueStatementType newContinueStatement(PropertyName* label, + ContinueStatementType newContinueStatement(const ParserName* label, const TokenPos& pos) { return NodeGeneric; } - BreakStatementType newBreakStatement(PropertyName* label, + BreakStatementType newBreakStatement(const ParserName* label, const TokenPos& pos) { return NodeBreak; } @@ -458,7 +469,7 @@ class SyntaxParseHandler { return NodeGeneric; } - LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, + LabeledStatementType newLabeledStatement(const ParserName* label, Node stmt, uint32_t begin) { return NodeGeneric; } @@ -475,7 +486,7 @@ class SyntaxParseHandler { return NodeGeneric; } - NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) { + NameNodeType newPropertyName(const ParserName* name, const TokenPos& pos) { lastAtom = name; return NodeGeneric; } @@ -489,6 +500,9 @@ class SyntaxParseHandler { } PropertyByValueType newPropertyByValue(Node lhs, Node index, uint32_t end) { + if (isPrivateName(index)) { + return NodePrivateElement; + } return NodeElement; } @@ -678,7 +692,10 @@ class SyntaxParseHandler { return node == NodePotentialAsyncKeyword; } - PropertyName* maybeDottedProperty(Node node) { + bool isPrivateName(Node node) { return node == NodePrivateName; } + bool isPrivateField(Node node) { return node == NodePrivateElement; } + + const ParserName* maybeDottedProperty(Node node) { // Note: |super.apply(...)| is a special form that calls an "apply" // method retrieved from one value, but using a *different* value as // |this|. It's not really eligible for the funapply/funcall @@ -687,10 +704,10 @@ class SyntaxParseHandler { if (node != NodeDottedProperty && node != NodeOptionalDottedProperty) { return nullptr; } - return lastAtom->asPropertyName(); + return lastAtom->asName(); } - JSAtom* isStringExprStatement(Node pn, TokenPos* pos) { + const ParserAtom* isStringExprStatement(Node pn, TokenPos* pos) { if (pn == NodeStringExprStatement) { *pos = lastStringPos; return lastAtom; @@ -704,7 +721,9 @@ class SyntaxParseHandler { MOZ_CRASH( "SyntaxParseHandler::canSkipLazyClosedOverBindings must return false"); } -} JS_HAZ_ROOTED; // See the top of SyntaxParseHandler for why this is safe. + + void setPrivateNameKind(Node node, PrivateNameKind kind) {} +}; } // namespace frontend } // namespace js diff --git a/js/src/frontend/TDZCheckCache.cpp b/js/src/frontend/TDZCheckCache.cpp index e932897f81..a951318d6d 100644 --- a/js/src/frontend/TDZCheckCache.cpp +++ b/js/src/frontend/TDZCheckCache.cpp @@ -22,7 +22,7 @@ bool TDZCheckCache::ensureCache(BytecodeEmitter* bce) { } Maybe TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce, - JSAtom* name) { + const ParserAtom* name) { if (!ensureCache(bce)) { return Nothing(); } @@ -50,7 +50,7 @@ Maybe TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce, return Some(rv); } -bool TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, JSAtom* name, +bool TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, const ParserAtom* name, MaybeCheckTDZ check) { if (!ensureCache(bce)) { return false; diff --git a/js/src/frontend/TDZCheckCache.h b/js/src/frontend/TDZCheckCache.h index 9456633fba..72eafa1c45 100644 --- a/js/src/frontend/TDZCheckCache.h +++ b/js/src/frontend/TDZCheckCache.h @@ -45,8 +45,8 @@ class TDZCheckCache : public Nestable { explicit TDZCheckCache(BytecodeEmitter* bce); mozilla::Maybe needsTDZCheck(BytecodeEmitter* bce, - JSAtom* name); - MOZ_MUST_USE bool noteTDZCheck(BytecodeEmitter* bce, JSAtom* name, + const ParserAtom* name); + MOZ_MUST_USE bool noteTDZCheck(BytecodeEmitter* bce, const ParserAtom* name, MaybeCheckTDZ check); }; diff --git a/js/src/frontend/Token.h b/js/src/frontend/Token.h index 664063d156..361ff2f8e7 100644 --- a/js/src/frontend/Token.h +++ b/js/src/frontend/Token.h @@ -14,9 +14,9 @@ #include // uint32_t -#include "frontend/TokenKind.h" // js::frontend::TokenKind -#include "js/RegExpFlags.h" // JS::RegExpFlags -#include "vm/StringType.h" // js::PropertyName +#include "frontend/ParserAtom.h" // js::frontend::{ParserAtom,ParserName} +#include "frontend/TokenKind.h" // js::frontend::TokenKind +#include "js/RegExpFlags.h" // JS::RegExpFlags namespace js { @@ -142,10 +142,10 @@ struct Token { friend struct Token; /** Non-numeric atom. */ - PropertyName* name; + const ParserName* name; /** Potentially-numeric atom. */ - JSAtom* atom; + const ParserAtom* atom; struct { /** Numeric literal's value. */ @@ -166,12 +166,12 @@ struct Token { // Mutators - void setName(PropertyName* name) { + void setName(const ParserName* name) { MOZ_ASSERT(type == TokenKind::Name || type == TokenKind::PrivateName); u.name = name; } - void setAtom(JSAtom* atom) { + void setAtom(const ParserAtom* atom) { MOZ_ASSERT(type == TokenKind::String || type == TokenKind::TemplateHead || type == TokenKind::NoSubsTemplate); u.atom = atom; @@ -190,12 +190,12 @@ struct Token { // Type-safe accessors - PropertyName* name() const { + const ParserName* name() const { MOZ_ASSERT(type == TokenKind::Name || type == TokenKind::PrivateName); - return u.name->JSAtom::asPropertyName(); // poor-man's type verification + return u.name->asName(); // poor-man's type verification } - JSAtom* atom() const { + const ParserAtom* atom() const { MOZ_ASSERT(type == TokenKind::String || type == TokenKind::TemplateHead || type == TokenKind::NoSubsTemplate); return u.atom; diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index afd28196bb..9461c9876c 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -31,6 +31,7 @@ #include "frontend/BytecodeCompiler.h" #include "frontend/Parser.h" +#include "frontend/ParserAtom.h" #include "frontend/ReservedWords.h" #include "js/CharacterEncoding.h" #include "js/RegExpFlags.h" // JS::RegExpFlags @@ -123,22 +124,10 @@ MOZ_ALWAYS_INLINE const ReservedWordInfo* FindReservedWord( return FindReservedWord(Utf8AsUnsignedChars(units), length); } +template static const ReservedWordInfo* FindReservedWord( - JSLinearString* str, js::frontend::NameVisibility* visibility) { - JS::AutoCheckCannotGC nogc; - if (str->hasLatin1Chars()) { - const JS::Latin1Char* chars = str->latin1Chars(nogc); - size_t length = str->length(); - if (length > 0 && chars[0] == '#') { - *visibility = js::frontend::NameVisibility::Private; - return nullptr; - } - *visibility = js::frontend::NameVisibility::Public; - return FindReservedWord(chars, length); - } - - const char16_t* chars = str->twoByteChars(nogc); - size_t length = str->length(); + const CharT* chars, size_t length, + js::frontend::NameVisibility* visibility) { if (length > 0 && chars[0] == '#') { *visibility = js::frontend::NameVisibility::Private; return nullptr; @@ -147,6 +136,24 @@ static const ReservedWordInfo* FindReservedWord( return FindReservedWord(chars, length); } +static const ReservedWordInfo* FindReservedWord( + JSLinearString* str, js::frontend::NameVisibility* visibility) { + JS::AutoCheckCannotGC nogc; + if (str->hasLatin1Chars()) { + return FindReservedWord(str->latin1Chars(nogc), str->length(), visibility); + } + return FindReservedWord(str->twoByteChars(nogc), str->length(), visibility); +} + +static const ReservedWordInfo* FindReservedWord( + const js::frontend::ParserAtomEntry* atom, + js::frontend::NameVisibility* visibility) { + if (atom->hasLatin1Chars()) { + return FindReservedWord(atom->latin1Chars(), atom->length(), visibility); + } + return FindReservedWord(atom->twoByteChars(), atom->length(), visibility); +} + static uint32_t GetSingleCodePoint(const char16_t** p, const char16_t* end) { using namespace js; @@ -198,6 +205,12 @@ bool IsIdentifier(JSLinearString* str) { } return IsIdentifier(str->twoByteChars(nogc), str->length()); } +bool IsIdentifier(const ParserAtom* atom) { + MOZ_ASSERT(atom); + return atom->hasLatin1Chars() + ? IsIdentifier(atom->latin1Chars(), atom->length()) + : IsIdentifier(atom->twoByteChars(), atom->length()); +} bool IsIdentifierNameOrPrivateName(JSLinearString* str) { JS::AutoCheckCannotGC nogc; @@ -207,6 +220,12 @@ bool IsIdentifierNameOrPrivateName(JSLinearString* str) { } return IsIdentifierNameOrPrivateName(str->twoByteChars(nogc), str->length()); } +bool IsIdentifierNameOrPrivateName(const ParserAtom* atom) { + if (atom->hasLatin1Chars()) { + return IsIdentifierNameOrPrivateName(atom->latin1Chars(), atom->length()); + } + return IsIdentifierNameOrPrivateName(atom->twoByteChars(), atom->length()); +} bool IsIdentifier(const Latin1Char* chars, size_t length) { if (length == 0) { @@ -300,6 +319,14 @@ bool IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length) { return true; } +bool IsKeyword(const ParserAtom* atom) { + NameVisibility visibility; + if (const ReservedWordInfo* rw = FindReservedWord(atom, &visibility)) { + return TokenKindIsKeyword(rw->tokentype); + } + + return false; +} bool IsKeyword(JSLinearString* str) { NameVisibility visibility; if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) { @@ -309,9 +336,9 @@ bool IsKeyword(JSLinearString* str) { return false; } -TokenKind ReservedWordTokenKind(PropertyName* str) { +TokenKind ReservedWordTokenKind(const ParserName* name) { NameVisibility visibility; - if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) { + if (const ReservedWordInfo* rw = FindReservedWord(name, &visibility)) { return rw->tokentype; } @@ -319,9 +346,9 @@ TokenKind ReservedWordTokenKind(PropertyName* str) { : TokenKind::Name; } -const char* ReservedWordToCharZ(PropertyName* str) { +const char* ReservedWordToCharZ(const ParserName* name) { NameVisibility visibility; - if (const ReservedWordInfo* rw = FindReservedWord(str, &visibility)) { + if (const ReservedWordInfo* rw = FindReservedWord(name, &visibility)) { return ReservedWordToCharZ(rw->tokentype); } @@ -342,13 +369,13 @@ const char* ReservedWordToCharZ(TokenKind tt) { return nullptr; } -PropertyName* TokenStreamAnyChars::reservedWordToPropertyName( +const ParserName* TokenStreamAnyChars::reservedWordToPropertyName( TokenKind tt) const { MOZ_ASSERT(tt != TokenKind::Name); switch (tt) { #define EMIT_CASE(word, name, type) \ case type: \ - return cx->names().name; + return cx->parserNames().name; FOR_EACH_JAVASCRIPT_RESERVED_WORD(EMIT_CASE) #undef EMIT_CASE default: @@ -1889,6 +1916,7 @@ TokenStreamSpecific::matchIdentifierStart( IdentifierEscapes* sawEscape) { int32_t unit = getCodeUnit(); if (unicode::IsIdentifierStart(char16_t(unit))) { + ungetCodeUnit(unit); *sawEscape = IdentifierEscapes::None; return true; } @@ -2221,7 +2249,7 @@ MOZ_MUST_USE bool TokenStreamSpecific::identifierName( } } - JSAtom* atom; + const ParserAtom* atom = nullptr; if (MOZ_UNLIKELY(escaping == IdentifierEscapes::SawUnicodeEscape)) { // Identifiers containing Unicode escapes have to be converted into // tokenbuf before atomizing. @@ -2229,7 +2257,7 @@ MOZ_MUST_USE bool TokenStreamSpecific::identifierName( return false; } - atom = drainCharBufferIntoAtom(anyCharsAccess().cx); + atom = drainCharBufferIntoAtom(); } else { // Escape-free identifiers can be created directly from sourceUnits. const Unit* chars = identStart; @@ -2245,7 +2273,7 @@ MOZ_MUST_USE bool TokenStreamSpecific::identifierName( } } - atom = atomizeSourceChars(anyCharsAccess().cx, MakeSpan(chars, length)); + atom = atomizeSourceChars(MakeSpan(chars, length)); } if (!atom) { return false; @@ -2253,10 +2281,10 @@ MOZ_MUST_USE bool TokenStreamSpecific::identifierName( noteBadToken.release(); if (visibility == NameVisibility::Private) { - newPrivateNameToken(atom->asPropertyName(), start, modifier, out); + newPrivateNameToken(atom->asName(), start, modifier, out); return true; } - newNameToken(atom->asPropertyName(), start, modifier, out); + newNameToken(atom->asName(), start, modifier, out); return true; } @@ -2924,6 +2952,7 @@ MOZ_MUST_USE bool TokenStreamSpecific::getTokenInternal( if (!strictModeError(JSMSG_DEPRECATED_OCTAL)) { return badToken(); } + anyCharsAccess().flags.sawDeprecatedOctal = true; radix = 8; isLegacyOctalOrNoctal = true; @@ -3602,7 +3631,7 @@ bool TokenStreamSpecific::getStringOrTemplateToken( if (!strictModeError(JSMSG_DEPRECATED_OCTAL)) { return false; } - anyChars.flags.sawOctalEscape = true; + anyChars.flags.sawDeprecatedOctal = true; } if (IsAsciiOctal(unit)) { @@ -3666,7 +3695,7 @@ bool TokenStreamSpecific::getStringOrTemplateToken( } } - JSAtom* atom = drainCharBufferIntoAtom(anyCharsAccess().cx); + const ParserAtom* atom = drainCharBufferIntoAtom(); if (!atom) { return false; } diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 02cf43ed32..c5f2fac1f7 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -203,6 +203,7 @@ #include "frontend/CompilationInfo.h" #include "frontend/ErrorReporter.h" +#include "frontend/ParserAtom.h" #include "frontend/Token.h" #include "frontend/TokenKind.h" #include "js/CompileOptions.h" @@ -221,24 +222,29 @@ struct KeywordInfo; namespace js { -class AutoKeepAtoms; - namespace frontend { -extern TokenKind ReservedWordTokenKind(PropertyName* str); +extern TokenKind ReservedWordTokenKind(const ParserName* name); -extern const char* ReservedWordToCharZ(PropertyName* str); +extern const char* ReservedWordToCharZ(const ParserName* name); extern const char* ReservedWordToCharZ(TokenKind tt); struct TokenStreamFlags { - bool isEOF : 1; // Hit end of file. - bool isDirtyLine : 1; // Non-whitespace since start of line. - bool sawOctalEscape : 1; // Saw an octal character escape. - bool hadError : 1; // Hit a syntax error, at start or during a - // token. - - TokenStreamFlags() : isEOF(), isDirtyLine(), sawOctalEscape(), hadError() {} + // Hit end of file. + bool isEOF : 1; + // Non-whitespace since start of line. + bool isDirtyLine : 1; + // Saw an octal character escape or a 0-prefixed octal literal. + bool sawDeprecatedOctal : 1; + // Hit a syntax error, at start or during a token. + bool hadError : 1; + + TokenStreamFlags() + : isEOF(false), + isDirtyLine(false), + sawDeprecatedOctal(false), + hadError(false) {} }; template @@ -286,16 +292,8 @@ class TokenStreamSpecific; template class MOZ_STACK_CLASS TokenStreamPosition final { public: - // The JS_HAZ_ROOTED is permissible below because: 1) the only field in - // TokenStreamPosition that can keep GC things alive is Token, 2) the only - // GC things Token can keep alive are atoms, and 3) the AutoKeepAtoms& - // passed to the constructor here represents that collection of atoms - // is disabled while atoms in Tokens in this Position are alive. DON'T - // ADD NON-ATOM GC THING POINTERS HERE! They would create a rooting - // hazard that JS_HAZ_ROOTED will cause to be ignored. template - inline TokenStreamPosition( - AutoKeepAtoms& keepAtoms, + inline explicit TokenStreamPosition( TokenStreamSpecific& tokenStream); private: @@ -316,7 +314,7 @@ class MOZ_STACK_CLASS TokenStreamPosition final { Token currentToken; unsigned lookahead; Token lookaheadTokens[TokenStreamShared::maxLookahead]; -} JS_HAZ_ROOTED; +}; template class SourceUnits; @@ -721,10 +719,10 @@ class TokenStreamAnyChars : public TokenStreamShared { MOZ_MUST_USE bool checkOptions(); private: - PropertyName* reservedWordToPropertyName(TokenKind tt) const; + const ParserName* reservedWordToPropertyName(TokenKind tt) const; public: - PropertyName* currentName() const { + const ParserName* currentName() const { if (isCurrentTokenType(TokenKind::Name) || isCurrentTokenType(TokenKind::PrivateName)) { return currentToken().name(); @@ -738,7 +736,8 @@ class TokenStreamAnyChars : public TokenStreamShared { if (isCurrentTokenType(TokenKind::Name) || isCurrentTokenType(TokenKind::PrivateName)) { TokenPos pos = currentToken().pos; - return (pos.end - pos.begin) != currentToken().name()->length(); + const ParserAtom* name = currentToken().name(); + return (pos.end - pos.begin) != name->length(); } MOZ_ASSERT(TokenKindIsPossibleIdentifierName(currentToken().type)); @@ -751,9 +750,9 @@ class TokenStreamAnyChars : public TokenStreamShared { // Flag methods. bool isEOF() const { return flags.isEOF; } - bool sawOctalEscape() const { return flags.sawOctalEscape; } + bool sawDeprecatedOctal() const { return flags.sawDeprecatedOctal; } bool hadError() const { return flags.hadError; } - void clearSawOctalEscape() { flags.sawOctalEscape = false; } + void clearSawDeprecatedOctal() { flags.sawDeprecatedOctal = false; } bool hasInvalidTemplateEscape() const { return invalidTemplateEscapeType != InvalidEscapeType::None; @@ -1498,6 +1497,8 @@ class TokenStreamCharsShared { using CharBuffer = Vector; protected: + JSContext* cx; + /** * Buffer transiently used to store sequences of identifier or string code * points when such can't be directly processed from the original source @@ -1511,7 +1512,7 @@ class TokenStreamCharsShared { protected: explicit TokenStreamCharsShared(JSContext* cx, CompilationInfo* compilationInfo) - : charBuffer(cx), compilationInfo(compilationInfo) {} + : cx(cx), charBuffer(cx), compilationInfo(compilationInfo) {} MOZ_MUST_USE bool appendCodePointToCharBuffer(uint32_t codePoint); @@ -1528,10 +1529,16 @@ class TokenStreamCharsShared { return mozilla::IsAscii(static_cast(unit)); } - JSAtom* drainCharBufferIntoAtom(JSContext* cx) { - JSAtom* atom = AtomizeChars(cx, charBuffer.begin(), charBuffer.length()); + const ParserAtom* drainCharBufferIntoAtom() { + // Add to parser atoms table. + auto maybeId = this->compilationInfo->stencil.parserAtoms.internChar16( + cx, charBuffer.begin(), charBuffer.length()); + if (maybeId.isErr()) { + return nullptr; + } + charBuffer.clear(); - return atom; + return maybeId.unwrap(); } protected: @@ -1593,8 +1600,8 @@ class TokenStreamCharsBase : public TokenStreamCharsShared { sourceUnits.ungetCodeUnit(); } - static MOZ_ALWAYS_INLINE JSAtom* atomizeSourceChars( - JSContext* cx, mozilla::Span units); + MOZ_ALWAYS_INLINE const ParserAtom* atomizeSourceChars( + mozilla::Span units); /** * Try to match a non-LineTerminator ASCII code point. Return true iff it @@ -1680,18 +1687,21 @@ inline void TokenStreamCharsBase::consumeKnownCodeUnit(int32_t unit) { } template <> -/* static */ MOZ_ALWAYS_INLINE JSAtom* +MOZ_ALWAYS_INLINE const ParserAtom* TokenStreamCharsBase::atomizeSourceChars( - JSContext* cx, mozilla::Span units) { - return AtomizeChars(cx, units.data(), units.size()); + mozilla::Span units) { + return this->compilationInfo->stencil.parserAtoms + .internChar16(cx, units.data(), units.size()) + .unwrapOr(nullptr); } template <> -/* static */ MOZ_ALWAYS_INLINE JSAtom* +/* static */ MOZ_ALWAYS_INLINE const ParserAtom* TokenStreamCharsBase::atomizeSourceChars( - JSContext* cx, mozilla::Span units) { - auto chars = ToCharSpan(units); - return AtomizeUTF8Chars(cx, chars.data(), chars.size()); + mozilla::Span units) { + return this->compilationInfo->stencil.parserAtoms + .internUtf8(cx, units.data(), units.size()) + .unwrapOr(nullptr); } template @@ -1975,7 +1985,7 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase { newToken(TokenKind::BigInt, start, modifier, out); } - void newAtomToken(TokenKind kind, JSAtom* atom, TokenStart start, + void newAtomToken(TokenKind kind, const ParserAtom* atom, TokenStart start, TokenStreamShared::Modifier modifier, TokenKind* out) { MOZ_ASSERT(kind == TokenKind::String || kind == TokenKind::TemplateHead || kind == TokenKind::NoSubsTemplate); @@ -1984,13 +1994,13 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase { token->setAtom(atom); } - void newNameToken(PropertyName* name, TokenStart start, + void newNameToken(const ParserName* name, TokenStart start, TokenStreamShared::Modifier modifier, TokenKind* out) { Token* token = newToken(TokenKind::Name, start, modifier, out); token->setName(name); } - void newPrivateNameToken(PropertyName* name, TokenStart start, + void newPrivateNameToken(const ParserName* name, TokenStart start, TokenStreamShared::Modifier modifier, TokenKind* out) { Token* token = newToken(TokenKind::PrivateName, start, modifier, out); @@ -2103,7 +2113,7 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase { */ void consumeOptionalHashbangComment(); - JSAtom* getRawTemplateStringAtom() { + const ParserAtom* getRawTemplateStringAtom() { TokenStreamAnyChars& anyChars = anyCharsAccess(); MOZ_ASSERT(anyChars.currentToken().type == TokenKind::TemplateHead || @@ -2132,7 +2142,7 @@ class GeneralTokenStreamChars : public SpecializedTokenStreamCharsBase { return nullptr; } - return drainCharBufferIntoAtom(anyChars.cx); + return drainCharBufferIntoAtom(); } }; @@ -2862,7 +2872,6 @@ class MOZ_STACK_CLASS TokenStreamSpecific template template inline TokenStreamPosition::TokenStreamPosition( - AutoKeepAtoms& keepAtoms, TokenStreamSpecific& tokenStream) : currentToken(tokenStream.anyCharsAccess().currentToken()) { TokenStreamAnyChars& anyChars = tokenStream.anyCharsAccess(); diff --git a/js/src/frontend/TryEmitter.cpp b/js/src/frontend/TryEmitter.cpp index d9febd70cb..8d7854a1ee 100644 --- a/js/src/frontend/TryEmitter.cpp +++ b/js/src/frontend/TryEmitter.cpp @@ -45,7 +45,8 @@ bool TryEmitter::emitTry() { // uses this depth to properly unwind the stack and the scope chain. depth_ = bce_->bytecodeSection().stackDepth(); - if (!bce_->emitN(JSOp::Try, 4, &tryOpOffset_)) { + tryOpOffset_ = bce_->bytecodeSection().offset(); + if (!bce_->emit1(JSOp::Try)) { return false; } @@ -66,12 +67,6 @@ bool TryEmitter::emitTryEnd() { } } - // Patch the JSOp::Try offset. - jsbytecode* trypc = bce_->bytecodeSection().code(tryOpOffset_); - BytecodeOffsetDiff offset = bce_->bytecodeSection().offset() - tryOpOffset_; - MOZ_ASSERT(JSOp(*trypc) == JSOp::Try); - SET_CODE_OFFSET(trypc, offset.value()); - // Emit jump over catch and/or finally. if (!bce_->emitJump(JSOp::Goto, &catchAndFinallyJump_)) { return false; diff --git a/js/src/frontend/TypedIndex.h b/js/src/frontend/TypedIndex.h index 9a10716a6d..c699e53bba 100644 --- a/js/src/frontend/TypedIndex.h +++ b/js/src/frontend/TypedIndex.h @@ -15,7 +15,7 @@ namespace frontend { template struct TypedIndex { TypedIndex() = default; - explicit TypedIndex(uint32_t index) : index(index){}; + constexpr explicit TypedIndex(uint32_t index) : index(index){}; uint32_t index = 0; @@ -26,6 +26,11 @@ struct TypedIndex { index = idx; return *this; } + + bool operator<(TypedIndex other) { return index < other.index; } + bool operator<=(TypedIndex other) { return index <= other.index; } + bool operator>(TypedIndex other) { return index > other.index; } + bool operator>=(TypedIndex other) { return index >= other.index; } }; } // namespace frontend diff --git a/js/src/frontend/UsedNameTracker.h b/js/src/frontend/UsedNameTracker.h index 54eb26ca02..442c2f03e6 100644 --- a/js/src/frontend/UsedNameTracker.h +++ b/js/src/frontend/UsedNameTracker.h @@ -7,6 +7,7 @@ #include "mozilla/Attributes.h" +#include "frontend/Token.h" #include "js/AllocPolicy.h" #include "js/HashTable.h" #include "js/Vector.h" @@ -18,36 +19,88 @@ namespace frontend { // A data structure for tracking used names per parsing session in order to // compute which bindings are closed over. Scripts and scopes are numbered -// monotonically in textual order and name uses are tracked by lists of -// (script id, scope id) pairs of their use sites. +// monotonically in textual order and unresolved uses of a name are tracked by +// lists of identifier uses, which are a pair of (ScriptId,ScopeId). // -// Intuitively, in a pair (P,S), P tracks the most nested function that has a -// use of u, and S tracks the most nested scope that is still being parsed. +// For an identifier `i` with a use (ScriptId,ScopeId) in the Used list, +// ScriptId tracks the most nested script that has a use of u, and ScopeId +// tracks the most nested scope that is still being parsed (as the lists will be +// filtered as we finish processing a particular scope). // -// P is used to answer the question "is u used by a nested function?" -// S is used to answer the question "is u used in any scopes currently being -// parsed?" +// ScriptId is used to answer the question "is `i` used by a nested function?" +// ScopeId is used to answer the question "is `i` used in any scopes currently +// being parsed?" // // The algorithm: // -// Let Used by a map of names to lists. +// Let Used be a map of names to lists. +// Let Declared(ScopeId) be a list of declarations for a scope numbered with +// ScopeId // // 1. Number all scopes in monotonic increasing order in textual order. // 2. Number all scripts in monotonic increasing order in textual order. -// 3. When an identifier u is used in scope numbered S in script numbered P, -// and u is found in Used, -// a. Append (P,S) to Used[u]. -// b. Otherwise, assign the the list [(P,S)] to Used[u]. -// 4. When we finish parsing a scope S in script P, for each declared name d in -// Declared(S): +// 3. When an identifier `i` is used in (ScriptId,ScopeId), append that use to +// the list Used[i] (creating the list and table entry if necessary). +// 4. When an identifier `i` is declared in a scope numbered ScopeId, append `i` +// to Declared(ScopeId). +// 5. When we finish parsing a scope numbered with ScopeId, in script numbered +// ScriptId, for each declared name d in Declared(ScopeId): // a. If d is found in Used, mark d as closed over if there is a value -// (P_d, S_d) in Used[d] such that P_d > P and S_d > S. -// b. Remove all values (P_d, S_d) in Used[d] such that S_d are >= S. +// (UsedScriptId, UsedScopeId) in Used[d] such that UsedScriptId > ScriptId +// and UsedScopeId > ScopeId. +// b. Remove all values uses in Used[d] where UsedScopeId > ScopeId. // // Steps 1 and 2 are implemented by UsedNameTracker::next{Script,Scope}Id. // Step 3 is implemented by UsedNameTracker::noteUsedInScope. -// Step 4 is implemented by UsedNameTracker::noteBoundInScope and -// Parser::propagateFreeNamesAndMarkClosedOverBindings. +// Step 4 is implemented by ParseContext::Scope::addDeclaredName. +// Step 5 is implemented by UsedNameTracker::noteBoundInScope and +// Parser::propagateFreeNamesAndMarkClosedOverBindings +// +// The following is a worked example to show how the algorithm works on a +// relatively simple piece of code. (clang-format is disabled due to the width +// of the example). + +// clang-format off +// +// // Script 1, Scope 1 +// var x = 1; // Declared(1) = [x]; +// function f() {// Script 2, Scope 2 +// if (x > 10) { //Scope 3 // Used[x] = [(2,2)]; +// var x = 12; // Declared(3) = [x]; +// function g() // Script 3 +// { // Scope 4 +// return x; // Used[x] = [(2,2), (3,4)] +// } // Leaving Script 3, Scope 4: No declared variables. +// } // Leaving Script 2, Scope 3: Declared(3) = [x]; +// // - Used[x][1] = (2,2) is not > (2,3) +// // - Used[x][2] = (3,4) is > (2,3), so mark x as closed over. +// // - Update Used[x]: [] -- Makes sense, as at this point we have +// // bound all the unbound x to a particlar +// // declaration.. +// +// else { // Scope 5 +// var x = 14; // Declared(5) = [x] +// function g() // Script 4 +// { // Scope 6 +// return y; // Used[y] = [(4,6)] +// } // Leaving Script 4, Scope 6: No declarations. +// } // Leaving Script 2, Scope 5: Declared(5) = [x] +// // - Used[x] = [], so don't mark x as closed over. +// var y = 12; // Declared(2) = [y] +// } // Leaving Script 2, Scope 2: Declared(2) = [y] +// // - Used[y][1] = (4,6) is > (2,2), so mark y as closed over. +// // - Update Used[y]: []. + +// clang-format on + +struct UnboundPrivateName { + const ParserAtom* atom; + TokenPos position; + + UnboundPrivateName(const ParserAtom* atom, TokenPos position) + : atom(atom), position(position) {} +}; + class UsedNameTracker { public: struct Use { @@ -62,10 +115,19 @@ class UsedNameTracker { void resetToScope(uint32_t scriptId, uint32_t scopeId); + NameVisibility visibility_ = NameVisibility::Public; + + // The first place this name was used. This is important to track + // for private names, as we will use this location to issue + // diagnostics for using a name that's not defined lexically. + mozilla::Maybe firstUsePos_; + public: - explicit UsedNameInfo(JSContext* cx) : uses_(cx) {} + explicit UsedNameInfo(JSContext* cx, NameVisibility visibility, + mozilla::Maybe position) + : uses_(cx), visibility_(visibility), firstUsePos_(position) {} - UsedNameInfo(UsedNameInfo&& other) : uses_(std::move(other.uses_)) {} + UsedNameInfo(UsedNameInfo&& other) = default; bool noteUsedInScope(uint32_t scriptId, uint32_t scopeId) { if (uses_.empty() || uses_.back().scopeId < scopeId) { @@ -92,9 +154,28 @@ class UsedNameTracker { bool isUsedInScript(uint32_t scriptId) const { return !uses_.empty() && uses_.back().scriptId >= scriptId; } + + // To allow disambiguating public and private symbols + bool isPublic() { return visibility_ == NameVisibility::Public; } + + bool empty() { return uses_.empty(); } + + mozilla::Maybe pos() { return firstUsePos_; } + + // When we leave a scope, and subsequently find a new private name + // reference, we don't want our error messages to be attributed to an old + // scope, so we update the position in that scenario. + void maybeUpdatePos(mozilla::Maybe p) { + MOZ_ASSERT_IF(!isPublic(), p.isSome()); + + if (empty() && !isPublic()) { + firstUsePos_ = p; + } + } }; - using UsedNameMap = HashMap>; + using UsedNameMap = HashMap>; private: // The map of names to chains of uses. @@ -106,9 +187,16 @@ class UsedNameTracker { // Monotonically increasing id for all nested scopes. uint32_t scopeCounter_; + // Set if a private name was encountered. + // Used to short circuit some private field early error checks + bool hasPrivateNames_; + public: explicit UsedNameTracker(JSContext* cx) - : map_(cx), scriptCounter_(0), scopeCounter_(0) {} + : map_(cx), + scriptCounter_(0), + scopeCounter_(0), + hasPrivateNames_(false) {} uint32_t nextScriptId() { MOZ_ASSERT(scriptCounter_ != UINT32_MAX, @@ -121,10 +209,24 @@ class UsedNameTracker { return scopeCounter_++; } - UsedNameMap::Ptr lookup(JSAtom* name) const { return map_.lookup(name); } + UsedNameMap::Ptr lookup(const ParserAtom* name) const { + return map_.lookup(name); + } + + MOZ_MUST_USE bool noteUse( + JSContext* cx, const ParserAtom* name, NameVisibility visibility, + uint32_t scriptId, uint32_t scopeId, + mozilla::Maybe tokenPosition = mozilla::Nothing()); + + // Fill maybeUnboundName with the first (source order) unbound name, or + // Nothing() if there are no unbound names. + MOZ_MUST_USE bool hasUnboundPrivateNames( + JSContext* cx, mozilla::Maybe& maybeUnboundName); - MOZ_MUST_USE bool noteUse(JSContext* cx, JSAtom* name, uint32_t scriptId, - uint32_t scopeId); + // Return a list of unbound private names, sorted by increasing location in + // the source. + MOZ_MUST_USE bool getUnboundPrivateNames( + Vector& unboundPrivateNames); struct RewindToken { private: diff --git a/js/src/frontend/binast/Cargo.toml b/js/src/frontend/binast/Cargo.toml deleted file mode 100644 index d8dc7e4e43..0000000000 --- a/js/src/frontend/binast/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "binast" -version = "0.2.0" -authors = ["David Teller "] -autobins = false - -[dependencies] -binjs_meta = "^0.5.2" -clap = "^2" -env_logger = "^0.6" -Inflector = "^0.11" -itertools = "^0.8" -log = "0.4" -yaml-rust = "^0.4.2" - -[[bin]] -name = "binast" -path = "src/main.rs" diff --git a/js/src/frontend/binast/README.md b/js/src/frontend/binast/README.md deleted file mode 100644 index 739c0d44bd..0000000000 --- a/js/src/frontend/binast/README.md +++ /dev/null @@ -1,16 +0,0 @@ -A parser generator used to generate the following files: - -- js/src/frontend/BinASTParser.h -- js/src/frontend/BinASTParser.cpp -- js/src/frontent/BinASTToken.h - -from the following files: - -- js/src/frontend/BinAST.webidl_ (specifications of BinAST) -- js/src/frontend/BinAST.yaml (parser generator driver) - -To use it: -```sh -$ cd $(topsrcdir)/js/src/frontend/binast -% ./build.sh -``` diff --git a/js/src/frontend/binast/build.sh b/js/src/frontend/binast/build.sh deleted file mode 100644 index 22a07d13c4..0000000000 --- a/js/src/frontend/binast/build.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -cargo run -- \ - ../BinAST.webidl_ \ - ../BinAST.yaml \ - --out-class ../BinASTParser-tmp.h \ - --out-impl ../BinASTParser-tmp.cpp \ - --out-enum ../BinASTEnum-tmp.h \ - --out-token ../BinASTToken-tmp.h - - -( - cd ../../../../; - ./mach clang-format -p \ - js/src/frontend/BinASTParser-tmp.h \ - js/src/frontend/BinASTParser-tmp.cpp \ - js/src/frontend/BinASTEnum-tmp.h \ - js/src/frontend/BinASTToken-tmp.h -) - -# Usage: update SRC DST -# -# If SRC file and DST file have different content, move SRC file to DST file. -# If not, remove SRC file. -update() { - SRC=$1 - DST=$2 - - if diff -q ${SRC} ${DST} > /dev/null; then - echo "SKIPPED: ${DST} was not modified" - rm ${SRC} - else - echo "UPDATED: ${DST} was modified" - mv ${SRC} ${DST} - fi -} - -update ../BinASTParser-tmp.h ../BinASTParser.h -update ../BinASTParser-tmp.cpp ../BinASTParser.cpp -update ../BinASTEnum-tmp.h ../BinASTEnum.h -update ../BinASTToken-tmp.h ../BinASTToken.h diff --git a/js/src/frontend/binast/moz.build b/js/src/frontend/binast/moz.build deleted file mode 100644 index 0d8ae99bab..0000000000 --- a/js/src/frontend/binast/moz.build +++ /dev/null @@ -1,5 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_RUST_PROGRAMS += ['binast'] diff --git a/js/src/frontend/binast/src/main.rs b/js/src/frontend/binast/src/main.rs deleted file mode 100644 index 94f8c18549..0000000000 --- a/js/src/frontend/binast/src/main.rs +++ /dev/null @@ -1,3074 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -extern crate binjs_meta; -extern crate clap; -extern crate env_logger; -extern crate inflector; -extern crate itertools; -#[macro_use] extern crate log; -extern crate yaml_rust; - -use binjs_meta::export::{ ToWebidl, TypeDeanonymizer, TypeName }; -use binjs_meta::import::Importer; -use binjs_meta::spec::*; -use binjs_meta::util:: { Reindentable, ToCases, ToStr }; - -mod refgraph; - -use refgraph::{ ReferenceGraph }; - -use std::borrow::Cow; -use std::collections::{ HashMap, HashSet }; -use std::fs::*; -use std::io::{ Read, Write }; -use std::rc::Rc; - -use clap::{ App, Arg }; - -use itertools::Itertools; - -/// An extension of `ToCases` to produce macro-style names, e.g. `FOO_BAR` -/// from `FooBar` or `foo_bar`. -trait ToCases2: ToCases { - fn to_cpp_macro_case(&self) -> String { - use inflector::cases::screamingsnakecase::to_screaming_snake_case; - to_screaming_snake_case(&self.to_cpp_enum_case()) - } -} -impl ToCases2 for T {} - -/// Rules for generating the code for parsing a single field -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct FieldRules { - /// Declaring the variable to hold the contents of that field. - declare: Option, - - /// Replace the declaration and assignation. - replace: Option, - - /// Things to add before the field, typically for checking invariants. - before_field: Option, - - /// Things to add after the field, typically for checking invariants. - after_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// putting guard values on the stack. - block_before_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// cleanup. - block_after_field: Option, - - /// Extra arguments passed to the method when parsing this field. - extra_args: Option>, -} - -#[derive(Clone, Default)] -struct SumRules { - after_arm: Option, - - // Disable this arm (false by default). - disabled: bool, -} - - -/// Rules for generating the code for parsing a full node -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct NodeRules { - /// This node inherits from another node. - inherits: Option, - - /// Override the result type for the method. - type_ok: Option>, - - /// Default value for the optional field. - default_value: Option>, - - /// Extra parameters for the method. - extra_params: Option>, - - /// Extra arguments passed to the method when parsing this interface. - /// For ListOf* interfaces, this arguments are passed to each item. - /// For sum interface, this arguments are passed to each interface. - extra_args: Option>, - - /// Things to add before calling the method when the optional field has - /// value. - some_before: Option>, - - /// Things to add after calling the method when the optional field has - /// value. - some_after: Option>, - - /// Replace the assignment when the option field has no value. - none_replace: Option>, - - /// Stuff to add at start. - init: Option, - - /// How to append to a list. Used only for lists. - append: Option, - - /// Custom per-field treatment. Used only for interfaces. - by_field: HashMap, - - by_sum: HashMap, - - /// How to build the result, eventually. - build_result: Option, -} - -/// Rules for generating entire files. -/// -/// Extracted from the yaml file. -#[derive(Default)] -struct GlobalRules { - /// C++ class name of the parser class. - parser_class_name: Rc, - - /// The template part of the parser class. - parser_class_template: Rc, - - /// The return value of each method. - parser_type_ok: Rc, - - /// Default value for the optional field. - parser_default_value: Rc, - - /// Code to append the list item. - parser_list_append: Option>, - - /// Header to add at the start of the .cpp file. - cpp_header: Option, - - /// Header to add at the end of the .cpp file. - cpp_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the class. - hpp_class_header: Option, - - /// Footer to add at the end of the .hpp file - /// defining the class. - hpp_class_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the enums. - hpp_enums_header: Option, - - /// Footer to add at the end of the .hpp file - /// defining the enums. - hpp_enums_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_header: Option, - - /// Footer to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_footer: Option, - - /// Documentation for the `BinASTKind` class enum. - hpp_tokens_kind_doc: Option, - - /// Documentation for the `BinASTField` class enum. - hpp_tokens_field_doc: Option, - - /// Documentation for the `BinASTVariant` class enum. - hpp_tokens_variants_doc: Option, - - /// Per-node rules. - per_node: HashMap, -} -impl GlobalRules { - fn new(syntax: &Spec, yaml: &yaml_rust::yaml::Yaml) -> Self { - let rules = yaml.as_hash() - .expect("Rules are not a dictionary"); - - let mut parser_class_name = None; - let mut parser_class_template = None; - let mut parser_type_ok = None; - let mut parser_default_value = None; - let mut parser_list_append = None; - let mut cpp_header = None; - let mut cpp_footer = None; - let mut hpp_class_header = None; - let mut hpp_class_footer = None; - let mut hpp_enums_header = None; - let mut hpp_enums_footer = None; - let mut hpp_tokens_header = None; - let mut hpp_tokens_footer = None; - let mut hpp_tokens_kind_doc = None; - let mut hpp_tokens_field_doc = None; - let mut hpp_tokens_variants_doc = None; - let mut per_node = HashMap::new(); - - for (node_key, node_entries) in rules.iter() { - let node_key = node_key.as_str() - .expect("Could not convert node_key to string"); - - match node_key { - "parser" => { - update_rule_rc(&mut parser_class_name, &node_entries["class-name"]) - .unwrap_or_else(|_| panic!("Rule parser.class-name must be a string")); - update_rule(&mut parser_class_template, &node_entries["class-template"]) - .unwrap_or_else(|_| panic!("Rule parser.class-template must be a string")); - update_rule_rc(&mut parser_type_ok, &node_entries["type-ok"]) - .unwrap_or_else(|_| panic!("Rule parser.type-ok must be a string")); - update_rule_rc(&mut parser_default_value, &node_entries["default-value"]) - .unwrap_or_else(|_| panic!("Rule parser.default-value must be a string")); - update_rule_rc(&mut parser_list_append, &node_entries["list"]["append"]) - .unwrap_or_else(|_| panic!("Rule parser.list.append must be a string")); - continue; - } - "cpp" => { - update_rule(&mut cpp_header, &node_entries["header"]) - .unwrap_or_else(|_| panic!("Rule cpp.header must be a string")); - update_rule(&mut cpp_footer, &node_entries["footer"]) - .unwrap_or_else(|_| panic!("Rule cpp.footer must be a string")); - continue; - } - "hpp" => { - update_rule(&mut hpp_class_header, &node_entries["class"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.class.header must be a string")); - update_rule(&mut hpp_class_footer, &node_entries["class"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.class.footer must be a string")); - update_rule(&mut hpp_enums_header, &node_entries["enums"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.enum.header must be a string")); - update_rule(&mut hpp_enums_footer, &node_entries["enums"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.enum.footer must be a string")); - update_rule(&mut hpp_tokens_header, &node_entries["tokens"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.header must be a string")); - update_rule(&mut hpp_tokens_footer, &node_entries["tokens"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.footer must be a string")); - update_rule(&mut hpp_tokens_kind_doc, &node_entries["tokens"]["kind"]["doc"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.kind.doc must be a string")); - update_rule(&mut hpp_tokens_field_doc, &node_entries["tokens"]["field"]["doc"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.field.doc must be a string")); - update_rule(&mut hpp_tokens_variants_doc, &node_entries["tokens"]["variants"]["doc"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.variants.doc must be a string")); - continue; - } - _ => {} - } - - - let node_name = syntax.get_node_name(&node_key) - .unwrap_or_else(|| panic!("Unknown node name {}", node_key)); - - let hash = node_entries.as_hash() - .unwrap_or_else(|| panic!("Node {} isn't a dictionary")); - - let mut node_rule = NodeRules::default(); - for (node_item_key, node_item_entry) in hash { - let as_string = node_item_key.as_str() - .unwrap_or_else(|| panic!("Keys for rule {} must be strings", node_key)); - match as_string { - "inherits" => { - let name = node_item_entry.as_str() - .unwrap_or_else(|| panic!("Rule {}.{} must be a string", node_key, as_string)); - let inherits = syntax.get_node_name(name) - .unwrap_or_else(|| panic!("Unknown node name {}", name)); - node_rule.inherits = Some(inherits).cloned(); - } - "extra-params" => { - update_rule_rc(&mut node_rule.extra_params, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "extra-args" => { - update_rule_rc(&mut node_rule.extra_args, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "some" => { - update_rule_rc(&mut node_rule.some_before, &node_item_entry["before"]) - .unwrap_or_else(|()| panic!("Rule {}.{}.before must be a string", node_key, as_string)); - update_rule_rc(&mut node_rule.some_after, &node_item_entry["after"]) - .unwrap_or_else(|()| panic!("Rule {}.{}.after must be a string", node_key, as_string)); - } - "none" => { - update_rule_rc(&mut node_rule.none_replace, &node_item_entry["replace"]) - .unwrap_or_else(|()| panic!("Rule {}.{}.replace must be a string", node_key, as_string)); - } - "init" => { - update_rule(&mut node_rule.init, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "build" => { - update_rule(&mut node_rule.build_result, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "append" => { - update_rule(&mut node_rule.append, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "type-ok" => { - update_rule_rc(&mut node_rule.type_ok, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "default-value" => { - update_rule_rc(&mut node_rule.default_value, node_item_entry) - .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); - } - "fields" => { - let fields = node_item_entry.as_hash() - .unwrap_or_else(|| panic!("Rule {}.fields must be a hash, got {:?}", node_key, node_entries["fields"])); - for (field_key, field_entry) in fields { - let field_key = field_key.as_str() - .unwrap_or_else(|| panic!("In rule {}, field entries must be field names", - node_key)) - .to_string(); - let field_name = syntax.get_field_name(&field_key) - .unwrap_or_else(|| panic!("In rule {}, can't find field {}", - node_key, - field_key)); - - let mut field_rule = FieldRules::default(); - for (field_config_key, field_config_entry) in field_entry.as_hash() - .unwrap_or_else(|| panic!("Rule {}.fields.{} must be a hash", node_key, field_key)) - { - let field_config_key = field_config_key.as_str() - .expect("Expected a string as a key"); - match field_config_key - { - "block" => { - update_rule(&mut field_rule.declare, &field_config_entry["declare"]) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "declare")); - - update_rule(&mut field_rule.replace, &field_config_entry["replace"]) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "replace")); - - update_rule(&mut field_rule.block_before_field, &field_config_entry["before"]) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "before")); - - update_rule(&mut field_rule.block_after_field, &field_config_entry["after"]) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "after")); - } - "before" => { - update_rule(&mut field_rule.before_field, &field_config_entry) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); - } - "after" => { - update_rule(&mut field_rule.after_field, &field_config_entry) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); - } - "extra-args" => { - update_rule_rc(&mut field_rule.extra_args, &field_config_entry) - .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); - } - _ => { - panic!("Unexpected {}.fields.{}.{}", node_key, field_key, field_config_key) - } - } - } - node_rule.by_field.insert(field_name.clone(), field_rule); - } - } - "sum-arms" => { - let arms = node_item_entry.as_hash() - .unwrap_or_else(|| panic!("Rule {}.sum-arms must be a hash, got {:?}", node_key, node_entries["sum-arms"])); - for (sum_arm_key, sum_arm_entry) in arms { - let sum_arm_key = sum_arm_key.as_str() - .unwrap_or_else(|| panic!("In rule {}, sum arms must be interface names")); - let sum_arm_name = syntax.get_node_name(&sum_arm_key) - .unwrap_or_else(|| panic!("In rule {}. cannot find interface {}", node_key, sum_arm_key)); - - let mut sum_rule = SumRules::default(); - for (arm_config_key, arm_config_entry) in sum_arm_entry.as_hash() - .unwrap_or_else(|| panic!("Rule {}.sum-arms.{} must be a hash", node_key, sum_arm_key)) - { - let arm_config_key = arm_config_key.as_str() - .expect("Expected a string as a key"); - match arm_config_key - { - "after" => { - update_rule(&mut sum_rule.after_arm, arm_config_entry) - .unwrap_or_else(|()| panic!("Rule {}.sum-arms.{}.{} must be a string", node_key, sum_arm_key, arm_config_key)); - } - "disabled" => { - if let Some(disabled) = arm_config_entry.as_bool() { - if disabled { - sum_rule.disabled = true; - } - } else { - panic!("Rule {}.sum-arms.{}.{} must be a bool", node_key, sum_arm_key, arm_config_key); - } - } - _ => { - panic!("Unexpected {}.sum-arms.{}.{}", node_key, sum_arm_key, arm_config_key); - } - } - } - node_rule.by_sum.insert(sum_arm_name.clone(), sum_rule); - } - } - _ => panic!("Unexpected node_item_key {}.{}", node_key, as_string) - } - } - - per_node.insert(node_name.clone(), node_rule); - } - - Self { - parser_class_name: parser_class_name - .expect("parser.class-name should be specified"), - parser_class_template: Rc::new(if parser_class_template.is_some() { - format!("{} ", parser_class_template.unwrap()) - } else { - "".to_string() - }), - parser_type_ok: parser_type_ok - .expect("parser.type-ok should be specified"), - parser_default_value: parser_default_value - .expect("parser.default-value should be specified"), - parser_list_append, - cpp_header, - cpp_footer, - hpp_class_header, - hpp_class_footer, - hpp_enums_header, - hpp_enums_footer, - hpp_tokens_header, - hpp_tokens_footer, - hpp_tokens_kind_doc, - hpp_tokens_field_doc, - hpp_tokens_variants_doc, - per_node, - } - } - fn get(&self, name: &NodeName) -> NodeRules { - let mut rules = self.per_node.get(name) - .cloned() - .unwrap_or_default(); - if let Some(ref parent) = rules.inherits { - let NodeRules { - inherits: _, - type_ok, - default_value, - extra_params, - extra_args, - some_before, - some_after, - none_replace, - init, - append, - by_field, - by_sum, - build_result, - } = self.get(parent); - if rules.type_ok.is_none() { - rules.type_ok = type_ok; - } - if rules.default_value.is_none() { - rules.default_value = default_value; - } - if rules.extra_params.is_none() { - rules.extra_params = extra_params; - } - if rules.extra_args.is_none() { - rules.extra_args = extra_args; - } - if rules.some_before.is_none() { - rules.some_before = some_before; - } - if rules.some_after.is_none() { - rules.some_after = some_after; - } - if rules.none_replace.is_none() { - rules.none_replace = none_replace; - } - if rules.init.is_none() { - rules.init = init; - } - if rules.append.is_none() { - rules.append = append; - } - if rules.build_result.is_none() { - rules.build_result = build_result; - } - for (key, value) in by_field { - rules.by_field.entry(key) - .or_insert(value); - } - for (key, value) in by_sum { - rules.by_sum.entry(key) - .or_insert(value); - } - } - rules - } -} - -/// The inforamtion used to generate a list parser. -#[derive(Clone, Debug)] -struct ListParserData { - /// Name of the node. - name: NodeName, - - /// If `true`, supports empty lists. - supports_empty: bool, - - /// Name of the elements in the list. - elements: NodeName, -} - -/// The inforamtion used to generate a parser for an optional data structure. -struct OptionParserData { - /// Name of the node. - name: NodeName, - - /// Name of the element that may be contained. - elements: NodeName, -} - -/// What to use when calling the method to store the result value. -enum MethodCallKind { - /// Use BINJS_MOZ_TRY_DECL if the result type is not "Ok", - /// use MOZ_TRY otherwise. - Decl, - - /// Always use MOZ_TRY_DECL regardless of the result type. - AlwaysDecl, - - /// Use MOZ_TRY_VAR if the result type is not "Ok", - /// use MOZ_TRY otherwise. - Var, - - /// Always use MOZ_TRY_VAR regardless of the result type. - AlwaysVar, -} - -/// Fixed parameter of interface method. -const INTERFACE_PARAMS: &str = - "const size_t start"; - -/// Fixed arguments of interface method. -const INTERFACE_ARGS: &str = - "start"; - -/// Fixed parameter of sum interface method. -const SUM_INTERFACE_PARAMS: &str = - "const size_t start, const BinASTKind kind"; - -/// Fixed arguments of sum interface method. -const SUM_INTERFACE_ARGS: &str = - "start, kind"; - -/// The name of the toplevel interface for the script. -const TOPLEVEL_INTERFACE: &str = - "Program"; - -/// In which context an interface appears. -#[derive(Clone, Debug, PartialEq)] -struct LookupContext { - /// In root of parsing. - in_root: bool, - - /// In list element. - in_list: bool, - - /// In interface field. - in_field: bool, -} -impl LookupContext { - fn empty() -> Self { - Self { - in_root: false, - in_list: false, - in_field: false, - } - } - - fn root() -> Self { - Self { - in_root: true, - in_list: false, - in_field: false, - } - } - - fn list() -> Self { - Self { - in_root: false, - in_list: true, - in_field: false, - } - } - - fn field() -> Self { - Self { - in_root: false, - in_list: false, - in_field: true, - } - } - - fn is_root(&self) -> bool { - self.in_root && !self.in_list && !self.in_field - } - - fn is_list(&self) -> bool { - !self.in_root && self.in_list && !self.in_field - } - - fn is_field(&self) -> bool { - !self.in_root && !self.in_list && self.in_field - } - - fn is_field_and_list(&self) -> bool { - !self.in_root && self.in_list && self.in_field - } - - fn is_field_and_root(&self) -> bool { - self.in_root && !self.in_list && self.in_field - } - - fn is_single(&self) -> bool { - self.is_root() || self.is_list() || self.is_field() - } - - fn is_valid_double(&self) -> bool { - self.is_field_and_root() || self.is_field_and_list() - } - - fn add(&mut self, rhs: Self) { - self.in_root |= rhs.in_root; - self.in_list |= rhs.in_list; - self.in_field |= rhs.in_field; - } -} - -type ContextMap = HashMap, LookupContext>; - -/// The actual exporter. -struct CPPExporter { - /// The syntax to export. - syntax: Spec, - - /// Rules, as specified in yaml. - rules: GlobalRules, - - /// Reference graph of the method call. - refgraph: ReferenceGraph, - - context_map: ContextMap, - - /// All parsers of lists. - list_parsers_to_generate: Vec, - - /// All parsers of options. - option_parsers_to_generate: Vec, - - /// A subset of `list_parsers_to_generate` guaranteed to have - /// a single representative for each list type, regardless - /// of typedefs. - /// - /// Indexed by the contents of the list. - canonical_list_parsers: HashMap, - - /// A mapping from symbol (e.g. `+`, `-`, `instanceof`, ...) to the - /// name of the symbol as part of `enum class BinASTVariant` - /// (e.g. `UnaryOperatorDelete`). - variants_by_symbol: HashMap, - - // A map from enum class names to the type. - enum_types: HashMap>, -} - -impl CPPExporter { - fn new(syntax: Spec, rules: GlobalRules) -> Self { - let mut list_parsers_to_generate = vec![]; - let mut option_parsers_to_generate = vec![]; - let mut canonical_list_parsers = HashMap::new(); - for (parser_node_name, typedef) in syntax.typedefs_by_name() { - if typedef.is_optional() { - let content_name = TypeName::type_spec(typedef.spec()); - let content_node_name = syntax.get_node_name(&content_name) - .unwrap_or_else(|| panic!("While generating an option parser, could not find node name \"{}\"", content_name)) - .clone(); - debug!(target: "generate_spidermonkey", "CPPExporter::new adding optional typedef {:?} => {:?} => {:?}", - parser_node_name, - content_name, - content_node_name); - option_parsers_to_generate.push(OptionParserData { - name: parser_node_name.clone(), - elements: content_node_name - }); - } else if let TypeSpec::Array { ref contents, ref supports_empty } = *typedef.spec() { - use std::collections::hash_map::Entry::*; - let content_name = TypeName::type_(&**contents); - let content_node_name = syntax.get_node_name(&content_name) - .unwrap_or_else(|| panic!("While generating an array parser, could not find node name {}", content_name)) - .clone(); - debug!(target: "generate_spidermonkey", "CPPExporter::new adding list typedef {:?} => {:?} => {:?}", - parser_node_name, - content_name, - content_node_name); - let data = ListParserData { - name: parser_node_name.clone(), - supports_empty: *supports_empty, - elements: content_node_name - }; - - match canonical_list_parsers.entry(data.elements.clone()) { - Occupied(mut entry) => { - debug!(target: "generate_spidermonkey", "lists: Comparing existing entry {existing:?} and {new:?}", - existing = entry.get(), - new = data); - // HACK: We assume that a parser with name `ListXXX` is more canonical than doesn't start with `List`. - if data.name.to_str().starts_with("List") { - entry.insert(data.clone()); - } - } - Vacant(entry) => { - debug!(target: "generate_spidermonkey", "lists: Inserting {new:?}", - new = data); - entry.insert(data.clone()); - } - } - - list_parsers_to_generate.push(data); - } - } - list_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - option_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - - // Prepare variant_by_symbol, which will let us lookup the BinASTVariant name of - // a symbol. Since some symbols can appear in several enums (e.g. "+" - // is both a unary and a binary operator), we need to collect all the - // string enums that contain each symbol and come up with a unique name - // (note that there is no guarantee of unicity – if collisions show up, - // we may need to tweak the name generation algorithm). - let mut enum_by_string : HashMap> = HashMap::new(); - let mut enum_types : HashMap> = HashMap::new(); - for (name, enum_) in syntax.string_enums_by_name().iter() { - let type_ = format!("typename {parser_class_name}::{kind}", - parser_class_name = rules.parser_class_name, - kind = name.to_class_cases()); - enum_types.insert(name.clone(), Rc::new(type_)); - for string in enum_.strings().iter() { - let vec = enum_by_string.entry(string.clone()) - .or_insert_with(|| vec![]); - vec.push(name.clone()); - } - } - let variants_by_symbol = enum_by_string.drain() - .map(|(string, names)| { - let expanded = format!("{names}{symbol}", - names = names.iter() - .map(NodeName::to_str) - .sorted() - .into_iter() - .format("Or"), - symbol = string.to_cpp_enum_case()); - (string, expanded) - }) - .collect(); - - // This is just a placeholder to instantiate the CPPExporter struct. - // The field will be overwritten later in generate_reference_graph. - let refgraph = ReferenceGraph::new(); - - let context_map = HashMap::new(); - - CPPExporter { - syntax, - rules, - refgraph, - context_map, - list_parsers_to_generate, - option_parsers_to_generate, - canonical_list_parsers, - variants_by_symbol, - enum_types, - } - } - - /// Return NamedType for given NodeName. - /// Panic if NodeName is not NamedType - fn get_named_implementation(&self, name: &NodeName) -> NamedType { - if let Some(NamedType::Typedef(ref typedef)) = self.syntax.get_type_by_name(name) { - assert!(typedef.is_optional()); - if let TypeSpec::NamedType(ref named) = *typedef.spec() { - self.syntax.get_type_by_name(named) - .unwrap_or_else(|| panic!("Internal error: Could not find type {}, which should have been generated.", named.to_str())) - } else { - panic!("Internal error: In {}, type {:?} should have been a named type", - name.to_str(), - typedef); - } - } else { - panic!("Internal error: In {}, there should be a type with that name", - name.to_str()); - } - } - - /// Generate a reference graph of methods. - fn generate_reference_graph(&mut self) { - let mut refgraph = ReferenceGraph::new(); - - // FIXME: Reflect `replace` rule in yaml file for each interface to - // the reference (bug 1504595). - - // 1. Typesums - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name(); - for (name, nodes) in sums_of_interfaces { - let rules_for_this_sum = self.rules.get(name); - - let mut edges: HashSet> = HashSet::new(); - edges.insert(Rc::new(format!("Sum{}", name))); - refgraph.insert(name.to_rc_string().clone(), edges); - - let mut sum_edges: HashSet> = HashSet::new(); - for node in nodes { - let rule_for_this_arm = rules_for_this_sum.by_sum.get(&node) - .cloned() - .unwrap_or_default(); - - // If this arm is disabled, we emit raiseError instead of - // call to parseInterface*. Do not add edge in that case. - if rule_for_this_arm.disabled { - continue; - } - - sum_edges.insert(Rc::new(format!("Interface{}", node.to_string()))); - } - refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges); - } - - // 2. Single interfaces - let interfaces_by_name = self.syntax.interfaces_by_name(); - for (name, interface) in interfaces_by_name { - let rules_for_this_interface = self.rules.get(name); - let is_implemented = rules_for_this_interface.build_result.is_some(); - // If this interafce is not implemented, parse* method should - // not be called nor referenced in the graph. - if is_implemented { - let mut edges: HashSet> = HashSet::new(); - edges.insert(Rc::new(format!("Interface{}", name))); - refgraph.insert(name.to_rc_string().clone(), edges); - } - - let mut interface_edges: HashSet> = HashSet::new(); - // If this interface is not implemented, we emit raiseError in - // parseInterface* method, instead of parse* for each fields. - // There can be reference to parseInterface* of this interface - // from sum interface, and this node needs to be represented in - // the reference graph. - if is_implemented { - for field in interface.contents().fields() { - match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) }) - | None => { - let typename = TypeName::type_(field.type_()); - interface_edges.insert(Rc::new(typename.to_string())); - }, - - // Don't have to handle other type of fields (string, - // number, bool, etc). - _ => {} - } - } - } - refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges); - } - - // 3. String Enums - for (kind, _) in self.syntax.string_enums_by_name() { - refgraph.insert(kind.to_rc_string().clone(), HashSet::new()); - } - - // 4. Lists - for parser in &self.list_parsers_to_generate { - let name = &parser.name; - let rules_for_this_list = self.rules.get(name); - let is_implemented = rules_for_this_list.init.is_some(); - // If this list is not implemented, this method should not be - // called nor referenced in the graph. - if !is_implemented { - continue; - } - - let mut edges: HashSet> = HashSet::new(); - edges.insert(parser.elements.to_rc_string().clone()); - refgraph.insert(name.to_rc_string().clone(), edges); - } - - // 5. Optional values - for parser in &self.option_parsers_to_generate { - let mut edges: HashSet> = HashSet::new(); - let named_implementation = self.get_named_implementation(&parser.name); - match named_implementation { - NamedType::Interface(_) => { - edges.insert(Rc::new(format!("Interface{}", parser.elements.to_string()))); - }, - NamedType::Typedef(ref type_) => { - match type_.spec() { - &TypeSpec::TypeSum(_) => { - edges.insert(Rc::new(format!("Sum{}", parser.elements.to_string()))); - }, - _ => {} - } - }, - _ => {} - } - refgraph.insert(parser.name.to_rc_string().clone(), edges); - } - - // 6. Primitive values. - refgraph.insert(Rc::new("IdentifierName".to_string()), HashSet::new()); - refgraph.insert(Rc::new("PropertyKey".to_string()), HashSet::new()); - - self.refgraph = refgraph; - } - - /// Trace the reference graph from the node with `name and mark all nodes - /// as used. `name` is the name of the method, without leading "parse". - fn trace(&mut self, name: Rc) { - self.refgraph.trace(name) - } - - /// Collect context information for each interface to determine - /// which *Context type each method should receive. - fn collect_context(&mut self) { - fn add_context(map: &mut ContextMap, name: Rc, - context: LookupContext) { - let entry = map.entry(name).or_insert(LookupContext::empty()); - (*entry).add(context); - } - - // 1. Root - add_context(&mut self.context_map, - Rc::new("Program".to_string()), LookupContext::root()); - add_context(&mut self.context_map, - Rc::new("FunctionExpressionContents".to_string()), - LookupContext::root()); - add_context(&mut self.context_map, - Rc::new("FunctionOrMethodContents".to_string()), - LookupContext::root()); - - // 2. Interface fields - // XXX => XXX.field - for (name, interface) in self.syntax.interfaces_by_name() { - let inner_prefix = "Interface"; - let inner_name = Rc::new(format!("{}{}", inner_prefix, name)); - if !self.refgraph.is_used(inner_name) { - continue; - } - - for field in interface.contents().fields() { - match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { is_nullable: _, - content: Primitive::Interface(_) }) - | None => { - let typename = TypeName::type_(field.type_()); - add_context(&mut self.context_map, - Rc::new(typename), - LookupContext::field()); - } - _ => {} - } - } - } - - // 3. List contents - // ListXXX => XXX - for parser in &self.list_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - add_context(&mut self.context_map, - Rc::new(parser.elements.to_class_cases()), - LookupContext::list()); - } - - fn propagate_context(map: &mut ContextMap, from: Rc, - to: Rc) { - let opt_context = match map.get(&from) { - Some(opt_context) => { - opt_context.clone() - } - _ => { - return; - } - }; - let entry = map.entry(to).or_insert(LookupContext::empty()); - (*entry).add(opt_context); - } - - // 4. Propagate Optional - // OptionalXXX => XXX - for parser in &self.option_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let named_implementation = self.get_named_implementation(&parser.name); - match named_implementation { - NamedType::Interface(_) => { - propagate_context(&mut self.context_map, - Rc::new(parser.name.to_class_cases()), - Rc::new(format!("Interface{}", parser.elements.to_class_cases()))); - }, - NamedType::Typedef(ref type_) => { - match type_.spec() { - &TypeSpec::TypeSum(_) => { - propagate_context(&mut self.context_map, - Rc::new(parser.name.to_class_cases()), - Rc::new(format!("Sum{}", parser.elements.to_class_cases()))); - }, - _ => {} - } - }, - _ => {} - } - } - - // 5. Propagate Sum - // XXX => SumXXX - // SumXXX => each arm - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name(); - for (name, nodes) in sums_of_interfaces { - if !self.refgraph.is_used(name.to_rc_string().clone()) { - continue; - } - - propagate_context( - &mut self.context_map, - Rc::new(name.to_class_cases()), - Rc::new(format!("Sum{}", name.to_class_cases()))); - - for node in nodes { - propagate_context( - &mut self.context_map, - Rc::new(format!("Sum{}", name.to_class_cases())), - Rc::new(format!("Interface{}", node.to_class_cases()))); - } - } - - // 6. Propagate Interface - // XXX => InterfaceXXX - // InterfaceXXX => XXX - for (name, _) in self.syntax.interfaces_by_name() { - let inner_prefix = "Interface"; - let inner_name = Rc::new(format!("{}{}", inner_prefix, name)); - if !self.refgraph.is_used(inner_name) { - continue; - } - - propagate_context( - &mut self.context_map, - Rc::new(name.to_class_cases()), - Rc::new(format!("Interface{}", name.to_class_cases()))); - propagate_context( - &mut self.context_map, - Rc::new(format!("Interface{}", name.to_class_cases())), - Rc::new(name.to_class_cases())); - } - } - -// ----- Generating the header - - /// Get the type representing a success for parsing this node. - fn get_type_ok(&self, name: &NodeName) -> Rc { - // enum has its own rule. - if self.enum_types.contains_key(name) { - return self.enum_types.get(name).unwrap().clone(); - } - - let rules_for_this_interface = self.rules.get(name); - // If the override is provided, use it. - if let Some(type_ok) = rules_for_this_interface.type_ok { - return type_ok; - } - self.rules.parser_type_ok.clone() - } - fn get_default_value(&self, name: &NodeName) -> Rc { - let rules_for_this_interface = self.rules.get(name); - // If the override is provided, use it. - if let Some(default_value) = rules_for_this_interface.default_value { - return default_value; - } - if let Some(type_ok) = rules_for_this_interface.type_ok { - if type_ok.as_str() == "Ok" { - return Rc::new("Ok()".to_string()); - } - } - self.rules.parser_default_value.clone() - } - - fn get_context_param(&self, name: &NodeName, prefix: &str) -> String { - let context = match self.context_map.get(&Rc::new(format!("{}{}", prefix, name.to_rc_string()))) { - Some(context) => { - context.clone() - } - _ => { - panic!("{}{} doesn't have context", prefix, name.to_rc_string()); - } - }; - if context.is_root() { - return "const RootContext& context".to_string(); - } - if context.is_list() { - return "const ListContext& context".to_string(); - } - if context.is_field() { - return "const FieldContext& context".to_string(); - } - if context.is_field_and_list() { - return "const FieldOrListContext& context".to_string(); - } - if context.is_field_and_root() { - return "const FieldOrRootContext& context".to_string(); - } - - panic!("unexpected context"); - } - - fn get_method_signature(&self, name: &NodeName, prefix: &str, args: &str, - extra_params: &Option>) -> String { - let type_ok = self.get_type_ok(name); - let kind = name.to_class_cases(); - let extra = match extra_params { - Some(s) => { - format!("{}\n{}", - if args.len() > 0 { - "," - } else { - "" - }, - s.reindent(" ")) - } - _ => { - "".to_string() - } - }; - format!(" JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra}{before_context}{context}); -", - prefix = prefix, - type_ok = type_ok, - kind = kind, - args = args, - extra = extra, - before_context = if args.len() > 0 || extra_params.is_some() { - ", " - } else { - "" - }, - context = self.get_context_param(name, prefix), - ) - } - - fn get_method_definition_start(&self, name: &NodeName, prefix: &str, args: &str, - extra_params: &Option>) -> String { - let type_ok = self.get_type_ok(name); - let kind = name.to_class_cases(); - let extra = match extra_params { - Some(s) => { - format!("{}\n{}", - if args.len() > 0 { - "," - } else { - "" - }, - s.reindent(" ")) - } - _ => { - "".to_string() - } - }; - format!("{parser_class_template}JS::Result<{type_ok}> -{parser_class_name}::parse{prefix}{kind}({args}{extra}{before_context}{context})", - parser_class_template = self.rules.parser_class_template, - prefix = prefix, - type_ok = type_ok, - parser_class_name = self.rules.parser_class_name, - kind = kind, - args = args, - extra = extra, - before_context = if args.len() > 0 || extra_params.is_some() { - ", " - } else { - "" - }, - context = self.get_context_param(name, prefix), - ) - } - - fn get_context_param_for_sum(&self, sum: &NodeName, - arm: &NodeName, context: &str) -> String { - let sum_name = format!("Sum{}", sum); - let arm_name = format!("Interface{}", arm); - - let sum_context = match self.context_map.get(&sum_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - let arm_context = match self.context_map.get(&arm_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - - if sum_context == arm_context { - return context.to_string(); - } - - assert!(sum_context.is_single()); - assert!(arm_context.is_valid_double()); - - if arm_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_optional(&self, optional: &NodeName, - body_prefix: &str, body: &NodeName, - context: &str) -> String { - let optional_name = optional.to_string().clone(); - let body_name = format!("{}{}", body_prefix, body); - - let optional_context = match self.context_map.get(&optional_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - let body_context = match self.context_map.get(&body_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - - if optional_context == body_context { - return context.to_string(); - } - - assert!(optional_context.is_single()); - assert!(body_context.is_valid_double()); - - if body_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_list(&self, element: &NodeName, - context: &str) -> String { - let element_name = element.to_string().clone(); - - let element_context = match self.context_map.get(&element_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - - if element_context.is_list() { - return context.to_string(); - } - - assert!(element_context.is_field_and_list()); - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_field(&self, field: &NodeName, - context: &str) -> String { - let field_name = field.to_string().clone(); - - let field_context = match self.context_map.get(&field_name) { - Some(context) => context.clone(), - _ => panic!("no context") - }; - - if field_context.is_field() { - return context.to_string(); - } - - assert!(field_context.is_valid_double()); - - if field_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_method_call(&self, var_name: &str, name: &NodeName, - prefix: &str, args: &str, - extra_params: &Option>, - context_name: String, - call_kind: MethodCallKind) -> String { - let type_ok_is_ok = match call_kind { - MethodCallKind::Decl | MethodCallKind::Var => { - self.get_type_ok(name).to_str() == "Ok" - } - MethodCallKind::AlwaysDecl | MethodCallKind::AlwaysVar => { - false - } - }; - let extra = match extra_params { - Some(s) => { - format!("{}\n{}", - if args.len() > 0 { - "," - } else { - "" - }, - s.reindent(" ")) - } - _ => { - "".to_string() - } - }; - let call = format!("parse{prefix}{name}({args}{extra}{before_context}{context})", - prefix = prefix, - name = name.to_class_cases(), - args = args, - extra = extra, - before_context = if extra_params.is_some() || args.len() > 0 { - ", " - } else { - "" - }, - context = context_name - ); - - if type_ok_is_ok { - // Special case: `Ok` means that we shouldn't bind the return value. - format!("MOZ_TRY({call});", - call = call) - } else { - match call_kind { - MethodCallKind::Decl | MethodCallKind::AlwaysDecl => { - format!("BINJS_MOZ_TRY_DECL({var_name}, {call});", - var_name = var_name, call = call) - } - MethodCallKind::Var | MethodCallKind::AlwaysVar => { - format!("MOZ_TRY_VAR({var_name}, {call});", - var_name = var_name, call = call) - } - } - } - } - - /// Auxiliary function: get a name for a field type. - fn get_field_type_name(canonical_list_parsers: &HashMap, _typedef: Option<&str>, spec: &Spec, type_: &Type, make_optional: bool) -> Cow<'static, str> { - let optional = make_optional || type_.is_optional(); - match *type_.spec() { - TypeSpec::Boolean if optional => Cow::from("PRIMITIVE(MaybeBoolean)"), - TypeSpec::Boolean => Cow::from("PRIMITIVE(Boolean)"), - TypeSpec::String if optional => Cow::from("PRIMITIVE(MaybeString)"), - TypeSpec::String => Cow::from("PRIMITIVE(String)"), - TypeSpec::Number if optional => Cow::from("PRIMITIVE(MaybeNumber)"), - TypeSpec::Number => Cow::from("PRIMITIVE(Number)"), - TypeSpec::UnsignedLong if optional => Cow::from("PRIMITIVE(MaybeUnsignedLong)"), - TypeSpec::UnsignedLong => Cow::from("PRIMITIVE(UnsignedLong)"), - TypeSpec::Offset if optional => Cow::from("PRIMITIVE(MaybeLazy)"), - TypeSpec::Offset => Cow::from("PRIMITIVE(Lazy)"), - TypeSpec::Void if optional => Cow::from("PRIMITIVE(MaybeVoid)"), - TypeSpec::Void => Cow::from("PRIMITIVE(Void)"), - TypeSpec::IdentifierName if optional => Cow::from("PRIMITIVE(MaybeIdentifierName)"), - TypeSpec::IdentifierName => Cow::from("PRIMITIVE(IdentifierName)"), - TypeSpec::PropertyKey if optional => Cow::from("PRIMITIVE(MaybePropertyKey)"), - TypeSpec::PropertyKey => Cow::from("PRIMITIVE(PropertyKey)"), - TypeSpec::Array { ref contents, .. } => { - let typename = TypeName::type_(contents); - let node_name = spec.get_node_name(&typename).unwrap(); - let ref name = canonical_list_parsers.get(node_name).unwrap().name; - let contents = Self::get_field_type_name(canonical_list_parsers, None, spec, contents, false); - debug!(target: "generate_spidermonkey", "get_field_type_name for LIST {name}", - name = name); - Cow::from(format!("LIST({name}, {contents})", - name = name, - contents = contents)) - }, - TypeSpec::NamedType(ref name) => { - debug!(target: "generate_spidermonkey", "get_field_type_name for named type {name} ({optional})", - name = name, - optional = if optional { "optional" } else { "required" }); - match spec.get_type_by_name(name).expect("By now, all types MUST exist") { - NamedType::Typedef(alias_type) => { - if alias_type.is_optional() { - return Self::get_field_type_name(canonical_list_parsers, Some(name.to_str()), spec, alias_type.as_ref(), true) - } - // Keep the simple name of sums and lists if there is one. - match *alias_type.spec() { - TypeSpec::TypeSum(_) => { - if optional { - Cow::from(format!("OPTIONAL_SUM({name})", name = name.to_cpp_enum_case())) - } else { - Cow::from(format!("SUM({name})", name = name.to_cpp_enum_case())) - } - } - TypeSpec::Array { ref contents, .. } => { - debug!(target: "generate_spidermonkey", "It's an array {:?}", contents); - let typename = TypeName::type_(contents); - let node_name = spec.get_node_name(&typename).unwrap(); - let ref name = canonical_list_parsers.get(node_name).unwrap().name; - let contents = Self::get_field_type_name(canonical_list_parsers, None, spec, contents, false); - debug!(target: "generate_spidermonkey", "get_field_type_name for typedefed LIST {name}", - name = name); - if optional { - Cow::from(format!("OPTIONAL_LIST({name}, {contents})", - name = name.to_cpp_enum_case(), - contents = contents)) - } else { - Cow::from(format!("LIST({name}, {contents})", - name = name.to_cpp_enum_case(), - contents = contents)) - } - } - _ => { - Self::get_field_type_name(canonical_list_parsers, Some(name.to_str()), spec, alias_type.as_ref(), optional) - } - } - } - NamedType::StringEnum(_) if type_.is_optional() => Cow::from( - format!("OPTIONAL_STRING_ENUM({name})", - name = TypeName::type_(type_))), - NamedType::StringEnum(_) => Cow::from( - format!("STRING_ENUM({name})", - name = TypeName::type_(type_))), - NamedType::Interface(ref interface) if type_.is_optional() => Cow::from( - format!("OPTIONAL_INTERFACE({name})", - name = interface.name().to_class_cases())), - NamedType::Interface(ref interface) => Cow::from( - format!("INTERFACE({name})", - name = interface.name().to_class_cases())), - } - } - TypeSpec::TypeSum(ref contents) if type_.is_optional() => { - // We need to make sure that we don't count the `optional` part twice. - // FIXME: The problem seems to only show up in this branch, but it looks like - // it might (should?) appear in other branches, too. - let non_optional_type = Type::sum(contents.types()).required(); - let name = TypeName::type_(&non_optional_type); - Cow::from(format!("OPTIONAL_SUM({name})", name = name)) - } - TypeSpec::TypeSum(_) => Cow::from(format!("SUM({name})", name = TypeName::type_(type_))), - } - } - - /// Declaring enums for kinds and fields. - fn export_declare_kinds_and_fields_enums(&self, buffer: &mut String) { - buffer.push_str(&self.rules.hpp_tokens_header.reindent("")); - - buffer.push_str("\n\n"); - if self.rules.hpp_tokens_kind_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_kind_doc.reindent("")); - } - - let node_names = self.syntax.interfaces_by_name() - .keys() - .map(|n| n.to_string()) - .sorted() - .collect_vec(); - let kind_limit = node_names.len(); - buffer.push_str(&format!(" -#define FOR_EACH_BIN_KIND(F) \\ - F(_Uninitialized, \"Uninitialized\", UNINITIALIZED) \\ -{nodes} -", - nodes = node_names.iter() - .map(|name| format!(" F({enum_name}, \"{spec_name}\", {macro_name})", - enum_name = name.to_cpp_enum_case(), - spec_name = name, - macro_name = name.to_cpp_macro_case())) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTKind: uint16_t { -#define EMIT_ENUM(name, _1, _2) name, - FOR_EACH_BIN_KIND(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - - buffer.push_str(&format!(" -// The number of distinct values of BinASTKind. -const size_t BINASTKIND_LIMIT = {}; - -", kind_limit)); - if self.rules.hpp_tokens_field_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_field_doc.reindent("")); - } - - let field_names = self.syntax.field_names() - .keys() - .sorted() - .collect_vec(); - let field_limit = field_names.len(); - buffer.push_str(&format!(" -#define FOR_EACH_BIN_FIELD(F) \\ -{nodes} -", - nodes = field_names.iter() - .map(|name| format!(" F({enum_name}, \"{spec_name}\")", - spec_name = name, - enum_name = name.to_cpp_enum_case())) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTField: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - buffer.push_str(&format!(" -// The number of distinct values of BinASTField. -const size_t BINASTFIELD_LIMIT = {}; - -", field_limit)); - - buffer.push_str(&format!(" - -#define FOR_EACH_BIN_INTERFACE_AND_FIELD(F) \\ -{nodes} -", - nodes = self.syntax.interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - .into_iter() - .flat_map(|(interface_name, interface)| { - let interface_enum_name = interface_name.to_cpp_enum_case(); - let interface_spec_name = interface_name.clone(); - interface.contents().fields() - .iter() - .map(move |field| format!(" F({interface_enum_name}__{field_enum_name}, \"{interface_spec_name}::{field_spec_name}\")", - interface_enum_name = interface_enum_name, - field_enum_name = field.name().to_cpp_enum_case(), - interface_spec_name = interface_spec_name, - field_spec_name = field.name().to_str(), - ) - ) - }) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTInterfaceAndField: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_INTERFACE_AND_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - - for (sum_name, sum) in self.syntax.resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - { - let sum_enum_name = sum_name.to_cpp_enum_case(); - let sum_macro_name = sum_name.to_cpp_macro_case(); - buffer.push_str(&format!(" -// Iteration through the interfaces of sum {sum_enum_name} -#define FOR_EACH_BIN_INTERFACE_IN_SUM_{sum_macro_name}(F) \\ -{nodes} - -const size_t BINAST_SUM_{sum_macro_name}_LIMIT = {limit}; - - ", - sum_enum_name = sum_enum_name.clone(), - sum_macro_name = sum_macro_name, - limit = sum.len(), - nodes = sum.iter() - .sorted() - .into_iter() - .enumerate() - .map(move |(i, interface_name)| { - let interface_macro_name = interface_name.to_cpp_macro_case(); - let interface_enum_name = interface_name.to_cpp_enum_case(); - format!(" F({sum_enum_name}, {index}, {interface_enum_name}, {interface_macro_name}, \"{sum_spec_name}::{interface_spec_name}\")", - sum_enum_name = sum_enum_name, - index = i, - interface_enum_name = interface_enum_name, - interface_macro_name = interface_macro_name, - sum_spec_name = sum_name, - interface_spec_name = interface_name, - ) - }) - .format(" \\\n"))); - - - } - - - buffer.push_str(" -// Strongly typed iterations through the fields of interfaces. -// -// Each of these macros accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNINITIALIZED( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) -"); - for (interface_name, interface) in self.syntax.interfaces_by_name().iter().sorted_by_key(|a| a.0) { - let interface_enum_name = interface_name.to_cpp_enum_case(); - let interface_spec_name = interface_name.clone(); - let interface_macro_name = interface.name().to_cpp_macro_case(); - buffer.push_str(&format!(" - -// Strongly typed iteration through the fields of interface {interface_enum_name}. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_{interface_macro_name}(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, STRING_ENUM, OPTIONAL_STRING_ENUM) \\ -{nodes} -", - interface_macro_name = interface_macro_name, - interface_enum_name = interface_enum_name.clone(), - nodes = interface.contents().fields() - .iter() - .enumerate() - .map(|(i, field)| { - let field_type_name = Self::get_field_type_name(&self.canonical_list_parsers, None, &self.syntax, field.type_(), false); - format!(" F({interface_enum_name}, {field_enum_name}, {field_index}, {field_type}, \"{interface_spec_name}::{field_spec_name}\")", - interface_enum_name = interface_enum_name, - field_enum_name = field.name().to_cpp_enum_case(), - field_index = i, - interface_spec_name = interface_spec_name, - field_spec_name = field.name().to_str(), - field_type = field_type_name - ) - }) - .format(" \\\n"))); - buffer.push_str(&format!(" -// The number of fields of interface {interface_spec_name}. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_{interface_macro_name} = {len};", - interface_spec_name = interface_spec_name, - interface_macro_name = interface_macro_name, - len = interface.contents().fields().len())); - } - - let total_number_of_fields: usize = self.syntax.interfaces_by_name() - .values() - .map(|interface| interface.contents().fields().len()) - .sum(); - buffer.push_str(&format!(" -// The total number of fields across all interfaces. Used typically to maintain a probability table per field. -const size_t BINAST_INTERFACE_AND_FIELD_LIMIT = {number}; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_INTERFACE_AND_FIELD_LIMIT. -#define BINAST_PARAM_NUMBER_OF_INTERFACE_AND_FIELD(X) {param} - -", number=total_number_of_fields, param=(0..total_number_of_fields) - .map(|_| "(X)") - .format(","))); - - if self.rules.hpp_tokens_variants_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_variants_doc.reindent("")); - } - let enum_variants : Vec<_> = self.variants_by_symbol - .iter() - .sorted_by_key(|a| a.0) - .collect_vec(); - let variants_limit = enum_variants.len(); - - buffer.push_str(&format!(" -#define FOR_EACH_BIN_VARIANT(F) \\ -{nodes} -", - nodes = enum_variants.into_iter() - .map(|(symbol, name)| format!(" F({variant_name}, \"{spec_name}\")", - spec_name = symbol, - variant_name = name)) - .format(" \\\n"))); - - buffer.push_str(" -enum class BinASTVariant: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_VARIANT(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - buffer.push_str(&format!(" -// The number of distinct values of BinASTVariant. -const size_t BINASTVARIANT_LIMIT = {}; - -", - variants_limit)); - - buffer.push_str(&format!(" -#define FOR_EACH_BIN_STRING_ENUM(F) \\ -{nodes} -", - nodes = self.syntax.string_enums_by_name() - .keys() - .sorted() - .into_iter() - .map(|name| format!(" F({enum_name}, \"{spec_name}\", {macro_name})", - enum_name = name.to_cpp_enum_case(), - spec_name = name.to_str(), - macro_name = name.to_cpp_macro_case())) - .format(" \\\n"))); - - buffer.push_str(" -enum class BinASTStringEnum: uint16_t { -#define EMIT_ENUM(NAME, _HUMAN_NAME, _MACRO_NAME) NAME, - FOR_EACH_BIN_STRING_ENUM(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - buffer.push_str(&format!(" -// The number of distinct values of BinASTStringEnum. -const size_t BINASTSTRINGENUM_LIMIT = {}; - -", - self.syntax.string_enums_by_name().len())); - - for (name, enum_) in self.syntax.string_enums_by_name() - .iter() - .sorted_by_key(|kv| kv.0) - .into_iter() - { - let enum_name = name.to_str().to_class_cases(); - let enum_macro_name = name.to_cpp_macro_case(); - buffer.push_str(&format!(" -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_{enum_macro_name}_BY_STRING_ORDER(F) \\ - {variants} -", - enum_macro_name = enum_macro_name, - variants = enum_.strings() - .iter() - .sorted() - .into_iter() - .map(|variant_string| { - format!(" F({enum_name}, {variant_name}, \"{variant_string}\")", - enum_name = enum_name, - variant_name = self.variants_by_symbol.get(variant_string).unwrap(), - variant_string = variant_string - ) - }) - .format("\\\n") - )); - buffer.push_str(&format!(" -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_{enum_macro_name}_BY_WEBIDL_ORDER(F) \\ - {variants} -", - enum_macro_name = enum_macro_name, - variants = enum_.strings() - .iter() - .map(|variant_string| { - format!(" F({enum_name}, {variant_name}, \"{variant_string}\")", - enum_name = enum_name, - variant_name = self.variants_by_symbol.get(variant_string).unwrap(), - variant_string = variant_string - ) - }) - .format("\\\n") - )); - buffer.push_str(&format!(" - -const size_t BIN_AST_STRING_ENUM_{enum_macro_name}_LIMIT = {len}; -", - enum_macro_name = enum_macro_name, - len = enum_.strings().len(), - )); - } - - buffer.push_str(&format!(" -// This macro accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_LIST(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, STRING_ENUM, OPTIONAL_STRING_ENUM) \\ -{nodes} -", - nodes = self.canonical_list_parsers.values() - .sorted_by_key(|data| &data.name) - .into_iter() - .map(|data| { - debug!(target: "generate_spidermonkey", "Generating FOR_EACH_BIN_LIST case {list_name} => {type_name:?}", - list_name = data.name, - type_name = self.syntax.typedefs_by_name().get(&data.name).unwrap()); - format!(" F({list_name}, {content_name}, \"{spec_name}\", {type_name})", - list_name = data.name.to_cpp_enum_case(), - content_name = data.elements.to_cpp_enum_case(), - spec_name = data.name.to_str(), - type_name = Self::get_field_type_name(&self.canonical_list_parsers, Some(data.name.to_str()), &self.syntax, self.syntax.typedefs_by_name().get(&data.name).unwrap(), false)) - }) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTList: uint16_t { -#define NOTHING(_) -#define EMIT_ENUM(name, _content, _user, _type_name) name, - FOR_EACH_BIN_LIST(EMIT_ENUM, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING) -#undef EMIT_ENUM -#undef NOTHING -}; -"); - - let number_of_lists = self.list_parsers_to_generate.len(); - - buffer.push_str(&format!(" -// The number of distinct list types in the grammar. Used typically to maintain a probability table per list type. -const size_t BINAST_NUMBER_OF_LIST_TYPES = {number}; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_NUMBER_OF_LIST_TYPES. -#define BINAST_PARAM_NUMBER_OF_LIST_TYPES(X) {param} - -", number=number_of_lists, param=(0..number_of_lists) - .map(|_| "(X)") - .format(","))); - - buffer.push_str(&format!(" -#define FOR_EACH_BIN_SUM(F) \\ -{nodes} -", - nodes = self.syntax.resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - .into_iter() - .map(|(name, _)| format!(" F({name}, \"{spec_name}\", {macro_name}, {type_name})", - name = name.to_cpp_enum_case(), - spec_name = name.to_str(), - macro_name = name.to_cpp_macro_case(), - type_name = Self::get_field_type_name(&self.canonical_list_parsers, Some(name.to_str()), &self.syntax, self.syntax.typedefs_by_name().get(name).unwrap(), false))) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTSum: uint16_t { -#define EMIT_ENUM(name, _user, _macro, _type) name, - FOR_EACH_BIN_SUM(EMIT_ENUM) -#undef EMIT_ENUM -}; -"); - buffer.push_str(&format!(" -// The number of distinct sum types in the grammar. Used typically to maintain a probability table per sum type. -const size_t BINAST_NUMBER_OF_SUM_TYPES = {}; - -", - self.syntax.resolved_sums_of_interfaces_by_name().len())); - - buffer.push_str(&self.rules.hpp_tokens_footer.reindent("")); - buffer.push_str("\n"); - - } - - /// Declare string enums - fn export_declare_string_enums(&self, buffer: &mut String) { - buffer.push_str(" -// ----- Declaring string enums (by lexicographical order) -"); - let string_enums_by_name = self.syntax.string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (name, enum_) in string_enums_by_name { - let rendered_cases = enum_.strings() - .iter() - .map(|str| format!(" // \"{original}\" - {case},", - case = str.to_cpp_enum_case(), - original = str)) - .format("\n"); - let rendered = format!(" -enum class {name} {{ -{cases} -}}; -", - cases = rendered_cases, - name = name.to_class_cases()); - buffer.push_str(&rendered); - } - } - - fn export_declare_sums_of_interface_methods(&self, buffer: &mut String) { - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)) - .collect_vec(); - buffer.push_str(" - // ----- Sums of interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr -"); - for &(ref name, _) in &sums_of_interfaces { - if !self.refgraph.is_used(name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let rendered = self.get_method_signature(name, "", "", - &extra_params); - buffer.push_str(&rendered.reindent(" ") - .newline_if_not_empty()); - } - for (name, _) in sums_of_interfaces { - let prefix = "Sum"; - if !self.refgraph.is_used(Rc::new(format!("{}{}", prefix, name))) { - continue; - } - - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let rendered = self.get_method_signature(name, prefix, - SUM_INTERFACE_PARAMS, - &extra_params); - buffer.push_str(&rendered.reindent(" ") - .newline_if_not_empty()); - } - } - - fn export_declare_single_interface_methods(&self, buffer: &mut String) { - buffer.push_str(" - // ----- Interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr -"); - let interfaces_by_name = self.syntax.interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())) - .collect_vec(); - - let mut outer_parsers = Vec::with_capacity(interfaces_by_name.len()); - let mut inner_parsers = Vec::with_capacity(interfaces_by_name.len()); - - for &(name, _) in &interfaces_by_name { - let rules_for_this_interface = self.rules.get(name); - let extra_params = rules_for_this_interface.extra_params; - - if self.refgraph.is_used(name.to_rc_string().clone()) { - let outer = self.get_method_signature(name, "", "", &extra_params); - outer_parsers.push(outer.reindent(" ")); - } - - let inner_prefix = "Interface"; - if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) { - continue; - } - let inner = self.get_method_signature(name, inner_prefix, - INTERFACE_PARAMS, - &extra_params); - inner_parsers.push(inner.reindent(" ")); - } - - for parser in outer_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - - for parser in inner_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - } - - fn export_declare_string_enums_methods(&self, buffer: &mut String) { - buffer.push_str(" - // ----- String enums (by lexicographical order) -"); - let string_enums_by_name = self.syntax.string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, _) in string_enums_by_name { - if !self.refgraph.is_used(kind.to_rc_string().clone()) { - continue; - } - - let rendered = self.get_method_signature(kind, "", "", &None); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn export_declare_list_methods(&self, buffer: &mut String) { - buffer.push_str(" - // ----- Lists (by lexicographical order) -"); - for parser in &self.list_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let rendered = self.get_method_signature(&parser.name, "", "", - &extra_params); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn export_declare_option_methods(&self, buffer: &mut String) { - buffer.push_str(" - // ----- Default values (by lexicographical order) -"); - for parser in &self.option_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let rendered = self.get_method_signature(&parser.name, "", "", - &extra_params); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn generate_autogenerated_warning(&self) -> String { - let warning = format!("// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -"); - warning - } - - /// Generate C++ headers for SpiderMonkey - fn to_spidermonkey_token_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - self.export_declare_kinds_and_fields_enums(&mut buffer); - - buffer.push_str("\n"); - buffer - } - fn to_spidermonkey_class_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - buffer.push_str(&self.rules.hpp_class_header.reindent("")); - buffer.push_str("\n"); - - self.export_declare_sums_of_interface_methods(&mut buffer); - self.export_declare_single_interface_methods(&mut buffer); - self.export_declare_string_enums_methods(&mut buffer); - self.export_declare_list_methods(&mut buffer); - self.export_declare_option_methods(&mut buffer); - - buffer.push_str("\n"); - buffer.push_str(&self.rules.hpp_class_footer.reindent("")); - buffer.push_str("\n"); - buffer - } - - fn to_spidermonkey_enum_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - buffer.push_str(&self.rules.hpp_enums_header.reindent("")); - buffer.push_str("\n"); - - self.export_declare_string_enums(&mut buffer); - - buffer.push_str("\n"); - buffer.push_str(&self.rules.hpp_enums_footer.reindent("")); - buffer.push_str("\n"); - buffer - } -} - -impl CPPExporter { - /// Generate implementation of a single typesum. - fn generate_implement_sum(&self, buffer: &mut String, name: &NodeName, nodes: &HashSet) { - // Generate comments (FIXME: We should use the actual webidl, not the resolved sum) - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let extra_args = rules_for_this_sum.extra_args; - let nodes = nodes.iter() - .sorted() - .collect_vec(); - let kind = name.to_class_cases(); - - if self.refgraph.is_used(name.to_rc_string().clone()) { - let rendered_bnf = format!("/* -{name} ::= {nodes} -*/", - nodes = nodes.iter() - .format("\n "), - name = name.to_str()); - - // Generate outer method - buffer.push_str(&format!("{bnf} -{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - -{call} - - MOZ_TRY(guard.done()); - return result; -}} -", - bnf = rendered_bnf, - call = self.get_method_call("result", name, - "Sum", SUM_INTERFACE_ARGS, - &extra_args, - "context".to_string(), - MethodCallKind::AlwaysDecl) - .reindent(" "), - first_line = self.get_method_definition_start(name, "", "", - &extra_params) - )); - } - - let inner_prefix = "Sum"; - if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) { - return; - } - - // Generate inner method - let mut buffer_cases = String::new(); - for node in nodes { - let rule_for_this_arm = rules_for_this_sum.by_sum.get(&node) - .cloned() - .unwrap_or_default(); - - if rule_for_this_arm.disabled { - buffer_cases.push_str(&format!(" - case BinASTKind::{variant_name}: - return raiseError(\"FIXME: Not implemented yet in this preview release ({variant_name})\");", - variant_name = node.to_cpp_enum_case())); - continue; - } - - buffer_cases.push_str(&format!(" - case BinASTKind::{variant_name}: -{call} -{arm_after} break;", - call = self.get_method_call("result", node, - "Interface", INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_sum( - name, node, "context"), - MethodCallKind::AlwaysVar) - .reindent(" "), - variant_name = node.to_cpp_enum_case(), - arm_after = rule_for_this_arm.after_arm.reindent(" ") - .newline_if_not_empty())); - } - buffer.push_str(&format!(" - -{first_line} -{{ - {type_ok} result; - switch (kind) {{{cases} - default: - if (isInvalidKindPossible()) {{ - return raiseInvalidKind(\"{kind}\", kind); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTKind should not appear\"); - }} - }} - return result; -}} - -", - kind = kind, - cases = buffer_cases, - first_line = self.get_method_definition_start(name, inner_prefix, - SUM_INTERFACE_PARAMS, - &extra_params), - type_ok = self.get_type_ok(name) - )); - } - - /// Generate the implementation of a single list parser - fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - return; - } - - let rules_for_this_list = self.rules.get(&parser.name); - let extra_params = rules_for_this_list.extra_params; - let extra_args = rules_for_this_list.extra_args; - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_list.build_result.is_some(), "build:"), - (rules_for_this_list.type_ok.is_some(), "type-ok:"), - (rules_for_this_list.by_field.len() > 0, "fields:"), - (rules_for_this_list.by_sum.len() > 0, "sum-arms:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored.", parser.name, name); - } - } - - let kind = parser.name.to_class_cases(); - let first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params); - - let init = match rules_for_this_list.init { - Some(str) => str.reindent(" "), - None => { - // We cannot generate the method if we don't know how to initialize the list. - let rendered = format!(" -{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} -", - first_line = first_line, - kind = kind, - ); - buffer.push_str(&rendered); - return; - } - }; - let append = match rules_for_this_list.append { - Some(str) => str.reindent(" ").newline_if_not_empty(), - None => { - match self.rules.parser_list_append { - Some(ref str) => str.reindent(" ").newline_if_not_empty(), - None => "".to_string(), - } - } - }; - - - let rendered = format!(" - -{first_line} -{{ - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = ListContext(context.position_, BinASTList::{content_kind}); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext));{empty_check} -{init} - - for (uint32_t i = 0; i < length; ++i) {{ -{call} -{append} }} - - MOZ_TRY(guard.done()); - return result; -}} -", - first_line = first_line, - content_kind = - self.canonical_list_parsers.get(&parser.elements).unwrap() // Each list parser has a deduplicated representative - .name.to_class_cases(), - empty_check = - if parser.supports_empty { - "".to_string() - } else { - format!(" - if (MOZ_UNLIKELY(length == 0)) {{ - return raiseEmpty(\"{kind}\"); - }} -", - kind = kind) - }, - call = self.get_method_call("item", - &parser.elements, "", "", - &extra_args, - self.get_context_param_for_list( - &parser.elements, - "childContext"), - MethodCallKind::Decl) - .reindent(" "), - init = init, - append = append); - buffer.push_str(&rendered); - } - - fn generate_implement_option(&self, buffer: &mut String, parser: &OptionParserData) { - debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}", - parser.name.to_str(), parser.elements.to_str()); - - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - return; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let extra_args = rules_for_this_node.extra_args; - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_node.build_result.is_some(), "build:"), - (rules_for_this_node.append.is_some(), "append:"), - (rules_for_this_node.by_field.len() > 0, "fields:"), - (rules_for_this_node.by_sum.len() > 0, "sum-arms:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored.", parser.name, name); - } - } - - let type_ok = self.get_type_ok(&parser.name); - let default_value = self.get_default_value(&parser.name); - - // At this stage, thanks to deanonymization, `contents` - // is something like `OptionalFooBar`. - let named_implementation = - if let Some(NamedType::Typedef(ref typedef)) = self.syntax.get_type_by_name(&parser.name) { - assert!(typedef.is_optional()); - if let TypeSpec::NamedType(ref named) = *typedef.spec() { - self.syntax.get_type_by_name(named) - .unwrap_or_else(|| panic!("Internal error: Could not find type {}, which should have been generated.", named.to_str())) - } else { - panic!("Internal error: In {}, type {:?} should have been a named type", - parser.name.to_str(), - typedef); - } - } else { - panic!("Internal error: In {}, there should be a type with that name", - parser.name.to_str()); - }; - match named_implementation { - NamedType::Interface(_) => { - buffer.push_str(&format!("{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterOptionalInterface(kind, context)); - {type_ok} result; - if (kind == BinASTKind::{null}) {{ -{none_block} - }} else if (!isInvalidKindPossible() || kind == BinASTKind::{kind}) {{ - const auto start = tokenizer_->offset(); -{before}{call}{after} - }} else {{ - if (isInvalidKindPossible()) {{ - return raiseInvalidKind(\"{kind}\", kind); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTKind should not appear\"); - }} - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params), - null = self.syntax.get_null_name().to_cpp_enum_case(), - call = self.get_method_call("result", - &parser.elements, - "Interface", INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_optional( - &parser.name, - "Interface", &parser.elements, - "context"), - MethodCallKind::AlwaysVar) - .reindent(" "), - before = rules_for_this_node.some_before - .map_or_else(|| "".to_string(), - |s| s - .reindent(" ") - .newline_if_not_empty()), - after = rules_for_this_node.some_after - .map_or_else(|| "".to_string(), - |s| s - .reindent(" ") - .newline_if_not_empty()), - none_block = rules_for_this_node.none_replace - .map_or_else(|| format!("result = {default_value};", - default_value = default_value) - .reindent(" "), - |s| s.reindent(" ")), - type_ok = type_ok, - kind = parser.elements.to_cpp_enum_case(), - )); - } - NamedType::Typedef(ref type_) => { - match type_.spec() { - &TypeSpec::TypeSum(_) => { - buffer.push_str(&format!("{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - {type_ok} result; - if (kind == BinASTKind::{null}) {{ -{none_block} - }} else {{ - const auto start = tokenizer_->offset(); -{before}{call}{after} - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params), - call = self.get_method_call("result", &parser.elements, - "Sum", SUM_INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_optional( - &parser.name, - "Sum", &parser.elements, - "context"), - MethodCallKind::AlwaysVar) - .reindent(" "), - before = rules_for_this_node.some_before - .map_or_else(|| "".to_string(), - |s| s - .reindent(" ") - .newline_if_not_empty()), - after = rules_for_this_node.some_after - .map_or_else(|| "".to_string(), - |s| s - .reindent(" ") - .newline_if_not_empty()), - none_block = rules_for_this_node.none_replace - .map_or_else(|| format!("result = {default_value};", - default_value = default_value) - .reindent(" "), - |s| s.reindent(" ")), - type_ok = type_ok, - null = self.syntax.get_null_name().to_cpp_enum_case(), - )); - } - &TypeSpec::String => { - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!("{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str())); - } else { - buffer.push_str(&format!("{first_line} -{{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom(context)); - -{build} - - return result; -}} - -", - first_line = first_line, - build = build_result, - )); - } - } - &TypeSpec::IdentifierName => { - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!("{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str())); - } else { - buffer.push_str(&format!("{first_line} -{{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeIdentifierName(context)); - -{build} - - return result; -}} - -", - first_line = first_line, - build = build_result, - )); - } - } - &TypeSpec::PropertyKey => { - debug!(target: "generate_spidermonkey", "Generating method for PropertyKey: {:?}", parser.name); - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = self.get_method_definition_start(&parser.name, "", "", - &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!("{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str())); - } else { - panic!("PropertyKey shouldn't be optional"); - } - } - _else => unimplemented!("{:?}", _else) - } - } - NamedType::StringEnum(_) => { - unimplemented!() - } - } - } - - fn generate_implement_interface(&self, buffer: &mut String, name: &NodeName, interface: &Interface) { - let rules_for_this_interface = self.rules.get(name); - let extra_params = rules_for_this_interface.extra_params; - let extra_args = rules_for_this_interface.extra_args; - - for &(condition, rule_name) in &[ - (rules_for_this_interface.append.is_some(), "build:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored.", name, rule_name); - } - } - - if self.refgraph.is_used(name.to_rc_string().clone()) { - // Generate comments - let comment = format!(" -/* -{}*/ -", ToWebidl::interface(interface, "", " ")); - buffer.push_str(&comment); - - // Generate public method - buffer.push_str(&format!("{first_line} -{{ - BinASTKind kind = BinASTKind::{kind}; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); -{call} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = self.get_method_definition_start(name, "", "", - &extra_params), - kind = name.to_cpp_enum_case(), - call = self.get_method_call("result", name, - "Interface", INTERFACE_ARGS, - &extra_args, - "context".to_string(), - MethodCallKind::AlwaysDecl) - .reindent(" ") - )); - } - - let inner_prefix = "Interface"; - if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) { - return; - } - - // Generate aux method - let first_line = self.get_method_definition_start(name, inner_prefix, - INTERFACE_PARAMS, - &extra_params); - - let mut fields_implem = String::new(); - for field in interface.contents().fields() { - let context = format!("FieldContext(BinASTInterfaceAndField::{kind}__{field})", - kind = name.to_cpp_enum_case(), - field = field.name().to_cpp_enum_case()); - - let rules_for_this_field = rules_for_this_interface.by_field.get(field.name()) - .cloned() - .unwrap_or_default(); - let needs_block = rules_for_this_field.block_before_field.is_some() || rules_for_this_field.block_after_field.is_some(); - - let var_name = field.name().to_cpp_field_case(); - let (decl_var, parse_var) = match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { is_nullable: false, content: Primitive::Number }) => { - if needs_block { - (Some(format!("double {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readDouble({context}));", - var_name = var_name, - context = context))) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { is_nullable: false, content: Primitive::UnsignedLong }) => { - if needs_block { - (Some(format!("uint32_t {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readUnsignedLong({context}));", - var_name = var_name, - context = context))) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readUnsignedLong({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { is_nullable: false, content: Primitive::Boolean }) => { - if needs_block { - (Some(format!("bool {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readBool({context}));", - var_name = var_name, - context = context))) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { is_nullable: false, content: Primitive::Offset }) => { - if needs_block { - (Some(format!("BinASTTokenReaderBase::SkippableSubTree {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree({context}));", - var_name = var_name, - context = context))) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readSkippableSubTree({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { content: Primitive::Void, .. }) => { - warn!("Internal error: We shouldn't have any `void` types at this stage."); - (Some(format!("// Skipping void field {}", field.name().to_str())), - None) - } - Some(IsNullable { is_nullable: false, content: Primitive::String }) => { - (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readAtom({context}));", - var_name = var_name, - context = context))) - } - Some(IsNullable { is_nullable: false, content: Primitive::IdentifierName }) => { - (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readIdentifierName({context}));", - var_name = var_name, - context = context))) - } - Some(IsNullable { is_nullable: false, content: Primitive::PropertyKey }) => { - (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readPropertyKey({context}));", - var_name = var_name, - context = context))) - } - Some(IsNullable { is_nullable: true, content: Primitive::String }) => { - (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeAtom({context}));", - var_name = var_name, - context = context))) - } - Some(IsNullable { is_nullable: true, content: Primitive::IdentifierName }) => { - (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeIdentifierName({context}));", - var_name = var_name, - context = context))) - } - Some(IsNullable { is_nullable: true, content: Primitive::PropertyKey }) => { - panic!("PropertyKey shouldn't be optional"); - } - _else => { - let typename = TypeName::type_(field.type_()); - let name = self.syntax.get_node_name(typename.to_str()) - .expect("NodeName for the field type should exist."); - let field_extra_args = rules_for_this_field.extra_args; - - let (decl_var, call_kind) = if needs_block { - (Some(format!("{typename} {var_name};", - var_name = var_name, - typename = typename)), - MethodCallKind::Var) - } else { - (None, - MethodCallKind::Decl) - }; - - (decl_var, - Some(self.get_method_call(var_name.to_str(), - &name, "", "", &field_extra_args, - self.get_context_param_for_field( - name, - &context), - call_kind))) - } - }; - let rendered = { - if rules_for_this_field.replace.is_some() { - for &(condition, rule_name) in &[ - (rules_for_this_field.before_field.is_some(), "before:"), - (rules_for_this_field.after_field.is_some(), "after:"), - (rules_for_this_field.declare.is_some(), "declare:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored because `replace:` is also specified.", name, rule_name); - } - } - rules_for_this_field.replace.reindent(" ") - .newline() - } else { - let before_field = rules_for_this_field.before_field.reindent(" "); - let after_field = rules_for_this_field.after_field.reindent(" "); - let decl_var = if rules_for_this_field.declare.is_some() { - rules_for_this_field.declare.reindent(" ") - } else { - decl_var.reindent(" ") - }; - if needs_block { - let parse_var = parse_var.reindent(" "); - format!(" -{before_field}{decl_var} {{ -{block_before_field}{parse_var}{block_after_field} - }} -{after_field}", - before_field = before_field.reindent(" ").newline_if_not_empty(), - decl_var = decl_var.reindent(" ").newline_if_not_empty(), - block_before_field = rules_for_this_field.block_before_field.reindent(" ").newline_if_not_empty(), - parse_var = parse_var.reindent(" ").newline_if_not_empty(), - block_after_field = rules_for_this_field.block_after_field.reindent(" "), - after_field = after_field.reindent(" "), - ) - } else { - // We have a before_field and an after_field. This will create newlines - // for them. - format!(" -{before_field}{decl_var}{parse_var}{after_field}", - before_field = before_field.reindent(" ").newline_if_not_empty(), - decl_var = decl_var.reindent(" ").newline_if_not_empty(), - parse_var = parse_var.reindent(" ").newline_if_not_empty(), - after_field = after_field.reindent(" ")) - } - } - }; - fields_implem.push_str(&rendered); - } - - let init = rules_for_this_interface.init.reindent(" "); - let build_result = rules_for_this_interface.build_result.reindent(" "); - - if build_result == "" { - buffer.push_str(&format!("{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({class_name})\"); -}} - -", - class_name = name.to_class_cases(), - first_line = first_line, - )); - } else { - buffer.push_str(&format!("{first_line} -{{ - BINJS_TRY(CheckRecursionLimit(cx_)); -{pre}{fields_implem} -{post} return result; -}} - -", - fields_implem = fields_implem, - pre = init.newline_if_not_empty(), - post = build_result.newline_if_not_empty(), - first_line = first_line, - )); - } - } - - /// Generate C++ code for SpiderMonkey - fn to_spidermonkey_cpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - // 0. Header - buffer.push_str(&self.rules.cpp_header.reindent("")); - buffer.push_str("\n"); - - // 1. Typesums - buffer.push_str(" - -// ----- Sums of interfaces (autogenerated, by lexicographical order) -"); - buffer.push_str("// Sums of sums are flattened. -"); - - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)); - - for (name, nodes) in sums_of_interfaces { - self.generate_implement_sum(&mut buffer, name, nodes); - } - - // 2. Single interfaces - buffer.push_str(" - -// ----- Interfaces (autogenerated, by lexicographical order) -"); - buffer.push_str("// When fields have a non-trivial type, implementation is deanonymized and delegated to another parser. -"); - let interfaces_by_name = self.syntax.interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - - for (name, interface) in interfaces_by_name { - self.generate_implement_interface(&mut buffer, name, interface); - } - - // 3. String Enums - buffer.push_str(" - -// ----- String enums (autogenerated, by lexicographical order) -"); - { - let string_enums_by_name = self.syntax.string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, enum_) in string_enums_by_name { - if !self.refgraph.is_used(kind.to_rc_string().clone()) { - continue; - } - - let convert = format!(" switch (variant) {{ -{cases} - default: - if (isInvalidVariantPossible()) {{ - return raiseInvalidVariant(\"{kind}\", variant); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTVariant should not appear\"); - }} - }}", - kind = kind, - cases = enum_.strings() - .iter() - .map(|symbol| { - format!(" case BinASTVariant::{binastvariant_variant}: - return {kind}::{specialized_variant};", - kind = kind, - specialized_variant = symbol.to_cpp_enum_case(), - binastvariant_variant = self.variants_by_symbol.get(symbol) - .unwrap() - ) - }) - .format("\n") - ); - - let rendered_doc = format!("/* -enum {kind} {{ -{cases} -}}; -*/ -", - kind = kind, - cases = enum_.strings() - .iter() - .map(|s| format!(" \"{}\"", s)) - .format(",\n") - ); - buffer.push_str(&format!("{rendered_doc}{first_line} -{{ - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - -{convert} -}} - -", - rendered_doc = rendered_doc, - convert = convert, - first_line = self.get_method_definition_start(kind, "", "", - &None) - )); - } - } - - // 4. Lists - buffer.push_str(" - -// ----- Lists (autogenerated, by lexicographical order) -"); - for parser in &self.list_parsers_to_generate { - self.generate_implement_list(&mut buffer, parser); - } - - // 5. Optional values - buffer.push_str(" - - // ----- Default values (by lexicographical order) -"); - for parser in &self.option_parsers_to_generate { - self.generate_implement_option(&mut buffer, parser); - } - - buffer.push_str("\n"); - buffer.push_str(&self.rules.cpp_footer.reindent("")); - buffer.push_str("\n"); - - buffer - } -} - -fn update_rule(rule: &mut Option, entry: &yaml_rust::Yaml) -> Result, ()> { - if entry.is_badvalue() { - return Ok(None) - } else if let Some(as_str) = entry.as_str() { - *rule = Some(as_str.to_string()); - Ok(Some(())) - } else { - Err(()) - } -} -fn update_rule_rc(rule: &mut Option>, entry: &yaml_rust::Yaml) -> Result, ()> { - let mut value = None; - let ret = update_rule(&mut value, entry)?; - if let Some(s) = value { - *rule = Some(Rc::new(s)); - } - Ok(ret) -} - -fn main() { - env_logger::init(); - - let matches = App::new("BinAST C++ parser generator") - .author("David Teller, ") - .about("Converts an webidl syntax definition and a yaml set of rules into the C++ source code of a parser.") - .args(&[ - Arg::with_name("INPUT.webidl") - .required(true) - .help("Input webidl file to use. Must be a webidl source file."), - Arg::with_name("INPUT.yaml") - .required(true) - .help("Input rules file to use. Must be a yaml source file."), - Arg::with_name("OUT_HEADER_CLASS_FILE") - .long("out-class") - .required(true) - .takes_value(true) - .help("Output header file for class (.h)"), - Arg::with_name("OUT_HEADER_ENUM_FILE") - .long("out-enum") - .required(true) - .takes_value(true) - .help("Output header file for enum (.h)"), - Arg::with_name("OUT_TOKEN_FILE") - .long("out-token") - .required(true) - .takes_value(true) - .help("Output token file (.h)"), - Arg::with_name("OUT_IMPL_FILE") - .long("out-impl") - .required(true) - .takes_value(true) - .help("Output implementation file (.cpp)"), - ]) - .get_matches(); - - let source_path = matches.value_of("INPUT.webidl") - .expect("Expected INPUT.webidl"); - - let mut file = File::open(source_path) - .expect("Could not open source"); - let mut source = String::new(); - file.read_to_string(&mut source) - .expect("Could not read source"); - - println!("...verifying grammar"); - let mut builder = Importer::import(vec![source.as_ref()]) - .expect("Invalid grammar"); - let fake_root = builder.node_name("@@ROOT@@"); // Unused - let null = builder.node_name(""); // Used - builder.add_interface(&null) - .unwrap(); - let syntax = builder.into_spec(SpecOptions { - root: &fake_root, - null: &null, - }); - - let deanonymizer = TypeDeanonymizer::new(&syntax); - let syntax_options = SpecOptions { - root: &fake_root, - null: &null, - }; - let new_syntax = deanonymizer.into_spec(syntax_options); - - let rules_source_path = matches.value_of("INPUT.yaml").unwrap(); - println!("...generating rules"); - let mut file = File::open(rules_source_path) - .expect("Could not open rules"); - let mut data = String::new(); - file.read_to_string(&mut data) - .expect("Could not read rules"); - - let yaml = yaml_rust::YamlLoader::load_from_str(&data) - .expect("Could not parse rules"); - assert_eq!(yaml.len(), 1); - - let global_rules = GlobalRules::new(&new_syntax, &yaml[0]); - let mut exporter = CPPExporter::new(new_syntax, global_rules); - - exporter.generate_reference_graph(); - exporter.trace(Rc::new(TOPLEVEL_INTERFACE.to_string())); - exporter.collect_context(); - - let write_to = |description, arg, data: &String| { - let dest_path = matches.value_of(arg) - .unwrap(); - print!("...exporting {description}: {path} ... ", - description = description, - path = dest_path); - - let mut dest = File::create(&dest_path) - .unwrap_or_else(|e| panic!("Could not create {description} at {path}: {error}", - description = description, - path = dest_path, - error = e)); - dest.write_all(data.as_bytes()) - .unwrap_or_else(|e| panic!("Could not write {description} at {path}: {error}", - description = description, - path = dest_path, - error = e)); - - println!("done"); - }; - - write_to("C++ class header code", "OUT_HEADER_CLASS_FILE", - &exporter.to_spidermonkey_class_hpp()); - write_to("C++ enum header code", "OUT_HEADER_ENUM_FILE", - &exporter.to_spidermonkey_enum_hpp()); - write_to("C++ token header code", "OUT_TOKEN_FILE", - &exporter.to_spidermonkey_token_hpp()); - write_to("C++ token implementation code", "OUT_IMPL_FILE", - &exporter.to_spidermonkey_cpp()); - - println!("...done"); -} diff --git a/js/src/frontend/binast/src/refgraph.rs b/js/src/frontend/binast/src/refgraph.rs deleted file mode 100644 index 534e3420dc..0000000000 --- a/js/src/frontend/binast/src/refgraph.rs +++ /dev/null @@ -1,96 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; -use std::rc::Rc; - -/// A node in the reference graph -struct ReferenceGraphNode { - /// True if this node is used. - used: RefCell, - - /// The set of method names which node uses. - edges: HashSet>, -} -impl ReferenceGraphNode { - fn new(edges: HashSet>) -> Self { - ReferenceGraphNode { - used: RefCell::new(false), - edges, - } - } -} - -/// A reference graph of the method call. -/// -/// Each auto-generated method has corresponding node in this reference graph, -/// and the method definition/declaration are written to the file only if the -/// method is marked as used. -/// -/// This is necessary for the following reason: -/// * we generate parseX and parseInterfaceX for `interface X` -/// * parseX is not used if `interface X` appears only in sum interface -pub struct ReferenceGraph { - /// The map from the node name to node struct. - /// Node name is the method name without leading "parse". - refnodes: HashMap, Rc>, -} -impl ReferenceGraph { - pub fn new() -> Self { - ReferenceGraph { - refnodes: HashMap::new(), - } - } - - /// Trace the reference graph from the node with `name and mark all nodes - /// as used. `name` is the name of the method, without leading "parse". - pub fn trace(&mut self, name: Rc) { - // The set of edges to trace in the current iteration. - let mut edges: HashSet> = HashSet::new(); - edges.insert(name); - - // Iterate over the remaining edges until all edges are traced. - loop { - // The set of edges to trace in the next iteration. - let mut next_edges: HashSet> = HashSet::new(); - - for edge in edges { - let refnode = self.refnodes.get(&edge).unwrap_or_else(|| { - panic!("While computing dependencies, node {} doesn't exist", edge) - }); - if *refnode.used.borrow() { - continue; - } - - refnode.used.replace(true); - - for next_edge in refnode.edges.iter() { - next_edges.insert(next_edge.clone()); - } - } - - if next_edges.len() == 0 { - break; - } - - edges = next_edges; - } - } - - /// Return true if the method named `name` (without leading "parse") is - /// used. - pub fn is_used(&self, name: Rc) -> bool { - match self.refnodes.get(&name) { - Some(refnode) => *refnode.used.borrow(), - None => false, - } - } - - /// Insert a node with `name` to the graph. - pub fn insert(&mut self, name: Rc, edges: HashSet>) { - self.refnodes - .insert(name, Rc::new(ReferenceGraphNode::new(edges))); - } -} diff --git a/js/src/frontend/moz.build b/js/src/frontend/moz.build index 20ed6d2c15..2b3207cd3b 100644 --- a/js/src/frontend/moz.build +++ b/js/src/frontend/moz.build @@ -18,6 +18,8 @@ include('../js-cxxflags.mozbuild') GeneratedFile('ReservedWordsGenerated.h', script='GenerateReservedWords.py', inputs=['ReservedWords.h']) +if CONFIG['JS_ENABLE_SMOOSH']: + CbindgenHeader('smoosh_generated.h', inputs=['/js/src/frontend/smoosh']) UNIFIED_SOURCES += [ 'AbstractScopePtr.cpp', @@ -49,6 +51,7 @@ UNIFIED_SOURCES += [ 'ParseContext.cpp', 'ParseNode.cpp', 'ParseNodeVerify.cpp', + 'ParserAtom.cpp', 'PropOpEmitter.cpp', 'SharedContext.cpp', 'SourceNotes.cpp', @@ -60,40 +63,14 @@ UNIFIED_SOURCES += [ 'WhileEmitter.cpp', ] +if CONFIG['JS_ENABLE_SMOOSH']: + UNIFIED_SOURCES += [ + 'Frontend2.cpp', + ] + + # Parser.cpp cannot be built in unified mode because of explicit # template instantiations. SOURCES += [ 'Parser.cpp', ] - -if CONFIG['JS_BUILD_BINAST']: - # Using SOURCES, as UNIFIED_SOURCES causes mysterious bugs on 32-bit - # platforms. - - # These parts of BinAST should eventually move to release. - SOURCES += [ - 'BinASTParser.cpp', - 'BinASTParserBase.cpp', - 'BinASTParserPerTokenizer.cpp', - 'BinASTRuntimeSupport.cpp', - 'BinASTToken.cpp', - 'BinASTTokenReaderBase.cpp', - 'BinASTTokenReaderContext.cpp', - 'BinASTTokenReaderMultipart.cpp', - ] - - if CONFIG['JS_STANDALONE']: - DIRS += [ - 'binast' - ] - - # Instrument BinAST files for fuzzing as we have a fuzzing target for BinAST. - if CONFIG['FUZZING_INTERFACES'] and CONFIG['LIBFUZZER']: - include('/tools/fuzzing/libfuzzer-flags.mozbuild') - - SOURCES['BinASTParser.cpp'].flags += libfuzzer_flags - SOURCES['BinASTParserBase.cpp'].flags += libfuzzer_flags - SOURCES['BinASTParserPerTokenizer.cpp'].flags += libfuzzer_flags - SOURCES['BinASTToken.cpp'].flags += libfuzzer_flags - SOURCES['BinASTTokenReaderBase.cpp'].flags += libfuzzer_flags - SOURCES['BinASTTokenReaderMultipart.cpp'].flags += libfuzzer_flags diff --git a/js/src/frontend/smoosh/Cargo.toml b/js/src/frontend/smoosh/Cargo.toml new file mode 100644 index 0000000000..33369373cd --- /dev/null +++ b/js/src/frontend/smoosh/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "smoosh" +version = "0.1.0" +authors = ["The jsparagus Project Developers"] +edition = "2018" +license = "MIT/Apache-2.0" + +[dependencies] +bumpalo = "3.4.0" +log = "0.4" +# Setup RUST_LOG logging. +# Disable regex feature for code size. +env_logger = {version = "0.6", default-features = false} +# For non-jsparagus developers. +jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "0b933acac9dc56067e66f26d16ee00194a91e13b" } +# For local development, replace above with +# jsparagus = { path = "{path to jsparagus}" } + +[build-dependencies] +# For non-jsparagus developers. +jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "0b933acac9dc56067e66f26d16ee00194a91e13b" } +# For local development, replace above with +# jsparagus = { path = "{path to jsparagus}" } diff --git a/js/src/frontend/smoosh/build.rs b/js/src/frontend/smoosh/build.rs new file mode 100644 index 0000000000..3ae2cf54cd --- /dev/null +++ b/js/src/frontend/smoosh/build.rs @@ -0,0 +1,30 @@ +use jsparagus::stencil::opcode_info; + +fn compare(name: &str, orig: &str, copied: &str) { + if copied != orig { + panic!( + "{} is out of sync. \ + It's possible that the bytecode generated by jsparagus is \ + based on older opcodes. Please run \ + update_stencil.py in jsparagus. \ + You can disable this check by setting \ + JS_SMOOSH_DISABLE_OPCODE_CHECK environment variable.", + name + ); + } +} + +fn main() { + match std::env::var("JS_SMOOSH_DISABLE_OPCODE_CHECK") { + Ok(_) => { + return; + } + Err(_) => {} + }; + + compare( + "Opcodes.h", + include_str!("../../vm/Opcodes.h"), + opcode_info::get_opcodes_source(), + ); +} diff --git a/js/src/frontend/smoosh/cbindgen.toml b/js/src/frontend/smoosh/cbindgen.toml new file mode 100644 index 0000000000..71a9568b35 --- /dev/null +++ b/js/src/frontend/smoosh/cbindgen.toml @@ -0,0 +1,19 @@ +header = """/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */""" +autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. See RunCbindgen.py */ + +#include "mozilla/Assertions.h" // MOZ_ASSERT +""" +include_version = true +braces = "SameLine" +line_length = 100 +tab_width = 2 +language = "C++" + +[enum] +derive_helper_methods = true +derive_const_casts = true +derive_mut_casts = true + +cast_assert_name = "MOZ_ASSERT" diff --git a/js/src/frontend/smoosh/moz.build b/js/src/frontend/smoosh/moz.build new file mode 100644 index 0000000000..61725da17a --- /dev/null +++ b/js/src/frontend/smoosh/moz.build @@ -0,0 +1,16 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FINAL_LIBRARY = 'js' + +# Includes should be relative to parent path +LOCAL_INCLUDES += [ + '!../..', + '../..' +] + +include('../../js-config.mozbuild') +include('../../js-cxxflags.mozbuild') + +DIRS += ['../../rust'] diff --git a/js/src/fuzz-tests/moz.build b/js/src/fuzz-tests/moz.build index 424de2ea5d..335419d1e2 100644 --- a/js/src/fuzz-tests/moz.build +++ b/js/src/fuzz-tests/moz.build @@ -15,11 +15,6 @@ UNIFIED_SOURCES += [ 'testWasm.cpp', ] -if CONFIG['JS_BUILD_BINAST']: - UNIFIED_SOURCES += [ - 'testBinASTReader.cpp', - ] - DEFINES['EXPORT_JS_API'] = True LOCAL_INCLUDES += [ diff --git a/js/src/fuzz-tests/testBinASTReader.cpp b/js/src/fuzz-tests/testBinASTReader.cpp deleted file mode 100644 index b0a9a7f1f2..0000000000 --- a/js/src/fuzz-tests/testBinASTReader.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mozilla/ScopeExit.h" - -#include "jsapi.h" - -#include "frontend/BinASTParser.h" -#include "frontend/FullParseHandler.h" -#include "frontend/ParseContext.h" -#include "frontend/Parser.h" -#include "fuzz-tests/tests.h" -#include "js/CompileOptions.h" -#include "vm/Interpreter.h" - -#include "vm/JSContext-inl.h" - -using UsedNameTracker = js::frontend::UsedNameTracker; -using namespace js; - -using JS::CompileOptions; - -// These are defined and pre-initialized by the harness (in tests.cpp). -extern JS::PersistentRootedObject gGlobal; -extern JSContext* gCx; - -static int testBinASTReaderInit(int* argc, char*** argv) { return 0; } - -static int testBinASTReaderFuzz(const uint8_t* buf, size_t size) { - using namespace js::frontend; - - auto gcGuard = mozilla::MakeScopeExit([&] { - JS::PrepareForFullGC(gCx); - JS::NonIncrementalGC(gCx, GC_NORMAL, JS::GCReason::API); - }); - - if (!size) return 0; - - CompileOptions options(gCx); - options.setIntroductionType("fuzzing parse").setFileAndLine("", 1); - - js::Vector binSource(gCx); - if (!binSource.append(buf, size)) { - ReportOutOfMemory(gCx); - return 0; - } - - LifoAllocScope allocScope(&gCx->tempLifoAlloc()); - CompilationInfo binCompilationInfo(gCx, allocScope, options); - if (!binCompilationInfo.init(gCx)) { - return 0; - } - - SourceExtent extent; - Directives directives(false); - GlobalSharedContext globalsc(gCx, ScopeKind::Global, binCompilationInfo, - directives, extent); - - BinASTParser reader( - gCx, binCompilationInfo, options); - - // Will be deallocated once `reader` goes out of scope. - auto binParsed = reader.parse(&globalsc, binSource); - RootedValue binExn(gCx); - if (binParsed.isErr()) { - js::GetAndClearException(gCx, &binExn); - return 0; - } - -#if defined(DEBUG) // Dumping an AST is only defined in DEBUG builds - Sprinter binPrinter(gCx); - if (!binPrinter.init()) { - ReportOutOfMemory(gCx); - return 0; - } - DumpParseTree(binParsed.unwrap(), binPrinter); -#endif // defined(DEBUG) - - return 0; -} - -MOZ_FUZZING_INTERFACE_RAW(testBinASTReaderInit, testBinASTReaderFuzz, BinAST); diff --git a/js/src/gc/AllocKind.h b/js/src/gc/AllocKind.h index b6c2a71c53..12ebe50f80 100644 --- a/js/src/gc/AllocKind.h +++ b/js/src/gc/AllocKind.h @@ -62,7 +62,7 @@ namespace gc { D(SHAPE, Shape, js::Shape, js::Shape, true, false, true) \ D(ACCESSOR_SHAPE, Shape, js::AccessorShape, js::AccessorShape, true, false, true) \ D(BASE_SHAPE, BaseShape, js::BaseShape, js::BaseShape, true, false, true) \ - D(OBJECT_GROUP, ObjectGroup, js::ObjectGroup, js::ObjectGroup, true, false, false) \ + D(OBJECT_GROUP, ObjectGroup, js::ObjectGroup, js::ObjectGroup, true, false, true) \ D(EXTERNAL_STRING, String, JSExternalString, JSExternalString, true, false, true) \ D(FAT_INLINE_ATOM, String, js::FatInlineAtom, js::FatInlineAtom, true, false, false) \ D(ATOM, String, js::NormalAtom, js::NormalAtom, true, false, false) \ diff --git a/js/src/gc/Allocator.cpp b/js/src/gc/Allocator.cpp index 176601b750..69c8e96e8a 100644 --- a/js/src/gc/Allocator.cpp +++ b/js/src/gc/Allocator.cpp @@ -125,28 +125,31 @@ template JSObject* GCRuntime::tryNewTenuredObject(JSContext* cx, AllocKind kind, size_t thingSize, size_t nDynamicSlots) { - HeapSlot* slots = nullptr; + ObjectSlots* slotsHeader = nullptr; if (nDynamicSlots) { - slots = cx->maybe_pod_malloc(nDynamicSlots); - if (MOZ_UNLIKELY(!slots)) { + HeapSlot* allocation = + cx->maybe_pod_malloc(ObjectSlots::allocCount(nDynamicSlots)); + if (MOZ_UNLIKELY(!allocation)) { if (allowGC) { ReportOutOfMemory(cx); } return nullptr; } - Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots); + + slotsHeader = new (allocation) ObjectSlots(nDynamicSlots, 0); + Debug_SetSlotRangeToCrashOnTouch(slotsHeader->slots(), nDynamicSlots); } JSObject* obj = tryNewTenuredThing(cx, kind, thingSize); if (obj) { if (nDynamicSlots) { - static_cast(obj)->initSlots(slots); - AddCellMemory(obj, nDynamicSlots * sizeof(HeapSlot), + static_cast(obj)->initSlots(slotsHeader->slots()); + AddCellMemory(obj, ObjectSlots::allocSize(nDynamicSlots), MemoryUse::ObjectSlots); } } else { - js_free(slots); + js_free(slotsHeader); } return obj; @@ -208,7 +211,7 @@ StringAllocT* js::AllocateStringImpl(JSContext* cx, InitialHeap heap) { if (cx->nursery().isEnabled() && heap != TenuredHeap && cx->nursery().canAllocateStrings() && cx->zone()->allocNurseryStrings) { - auto str = static_cast( + auto* str = static_cast( rt->gc.tryNewNurseryString(cx, size, kind)); if (str) { return str; @@ -279,7 +282,7 @@ JS::BigInt* js::AllocateBigInt(JSContext* cx, InitialHeap heap) { if (cx->nursery().isEnabled() && heap != TenuredHeap && cx->nursery().canAllocateBigInts() && cx->zone()->allocNurseryBigInts) { - auto bi = static_cast( + auto* bi = static_cast( rt->gc.tryNewNurseryBigInt(cx, size, kind)); if (bi) { return bi; @@ -344,7 +347,7 @@ template T* GCRuntime::tryNewTenuredThing(JSContext* cx, AllocKind kind, size_t thingSize) { // Bump allocate in the arena's current free-list span. - T* t = reinterpret_cast(cx->freeLists().allocate(kind)); + auto* t = reinterpret_cast(cx->freeLists().allocate(kind)); if (MOZ_UNLIKELY(!t)) { // Get the next available free list and allocate out of it. This may // acquire a new arena, which will lock the chunk list. If there are no @@ -553,8 +556,7 @@ TenuredCell* ArenaLists::refillFreeListAndAllocate( maybeLock.emplace(rt); } - ArenaList& al = arenaList(thingKind); - Arena* arena = al.takeNextArena(); + Arena* arena = arenaList(thingKind).takeNextArena(); if (arena) { // Empty arenas should be immediately freed. MOZ_ASSERT(!arena->isEmpty()); @@ -581,12 +583,19 @@ TenuredCell* ArenaLists::refillFreeListAndAllocate( return nullptr; } - MOZ_ASSERT(al.isCursorAtEnd()); - al.insertBeforeCursor(arena); + addNewArena(arena, thingKind); return freeLists.setArenaAndAllocate(arena, thingKind); } +inline void ArenaLists::addNewArena(Arena* arena, AllocKind thingKind) { + ArenaList& al = zone_->isGCMarking() ? newArenasInMarkPhase(thingKind) + : arenaList(thingKind); + + MOZ_ASSERT(al.isCursorAtEnd()); + al.insertBeforeCursor(arena); +} + inline TenuredCell* FreeLists::setArenaAndAllocate(Arena* arena, AllocKind kind) { #ifdef DEBUG @@ -790,15 +799,17 @@ BackgroundAllocTask::BackgroundAllocTask(GCRuntime* gc, ChunkPool& pool) chunkPool_(pool), enabled_(CanUseExtraThreads() && GetCPUCount() >= 2) {} -void BackgroundAllocTask::run() { +void BackgroundAllocTask::run(AutoLockHelperThreadState& lock) { + AutoUnlockHelperThreadState unlock(lock); + TraceLoggerThread* logger = TraceLoggerForCurrentThread(); AutoTraceLog logAllocation(logger, TraceLogger_GCAllocation); - AutoLockGC lock(gc); - while (!cancel_ && gc->wantBackgroundAllocation(lock)) { + AutoLockGC gcLock(gc); + while (!cancel_ && gc->wantBackgroundAllocation(gcLock)) { Chunk* chunk; { - AutoUnlockGC unlock(lock); + AutoUnlockGC unlock(gcLock); chunk = Chunk::allocate(gc); if (!chunk) { break; @@ -811,7 +822,7 @@ void BackgroundAllocTask::run() { /* static */ Chunk* Chunk::allocate(GCRuntime* gc) { - Chunk* chunk = static_cast(MapAlignedPages(ChunkSize, ChunkSize)); + auto* chunk = static_cast(MapAlignedPages(ChunkSize, ChunkSize)); if (!chunk) { return nullptr; } diff --git a/js/src/gc/ArenaList-inl.h b/js/src/gc/ArenaList-inl.h index 199493511a..6938e3643d 100644 --- a/js/src/gc/ArenaList-inl.h +++ b/js/src/gc/ArenaList-inl.h @@ -254,6 +254,11 @@ js::gc::Arena* js::gc::ArenaLists::getFirstSweptArena( return incrementalSweptArenas.ref().head(); } +js::gc::Arena* js::gc::ArenaLists::getFirstNewArenaInMarkPhase( + AllocKind thingKind) const { + return newArenasInMarkPhase(thingKind).head(); +} + js::gc::Arena* js::gc::ArenaLists::getArenaAfterCursor( AllocKind thingKind) const { return arenaList(thingKind).arenaAfterCursor(); @@ -306,6 +311,13 @@ void js::gc::ArenaLists::unmarkPreMarkedFreeCells() { } } +void js::gc::ArenaLists::mergeNewArenasInMarkPhase() { + for (auto i : AllAllocKinds()) { + arenaList(i).insertListWithCursorAtEnd(newArenasInMarkPhase(i)); + newArenasInMarkPhase(i).clear(); + } +} + void js::gc::ArenaLists::checkEmptyFreeLists() { MOZ_ASSERT(freeLists().allEmpty()); } diff --git a/js/src/gc/ArenaList.h b/js/src/gc/ArenaList.h index 959f8db0df..7c8e93a778 100644 --- a/js/src/gc/ArenaList.h +++ b/js/src/gc/ArenaList.h @@ -258,8 +258,12 @@ class ArenaLists { ZoneData freeLists_; + /* The main list of arenas for each alloc kind. */ ArenaListData> arenaLists_; + /* For each arena kind, a list of arenas allocated during marking. */ + ArenaListData> newArenasInMarkPhase_; + /* For each arena kind, a list of arenas remaining to be swept. */ MainThreadOrGCTaskData> arenasToSweep_; @@ -272,7 +276,9 @@ class ArenaLists { ZoneData gcShapeArenasToUpdate; ZoneData gcAccessorShapeArenasToUpdate; ZoneData gcScriptArenasToUpdate; + ZoneData gcNewScriptArenasToUpdate; ZoneData gcObjectGroupArenasToUpdate; + ZoneData gcNewObjectGroupArenasToUpdate; // The list of empty arenas which are collected during the sweep phase and // released at the end of sweeping every sweep group. @@ -292,6 +298,7 @@ class ArenaLists { inline Arena* getFirstArena(AllocKind thingKind) const; inline Arena* getFirstArenaToSweep(AllocKind thingKind) const; inline Arena* getFirstSweptArena(AllocKind thingKind) const; + inline Arena* getFirstNewArenaInMarkPhase(AllocKind thingKind) const; inline Arena* getArenaAfterCursor(AllocKind thingKind) const; inline bool arenaListsAreEmpty() const; @@ -332,6 +339,9 @@ class ArenaLists { void setParallelAllocEnabled(bool enabled); + inline void mergeNewArenasInMarkPhase(); + + void checkGCStateNotInUse(); void checkSweepStateNotInUse(); void checkNoArenasToUpdate(); void checkNoArenasToUpdateForKind(AllocKind kind); @@ -340,6 +350,13 @@ class ArenaLists { ArenaList& arenaList(AllocKind i) { return arenaLists_.ref()[i]; } const ArenaList& arenaList(AllocKind i) const { return arenaLists_.ref()[i]; } + ArenaList& newArenasInMarkPhase(AllocKind i) { + return newArenasInMarkPhase_.ref()[i]; + } + const ArenaList& newArenasInMarkPhase(AllocKind i) const { + return newArenasInMarkPhase_.ref()[i]; + } + ConcurrentUseState& concurrentUse(AllocKind i) { return concurrentUseState_.ref()[i]; } @@ -364,6 +381,8 @@ class ArenaLists { AllocKind thingKind, ShouldCheckThresholds checkThresholds); + void addNewArena(Arena* arena, AllocKind thingKind); + friend class GCRuntime; friend class js::Nursery; friend class js::TenuringTracer; diff --git a/js/src/gc/AtomMarking-inl.h b/js/src/gc/AtomMarking-inl.h index 64300dee4b..92e75fdd62 100644 --- a/js/src/gc/AtomMarking-inl.h +++ b/js/src/gc/AtomMarking-inl.h @@ -9,6 +9,7 @@ #include #include "vm/Realm.h" +#include "vm/SymbolType.h" #include "gc/Heap-inl.h" @@ -23,12 +24,6 @@ inline size_t GetAtomBit(TenuredCell* thing) { return arena->atomBitmapStart() * JS_BITS_PER_WORD + arenaBit; } -inline bool ThingIsPermanent(JSAtom* atom) { return atom->isPinned(); } - -inline bool ThingIsPermanent(JS::Symbol* symbol) { - return symbol->isWellKnownSymbol(); -} - template MOZ_ALWAYS_INLINE bool AtomMarkingRuntime::inlinedMarkAtomInternal( JSContext* cx, T* thing) { @@ -45,7 +40,9 @@ MOZ_ALWAYS_INLINE bool AtomMarkingRuntime::inlinedMarkAtomInternal( } MOZ_ASSERT(!cx->zone()->isAtomsZone()); - if (ThingIsPermanent(thing)) { + // This doesn't check for pinned atoms since that might require taking a + // lock. This is not required for correctness. + if (thing->isPermanentAndMayBeShared()) { return true; } @@ -65,7 +62,7 @@ MOZ_ALWAYS_INLINE bool AtomMarkingRuntime::inlinedMarkAtomInternal( // GC in progress. This is necessary if the atom is being marked // because a reference to it was obtained from another zone which is // not being collected by the incremental GC. - T::readBarrier(thing); + ReadBarrier(thing); } // Children of the thing also need to be marked in the context's zone. @@ -76,6 +73,14 @@ MOZ_ALWAYS_INLINE bool AtomMarkingRuntime::inlinedMarkAtomInternal( return true; } +void AtomMarkingRuntime::markChildren(JSContext* cx, JSAtom*) {} + +void AtomMarkingRuntime::markChildren(JSContext* cx, JS::Symbol* symbol) { + if (JSAtom* description = symbol->description()) { + markAtom(cx, description); + } +} + template MOZ_ALWAYS_INLINE void AtomMarkingRuntime::inlinedMarkAtom(JSContext* cx, T* thing) { diff --git a/js/src/gc/AtomMarking.cpp b/js/src/gc/AtomMarking.cpp index 5e10c7096a..27ca3620e2 100644 --- a/js/src/gc/AtomMarking.cpp +++ b/js/src/gc/AtomMarking.cpp @@ -84,7 +84,7 @@ bool AtomMarkingRuntime::computeBitmapFromChunkMarkBits(JSRuntime* runtime, for (auto thingKind : AllAllocKinds()) { for (ArenaIter aiter(atomsZone, thingKind); !aiter.done(); aiter.next()) { Arena* arena = aiter.get(); - uintptr_t* chunkWords = arena->chunk()->bitmap.arenaBits(arena); + MarkBitmapWord* chunkWords = arena->chunk()->bitmap.arenaBits(arena); bitmap.copyBitsFrom(arena->atomBitmapStart(), ArenaBitmapWords, chunkWords); } @@ -119,7 +119,7 @@ static void BitwiseOrIntoChunkMarkBits(JSRuntime* runtime, Bitmap& bitmap) { for (auto thingKind : AllAllocKinds()) { for (ArenaIter aiter(atomsZone, thingKind); !aiter.done(); aiter.next()) { Arena* arena = aiter.get(); - uintptr_t* chunkWords = arena->chunk()->bitmap.arenaBits(arena); + MarkBitmapWord* chunkWords = arena->chunk()->bitmap.arenaBits(arena); bitmap.bitwiseOrRangeInto(arena->atomBitmapStart(), ArenaBitmapWords, chunkWords); } @@ -209,10 +209,17 @@ bool AtomMarkingRuntime::atomIsMarked(Zone* zone, T* thing) { return true; } - if (ThingIsPermanent(thing)) { + if (thing->isPermanentAndMayBeShared()) { return true; } + if constexpr (std::is_same_v) { + JSRuntime* rt = zone->runtimeFromAnyThread(); + if (rt->atoms().atomIsPinned(rt, thing)) { + return true; + } + } + size_t bit = GetAtomBit(&thing->asTenured()); return zone->markedAtoms().getBit(bit); } diff --git a/js/src/gc/AtomMarking.h b/js/src/gc/AtomMarking.h index 581ae2c73a..3588818973 100644 --- a/js/src/gc/AtomMarking.h +++ b/js/src/gc/AtomMarking.h @@ -8,9 +8,11 @@ #include "NamespaceImports.h" #include "ds/Bitmap.h" #include "threading/ProtectedData.h" -#include "vm/SymbolType.h" namespace js { + +class AutoLockGC; + namespace gc { class Arena; @@ -21,13 +23,8 @@ class AtomMarkingRuntime { // Unused arena atom bitmap indexes. Protected by the GC lock. js::GCLockData> freeArenaIndexes; - void markChildren(JSContext* cx, JSAtom*) {} - - void markChildren(JSContext* cx, JS::Symbol* symbol) { - if (JSAtom* description = symbol->description()) { - markAtom(cx, description); - } - } + inline void markChildren(JSContext* cx, JSAtom*); + inline void markChildren(JSContext* cx, JS::Symbol* symbol); public: // The extent of all allocated and free words in atom mark bitmaps. diff --git a/js/src/gc/Barrier.cpp b/js/src/gc/Barrier.cpp index fc9691808e..bd02d8b4d8 100644 --- a/js/src/gc/Barrier.cpp +++ b/js/src/gc/Barrier.cpp @@ -8,6 +8,7 @@ #include "gc/Policy.h" #include "jit/Ion.h" #include "js/HashTable.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone #include "js/Value.h" #include "vm/BigIntType.h" // JS::BigInt #include "vm/EnvironmentObject.h" @@ -43,7 +44,7 @@ bool HeapSlot::preconditionForSet(NativeObject* owner, Kind kind, return &owner->getDenseElement(slot - numShifted) == (const Value*)this; } -void HeapSlot::assertPreconditionForWriteBarrierPost( +void HeapSlot::assertPreconditionForPostWriteBarrier( NativeObject* obj, Kind kind, uint32_t slot, const Value& target) const { if (kind == Slot) { MOZ_ASSERT(obj->getSlotAddressUnchecked(slot)->get() == target); @@ -69,19 +70,23 @@ bool CurrentThreadIsIonCompilingSafeForMinorGC() { } bool CurrentThreadIsGCMarking() { - return TlsContext.get()->gcUse == JSContext::GCUse::Marking; + JSContext* cx = MaybeGetJSContext(); + return cx && cx->gcUse == JSContext::GCUse::Marking; } bool CurrentThreadIsGCSweeping() { - return TlsContext.get()->gcUse == JSContext::GCUse::Sweeping; + JSContext* cx = MaybeGetJSContext(); + return cx && cx->gcUse == JSContext::GCUse::Sweeping; } bool CurrentThreadIsGCFinalizing() { - return TlsContext.get()->gcUse == JSContext::GCUse::Finalizing; + JSContext* cx = MaybeGetJSContext(); + return cx && cx->gcUse == JSContext::GCUse::Finalizing; } bool CurrentThreadIsTouchingGrayThings() { - return TlsContext.get()->isTouchingGrayThings; + JSContext* cx = MaybeGetJSContext(); + return cx && cx->isTouchingGrayThings; } AutoTouchingGrayThings::AutoTouchingGrayThings() { @@ -96,16 +101,103 @@ AutoTouchingGrayThings::~AutoTouchingGrayThings() { #endif // DEBUG -/* static */ void InternalBarrierMethods::readBarrier(const Value& v) { - ApplyGCThingTyped(v, [](auto t) { t->readBarrier(t); }); +// Tagged pointer barriers +// +// It's tempting to use ApplyGCThingTyped to dispatch to the typed barrier +// functions (e.g. gc::ReadBarrier(JSObject*)) but this does not compile well +// (clang generates 1580 bytes on x64 versus 296 bytes for this implementation +// of ValueReadBarrier). +// +// Instead, check known special cases and call the generic barrier functions. + +static MOZ_ALWAYS_INLINE bool ValueIsPermanent(const Value& value) { + gc::Cell* cell = value.toGCThing(); + + if (value.isString()) { + return cell->as()->isPermanentAndMayBeShared(); + } + + if (value.isSymbol()) { + return cell->as()->isPermanentAndMayBeShared(); + } + +#ifdef DEBUG + // Using mozilla::DebugOnly here still generated code in opt builds. + bool isPermanent = MapGCThingTyped(value, [](auto t) { + return t->isPermanentAndMayBeShared(); + }).value(); + MOZ_ASSERT(!isPermanent); +#endif + + return false; +} + +void gc::ValueReadBarrier(const Value& v) { + MOZ_ASSERT(v.isGCThing()); + + if (!ValueIsPermanent(v)) { + ReadBarrierImpl(v.toGCThing()); + } } -/* static */ void InternalBarrierMethods::preBarrier(const Value& v) { - ApplyGCThingTyped(v, [](auto t) { t->writeBarrierPre(t); }); +void gc::ValuePreWriteBarrier(const Value& v) { + MOZ_ASSERT(v.isGCThing()); + + if (!ValueIsPermanent(v)) { + PreWriteBarrierImpl(v.toGCThing()); + } } -/* static */ void InternalBarrierMethods::preBarrier(jsid id) { - ApplyGCThingTyped(id, [](auto t) { t->writeBarrierPre(t); }); +static MOZ_ALWAYS_INLINE bool IdIsPermanent(jsid id) { + gc::Cell* cell = id.toGCThing(); + + if (id.isString()) { + return cell->as()->isPermanentAndMayBeShared(); + } + + if (id.isSymbol()) { + return cell->as()->isPermanentAndMayBeShared(); + } + +#ifdef DEBUG + bool isPermanent = MapGCThingTyped(id, [](auto t) { + return t->isPermanentAndMayBeShared(); + }).value(); + MOZ_ASSERT(!isPermanent); +#endif + + return false; +} + +void gc::IdPreWriteBarrier(jsid id) { + MOZ_ASSERT(id.isGCThing()); + + if (!IdIsPermanent(id)) { + PreWriteBarrierImpl(&id.toGCThing()->asTenured()); + } +} + +static MOZ_ALWAYS_INLINE bool CellPtrIsPermanent(JS::GCCellPtr thing) { + if (thing.mayBeOwnedByOtherRuntime()) { + return true; + } + +#ifdef DEBUG + bool isPermanent = MapGCThingTyped(thing, [](auto t) { + return t->isPermanentAndMayBeShared(); + }); + MOZ_ASSERT(!isPermanent); +#endif + + return false; +} + +void gc::CellPtrPreWriteBarrier(JS::GCCellPtr thing) { + MOZ_ASSERT(thing); + + if (!CellPtrIsPermanent(thing)) { + PreWriteBarrierImpl(thing.asCell()); + } } template diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index bc1dd877d8..691f396cdc 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -5,6 +5,8 @@ #ifndef gc_Barrier_h #define gc_Barrier_h +#include "mozilla/DebugOnly.h" + #include // std::true_type #include "NamespaceImports.h" @@ -179,7 +181,7 @@ * extra branch. * * In practice, we implement the pre-barrier differently based on the type of - * value0. E.g., see JSObject::writeBarrierPre, which is used if obj->field is + * value0. E.g., see JSObject::preWriteBarrier, which is used if obj->field is * a JSObject*. It takes value0 as a parameter. * * Post-write barrier @@ -259,20 +261,20 @@ * WeakHeapPtr provides read barriers only * * - * The implementation of the barrier logic is implemented on T::writeBarrier.*, - * via: + * The implementation of the barrier logic is implemented in the + * Cell/TenuredCell base classes, which are called via: * * WriteBarriered::pre * -> InternalBarrierMethods::preBarrier - * -> T::writeBarrierPre + * -> Cell::preWriteBarrier * -> InternalBarrierMethods::preBarrier * -> InternalBarrierMethods::preBarrier * -> InternalBarrierMethods::preBarrier - * -> T::writeBarrierPre + * -> Cell::preWriteBarrier * * GCPtr::post and HeapPtr::post * -> InternalBarrierMethods::postBarrier - * -> T::writeBarrierPost + * -> gc::PostWriteBarrierImpl * -> InternalBarrierMethods::postBarrier * -> StoreBuffer::put * @@ -290,6 +292,15 @@ namespace js { class NativeObject; +namespace gc { + +void ValueReadBarrier(const Value& v); +void ValuePreWriteBarrier(const Value& v); +void IdPreWriteBarrier(jsid id); +void CellPtrPreWriteBarrier(JS::GCCellPtr thing); + +} // namespace gc + #ifdef DEBUG // Barriers can't be triggered during backend Ion compilation, which may run on @@ -297,15 +308,12 @@ class NativeObject; bool CurrentThreadIsIonCompiling(); bool CurrentThreadIsIonCompilingSafeForMinorGC(); - bool CurrentThreadIsGCSweeping(); - bool CurrentThreadIsGCFinalizing(); +bool CurrentThreadIsTouchingGrayThings(); bool IsMarkedBlack(JSObject* obj); -bool CurrentThreadIsTouchingGrayThings(); - #endif struct MOZ_RAII AutoTouchingGrayThings { @@ -322,15 +330,15 @@ struct InternalBarrierMethods {}; template struct InternalBarrierMethods { - static bool isMarkable(T* v) { return v != nullptr; } + static bool isMarkable(const T* v) { return v != nullptr; } - static void preBarrier(T* v) { T::writeBarrierPre(v); } + static void preBarrier(T* v) { gc::PreWriteBarrier(v); } static void postBarrier(T** vp, T* prev, T* next) { - T::writeBarrierPost(vp, prev, next); + gc::PostWriteBarrier(vp, prev, next); } - static void readBarrier(T* v) { T::readBarrier(v); } + static void readBarrier(T* v) { gc::ReadBarrier(v); } #ifdef DEBUG static void assertThingIsNotGray(T* v) { return T::assertThingIsNotGray(v); } @@ -341,7 +349,11 @@ template <> struct InternalBarrierMethods { static bool isMarkable(const Value& v) { return v.isGCThing(); } - static void preBarrier(const Value& v); + static void preBarrier(const Value& v) { + if (v.isGCThing()) { + gc::ValuePreWriteBarrier(v); + } + } static MOZ_ALWAYS_INLINE void postBarrier(Value* vp, const Value& prev, const Value& next) { @@ -370,7 +382,11 @@ struct InternalBarrierMethods { } } - static void readBarrier(const Value& v); + static void readBarrier(const Value& v) { + if (v.isGCThing()) { + gc::ValueReadBarrier(v); + } + } #ifdef DEBUG static void assertThingIsNotGray(const Value& v) { @@ -382,7 +398,11 @@ struct InternalBarrierMethods { template <> struct InternalBarrierMethods { static bool isMarkable(jsid id) { return id.isGCThing(); } - static void preBarrier(jsid id); + static void preBarrier(jsid id) { + if (id.isGCThing()) { + gc::IdPreWriteBarrier(id); + } + } static void postBarrier(jsid* idp, jsid prev, jsid next) {} #ifdef DEBUG static void assertThingIsNotGray(jsid id) { JS::AssertIdIsNotGray(id); } @@ -424,7 +444,7 @@ class MOZ_NON_MEMMOVABLE BarrieredBase { // instantiation. Friending to the generic template leads to a number of // unintended consequences, including template resolution ambiguity and a // circular dependency with Tracing.h. - T* unsafeUnbarrieredForTracing() const { return const_cast(&value); } + T* unbarrieredAddress() const { return const_cast(&value); } }; // Base class for barriered pointer types that intercept only writes. @@ -445,10 +465,10 @@ class WriteBarriered : public BarrieredBase, // Use this if you want to change the value without invoking barriers. // Obviously this is dangerous unless you know the barrier is not needed. - void unsafeSet(const T& v) { this->value = v; } + void unbarrieredSet(const T& v) { this->value = v; } // For users who need to manually barrier the raw types. - static void writeBarrierPre(const T& v) { + static void preWriteBarrier(const T& v) { InternalBarrierMethods::preBarrier(v); } @@ -796,14 +816,16 @@ class WeakHeapPtr : public ReadBarriered, const T& operator->() const { return get(); } - T* unsafeGet() { return &this->value; } - T const* unsafeGet() const { return &this->value; } - void set(const T& v) { AssertTargetIsNotGray(v); setUnchecked(v); } + void unbarrieredSet(const T& v) { + AssertTargetIsNotGray(v); + this->value = v; + } + private: void setUnchecked(const T& v) { T tmp = this->value; @@ -858,7 +880,7 @@ class HeapSlot : public WriteBarriered { #ifdef DEBUG bool preconditionForSet(NativeObject* owner, Kind kind, uint32_t slot) const; - void assertPreconditionForWriteBarrierPost(NativeObject* obj, Kind kind, + void assertPreconditionForPostWriteBarrier(NativeObject* obj, Kind kind, uint32_t slot, const Value& target) const; #endif @@ -875,7 +897,7 @@ class HeapSlot : public WriteBarriered { void post(NativeObject* owner, Kind kind, uint32_t slot, const Value& target) { #ifdef DEBUG - assertPreconditionForWriteBarrierPost(owner, kind, slot, target); + assertPreconditionForPostWriteBarrier(owner, kind, slot, target); #endif if (this->value.isObject() || this->value.isString() || this->value.isBigInt()) { @@ -923,15 +945,17 @@ class HeapSlotArray { { } + HeapSlot* begin() const { + MOZ_ASSERT(allowWrite()); + return array; + } + operator const Value*() const { static_assert(sizeof(GCPtr) == sizeof(Value)); static_assert(sizeof(HeapSlot) == sizeof(Value)); return reinterpret_cast(array); } - operator HeapSlot*() const { - MOZ_ASSERT(allowWrite()); - return array; - } + operator HeapSlot*() const { return begin(); } HeapSlotArray operator+(int offset) const { return HeapSlotArray(array + offset, allowWrite()); @@ -959,7 +983,7 @@ static inline void BarrieredSetPair(Zone* zone, HeapPtr& v1, T1* val1, HeapPtr& v2, T2* val2) { AssertTargetIsNotGray(val1); AssertTargetIsNotGray(val2); - if (T1::needWriteBarrierPre(zone)) { + if (T1::needPreWriteBarrier(zone)) { v1.pre(); v2.pre(); } @@ -1026,7 +1050,6 @@ struct MovableCellHasher> { static bool match(const Key& k, const Lookup& l) { return MovableCellHasher::match(k, l); } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } }; template @@ -1046,7 +1069,6 @@ struct MovableCellHasher> { static bool match(const Key& k, const Lookup& l) { return MovableCellHasher::match(k, l); } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } }; template @@ -1066,7 +1088,6 @@ struct MovableCellHasher> { static bool match(const Key& k, const Lookup& l) { return MovableCellHasher::match(k.unbarrieredGet(), l); } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } }; /* Useful for hashtables with a HeapPtr as key. */ @@ -1077,7 +1098,7 @@ struct HeapPtrHasher { static HashNumber hash(Lookup obj) { return DefaultHasher::hash(obj); } static bool match(const Key& k, Lookup l) { return k.get() == l; } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } + static void rekey(Key& k, const Key& newKey) { k.unbarrieredSet(newKey); } }; template @@ -1087,7 +1108,7 @@ struct PreBarrieredHasher { static HashNumber hash(Lookup obj) { return DefaultHasher::hash(obj); } static bool match(const Key& k, Lookup l) { return k.get() == l; } - static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); } + static void rekey(Key& k, const Key& newKey) { k.unbarrieredSet(newKey); } }; /* Useful for hashtables with a WeakHeapPtr as key. */ diff --git a/js/src/gc/Cell.h b/js/src/gc/Cell.h index 601457d45c..6b78509ce4 100644 --- a/js/src/gc/Cell.h +++ b/js/src/gc/Cell.h @@ -5,20 +5,18 @@ #ifndef gc_Cell_h #define gc_Cell_h +#include "mozilla/Atomics.h" + #include #include "gc/GCEnum.h" #include "gc/Heap.h" #include "js/GCAnnotations.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone #include "js/TraceKind.h" #include "js/TypeDecls.h" namespace JS { - -namespace shadow { -struct Zone; -} /* namespace shadow */ - enum class TraceKind; } /* namespace JS */ @@ -47,11 +45,12 @@ namespace gc { class Arena; enum class AllocKind : uint8_t; -class CellHeaderWithLengthAndFlags; struct Chunk; class StoreBuffer; class TenuredCell; +extern void UnmarkGrayGCThingRecursively(TenuredCell* cell); + // Like gc::MarkColor but allows the possibility of the cell being unmarked. // // This class mimics an enum class, but supports operator overloading. @@ -100,49 +99,47 @@ class CellColor { Color color; }; -// The cell header contains flags used by the GC. All GC cells must start with a -// CellHeader, or one of its derived classes that allows use of spare bits to -// store data. -class CellHeader { +// [SMDOC] GC Cell +// +// A GC cell is the ultimate base class for all GC things. All types allocated +// on the GC heap extend either gc::Cell or gc::TenuredCell. If a type is always +// tenured, prefer the TenuredCell class as base. +// +// The first word of Cell is a uintptr_t that reserves the low three bits for GC +// purposes. The remaining bits are available to sub-classes and can be used +// store a pointer to another gc::Cell. It can also be used for temporary +// storage (see setTemporaryGCUnsafeData). To make use of the remaining space, +// sub-classes derive from a helper class such as TenuredCellWithNonGCPointer. +// +// During moving GC operation a Cell may be marked as forwarded. This indicates +// that a gc::RelocationOverlay is currently stored in the Cell's memory and +// should be used to find the new location of the Cell. +struct Cell { + protected: + // Cell header word. Stores GC flags and derived class data. + // + // This is atomic since it can be read from and written to by different + // threads during compacting GC, in a limited way. Specifically, writes that + // update the derived class data can race with reads that check the forwarded + // flag. The writes do not change the forwarded flag (which is always false in + // this situation). + mozilla::Atomic header_; + public: static_assert(gc::CellFlagBitsReservedForGC >= 3, "Not enough flag bits reserved for GC"); - static constexpr uintptr_t RESERVED_MASK = BitMask(gc::CellFlagBitsReservedForGC); - // Indicates if the cell has been forwarded (moved) by generational or + // Indicates whether the cell has been forwarded (moved) by generational or // compacting GC and is now a RelocationOverlay. static constexpr uintptr_t FORWARD_BIT = Bit(0); // Bits 1 and 2 are currently unused. bool isForwarded() const { return header_ & FORWARD_BIT; } - uintptr_t flags() const { return header_ & RESERVED_MASK; } - protected: - // NOTE: This word can also be used for temporary storage, see - // setTemporaryGCUnsafeData. - uintptr_t header_; - friend class CellHeaderWithLengthAndFlags; -}; - -// [SMDOC] GC Cell -// -// A GC cell is the base class for all GC things. All types allocated on the GC -// heap extend either gc::Cell or gc::TenuredCell. If a type is always tenured, -// prefer the TenuredCell class as base. -// -// The first word (a pointer or uintptr_t) of each Cell must reserve the low -// three bits for GC purposes. The remaining bits are available to sub-classes -// and typically store a pointer to another gc::Cell. -// -// During moving GC operation a Cell may be marked as forwarded. This indicates -// that a gc::RelocationOverlay is currently stored in the Cell's memory and -// should be used to find the new location of the Cell. -struct alignas(gc::CellAlignBytes) Cell { - public: MOZ_ALWAYS_INLINE bool isTenured() const { return !IsInsideNursery(this); } MOZ_ALWAYS_INLINE const TenuredCell& asTenured() const; MOZ_ALWAYS_INLINE TenuredCell& asTenured(); @@ -174,11 +171,7 @@ struct alignas(gc::CellAlignBytes) Cell { inline JS::TraceKind getTraceKind() const; - static MOZ_ALWAYS_INLINE bool needWriteBarrierPre(JS::Zone* zone); - - inline bool isForwarded() const { - return reinterpret_cast(this)->isForwarded(); - } + static MOZ_ALWAYS_INLINE bool needPreWriteBarrier(JS::Zone* zone); template >> inline bool is() const { @@ -208,6 +201,10 @@ struct alignas(gc::CellAlignBytes) Cell { inline JS::Zone* nurseryZone() const; inline JS::Zone* nurseryZoneFromAnyThread() const; + // Default implementation for kinds that cannot be permanent. This may be + // overriden by derived classes. + MOZ_ALWAYS_INLINE bool isPermanentAndMayBeShared() const { return false; } + #ifdef DEBUG static inline void assertThingIsNotGray(Cell* cell); inline bool isAligned() const; @@ -288,12 +285,6 @@ class TenuredCell : public Cell { return static_cast(this); } - static MOZ_ALWAYS_INLINE void readBarrier(TenuredCell* thing); - static MOZ_ALWAYS_INLINE void writeBarrierPre(TenuredCell* thing); - - static void MOZ_ALWAYS_INLINE writeBarrierPost(void* cellp, - TenuredCell* prior, - TenuredCell* next); // Default implementation for kinds that don't require fixup. void fixupAfterMovingGC() {} @@ -401,7 +392,7 @@ inline JS::TraceKind Cell::getTraceKind() const { return NurseryCellHeader::from(this)->traceKind(); } -/* static */ MOZ_ALWAYS_INLINE bool Cell::needWriteBarrierPre(JS::Zone* zone) { +/* static */ MOZ_ALWAYS_INLINE bool Cell::needPreWriteBarrier(JS::Zone* zone) { return JS::shadow::Zone::from(zone)->needsIncrementalBarrier(); } @@ -459,41 +450,60 @@ bool TenuredCell::isInsideZone(JS::Zone* zone) const { return zone == arena()->zone; } -/* static */ MOZ_ALWAYS_INLINE void TenuredCell::readBarrier( - TenuredCell* thing) { +// Read barrier and pre-write barrier implementation for GC cells. + +template +MOZ_ALWAYS_INLINE void ReadBarrier(T* thing) { + static_assert(std::is_base_of_v); + static_assert(!std::is_same_v && !std::is_same_v); + + if (thing && !thing->isPermanentAndMayBeShared()) { + ReadBarrierImpl(thing); + } +} + +MOZ_ALWAYS_INLINE void ReadBarrierImpl(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); + MOZ_ASSERT(!CurrentThreadIsGCMarking()); MOZ_ASSERT(thing); MOZ_ASSERT(CurrentThreadCanAccessZone(thing->zoneFromAnyThread())); + // Barriers should not be triggered on main thread while collecting. - MOZ_ASSERT_IF(CurrentThreadCanAccessRuntime(thing->runtimeFromAnyThread()), + mozilla::DebugOnly runtime = thing->runtimeFromAnyThread(); + MOZ_ASSERT_IF(CurrentThreadCanAccessRuntime(runtime), !JS::RuntimeHeapIsCollecting()); JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread(); if (shadowZone->needsIncrementalBarrier()) { - // Barriers are only enabled on the main thread and are disabled while - // collecting. - MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone)); + // We should only observe barriers being enabled on the main thread. + MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime)); Cell* tmp = thing; TraceManuallyBarrieredGenericPointerEdge(shadowZone->barrierTracer(), &tmp, "read barrier"); MOZ_ASSERT(tmp == thing); + return; } if (thing->isMarkedGray()) { // There shouldn't be anything marked gray unless we're on the main thread. - MOZ_ASSERT(CurrentThreadCanAccessRuntime(thing->runtimeFromAnyThread())); - if (!JS::RuntimeHeapIsCollecting()) { - JS::UnmarkGrayGCThingRecursively( - JS::GCCellPtr(thing, thing->getTraceKind())); - } + MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime)); + UnmarkGrayGCThingRecursively(thing); + } +} + +MOZ_ALWAYS_INLINE void ReadBarrierImpl(Cell* thing) { + MOZ_ASSERT(!CurrentThreadIsGCMarking()); + if (thing->isTenured()) { + ReadBarrierImpl(&thing->asTenured()); } } -void AssertSafeToSkipBarrier(TenuredCell* thing); +void AssertSafeToSkipPreWriteBarrier(TenuredCell* thing); -/* static */ MOZ_ALWAYS_INLINE void TenuredCell::writeBarrierPre( - TenuredCell* thing) { +MOZ_ALWAYS_INLINE void PreWriteBarrierImpl(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); + MOZ_ASSERT(!CurrentThreadIsGCMarking()); + if (!thing) { return; } @@ -509,11 +519,14 @@ void AssertSafeToSkipBarrier(TenuredCell* thing); // any off thread barriers that reach us and assert that they would normally // not be possible. if (!CurrentThreadCanAccessRuntime(thing->runtimeFromAnyThread())) { - AssertSafeToSkipBarrier(thing); + AssertSafeToSkipPreWriteBarrier(thing); return; } #endif + // Barriers can be triggered on the main thread while collecting, but are + // disabled. For example, this happens when destroying HeapPtr wrappers. + JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread(); if (shadowZone->needsIncrementalBarrier()) { MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone)); @@ -524,17 +537,21 @@ void AssertSafeToSkipBarrier(TenuredCell* thing); } } -static MOZ_ALWAYS_INLINE void AssertValidToSkipBarrier(TenuredCell* thing) { - MOZ_ASSERT(!IsInsideNursery(thing)); - MOZ_ASSERT_IF( - thing, - MapAllocToTraceKind(thing->getAllocKind()) != JS::TraceKind::Object && - MapAllocToTraceKind(thing->getAllocKind()) != JS::TraceKind::String); +MOZ_ALWAYS_INLINE void PreWriteBarrierImpl(Cell* thing) { + MOZ_ASSERT(!CurrentThreadIsGCMarking()); + if (thing && thing->isTenured()) { + PreWriteBarrierImpl(&thing->asTenured()); + } } -/* static */ MOZ_ALWAYS_INLINE void TenuredCell::writeBarrierPost( - void* cellp, TenuredCell* prior, TenuredCell* next) { - AssertValidToSkipBarrier(next); +template +MOZ_ALWAYS_INLINE void PreWriteBarrier(T* thing) { + static_assert(std::is_base_of_v); + static_assert(!std::is_same_v && !std::is_same_v); + + if (thing && !thing->isPermanentAndMayBeShared()) { + PreWriteBarrierImpl(thing); + } } #ifdef DEBUG @@ -556,11 +573,11 @@ bool TenuredCell::isAligned() const { #endif -// Cell header for GC things that have 32-bit length and 32-bit flags (currently -// JSString and BigInt). +// Base class for nusery-allocatable GC things that have 32-bit length and +// 32-bit flags (currently JSString and BigInt). // -// This tries to store both in CellHeader::header_, but if that isn't large -// enough the length is stored separately. +// This tries to store both in Cell::header_, but if that isn't large enough the +// length is stored separately. // // 32 0 // ------------------ @@ -570,121 +587,114 @@ bool TenuredCell::isAligned() const { // The low bits of the flags word (see CellFlagBitsReservedForGC) are reserved // for GC. Derived classes must ensure they don't use these flags for non-GC // purposes. -class CellHeaderWithLengthAndFlags { - // Use composition rather than inheritance so this ends up a standard layout - // type. - CellHeader header_; - +class alignas(gc::CellAlignBytes) CellWithLengthAndFlags : public Cell { #if JS_BITS_PER_WORD == 32 // Additional storage for length if |header_| is too small to fit both. uint32_t length_; #endif - uintptr_t& header() { return header_.header_; } - const uintptr_t& header() const { return header_.header_; } - - public: - uint32_t lengthField() const { + protected: + uint32_t headerLengthField() const { #if JS_BITS_PER_WORD == 32 return length_; #else - return uint32_t(header() >> 32); + return uint32_t(header_ >> 32); #endif } - uint32_t flagsField() const { return uint32_t(header()); } + uint32_t headerFlagsField() const { return uint32_t(header_); } - void setFlagBit(uint32_t flag) { header() |= uintptr_t(flag); } - void clearFlagBit(uint32_t flag) { header() &= ~uintptr_t(flag); } - void toggleFlagBit(uint32_t flag) { header() ^= uintptr_t(flag); } + void setHeaderFlagBit(uint32_t flag) { header_ |= uintptr_t(flag); } + void clearHeaderFlagBit(uint32_t flag) { header_ &= ~uintptr_t(flag); } + void toggleHeaderFlagBit(uint32_t flag) { header_ ^= uintptr_t(flag); } - void setLengthAndFlags(uint32_t len, uint32_t flags) { + void setHeaderLengthAndFlags(uint32_t len, uint32_t flags) { #if JS_BITS_PER_WORD == 32 - header() = flags; + header_ = flags; length_ = len; #else - header() = (uint64_t(len) << 32) | uint64_t(flags); + header_ = (uint64_t(len) << 32) | uint64_t(flags); #endif } // Sub classes can store temporary data in the flags word. This is not GC safe // and users must ensure flags/length are never checked (including by asserts) // while this data is stored. Use of this method is strongly discouraged! - void setTemporaryGCUnsafeData(uintptr_t data) { header() = data; } + void setTemporaryGCUnsafeData(uintptr_t data) { header_ = data; } // To get back the data, values to safely re-initialize clobbered flags // must be provided. uintptr_t unsetTemporaryGCUnsafeData(uint32_t len, uint32_t flags) { - uintptr_t data = header(); - setLengthAndFlags(len, flags); + uintptr_t data = header_; + setHeaderLengthAndFlags(len, flags); return data; } - const js::gc::CellHeader& cellHeader() const { return header_; } - + public: // Returns the offset of header_. JIT code should use offsetOfFlags // below. - static constexpr size_t offsetOfRawFlagsField() { - return offsetof(CellHeaderWithLengthAndFlags, header_); + static constexpr size_t offsetOfRawHeaderFlagsField() { + return offsetof(CellWithLengthAndFlags, header_); } // Offsets for direct field from jit code. A number of places directly // access 32-bit length and flags fields so do endian trickery here. #if JS_BITS_PER_WORD == 32 - static constexpr size_t offsetOfFlags() { - return offsetof(CellHeaderWithLengthAndFlags, header_); + static constexpr size_t offsetOfHeaderFlags() { + return offsetof(CellWithLengthAndFlags, header_); } - static constexpr size_t offsetOfLength() { - return offsetof(CellHeaderWithLengthAndFlags, length_); + static constexpr size_t offsetOfHeaderLength() { + return offsetof(CellWithLengthAndFlags, length_); } #elif MOZ_LITTLE_ENDIAN() - static constexpr size_t offsetOfFlags() { - return offsetof(CellHeaderWithLengthAndFlags, header_); + static constexpr size_t offsetOfHeaderFlags() { + return offsetof(CellWithLengthAndFlags, header_); } - static constexpr size_t offsetOfLength() { - return offsetof(CellHeaderWithLengthAndFlags, header_) + sizeof(uint32_t); + static constexpr size_t offsetOfHeaderLength() { + return offsetof(CellWithLengthAndFlags, header_) + sizeof(uint32_t); } #else - static constexpr size_t offsetOfFlags() { - return offsetof(CellHeaderWithLengthAndFlags, header_) + sizeof(uint32_t); + static constexpr size_t offsetOfHeaderFlags() { + return offsetof(CellWithLengthAndFlags, header_) + sizeof(uint32_t); } - static constexpr size_t offsetOfLength() { - return offsetof(CellHeaderWithLengthAndFlags, header_); + static constexpr size_t offsetOfHeaderLength() { + return offsetof(CellWithLengthAndFlags, header_); } #endif }; -// Cell header for GC things that allows storing a non-GC thing pointer in the -// first word. +// Base class for non-nursery-allocatable GC things that allows storing a non-GC +// thing pointer in the first word. // // The low bits of the word (see CellFlagBitsReservedForGC) are reserved for GC. template -class CellHeaderWithNonGCPointer : public CellHeader { +class alignas(gc::CellAlignBytes) TenuredCellWithNonGCPointer + : public TenuredCell { static_assert(!std::is_pointer_v, "PtrT should be the type of the referent, not of the pointer"); static_assert( !std::is_base_of_v, - "Don't use CellHeaderWithNonGCPointer for pointers to GC things"); + "Don't use TenuredCellWithNonGCPointer for pointers to GC things"); - public: - CellHeaderWithNonGCPointer() = default; - explicit CellHeaderWithNonGCPointer(PtrT* initial) : CellHeader() { + protected: + TenuredCellWithNonGCPointer() = default; + explicit TenuredCellWithNonGCPointer(PtrT* initial) { uintptr_t data = uintptr_t(initial); MOZ_ASSERT((data & RESERVED_MASK) == 0); header_ = data; } - PtrT* ptr() const { + PtrT* headerPtr() const { // Currently we never observe any flags set here because this base class is // only used for JSObject (for which the nursery kind flags are always // clear) or GC things that are always tenured (for which the nursery kind // flags are also always clear). This means we don't need to use masking to // get and set the pointer. MOZ_ASSERT(flags() == 0); - return reinterpret_cast(header_); + return reinterpret_cast(uintptr_t(header_)); } - void setPtr(PtrT* newValue) { + void setHeaderPtr(PtrT* newValue) { // As above, no flags are expected to be set here. uintptr_t data = uintptr_t(newValue); MOZ_ASSERT(flags() == 0); @@ -692,8 +702,9 @@ class CellHeaderWithNonGCPointer : public CellHeader { header_ = data; } - static constexpr size_t offsetOfPtr() { - return offsetof(CellHeaderWithNonGCPointer, header_); + public: + static constexpr size_t offsetOfHeaderPtr() { + return offsetof(TenuredCellWithNonGCPointer, header_); } }; @@ -704,58 +715,60 @@ class CellHeaderWithNonGCPointer : public CellHeader { // // This includes a pre write barrier when the pointer is update. No post barrier // is necessary as the pointer is always tenured. -template -class CellHeaderWithTenuredGCPointer : public CellHeader { +template +class alignas(gc::CellAlignBytes) CellWithTenuredGCPointer : public BaseCell { static void staticAsserts() { // These static asserts are not in class scope because the PtrT may not be // defined when this class template is instantiated. + static_assert( + std::is_same_v || std::is_same_v, + "BaseCell must be either Cell or TenuredCell"); static_assert( !std::is_pointer_v, "PtrT should be the type of the referent, not of the pointer"); static_assert( std::is_base_of_v, - "Only use CellHeaderWithTenuredGCPointer for pointers to GC things"); + "Only use CellWithTenuredGCPointer for pointers to GC things"); } - public: - CellHeaderWithTenuredGCPointer() = default; - explicit CellHeaderWithTenuredGCPointer(PtrT* initial) : CellHeader() { - initPtr(initial); - } + protected: + CellWithTenuredGCPointer() = default; + explicit CellWithTenuredGCPointer(PtrT* initial) { initHeaderPtr(initial); } - void initPtr(PtrT* initial) { + void initHeaderPtr(PtrT* initial) { MOZ_ASSERT(!IsInsideNursery(initial)); uintptr_t data = uintptr_t(initial); - MOZ_ASSERT((data & RESERVED_MASK) == 0); + MOZ_ASSERT((data & Cell::RESERVED_MASK) == 0); this->header_ = data; } - PtrT* ptr() const { + void setHeaderPtr(PtrT* newValue) { + // As above, no flags are expected to be set here. + MOZ_ASSERT(!IsInsideNursery(newValue)); + PreWriteBarrier(headerPtr()); + unbarrieredSetHeaderPtr(newValue); + } + + public: + PtrT* headerPtr() const { // Currently we never observe any flags set here because this base class is // only used for GC things that are always tenured (for which the nursery // kind flags are also always clear). This means we don't need to use // masking to get and set the pointer. staticAsserts(); - MOZ_ASSERT(flags() == 0); - return reinterpret_cast(this->header_); + MOZ_ASSERT(this->flags() == 0); + return reinterpret_cast(uintptr_t(this->header_)); } - void setPtr(PtrT* newValue) { - // As above, no flags are expected to be set here. - MOZ_ASSERT(!IsInsideNursery(newValue)); - PtrT::writeBarrierPre(ptr()); - unsafeSetPtr(newValue); - } - - void unsafeSetPtr(PtrT* newValue) { + void unbarrieredSetHeaderPtr(PtrT* newValue) { uintptr_t data = uintptr_t(newValue); - MOZ_ASSERT(flags() == 0); - MOZ_ASSERT((data & RESERVED_MASK) == 0); + MOZ_ASSERT(this->flags() == 0); + MOZ_ASSERT((data & Cell::RESERVED_MASK) == 0); this->header_ = data; } - static constexpr size_t offsetOfPtr() { - return offsetof(CellHeaderWithTenuredGCPointer, header_); + static constexpr size_t offsetOfHeaderPtr() { + return offsetof(CellWithTenuredGCPointer, header_); } }; diff --git a/js/src/gc/FinalizationRegistry.cpp b/js/src/gc/FinalizationRegistry.cpp index ef79de010a..d0a5bd9df6 100644 --- a/js/src/gc/FinalizationRegistry.cpp +++ b/js/src/gc/FinalizationRegistry.cpp @@ -12,6 +12,7 @@ #include "vm/JSContext.h" #include "gc/PrivateIterators-inl.h" +#include "vm/JSObject-inl.h" using namespace js; using namespace js::gc; @@ -50,9 +51,9 @@ bool GCRuntime::registerWithFinalizationRegistry(JSContext* cx, } void GCRuntime::markFinalizationRegistryRoots(JSTracer* trc) { - // The held values for all finalization records store in zone maps are marked - // as roots. Finalization records store a finalization registry as a weak - // pointer in a private value, which does not get marked. + // All finalization records stored in the zone maps are marked as roots. + // Records can be removed from these maps during sweeping in which case they + // die in the next collection. for (GCZonesIter zone(this); !zone.done(); zone.next()) { Zone::FinalizationRecordMap& map = zone->finalizationRecordMap(); for (Zone::FinalizationRecordMap::Enum e(map); !e.empty(); e.popFront()) { @@ -77,9 +78,14 @@ void GCRuntime::sweepFinalizationRegistries(Zone* zone) { // for any entries whose target is dying and remove them from the map. Zone::FinalizationRegistrySet& set = zone->finalizationRegistries(); - set.sweep(); - for (auto r = set.all(); !r.empty(); r.popFront()) { - r.front()->as().sweep(); + for (Zone::FinalizationRegistrySet::Enum e(set); !e.empty(); e.popFront()) { + if (IsAboutToBeFinalized(&e.mutableFront())) { + e.front()->as().queue()->setHasRegistry( + false); + e.removeFront(); + } else { + e.front()->as().sweep(); + } } Zone::FinalizationRecordMap& map = zone->finalizationRecordMap(); @@ -92,20 +98,18 @@ void GCRuntime::sweepFinalizationRegistries(Zone* zone) { // Sweep finalization records and remove records for: records.eraseIf([](JSObject* obj) { FinalizationRecordObject* record = UnwrapFinalizationRecord(obj); - return !record || // Nuked CCW to record. - !record->isActive() || // Unregistered record or dead finalization - // registry in previous sweep group. - !record->sweep(); // Dead finalization registry in this sweep - // group. + return !record || // Nuked CCW to record. + !record->isActive() || // Unregistered record. + !record->queue()->hasRegistry(); // Dead finalization registry. }); // Queue finalization records for targets that are dying. if (IsAboutToBeFinalized(&e.front().mutableKey())) { for (JSObject* obj : records) { FinalizationRecordObject* record = UnwrapFinalizationRecord(obj); - FinalizationRegistryObject* registry = record->registryDuringGC(this); - registry->queueRecordToBeCleanedUp(record); - queueFinalizationRegistryForCleanup(registry); + FinalizationQueueObject* queue = record->queue(); + queue->queueRecordToBeCleanedUp(record); + queueFinalizationRegistryForCleanup(queue); } e.removeFront(); } @@ -113,17 +117,22 @@ void GCRuntime::sweepFinalizationRegistries(Zone* zone) { } void GCRuntime::queueFinalizationRegistryForCleanup( - FinalizationRegistryObject* registry) { - // Prod the embedding to call us back later to run the finalization callbacks. - if (!registry->isQueuedForCleanup()) { - callHostCleanupFinalizationRegistryCallback(registry); - registry->setQueuedForCleanup(true); + FinalizationQueueObject* queue) { + // Prod the embedding to call us back later to run the finalization callbacks, + // if necessary. + + if (queue->isQueuedForCleanup()) { + return; } -} -bool GCRuntime::cleanupQueuedFinalizationRegistry( - JSContext* cx, HandleFinalizationRegistryObject registry) { - registry->setQueuedForCleanup(false); - bool ok = FinalizationRegistryObject::cleanupQueuedRecords(cx, registry); - return ok; + // Derive the incumbent global by unwrapping the incumbent global object and + // then getting its global. + JSObject* object = UncheckedUnwrapWithoutExpose(queue->incumbentObject()); + MOZ_ASSERT(object); + GlobalObject* incumbentGlobal = &object->nonCCWGlobal(); + + callHostCleanupFinalizationRegistryCallback(queue->doCleanupFunction(), + incumbentGlobal); + + queue->setQueuedForCleanup(true); } diff --git a/js/src/gc/FindSCCs.h b/js/src/gc/FindSCCs.h index d1c6e36794..c15139b55a 100644 --- a/js/src/gc/FindSCCs.h +++ b/js/src/gc/FindSCCs.h @@ -5,13 +5,14 @@ #ifndef gc_FindSCCs_h #define gc_FindSCCs_h -#include "mozilla/Move.h" +#include "mozilla/Assertions.h" // MOZ_ASSERT -#include +#include // std::min +#include // uintptr_t -#include "jsfriendapi.h" - -#include "js/HashTable.h" +#include "js/AllocPolicy.h" // js::SystemAllocPolicy +#include "js/friend/StackLimits.h" // JS_CHECK_STACK_SIZE +#include "js/HashTable.h" // js::HashSet, js::DefaultHasher namespace js { namespace gc { diff --git a/js/src/gc/GC-inl.h b/js/src/gc/GC-inl.h index 888fa7aa32..cc9ab898d2 100644 --- a/js/src/gc/GC-inl.h +++ b/js/src/gc/GC-inl.h @@ -21,43 +21,32 @@ namespace gc { class AutoAssertEmptyNursery; class ArenaIter { - Arena* arena; - Arena* unsweptArena; - Arena* sweptArena; - mozilla::DebugOnly initialized; + static constexpr size_t SourceCount = 4; + + Arena* arena = nullptr; + Arena* sources[SourceCount] = {nullptr}; + size_t index = 0; + mozilla::DebugOnly initialized = false; public: - ArenaIter() - : arena(nullptr), - unsweptArena(nullptr), - sweptArena(nullptr), - initialized(false) {} + ArenaIter() = default; - ArenaIter(JS::Zone* zone, AllocKind kind) : initialized(false) { - init(zone, kind); - } + ArenaIter(JS::Zone* zone, AllocKind kind) { init(zone, kind); } void init(JS::Zone* zone, AllocKind kind) { MOZ_ASSERT(!initialized); MOZ_ASSERT(zone); + sources[0] = zone->arenas.getFirstArena(kind); + sources[1] = zone->arenas.getFirstArenaToSweep(kind); + sources[2] = zone->arenas.getFirstSweptArena(kind); + sources[3] = zone->arenas.getFirstNewArenaInMarkPhase(kind); initialized = true; - arena = zone->arenas.getFirstArena(kind); - unsweptArena = zone->arenas.getFirstArenaToSweep(kind); - sweptArena = zone->arenas.getFirstSweptArena(kind); - if (!unsweptArena) { - unsweptArena = sweptArena; - sweptArena = nullptr; - } - if (!arena) { - arena = unsweptArena; - unsweptArena = sweptArena; - sweptArena = nullptr; - } + settle(); } bool done() const { MOZ_ASSERT(initialized); - return !arena; + return index == SourceCount; } Arena* get() const { @@ -69,9 +58,19 @@ class ArenaIter { MOZ_ASSERT(!done()); arena = arena->next; if (!arena) { - arena = unsweptArena; - unsweptArena = sweptArena; - sweptArena = nullptr; + index++; + settle(); + } + } + + private: + void settle() { + while (index < SourceCount) { + arena = sources[index]; + if (arena) { + break; + } + index++; } } }; diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index 0f9b05e9b5..404542b6e4 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -26,7 +26,6 @@ * - the collection must be run by calling js::GCSlice() rather than js::GC() * - the GC mode must have been set to JSGC_MODE_INCREMENTAL or * JSGC_MODE_ZONE_INCREMENTAL with JS_SetGCParameter() - * - no thread may have an AutoKeepAtoms instance on the stack * * The last condition is an engine-internal mechanism to ensure that incremental * collection is not carried out without the correct barriers being implemented. @@ -191,7 +190,6 @@ #include "mozilla/DebugOnly.h" #include "mozilla/MacroForEach.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/Move.h" #include "mozilla/Range.h" #include "mozilla/ScopeExit.h" #include "mozilla/TextUtils.h" @@ -201,6 +199,7 @@ #include #include #include +#include #ifndef XP_WIN # include # include @@ -211,6 +210,7 @@ #include "jstypes.h" #include "builtin/FinalizationRegistryObject.h" +#include "builtin/WeakRefObject.h" #include "debugger/DebugAPI.h" #include "gc/FindSCCs.h" #include "gc/FreeOp.h" @@ -225,13 +225,14 @@ #include "jit/JitCode.h" #include "jit/JitcodeMap.h" #include "jit/JitRealm.h" -#include "jit/MacroAssembler.h" +#include "js/Object.h" // JS::GetClass #include "js/SliceBudget.h" #include "proxy/DeadObjectProxy.h" #include "util/Poison.h" #include "util/Windows.h" #include "vm/BigIntType.h" #include "vm/GeckoProfiler.h" +#include "vm/HelperThreadState.h" #include "vm/JSAtom.h" #include "vm/JSContext.h" #include "vm/JSObject.h" @@ -264,7 +265,6 @@ using mozilla::ArrayLength; using mozilla::Maybe; using mozilla::Nothing; using mozilla::Some; -using mozilla::Swap; using mozilla::TimeDuration; using mozilla::TimeStamp; @@ -294,6 +294,8 @@ static_assert(js::jit::CodeAlignment >= MinFirstWordAlignment, "CellFlagBitsReservedForGC should support JIT code"); static_assert(js::gc::JSClassAlignBytes >= MinFirstWordAlignment, "CellFlagBitsReservedForGC should support JSClass pointers"); +static_assert(js::ScopeDataAlignBytes >= MinFirstWordAlignment, + "CellFlagBitsReservedForGC should support scope data pointers"); static_assert(mozilla::ArrayLength(slotsToThingKind) == SLOTS_TO_THING_KIND_LIMIT, @@ -312,17 +314,6 @@ static_assert(mozilla::ArrayLength(slotsToThingKind) == FOR_EACH_ALLOCKIND(CHECK_THING_SIZE); #undef CHECK_THING_SIZE -// GC things must be standard-layout classes so we can access the cell header by -// casting the thing pointer to a CellHeader*. This checks the property for the -// least derived thing type. -#define CHECK_THING_LAYOUT(_1, traceKind, _2, _3, _4, _5, _6) \ - static_assert( \ - std::is_standard_layout< \ - MapTraceKindToType::Type>::value, \ - "The class for " #traceKind " must by a standard layout type."); -FOR_EACH_ALLOCKIND(CHECK_THING_LAYOUT) -#undef CHECK_THING_LAYOUT - template struct ArenaLayout { static constexpr size_t thingSize() { return sizeof(T); } @@ -404,8 +395,10 @@ static constexpr FinalizePhase BackgroundFinalizePhases[] = { AllocKind::OBJECT_GROUP}}}; void Arena::unmarkAll() { - uintptr_t* word = chunk()->bitmap.arenaBits(this); - memset(word, 0, ArenaBitmapWords * sizeof(uintptr_t)); + MarkBitmapWord* arenaBits = chunk()->bitmap.arenaBits(this); + for (size_t i = 0; i < ArenaBitmapWords; i++) { + arenaBits[i] = 0; + } } void Arena::unmarkPreMarkedFreeCells() { @@ -876,6 +869,9 @@ GCRuntime::GCRuntime(JSRuntime* rt) stats_(this), marker(rt), heapSize(nullptr), + helperThreadRatio(TuningDefaults::HelperThreadRatio), + maxHelperThreads(TuningDefaults::MaxHelperThreads), + helperThreadCount(1), rootsHash(256), nextCellUniqueId_(LargestTaggedNullCellPointer + 1), // Ensure disjoint from null tagged pointers. @@ -914,7 +910,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) sweepZone(nullptr), hasMarkedGrayRoots(false), abortSweepAfterCurrentGroup(false), - sweepMarkTaskStarted(false), sweepMarkResult(IncrementalProgress::NotFinished), startedCompacting(false), relocatedArenasToRelease(nullptr), @@ -1275,6 +1270,8 @@ bool GCRuntime::init(uint32_t maxbytes) { gcprobes::Init(this); + updateHelperThreadCount(); + return true; } @@ -1374,6 +1371,28 @@ bool GCRuntime::setParameter(JSGCParamKey key, uint32_t value, case JSGC_INCREMENTAL_WEAKMAP_ENABLED: marker.incrementalWeakMapMarkingEnabled = value != 0; break; + case JSGC_HELPER_THREAD_RATIO: + if (rt->parentRuntime) { + // Don't allow this to be set for worker runtimes. + return false; + } + if (value == 0) { + return false; + } + helperThreadRatio = double(value) / 100.0; + updateHelperThreadCount(); + break; + case JSGC_MAX_HELPER_THREADS: + if (rt->parentRuntime) { + // Don't allow this to be set for worker runtimes. + return false; + } + if (value == 0) { + return false; + } + maxHelperThreads = value; + updateHelperThreadCount(); + break; default: if (!tunables.setParameter(key, value, lock)) { return false; @@ -1411,6 +1430,20 @@ void GCRuntime::resetParameter(JSGCParamKey key, AutoLockGC& lock) { marker.incrementalWeakMapMarkingEnabled = TuningDefaults::IncrementalWeakMapMarkingEnabled; break; + case JSGC_HELPER_THREAD_RATIO: + if (rt->parentRuntime) { + return; + } + helperThreadRatio = TuningDefaults::HelperThreadRatio; + updateHelperThreadCount(); + break; + case JSGC_MAX_HELPER_THREADS: + if (rt->parentRuntime) { + return; + } + maxHelperThreads = TuningDefaults::MaxHelperThreads; + updateHelperThreadCount(); + break; default: tunables.resetParameter(key, lock); for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) { @@ -1501,6 +1534,16 @@ uint32_t GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock) { return tunables.mallocThresholdBase() / 1024 / 1024; case JSGC_MALLOC_GROWTH_FACTOR: return uint32_t(tunables.mallocGrowthFactor() * 100); + case JSGC_CHUNK_BYTES: + return ChunkSize; + case JSGC_HELPER_THREAD_RATIO: + MOZ_ASSERT(helperThreadRatio > 0.0); + return uint32_t(helperThreadRatio * 100.0); + case JSGC_MAX_HELPER_THREADS: + MOZ_ASSERT(maxHelperThreads <= UINT32_MAX); + return maxHelperThreads; + case JSGC_HELPER_THREAD_COUNT: + return helperThreadCount; default: MOZ_CRASH("Unknown parameter key"); } @@ -1513,6 +1556,30 @@ void GCRuntime::setMarkStackLimit(size_t limit, AutoLockGC& lock) { marker.setMaxCapacity(limit); } +void GCRuntime::updateHelperThreadCount() { + if (!CanUseExtraThreads()) { + // startTask will run the work on the main thread if the count is 1. + MOZ_ASSERT(helperThreadCount == 1); + return; + } + + // The count of helper threads used for GC tasks is process wide. Don't set it + // for worker JS runtimes. + if (rt->parentRuntime) { + helperThreadCount = rt->parentRuntime->gc.helperThreadCount; + return; + } + + double cpuCount = HelperThreadState().cpuCount; + size_t target = size_t(cpuCount * helperThreadRatio.ref()); + helperThreadCount = mozilla::Clamp(target, size_t(1), maxHelperThreads.ref()); + + HelperThreadState().ensureThreadCount(helperThreadCount); + + AutoLockHelperThreadState lock; + HelperThreadState().setGCParallelThreadCount(helperThreadCount, lock); +} + bool GCRuntime::addBlackRootsTracer(JSTraceDataOp traceOp, void* data) { AssertHeapIsIdle(); return !!blackRootTracers.ref().append( @@ -1596,11 +1663,11 @@ void GCRuntime::setHostCleanupFinalizationRegistryCallback( } void GCRuntime::callHostCleanupFinalizationRegistryCallback( - FinalizationRegistryObject* registry) { + JSFunction* doCleanup, GlobalObject* incumbentGlobal) { JS::AutoSuppressGCAnalysis nogc; const auto& callback = hostCleanupFinalizationRegistryCallback.ref(); if (callback.op) { - callback.op(registry, callback.data); + callback.op(doCleanup, incumbentGlobal, callback.data); } } @@ -1672,7 +1739,7 @@ bool GCRuntime::addRoot(Value* vp, const char* name) { * cases. */ if (isIncrementalGCInProgress()) { - GCPtrValue::writeBarrierPre(*vp); + GCPtrValue::preWriteBarrier(*vp); } return rootsHash.ref().put(vp, name); @@ -1859,8 +1926,8 @@ static void RelocateCell(Zone* zone, TenuredCell* src, AllocKind thingKind, src->zone()->transferUniqueId(dst, src); if (IsObjectAllocKind(thingKind)) { - JSObject* srcObj = static_cast(static_cast(src)); - JSObject* dstObj = static_cast(static_cast(dst)); + auto* srcObj = static_cast(static_cast(src)); + auto* dstObj = static_cast(static_cast(dst)); if (srcObj->isNative()) { NativeObject* srcNative = &srcObj->as(); @@ -2129,6 +2196,9 @@ bool MovingTracer::onRegExpSharedEdge(RegExpShared** sharedp) { return updateEdge(sharedp); } bool MovingTracer::onBigIntEdge(BigInt** bip) { return updateEdge(bip); } +bool MovingTracer::onObjectGroupEdge(ObjectGroup** groupp) { + return updateEdge(groupp); +} void Zone::prepareForCompacting() { JSFreeOp* fop = runtimeFromMainThread()->defaultFreeOp(); @@ -2159,7 +2229,7 @@ void GCRuntime::sweepZoneAfterCompacting(MovingTracer* trc, Zone* zone) { MOZ_ASSERT(zone->isCollecting()); sweepTypesAfterCompacting(zone); sweepFinalizationRegistries(zone); - zone->weakRefMap().sweep(); + zone->weakRefMap().sweep(&storeBuffer()); { zone->sweepWeakMaps(); @@ -2364,9 +2434,11 @@ void GCRuntime::updateTypeDescrObjects(MovingTracer* trc, Zone* zone) { zone->typeDescrObjects().sweep(nullptr); for (auto r = zone->typeDescrObjects().all(); !r.empty(); r.popFront()) { - NativeObject* obj = &r.front()->as(); + MOZ_ASSERT(MaybeForwardedObjectClass(r.front())->isNative()); + NativeObject* obj = static_cast(r.front()); UpdateCellPointers(trc, obj); - MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(obj->getClass()) == JS_DESCR_SLOTS); + MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(MaybeForwardedObjectClass(obj)) == + JS_DESCR_SLOTS); for (size_t i = 0; i < JS_DESCR_SLOTS; i++) { Value value = obj->getSlot(i); if (value.isObject()) { @@ -2418,22 +2490,22 @@ void GCRuntime::updateCellPointers(Zone* zone, AllocKinds kinds) { // 3) all other objects // // Also, there can be data races calling IsForwarded() on the new location of a -// cell that is being updated in parallel on another thread. This can be avoided -// by updating some kinds of cells in different phases. This is done for -// BaseScripts and Scopes. +// cell whose first word is being updated in parallel on another thread. This +// easiest way to avoid this is to not store a GC pointer in the first word of a +// cell. Otherwise this can be avoided by updating different kinds of cell in +// different phases. // // Since we want to minimize the number of phases, arrange kinds into three // arbitrary phases. static constexpr AllocKinds UpdatePhaseOne{ - AllocKind::SCRIPT, AllocKind::BASE_SHAPE, AllocKind::SHAPE, - AllocKind::ACCESSOR_SHAPE, AllocKind::OBJECT_GROUP, AllocKind::STRING, - AllocKind::JITCODE, AllocKind::REGEXP_SHARED}; + AllocKind::SCRIPT, AllocKind::BASE_SHAPE, AllocKind::SHAPE, + AllocKind::ACCESSOR_SHAPE, AllocKind::OBJECT_GROUP, AllocKind::STRING, + AllocKind::JITCODE, AllocKind::REGEXP_SHARED, AllocKind::SCOPE}; // UpdatePhaseTwo is typed object descriptor objects. -static constexpr AllocKinds UpdatePhaseThree{AllocKind::SCOPE, - AllocKind::FUNCTION, +static constexpr AllocKinds UpdatePhaseThree{AllocKind::FUNCTION, AllocKind::FUNCTION_EXTENDED, AllocKind::OBJECT0, AllocKind::OBJECT0_BACKGROUND, @@ -2488,6 +2560,7 @@ void GCRuntime::updateZonePointersToRelocatedCells(Zone* zone) { zone->externalStringCache().purge(); zone->functionToStringCache().purge(); + rt->caches().stringToAtomCache.purge(); // Iterate through all cells that can contain relocatable pointers to update // them. Since updating each cell is independent we try to parallelize this @@ -2669,13 +2742,16 @@ ArenaLists::ArenaLists(Zone* zone) : zone_(zone), freeLists_(zone), arenaLists_(zone), + newArenasInMarkPhase_(zone), arenasToSweep_(), incrementalSweptArenaKind(zone, AllocKind::LIMIT), incrementalSweptArenas(zone), gcShapeArenasToUpdate(zone, nullptr), gcAccessorShapeArenasToUpdate(zone, nullptr), gcScriptArenasToUpdate(zone, nullptr), + gcNewScriptArenasToUpdate(zone, nullptr), gcObjectGroupArenasToUpdate(zone, nullptr), + gcNewObjectGroupArenasToUpdate(zone, nullptr), savedEmptyArenas(zone, nullptr) { for (auto i : AllAllocKinds()) { concurrentUse(i) = ConcurrentUse::None; @@ -2734,18 +2810,18 @@ void ArenaLists::queueForBackgroundSweep(JSFreeOp* fop, inline void ArenaLists::queueForBackgroundSweep(AllocKind thingKind) { MOZ_ASSERT(IsBackgroundFinalized(thingKind)); - - ArenaList* al = &arenaList(thingKind); - if (al->isEmpty()) { - MOZ_ASSERT(concurrentUse(thingKind) == ConcurrentUse::None); - return; - } - MOZ_ASSERT(concurrentUse(thingKind) == ConcurrentUse::None); + ArenaList* al = &arenaList(thingKind); arenasToSweep(thingKind) = al->head(); - al->clear(); - concurrentUse(thingKind) = ConcurrentUse::BackgroundFinalize; + arenaList(thingKind).clear(); + + if (arenasToSweep(thingKind)) { + concurrentUse(thingKind) = ConcurrentUse::BackgroundFinalize; + } else { + arenaList(thingKind) = newArenasInMarkPhase(thingKind); + newArenasInMarkPhase(thingKind).clear(); + } } /*static*/ @@ -2771,7 +2847,7 @@ void ArenaLists::backgroundFinalize(JSFreeOp* fop, Arena* listHead, // allocated before background finalization finishes; now that finalization is // complete, we want to merge these lists back together. ArenaLists* lists = &zone->arenas; - ArenaList* al = &lists->arenaList(thingKind); + ArenaList& al = lists->arenaList(thingKind); // Flatten |finalizedSorted| into a regular ArenaList. ArenaList finalized = finalizedSorted.toArenaList(); @@ -2787,8 +2863,12 @@ void ArenaLists::backgroundFinalize(JSFreeOp* fop, Arena* listHead, ConcurrentUse::BackgroundFinalize); // Join |al| and |finalized| into a single list. - *al = finalized.insertListWithCursorAtEnd(*al); + ArenaList allocatedDuringSweep = al; + al = finalized; + al.insertListWithCursorAtEnd(lists->newArenasInMarkPhase(thingKind)); + al.insertListWithCursorAtEnd(allocatedDuringSweep); + lists->newArenasInMarkPhase(thingKind).clear(); lists->arenasToSweep(thingKind) = nullptr; } @@ -2805,11 +2885,23 @@ void ArenaLists::queueForegroundThingsForSweep() { gcShapeArenasToUpdate = arenasToSweep(AllocKind::SHAPE); gcAccessorShapeArenasToUpdate = arenasToSweep(AllocKind::ACCESSOR_SHAPE); gcObjectGroupArenasToUpdate = arenasToSweep(AllocKind::OBJECT_GROUP); + gcNewObjectGroupArenasToUpdate = + newArenasInMarkPhase(AllocKind::OBJECT_GROUP).head(); gcScriptArenasToUpdate = arenasToSweep(AllocKind::SCRIPT); + gcNewScriptArenasToUpdate = newArenasInMarkPhase(AllocKind::SCRIPT).head(); +} + +void ArenaLists::checkGCStateNotInUse() { + // Called before and after collection to check the state is as expected. +#ifdef DEBUG + checkSweepStateNotInUse(); + for (auto i : AllAllocKinds()) { + MOZ_ASSERT(newArenasInMarkPhase(i).isEmpty()); + } +#endif } void ArenaLists::checkSweepStateNotInUse() { - // Called before and after sweeping to check the sweep state is as expected. #ifdef DEBUG checkNoArenasToUpdate(); MOZ_ASSERT(incrementalSweptArenaKind == AllocKind::LIMIT); @@ -2826,7 +2918,9 @@ void ArenaLists::checkNoArenasToUpdate() { MOZ_ASSERT(!gcShapeArenasToUpdate); MOZ_ASSERT(!gcAccessorShapeArenasToUpdate); MOZ_ASSERT(!gcScriptArenasToUpdate); + MOZ_ASSERT(!gcNewScriptArenasToUpdate); MOZ_ASSERT(!gcObjectGroupArenasToUpdate); + MOZ_ASSERT(!gcNewObjectGroupArenasToUpdate); } void ArenaLists::checkNoArenasToUpdateForKind(AllocKind kind) { @@ -2840,9 +2934,11 @@ void ArenaLists::checkNoArenasToUpdateForKind(AllocKind kind) { break; case AllocKind::SCRIPT: MOZ_ASSERT(!gcScriptArenasToUpdate); + MOZ_ASSERT(!gcNewScriptArenasToUpdate); break; case AllocKind::OBJECT_GROUP: MOZ_ASSERT(!gcObjectGroupArenasToUpdate); + MOZ_ASSERT(!gcNewObjectGroupArenasToUpdate); break; default: break; @@ -3145,22 +3241,27 @@ void GCRuntime::triggerFullGCForAtoms(JSContext* cx) { MOZ_RELEASE_ASSERT(triggerGC(JS::GCReason::DELAYED_ATOMS_GC)); } -// Do all possible decommit immediately from the current thread without -// releasing the GC lock or allocating any memory. -void GCRuntime::decommitFreeArenasWithoutUnlocking(const AutoLockGC& lock) { - MOZ_ASSERT(emptyChunks(lock).count() == 0); - for (ChunkPool::Iter chunk(availableChunks(lock)); !chunk.done(); - chunk.next()) { - chunk->decommitFreeArenasWithoutUnlocking(lock); - } - MOZ_ASSERT(availableChunks(lock).verify()); -} - void GCRuntime::startDecommit() { gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::DECOMMIT); + +#ifdef DEBUG MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); MOZ_ASSERT(decommitTask.isIdle()); + { + AutoLockGC lock(this); + MOZ_ASSERT(fullChunks(lock).verify()); + MOZ_ASSERT(availableChunks(lock).verify()); + MOZ_ASSERT(emptyChunks(lock).verify()); + + // Verify that all entries in the empty chunks pool are already decommitted. + for (ChunkPool::Iter chunk(emptyChunks(lock)); !chunk.done(); + chunk.next()) { + MOZ_ASSERT(chunk->info.numArenasFreeCommitted == 0); + } + } +#endif + // If we are allocating heavily enough to trigger "high frequency" GC, then // skip decommit so that we do not compete with the mutator. However if we're // doing a shrinking GC we always decommit to release as much memory as @@ -3169,37 +3270,13 @@ void GCRuntime::startDecommit() { return; } - BackgroundDecommitTask::ChunkVector toDecommit; { AutoLockGC lock(this); - - // Verify that all entries in the empty chunks pool are already decommitted. - for (ChunkPool::Iter chunk(emptyChunks(lock)); !chunk.done(); - chunk.next()) { - MOZ_ASSERT(!chunk->info.numArenasFreeCommitted); - } - - // Since we release the GC lock while doing the decommit syscall below, - // it is dangerous to iterate the available list directly, as the active - // thread could modify it concurrently. Instead, we build and pass an - // explicit Vector containing the Chunks we want to visit. - MOZ_ASSERT(availableChunks(lock).verify()); - availableChunks(lock).sort(); - for (ChunkPool::Iter chunk(availableChunks(lock)); !chunk.done(); - chunk.next()) { - if (chunk->info.numArenasFreeCommitted && !toDecommit.append(chunk)) { - // The OOM handler does a full, immediate decommit. - return onOutOfMallocMemory(lock); - } - } - - if (toDecommit.empty() && !tooManyEmptyChunks(lock)) { - return; + if (availableChunks(lock).empty() && !tooManyEmptyChunks(lock)) { + return; // Nothing to do. } } - decommitTask.setChunksToScan(toDecommit); - #ifdef DEBUG { AutoLockHelperThreadState lock; @@ -3215,43 +3292,70 @@ void GCRuntime::startDecommit() { decommitTask.runFromMainThread(); } -void js::gc::BackgroundDecommitTask::setChunksToScan(ChunkVector& chunks) { - MOZ_ASSERT(CurrentThreadCanAccessRuntime(gc->rt)); - MOZ_ASSERT(isIdle()); - MOZ_ASSERT(toDecommit.ref().empty()); - Swap(toDecommit.ref(), chunks); -} +void js::gc::BackgroundDecommitTask::run(AutoLockHelperThreadState& lock) { + { + AutoUnlockHelperThreadState unlock(lock); -void js::gc::BackgroundDecommitTask::run() { - ChunkPool toFree; + ChunkPool emptyChunksToFree; + { + AutoLockGC gcLock(gc); - { - AutoLockGC lock(gc); + // To help minimize the total number of chunks needed over time, sort the + // available chunks list so that we allocate into more-used chunks first. + gc->availableChunks(gcLock).sort(); - for (Chunk* chunk : toDecommit.ref()) { - // The arena list is not doubly-linked, so we have to work in the free - // list order and not in the natural order. + gc->decommitFreeArenas(cancel_, gcLock); - while (chunk->info.numArenasFreeCommitted && !cancel_) { - if (!chunk->decommitOneFreeArena(gc, lock)) { - // If we are low enough on memory that we can't update the page - // tables, break out of the loop. - break; - } - } + emptyChunksToFree = gc->expireEmptyChunkPool(gcLock); } - toDecommit.ref().clearAndFree(); - toFree = gc->expireEmptyChunkPool(lock); + FreeChunkPool(emptyChunksToFree); } - FreeChunkPool(toFree); - - AutoLockHelperThreadState lock; - setFinishing(lock); gc->maybeRequestGCAfterBackgroundTask(lock); } +// Called from a background thread to decommit free arenas. Releases the GC +// lock. +void GCRuntime::decommitFreeArenas(const bool& cancel, AutoLockGC& lock) { + // Since we release the GC lock while doing the decommit syscall below, + // it is dangerous to iterate the available list directly, as the active + // thread could modify it concurrently. Instead, we build and pass an + // explicit Vector containing the Chunks we want to visit. + Vector chunksToDecommit; + for (ChunkPool::Iter chunk(availableChunks(lock)); !chunk.done(); + chunk.next()) { + if (chunk->info.numArenasFreeCommitted != 0 && + !chunksToDecommit.append(chunk)) { + onOutOfMallocMemory(lock); + return; + } + } + + for (Chunk* chunk : chunksToDecommit) { + // The arena list is not doubly-linked, so we have to work in the free + // list order and not in the natural order. + + while (chunk->info.numArenasFreeCommitted && !cancel) { + if (!chunk->decommitOneFreeArena(this, lock)) { + // If we are low enough on memory that we can't update the page + // tables, break out of the loop. + break; + } + } + } +} + +// Do all possible decommit immediately from the current thread without +// releasing the GC lock or allocating any memory. +void GCRuntime::decommitFreeArenasWithoutUnlocking(const AutoLockGC& lock) { + for (ChunkPool::Iter chunk(availableChunks(lock)); !chunk.done(); + chunk.next()) { + chunk->decommitFreeArenasWithoutUnlocking(lock); + } + MOZ_ASSERT(availableChunks(lock).verify()); +} + void GCRuntime::maybeRequestGCAfterBackgroundTask( const AutoLockHelperThreadState& lock) { if (requestSliceAfterBackgroundTask) { @@ -3356,17 +3460,11 @@ void GCRuntime::queueZonesAndStartBackgroundSweep(ZoneList& zones) { } } -void BackgroundSweepTask::run() { +void BackgroundSweepTask::run(AutoLockHelperThreadState& lock) { AutoTraceLog logSweeping(TraceLoggerForCurrentThread(), TraceLogger_GCSweeping); - AutoLockHelperThreadState lock; - gc->sweepFromBackgroundThread(lock); - - // Signal to the main thread that we're about to finish, because we release - // the lock again before GCParallelTask's state is changed to finished. - setFinishing(lock); } void GCRuntime::sweepFromBackgroundThread(AutoLockHelperThreadState& lock) { @@ -3419,7 +3517,7 @@ void GCRuntime::queueBuffersForFreeAfterMinorGC(Nursery::BufferSet& buffers) { } MOZ_ASSERT(buffersToFreeAfterMinorGC.ref().empty()); - mozilla::Swap(buffersToFreeAfterMinorGC.ref(), buffers); + std::swap(buffersToFreeAfterMinorGC.ref(), buffers); } void GCRuntime::startBackgroundFree() { @@ -3427,16 +3525,10 @@ void GCRuntime::startBackgroundFree() { freeTask.startOrRunIfIdle(lock); } -void BackgroundFreeTask::run() { +void BackgroundFreeTask::run(AutoLockHelperThreadState& lock) { AutoTraceLog logFreeing(TraceLoggerForCurrentThread(), TraceLogger_GCFree); - AutoLockHelperThreadState lock; - gc->freeFromBackgroundThread(lock); - - // Signal to the main thread that we're about to finish, because we release - // the lock again before GCParallelTask's state is changed to finished. - setFinishing(lock); } void GCRuntime::freeFromBackgroundThread(AutoLockHelperThreadState& lock) { @@ -3445,7 +3537,7 @@ void GCRuntime::freeFromBackgroundThread(AutoLockHelperThreadState& lock) { lifoBlocks.transferFrom(&lifoBlocksToFree.ref()); Nursery::BufferSet buffers; - mozilla::Swap(buffers, buffersToFreeAfterMinorGC.ref()); + std::swap(buffers, buffersToFreeAfterMinorGC.ref()); AutoUnlockHelperThreadState unlock(lock); @@ -3649,7 +3741,9 @@ class MOZ_RAII AutoRunParallelTask : public GCParallelTask { ~AutoRunParallelTask() { gc->joinTask(*this, phase_, lock_); } - void run() override { + void run(AutoLockHelperThreadState& lock) override { + AutoUnlockHelperThreadState unlock(lock); + // The hazard analysis can't tell what the call to func_ will do but it's // not allowed to GC. JS::AutoSuppressGCAnalysis nogc; @@ -3679,7 +3773,7 @@ void GCRuntime::purgeRuntime() { } for (GCZonesIter zone(this); !zone.done(); zone.next()) { - zone->purgeAtomCacheOrDefer(); + zone->purgeAtomCache(); zone->externalStringCache().purge(); zone->functionToStringCache().purge(); } @@ -3859,10 +3953,9 @@ static bool ShouldCollectZone(Zone* zone, JS::GCReason reason) { return false; } - // If canCollectAtoms() is false then either an instance of AutoKeepAtoms is - // currently on the stack or parsing is currently happening on another - // thread. In either case we don't have information about which atoms are - // roots, so we must skip collecting atoms. + // If canCollectAtoms() is false then parsing is currently happening on + // another thread, in which case we don't have information about which atoms + // are roots, so we must skip collecting atoms. // // Note that only affects the first slice of an incremental GC since root // marking is completed before we return to the mutator. @@ -4075,12 +4168,6 @@ void GCRuntime::unmarkWeakMaps() { } } -static bool IsShutdownGC(JS::GCReason reason) { - return reason == JS::GCReason::WORKER_SHUTDOWN || - reason == JS::GCReason::SHUTDOWN_CC || - reason == JS::GCReason::DESTROY_RUNTIME; -} - bool GCRuntime::beginMarkPhase(JS::GCReason reason, AutoGCSession& session) { #ifdef DEBUG if (fullCompartmentChecks) { @@ -4104,6 +4191,7 @@ bool GCRuntime::beginMarkPhase(JS::GCReason reason, AutoGCSession& session) { */ for (GCZonesIter zone(this); !zone.done(); zone.next()) { zone->arenas.clearFreeLists(); + zone->arenas.checkGCStateNotInUse(); } marker.start(); @@ -4173,7 +4261,7 @@ bool GCRuntime::beginMarkPhase(JS::GCReason reason, AutoGCSession& session) { */ purgeRuntime(); - if (IsShutdownGC(reason)) { + if (IsShutdownReason(reason)) { /* Clear any engine roots that may hold external data live. */ for (GCZonesIter zone(this, SkipAtoms); !zone.done(); zone.next()) { zone->clearRootsForShutdownGC(); @@ -4201,10 +4289,9 @@ bool GCRuntime::beginMarkPhase(JS::GCReason reason, AutoGCSession& session) { * Process any queued source compressions during the start of a major * GC. */ - { - AutoLockHelperThreadState helperLock; - HelperThreadState().startHandlingCompressionTasks( - helperLock, GlobalHelperThreadState::ScheduleCompressionTask::GC); + if (!IsShutdownReason(reason) && reason != JS::GCReason::ROOTS_REMOVED && + reason != JS::GCReason::XPCONNECT_SHUTDOWN) { + StartHandlingCompressionsOnGC(rt); } return true; @@ -4593,6 +4680,7 @@ void GCRuntime::getNextSweepGroup() { zone->setNeedsIncrementalBarrier(false); zone->changeGCState(Zone::MarkBlackOnly, Zone::NoGC); zone->arenas.unmarkPreMarkedFreeCells(); + zone->arenas.mergeNewArenasInMarkPhase(); zone->gcGrayRoots().Clear(); zone->clearGCSliceThresholds(); } @@ -4814,12 +4902,35 @@ static bool HasIncomingCrossCompartmentPointers(JSRuntime* rt) { } #endif -void js::NotifyGCNukeWrapper(JSObject* obj) { +void js::NotifyGCNukeWrapper(JSObject* wrapper) { + MOZ_ASSERT(IsCrossCompartmentWrapper(wrapper)); + /* * References to target of wrapper are being removed, we no longer have to * remember to mark it. */ - RemoveFromGrayList(obj); + RemoveFromGrayList(wrapper); + + /* + * Clean up WeakRef maps which might include this wrapper. + */ + JSObject* target = UncheckedUnwrapWithoutExpose(wrapper); + if (target->is()) { + WeakRefObject* weakRef = &target->as(); + GCRuntime* gc = &weakRef->runtimeFromMainThread()->gc; + if (weakRef->target() && gc->unregisterWeakRefWrapper(wrapper)) { + weakRef->setTarget(nullptr); + } + } + + /* + * Clean up FinalizationRecord record objects which might be the target of + * this wrapper. + */ + if (target->is()) { + auto* record = &target->as(); + FinalizationRegistryObject::unregisterRecord(record); + } } enum { @@ -4970,7 +5081,8 @@ class ImmediateSweepWeakCacheTask : public GCParallelTask { zone(other.zone), cache(other.cache) {} - void run() override { + void run(AutoLockHelperThreadState& lock) override { + AutoUnlockHelperThreadState unlock(lock); AutoSetThreadIsSweeping threadIsSweeping(zone); cache.sweep(&gc->storeBuffer()); } @@ -5033,14 +5145,7 @@ void GCRuntime::sweepCompressionTasks() { // Attach finished compression tasks. AutoLockHelperThreadState lock; AttachFinishedCompressions(runtime, lock); - - // Sweep pending tasks that are holding onto should-be-dead ScriptSources. - auto& pending = HelperThreadState().compressionPendingList(lock); - for (size_t i = 0; i < pending.length(); i++) { - if (pending[i]->shouldCancel()) { - HelperThreadState().remove(pending, &i); - } - } + SweepPendingCompressions(lock); } void GCRuntime::sweepWeakMaps() { @@ -5069,7 +5174,7 @@ void GCRuntime::sweepUniqueIds() { void GCRuntime::sweepWeakRefs() { for (SweepGroupZonesIter zone(this); !zone.done(); zone.next()) { AutoSetThreadIsSweeping threadIsSweeping(zone); - zone->weakRefMap().sweep(); + zone->weakRefMap().sweep(&storeBuffer()); } } @@ -5079,6 +5184,7 @@ void GCRuntime::sweepFinalizationRegistriesOnMainThread() { gcstats::AutoPhase ap1(stats(), gcstats::PhaseKind::SWEEP_COMPARTMENTS); gcstats::AutoPhase ap2(stats(), gcstats::PhaseKind::SWEEP_FINALIZATION_REGISTRIES); + AutoLockStoreBuffer lock(&storeBuffer()); for (SweepGroupZonesIter zone(this); !zone.done(); zone.next()) { sweepFinalizationRegistries(zone); } @@ -5127,6 +5233,8 @@ void GCRuntime::joinTask(GCParallelTask& task, gcstats::PhaseKind phase) { } void GCRuntime::sweepDebuggerOnMainThread(JSFreeOp* fop) { + AutoLockStoreBuffer lock(&storeBuffer()); + // Detach unreachable debuggers and global objects from each other. // This can modify weakmaps and so must happen before weakmap sweeping. DebugAPI::sweepAll(fop); @@ -5255,7 +5363,7 @@ static void SweepAllWeakCachesOnMainThread(JSRuntime* rt) { if (cache->needsIncrementalBarrier()) { cache->setNeedsIncrementalBarrier(false); } - cache->sweep(nullptr); + cache->sweep(&rt->gc.storeBuffer()); return true; }); } @@ -5300,6 +5408,8 @@ IncrementalProgress GCRuntime::beginSweepingSweepGroup(JSFreeOp* fop, #endif { + AutoLockStoreBuffer lock(&storeBuffer()); + AutoPhase ap(stats(), PhaseKind::FINALIZE_START); callFinalizeCallbacks(fop, JSFINALIZE_GROUP_PREPARE); { @@ -5350,19 +5460,23 @@ IncrementalProgress GCRuntime::beginSweepingSweepGroup(JSFreeOp* fop, PhaseKind::SWEEP_WEAKREFS, lock); WeakCacheTaskVector sweepCacheTasks; - if (PrepareWeakCacheTasks(rt, &sweepCacheTasks)) { + bool canSweepWeakCachesOffThread = + PrepareWeakCacheTasks(rt, &sweepCacheTasks); + if (canSweepWeakCachesOffThread) { weakCachesToSweep.ref().emplace(currentSweepGroup); - } else { - SweepAllWeakCachesOnMainThread(rt); - } - - for (auto& task : sweepCacheTasks) { - startTask(task, PhaseKind::SWEEP_WEAK_CACHES, lock); + for (auto& task : sweepCacheTasks) { + startTask(task, PhaseKind::SWEEP_WEAK_CACHES, lock); + } } { AutoUnlockHelperThreadState unlock(lock); sweepJitDataOnMainThread(fop); + + if (!canSweepWeakCachesOffThread) { + MOZ_ASSERT(sweepCacheTasks.empty()); + SweepAllWeakCachesOnMainThread(rt); + } } for (auto& task : sweepCacheTasks) { @@ -5416,18 +5530,21 @@ bool GCRuntime::shouldYieldForZeal(ZealMode mode) { IncrementalProgress GCRuntime::endSweepingSweepGroup(JSFreeOp* fop, SliceBudget& budget) { - // This is to prevent TSan data race, sweepMarkTask will check if the GC state - // is Marking, but later below we will change GC state to Finished. + // This is to prevent a race between sweepMarkTask checking the zone state and + // us changing it below. if (joinSweepMarkTask() == NotFinished) { return NotFinished; } + MOZ_ASSERT(marker.isDrained()); + // Disable background marking during sweeping until we start sweeping the next // zone group. markOnBackgroundThreadDuringSweeping = false; { gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::FINALIZE_END); + AutoLockStoreBuffer lock(&storeBuffer()); JSFreeOp fop(rt); callFinalizeCallbacks(&fop, JSFINALIZE_GROUP_END); } @@ -5471,7 +5588,9 @@ IncrementalProgress GCRuntime::endSweepingSweepGroup(JSFreeOp* fop, IncrementalProgress GCRuntime::markDuringSweeping(JSFreeOp* fop, SliceBudget& budget) { - if (sweepMarkTaskStarted || marker.isDrained()) { + MOZ_ASSERT(sweepMarkTask.isIdle()); + + if (marker.isDrained()) { return Finished; } @@ -5480,7 +5599,6 @@ IncrementalProgress GCRuntime::markDuringSweeping(JSFreeOp* fop, MOZ_ASSERT(sweepMarkTask.isIdle(lock)); sweepMarkTask.setBudget(budget); sweepMarkTask.startOrRunIfIdle(lock); - sweepMarkTaskStarted = true; return Finished; // This means don't yield to the mutator here. } @@ -5523,10 +5641,6 @@ bool ArenaLists::foregroundFinalize(JSFreeOp* fop, AllocKind thingKind, SortedArenaList& sweepList) { checkNoArenasToUpdateForKind(thingKind); - if (!arenasToSweep(thingKind) && incrementalSweptArenas.ref().isEmpty()) { - return true; - } - // Arenas are released for use for new allocations as soon as the finalizers // for that allocation kind have run. This means that a cell's finalizer can // safely use IsAboutToBeFinalized to check other cells of the same alloc @@ -5547,23 +5661,36 @@ bool ArenaLists::foregroundFinalize(JSFreeOp* fop, AllocKind thingKind, sweepList.extractEmpty(&savedEmptyArenas.ref()); - ArenaList finalized = sweepList.toArenaList(); - arenaList(thingKind) = - finalized.insertListWithCursorAtEnd(arenaList(thingKind)); + ArenaList& al = arenaList(thingKind); + ArenaList allocatedDuringSweep = al; + al = sweepList.toArenaList(); + al.insertListWithCursorAtEnd(newArenasInMarkPhase(thingKind)); + al.insertListWithCursorAtEnd(allocatedDuringSweep); + + newArenasInMarkPhase(thingKind).clear(); return true; } -void js::gc::SweepMarkTask::run() { +void js::gc::SweepMarkTask::run(AutoLockHelperThreadState& lock) { + AutoUnlockHelperThreadState unlock(lock); + // Time reporting is handled separately for parallel tasks. gc->sweepMarkResult = gc->markUntilBudgetExhausted(this->budget, GCMarker::DontReportMarkTime); } IncrementalProgress GCRuntime::joinSweepMarkTask() { - joinTask(sweepMarkTask, gcstats::PhaseKind::SWEEP_MARK); + AutoLockHelperThreadState lock; + if (sweepMarkTask.isIdle(lock)) { + return Finished; + } + + joinTask(sweepMarkTask, gcstats::PhaseKind::SWEEP_MARK, lock); - return sweepMarkTaskStarted ? sweepMarkResult : Finished; + IncrementalProgress result = sweepMarkResult; + sweepMarkResult = Finished; + return result; } IncrementalProgress GCRuntime::markUntilBudgetExhausted( @@ -5649,11 +5776,21 @@ IncrementalProgress GCRuntime::sweepTypeInformation(JSFreeOp* fop, return NotFinished; } + if (!SweepArenaList(fop, &al.gcNewScriptArenasToUpdate.ref(), + budget)) { + return NotFinished; + } + if (!SweepArenaList(fop, &al.gcObjectGroupArenasToUpdate.ref(), budget)) { return NotFinished; } + if (!SweepArenaList( + fop, &al.gcNewObjectGroupArenasToUpdate.ref(), budget)) { + return NotFinished; + } + // Finish sweeping type information in the zone. { gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::SWEEP_TYPES_END); @@ -6120,7 +6257,6 @@ bool GCRuntime::initSweepActions() { Call(&GCRuntime::endMarkingSweepGroup), Call(&GCRuntime::beginSweepingSweepGroup), MaybeYield(ZealMode::IncrementalMultipleSlices), - Call(&GCRuntime::markDuringSweeping), MaybeYield(ZealMode::YieldBeforeSweepingAtoms), Call(&GCRuntime::sweepAtomsTable), MaybeYield(ZealMode::YieldBeforeSweepingCaches), @@ -6166,18 +6302,15 @@ IncrementalProgress GCRuntime::performSweepActions(SliceBudget& budget) { // Then continue running sweep actions. SweepAction::Args args{this, &fop, budget}; - IncrementalProgress progress = sweepActions->run(args); + IncrementalProgress sweepProgress = sweepActions->run(args); + IncrementalProgress markProgress = joinSweepMarkTask(); - if (sweepMarkTaskStarted) { - joinSweepMarkTask(); - sweepMarkTaskStarted = false; - if (sweepMarkResult == NotFinished) { - progress = NotFinished; - } + if (sweepProgress == Finished && markProgress == Finished) { + return Finished; } - MOZ_ASSERT_IF(progress == NotFinished, isIncremental); - return progress; + MOZ_ASSERT(isIncremental); + return NotFinished; } bool GCRuntime::allCCVisibleZonesWereCollected() { @@ -6227,6 +6360,7 @@ void GCRuntime::endSweepPhase(bool destroyingRuntime) { { gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::FINALIZE_END); + AutoLockStoreBuffer lock(&storeBuffer()); callFinalizeCallbacks(&fop, JSFINALIZE_COLLECTION_END); if (allCCVisibleZonesWereCollected()) { @@ -6351,7 +6485,7 @@ void GCRuntime::finishCollection() { zone->clearGCSliceThresholds(); zone->notifyObservingDebuggers(); zone->updateGCStartThresholds(*this, invocationKind, lock); - zone->arenas.checkSweepStateNotInUse(); + zone->arenas.checkGCStateNotInUse(); } } @@ -6414,7 +6548,7 @@ JS_PUBLIC_API JS::HeapState JS::RuntimeHeapState() { } GCRuntime::IncrementalResult GCRuntime::resetIncrementalGC( - gc::AbortReason reason) { + GCAbortReason reason) { // Drop as much work as possible from an ongoing incremental GC so // we can start a new GC after it has finished. if (incrementalState == State::NotActive) { @@ -6444,6 +6578,7 @@ GCRuntime::IncrementalResult GCRuntime::resetIncrementalGC( zone->changeGCState(Zone::MarkBlackOnly, Zone::NoGC); zone->clearGCSliceThresholds(); zone->arenas.unmarkPreMarkedFreeCells(); + zone->arenas.mergeNewArenasInMarkPhase(); } { @@ -6497,12 +6632,13 @@ GCRuntime::IncrementalResult GCRuntime::resetIncrementalGC( namespace { /* - * Temporarily disable barriers during GC slices. + * Manage barriers: disable during GC slices, and enable during an incremental + * GC for all zones that are marking. */ -class AutoDisableBarriers { +class AutoUpdateBarriers { public: - explicit AutoDisableBarriers(GCRuntime* gc); - ~AutoDisableBarriers(); + explicit AutoUpdateBarriers(GCRuntime* gc); + ~AutoUpdateBarriers(); private: GCRuntime* gc; @@ -6510,13 +6646,13 @@ class AutoDisableBarriers { } /* anonymous namespace */ -AutoDisableBarriers::AutoDisableBarriers(GCRuntime* gc) : gc(gc) { +AutoUpdateBarriers::AutoUpdateBarriers(GCRuntime* gc) : gc(gc) { for (GCZonesIter zone(gc); !zone.done(); zone.next()) { /* * Clear needsIncrementalBarrier early so we don't do any write * barriers during GC. We don't need to update the Ion barriers (which * is expensive) because Ion code doesn't run during GC. If need be, - * we'll update the Ion barriers in ~AutoDisableBarriers. + * we'll update the Ion barriers in ~AutoUpdateBarriers. */ if (zone->isGCMarking()) { MOZ_ASSERT(zone->needsIncrementalBarrier()); @@ -6526,7 +6662,7 @@ AutoDisableBarriers::AutoDisableBarriers(GCRuntime* gc) : gc(gc) { } } -AutoDisableBarriers::~AutoDisableBarriers() { +AutoUpdateBarriers::~AutoUpdateBarriers() { /* We can't use GCZonesIter if this is the end of the last slice. */ for (ZonesIter zone(gc, WithAtoms); !zone.done(); zone.next()) { MOZ_ASSERT(!zone->needsIncrementalBarrier()); @@ -6541,7 +6677,7 @@ static bool ShouldCleanUpEverything(JS::GCReason reason, // During shutdown, we must clean everything up, for the sake of leak // detection. When a runtime has no contexts, or we're doing a GC before a // shutdown CC, those are strong indications that we're shutting down. - return IsShutdownGC(reason) || gckind == GC_SHRINK; + return IsShutdownReason(reason) || gckind == GC_SHRINK; } static bool ShouldSweepOnBackgroundThread(JS::GCReason reason) { @@ -6551,7 +6687,7 @@ static bool ShouldSweepOnBackgroundThread(JS::GCReason reason) { void GCRuntime::incrementalSlice(SliceBudget& budget, const MaybeInvocationKind& gckind, JS::GCReason reason, AutoGCSession& session) { - AutoDisableBarriers disableBarriers(this); + AutoUpdateBarriers updateBarriers(this); AutoSetThreadIsPerformingGC performingGC; bool destroyingRuntime = (reason == JS::GCReason::DESTROY_RUNTIME); @@ -6635,7 +6771,7 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, if (isIncremental && !hasValidGrayRootsBuffer()) { budget.makeUnlimited(); isIncremental = false; - stats().nonincremental(AbortReason::GrayRootBufferingFailed); + stats().nonincremental(GCAbortReason::GrayRootBufferingFailed); } incrementalState = State::Mark; @@ -6648,7 +6784,11 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, [[fallthrough]]; case State::Mark: - rt->mainContextFromOwnThread()->traceWrapperGCRooters(&marker); + if (mightSweepInThisSlice(budget.isUnlimited())) { + // Trace wrapper rooters before marking if we might start sweeping in + // this slice. + rt->mainContextFromOwnThread()->traceWrapperGCRooters(&marker); + } { gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK); @@ -6695,7 +6835,9 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, [[fallthrough]]; case State::Sweep: - rt->mainContextFromOwnThread()->traceWrapperGCRooters(&marker); + if (initialState == State::Sweep) { + rt->mainContextFromOwnThread()->traceWrapperGCRooters(&marker); + } if (performSweepActions(budget) == NotFinished) { break; @@ -6708,22 +6850,11 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, [[fallthrough]]; case State::Finalize: - // In incremental collections, yield here until background finalization - // is done and request a slice to notify us when this happens. - if (!budget.isUnlimited()) { - AutoLockHelperThreadState lock; - if (sweepTask.wasStarted(lock)) { - requestSliceAfterBackgroundTask = true; - break; - } + if (waitForBackgroundTask(sweepTask, budget) == NotFinished) { + break; } - { - gcstats::AutoPhase ap(stats(), - gcstats::PhaseKind::WAIT_BACKGROUND_THREAD); - waitBackgroundSweepEnd(); - cancelRequestedGCAfterBackgroundTask(); - } + assertBackgroundSweepingFinished(); { // Sweep the zones list now that background finalization is finished to @@ -6765,21 +6896,8 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, [[fallthrough]]; case State::Decommit: - // In incremental collections, yield until background decommit is done and - // request a slice to notify us when that happens. - if (!budget.isUnlimited()) { - AutoLockHelperThreadState lock; - if (decommitTask.wasStarted(lock)) { - requestSliceAfterBackgroundTask = true; - break; - } - } - - { - gcstats::AutoPhase ap(stats(), - gcstats::PhaseKind::WAIT_BACKGROUND_THREAD); - decommitTask.join(); - cancelRequestedGCAfterBackgroundTask(); + if (waitForBackgroundTask(decommitTask, budget) == NotFinished) { + break; } incrementalState = State::Finish; @@ -6813,14 +6931,34 @@ bool GCRuntime::hasForegroundWork() const { } } -gc::AbortReason gc::IsIncrementalGCUnsafe(JSRuntime* rt) { +IncrementalProgress GCRuntime::waitForBackgroundTask(GCParallelTask& task, + SliceBudget& budget) { + // In incremental collections, yield if the task has not finished and request + // a slice to notify us when this happens. + if (!budget.isUnlimited()) { + AutoLockHelperThreadState lock; + if (task.wasStarted(lock)) { + requestSliceAfterBackgroundTask = true; + return NotFinished; + } + } + + // Otherwise in non-incremental collections, wait here. + gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::WAIT_BACKGROUND_THREAD); + task.join(); + cancelRequestedGCAfterBackgroundTask(); + + return Finished; +} + +GCAbortReason gc::IsIncrementalGCUnsafe(JSRuntime* rt) { MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC); if (!rt->gc.isIncrementalGCAllowed()) { - return gc::AbortReason::IncrementalDisabled; + return GCAbortReason::IncrementalDisabled; } - return gc::AbortReason::None; + return GCAbortReason::None; } inline void GCRuntime::checkZoneIsScheduled(Zone* zone, JS::GCReason reason, @@ -6847,7 +6985,7 @@ inline void GCRuntime::checkZoneIsScheduled(Zone* zone, JS::GCReason reason, GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( bool nonincrementalByAPI, JS::GCReason reason, SliceBudget& budget) { if (nonincrementalByAPI) { - stats().nonincremental(gc::AbortReason::NonIncrementalRequested); + stats().nonincremental(GCAbortReason::NonIncrementalRequested); budget.makeUnlimited(); // Reset any in progress incremental GC if this was triggered via the @@ -6855,7 +6993,7 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( // the caller expects this GC to collect certain objects, and we need // to make sure to collect everything possible. if (reason != JS::GCReason::ALLOC_TRIGGER) { - return resetIncrementalGC(gc::AbortReason::NonIncrementalRequested); + return resetIncrementalGC(GCAbortReason::NonIncrementalRequested); } return IncrementalResult::Ok; @@ -6863,27 +7001,27 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( if (reason == JS::GCReason::ABORT_GC) { budget.makeUnlimited(); - stats().nonincremental(gc::AbortReason::AbortRequested); - return resetIncrementalGC(gc::AbortReason::AbortRequested); + stats().nonincremental(GCAbortReason::AbortRequested); + return resetIncrementalGC(GCAbortReason::AbortRequested); } - AbortReason unsafeReason = IsIncrementalGCUnsafe(rt); - if (unsafeReason == AbortReason::None) { + GCAbortReason unsafeReason = IsIncrementalGCUnsafe(rt); + if (unsafeReason == GCAbortReason::None) { if (reason == JS::GCReason::COMPARTMENT_REVIVED) { - unsafeReason = gc::AbortReason::CompartmentRevived; + unsafeReason = GCAbortReason::CompartmentRevived; } else if (mode != JSGC_MODE_INCREMENTAL && mode != JSGC_MODE_ZONE_INCREMENTAL) { - unsafeReason = gc::AbortReason::ModeChange; + unsafeReason = GCAbortReason::ModeChange; } } - if (unsafeReason != AbortReason::None) { + if (unsafeReason != GCAbortReason::None) { budget.makeUnlimited(); stats().nonincremental(unsafeReason); return resetIncrementalGC(unsafeReason); } - AbortReason resetReason = AbortReason::None; + GCAbortReason resetReason = GCAbortReason::None; for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) { if (!zone->canCollect()) { continue; @@ -6893,9 +7031,9 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( zone->gcHeapThreshold.incrementalLimitBytes()) { checkZoneIsScheduled(zone, reason, "GC bytes"); budget.makeUnlimited(); - stats().nonincremental(AbortReason::GCBytesTrigger); + stats().nonincremental(GCAbortReason::GCBytesTrigger); if (zone->wasGCStarted() && zone->gcState() > Zone::Sweep) { - resetReason = AbortReason::GCBytesTrigger; + resetReason = GCAbortReason::GCBytesTrigger; } } @@ -6903,9 +7041,9 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( zone->mallocHeapThreshold.incrementalLimitBytes()) { checkZoneIsScheduled(zone, reason, "malloc bytes"); budget.makeUnlimited(); - stats().nonincremental(AbortReason::MallocBytesTrigger); + stats().nonincremental(GCAbortReason::MallocBytesTrigger); if (zone->wasGCStarted() && zone->gcState() > Zone::Sweep) { - resetReason = AbortReason::MallocBytesTrigger; + resetReason = GCAbortReason::MallocBytesTrigger; } } @@ -6913,20 +7051,20 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( zone->jitHeapThreshold.incrementalLimitBytes()) { checkZoneIsScheduled(zone, reason, "JIT code bytes"); budget.makeUnlimited(); - stats().nonincremental(AbortReason::JitCodeBytesTrigger); + stats().nonincremental(GCAbortReason::JitCodeBytesTrigger); if (zone->wasGCStarted() && zone->gcState() > Zone::Sweep) { - resetReason = AbortReason::JitCodeBytesTrigger; + resetReason = GCAbortReason::JitCodeBytesTrigger; } } if (isIncrementalGCInProgress() && zone->isGCScheduled() != zone->wasGCStarted()) { budget.makeUnlimited(); - resetReason = AbortReason::ZoneChange; + resetReason = GCAbortReason::ZoneChange; } } - if (resetReason != AbortReason::None) { + if (resetReason != GCAbortReason::None) { return resetIncrementalGC(resetReason); } @@ -7072,7 +7210,8 @@ MOZ_NEVER_INLINE GCRuntime::IncrementalResult GCRuntime::gcCycle( } if (shouldCollectNurseryForSlice(nonincrementalByAPI, budget)) { - collectNursery(reason, gcstats::PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC); + collectNursery(gckind.valueOr(GC_NORMAL), reason, + gcstats::PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC); } else { ++number; // This otherwise happens in Nursery::collect(). } @@ -7250,7 +7389,7 @@ bool GCRuntime::checkIfGCAllowedInCurrentState(JS::GCReason reason) { // Only allow shutdown GCs when we're destroying the runtime. This keeps // the GC callback from triggering a nested GC and resetting global state. - if (rt->isBeingDestroyed() && !IsShutdownGC(reason)) { + if (rt->isBeingDestroyed() && !IsShutdownReason(reason)) { return false; } @@ -7327,13 +7466,13 @@ void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, StateName(incrementalState)); AutoTraceLog logGC(TraceLoggerForCurrentThread(), TraceLogger_GC); - AutoStopVerifyingBarriers av(rt, IsShutdownGC(reason)); + AutoStopVerifyingBarriers av(rt, IsShutdownReason(reason)); AutoEnqueuePendingParseTasksAfterGC aept(*this); AutoMaybeLeaveAtomsZone leaveAtomsZone(rt->mainContextFromOwnThread()); AutoSetZoneSliceThresholds sliceThresholds(this); #ifdef DEBUG - if (IsShutdownGC(reason)) { + if (IsShutdownReason(reason)) { marker.markQueue.clear(); marker.queuePos = 0; } @@ -7362,7 +7501,7 @@ void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, if (!isIncrementalGCInProgress()) { if (cycleResult == ResetIncremental) { repeat = true; - } else if (rootsRemoved && IsShutdownGC(reason)) { + } else if (rootsRemoved && IsShutdownReason(reason)) { /* Need to re-schedule all zones for GC. */ JS::PrepareForFullGC(rt->mainContextFromOwnThread()); repeat = true; @@ -7532,7 +7671,7 @@ void GCRuntime::minorGC(JS::GCReason reason, gcstats::PhaseKind phase) { return; } - collectNursery(reason, phase); + collectNursery(GC_NORMAL, reason, phase); for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) { maybeAllocTriggerZoneGC(zone); @@ -7540,7 +7679,8 @@ void GCRuntime::minorGC(JS::GCReason reason, gcstats::PhaseKind phase) { } } -void GCRuntime::collectNursery(JS::GCReason reason, gcstats::PhaseKind phase) { +void GCRuntime::collectNursery(JSGCInvocationKind kind, JS::GCReason reason, + gcstats::PhaseKind phase) { AutoMaybeLeaveAtomsZone leaveAtomsZone(rt->mainContextFromOwnThread()); // Note that we aren't collecting the updated alloc counts from any helper @@ -7558,7 +7698,7 @@ void GCRuntime::collectNursery(JS::GCReason reason, gcstats::PhaseKind phase) { nursery().clearMinorGCRequest(); TraceLoggerThread* logger = TraceLoggerForCurrentThread(); AutoTraceLog logMinorGC(logger, TraceLogger_MinorGC); - nursery().collect(reason); + nursery().collect(kind, reason); MOZ_ASSERT(nursery().isEmpty()); startBackgroundFreeAfterMinorGC(); @@ -7689,7 +7829,11 @@ Realm* js::NewRealm(JSContext* cx, JSPrincipals* principals, const JSPrincipals* trusted = rt->trustedPrincipals(); bool isSystem = principals && principals == trusted; - if (isSystem) { + // If this is a NewCompartmentInSystemZone request, we're going to call + // `setIsSystemZone` below when we store the new zone in `gc.systemZone`, so + // don't do it here too. + if (isSystem && + compSpec != JS::CompartmentSpecifier::NewCompartmentInSystemZone) { zoneHolder->setIsSystemZone(); } @@ -7813,8 +7957,6 @@ void GCRuntime::mergeRealms(Realm* source, Realm* target) { JSObject* targetProto = global->getPrototypeForOffThreadPlaceholder(obj); MOZ_ASSERT(targetProto->isDelegate()); - MOZ_ASSERT_IF(targetProto->staticPrototypeIsImmutable(), - obj->staticPrototypeIsImmutable()); MOZ_ASSERT_IF(targetProto->isNewGroupUnknown(), obj->isNewGroupUnknown()); group->setProtoUnchecked(TaggedProto(targetProto)); @@ -8143,19 +8285,19 @@ JS::GCCellPtr::GCCellPtr(const Value& v) : ptr(0) { switch (v.type()) { case ValueType::String: ptr = checkedCast(v.toString(), JS::TraceKind::String); - break; + return; case ValueType::Object: ptr = checkedCast(&v.toObject(), JS::TraceKind::Object); - break; + return; case ValueType::Symbol: ptr = checkedCast(v.toSymbol(), JS::TraceKind::Symbol); - break; + return; case ValueType::BigInt: ptr = checkedCast(v.toBigInt(), JS::TraceKind::BigInt); - break; + return; case ValueType::PrivateGCThing: ptr = checkedCast(v.toGCThing(), v.toGCThing()->getTraceKind()); - break; + return; case ValueType::Double: case ValueType::Int32: case ValueType::Boolean: @@ -8164,9 +8306,11 @@ JS::GCCellPtr::GCCellPtr(const Value& v) : ptr(0) { case ValueType::Magic: { MOZ_ASSERT(!v.isGCThing()); ptr = checkedCast(nullptr, JS::TraceKind::Null); - break; + return; } } + + ReportBadValueTypeAndCrash(v); } JS::TraceKind JS::GCCellPtr::outOfLineKind() const { @@ -8311,22 +8455,6 @@ JS::dbg::GarbageCollectionEvent::Ptr JS::GCDescription::toGCEvent( cx->runtime()->gc.majorGCCount()); } -char16_t* JS::GCDescription::formatJSONTelemetry(JSContext* cx, - uint64_t timestamp) const { - UniqueChars cstr = cx->runtime()->gc.stats().renderJsonMessage( - timestamp, gcstats::Statistics::JSONUse::TELEMETRY); - - size_t nchars = strlen(cstr.get()); - UniqueTwoByteChars out(js_pod_malloc(nchars + 1)); - if (!out) { - return nullptr; - } - out.get()[nchars] = 0; - - CopyAndInflateChars(out.get(), cstr.get(), nchars); - return out.release(); -} - TimeStamp JS::GCDescription::startTime(JSContext* cx) const { return cx->runtime()->gc.stats().start(); } @@ -8350,8 +8478,7 @@ JS::UniqueChars JS::GCDescription::sliceToJSONProfiler(JSContext* cx) const { } JS::UniqueChars JS::GCDescription::formatJSONProfiler(JSContext* cx) const { - return cx->runtime()->gc.stats().renderJsonMessage( - 0, js::gcstats::Statistics::JSONUse::PROFILER); + return cx->runtime()->gc.stats().renderJsonMessage(); } JS_PUBLIC_API JS::UniqueChars JS::MinorGcToJSON(JSContext* cx) { @@ -8410,7 +8537,7 @@ JS_PUBLIC_API void JS::IncrementalPreWriteBarrier(JSObject* obj) { return; } - JSObject::writeBarrierPre(obj); + PreWriteBarrier(obj); } JS_PUBLIC_API void JS::IncrementalPreWriteBarrier(GCCellPtr thing) { @@ -8418,7 +8545,7 @@ JS_PUBLIC_API void JS::IncrementalPreWriteBarrier(GCCellPtr thing) { return; } - TenuredCell::writeBarrierPre(&thing.asCell()->asTenured()); + CellPtrPreWriteBarrier(thing); } JS_PUBLIC_API bool JS::WasIncrementalGC(JSRuntime* rt) { @@ -8439,6 +8566,16 @@ static bool GCBytesGetter(JSContext* cx, unsigned argc, Value* vp) { return true; } +static bool MallocBytesGetter(JSContext* cx, unsigned argc, Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + double bytes = 0; + for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) { + bytes += zone->mallocHeapSize.bytes(); + } + args.rval().setNumber(bytes); + return true; +} + static bool GCMaxBytesGetter(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); args.rval().setNumber(double(cx->runtime()->gc.tunables.gcMaxBytes())); @@ -8538,6 +8675,7 @@ JSObject* NewMemoryInfoObject(JSContext* cx) { JSNative getter; } getters[] = {{"gcBytes", GCBytesGetter}, {"gcMaxBytes", GCMaxBytesGetter}, + {"mallocBytes", MallocBytesGetter}, {"gcIsHighFrequencyMode", GCHighFreqGetter}, {"gcNumber", GCNumberGetter}, {"majorGCCount", MajorGCCountGetter}, @@ -8823,7 +8961,7 @@ JS_PUBLIC_API void js::gc::FinalizeDeadNurseryObject(JSContext* cx, MOZ_ASSERT(IsAboutToBeFinalizedUnbarriered(&prior)); MOZ_ASSERT(obj == prior); - const JSClass* jsClass = js::GetObjectClass(obj); + const JSClass* jsClass = JS::GetClass(obj); jsClass->doFinalize(cx->defaultFreeOp(), obj); } diff --git a/js/src/gc/GC.h b/js/src/gc/GC.h index 73bc6e1dae..7d30a6b32d 100644 --- a/js/src/gc/GC.h +++ b/js/src/gc/GC.h @@ -69,11 +69,15 @@ extern unsigned NotifyGCPreSwap(JSObject* a, JSObject* b); extern void NotifyGCPostSwap(JSObject* a, JSObject* b, unsigned preResult); -using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::Chunk*); -using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*); +using IterateChunkCallback = void (*)(JSRuntime*, void*, gc::Chunk*, + const JS::AutoRequireNoGC&); +using IterateZoneCallback = void (*)(JSRuntime*, void*, JS::Zone*, + const JS::AutoRequireNoGC&); using IterateArenaCallback = void (*)(JSRuntime*, void*, gc::Arena*, - JS::TraceKind, size_t); -using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t); + JS::TraceKind, size_t, + const JS::AutoRequireNoGC&); +using IterateCellCallback = void (*)(JSRuntime*, void*, JS::GCCellPtr, size_t, + const JS::AutoRequireNoGC&); /* * This function calls |zoneCallback| on every zone, |realmCallback| on diff --git a/js/src/gc/GCEnum.h b/js/src/gc/GCEnum.h index 6073cf74f8..854307ee62 100644 --- a/js/src/gc/GCEnum.h +++ b/js/src/gc/GCEnum.h @@ -36,26 +36,6 @@ enum class State { #undef MAKE_STATE }; -// Reasons we reset an ongoing incremental GC or perform a non-incremental GC. -#define GC_ABORT_REASONS(D) \ - D(None, 0) \ - D(NonIncrementalRequested, 1) \ - D(AbortRequested, 2) \ - D(Unused1, 3) \ - D(IncrementalDisabled, 4) \ - D(ModeChange, 5) \ - D(MallocBytesTrigger, 6) \ - D(GCBytesTrigger, 7) \ - D(ZoneChange, 8) \ - D(CompartmentRevived, 9) \ - D(GrayRootBufferingFailed, 10) \ - D(JitCodeBytesTrigger, 11) -enum class AbortReason { -#define MAKE_REASON(name, num) name = num, - GC_ABORT_REASONS(MAKE_REASON) -#undef MAKE_REASON -}; - #define JS_FOR_EACH_ZEAL_MODE(D) \ D(RootsChange, 1) \ D(Alloc, 2) \ @@ -90,6 +70,26 @@ enum class ZealMode { } /* namespace gc */ +// Reasons we reset an ongoing incremental GC or perform a non-incremental GC. +#define GC_ABORT_REASONS(D) \ + D(None, 0) \ + D(NonIncrementalRequested, 1) \ + D(AbortRequested, 2) \ + D(Unused1, 3) \ + D(IncrementalDisabled, 4) \ + D(ModeChange, 5) \ + D(MallocBytesTrigger, 6) \ + D(GCBytesTrigger, 7) \ + D(ZoneChange, 8) \ + D(CompartmentRevived, 9) \ + D(GrayRootBufferingFailed, 10) \ + D(JitCodeBytesTrigger, 11) +enum class GCAbortReason { +#define MAKE_REASON(name, num) name = num, + GC_ABORT_REASONS(MAKE_REASON) +#undef MAKE_REASON +}; + #define JS_FOR_EACH_INTERNAL_MEMORY_USE(_) \ _(ArrayBufferContents) \ _(StringContents) \ @@ -138,7 +138,6 @@ enum class ZealMode { _(RealmInstrumentation) \ _(ICUObject) \ _(FinalizationRegistryRecordVector) \ - _(FinalizationRegistryRecordSet) \ _(FinalizationRegistryRegistrations) \ _(FinalizationRecordVector) \ _(ZoneAllocPolicy) \ diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 53e6555c79..0e4839db5a 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -162,7 +162,7 @@ class MOZ_RAII AutoEmptyNurseryAndPrepareForTracing : private AutoFinishGC, AutoTraceSession(cx->runtime()) {} }; -AbortReason IsIncrementalGCUnsafe(JSRuntime* rt); +GCAbortReason IsIncrementalGCUnsafe(JSRuntime* rt); #ifdef JS_GC_ZEAL @@ -223,6 +223,7 @@ struct MovingTracer final : public JS::CallbackTracer { bool onScopeEdge(Scope** scopep) override; bool onRegExpSharedEdge(RegExpShared** sharedp) override; bool onBigIntEdge(BigInt** bip) override; + bool onObjectGroupEdge(ObjectGroup** groupp) override; bool onChild(const JS::GCCellPtr& thing) override { MOZ_ASSERT(!thing.asCell()->isForwarded()); return true; @@ -312,6 +313,13 @@ inline bool IsOOMReason(JS::GCReason reason) { reason == JS::GCReason::MEM_PRESSURE; } +// TODO: Bug 1650075. Adding XPCONNECT_SHUTDOWN seems to cause crash. +inline bool IsShutdownReason(JS::GCReason reason) { + return reason == JS::GCReason::WORKER_SHUTDOWN || + reason == JS::GCReason::SHUTDOWN_CC || + reason == JS::GCReason::DESTROY_RUNTIME; +} + TenuredCell* AllocateCellInGC(JS::Zone* zone, AllocKind thingKind); } /* namespace gc */ diff --git a/js/src/gc/GCLock.h b/js/src/gc/GCLock.h index 22720a8517..447e1245e5 100644 --- a/js/src/gc/GCLock.h +++ b/js/src/gc/GCLock.h @@ -25,15 +25,8 @@ class AutoUnlockGC; */ class MOZ_RAII AutoLockGC { public: - explicit AutoLockGC(gc::GCRuntime* gc MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : gc(gc) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - lock(); - } - explicit AutoLockGC(JSRuntime* rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoLockGC(&rt->gc) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } + explicit AutoLockGC(gc::GCRuntime* gc) : gc(gc) { lock(); } + explicit AutoLockGC(JSRuntime* rt) : AutoLockGC(&rt->gc) {} ~AutoLockGC() { lockGuard_.reset(); } @@ -54,7 +47,6 @@ class MOZ_RAII AutoLockGC { private: mozilla::Maybe> lockGuard_; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER AutoLockGC(const AutoLockGC&) = delete; AutoLockGC& operator=(const AutoLockGC&) = delete; @@ -100,17 +92,12 @@ class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC { class MOZ_RAII AutoUnlockGC { public: - explicit AutoUnlockGC(AutoLockGC& lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : lock(lock) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - lock.unlock(); - } + explicit AutoUnlockGC(AutoLockGC& lock) : lock(lock) { lock.unlock(); } ~AutoUnlockGC() { lock.lock(); } private: AutoLockGC& lock; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER AutoUnlockGC(const AutoUnlockGC&) = delete; AutoUnlockGC& operator=(const AutoUnlockGC&) = delete; diff --git a/js/src/gc/GCMarker.h b/js/src/gc/GCMarker.h index 0f0aae5abd..48b1b4a7bb 100644 --- a/js/src/gc/GCMarker.h +++ b/js/src/gc/GCMarker.h @@ -9,6 +9,7 @@ #include "mozilla/Unused.h" #include "ds/OrderedHashTable.h" +#include "gc/Barrier.h" #include "js/SliceBudget.h" #include "js/TracingAPI.h" #include "js/TypeDecls.h" @@ -79,10 +80,10 @@ class MarkStack { * the context of push or pop operation. */ enum Tag { - ValueArrayTag, + SlotsRangeTag, + ElementsRangeTag, ObjectTag, GroupTag, - SavedValueArrayTag, JitCodeTag, ScriptTag, TempRopeTag, @@ -108,28 +109,18 @@ class MarkStack { template T* as() const; - JSObject* asValueArrayObject() const; - JSObject* asSavedValueArrayObject() const; + JSObject* asSlotsRangeObject() const; + JSObject* asElementsRangeObject() const; JSRope* asTempRope() const; void assertValid() const; }; - struct ValueArray { - ValueArray(JSObject* obj, HeapSlot* start, HeapSlot* end); + struct SlotsOrElementsRange { + SlotsOrElementsRange(Tag, JSObject* obj, size_t start); void assertValid() const; - HeapSlot* end; - HeapSlot* start; - TaggedPtr ptr; - }; - - struct SavedValueArray { - SavedValueArray(JSObject* obj, size_t index, HeapSlot::Kind kind); - void assertValid() const; - - uintptr_t kind; - uintptr_t index; + size_t start; TaggedPtr ptr; }; @@ -154,9 +145,8 @@ class MarkStack { template MOZ_MUST_USE bool push(T* ptr); - MOZ_MUST_USE bool push(JSObject* obj, HeapSlot* start, HeapSlot* end); - MOZ_MUST_USE bool push(const ValueArray& array); - MOZ_MUST_USE bool push(const SavedValueArray& array); + MOZ_MUST_USE bool push(JSObject* obj, HeapSlot::Kind kind, size_t start); + MOZ_MUST_USE bool push(const SlotsOrElementsRange& array); // GCMarker::eagerlyMarkChildren uses unused marking stack as temporary // storage to hold rope pointers. @@ -166,8 +156,7 @@ class MarkStack { Tag peekTag() const; TaggedPtr popPtr(); - ValueArray popValueArray(); - SavedValueArray popSavedValueArray(); + SlotsOrElementsRange popSlotsOrElementsRange(); void clear() { // Fall back to the smaller initial capacity so we don't hold on to excess @@ -227,14 +216,11 @@ class MarkStackIter { bool done() const; MarkStack::Tag peekTag() const; MarkStack::TaggedPtr peekPtr() const; - MarkStack::ValueArray peekValueArray() const; + MarkStack::SlotsOrElementsRange peekSlotsOrElementsRange() const; void next(); void nextPtr(); void nextArray(); - // Mutate the current ValueArray to a SavedValueArray. - void saveValueArray(const MarkStack::SavedValueArray& savedArray); - private: size_t position() const; }; @@ -419,7 +405,10 @@ class GCMarker : public JSTracer { template inline void pushTaggedPtr(T* ptr); - inline void pushValueArray(JSObject* obj, HeapSlot* start, HeapSlot* end); + enum class RangeKind { Elements, FixedSlots, DynamicSlots }; + + inline void pushValueRange(JSObject* obj, RangeKind kind, size_t start, + size_t end); bool isMarkStackEmpty() { return stack.isEmpty() && auxStack.isEmpty(); } @@ -431,16 +420,6 @@ class GCMarker : public JSTracer { return !getStack(gc::MarkColor::Gray).isEmpty(); } - MOZ_MUST_USE bool restoreValueArray( - const gc::MarkStack::SavedValueArray& array, HeapSlot** vpp, - HeapSlot** endp); - gc::MarkStack::ValueArray restoreValueArray( - const gc::MarkStack::SavedValueArray& savedArray); - - void saveValueRanges(); - gc::MarkStack::SavedValueArray saveValueRange( - const gc::MarkStack::ValueArray& array); - inline void processMarkStackTop(SliceBudget& budget); void markDelayedChildren(gc::Arena* arena, gc::MarkColor color); @@ -577,11 +556,4 @@ class MOZ_RAII AutoSetMarkColor { } /* namespace js */ -// Exported for Tracer.cpp -inline bool ThingIsPermanentAtomOrWellKnownSymbol(js::gc::Cell* thing) { - return false; -} -bool ThingIsPermanentAtomOrWellKnownSymbol(JSString*); -bool ThingIsPermanentAtomOrWellKnownSymbol(JS::Symbol*); - #endif /* gc_GCMarker_h */ diff --git a/js/src/gc/GCParallelTask.cpp b/js/src/gc/GCParallelTask.cpp index cf41ca1f93..dcd1f7fcb8 100644 --- a/js/src/gc/GCParallelTask.cpp +++ b/js/src/gc/GCParallelTask.cpp @@ -7,8 +7,9 @@ #include "mozilla/MathAlgorithms.h" #include "gc/ParallelWork.h" -#include "vm/HelperThreads.h" +#include "vm/HelperThreadState.h" #include "vm/Runtime.h" +#include "vm/TraceLogging.h" using namespace js; using namespace js::gc; @@ -26,13 +27,11 @@ js::GCParallelTask::~GCParallelTask() { void js::GCParallelTask::startWithLockHeld(AutoLockHelperThreadState& lock) { MOZ_ASSERT(CanUseExtraThreads()); - MOZ_ASSERT(HelperThreadState().threads); + MOZ_ASSERT(!HelperThreadState().threads(lock).empty()); assertIdle(); - HelperThreadState().gcParallelWorklist(lock).insertBack(this); setDispatched(lock); - - HelperThreadState().notifyOne(GlobalHelperThreadState::PRODUCER, lock); + HelperThreadState().submitTask(this, lock); } void js::GCParallelTask::start() { @@ -84,7 +83,7 @@ void js::GCParallelTask::joinWithLockHeld(AutoLockHelperThreadState& lock) { void js::GCParallelTask::joinRunningOrFinishedTask( AutoLockHelperThreadState& lock) { - MOZ_ASSERT(isRunning(lock) || isFinishing(lock) || isFinished(lock)); + MOZ_ASSERT(isRunning(lock) || isFinished(lock)); // Wait for the task to run to completion. while (!isFinished(lock)) { @@ -115,25 +114,25 @@ static inline TimeDuration TimeSince(TimeStamp prev) { void js::GCParallelTask::runFromMainThread() { assertIdle(); MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(gc->rt)); - runTask(); + AutoLockHelperThreadState lock; + runTask(lock); } -void js::GCParallelTask::runFromHelperThread(AutoLockHelperThreadState& lock) { +void js::GCParallelTask::runHelperThreadTask(AutoLockHelperThreadState& lock) { + TraceLoggerThread* logger = TraceLoggerForCurrentThread(); + AutoTraceLog logCompile(logger, TraceLogger_GC); + setRunning(lock); - { - AutoUnlockHelperThreadState parallelSection(lock); - AutoSetHelperThreadContext usesContext; - AutoSetContextRuntime ascr(gc->rt); - gc::AutoSetThreadIsPerformingGC performingGC; - runTask(); - } + AutoSetHelperThreadContext usesContext(lock); + AutoSetContextRuntime ascr(gc->rt); + gc::AutoSetThreadIsPerformingGC performingGC; + runTask(lock); setFinished(lock); - HelperThreadState().notifyAll(GlobalHelperThreadState::CONSUMER, lock); } -void GCParallelTask::runTask() { +void GCParallelTask::runTask(AutoLockHelperThreadState& lock) { // Run the task from either the main thread or a helper thread. // The hazard analysis can't tell what the call to func_ will do but it's not @@ -141,7 +140,7 @@ void GCParallelTask::runTask() { JS::AutoSuppressGCAnalysis nogc; TimeStamp timeStart = ReallyNow(); - run(); + run(lock); duration_ = TimeSince(timeStart); } @@ -156,11 +155,6 @@ bool js::GCParallelTask::wasStarted() const { } /* static */ -size_t js::gc::ParallelWorkerCount() { - if (!CanUseExtraThreads()) { - return 1; // GCRuntime::startTask will run the work on the main thread. - } - - size_t targetTaskCount = HelperThreadState().cpuCount / 2; - return mozilla::Clamp(targetTaskCount, size_t(1), MaxParallelWorkers); +size_t js::gc::GCRuntime::parallelWorkerCount() const { + return std::min(helperThreadCount.ref(), MaxParallelWorkers); } diff --git a/js/src/gc/GCParallelTask.h b/js/src/gc/GCParallelTask.h index 7ff015bda9..90821cde4f 100644 --- a/js/src/gc/GCParallelTask.h +++ b/js/src/gc/GCParallelTask.h @@ -6,12 +6,14 @@ #define gc_GCParallelTask_h #include "mozilla/LinkedList.h" -#include "mozilla/Move.h" #include "mozilla/TimeStamp.h" +#include + #include "js/TypeDecls.h" #include "js/Utility.h" #include "threading/ProtectedData.h" +#include "vm/HelperThreadTask.h" #define JS_MEMBER_FN_PTR_TYPE(ClassT, ReturnT, /* ArgTs */...) \ ReturnT (ClassT::*)(__VA_ARGS__) @@ -26,12 +28,12 @@ class GCRuntime; } class AutoLockHelperThreadState; -struct HelperThread; +class HelperThread; // A generic task used to dispatch work to the helper thread system. // Users override the pure-virtual run() method. class GCParallelTask : public mozilla::LinkedListElement, - public RunnableTask { + public HelperThreadTask { public: gc::GCRuntime* const gc; @@ -49,10 +51,6 @@ class GCParallelTask : public mozilla::LinkedListElement, // The task is currently running on a helper thread. Running, - // The task is currently running on a helper thread but has indicated that - // it will finish soon. - Finishing, - // The task has finished running but has not yet been joined by the main // thread. Finished @@ -130,22 +128,10 @@ class GCParallelTask : public mozilla::LinkedListElement, return state_ == State::Dispatched; } - ThreadType threadType() override { - return ThreadType::THREAD_TYPE_GCPARALLEL; - } protected: // Override this method to provide the task's functionality. - virtual void run() = 0; - - // Can be called to indicate that although the task is still running, it is - // about to finish. - void setFinishing(const AutoLockHelperThreadState& lock) { - MOZ_ASSERT(isIdle(lock) || isRunning(lock)); - if (isRunning(lock)) { - state_ = State::Finishing; - } - } + virtual void run(AutoLockHelperThreadState& lock) = 0; private: void assertIdle() const { @@ -156,9 +142,6 @@ class GCParallelTask : public mozilla::LinkedListElement, bool isRunning(const AutoLockHelperThreadState& lock) const { return state_ == State::Running; } - bool isFinishing(const AutoLockHelperThreadState& lock) const { - return state_ == State::Finishing; - } bool isFinished(const AutoLockHelperThreadState& lock) const { return state_ == State::Finished; } @@ -172,7 +155,7 @@ class GCParallelTask : public mozilla::LinkedListElement, state_ = State::Running; } void setFinished(const AutoLockHelperThreadState& lock) { - MOZ_ASSERT(isRunning(lock) || isFinishing(lock)); + MOZ_ASSERT(isRunning(lock)); state_ = State::Finished; } void setIdle(const AutoLockHelperThreadState& lock) { @@ -180,10 +163,13 @@ class GCParallelTask : public mozilla::LinkedListElement, state_ = State::Idle; } - void runTask() override; + void runTask(AutoLockHelperThreadState& lock); - friend struct HelperThread; - void runFromHelperThread(AutoLockHelperThreadState& locked); + // Implement the HelperThreadTask interface. + ThreadType threadType() override { + return ThreadType::THREAD_TYPE_GCPARALLEL; + } + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; }; } /* namespace js */ diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index b7f50da299..1e27c9c78a 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -10,6 +10,8 @@ #include "mozilla/Maybe.h" #include "mozilla/TimeStamp.h" +#include "jsfriendapi.h" // For PerformanceHint + #include "gc/ArenaList.h" #include "gc/AtomMarking.h" #include "gc/GCMarker.h" @@ -28,6 +30,7 @@ class AutoLockGC; class AutoLockGCBgAlloc; class AutoLockHelperThreadState; class FinalizationRegistryObject; +class FinalizationQueueObject; class VerifyPreTracer; class WeakRefObject; class ZoneAllocator; @@ -127,13 +130,13 @@ class ChunkPool { class BackgroundSweepTask : public GCParallelTask { public: explicit BackgroundSweepTask(GCRuntime* gc) : GCParallelTask(gc) {} - void run() override; + void run(AutoLockHelperThreadState& lock) override; }; class BackgroundFreeTask : public GCParallelTask { public: explicit BackgroundFreeTask(GCRuntime* gc) : GCParallelTask(gc) {} - void run() override; + void run(AutoLockHelperThreadState& lock) override; }; // Performs extra allocation off thread so that when memory is required on the @@ -148,21 +151,15 @@ class BackgroundAllocTask : public GCParallelTask { BackgroundAllocTask(GCRuntime* gc, ChunkPool& pool); bool enabled() const { return enabled_; } - void run() override; + void run(AutoLockHelperThreadState& lock) override; }; // Search the provided Chunks for free arenas and decommit them. class BackgroundDecommitTask : public GCParallelTask { public: - using ChunkVector = mozilla::Vector; - explicit BackgroundDecommitTask(GCRuntime* gc) : GCParallelTask(gc) {} - void setChunksToScan(ChunkVector& chunks); - - void run() override; - private: - MainThreadOrGCTaskData toDecommit; + void run(AutoLockHelperThreadState& lock) override; }; class SweepMarkTask : public GCParallelTask { @@ -170,7 +167,7 @@ class SweepMarkTask : public GCParallelTask { explicit SweepMarkTask(GCRuntime* gc) : GCParallelTask(gc), budget(SliceBudget::unlimited()) {} void setBudget(const SliceBudget& budget) { this->budget = budget; } - void run() override; + void run(AutoLockHelperThreadState& lock) override; private: SliceBudget budget; @@ -456,7 +453,7 @@ class GCRuntime { void setHostCleanupFinalizationRegistryCallback( JSHostCleanupFinalizationRegistryCallback callback, void* data); void callHostCleanupFinalizationRegistryCallback( - FinalizationRegistryObject* registry); + JSFunction* doCleanup, GlobalObject* incumbentGlobal); MOZ_MUST_USE bool addWeakPointerZonesCallback( JSWeakPointerZonesCallback callback, void* data); void removeWeakPointerZonesCallback(JSWeakPointerZonesCallback callback); @@ -474,8 +471,6 @@ class GCRuntime { FinalizationRegistryObject* registry); bool registerWithFinalizationRegistry(JSContext* cx, HandleObject target, HandleObject record); - bool cleanupQueuedFinalizationRegistry( - JSContext* cx, Handle registry); void setFullCompartmentChecks(bool enable); @@ -567,6 +562,12 @@ class GCRuntime { void checkHashTablesAfterMovingGC(); #endif +#ifdef DEBUG + // Crawl the heap to check whether an arbitary pointer is within a cell of + // the given kind. + bool isPointerWithinTenuredCell(void* ptr, JS::TraceKind traceKind); +#endif + // Queue memory memory to be freed on a background thread if possible. void queueUnusedLifoBlocksForFree(LifoAlloc* lifo); void queueAllLifoBlocksForFree(LifoAlloc* lifo); @@ -608,13 +609,14 @@ class GCRuntime { void joinTask(GCParallelTask& task, gcstats::PhaseKind phase, AutoLockHelperThreadState& locked); void joinTask(GCParallelTask& task, gcstats::PhaseKind phase); + void updateHelperThreadCount(); + size_t parallelWorkerCount() const; void mergeRealms(JS::Realm* source, JS::Realm* target); // WeakRefs bool registerWeakRef(HandleObject target, HandleObject weakRef); - bool unregisterWeakRef(JSContext* cx, JSObject* target, - js::WeakRefObject* weakRef); + bool unregisterWeakRefWrapper(JSObject* wrapper); void traceKeptObjects(JSTracer* trc); private: @@ -667,7 +669,7 @@ class GCRuntime { SliceBudget& budget); void checkZoneIsScheduled(Zone* zone, JS::GCReason reason, const char* trigger); - IncrementalResult resetIncrementalGC(AbortReason reason); + IncrementalResult resetIncrementalGC(GCAbortReason reason); // Assert if the system state is such that we should never // receive a request to do GC work. @@ -705,7 +707,8 @@ class GCRuntime { SliceBudget& budget); bool mightSweepInThisSlice(bool nonIncremental); bool mightCompactInThisSlice(bool nonIncremental); - void collectNursery(JS::GCReason reason, gcstats::PhaseKind phase); + void collectNursery(JSGCInvocationKind kind, JS::GCReason reason, + gcstats::PhaseKind phase); friend class AutoCallGCCallbacks; void maybeCallGCCallback(JSGCStatus status, JS::GCReason reason); @@ -725,7 +728,6 @@ class GCRuntime { void purgeSourceURLsForShrinkingGC(); void traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session); void traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess); - void traceKeptAtoms(JSTracer* trc); void traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark); void traceEmbeddingBlackRoots(JSTracer* trc); void traceEmbeddingGrayRoots(JSTracer* trc); @@ -771,8 +773,7 @@ class GCRuntime { void sweepJitDataOnMainThread(JSFreeOp* fop); void sweepFinalizationRegistriesOnMainThread(); void sweepFinalizationRegistries(Zone* zone); - void queueFinalizationRegistryForCleanup( - FinalizationRegistryObject* registry); + void queueFinalizationRegistryForCleanup(FinalizationQueueObject* queue); void sweepWeakRefs(); IncrementalProgress endSweepingSweepGroup(JSFreeOp* fop, SliceBudget& budget); IncrementalProgress performSweepActions(SliceBudget& sliceBudget); @@ -787,8 +788,9 @@ class GCRuntime { void endSweepPhase(bool lastGC); bool allCCVisibleZonesWereCollected(); void sweepZones(JSFreeOp* fop, bool destroyingRuntime); - void decommitFreeArenasWithoutUnlocking(const AutoLockGC& lock); void startDecommit(); + void decommitFreeArenas(const bool& canel, AutoLockGC& lock); + void decommitFreeArenasWithoutUnlocking(const AutoLockGC& lock); void queueZonesAndStartBackgroundSweep(ZoneList& zones); void sweepFromBackgroundThread(AutoLockHelperThreadState& lock); void startBackgroundFree(); @@ -821,6 +823,8 @@ class GCRuntime { void releaseRelocatedArenas(Arena* arenaList); void releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLockGC& lock); + IncrementalProgress waitForBackgroundTask(GCParallelTask& task, + SliceBudget& budget); void maybeRequestGCAfterBackgroundTask(const AutoLockHelperThreadState& lock); void cancelRequestedGCAfterBackgroundTask(); void finishCollection(); @@ -879,6 +883,11 @@ class GCRuntime { GCSchedulingTunables tunables; GCSchedulingState schedulingState; + // Helper thread configuration. + MainThreadData helperThreadRatio; + MainThreadData maxHelperThreads; + MainThreadData helperThreadCount; + // State used for managing atom mark bitmaps in each zone. AtomMarkingRuntime atomMarking; @@ -965,7 +974,7 @@ class GCRuntime { mozilla::Atomic majorGCTriggerReason; private: - /* Perform full GC if rt->keepAtoms() becomes false. */ + /* Perform full GC when we are able to collect the atoms zone. */ MainThreadData fullGCForAtomsRequested_; /* Incremented at the start of every minor GC. */ @@ -1058,7 +1067,6 @@ class GCRuntime { weakCachesToSweep; MainThreadData hasMarkedGrayRoots; MainThreadData abortSweepAfterCurrentGroup; - MainThreadData sweepMarkTaskStarted; MainThreadOrGCTaskData sweepMarkResult; #ifdef DEBUG diff --git a/js/src/gc/GenerateStatsPhases.py b/js/src/gc/GenerateStatsPhases.py index 1b96d86e01..9729509fcb 100644 --- a/js/src/gc/GenerateStatsPhases.py +++ b/js/src/gc/GenerateStatsPhases.py @@ -339,4 +339,4 @@ def name(phase): # Print in a comment the next available phase kind number. # out.write("// The next available phase kind number is: %d\n" % - (MaxBucket + 1)) + (MaxBucket + 1)) diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 30c734d040..31952561e0 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -5,7 +5,6 @@ #ifndef gc_Heap_h #define gc_Heap_h -#include "mozilla/Atomics.h" #include "mozilla/DebugOnly.h" #include "ds/BitArray.h" @@ -609,39 +608,37 @@ static_assert(ArenasPerChunk == 252, /* A chunk bitmap contains enough mark bits for all the cells in a chunk. */ struct ChunkBitmap { - volatile uintptr_t bitmap[ArenaBitmapWords * ArenasPerChunk]; - - public: - ChunkBitmap() = default; + static constexpr size_t WordCount = ArenaBitmapWords * ArenasPerChunk; + MarkBitmapWord bitmap[WordCount]; MOZ_ALWAYS_INLINE void getMarkWordAndMask(const TenuredCell* cell, ColorBit colorBit, - uintptr_t** wordp, + MarkBitmapWord** wordp, uintptr_t* maskp) { MOZ_ASSERT(size_t(colorBit) < MarkBitsPerCell); detail::GetGCThingMarkWordAndMask(uintptr_t(cell), colorBit, wordp, maskp); } - MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool markBit(const TenuredCell* cell, - ColorBit colorBit) { - uintptr_t *word, mask; + public: + ChunkBitmap() = default; + + MOZ_ALWAYS_INLINE bool markBit(const TenuredCell* cell, ColorBit colorBit) { + MarkBitmapWord* word; + uintptr_t mask; getMarkWordAndMask(cell, colorBit, &word, &mask); return *word & mask; } - MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool isMarkedAny( - const TenuredCell* cell) { + MOZ_ALWAYS_INLINE bool isMarkedAny(const TenuredCell* cell) { return markBit(cell, ColorBit::BlackBit) || markBit(cell, ColorBit::GrayOrBlackBit); } - MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool isMarkedBlack( - const TenuredCell* cell) { + MOZ_ALWAYS_INLINE bool isMarkedBlack(const TenuredCell* cell) { return markBit(cell, ColorBit::BlackBit); } - MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool isMarkedGray( - const TenuredCell* cell) { + MOZ_ALWAYS_INLINE bool isMarkedGray(const TenuredCell* cell) { return !markBit(cell, ColorBit::BlackBit) && markBit(cell, ColorBit::GrayOrBlackBit); } @@ -649,7 +646,8 @@ struct ChunkBitmap { // The return value indicates if the cell went from unmarked to marked. MOZ_ALWAYS_INLINE bool markIfUnmarked(const TenuredCell* cell, MarkColor color) { - uintptr_t *word, mask; + MarkBitmapWord* word; + uintptr_t mask; getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); if (*word & mask) { return false; @@ -671,17 +669,20 @@ struct ChunkBitmap { } MOZ_ALWAYS_INLINE void markBlack(const TenuredCell* cell) { - uintptr_t *word, mask; + MarkBitmapWord* word; + uintptr_t mask; getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); *word |= mask; } MOZ_ALWAYS_INLINE void copyMarkBit(TenuredCell* dst, const TenuredCell* src, ColorBit colorBit) { - uintptr_t *srcWord, srcMask; + MarkBitmapWord* srcWord; + uintptr_t srcMask; getMarkWordAndMask(src, colorBit, &srcWord, &srcMask); - uintptr_t *dstWord, dstMask; + MarkBitmapWord* dstWord; + uintptr_t dstMask; getMarkWordAndMask(dst, colorBit, &dstWord, &dstMask); *dstWord &= ~dstMask; @@ -691,23 +692,29 @@ struct ChunkBitmap { } MOZ_ALWAYS_INLINE void unmark(const TenuredCell* cell) { - uintptr_t *word, mask; + MarkBitmapWord* word; + uintptr_t mask; getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); *word &= ~mask; getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask); *word &= ~mask; } - void clear() { memset((void*)bitmap, 0, sizeof(bitmap)); } + void clear() { + for (size_t i = 0; i < WordCount; i++) { + bitmap[i] = 0; + } + } - uintptr_t* arenaBits(Arena* arena) { + MarkBitmapWord* arenaBits(Arena* arena) { static_assert( ArenaBitmapBits == ArenaBitmapWords * JS_BITS_PER_WORD, "We assume that the part of the bitmap corresponding to the arena " "has the exact number of words so we do not need to deal with a word " "that covers bits from two arenas."); - uintptr_t *word, unused; + MarkBitmapWord* word; + uintptr_t unused; getMarkWordAndMask(reinterpret_cast(arena->address()), ColorBit::BlackBit, &word, &unused); return word; diff --git a/js/src/gc/Marking-inl.h b/js/src/gc/Marking-inl.h index 33a806a086..59281d4d53 100644 --- a/js/src/gc/Marking-inl.h +++ b/js/src/gc/Marking-inl.h @@ -66,7 +66,8 @@ struct MightBeForwarded { std::is_base_of_v || std::is_base_of_v || std::is_base_of_v || std::is_base_of_v || std::is_base_of_v || - std::is_base_of_v; + std::is_base_of_v || + std::is_base_of_v; }; template @@ -104,32 +105,34 @@ inline T MaybeForwarded(T t) { return t; } -inline RelocatedCellHeader::RelocatedCellHeader(Cell* location, - uintptr_t flags) { - uintptr_t ptr = uintptr_t(location); - MOZ_ASSERT((ptr & RESERVED_MASK) == 0); - MOZ_ASSERT((flags & ~RESERVED_MASK) == 0); - header_ = ptr | flags | FORWARD_BIT; +inline const JSClass* MaybeForwardedObjectClass(const JSObject* obj) { + return MaybeForwarded(obj->groupRaw())->clasp(); +} + +template +inline bool MaybeForwardedObjectIs(JSObject* obj) { + MOZ_ASSERT(!obj->isForwarded()); + return MaybeForwardedObjectClass(obj) == &T::class_; +} + +template +inline T& MaybeForwardedObjectAs(JSObject* obj) { + MOZ_ASSERT(MaybeForwardedObjectIs(obj)); + return *static_cast(obj); } -inline RelocationOverlay::RelocationOverlay(Cell* dst, uintptr_t flags) - : header_(dst, flags) {} +inline RelocationOverlay::RelocationOverlay(Cell* dst) { + MOZ_ASSERT(dst->flags() == 0); + uintptr_t ptr = uintptr_t(dst); + MOZ_ASSERT((ptr & RESERVED_MASK) == 0); + header_ = ptr | FORWARD_BIT; +} /* static */ inline RelocationOverlay* RelocationOverlay::forwardCell(Cell* src, Cell* dst) { MOZ_ASSERT(!src->isForwarded()); MOZ_ASSERT(!dst->isForwarded()); - - // Preserve old flags because nursery may check them before checking - // if this is a forwarded Cell. - // - // This is pretty terrible and we should find a better way to implement - // Cell::getTraceKind() that doesn't rely on this behavior. - // - // The copied over flags are only used for nursery Cells, when the Cell is - // tenured, these bits are never read and hence may contain any content. - uintptr_t flags = reinterpret_cast(dst)->flags(); - return new (src) RelocationOverlay(dst, flags); + return new (src) RelocationOverlay(dst); } inline bool IsAboutToBeFinalizedDuringMinorSweep(Cell** cellp) { diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 43a76d70f1..178523ea6e 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -21,8 +21,10 @@ #include "builtin/ModuleObject.h" #include "debugger/DebugAPI.h" #include "gc/GCInternals.h" +#include "gc/GCProbes.h" #include "gc/Policy.h" #include "jit/JitCode.h" +#include "js/friend/DumpFunctions.h" // js::DumpObject #include "js/GCTypeMacros.h" // JS_FOR_EACH_PUBLIC_{,TAGGED_}GC_POINTER_TYPE #include "js/SliceBudget.h" #include "util/DiagnosticAssertions.h" @@ -31,7 +33,6 @@ #include "vm/ArgumentsObject.h" #include "vm/ArrayObject.h" #include "vm/BigIntType.h" -#include "vm/EnvironmentObject.h" #include "vm/GeneratorObject.h" #include "vm/RegExpShared.h" #include "vm/Scope.h" @@ -51,6 +52,8 @@ #include "vm/Realm-inl.h" #include "vm/StringType-inl.h" +#define MAX_DEDUPLICATABLE_STRING_LENGTH 500 + using namespace js; using namespace js::gc; @@ -165,17 +168,10 @@ bool js::IsTracerKind(JSTracer* trc, JS::CallbackTracer::TracerKind kind) { } #endif -bool ThingIsPermanentAtomOrWellKnownSymbol(JSString* str) { - return str->isPermanentAtom(); -} -bool ThingIsPermanentAtomOrWellKnownSymbol(JS::Symbol* sym) { - return sym->isWellKnownSymbol(); -} - template static inline bool IsOwnedByOtherRuntime(JSRuntime* rt, T thing) { bool other = thing->runtimeFromAnyThread() != rt; - MOZ_ASSERT_IF(other, ThingIsPermanentAtomOrWellKnownSymbol(thing) || + MOZ_ASSERT_IF(other, thing->isPermanentAndMayBeShared() || thing->zoneFromAnyThread()->isSelfHostingZone()); return other; } @@ -186,15 +182,6 @@ void js::CheckTracedThing(JSTracer* trc, T* thing) { MOZ_ASSERT(trc); MOZ_ASSERT(thing); - // Check that CellHeader is the first field in the cell. - static_assert( - std::is_base_of_vcellHeader())>>>, - "GC things must provide a cellHeader() method that returns a reference " - "to the cell header"); - MOZ_ASSERT(static_cast(&thing->cellHeader()) == - static_cast(thing)); - if (!trc->checkEdges()) { return; } @@ -605,7 +592,7 @@ template void js::TraceWeakMapKeyEdgeInternal(JSTracer*, Zone*, template void js::TraceProcessGlobalRoot(JSTracer* trc, T* thing, const char* name) { AssertRootMarkingPhase(trc); - MOZ_ASSERT(ThingIsPermanentAtomOrWellKnownSymbol(thing)); + MOZ_ASSERT(thing->isPermanentAndMayBeShared()); // We have to mark permanent atoms and well-known symbols through a special // method because the default DoMarking implementation automatically skips @@ -837,8 +824,7 @@ void GCMarker::severWeakDelegate(JSObject* key, JSObject* delegate) { // 'delegate' is now the delegate of 'key'. Update weakmap marking state. void GCMarker::restoreWeakDelegate(JSObject* key, JSObject* delegate) { if (!key->zone()->needsIncrementalBarrier() || - !delegate->zone()->needsIncrementalBarrier()) - { + !delegate->zone()->needsIncrementalBarrier()) { MOZ_ASSERT(!key->zone()->gcWeakKeys(key).get(key), "non-collecting zone should not have populated gcWeakKeys"); return; @@ -1014,7 +1000,7 @@ JS_PUBLIC_API void js::gc::PerformIncrementalReadBarrier(JS::GCCellPtr thing) { // tracing will not recurse. template void js::GCMarker::markAndTraceChildren(T* thing) { - if (ThingIsPermanentAtomOrWellKnownSymbol(thing)) { + if (thing->isPermanentAndMayBeShared()) { return; } if (mark(thing)) { @@ -1046,7 +1032,7 @@ void GCMarker::traverse(RegExpShared* thing) { // manual inlining, implemented by eagerlyTraceChildren. template void js::GCMarker::markAndScan(T* thing) { - if (ThingIsPermanentAtomOrWellKnownSymbol(thing)) { + if (thing->isPermanentAndMayBeShared()) { return; } if (mark(thing)) { @@ -1107,34 +1093,44 @@ void GCMarker::traverse(AccessorShape* thing) { } // namespace js template -static void CheckTraversedEdge(S source, T* target) { +static inline void CheckTraversedEdge(S source, T* target) { +#ifdef DEBUG // Atoms and Symbols do not have or mark their internal pointers, // respectively. - MOZ_ASSERT(!ThingIsPermanentAtomOrWellKnownSymbol(source)); + MOZ_ASSERT(!source->isPermanentAndMayBeShared()); + + if (target->isPermanentAndMayBeShared()) { + MOZ_ASSERT(!target->maybeCompartment()); + + // No further checks for parmanent/shared things. + return; + } + + Zone* sourceZone = source->zone(); + Zone* targetZone = target->zone(); + + // Atoms and Symbols do not have access to a compartment pointer, or we'd need + // to adjust the subsequent check to catch that case. + MOZ_ASSERT_IF(targetZone->isAtomsZone(), !target->maybeCompartment()); // The Zones must match, unless the target is an atom. - MOZ_ASSERT_IF( - !ThingIsPermanentAtomOrWellKnownSymbol(target), - target->zone()->isAtomsZone() || target->zone() == source->zone()); + MOZ_ASSERT(targetZone == sourceZone || targetZone->isAtomsZone()); // If we are marking an atom, that atom must be marked in the source zone's // atom bitmap. - MOZ_ASSERT_IF(!ThingIsPermanentAtomOrWellKnownSymbol(target) && - target->zone()->isAtomsZone() && - !source->zone()->isAtomsZone(), - target->runtimeFromAnyThread()->gc.atomMarking.atomIsMarked( - source->zone(), reinterpret_cast(target))); + if (!sourceZone->isAtomsZone() && targetZone->isAtomsZone()) { + // We can't currently check this if the helper thread lock is held. + if (!gHelperThreadLock.ownedByCurrentThread()) { + MOZ_ASSERT(target->runtimeFromAnyThread()->gc.atomMarking.atomIsMarked( + sourceZone, reinterpret_cast(target))); + } + } - // Atoms and Symbols do not have access to a compartment pointer, or we'd need - // to adjust the subsequent check to catch that case. - MOZ_ASSERT_IF(ThingIsPermanentAtomOrWellKnownSymbol(target), - !target->maybeCompartment()); - MOZ_ASSERT_IF(target->zoneFromAnyThread()->isAtomsZone(), - !target->maybeCompartment()); // If we have access to a compartment pointer for both things, they must // match. MOZ_ASSERT_IF(source->maybeCompartment() && target->maybeCompartment(), source->maybeCompartment() == target->maybeCompartment()); +#endif } template @@ -1226,7 +1222,7 @@ void BaseScript::traceChildren(JSTracer* trc) { } void Shape::traceChildren(JSTracer* trc) { - TraceEdge(trc, &headerAndBase_, "base"); + TraceCellHeaderEdge(trc, this, "base"); TraceEdge(trc, &propidRef(), "propid"); if (parent) { TraceEdge(trc, &parent, "parent"); @@ -1394,7 +1390,8 @@ static inline void TraceNullableBindingNames(JSTracer* trc, BindingName* names, } } }; -void BindingName::trace(JSTracer* trc) { +template <> +void AbstractBindingName::trace(JSTracer* trc) { if (JSAtom* atom = name()) { TraceManuallyBarrieredEdge(trc, &atom, "binding name"); } @@ -1402,36 +1399,44 @@ void BindingName::trace(JSTracer* trc) { void BindingIter::trace(JSTracer* trc) { TraceNullableBindingNames(trc, names_, length_); } -void LexicalScope::Data::trace(JSTracer* trc) { +template <> +void LexicalScope::AbstractData::trace(JSTracer* trc) { TraceBindingNames(trc, trailingNames.start(), length); } -void FunctionScope::Data::trace(JSTracer* trc) { +template <> +void FunctionScope::AbstractData::trace(JSTracer* trc) { TraceNullableEdge(trc, &canonicalFunction, "scope canonical function"); TraceNullableBindingNames(trc, trailingNames.start(), length); } -void VarScope::Data::trace(JSTracer* trc) { +template <> +void VarScope::AbstractData::trace(JSTracer* trc) { TraceBindingNames(trc, trailingNames.start(), length); } -void GlobalScope::Data::trace(JSTracer* trc) { +template <> +void GlobalScope::AbstractData::trace(JSTracer* trc) { TraceBindingNames(trc, trailingNames.start(), length); } -void EvalScope::Data::trace(JSTracer* trc) { +template <> +void EvalScope::AbstractData::trace(JSTracer* trc) { TraceBindingNames(trc, trailingNames.start(), length); } -void ModuleScope::Data::trace(JSTracer* trc) { +template <> +void ModuleScope::AbstractData::trace(JSTracer* trc) { TraceNullableEdge(trc, &module, "scope module"); TraceBindingNames(trc, trailingNames.start(), length); } -void WasmInstanceScope::Data::trace(JSTracer* trc) { +template <> +void WasmInstanceScope::AbstractData::trace(JSTracer* trc) { TraceNullableEdge(trc, &instance, "wasm instance"); TraceBindingNames(trc, trailingNames.start(), length); } -void WasmFunctionScope::Data::trace(JSTracer* trc) { +template <> +void WasmFunctionScope::AbstractData::trace(JSTracer* trc) { TraceBindingNames(trc, trailingNames.start(), length); } void Scope::traceChildren(JSTracer* trc) { - TraceNullableEdge(trc, &headerAndEnclosingScope_, "scope enclosing"); TraceNullableEdge(trc, &environmentShape_, "scope env shape"); + TraceNullableEdge(trc, &enclosingScope_, "scope enclosing"); applyScopeDataTyped([trc](auto data) { data->trace(trc); }); } inline void js::GCMarker::eagerlyMarkChildren(Scope* scope) { @@ -1439,7 +1444,7 @@ inline void js::GCMarker::eagerlyMarkChildren(Scope* scope) { if (scope->environmentShape()) { traverseEdge(scope, scope->environmentShape()); } - TrailingNamesArray* names = nullptr; + AbstractTrailingNamesArray* names = nullptr; uint32_t length = 0; switch (scope->kind()) { case ScopeKind::Function: { @@ -1464,7 +1469,8 @@ inline void js::GCMarker::eagerlyMarkChildren(Scope* scope) { case ScopeKind::Catch: case ScopeKind::NamedLambda: case ScopeKind::StrictNamedLambda: - case ScopeKind::FunctionLexical: { + case ScopeKind::FunctionLexical: + case ScopeKind::ClassBody: { LexicalScope::Data& data = scope->as().data(); names = &data.trailingNames; length = data.length; @@ -1489,7 +1495,9 @@ inline void js::GCMarker::eagerlyMarkChildren(Scope* scope) { case ScopeKind::Module: { ModuleScope::Data& data = scope->as().data(); - traverseObjectEdge(scope, data.module); + if (data.module) { + traverseObjectEdge(scope, data.module); + } names = &data.trailingNames; length = data.length; break; @@ -1559,12 +1567,13 @@ void js::ObjectGroup::traceChildren(JSTracer* trc) { if (JSObject* descr = maybeTypeDescr()) { TraceManuallyBarrieredEdge(trc, &descr, "group_type_descr"); - setTypeDescr(&descr->as()); + MOZ_ASSERT(js::IsTypeDescrClass(MaybeForwardedObjectClass(descr))); + setTypeDescr(static_cast(descr)); } if (JSObject* fun = maybeInterpretedFunction()) { TraceManuallyBarrieredEdge(trc, &fun, "group_function"); - setInterpretedFunction(&fun->as()); + setInterpretedFunction(&MaybeForwardedObjectAs(fun)); } } void js::GCMarker::lazilyMarkChildren(ObjectGroup* group) { @@ -1602,52 +1611,24 @@ void js::GCMarker::lazilyMarkChildren(ObjectGroup* group) { } } -void JS::BigInt::traceChildren(JSTracer* trc) { return; } +void JS::BigInt::traceChildren(JSTracer* trc) {} -template -static void VisitTraceList(const Functor& f, const uint32_t* traceList, - uint8_t* memory); - -// Call the trace hook set on the object, if present. If further tracing of -// NativeObject fields is required, this will return the native object. -enum class CheckGeneration { DoChecks, NoChecks }; -template -static inline NativeObject* CallTraceHook(Functor&& f, JSTracer* trc, - JSObject* obj, - CheckGeneration check) { +// Call the trace hook set on the object, if present. +static inline void CallTraceHook(JSTracer* trc, JSObject* obj) { const JSClass* clasp = obj->getClass(); MOZ_ASSERT(clasp); MOZ_ASSERT(obj->isNative() == clasp->isNative()); - if (!clasp->hasTrace()) { - return &obj->as(); + if (clasp->hasTrace()) { + AutoSetTracingSource asts(trc, obj); + clasp->doTrace(trc, obj); } - - if (clasp->isTrace(InlineTypedObject::obj_trace)) { - Shape** pshape = obj->as().addressOfShapeFromGC(); - f(pshape); - - InlineTypedObject& tobj = obj->as(); - if (tobj.typeDescr().hasTraceList()) { - VisitTraceList(f, tobj.typeDescr().traceList(), - tobj.inlineTypedMemForGC()); - } - - return nullptr; - } - - AutoSetTracingSource asts(trc, obj); - clasp->doTrace(trc, obj); - - if (!clasp->isNative()) { - return nullptr; - } - return &obj->as(); } template -static void VisitTraceList(const Functor& f, const uint32_t* traceList, - uint8_t* memory) { +static void VisitTraceListWithFunctor(const Functor& f, + const uint32_t* traceList, + uint8_t* memory) { size_t stringCount = *traceList++; size_t objectCount = *traceList++; size_t valueCount = *traceList++; @@ -1656,7 +1637,7 @@ static void VisitTraceList(const Functor& f, const uint32_t* traceList, traceList++; } for (size_t i = 0; i < objectCount; i++) { - JSObject** objp = reinterpret_cast(memory + *traceList); + auto** objp = reinterpret_cast(memory + *traceList); if (*objp) { f(objp); } @@ -1668,6 +1649,35 @@ static void VisitTraceList(const Functor& f, const uint32_t* traceList, } } +/* + * Trace TypedObject memory according to the layout specified by |traceList| + * with optimized paths for GC tracers. + * + * I'm not sure how much difference this makes versus calling TraceEdge for each + * edge; that at least has to dispatch on the tracer kind each time. + */ +void js::gc::VisitTraceList(JSTracer* trc, JSObject* obj, + const uint32_t* traceList, uint8_t* memory) { + if (trc->isMarkingTracer()) { + auto* marker = GCMarker::fromTracer(trc); + VisitTraceListWithFunctor([=](auto thingp) { DoMarking(marker, *thingp); }, + traceList, memory); + return; + } + + if (trc->isTenuringTracer()) { + auto* ttrc = static_cast(trc); + VisitTraceListWithFunctor([=](auto thingp) { ttrc->traverse(thingp); }, + traceList, memory); + return; + } + + VisitTraceListWithFunctor( + [=](auto thingp) { TraceEdgeInternal(trc, thingp, "TypedObject edge"); }, + traceList, memory); + return; +} + /*** Mark-stack Marking *****************************************************/ GCMarker::MarkQueueProgress GCMarker::processMarkQueue() { @@ -1826,10 +1836,6 @@ bool GCMarker::markUntilBudgetExhausted(SliceBudget& budget, // This method leaves the mark color as it found it. AutoSetMarkColor autoSetBlack(*this, MarkColor::Black); - // Change representation of value arrays on the stack while the mutator - // runs. - auto svr = mozilla::MakeScopeExit([&] { saveValueRanges(); }); - for (;;) { while (hasBlackEntries()) { MOZ_ASSERT(markColor() == MarkColor::Black); @@ -1941,23 +1947,58 @@ static inline void CheckForCompartmentMismatch(JSObject* obj, JSObject* obj2) { inline void GCMarker::processMarkStackTop(SliceBudget& budget) { /* - * The function uses explicit goto and implements the scanning of the - * object directly. It allows to eliminate the tail recursion and - * significantly improve the marking performance, see bug 641025. + * This function uses explicit goto and scans objects directly. This allows us + * to eliminate tail recursion and significantly improve the marking + * performance, see bug 641025. + * + * Note that the mutator can change the size and layout of objects between + * marking slices, so we must check slots and element ranges read from the + * stack. */ - HeapSlot* vp; - HeapSlot* end; - JSObject* obj; + + JSObject* obj; // The object being scanned. + RangeKind kind; // The kind of slot range being scanned, if any. + HeapSlot* base; // Slot range base pointer. + size_t index; // Index of the next slot to mark. + size_t end; // End of slot range to mark. gc::MarkStack& stack = currentStack(); switch (stack.peekTag()) { - case MarkStack::ValueArrayTag: { - auto array = stack.popValueArray(); - obj = array.ptr.asValueArrayObject(); - vp = array.start; - end = array.end; - goto scan_value_array; + case MarkStack::SlotsRangeTag: { + auto range = stack.popSlotsOrElementsRange(); + obj = range.ptr.asSlotsRangeObject(); + NativeObject* nobj = &obj->as(); + size_t nfixed = nobj->numFixedSlots(); + size_t nslots = nobj->slotSpan(); + if (range.start < nfixed) { + kind = RangeKind::FixedSlots; + base = nobj->fixedSlots(); + index = range.start; + end = std::min(nfixed, nslots); + } else { + kind = RangeKind::DynamicSlots; + base = nobj->slots_; + index = range.start - nfixed; + end = std::max(nslots, nfixed) - nfixed; + } + goto scan_value_range; + } + + case MarkStack::ElementsRangeTag: { + auto range = stack.popSlotsOrElementsRange(); + obj = range.ptr.asElementsRangeObject(); + NativeObject* nobj = &obj->as(); + kind = RangeKind::Elements; + base = nobj->getDenseElementsAllowCopyOnWrite(); + + // Account for shifted elements. + size_t numShifted = nobj->getElementsHeader()->numShiftedElements(); + size_t initlen = nobj->getDenseInitializedLength(); + index = std::max(range.start, numShifted) - numShifted; + end = initlen; + + goto scan_value_range; } case MarkStack::ObjectTag: { @@ -1983,32 +2024,22 @@ inline void GCMarker::processMarkStackTop(SliceBudget& budget) { return script->traceChildren(this); } - case MarkStack::SavedValueArrayTag: { - auto savedArray = stack.popSavedValueArray(); - JSObject* obj = savedArray.ptr.asSavedValueArrayObject(); - if (restoreValueArray(savedArray, &vp, &end)) { - pushValueArray(obj, vp, end); - } else { - repush(obj); - } - return; - } - default: MOZ_CRASH("Invalid tag in mark stack"); } return; -scan_value_array: - MOZ_ASSERT(vp <= end); - while (vp != end) { +scan_value_range: + while (index < end) { budget.step(); if (budget.isOverBudget()) { - pushValueArray(obj, vp, end); + pushValueRange(obj, kind, index, end); return; } - const Value& v = *vp++; + const Value& v = base[index]; + index++; + if (v.isString()) { traverseEdge(obj, v.toString()); } else if (v.isObject()) { @@ -2017,16 +2048,16 @@ inline void GCMarker::processMarkStackTop(SliceBudget& budget) { if (!obj2) { fprintf(stderr, "processMarkStackTop found ObjectValue(nullptr) " - "at %zu Values from end of array in object:\n", - size_t(end - (vp - 1))); + "at %zu Values from end of range in object:\n", + size_t(end - (index - 1))); DumpObject(obj); } #endif CheckForCompartmentMismatch(obj, obj2); if (mark(obj2)) { - // Save the rest of this value array for later and start scanning obj2's + // Save the rest of this value range for later and start scanning obj2's // children. - pushValueArray(obj, vp, end); + pushValueRange(obj, kind, index, end); obj = obj2; goto scan_obj; } @@ -2054,13 +2085,13 @@ scan_obj : { markImplicitEdges(obj); traverseEdge(obj, obj->groupRaw()); - NativeObject* nobj = CallTraceHook( - [this, obj](auto thingp) { this->traverseEdge(obj, *thingp); }, this, obj, - CheckGeneration::DoChecks); - if (!nobj) { + CallTraceHook(this, obj); + + if (!obj->isNative()) { return; } + NativeObject* nobj = &obj->as(); Shape* shape = nobj->lastProperty(); traverseEdge(obj, shape); @@ -2083,168 +2114,48 @@ scan_obj : { break; } - vp = nobj->getDenseElementsAllowCopyOnWrite(); - end = vp + nobj->getDenseInitializedLength(); + base = nobj->getDenseElementsAllowCopyOnWrite(); + kind = RangeKind::Elements; + index = 0; + end = nobj->getDenseInitializedLength(); if (!nslots) { - goto scan_value_array; + goto scan_value_range; } - pushValueArray(nobj, vp, end); + pushValueRange(nobj, kind, index, end); } while (false); - vp = nobj->fixedSlots(); - if (nobj->slots_) { - unsigned nfixed = nobj->numFixedSlots(); - if (nslots > nfixed) { - pushValueArray(nobj, vp, vp + nfixed); - vp = nobj->slots_; - end = vp + (nslots - nfixed); - goto scan_value_array; - } - } - MOZ_ASSERT(nslots <= nobj->numFixedSlots()); - end = vp + nslots; - goto scan_value_array; -} -} - -/* - * During incremental GC, we return from drainMarkStack without having processed - * the entire stack. At that point, JS code can run and reallocate slot arrays - * that are stored on the stack. To prevent this from happening, we replace all - * ValueArrayTag stack items with SavedValueArrayTag. In the latter, slots - * pointers are replaced with slot indexes, and slot array end pointers are - * replaced with the kind of index (properties vs. elements). - */ - -void GCMarker::saveValueRanges() { - gc::MarkStack* stacks[2] = {&stack, &auxStack}; - for (auto& stack : stacks) { - MarkStackIter iter(*stack); - while (!iter.done()) { - auto tag = iter.peekTag(); - if (tag == MarkStack::ValueArrayTag) { - const auto& array = iter.peekValueArray(); - auto savedArray = saveValueRange(array); - iter.saveValueArray(savedArray); - iter.nextArray(); - } else if (tag == MarkStack::SavedValueArrayTag) { - iter.nextArray(); - } else { - iter.nextPtr(); - } - } - - // This is also a convenient point to poison unused stack memory. - stack->poisonUnused(); - } -} - -bool GCMarker::restoreValueArray(const MarkStack::SavedValueArray& savedArray, - HeapSlot** vpp, HeapSlot** endp) { - JSObject* objArg = savedArray.ptr.asSavedValueArrayObject(); - if (!objArg->isNative()) { - return false; - } + unsigned nfixed = nobj->numFixedSlots(); - auto array = restoreValueArray(savedArray); - *vpp = array.start; - *endp = array.end; - return true; -} + base = nobj->fixedSlots(); + kind = RangeKind::FixedSlots; + index = 0; -MarkStack::SavedValueArray GCMarker::saveValueRange( - const MarkStack::ValueArray& array) { - NativeObject* obj = &array.ptr.asValueArrayObject()->as(); - MOZ_ASSERT(obj->isNative()); - - uintptr_t index; - HeapSlot::Kind kind; - HeapSlot* vp = obj->getDenseElementsAllowCopyOnWrite(); - if (array.end == vp + obj->getDenseInitializedLength()) { - MOZ_ASSERT(array.start >= vp); - // Add the number of shifted elements here (and subtract in - // restoreValueArray) to ensure shift() calls on the array - // are handled correctly. - index = obj->unshiftedIndex(array.start - vp); - kind = HeapSlot::Element; - } else { - HeapSlot* vp = obj->fixedSlots(); - unsigned nfixed = obj->numFixedSlots(); - if (array.start == array.end) { - index = obj->slotSpan(); - } else if (array.start >= vp && array.start < vp + nfixed) { - MOZ_ASSERT(array.end == vp + std::min(nfixed, obj->slotSpan())); - index = array.start - vp; - } else { - MOZ_ASSERT(array.start >= obj->slots_ && - array.end == obj->slots_ + obj->slotSpan() - nfixed); - index = (array.start - obj->slots_) + nfixed; - } - kind = HeapSlot::Slot; + if (nslots > nfixed) { + pushValueRange(nobj, kind, index, nfixed); + kind = RangeKind::DynamicSlots; + base = nobj->slots_; + end = nslots - nfixed; + goto scan_value_range; } - return MarkStack::SavedValueArray(obj, index, kind); + MOZ_ASSERT(nslots <= nobj->numFixedSlots()); + end = nslots; + goto scan_value_range; } - -MarkStack::ValueArray GCMarker::restoreValueArray( - const MarkStack::SavedValueArray& savedArray) { - NativeObject* obj = - &savedArray.ptr.asSavedValueArrayObject()->as(); - HeapSlot* start = nullptr; - HeapSlot* end = nullptr; - - uintptr_t index = savedArray.index; - if (savedArray.kind == HeapSlot::Element) { - uint32_t initlen = obj->getDenseInitializedLength(); - - // Account for shifted elements. - uint32_t numShifted = obj->getElementsHeader()->numShiftedElements(); - index = (numShifted < index) ? index - numShifted : 0; - - HeapSlot* vp = obj->getDenseElementsAllowCopyOnWrite(); - if (index < initlen) { - start = vp + index; - end = vp + initlen; - } else { - /* The object shrunk, in which case no scanning is needed. */ - start = end = vp; - } - } else { - MOZ_ASSERT(savedArray.kind == HeapSlot::Slot); - HeapSlot* vp = obj->fixedSlots(); - unsigned nfixed = obj->numFixedSlots(); - unsigned nslots = obj->slotSpan(); - if (index < nslots) { - if (index < nfixed) { - start = vp + index; - end = vp + std::min(nfixed, nslots); - } else { - start = obj->slots_ + index - nfixed; - end = obj->slots_ + nslots - nfixed; - } - } else { - /* The object shrunk, in which case no scanning is needed. */ - start = end = vp; - } - } - - return MarkStack::ValueArray(obj, start, end); } /*** Mark Stack *************************************************************/ static_assert(sizeof(MarkStack::TaggedPtr) == sizeof(uintptr_t), "A TaggedPtr should be the same size as a pointer"); -static_assert(sizeof(MarkStack::ValueArray) == - sizeof(MarkStack::SavedValueArray), - "ValueArray and SavedValueArray should be the same size"); -static_assert( - (sizeof(MarkStack::ValueArray) % sizeof(uintptr_t)) == 0, - "ValueArray and SavedValueArray should be multiples of the pointer size"); +static_assert((sizeof(MarkStack::SlotsOrElementsRange) % sizeof(uintptr_t)) == + 0, + "SlotsOrElementsRange size should be a multiple of " + "the pointer size"); -static const size_t ValueArrayWords = - sizeof(MarkStack::ValueArray) / sizeof(uintptr_t); +static const size_t ValueRangeWords = + sizeof(MarkStack::SlotsOrElementsRange) / sizeof(uintptr_t); template struct MapTypeToMarkStackTag {}; @@ -2265,9 +2176,8 @@ struct MapTypeToMarkStackTag { static const auto value = MarkStack::ScriptTag; }; -static inline bool TagIsArrayTag(MarkStack::Tag tag) { - return tag == MarkStack::ValueArrayTag || - tag == MarkStack::SavedValueArrayTag; +static inline bool TagIsRangeTag(MarkStack::Tag tag) { + return tag == MarkStack::SlotsRangeTag || tag == MarkStack::ElementsRangeTag; } inline MarkStack::TaggedPtr::TaggedPtr(Tag tag, Cell* ptr) @@ -2298,52 +2208,33 @@ inline T* MarkStack::TaggedPtr::as() const { return static_cast(ptr()); } -inline JSObject* MarkStack::TaggedPtr::asValueArrayObject() const { - MOZ_ASSERT(tag() == ValueArrayTag); +inline JSObject* MarkStack::TaggedPtr::asSlotsRangeObject() const { + MOZ_ASSERT(tag() == SlotsRangeTag); MOZ_ASSERT(ptr()->isTenured()); - MOZ_ASSERT(ptr()->is()); - return static_cast(ptr()); + return ptr()->as(); } -inline JSObject* MarkStack::TaggedPtr::asSavedValueArrayObject() const { - MOZ_ASSERT(tag() == SavedValueArrayTag); +inline JSObject* MarkStack::TaggedPtr::asElementsRangeObject() const { + MOZ_ASSERT(tag() == ElementsRangeTag); MOZ_ASSERT(ptr()->isTenured()); - MOZ_ASSERT(ptr()->is()); - return static_cast(ptr()); + return ptr()->as(); } inline JSRope* MarkStack::TaggedPtr::asTempRope() const { MOZ_ASSERT(tag() == TempRopeTag); - MOZ_ASSERT(ptr()->is()); - return static_cast(ptr()); + return &ptr()->as()->asRope(); } -inline MarkStack::ValueArray::ValueArray(JSObject* obj, HeapSlot* startArg, - HeapSlot* endArg) - : end(endArg), start(startArg), ptr(ValueArrayTag, obj) { +inline MarkStack::SlotsOrElementsRange::SlotsOrElementsRange(Tag tag, + JSObject* obj, + size_t startArg) + : start(startArg), ptr(tag, obj) { assertValid(); } -inline void MarkStack::ValueArray::assertValid() const { +inline void MarkStack::SlotsOrElementsRange::assertValid() const { ptr.assertValid(); - MOZ_ASSERT(ptr.tag() == MarkStack::ValueArrayTag); - MOZ_ASSERT(start); - MOZ_ASSERT(end); - MOZ_ASSERT(uintptr_t(start) <= uintptr_t(end)); - MOZ_ASSERT((uintptr_t(end) - uintptr_t(start)) % sizeof(Value) == 0); -} - -inline MarkStack::SavedValueArray::SavedValueArray(JSObject* obj, - size_t indexArg, - HeapSlot::Kind kindArg) - : kind(kindArg), index(indexArg), ptr(SavedValueArrayTag, obj) { - assertValid(); -} - -inline void MarkStack::SavedValueArray::assertValid() const { - ptr.assertValid(); - MOZ_ASSERT(ptr.tag() == MarkStack::SavedValueArrayTag); - MOZ_ASSERT(kind == HeapSlot::Slot || kind == HeapSlot::Element); + MOZ_ASSERT(TagIsRangeTag(ptr.tag())); } MarkStack::MarkStack(size_t maxCapacity) @@ -2432,35 +2323,25 @@ inline bool MarkStack::pushTempRope(JSRope* rope) { return pushTaggedPtr(TempRopeTag, rope); } -inline bool MarkStack::push(JSObject* obj, HeapSlot* start, HeapSlot* end) { - return push(ValueArray(obj, start, end)); -} - -inline bool MarkStack::push(const ValueArray& array) { - array.assertValid(); - - if (!ensureSpace(ValueArrayWords)) { - return false; +inline bool MarkStack::push(JSObject* obj, HeapSlot::Kind kind, size_t start) { + if (kind == HeapSlot::Slot) { + return push(SlotsOrElementsRange(SlotsRangeTag, obj, start)); } - *reinterpret_cast(topPtr()) = array; - topIndex_ += ValueArrayWords; - MOZ_ASSERT(position() <= capacity()); - MOZ_ASSERT(peekTag() == ValueArrayTag); - return true; + return push(SlotsOrElementsRange(ElementsRangeTag, obj, start)); } -inline bool MarkStack::push(const SavedValueArray& array) { +inline bool MarkStack::push(const SlotsOrElementsRange& array) { array.assertValid(); - if (!ensureSpace(ValueArrayWords)) { + if (!ensureSpace(ValueRangeWords)) { return false; } - *reinterpret_cast(topPtr()) = array; - topIndex_ += ValueArrayWords; + *reinterpret_cast(topPtr()) = array; + topIndex_ += ValueRangeWords; MOZ_ASSERT(position() <= capacity()); - MOZ_ASSERT(peekTag() == SavedValueArrayTag); + MOZ_ASSERT(TagIsRangeTag(peekTag())); return true; } @@ -2472,28 +2353,18 @@ inline MarkStack::Tag MarkStack::peekTag() const { return peekPtr().tag(); } inline MarkStack::TaggedPtr MarkStack::popPtr() { MOZ_ASSERT(!isEmpty()); - MOZ_ASSERT(!TagIsArrayTag(peekTag())); + MOZ_ASSERT(!TagIsRangeTag(peekTag())); peekPtr().assertValid(); topIndex_--; return *topPtr(); } -inline MarkStack::ValueArray MarkStack::popValueArray() { - MOZ_ASSERT(peekTag() == ValueArrayTag); - MOZ_ASSERT(position() >= ValueArrayWords); +inline MarkStack::SlotsOrElementsRange MarkStack::popSlotsOrElementsRange() { + MOZ_ASSERT(TagIsRangeTag(peekTag())); + MOZ_ASSERT(position() >= ValueRangeWords); - topIndex_ -= ValueArrayWords; - const auto& array = *reinterpret_cast(topPtr()); - array.assertValid(); - return array; -} - -inline MarkStack::SavedValueArray MarkStack::popSavedValueArray() { - MOZ_ASSERT(peekTag() == SavedValueArrayTag); - MOZ_ASSERT(position() >= ValueArrayWords); - - topIndex_ -= ValueArrayWords; - const auto& array = *reinterpret_cast(topPtr()); + topIndex_ -= ValueRangeWords; + const auto& array = *reinterpret_cast(topPtr()); array.assertValid(); return array; } @@ -2564,24 +2435,14 @@ inline MarkStack::TaggedPtr MarkStackIter::peekPtr() const { inline MarkStack::Tag MarkStackIter::peekTag() const { return peekPtr().tag(); } -inline MarkStack::ValueArray MarkStackIter::peekValueArray() const { - MOZ_ASSERT(peekTag() == MarkStack::ValueArrayTag); - MOZ_ASSERT(position() >= ValueArrayWords); - - const MarkStack::TaggedPtr* ptr = &stack_.stack()[pos_ - ValueArrayWords]; - const auto& array = *reinterpret_cast(ptr); - array.assertValid(); - return array; -} - inline void MarkStackIter::nextPtr() { MOZ_ASSERT(!done()); - MOZ_ASSERT(!TagIsArrayTag(peekTag())); + MOZ_ASSERT(!TagIsRangeTag(peekTag())); pos_--; } inline void MarkStackIter::next() { - if (TagIsArrayTag(peekTag())) { + if (TagIsRangeTag(peekTag())) { nextArray(); } else { nextPtr(); @@ -2589,22 +2450,9 @@ inline void MarkStackIter::next() { } inline void MarkStackIter::nextArray() { - MOZ_ASSERT(TagIsArrayTag(peekTag())); - MOZ_ASSERT(position() >= ValueArrayWords); - pos_ -= ValueArrayWords; -} - -void MarkStackIter::saveValueArray( - const MarkStack::SavedValueArray& savedArray) { - MOZ_ASSERT(peekTag() == MarkStack::ValueArrayTag); - MOZ_ASSERT(peekPtr().asValueArrayObject() == - savedArray.ptr.asSavedValueArrayObject()); - MOZ_ASSERT(position() >= ValueArrayWords); - - MarkStack::TaggedPtr* ptr = &stack_.stack()[pos_ - ValueArrayWords]; - auto dest = reinterpret_cast(ptr); - *dest = savedArray; - MOZ_ASSERT(peekTag() == MarkStack::SavedValueArrayTag); + MOZ_ASSERT(TagIsRangeTag(peekTag())); + MOZ_ASSERT(position() >= ValueRangeWords); + pos_ -= ValueRangeWords; } /*** GCMarker ***************************************************************/ @@ -2738,14 +2586,25 @@ void GCMarker::pushTaggedPtr(T* ptr) { } } -void GCMarker::pushValueArray(JSObject* obj, HeapSlot* start, HeapSlot* end) { +void GCMarker::pushValueRange(JSObject* obj, RangeKind kind, size_t start, + size_t end) { checkZone(obj); + MOZ_ASSERT(obj->is()); + MOZ_ASSERT(start <= end); if (start == end) { return; } - if (!currentStack().push(obj, start, end)) { + if (kind == RangeKind::DynamicSlots) { + uint32_t nfixed = obj->as().numFixedSlots(); + start += nfixed; + } + + HeapSlot::Kind slotsOrElements = + kind == RangeKind::Elements ? HeapSlot::Element : HeapSlot::Slot; + + if (!currentStack().push(obj, slotsOrElements, start)) { delayMarkingChildren(obj); } } @@ -3034,7 +2893,7 @@ void TenuringTracer::traverse(JSObject** objp) { // We only ever visit the internals of objects after moving them to tenured. MOZ_ASSERT(!nursery().isInside(objp)); - Cell** cellp = reinterpret_cast(objp); + auto** cellp = reinterpret_cast(objp); if (!IsInsideNursery(*cellp) || nursery().getForwardedPointer(cellp)) { return; } @@ -3055,7 +2914,7 @@ void TenuringTracer::traverse(JSString** strp) { // We only ever visit the internals of strings after moving them to tenured. MOZ_ASSERT(!nursery().isInside(strp)); - Cell** cellp = reinterpret_cast(strp); + auto** cellp = reinterpret_cast(strp); if (IsInsideNursery(*cellp) && !nursery().getForwardedPointer(cellp)) { *strp = moveToTenured(*strp); } @@ -3066,7 +2925,7 @@ void TenuringTracer::traverse(JS::BigInt** bip) { // We only ever visit the internals of BigInts after moving them to tenured. MOZ_ASSERT(!nursery().isInside(bip)); - Cell** cellp = reinterpret_cast(bip); + auto** cellp = reinterpret_cast(bip); if (IsInsideNursery(*cellp) && !nursery().getForwardedPointer(cellp)) { *bip = moveToTenured(*bip); } @@ -3132,7 +2991,7 @@ void js::gc::StoreBuffer::SlotsEdge::trace(TenuringTracer& mover) const { MOZ_ASSERT(clampedStart <= clampedEnd); mover.traceSlots( static_cast(obj->getDenseElements() + clampedStart) - ->unsafeUnbarrieredForTracing(), + ->unbarrieredAddress(), clampedEnd - clampedStart); } else { uint32_t start = std::min(start_, obj->slotSpan()); @@ -3143,10 +3002,85 @@ void js::gc::StoreBuffer::SlotsEdge::trace(TenuringTracer& mover) const { } static inline void TraceWholeCell(TenuringTracer& mover, JSObject* object) { + MOZ_ASSERT_IF(object->storeBuffer(), + !object->storeBuffer()->markingNondeduplicatable); mover.traceObject(object); } +// Non-deduplicatable marking is necessary because of the following 2 reasons: +// +// 1. Tenured string chars cannot be updated: +// +// If any of the tenured string's bases were deduplicated during tenuring, +// the tenured string's chars pointer would need to be adjusted. This would +// then require updating any other tenured strings that are dependent on the +// first tenured string, and we have no way to find them without scanning +// the entire tenured heap. +// +// 2. Tenured string cannot store its nursery base or base's chars: +// +// Tenured strings have no place to stash a pointer to their nursery base or +// its chars. You need to be able to traverse any dependent string's chain +// of bases up to a nursery "root base" that points to the malloced chars +// that the dependent strings started out pointing to, so that you can +// calculate the offset of any dependent string and update the ptr+offset if +// the root base gets deduplicated to a different allocation. Tenured +// strings in this base chain will stop you from reaching the nursery +// version of the root base; you can only get to the tenured version, and it +// has no place to store the original chars pointer. +static inline void PreventDeduplicationOfReachableStrings(JSString* str) { + MOZ_ASSERT(str->isTenured()); + MOZ_ASSERT(!str->isForwarded()); + + JSLinearString* baseOrRelocOverlay = str->nurseryBaseOrRelocOverlay(); + + // Walk along the chain of dependent strings' base string pointers + // to mark them all non-deduplicatable. + while (true) { + // baseOrRelocOverlay can be one of the three cases: + // 1. forwarded nursery string: + // The forwarded string still retains the flag that can tell whether + // this string is a dependent string with a base. Its + // StringRelocationOverlay holds a saved pointer to its base in the + // nursery. + // 2. not yet forwarded nursery string: + // Retrieve the base field directly from the string. + // 3. tenured string: + // The nursery base chain ends here, so stop traversing. + if (baseOrRelocOverlay->isForwarded()) { + JSLinearString* tenuredBase = Forwarded(baseOrRelocOverlay); + if (!tenuredBase->hasBase()) { + break; + } + baseOrRelocOverlay = StringRelocationOverlay::fromCell(baseOrRelocOverlay) + ->savedNurseryBaseOrRelocOverlay(); + } else { + JSLinearString* base = baseOrRelocOverlay; + if (base->isTenured()) { + break; + } + if (base->isDeduplicatable()) { + base->setNonDeduplicatable(); + } + if (!base->hasBase()) { + break; + } + baseOrRelocOverlay = base->nurseryBaseOrRelocOverlay(); + } + } +} + static inline void TraceWholeCell(TenuringTracer& mover, JSString* str) { + MOZ_ASSERT_IF(str->storeBuffer(), + str->storeBuffer()->markingNondeduplicatable); + + // Mark all strings reachable from the tenured string `str` as + // non-deduplicatable. These strings are the bases of the tenured dependent + // string. + if (str->hasBase()) { + PreventDeduplicationOfReachableStrings(str); + } + str->traceChildren(&mover); } @@ -3174,10 +3108,8 @@ static void TraceBufferedCells(TenuringTracer& mover, Arena* arena, } } -void js::gc::StoreBuffer::WholeCellBuffer::trace(TenuringTracer& mover) { - MOZ_ASSERT(owner_->isEnabled()); - - for (ArenaCellSet* cells = head_; cells; cells = cells->next) { +void ArenaCellSet::trace(TenuringTracer& mover) { + for (ArenaCellSet* cells = this; cells; cells = cells->next) { cells->check(); Arena* arena = cells->arena; @@ -3201,8 +3133,30 @@ void js::gc::StoreBuffer::WholeCellBuffer::trace(TenuringTracer& mover) { MOZ_CRASH("Unexpected trace kind"); } } +} + +void js::gc::StoreBuffer::WholeCellBuffer::trace(TenuringTracer& mover) { + MOZ_ASSERT(owner_->isEnabled()); + +#ifdef DEBUG + // Verify that all string whole cells are traced first before any other + // strings are visited for any reason. + MOZ_ASSERT(!owner_->markingNondeduplicatable); + owner_->markingNondeduplicatable = true; +#endif + // Trace all of the strings to mark the non-deduplicatable bits, then trace + // all other whole cells. + if (stringHead_) { + stringHead_->trace(mover); + } +#ifdef DEBUG + owner_->markingNondeduplicatable = false; +#endif + if (nonStringHead_) { + nonStringHead_->trace(mover); + } - head_ = nullptr; + stringHead_ = nonStringHead_ = nullptr; } template @@ -3218,6 +3172,14 @@ void js::gc::StoreBuffer::CellPtrEdge::trace(TenuringTracer& mover) const { MOZ_ASSERT(IsCellPointerValid(*edge)); MOZ_ASSERT((*edge)->getTraceKind() == JS::MapTypeToTraceKind::kind); + if (std::is_same_v) { + // Nursery string deduplication requires all tenured string -> nursery + // string edges to be registered with the whole cell buffer in order to + // correctly set the non-deduplicatable bit. + MOZ_ASSERT(!mover.runtime()->gc.isPointerWithinTenuredCell( + edge, JS::TraceKind::String)); + } + mover.traverse(edge); } @@ -3229,19 +3191,19 @@ void js::gc::StoreBuffer::ValueEdge::trace(TenuringTracer& mover) const { // Visit all object children of the object and trace them. void js::TenuringTracer::traceObject(JSObject* obj) { - NativeObject* nobj = - CallTraceHook([this](auto thingp) { this->traverse(thingp); }, this, obj, - CheckGeneration::NoChecks); - if (!nobj) { + CallTraceHook(this, obj); + + if (!obj->isNative()) { return; } // Note: the contents of copy on write elements pointers are filled in // during parsing and cannot contain nursery pointers. + NativeObject* nobj = &obj->as(); if (!nobj->hasEmptyElements() && !nobj->denseElementsAreCopyOnWrite() && ObjectDenseElementsMayBeMarkable(nobj)) { - Value* elems = static_cast(nobj->getDenseElements()) - ->unsafeUnbarrieredForTracing(); + HeapSlotArray elements = nobj->getDenseElements(); + Value* elems = elements.begin()->unbarrieredAddress(); traceSlots(elems, elems + nobj->getDenseInitializedLength()); } @@ -3256,12 +3218,11 @@ void js::TenuringTracer::traceObjectSlots(NativeObject* nobj, uint32_t start, HeapSlot* dynEnd; nobj->getSlotRange(start, length, &fixedStart, &fixedEnd, &dynStart, &dynEnd); if (fixedStart) { - traceSlots(fixedStart->unsafeUnbarrieredForTracing(), - fixedEnd->unsafeUnbarrieredForTracing()); + traceSlots(fixedStart->unbarrieredAddress(), + fixedEnd->unbarrieredAddress()); } if (dynStart) { - traceSlots(dynStart->unsafeUnbarrieredForTracing(), - dynEnd->unsafeUnbarrieredForTracing()); + traceSlots(dynStart->unbarrieredAddress(), dynEnd->unbarrieredAddress()); } } @@ -3302,6 +3263,15 @@ inline T* js::TenuringTracer::allocTenured(Zone* zone, AllocKind kind) { return static_cast(static_cast(AllocateCellInGC(zone, kind))); } +JSString* js::TenuringTracer::allocTenuredString(JSString* src, Zone* zone, + AllocKind dstKind) { + JSString* dst = allocTenured(zone, dstKind); + tenuredSize += moveStringToTenured(dst, src, dstKind); + tenuredCells++; + + return dst; +} + JSObject* js::TenuringTracer::moveToTenuredSlow(JSObject* src) { MOZ_ASSERT(IsInsideNursery(src)); MOZ_ASSERT(!src->nurseryZone()->usedByHelperThread()); @@ -3419,24 +3389,30 @@ size_t js::TenuringTracer::moveSlotsToTenured(NativeObject* dst, size_t count = src->numDynamicSlots(); if (!nursery().isInside(src->slots_)) { - AddCellMemory(dst, count * sizeof(HeapSlot), MemoryUse::ObjectSlots); - nursery().removeMallocedBufferDuringMinorGC(src->slots_); + AddCellMemory(dst, ObjectSlots::allocSize(count), MemoryUse::ObjectSlots); + nursery().removeMallocedBufferDuringMinorGC(src->getSlotsHeader()); return 0; } { AutoEnterOOMUnsafeRegion oomUnsafe; - dst->slots_ = zone->pod_malloc(count); - if (!dst->slots_) { - oomUnsafe.crash(sizeof(HeapSlot) * count, + HeapSlot* allocation = + zone->pod_malloc(ObjectSlots::allocCount(count)); + if (!allocation) { + oomUnsafe.crash(ObjectSlots::allocSize(count), "Failed to allocate slots while tenuring."); } + + ObjectSlots* slotsHeader = new (allocation) + ObjectSlots(count, src->getSlotsHeader()->dictionarySlotSpan()); + dst->slots_ = slotsHeader->slots(); } - AddCellMemory(dst, count * sizeof(HeapSlot), MemoryUse::ObjectSlots); + AddCellMemory(dst, ObjectSlots::allocSize(count), MemoryUse::ObjectSlots); PodCopy(dst->slots_, src->slots_, count); nursery().setSlotsForwardingPointer(src->slots_, dst->slots_, count); + return count * sizeof(HeapSlot); } @@ -3501,7 +3477,7 @@ size_t js::TenuringTracer::moveElementsToTenured(NativeObject* dst, } inline void js::TenuringTracer::insertIntoStringFixupList( - RelocationOverlay* entry) { + StringRelocationOverlay* entry) { *stringTail = entry; stringTail = &entry->nextRef(); *stringTail = nullptr; @@ -3510,22 +3486,149 @@ inline void js::TenuringTracer::insertIntoStringFixupList( JSString* js::TenuringTracer::moveToTenured(JSString* src) { MOZ_ASSERT(IsInsideNursery(src)); MOZ_ASSERT(!src->nurseryZone()->usedByHelperThread()); + MOZ_ASSERT(!src->isExternal()); AllocKind dstKind = src->getAllocKind(); Zone* zone = src->nurseryZone(); zone->tenuredStrings++; - JSString* dst = allocTenured(zone, dstKind); - tenuredSize += moveStringToTenured(dst, src, dstKind); - tenuredCells++; + // If this string is in the StringToAtomCache, try to deduplicate it by using + // the atom. Don't do this for dependent strings because they're more + // complicated. See StringRelocationOverlay and DeduplicationStringHasher + // comments. + if (src->inStringToAtomCache() && src->isDeduplicatable() && + !src->hasBase()) { + JSLinearString* linear = &src->asLinear(); + JSAtom* atom = runtime()->caches().stringToAtomCache.lookup(linear); + MOZ_ASSERT(atom, "Why was the cache purged before minor GC?"); + + // Only deduplicate if both strings have the same encoding, to not confuse + // dependent strings. + if (src->hasTwoByteChars() == atom->hasTwoByteChars()) { + // The StringToAtomCache isn't used for inline strings (due to the minimum + // length) so canOwnDependentChars must be true for both src and atom. + // This means if there are dependent strings floating around using str's + // chars, they will be able to use the chars from the atom. + static_assert(StringToAtomCache::MinStringLength > + JSFatInlineString::MAX_LENGTH_LATIN1); + static_assert(StringToAtomCache::MinStringLength > + JSFatInlineString::MAX_LENGTH_TWO_BYTE); + MOZ_ASSERT(src->canOwnDependentChars()); + MOZ_ASSERT(atom->canOwnDependentChars()); + + StringRelocationOverlay::forwardCell(src, atom); + gcprobes::PromoteToTenured(src, atom); + return atom; + } + } - RelocationOverlay* overlay = RelocationOverlay::forwardCell(src, dst); + JSString* dst; + + // A live nursery string can only get deduplicated when: + // 1. Its length is smaller than MAX_DEDUPLICATABLE_STRING_LENGTH: + // Hashing a long string can affect performance. + // 2. It is linear: + // Deduplicating every node in it would end up doing O(n^2) hashing work. + // 3. It is deduplicatable: + // The JSString NON_DEDUP_BIT flag is unset. + // 4. It matches an entry in stringDeDupSet. + + if (src->length() < MAX_DEDUPLICATABLE_STRING_LENGTH && src->isLinear() && + src->isDeduplicatable() && nursery().stringDeDupSet.isSome()) { + if (auto p = nursery().stringDeDupSet->lookup(src)) { + // Deduplicate to the looked-up string! + dst = *p; + StringRelocationOverlay::forwardCell(src, dst); + gcprobes::PromoteToTenured(src, dst); + return dst; + } + + dst = allocTenuredString(src, zone, dstKind); + + if (!nursery().stringDeDupSet->putNew(dst)) { + // When there is oom caused by the stringDeDupSet, stop deduplicating + // strings. + nursery().stringDeDupSet.reset(); + } + } else { + dst = allocTenuredString(src, zone, dstKind); + dst->clearNonDeduplicatable(); + } + + auto* overlay = StringRelocationOverlay::forwardCell(src, dst); + MOZ_ASSERT(dst->isDeduplicatable()); + // The base root might be deduplicated, so the non-inlined chars might no + // longer be valid. Insert the overlay into this list to relocate it later. insertIntoStringFixupList(overlay); gcprobes::PromoteToTenured(src, dst); return dst; } +template +void js::Nursery::relocateDependentStringChars( + JSDependentString* tenuredDependentStr, JSLinearString* baseOrRelocOverlay, + size_t* offset, bool* rootBaseNotYetForwarded, JSLinearString** rootBase) { + MOZ_ASSERT(*offset == 0); + MOZ_ASSERT(*rootBaseNotYetForwarded == false); + MOZ_ASSERT(*rootBase == nullptr); + + JS::AutoCheckCannotGC nogc; + + const CharT* dependentStrChars = + tenuredDependentStr->nonInlineChars(nogc); + + // Traverse the dependent string nursery base chain to find the base that + // it's using chars from. + while (true) { + if (baseOrRelocOverlay->isForwarded()) { + JSLinearString* tenuredBase = Forwarded(baseOrRelocOverlay); + StringRelocationOverlay* relocOverlay = + StringRelocationOverlay::fromCell(baseOrRelocOverlay); + + if (!tenuredBase->hasBase()) { + // The nursery root base is relocOverlay, it is tenured to tenuredBase. + // Relocate tenuredDependentStr chars and reassign the tenured root base + // as its base. + JSLinearString* tenuredRootBase = tenuredBase; + const CharT* rootBaseChars = relocOverlay->savedNurseryChars(); + *offset = dependentStrChars - rootBaseChars; + MOZ_ASSERT(*offset < tenuredRootBase->length()); + tenuredDependentStr->relocateNonInlineChars( + tenuredRootBase->nonInlineChars(nogc), *offset); + tenuredDependentStr->setBase(tenuredRootBase); + return; + } + + baseOrRelocOverlay = relocOverlay->savedNurseryBaseOrRelocOverlay(); + + } else { + JSLinearString* base = baseOrRelocOverlay; + + if (!base->hasBase()) { + // The root base is not forwarded yet, it is simply base. + *rootBase = base; + + // The root base can be in either the nursery or the tenured heap. + // dependentStr chars needs to be relocated after traceString if the + // root base is in the nursery. + if (!(*rootBase)->isTenured()) { + *rootBaseNotYetForwarded = true; + const CharT* rootBaseChars = (*rootBase)->nonInlineChars(nogc); + *offset = dependentStrChars - rootBaseChars; + MOZ_ASSERT(*offset < base->length(), "Tenured root base"); + } + + tenuredDependentStr->setBase(*rootBase); + + return; + } + + baseOrRelocOverlay = base->nurseryBaseOrRelocOverlay(); + } + } +} + inline void js::TenuringTracer::insertIntoBigIntFixupList( RelocationOverlay* entry) { *bigIntTail = entry; @@ -3555,7 +3658,7 @@ JS::BigInt* js::TenuringTracer::moveToTenured(JS::BigInt* src) { void js::Nursery::collectToFixedPoint(TenuringTracer& mover, TenureCountCache& tenureCounts) { for (RelocationOverlay* p = mover.objHead; p; p = p->next()) { - JSObject* obj = static_cast(p->forwardingAddress()); + auto* obj = static_cast(p->forwardingAddress()); mover.traceObject(obj); TenureCount& entry = tenureCounts.findEntry(obj->groupRaw()); @@ -3567,8 +3670,50 @@ void js::Nursery::collectToFixedPoint(TenuringTracer& mover, } } - for (RelocationOverlay* p = mover.stringHead; p; p = p->next()) { - mover.traceString(static_cast(p->forwardingAddress())); + for (StringRelocationOverlay* p = mover.stringHead; p; p = p->next()) { + auto* tenuredStr = static_cast(p->forwardingAddress()); + // To ensure the NON_DEDUP_BIT was reset properly. + MOZ_ASSERT(tenuredStr->isDeduplicatable()); + + // The nursery root base might not be forwarded before + // traceString(tenuredStr). traceString(tenuredStr) will forward the root + // base if that's the case. Dependent string chars needs to be relocated + // after traceString if root base was not forwarded. + size_t offset = 0; + bool rootBaseNotYetForwarded = false; + JSLinearString* rootBase = nullptr; + + if (tenuredStr->isDependent()) { + if (tenuredStr->hasTwoByteChars()) { + relocateDependentStringChars( + &tenuredStr->asDependent(), p->savedNurseryBaseOrRelocOverlay(), + &offset, &rootBaseNotYetForwarded, &rootBase); + } else { + relocateDependentStringChars( + &tenuredStr->asDependent(), p->savedNurseryBaseOrRelocOverlay(), + &offset, &rootBaseNotYetForwarded, &rootBase); + } + } + + mover.traceString(tenuredStr); + + if (rootBaseNotYetForwarded) { + MOZ_ASSERT(rootBase->isForwarded(), + "traceString() should make it forwarded"); + JS::AutoCheckCannotGC nogc; + + JSLinearString* tenuredRootBase = Forwarded(rootBase); + MOZ_ASSERT(offset < tenuredRootBase->length()); + + if (tenuredStr->hasTwoByteChars()) { + tenuredStr->asDependent().relocateNonInlineChars( + tenuredRootBase->twoByteChars(nogc), offset); + } else { + tenuredStr->asDependent().relocateNonInlineChars( + tenuredRootBase->latin1Chars(nogc), offset); + } + tenuredStr->setBase(tenuredRootBase); + } } for (RelocationOverlay* p = mover.bigIntHead; p; p = p->next()) { @@ -3655,7 +3800,7 @@ static inline void CheckIsMarkedThing(T* thingp) { // Allow any thread access to uncollected things. T thing = *thingp; - if (ThingIsPermanentAtomOrWellKnownSymbol(thing)) { + if (thing->isPermanentAndMayBeShared()) { return; } @@ -3715,7 +3860,7 @@ bool js::gc::IsMarkedInternal(JSRuntime* rt, T** thingp) { if (MightBeNurseryAllocated::value && IsInsideNursery(*thingp)) { MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); - Cell** cellp = reinterpret_cast(thingp); + auto** cellp = reinterpret_cast(thingp); return Nursery::getForwardedPointer(cellp); } @@ -3726,16 +3871,6 @@ bool js::gc::IsMarkedInternal(JSRuntime* rt, T** thingp) { return (*thingp)->asTenured().isMarkedAny(); } -bool js::gc::IsAboutToBeFinalizedDuringSweep(TenuredCell& tenured) { - MOZ_ASSERT(!IsInsideNursery(&tenured)); - MOZ_ASSERT(tenured.zoneFromAnyThread()->isGCSweeping()); - - // Don't depend on the mark state of other cells during finalization. - MOZ_ASSERT(!CurrentThreadIsGCFinalizing()); - - return !tenured.isMarkedAny(); -} - template bool js::gc::IsAboutToBeFinalizedInternal(T** thingp) { // Don't depend on the mark state of other cells during finalization. @@ -3746,7 +3881,7 @@ bool js::gc::IsAboutToBeFinalizedInternal(T** thingp) { JSRuntime* rt = thing->runtimeFromAnyThread(); /* Permanent atoms are never finalized by non-owning runtimes. */ - if (ThingIsPermanentAtomOrWellKnownSymbol(thing) && + if (thing->isPermanentAndMayBeShared() && TlsContext.get()->runtime() != rt) { return false; } @@ -3758,8 +3893,10 @@ bool js::gc::IsAboutToBeFinalizedInternal(T** thingp) { Zone* zone = thing->asTenured().zoneFromAnyThread(); if (zone->isGCSweeping()) { - return IsAboutToBeFinalizedDuringSweep(thing->asTenured()); - } else if (zone->isGCCompacting() && IsForwarded(thing)) { + return !thing->asTenured().isMarkedAny(); + } + + if (zone->isGCCompacting() && IsForwarded(thing)) { *thingp = Forwarded(thing); return false; } @@ -3786,7 +3923,7 @@ inline bool SweepingTracer::sweepEdge(T** thingp) { T* thing = *thingp; JSRuntime* rt = thing->runtimeFromAnyThread(); - if (ThingIsPermanentAtomOrWellKnownSymbol(thing) && runtime() != rt) { + if (thing->isPermanentAndMayBeShared() && runtime() != rt) { return true; } @@ -4033,6 +4170,10 @@ JS_FRIEND_API bool JS::UnmarkGrayGCThingRecursively(JS::GCCellPtr thing) { return UnmarkGrayGCThingUnchecked(rt, thing); } +void js::gc::UnmarkGrayGCThingRecursively(TenuredCell* cell) { + JS::UnmarkGrayGCThingRecursively(JS::GCCellPtr(cell, cell->getTraceKind())); +} + bool js::UnmarkGrayShapeRecursively(Shape* shape) { return JS::UnmarkGrayGCThingRecursively(JS::GCCellPtr(shape)); } @@ -4064,11 +4205,11 @@ uintptr_t* GetMarkWordAddress(Cell* cell) { return nullptr; } - uintptr_t* wordp; + MarkBitmapWord* wordp; uintptr_t mask; js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), ColorBit::BlackBit, &wordp, &mask); - return wordp; + return reinterpret_cast(wordp); } uintptr_t GetMarkMask(Cell* cell, uint32_t colorBit) { @@ -4079,7 +4220,7 @@ uintptr_t GetMarkMask(Cell* cell, uint32_t colorBit) { } ColorBit bit = colorBit == 0 ? ColorBit::BlackBit : ColorBit::GrayOrBlackBit; - uintptr_t* wordp; + MarkBitmapWord* wordp; uintptr_t mask; js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), bit, &wordp, &mask); diff --git a/js/src/gc/Marking.h b/js/src/gc/Marking.h index 5efbe47032..44fdfb8664 100644 --- a/js/src/gc/Marking.h +++ b/js/src/gc/Marking.h @@ -16,6 +16,7 @@ class JSLinearString; class JSRope; class JSTracer; +struct JSClass; namespace js { class BaseShape; @@ -71,8 +72,7 @@ inline bool IsMarkedUnbarriered(JSRuntime* rt, T* thingp) { // are always reported as being marked. template inline bool IsMarked(JSRuntime* rt, BarrieredBase* thingp) { - return IsMarkedInternal(rt, - ConvertToBase(thingp->unsafeUnbarrieredForTracing())); + return IsMarkedInternal(rt, ConvertToBase(thingp->unbarrieredAddress())); } template @@ -83,17 +83,15 @@ inline bool IsAboutToBeFinalizedUnbarriered(T* thingp) { template inline bool IsAboutToBeFinalized(const WriteBarriered* thingp) { return IsAboutToBeFinalizedInternal( - ConvertToBase(thingp->unsafeUnbarrieredForTracing())); + ConvertToBase(thingp->unbarrieredAddress())); } template inline bool IsAboutToBeFinalized(ReadBarriered* thingp) { return IsAboutToBeFinalizedInternal( - ConvertToBase(thingp->unsafeUnbarrieredForTracing())); + ConvertToBase(thingp->unbarrieredAddress())); } -bool IsAboutToBeFinalizedDuringSweep(TenuredCell& tenured); - inline bool IsAboutToBeFinalizedDuringMinorSweep(Cell* cell); inline Cell* ToMarkable(const Value& v) { @@ -146,6 +144,22 @@ inline Value Forwarded(const JS::Value& value); template inline T MaybeForwarded(T t); +// Helper functions for use in situations where the object's group might be +// forwarded, for example while marking. + +inline const JSClass* MaybeForwardedObjectClass(const JSObject* obj); + +template +inline bool MaybeForwardedObjectIs(JSObject* obj); + +template +inline T& MaybeForwardedObjectAs(JSObject* obj); + +// Trace TypedObject trace lists with specialised paths for GCMarker and +// TenuringTracer. +void VisitTraceList(JSTracer* trc, JSObject* obj, const uint32_t* traceList, + uint8_t* memory); + #ifdef JSGC_HASH_TABLE_CHECKS template diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp index f8d1b6e1a2..a8e469a8ab 100644 --- a/js/src/gc/Memory.cpp +++ b/js/src/gc/Memory.cpp @@ -694,9 +694,9 @@ static bool TryToAlignChunk(void** aRegion, void** aRetainedRegion, break; } } else { - void* lowerStart = + auto* lowerStart = reinterpret_cast(uintptr_t(regionStart) - offsetLower); - void* lowerEnd = reinterpret_cast(uintptr_t(lowerStart) + length); + auto* lowerEnd = reinterpret_cast(uintptr_t(lowerStart) + length); if (MapMemoryAt(lowerStart, offsetLower)) { UnmapInternal(lowerEnd, offsetLower); if (directionUncertain) { diff --git a/js/src/gc/Nursery-inl.h b/js/src/gc/Nursery-inl.h index 9bd022e440..874303f3b3 100644 --- a/js/src/gc/Nursery-inl.h +++ b/js/src/gc/Nursery-inl.h @@ -98,7 +98,8 @@ namespace js { template static inline T* AllocateObjectBuffer(JSContext* cx, uint32_t count) { size_t nbytes = RoundUp(count * sizeof(T), sizeof(Value)); - T* buffer = static_cast(cx->nursery().allocateBuffer(cx->zone(), nbytes)); + auto* buffer = + static_cast(cx->nursery().allocateBuffer(cx->zone(), nbytes)); if (!buffer) { ReportOutOfMemory(cx); } @@ -112,7 +113,7 @@ static inline T* AllocateObjectBuffer(JSContext* cx, JSObject* obj, return cx->pod_malloc(count); } size_t nbytes = RoundUp(count * sizeof(T), sizeof(Value)); - T* buffer = static_cast(cx->nursery().allocateBuffer(obj, nbytes)); + auto* buffer = static_cast(cx->nursery().allocateBuffer(obj, nbytes)); if (!buffer) { ReportOutOfMemory(cx); } @@ -127,7 +128,7 @@ static inline T* ReallocateObjectBuffer(JSContext* cx, JSObject* obj, if (cx->isHelperThreadContext()) { return obj->zone()->pod_realloc(oldBuffer, oldCount, newCount); } - T* buffer = static_cast(cx->nursery().reallocateBuffer( + auto* buffer = static_cast(cx->nursery().reallocateBuffer( obj->zone(), obj, oldBuffer, oldCount * sizeof(T), newCount * sizeof(T))); if (!buffer) { ReportOutOfMemory(cx); diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 3b57111dec..82d5018864 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -6,10 +6,12 @@ #include "mozilla/DebugOnly.h" #include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/Move.h" +#include "mozilla/ScopeExit.h" #include "mozilla/Unused.h" #include +#include +#include #include "builtin/MapObject.h" #include "debugger/DebugAPI.h" @@ -22,9 +24,6 @@ #include "jit/JitRealm.h" #include "util/Poison.h" #include "vm/ArrayObject.h" -#if defined(DEBUG) -# include "vm/EnvironmentObject.h" -#endif #include "vm/JSONPrinter.h" #include "vm/Realm.h" #include "vm/Time.h" @@ -88,7 +87,7 @@ inline void js::NurseryChunk::poisonRange(size_t from, size_t size, MOZ_ASSERT(from <= js::Nursery::NurseryChunkUsableSize); MOZ_ASSERT(from + size <= ChunkSize); - uint8_t* start = reinterpret_cast(this) + from; + auto* start = reinterpret_cast(this) + from; // We can poison the same chunk more than once, so first make sure memory // sanitizers will let us poison it. @@ -118,7 +117,7 @@ inline js::NurseryChunk* js::NurseryChunk::fromChunk(Chunk* chunk) { } inline Chunk* js::NurseryChunk::toChunk(GCRuntime* gc) { - auto chunk = reinterpret_cast(this); + auto* chunk = reinterpret_cast(this); chunk->init(gc); return chunk; } @@ -163,26 +162,19 @@ Chunk* js::NurseryDecommitTask::popChunk( return chunk; } -void js::NurseryDecommitTask::run() { +void js::NurseryDecommitTask::run(AutoLockHelperThreadState& lock) { Chunk* chunk; - - { - AutoLockHelperThreadState lock; - - while ((chunk = popChunk(lock)) || partialChunk) { - if (chunk) { - AutoUnlockHelperThreadState unlock(lock); - decommitChunk(chunk); - continue; - } - - if (partialChunk) { - decommitRange(lock); - continue; - } + while ((chunk = popChunk(lock)) || partialChunk) { + if (chunk) { + AutoUnlockHelperThreadState unlock(lock); + decommitChunk(chunk); + continue; } - setFinishing(lock); + if (partialChunk) { + decommitRange(lock); + continue; + } } } @@ -225,6 +217,9 @@ js::Nursery::Nursery(GCRuntime* gc) canAllocateBigInts_(true), reportTenurings_(0), minorGCTriggerReason_(JS::GCReason::NO_REASON), +#ifndef JS_MORE_DETERMINISTIC + smoothedGrowthFactor(1.0), +#endif decommitTask(gc) #ifdef JS_GC_ZEAL , @@ -242,17 +237,6 @@ js::Nursery::Nursery(GCRuntime* gc) } bool js::Nursery::init(AutoLockGCBgAlloc& lock) { - capacity_ = roundSize(tunables().gcMinNurseryBytes()); - if (!allocateNextChunk(0, lock)) { - capacity_ = 0; - return false; - } - // After this point the Nursery has been enabled. - - setCurrentChunk(0); - setStartPosition(); - poisonAndInitCurrentChunk(); - char* env = getenv("JS_GC_PROFILE_NURSERY"); if (env) { if (0 == strcmp(env, "help")) { @@ -281,8 +265,7 @@ bool js::Nursery::init(AutoLockGCBgAlloc& lock) { return false; } - MOZ_ASSERT(isEnabled()); - return true; + return initFirstChunk(lock); } js::Nursery::~Nursery() { disable(); } @@ -296,26 +279,43 @@ void js::Nursery::enable() { { AutoLockGCBgAlloc lock(gc); - capacity_ = roundSize(tunables().gcMinNurseryBytes()); - if (!allocateNextChunk(0, lock)) { - capacity_ = 0; + if (!initFirstChunk(lock)) { + // If we fail to allocate memory, the nursery will not be enabled. return; } } - setCurrentChunk(0); - setStartPosition(); - poisonAndInitCurrentChunk(); #ifdef JS_GC_ZEAL if (gc->hasZealMode(ZealMode::GenerationalGC)) { enterZealMode(); } #endif + // This should always succeed after the first time it's called. MOZ_ALWAYS_TRUE(gc->storeBuffer().enable()); } +bool js::Nursery::initFirstChunk(AutoLockGCBgAlloc& lock) { + MOZ_ASSERT(!isEnabled()); + + capacity_ = tunables().gcMinNurseryBytes(); + if (!allocateNextChunk(0, lock)) { + capacity_ = 0; + return false; + } + + setCurrentChunk(0); + setStartPosition(); + poisonAndInitCurrentChunk(); + + // Clear any information about previous collections. + clearRecentGrowthData(); + + return true; +} + void js::Nursery::disable() { + stringDeDupSet.reset(); MOZ_ASSERT(isEmpty()); if (!isEnabled()) { return; @@ -422,30 +422,31 @@ JSObject* js::Nursery::allocateObject(JSContext* cx, size_t size, MOZ_ASSERT_IF(clasp->hasFinalize(), CanNurseryAllocateFinalizedClass(clasp) || clasp->isProxy()); - auto obj = reinterpret_cast( + auto* obj = reinterpret_cast( allocateCell(cx->zone(), size, JS::TraceKind::Object)); if (!obj) { return nullptr; } // If we want external slots, add them. - HeapSlot* slots = nullptr; + ObjectSlots* slotsHeader = nullptr; if (nDynamicSlots) { MOZ_ASSERT(clasp->isNative()); - slots = static_cast( - allocateBuffer(cx->zone(), nDynamicSlots * sizeof(HeapSlot))); - if (!slots) { + void* allocation = + allocateBuffer(cx->zone(), ObjectSlots::allocSize(nDynamicSlots)); + if (!allocation) { // It is safe to leave the allocated object uninitialized, since we // do not visit unallocated things in the nursery. return nullptr; } + slotsHeader = new (allocation) ObjectSlots(nDynamicSlots, 0); } // Store slots pointer directly in new object. If no dynamic slots were // requested, caller must initialize slots_ field itself as needed. We // don't know if the caller was a native object or not. if (nDynamicSlots) { - static_cast(obj)->initSlots(slots); + static_cast(obj)->initSlots(slotsHeader->slots()); } gcprobes::NurseryAlloc(obj, size); @@ -697,7 +698,7 @@ void Nursery::setIndirectForwardingPointer(void* oldData, void* newData) { #ifdef DEBUG static bool IsWriteableAddress(void* ptr) { - volatile uint64_t* vPtr = reinterpret_cast(ptr); + auto* vPtr = reinterpret_cast(ptr); *vPtr = *vPtr; return true; } @@ -711,7 +712,7 @@ void js::Nursery::forwardBufferPointer(uintptr_t* pSlotsElems) { // // Note: The buffer has already be relocated. We are just patching stale // pointers now. - void* buffer = reinterpret_cast(*pSlotsElems); + auto* buffer = reinterpret_cast(*pSlotsElems); if (!isInside(buffer)) { return; @@ -746,24 +747,24 @@ js::TenuringTracer::TenuringTracer(JSRuntime* rt, Nursery* nursery) bigIntHead(nullptr), bigIntTail(&bigIntHead) {} -inline float js::Nursery::calcPromotionRate(bool* validForTenuring) const { - float used = float(previousGC.nurseryUsedBytes); - float capacity = float(previousGC.nurseryCapacity); - float tenured = float(previousGC.tenuredBytes); - float rate; +inline double js::Nursery::calcPromotionRate(bool* validForTenuring) const { + double used = double(previousGC.nurseryUsedBytes); + double capacity = double(previousGC.nurseryCapacity); + double tenured = double(previousGC.tenuredBytes); + double rate; if (previousGC.nurseryUsedBytes > 0) { if (validForTenuring) { // We can only use promotion rates if they're likely to be valid, // they're only valid if the nursery was at least 90% full. - *validForTenuring = used > capacity * 0.9f; + *validForTenuring = used > capacity * 0.9; } rate = tenured / used; } else { if (validForTenuring) { *validForTenuring = false; } - rate = 0.0f; + rate = 0.0; } return rate; @@ -906,7 +907,7 @@ bool js::Nursery::shouldCollect() const { bool belowBytesThreshold = freeSpace() < tunables().nurseryFreeThresholdForIdleCollection(); bool belowFractionThreshold = - float(freeSpace()) / float(capacity()) < + double(freeSpace()) / double(capacity()) < tunables().nurseryFreeThresholdForIdleCollectionFraction(); // We want to use belowBytesThreshold when the nursery is sufficiently large, @@ -942,7 +943,7 @@ static inline bool IsFullStoreBufferReason(JS::GCReason reason, reason == JS::GCReason::FULL_SHAPE_BUFFER; } -void js::Nursery::collect(JS::GCReason reason) { +void js::Nursery::collect(JSGCInvocationKind kind, JS::GCReason reason) { JSRuntime* rt = runtime(); MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC); @@ -970,6 +971,10 @@ void js::Nursery::collect(JS::GCReason reason) { stats().beginNurseryCollection(reason); gcprobes::MinorGCStart(); + stringDeDupSet.emplace(); + auto guardStringDedupSet = + mozilla::MakeScopeExit([&] { stringDeDupSet.reset(); }); + maybeClearProfileDurations(); startProfile(ProfileKey::Total); @@ -978,23 +983,30 @@ void js::Nursery::collect(JS::GCReason reason) { // nursery-allocated. MOZ_ASSERT(!IsNurseryAllocable(AllocKind::OBJECT_GROUP)); - TenureCountCache tenureCounts; previousGC.reason = JS::GCReason::NO_REASON; - if (!isEmpty()) { - doCollection(reason, tenureCounts); - } else { - previousGC.nurseryUsedBytes = 0; - previousGC.nurseryCapacity = capacity(); - previousGC.nurseryCommitted = committed(); - previousGC.tenuredBytes = 0; - previousGC.tenuredCells = 0; + previousGC.nurseryUsedBytes = usedSpace(); + previousGC.nurseryCapacity = capacity(); + previousGC.nurseryCommitted = committed(); + previousGC.tenuredBytes = 0; + previousGC.tenuredCells = 0; + + // If it isn't empty, it will call doCollection, and possibly after that + // isEmpty() will become true, so use another variable to keep track of the + // old empty state. + bool wasEmpty = isEmpty(); + TenureCountCache tenureCounts; + if (!wasEmpty) { + CollectionResult result = doCollection(reason, tenureCounts); + previousGC.reason = reason; + previousGC.tenuredBytes = result.tenuredBytes; + previousGC.tenuredCells = result.tenuredCells; } // Resize the nursery. - maybeResizeNursery(reason); + maybeResizeNursery(kind, reason); // Poison/initialise the first chunk. - if (isEnabled() && previousGC.nurseryUsedBytes) { + if (previousGC.nurseryUsedBytes) { // In most cases Nursery::clear() has not poisoned this chunk or marked it // as NoAccess; so we only need to poison the region used during the last // cycle. Also, if the heap was recently expanded we don't want to @@ -1007,7 +1019,15 @@ void js::Nursery::collect(JS::GCReason reason) { poisonAndInitCurrentChunk(previousGC.nurseryUsedBytes); } - const float promotionRate = doPretenuring(rt, reason, tenureCounts); + bool validPromotionRate; + const double promotionRate = calcPromotionRate(&validPromotionRate); + bool highPromotionRate = + validPromotionRate && promotionRate > tunables().pretenureThreshold(); + + startProfile(ProfileKey::Pretenure); + size_t pretenureCount = + doPretenuring(rt, reason, tenureCounts, highPromotionRate); + endProfile(ProfileKey::Pretenure); // We ignore gcMaxBytes when allocating for minor collection. However, if we // overflowed, we disable the nursery. The next time we allocate, we'll fail @@ -1020,39 +1040,61 @@ void js::Nursery::collect(JS::GCReason reason) { gc->incMinorGcNumber(); TimeDuration totalTime = profileDurations_[ProfileKey::Total]; - rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime.ToMicroseconds()); + sendTelemetry(reason, totalTime, wasEmpty, pretenureCount, promotionRate); + + stats().endNurseryCollection(reason); + gcprobes::MinorGCEnd(); + + timeInChunkAlloc_ = mozilla::TimeDuration(); + + if (enableProfiling_ && totalTime >= profileThreshold_) { + printCollectionProfile(reason, promotionRate); + } + + if (reportTenurings_) { + printTenuringData(tenureCounts); + } +} + +void js::Nursery::sendTelemetry(JS::GCReason reason, TimeDuration totalTime, + bool wasEmpty, size_t pretenureCount, + double promotionRate) { + JSRuntime* rt = runtime(); rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, uint32_t(reason)); if (totalTime.ToMilliseconds() > 1.0) { rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, uint32_t(reason)); } + rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime.ToMicroseconds()); rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, committed()); - stats().endNurseryCollection(reason); - gcprobes::MinorGCEnd(); - timeInChunkAlloc_ = mozilla::TimeDuration(); + if (!wasEmpty) { + rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_PROMOTION_RATE, + promotionRate * 100); + } +} - if (enableProfiling_ && totalTime >= profileThreshold_) { - stats().maybePrintProfileHeaders(); - - fprintf(stderr, "MinorGC: %20s %5.1f%% %5zu ", - JS::ExplainGCReason(reason), promotionRate * 100, - capacity() / 1024); - printProfileDurations(profileDurations_); - - if (reportTenurings_) { - for (auto& entry : tenureCounts.entries) { - if (entry.count >= reportTenurings_) { - fprintf(stderr, " %u x ", entry.count); - AutoSweepObjectGroup sweep(entry.group); - entry.group->print(sweep); - } - } +void js::Nursery::printCollectionProfile(JS::GCReason reason, + double promotionRate) { + stats().maybePrintProfileHeaders(); + + fprintf(stderr, "MinorGC: %20s %5.1f%% %5zu ", + JS::ExplainGCReason(reason), promotionRate * 100, capacity() / 1024); + + printProfileDurations(profileDurations_); +} + +void js::Nursery::printTenuringData(const TenureCountCache& tenureCounts) { + for (const auto& entry : tenureCounts.entries) { + if (entry.count >= reportTenurings_) { + fprintf(stderr, " %u x ", entry.count); + AutoSweepObjectGroup sweep(entry.group); + entry.group->print(sweep); } } } -void js::Nursery::doCollection(JS::GCReason reason, - TenureCountCache& tenureCounts) { +js::Nursery::CollectionResult js::Nursery::doCollection( + JS::GCReason reason, TenureCountCache& tenureCounts) { JSRuntime* rt = runtime(); AutoGCSession session(gc, JS::HeapState::MinorCollecting); AutoSetThreadIsPerformingGC performingGC; @@ -1060,9 +1102,6 @@ void js::Nursery::doCollection(JS::GCReason reason, AutoDisableProxyCheck disableStrictProxyChecking; mozilla::DebugOnly oomUnsafeRegion; - const size_t initialNurseryCapacity = capacity(); - const size_t initialNurseryUsedBytes = usedSpace(); - // Move objects pointed to by roots from the nursery to the major heap. TenuringTracer mover(rt, this); @@ -1078,6 +1117,13 @@ void js::Nursery::doCollection(JS::GCReason reason, } endProfile(ProfileKey::CancelIonCompilations); + // Strings in the whole cell buffer must be traced first, in order to mark + // tenured dependent strings' bases as non-deduplicatable. The rest of + // nursery collection (whole non-string cells, edges, etc.) can happen later. + startProfile(ProfileKey::TraceWholeCells); + sb.traceWholeCells(mover); + endProfile(ProfileKey::TraceWholeCells); + startProfile(ProfileKey::TraceValues); sb.traceValues(mover); endProfile(ProfileKey::TraceValues); @@ -1090,10 +1136,6 @@ void js::Nursery::doCollection(JS::GCReason reason, sb.traceSlots(mover); endProfile(ProfileKey::TraceSlots); - startProfile(ProfileKey::TraceWholeCells); - sb.traceWholeCells(mover); - endProfile(ProfileKey::TraceWholeCells); - startProfile(ProfileKey::TraceGenericEntries); sb.traceGenericEntries(&mover); endProfile(ProfileKey::TraceGenericEntries); @@ -1151,6 +1193,12 @@ void js::Nursery::doCollection(JS::GCReason reason, gc->storeBuffer().clear(); endProfile(ProfileKey::ClearStoreBuffer); + // Purge the StringToAtomCache. This has to happen at the end because the + // cache is used when tenuring strings. + startProfile(ProfileKey::PurgeStringToAtomCache); + runtime()->caches().stringToAtomCache.purge(); + endProfile(ProfileKey::PurgeStringToAtomCache); + // Make sure hashtables have been updated after the collection. startProfile(ProfileKey::CheckHashTables); #ifdef JS_GC_ZEAL @@ -1160,47 +1208,38 @@ void js::Nursery::doCollection(JS::GCReason reason, #endif endProfile(ProfileKey::CheckHashTables); - previousGC.reason = reason; - previousGC.nurseryCapacity = initialNurseryCapacity; - previousGC.nurseryCommitted = spaceToEnd(allocatedChunkCount()); - previousGC.nurseryUsedBytes = initialNurseryUsedBytes; - previousGC.tenuredBytes = mover.tenuredSize; - previousGC.tenuredCells = mover.tenuredCells; + return {mover.tenuredSize, mover.tenuredCells}; } -float js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason, - TenureCountCache& tenureCounts) { +size_t js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason, + const TenureCountCache& tenureCounts, + bool highPromotionRate) { // If we are promoting the nursery, or exhausted the store buffer with // pointers to nursery things, which will force a collection well before // the nursery is full, look for object groups that are getting promoted // excessively and try to pretenure them. - startProfile(ProfileKey::Pretenure); - bool validPromotionRate; - const float promotionRate = calcPromotionRate(&validPromotionRate); - uint32_t pretenureCount = 0; - bool attempt = tunables().attemptPretenuring(); - - bool pretenureObj, pretenureStr, pretenureBigInt; - if (attempt) { - // Should we do pretenuring regardless of gcreason? - bool shouldPretenure = validPromotionRate && - promotionRate > tunables().pretenureThreshold() && - previousGC.nurseryUsedBytes >= 4 * 1024 * 1024; + + bool pretenureObj = false; + bool pretenureStr = false; + bool pretenureBigInt = false; + if (tunables().attemptPretenuring()) { + // Should we check for pretenuring regardless of GCReason? + bool pretenureAll = + highPromotionRate && previousGC.nurseryUsedBytes >= 4 * 1024 * 1024; + pretenureObj = - shouldPretenure || + pretenureAll || IsFullStoreBufferReason(reason, JS::GCReason::FULL_CELL_PTR_OBJ_BUFFER); pretenureStr = - shouldPretenure || + pretenureAll || IsFullStoreBufferReason(reason, JS::GCReason::FULL_CELL_PTR_STR_BUFFER); - pretenureBigInt = shouldPretenure || - IsFullStoreBufferReason( - reason, JS::GCReason::FULL_CELL_PTR_BIGINT_BUFFER); - } else { - pretenureObj = false; - pretenureStr = false; - pretenureBigInt = false; + pretenureBigInt = + pretenureAll || IsFullStoreBufferReason( + reason, JS::GCReason::FULL_CELL_PTR_BIGINT_BUFFER); } + size_t pretenureCount = 0; + if (pretenureObj) { JSContext* cx = rt->mainContextFromOwnThread(); uint32_t threshold = tunables().pretenureGroupThreshold(); @@ -1271,12 +1310,8 @@ float js::Nursery::doPretenuring(JSRuntime* rt, JS::GCReason reason, stats().setStat(gcstats::STAT_NURSERY_BIGINT_REALMS_DISABLED, numNurseryBigIntRealmsDisabled); stats().setStat(gcstats::STAT_BIGINTS_TENURED, numBigIntsTenured); - endProfile(ProfileKey::Pretenure); - rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount); - rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_PROMOTION_RATE, promotionRate * 100); - - return promotionRate; + return pretenureCount; } bool js::Nursery::registerMallocedBuffer(void* buffer, size_t nbytes) { @@ -1298,7 +1333,7 @@ void js::Nursery::sweep(JSTracer* trc) { // Sweep unique IDs first before we sweep any tables that may be keyed based // on them. for (Cell* cell : cellsWithUid_) { - JSObject* obj = static_cast(cell); + auto* obj = static_cast(cell); if (!IsForwarded(obj)) { obj->nurseryZone()->removeUniqueId(obj); } else { @@ -1451,111 +1486,139 @@ MOZ_ALWAYS_INLINE void js::Nursery::setStartPosition() { currentStartPosition_ = position(); } -void js::Nursery::maybeResizeNursery(JS::GCReason reason) { - if (maybeResizeExact(reason)) { +void js::Nursery::maybeResizeNursery(JSGCInvocationKind kind, + JS::GCReason reason) { +#ifdef JS_GC_ZEAL + // This zeal mode disabled nursery resizing. + if (gc->hasZealMode(ZealMode::GenerationalGC)) { return; } - - // This incorrect promotion rate results in better nursery sizing - // decisions, however we should to better tuning based on the real - // promotion rate in the future. - const float promotionRate = - float(previousGC.tenuredBytes) / float(previousGC.nurseryCapacity); - - // Object lifetimes aren't going to behave linearly, but a better - // relationship that works for all programs and can be predicted in - // advance doesn't exist. - static const float GrowThreshold = 0.03f; - static const float ShrinkThreshold = 0.01f; - static const float PromotionGoal = (GrowThreshold + ShrinkThreshold) / 2.0f; - const float factor = promotionRate / PromotionGoal; - MOZ_ASSERT(factor >= 0.0f); - -#ifdef DEBUG - // This is |... <= SIZE_MAX|, just without the implicit value-changing - // conversion that expression would involve and modern clang would warn about. - static const float SizeMaxPlusOne = - 2.0f * float(1ULL << (sizeof(void*) * CHAR_BIT - 1)); - MOZ_ASSERT((float(capacity()) * factor) < SizeMaxPlusOne); #endif - size_t newCapacity = size_t(float(capacity()) * factor); + size_t newCapacity = + mozilla::Clamp(targetSize(kind, reason), tunables().gcMinNurseryBytes(), + tunables().gcMaxNurseryBytes()); - const size_t minNurseryBytes = roundSize(tunables().gcMinNurseryBytes()); - MOZ_ASSERT(minNurseryBytes >= ArenaSize); - const size_t maxNurseryBytes = roundSize(tunables().gcMaxNurseryBytes()); - MOZ_ASSERT(maxNurseryBytes >= ArenaSize); + MOZ_ASSERT(roundSize(newCapacity) == newCapacity); - // If one of these conditions is true then we always shrink or grow the - // nursery. This way the thresholds still have an effect even if the goal - // seeking says the current size is ideal. - size_t lowLimit = std::max(minNurseryBytes, capacity() / 2); - size_t highLimit = - std::min(maxNurseryBytes, (CheckedInt(capacity()) * 2).value()); - newCapacity = roundSize(mozilla::Clamp(newCapacity, lowLimit, highLimit)); - - if (capacity() < maxNurseryBytes && promotionRate > GrowThreshold && - newCapacity > capacity()) { + if (newCapacity > capacity()) { growAllocableSpace(newCapacity); - } else if (capacity() >= minNurseryBytes + SubChunkStep && - promotionRate < ShrinkThreshold && newCapacity < capacity()) { + } else if (newCapacity < capacity()) { shrinkAllocableSpace(newCapacity); } } -bool js::Nursery::maybeResizeExact(JS::GCReason reason) { - // Shrink the nursery to its minimum size if we ran out of memory or - // received a memory pressure event. - if (gc::IsOOMReason(reason) || gc->systemHasLowMemory()) { - minimizeAllocableSpace(); - return true; +static inline double ClampDouble(double value, double min, double max) { + MOZ_ASSERT(!std::isnan(value) && !std::isnan(min) && !std::isnan(max)); + MOZ_ASSERT(max >= min); + + if (value <= min) { + return min; } -#ifdef JS_GC_ZEAL - // This zeal mode disabled nursery resizing. - if (gc->hasZealMode(ZealMode::GenerationalGC)) { - return true; + if (value >= max) { + return max; + } + + return value; +} + +size_t js::Nursery::targetSize(JSGCInvocationKind kind, JS::GCReason reason) { + // Shrink the nursery as much as possible if shrinking was requested or in low + // memory situations. + if (kind == GC_SHRINK || gc::IsOOMReason(reason) || + gc->systemHasLowMemory()) { + clearRecentGrowthData(); + return 0; + } + + // Don't resize the nursery during shutdown. + if (gc::IsShutdownReason(reason)) { + clearRecentGrowthData(); + return capacity(); + } + + TimeStamp now = ReallyNow(); + + // Calculate the fraction of the nursery promoted out of its entire + // capacity. This gives better results than using the promotion rate (based on + // the amount of nursery used) in cases where we collect before the nursery is + // full. + double fractionPromoted = + double(previousGC.tenuredBytes) / double(previousGC.nurseryCapacity); + + // Calculate the fraction of time spent collecting the nursery. + double timeFraction = 0.0; +#ifndef JS_MORE_DETERMINISTIC + if (lastResizeTime) { + TimeDuration collectorTime = now - collectionStartTime(); + TimeDuration totalTime = now - lastResizeTime; + timeFraction = collectorTime.ToSeconds() / totalTime.ToSeconds(); } #endif - MOZ_ASSERT(tunables().gcMaxNurseryBytes() >= ArenaSize); - const size_t newMaxNurseryBytes = roundSize(tunables().gcMaxNurseryBytes()); - MOZ_ASSERT(newMaxNurseryBytes >= ArenaSize); + // Adjust the nursery size to try to achieve a target promotion rate and + // collector time goals. + static const double PromotionGoal = 0.02; + static const double TimeGoal = 0.01; + double growthFactor = + std::max(fractionPromoted / PromotionGoal, timeFraction / TimeGoal); - if (capacity_ > newMaxNurseryBytes) { - // The configured maximum nursery size is changing. - // We need to shrink the nursery. - shrinkAllocableSpace(newMaxNurseryBytes); - return true; + // Limit the range of the growth factor to prevent transient high promotion + // rates from affecting the nursery size too far into the future. + static const double GrowthRange = 2.0; + growthFactor = ClampDouble(growthFactor, 1.0 / GrowthRange, GrowthRange); + +#ifndef JS_MORE_DETERMINISTIC + // Use exponential smoothing on the desired growth rate to take into account + // the promotion rate from recent previous collections. + if (lastResizeTime && + now - lastResizeTime < TimeDuration::FromMilliseconds(200)) { + growthFactor = 0.75 * smoothedGrowthFactor + 0.25 * growthFactor; } - const size_t newMinNurseryBytes = roundSize(tunables().gcMinNurseryBytes()); - MOZ_ASSERT(newMinNurseryBytes >= ArenaSize); + lastResizeTime = now; + smoothedGrowthFactor = growthFactor; +#endif - if (newMinNurseryBytes > capacity()) { - // the configured minimum nursery size is changing, so grow the nursery. - MOZ_ASSERT(newMinNurseryBytes <= roundSize(tunables().gcMaxNurseryBytes())); - growAllocableSpace(newMinNurseryBytes); - return true; + // Leave size untouched if we are close to the promotion goal. + static const double GoalWidth = 1.5; + if (growthFactor > (1.0 / GoalWidth) && growthFactor < GoalWidth) { + return capacity(); } - return false; + // The multiplication below cannot overflow because growthFactor is at + // most two. + MOZ_ASSERT(growthFactor <= 2.0); + MOZ_ASSERT(capacity() < SIZE_MAX / 2); + + return roundSize(size_t(double(capacity()) * growthFactor)); } +void js::Nursery::clearRecentGrowthData() { +#ifndef JS_MORE_DETERMINISTIC + lastResizeTime = TimeStamp(); + smoothedGrowthFactor = 1.0; +#endif +} + +/* static */ size_t js::Nursery::roundSize(size_t size) { - if (size >= ChunkSize) { - size = Round(size, ChunkSize); - } else { - size = std::min(Round(size, SubChunkStep), - RoundDown(NurseryChunkUsableSize, SubChunkStep)); - } + static_assert(SubChunkStep > gc::ChunkTrailerSize, + "Don't allow the nursery to overwrite the trailer when using " + "less than a chunk"); + + size_t step = size >= ChunkSize ? ChunkSize : SubChunkStep; + size = Round(size, step); + MOZ_ASSERT(size >= ArenaSize); + return size; } void js::Nursery::growAllocableSpace(size_t newCapacity) { MOZ_ASSERT_IF(!isSubChunkMode(), newCapacity > currentChunk_ * ChunkSize); - MOZ_ASSERT(newCapacity <= roundSize(tunables().gcMaxNurseryBytes())); + MOZ_ASSERT(newCapacity <= tunables().gcMaxNurseryBytes()); MOZ_ASSERT(newCapacity > capacity()); if (isSubChunkMode()) { @@ -1656,21 +1719,6 @@ void js::Nursery::shrinkAllocableSpace(size_t newCapacity) { } } -void js::Nursery::minimizeAllocableSpace() { - if (capacity_ < roundSize(tunables().gcMinNurseryBytes())) { - // The nursery is already smaller than the minimum size. This can happen - // because changing parameters (like an increase in minimum size) can only - // occur after a minor GC. See Bug 1585159. - // - // We could either do the /correct/ thing and increase the size to the - // configured minimum size. Or do nothing, keeping the nursery smaller. We - // do nothing because this can be executed as a last-ditch GC and we don't - // want to add memory pressure then. - return; - } - shrinkAllocableSpace(roundSize(tunables().gcMinNurseryBytes())); -} - bool js::Nursery::queueDictionaryModeObjectToSweep(NativeObject* obj) { MOZ_ASSERT(IsInsideNursery(obj)); return dictionaryModeObjects_.append(obj); diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index b6f59eb465..18615f9b34 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -6,15 +6,18 @@ #define gc_Nursery_h #include "mozilla/EnumeratedArray.h" +#include "mozilla/Maybe.h" #include "mozilla/TimeStamp.h" #include "gc/GCParallelTask.h" #include "gc/Heap.h" +#include "js/AllocPolicy.h" #include "js/Class.h" #include "js/HeapAPI.h" #include "js/TracingAPI.h" #include "js/TypeDecls.h" #include "js/Vector.h" +#include "util/Text.h" #define FOR_EACH_NURSERY_PROFILE_TIME(_) \ /* Key Header text */ \ @@ -36,10 +39,12 @@ _(FreeMallocedBuffers, "frSlts") \ _(ClearStoreBuffer, "clrSB") \ _(ClearNursery, "clear") \ + _(PurgeStringToAtomCache, "pStoA") \ _(Pretenure, "pretnr") template class SharedMem; +class JSDependentString; namespace js { @@ -61,6 +66,7 @@ struct Cell; class GCSchedulingTunables; class MinorCollectionTracer; class RelocationOverlay; +class StringRelocationOverlay; struct TenureCountCache; enum class AllocKind : uint8_t; class TenuredCell; @@ -81,7 +87,7 @@ class NurseryDecommitTask : public GCParallelTask { void queueRange(size_t newCapacity, NurseryChunk& chunk, const AutoLockHelperThreadState& lock); - void run() override; + void run(AutoLockHelperThreadState& lock) override; void decommitChunk(gc::Chunk* chunk); void decommitRange(AutoLockHelperThreadState& lock); @@ -109,8 +115,8 @@ class TenuringTracer : public JSTracer { // to find things held live by intra-Nursery pointers. gc::RelocationOverlay* objHead; gc::RelocationOverlay** objTail; - gc::RelocationOverlay* stringHead; - gc::RelocationOverlay** stringTail; + gc::StringRelocationOverlay* stringHead; + gc::StringRelocationOverlay** stringTail; gc::RelocationOverlay* bigIntHead; gc::RelocationOverlay** bigIntTail; @@ -133,11 +139,13 @@ class TenuringTracer : public JSTracer { private: inline void insertIntoObjectFixupList(gc::RelocationOverlay* entry); - inline void insertIntoStringFixupList(gc::RelocationOverlay* entry); + inline void insertIntoStringFixupList(gc::StringRelocationOverlay* entry); inline void insertIntoBigIntFixupList(gc::RelocationOverlay* entry); template inline T* allocTenured(JS::Zone* zone, gc::AllocKind kind); + JSString* allocTenuredString(JSString* src, JS::Zone* zone, + gc::AllocKind dstKind); inline JSObject* movePlainObjectToTenured(PlainObject* src); JSObject* moveToTenuredSlow(JSObject* src); @@ -280,7 +288,7 @@ class Nursery { static const size_t MaxNurseryBufferSize = 1024; // Do a minor collection. - void collect(JS::GCReason reason); + void collect(JSGCInvocationKind kind, JS::GCReason reason); // If the thing at |*ref| in the Nursery has been forwarded, set |*ref| to // the new location and return true. Otherwise return false and leave @@ -415,6 +423,13 @@ class Nursery { void joinDecommitTask() { decommitTask.join(); } + mozilla::TimeStamp collectionStartTime() { + return startTimes_[ProfileKey::Total]; + } + + // Round a size in bytes to the nearest valid nursery size. + static size_t roundSize(size_t size); + private: gc::GCRuntime* const gc; @@ -490,14 +505,21 @@ class Nursery { ProfileDurations profileDurations_; ProfileDurations totalDurations_; - struct { + // Data about the previous collection. + struct PreviousGC { JS::GCReason reason = JS::GCReason::NO_REASON; size_t nurseryCapacity = 0; size_t nurseryCommitted = 0; size_t nurseryUsedBytes = 0; size_t tenuredBytes = 0; size_t tenuredCells = 0; - } previousGC; + }; + PreviousGC previousGC; + +#ifndef JS_MORE_DETERMINISTIC + mozilla::TimeStamp lastResizeTime; + double smoothedGrowthFactor; +#endif // Calculate the promotion rate of the most recent minor GC. // The valid_for_tenuring parameter is used to return whether this @@ -505,7 +527,7 @@ class Nursery { // used for tenuring and other decisions. // // Must only be called if the previousGC data is initialised. - float calcPromotionRate(bool* validForTenuring) const; + double calcPromotionRate(bool* validForTenuring) const; // The set of externally malloced buffers potentially kept live by objects // stored in the nursery. Any external buffers that do not belong to a @@ -538,6 +560,66 @@ class Nursery { using NativeObjectVector = Vector; NativeObjectVector dictionaryModeObjects_; + template + struct DeduplicationStringHasher { + using Lookup = Key; + + static inline HashNumber hash(const Lookup& lookup) { + JS::AutoCheckCannotGC nogc; + HashNumber strHash; + + // Include flags in the hash. A string relocation overlay stores either + // the nursery root base chars or the dependent string nursery base, but + // does not indicate which one. If strings with different string types + // were deduplicated, for example, a dependent string gets deduplicated + // into an extensible string, the base chain would be broken and the root + // base would be unreachable. + + if (lookup->asLinear().hasLatin1Chars()) { + strHash = mozilla::HashString(lookup->asLinear().latin1Chars(nogc), + lookup->length()); + } else { + MOZ_ASSERT(lookup->asLinear().hasTwoByteChars()); + strHash = mozilla::HashString(lookup->asLinear().twoByteChars(nogc), + lookup->length()); + } + + return mozilla::HashGeneric(strHash, lookup->zone(), lookup->flags()); + } + + static MOZ_ALWAYS_INLINE bool match(const Key& key, const Lookup& lookup) { + if (!key->sameLengthAndFlags(*lookup) || + key->asTenured().zone() != lookup->zone() || + key->asTenured().getAllocKind() != lookup->getAllocKind()) { + return false; + } + + JS::AutoCheckCannotGC nogc; + + if (key->asLinear().hasLatin1Chars()) { + MOZ_ASSERT(lookup->asLinear().hasLatin1Chars()); + return mozilla::ArrayEqual(key->asLinear().latin1Chars(nogc), + lookup->asLinear().latin1Chars(nogc), + lookup->length()); + } else { + MOZ_ASSERT(key->asLinear().hasTwoByteChars()); + MOZ_ASSERT(lookup->asLinear().hasTwoByteChars()); + return EqualChars(key->asLinear().twoByteChars(nogc), + lookup->asLinear().twoByteChars(nogc), + lookup->length()); + } + } + }; + + using StringDeDupSet = + HashSet, + SystemAllocPolicy>; + + // deDupSet is emplaced at the beginning of the nursery collection and reset + // at the end of the nursery collection. It can also be reset during nursery + // collection when out of memory to insert new entries. + mozilla::Maybe stringDeDupSet; + // Lists of map and set objects allocated in the nursery or with iterators // allocated there. Such objects need to be swept after minor GC. Vector mapsWithNurseryMemory_; @@ -559,6 +641,8 @@ class Nursery { // the current chunk. void setCurrentChunk(unsigned chunkno); + bool initFirstChunk(AutoLockGCBgAlloc& lock); + // extent is advisory, it will be ignored in sub-chunk and generational zeal // modes. It will be clamped to Min(NurseryChunkUsableSize, capacity_). void poisonAndInitCurrentChunk(size_t extent = NurseryChunkUsableSize); @@ -591,16 +675,31 @@ class Nursery { void writeCanary(uintptr_t address); #endif - void doCollection(JS::GCReason reason, gc::TenureCountCache& tenureCounts); + struct CollectionResult { + size_t tenuredBytes; + size_t tenuredCells; + }; + CollectionResult doCollection(JS::GCReason reason, + gc::TenureCountCache& tenureCounts); - float doPretenuring(JSRuntime* rt, JS::GCReason reason, - gc::TenureCountCache& tenureCounts); + size_t doPretenuring(JSRuntime* rt, JS::GCReason reason, + const gc::TenureCountCache& tenureCounts, + bool highPromotionRate); // Move the object at |src| in the Nursery to an already-allocated cell // |dst| in Tenured. void collectToFixedPoint(TenuringTracer& trc, gc::TenureCountCache& tenureCounts); + // The dependent string chars needs to be relocated if the base which it's + // using chars from has been deduplicated. + template + void relocateDependentStringChars(JSDependentString* tenuredDependentStr, + JSLinearString* baseOrRelocOverlay, + size_t* offset, + bool* rootBaseNotYetForwarded, + JSLinearString** rootBase); + // Handle relocation of slots/elements pointers stored in Ion frames. inline void setForwardingPointer(void* oldData, void* newData, bool direct); @@ -625,9 +724,9 @@ class Nursery { void sweepMapAndSetObjects(); // Change the allocable space provided by the nursery. - void maybeResizeNursery(JS::GCReason reason); - bool maybeResizeExact(JS::GCReason reason); - static size_t roundSize(size_t size); + void maybeResizeNursery(JSGCInvocationKind kind, JS::GCReason reason); + size_t targetSize(JSGCInvocationKind kind, JS::GCReason reason); + void clearRecentGrowthData(); void growAllocableSpace(size_t newCapacity); void shrinkAllocableSpace(size_t newCapacity); void minimizeAllocableSpace(); @@ -636,6 +735,13 @@ class Nursery { // vector. Shrinks the vector but does not update maxChunkCount(). void freeChunksFrom(unsigned firstFreeChunk); + void sendTelemetry(JS::GCReason reason, mozilla::TimeDuration totalTime, + bool wasEmpty, size_t pretenureCount, + double promotionRate); + + void printCollectionProfile(JS::GCReason reason, double promotionRate); + void printTenuringData(const gc::TenureCountCache& tenureCounts); + // Profile recording and printing. void maybeClearProfileDurations(); void startProfile(ProfileKey key); diff --git a/js/src/gc/NurseryAwareHashMap.h b/js/src/gc/NurseryAwareHashMap.h index a4526953d6..4af4c99bb9 100644 --- a/js/src/gc/NurseryAwareHashMap.h +++ b/js/src/gc/NurseryAwareHashMap.h @@ -53,6 +53,8 @@ class UnsafeBareWeakHeapPtr : public ReadBarriered { }; } // namespace detail +enum : bool { DuplicatesNotPossible, DuplicatesPossible }; + // The "nursery aware" hash map is a special case of GCHashMap that is able to // treat nursery allocated members weakly during a minor GC: e.g. it allows for // nursery allocated objects to be collected during nursery GC where a normal @@ -66,7 +68,8 @@ class UnsafeBareWeakHeapPtr : public ReadBarriered { // moment, but might serve as a useful base for other tables in future. template , - typename AllocPolicy = TempAllocPolicy> + typename AllocPolicy = TempAllocPolicy, + bool AllowDuplicates = DuplicatesNotPossible> class NurseryAwareHashMap { using BarrieredValue = detail::UnsafeBareWeakHeapPtr; using MapType = @@ -162,7 +165,25 @@ class NurseryAwareHashMap { map.remove(key); continue; } - map.rekeyIfMoved(key, copy); + if (AllowDuplicates) { + // Drop duplicated keys. + // + // A key can be forwarded to another place. In this case, rekey the + // item. If two or more different keys are forwarded to the same new + // key, simply drop the later ones. + if (key == copy) { + // No rekey needed. + } else if (map.has(copy)) { + // Key was forwarded to the same place that another key was already + // forwarded to. + map.remove(key); + } else { + map.rekeyAs(key, copy, copy); + } + } else { + MOZ_ASSERT(key == copy || !map.has(copy)); + map.rekeyIfMoved(key, copy); + } } nurseryEntries.clear(); } diff --git a/js/src/gc/ParallelWork.h b/js/src/gc/ParallelWork.h index fec81be256..bf1fb838d8 100644 --- a/js/src/gc/ParallelWork.h +++ b/js/src/gc/ParallelWork.h @@ -10,6 +10,7 @@ #include "gc/GC.h" #include "gc/GCParallelTask.h" +#include "gc/GCRuntime.h" #include "js/SliceBudget.h" #include "vm/HelperThreads.h" @@ -45,7 +46,9 @@ class ParallelWorker : public GCParallelTask { work.next(); } - void run() { + void run(AutoLockHelperThreadState& lock) { + AutoUnlockHelperThreadState unlock(lock); + // These checks assert when run in parallel. AutoDisableProxyCheck noProxyCheck; @@ -99,7 +102,7 @@ class MOZ_RAII AutoRunParallelWork { const SliceBudget& budget, AutoLockHelperThreadState& lock) : gc(gc), phaseKind(phaseKind), lock(lock), tasksStarted(0) { - size_t workerCount = ParallelWorkerCount(); + size_t workerCount = gc->parallelWorkerCount(); MOZ_ASSERT(workerCount <= MaxParallelWorkers); MOZ_ASSERT_IF(workerCount == 0, work.done()); @@ -111,7 +114,7 @@ class MOZ_RAII AutoRunParallelWork { } ~AutoRunParallelWork() { - MOZ_ASSERT(HelperThreadState().isLockedByCurrentThread()); + MOZ_ASSERT(gHelperThreadLock.ownedByCurrentThread()); for (size_t i = 0; i < tasksStarted; i++) { gc->joinTask(*tasks[i], phaseKind, lock); diff --git a/js/src/gc/Policy.h b/js/src/gc/Policy.h index 8e1ce0a0fb..4984e702b0 100644 --- a/js/src/gc/Policy.h +++ b/js/src/gc/Policy.h @@ -26,21 +26,6 @@ struct InternalGCPointerPolicy : public JS::GCPointerPolicy { "InternalGCPointerPolicy must only be used for GC thing pointers"); #undef IS_BASE_OF_OR - static void preBarrier(T v) { - if (v) { - Type::writeBarrierPre(v); - } - } - static void postBarrier(T* vp, T prev, T next) { - if (*vp) { - Type::writeBarrierPost(vp, prev, next); - } - } - static void readBarrier(T v) { - if (v) { - Type::readBarrier(v); - } - } static void trace(JSTracer* trc, T* vp, const char* name) { // It's not safe to trace unbarriered pointers except as part of root // marking. If you get an assertion here you probably need to add a barrier, diff --git a/js/src/gc/PrivateIterators-inl.h b/js/src/gc/PrivateIterators-inl.h index 3d074d42a5..462fa54b1b 100644 --- a/js/src/gc/PrivateIterators-inl.h +++ b/js/src/gc/PrivateIterators-inl.h @@ -51,7 +51,7 @@ class GCZonesIter { explicit GCZonesIter(GCRuntime* gc, ZoneSelector selector = WithAtoms) : zone(gc, selector) { MOZ_ASSERT(JS::RuntimeHeapIsBusy()); - MOZ_ASSERT_IF(gc->atomsZone->isCollectingFromAnyThread(), + MOZ_ASSERT_IF(gc->atomsZone->wasGCStarted(), !gc->rt->hasHelperThreadZones()); if (!done() && !zone->isCollectingFromAnyThread()) { diff --git a/js/src/gc/PublicIterators.cpp b/js/src/gc/PublicIterators.cpp index 1712698375..67a64887d9 100644 --- a/js/src/gc/PublicIterators.cpp +++ b/js/src/gc/PublicIterators.cpp @@ -19,12 +19,12 @@ using namespace js::gc; static void IterateRealmsArenasCellsUnbarriered( JSContext* cx, Zone* zone, void* data, JS::IterateRealmCallback realmCallback, IterateArenaCallback arenaCallback, - IterateCellCallback cellCallback) { + IterateCellCallback cellCallback, const JS::AutoRequireNoGC& nogc) { { Rooted realm(cx); for (RealmsInZoneIter r(zone); !r.done(); r.next()) { realm = r; - (*realmCallback)(cx, data, realm); + (*realmCallback)(cx, data, realm, nogc); } } @@ -34,10 +34,11 @@ static void IterateRealmsArenasCellsUnbarriered( for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) { Arena* arena = aiter.get(); - (*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize); + (*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize, nogc); for (ArenaCellIter iter(arena); !iter.done(); iter.next()) { (*cellCallback)(cx->runtime(), data, - JS::GCCellPtr(iter.getCell(), traceKind), thingSize); + JS::GCCellPtr(iter.getCell(), traceKind), thingSize, + nogc); } } } @@ -49,11 +50,12 @@ void js::IterateHeapUnbarriered(JSContext* cx, void* data, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback) { AutoPrepareForTracing prep(cx); + JS::AutoSuppressGCAnalysis nogc(cx); for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) { - (*zoneCallback)(cx->runtime(), data, zone); + (*zoneCallback)(cx->runtime(), data, zone, nogc); IterateRealmsArenasCellsUnbarriered(cx, zone, data, realmCallback, - arenaCallback, cellCallback); + arenaCallback, cellCallback, nogc); } } @@ -63,20 +65,22 @@ void js::IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback) { AutoPrepareForTracing prep(cx); + JS::AutoSuppressGCAnalysis nogc(cx); - (*zoneCallback)(cx->runtime(), data, zone); + (*zoneCallback)(cx->runtime(), data, zone, nogc); IterateRealmsArenasCellsUnbarriered(cx, zone, data, realmCallback, - arenaCallback, cellCallback); + arenaCallback, cellCallback, nogc); } void js::IterateChunks(JSContext* cx, void* data, IterateChunkCallback chunkCallback) { AutoPrepareForTracing prep(cx); AutoLockGC lock(cx->runtime()); + JS::AutoSuppressGCAnalysis nogc(cx); for (auto chunk = cx->runtime()->gc.allNonEmptyChunks(lock); !chunk.done(); chunk.next()) { - chunkCallback(cx->runtime(), data, chunk); + chunkCallback(cx->runtime(), data, chunk, nogc); } } @@ -174,15 +178,18 @@ void js::IterateLazyScripts(JSContext* cx, Realm* realm, void* data, IterateScriptsImpl(cx, realm, data, scriptCallback); } -void js::IterateGrayObjects(Zone* zone, GCThingCallback cellCallback, +void js::IterateGrayObjects(Zone* zone, IterateGCThingCallback cellCallback, void* data) { MOZ_ASSERT(!JS::RuntimeHeapIsBusy()); - AutoPrepareForTracing prep(TlsContext.get()); + JSContext* cx = TlsContext.get(); + AutoPrepareForTracing prep(cx); + JS::AutoSuppressGCAnalysis nogc(cx); + for (auto kind : ObjectAllocKinds()) { for (GrayObjectIter obj(zone, kind); !obj.done(); obj.next()) { if (obj->asTenured().isMarkedGray()) { - cellCallback(data, JS::GCCellPtr(obj.get())); + cellCallback(data, JS::GCCellPtr(obj.get()), nogc); } } } @@ -217,11 +224,12 @@ JS_PUBLIC_API void JS_IterateCompartmentsInZone( JS_PUBLIC_API void JS::IterateRealms(JSContext* cx, void* data, JS::IterateRealmCallback realmCallback) { AutoTraceSession session(cx->runtime()); + JS::AutoSuppressGCAnalysis nogc(cx); Rooted realm(cx); for (RealmsIter r(cx->runtime()); !r.done(); r.next()) { realm = r; - (*realmCallback)(cx, data, realm); + (*realmCallback)(cx, data, realm, nogc); } } @@ -231,6 +239,7 @@ JS_PUBLIC_API void JS::IterateRealmsWithPrincipals( MOZ_ASSERT(principals); AutoTraceSession session(cx->runtime()); + JS::AutoSuppressGCAnalysis nogc(cx); Rooted realm(cx); for (RealmsIter r(cx->runtime()); !r.done(); r.next()) { @@ -238,7 +247,7 @@ JS_PUBLIC_API void JS::IterateRealmsWithPrincipals( continue; } realm = r; - (*realmCallback)(cx, data, realm); + (*realmCallback)(cx, data, realm, nogc); } } @@ -246,10 +255,11 @@ JS_PUBLIC_API void JS::IterateRealmsInCompartment( JSContext* cx, JS::Compartment* compartment, void* data, JS::IterateRealmCallback realmCallback) { AutoTraceSession session(cx->runtime()); + JS::AutoSuppressGCAnalysis nogc(cx); Rooted realm(cx); for (RealmsInCompartmentIter r(compartment); !r.done(); r.next()) { realm = r; - (*realmCallback)(cx, data, realm); + (*realmCallback)(cx, data, realm, nogc); } } diff --git a/js/src/gc/RelocationOverlay.h b/js/src/gc/RelocationOverlay.h index 2519d31f1f..3f4f3e06e9 100644 --- a/js/src/gc/RelocationOverlay.h +++ b/js/src/gc/RelocationOverlay.h @@ -18,32 +18,23 @@ namespace js { namespace gc { -class RelocatedCellHeader : public CellHeader { - public: - RelocatedCellHeader(Cell* location, uintptr_t flags); - - Cell* location() const { - return reinterpret_cast(header_ & ~RESERVED_MASK); - } -}; - /* * This structure overlays a Cell that has been moved and provides a way to find * its new location. It's used during generational and compacting GC. */ class RelocationOverlay : public Cell { - // First word of a Cell has additional requirements from GC. The GC flags - // determine if a Cell is a normal entry or is a RelocationOverlay. - // 3 0 - // ------------------------- - // | NewLocation | GCFlags | - // ------------------------- - RelocatedCellHeader header_; + public: + /* The location the cell has been moved to, stored in the cell header. */ + Cell* forwardingAddress() const { + MOZ_ASSERT(isForwarded()); + return reinterpret_cast(header_ & ~RESERVED_MASK); + } + protected: /* A list entry to track all relocated things. */ RelocationOverlay* next_; - RelocationOverlay(Cell* dst, uintptr_t flags); + explicit RelocationOverlay(Cell* dst); public: static const RelocationOverlay* fromCell(const Cell* cell) { @@ -56,11 +47,6 @@ class RelocationOverlay : public Cell { static RelocationOverlay* forwardCell(Cell* src, Cell* dst); - Cell* forwardingAddress() const { - MOZ_ASSERT(isForwarded()); - return header_.location(); - } - RelocationOverlay*& nextRef() { MOZ_ASSERT(isForwarded()); return next_; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 3664aa2654..0767cdc390 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -10,15 +10,14 @@ #include "builtin/MapObject.h" #include "debugger/DebugAPI.h" -#include "frontend/BinASTParserBase.h" #include "frontend/BytecodeCompiler.h" #include "frontend/Parser.h" #include "gc/ClearEdgesTracer.h" #include "gc/GCInternals.h" #include "gc/Marking.h" -#include "jit/MacroAssembler.h" #include "js/HashTable.h" #include "js/ValueArray.h" +#include "vm/HelperThreadState.h" #include "vm/JSContext.h" #include "vm/JSONParser.h" @@ -29,47 +28,55 @@ using namespace js; using namespace js::gc; +using mozilla::LinkedList; + using JS::AutoGCRooter; using RootRange = RootedValueMap::Range; using RootEntry = RootedValueMap::Entry; using RootEnum = RootedValueMap::Enum; -template -using TraceFunction = void (*)(JSTracer* trc, T* ref, const char* name); - -// For more detail see JS::Rooted::ptr and js::DispatchWrapper. +// For more detail see JS::Rooted::root and js::RootedTraceable. // -// The JS::RootKind::Traceable list contains a bunch of totally disparate -// types, but the instantiations of DispatchWrapper below need /something/ in -// the type field. We use the following type as a compatible stand-in. No -// actual methods from ConcreteTraceable type are actually used at runtime -- -// the real trace function has been stored inline in the DispatchWrapper. +// The JS::RootKind::Traceable list contains a bunch of totally disparate types, +// but to refer to this list we need /something/ in the type field. We use the +// following type as a compatible stand-in. No actual methods from +// ConcreteTraceable type are actually used at runtime. struct ConcreteTraceable { - ConcreteTraceable() { MOZ_CRASH("instantiation of ConcreteTraceable"); } - void trace(JSTracer*) {} + ConcreteTraceable() = delete; + void trace(JSTracer*) = delete; }; template -static inline void TraceStackOrPersistentRoot(JSTracer* trc, T* thingp, - const char* name) { +inline void RootedGCThingTraits::trace(JSTracer* trc, T* thingp, + const char* name) { TraceNullableRoot(trc, thingp, name); } -template <> -inline void TraceStackOrPersistentRoot(JSTracer* trc, ConcreteTraceable* thingp, - const char* name) { - js::DispatchWrapper::TraceWrapped(trc, thingp, name); +template +inline void RootedTraceableTraits::trace(JSTracer* trc, + VirtualTraceable* thingp, + const char* name) { + thingp->trace(trc, name); +} + +template +inline void JS::Rooted::trace(JSTracer* trc, const char* name) { + PtrTraits::trace(trc, &ptr, name); +} + +template +inline void JS::PersistentRooted::trace(JSTracer* trc, const char* name) { + PtrTraits::trace(trc, &ptr, name); } template static inline void TraceExactStackRootList(JSTracer* trc, - JS::Rooted* rooter, + JS::Rooted* listHead, const char* name) { - while (rooter) { - T* addr = reinterpret_cast*>(rooter)->address(); - TraceStackOrPersistentRoot(trc, addr, name); - rooter = rooter->previous(); + auto* typedList = reinterpret_cast*>(listHead); + for (JS::Rooted* root = typedList; root; root = root->previous()) { + root->trace(trc, name); } } @@ -84,7 +91,7 @@ static inline void TraceStackRoots(JSTracer* trc, TraceExactStackRootList(trc, stackRoots[JS::RootKind::Value], "exact-value"); - // ConcreteTraceable calls through a function pointer. + // RootedTraceable uses virtual dispatch. JS::AutoSuppressGCAnalysis nogc; TraceExactStackRootList( @@ -101,11 +108,11 @@ static void TraceExactStackRoots(JSContext* cx, JSTracer* trc) { template static inline void TracePersistentRootedList( - JSTracer* trc, mozilla::LinkedList>& list, + JSTracer* trc, LinkedList>& list, const char* name) { - for (PersistentRooted* r : list) { - TraceStackOrPersistentRoot( - trc, reinterpret_cast*>(r)->address(), name); + auto& typedList = reinterpret_cast>&>(list); + for (PersistentRooted* root : typedList) { + root->trace(trc, name); } } @@ -120,7 +127,7 @@ void JSRuntime::tracePersistentRoots(JSTracer* trc) { TracePersistentRootedList(trc, heapRoots.ref()[JS::RootKind::Value], "persistent-value"); - // ConcreteTraceable calls through a function pointer. + // RootedTraceable uses virtual dispatch. JS::AutoSuppressGCAnalysis nogc; TracePersistentRootedList( @@ -133,9 +140,8 @@ static void TracePersistentRooted(JSRuntime* rt, JSTracer* trc) { template static void FinishPersistentRootedChain( - mozilla::LinkedList>& listArg) { - auto& list = - reinterpret_cast>&>(listArg); + LinkedList>& listArg) { + auto& list = reinterpret_cast>&>(listArg); while (!list.isEmpty()) { list.getFirst()->reset(); } @@ -260,7 +266,6 @@ void js::gc::GCRuntime::traceRuntimeForMajorGC(JSTracer* trc, if (atomsZone->isCollecting()) { traceRuntimeAtoms(trc, session.checkAtomsAccess()); } - traceKeptAtoms(trc); { // Trace incoming cross compartment edges from uncollected compartments, @@ -327,17 +332,6 @@ void js::gc::GCRuntime::traceRuntimeAtoms(JSTracer* trc, jit::JitRuntime::Trace(trc, access); } -void js::gc::GCRuntime::traceKeptAtoms(JSTracer* trc) { - // We don't have exact rooting information for atoms while parsing. When - // this is happeninng we set a flag on the zone and trace all atoms in the - // zone's cache. - for (GCZonesIter zone(this); !zone.done(); zone.next()) { - if (zone->hasKeptAtoms()) { - zone->traceAtomCache(trc); - } - } -} - void js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark) { { @@ -456,6 +450,7 @@ class AssertNoRootsTracer final : public JS::CallbackTracer { void js::gc::GCRuntime::finishRoots() { AutoNoteSingleThreadedRegion anstr; + rt->finishParserAtoms(); rt->finishAtoms(); rootsHash.ref().clear(); diff --git a/js/src/gc/Scheduling.cpp b/js/src/gc/Scheduling.cpp index 0de6442a79..5d8898f77a 100644 --- a/js/src/gc/Scheduling.cpp +++ b/js/src/gc/Scheduling.cpp @@ -9,6 +9,7 @@ #include +#include "gc/Nursery.h" #include "gc/RelocationOverlay.h" #include "gc/ZoneAllocator.h" #include "vm/MutexIDs.h" @@ -37,8 +38,8 @@ static constexpr double MinHeapGrowthFactor = GCSchedulingTunables::GCSchedulingTunables() : gcMaxBytes_(0), - gcMinNurseryBytes_(TuningDefaults::GCMinNurseryBytes), - gcMaxNurseryBytes_(JS::DefaultNurseryMaxBytes), + gcMinNurseryBytes_(Nursery::roundSize(TuningDefaults::GCMinNurseryBytes)), + gcMaxNurseryBytes_(Nursery::roundSize(JS::DefaultNurseryMaxBytes)), gcZoneAllocThresholdBase_(TuningDefaults::GCZoneAllocThresholdBase), smallHeapIncrementalLimit_(TuningDefaults::SmallHeapIncrementalLimit), largeHeapIncrementalLimit_(TuningDefaults::LargeHeapIncrementalLimit), @@ -76,14 +77,21 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, gcMaxBytes_ = value; break; case JSGC_MIN_NURSERY_BYTES: - if (value > gcMaxNurseryBytes_ || value < ArenaSize || - value >= MaxNurseryBytes) { + if (value < ArenaSize || value >= MaxNurseryBytes) { + return false; + } + value = Nursery::roundSize(value); + if (value > gcMaxNurseryBytes_) { return false; } gcMinNurseryBytes_ = value; break; case JSGC_MAX_NURSERY_BYTES: - if (value < gcMinNurseryBytes_ || value >= MaxNurseryBytes) { + if (value < ArenaSize || value >= MaxNurseryBytes) { + return false; + } + value = Nursery::roundSize(value); + if (value < gcMinNurseryBytes_) { return false; } gcMaxNurseryBytes_ = value; diff --git a/js/src/gc/Scheduling.h b/js/src/gc/Scheduling.h index 99befddf23..820c02c283 100644 --- a/js/src/gc/Scheduling.h +++ b/js/src/gc/Scheduling.h @@ -419,6 +419,12 @@ static const size_t MallocThresholdBase = 38 * 1024 * 1024; /* JSGC_MALLOC_GROWTH_FACTOR */ static const double MallocGrowthFactor = 1.5; +/* JSGC_HELPER_THREAD_RATIO */ +static const double HelperThreadRatio = 0.5; + +/* JSGC_MAX_HELPER_THREADS */ +static const size_t MaxHelperThreads = 8; + } // namespace TuningDefaults /* diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index a1f9a35fdc..59cbe1f507 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -17,6 +17,7 @@ #include "debugger/DebugAPI.h" #include "gc/GC.h" #include "gc/Memory.h" +#include "js/friend/UsageStatistics.h" // JS_TELEMETRY_* #include "util/Text.h" #include "vm/HelperThreads.h" #include "vm/Runtime.h" @@ -79,10 +80,10 @@ JS_PUBLIC_API bool JS::InternalGCReason(JS::GCReason reason) { return reason < JS::GCReason::FIRST_FIREFOX_REASON; } -const char* js::gcstats::ExplainAbortReason(gc::AbortReason reason) { +const char* js::gcstats::ExplainAbortReason(GCAbortReason reason) { switch (reason) { #define SWITCH_REASON(name, _) \ - case gc::AbortReason::name: \ + case GCAbortReason::name: \ return #name; GC_ABORT_REASONS(SWITCH_REASON) @@ -613,8 +614,7 @@ void Statistics::writeLogMessage(const char* fmt, ...) { } #endif -UniqueChars Statistics::renderJsonMessage(uint64_t timestamp, - Statistics::JSONUse use) const { +UniqueChars Statistics::renderJsonMessage() const { /* * The format of the JSON message is specified by the GCMajorMarkerPayload * type in profiler.firefox.com @@ -634,18 +634,10 @@ UniqueChars Statistics::renderJsonMessage(uint64_t timestamp, JSONPrinter json(printer); json.beginObject(); - json.property("status", "completed"); // JSON Key #1 - formatJsonDescription(timestamp, json, use); // #2-22 + json.property("status", "completed"); + formatJsonDescription(json); - if (use == Statistics::JSONUse::TELEMETRY) { - json.beginListProperty("slices_list"); // #23 - for (unsigned i = 0; i < slices_.length(); i++) { - formatJsonSlice(i, json); - } - json.endList(); - } - - json.beginObjectProperty("totals"); // #24 + json.beginObjectProperty("totals"); formatJsonPhaseTimes(phaseTimes, json); json.endObject(); @@ -654,84 +646,61 @@ UniqueChars Statistics::renderJsonMessage(uint64_t timestamp, return printer.release(); } -void Statistics::formatJsonDescription(uint64_t timestamp, JSONPrinter& json, - JSONUse use) const { +void Statistics::formatJsonDescription(JSONPrinter& json) const { // If you change JSON properties here, please update: - // Telemetry ping code: - // toolkit/components/telemetry/other/GCTelemetry.jsm - // Telemetry documentation: - // toolkit/components/telemetry/docs/data/main-ping.rst - // Telemetry tests: - // toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js, - // toolkit/components/telemetry/tests/unit/test_TelemetryGC.js // Firefox Profiler: // https://github.com/firefox-devtools/profiler - // - // Please also number each property to help correctly maintain the Telemetry - // ping code - - json.property("timestamp", timestamp); // # JSON Key #2 TimeDuration total, longest; gcDuration(&total, &longest); - json.property("max_pause", longest, JSONPrinter::MILLISECONDS); // #3 - json.property("total_time", total, JSONPrinter::MILLISECONDS); // #4 + json.property("max_pause", longest, JSONPrinter::MILLISECONDS); + json.property("total_time", total, JSONPrinter::MILLISECONDS); // We might be able to omit reason if profiler.firefox.com was able to retrive // it from the first slice. But it doesn't do this yet. - json.property("reason", ExplainGCReason(slices_[0].reason)); // #5 - json.property("zones_collected", zoneStats.collectedZoneCount); // #6 - json.property("total_zones", zoneStats.zoneCount); // #7 - json.property("total_compartments", zoneStats.compartmentCount); // #8 - json.property("minor_gcs", getCount(COUNT_MINOR_GC)); // #9 + json.property("reason", ExplainGCReason(slices_[0].reason)); + json.property("zones_collected", zoneStats.collectedZoneCount); + json.property("total_zones", zoneStats.zoneCount); + json.property("total_compartments", zoneStats.compartmentCount); + json.property("minor_gcs", getCount(COUNT_MINOR_GC)); uint32_t storebufferOverflows = getCount(COUNT_STOREBUFFER_OVERFLOW); if (storebufferOverflows) { - json.property("store_buffer_overflows", storebufferOverflows); // #10 + json.property("store_buffer_overflows", storebufferOverflows); } - json.property("slices", slices_.length()); // #11 + json.property("slices", slices_.length()); const double mmu20 = computeMMU(TimeDuration::FromMilliseconds(20)); const double mmu50 = computeMMU(TimeDuration::FromMilliseconds(50)); - json.property("mmu_20ms", int(mmu20 * 100)); // #12 - json.property("mmu_50ms", int(mmu50 * 100)); // #13 + json.property("mmu_20ms", int(mmu20 * 100)); + json.property("mmu_50ms", int(mmu50 * 100)); TimeDuration sccTotal, sccLongest; sccDurations(&sccTotal, &sccLongest); - json.property("scc_sweep_total", sccTotal, JSONPrinter::MILLISECONDS); // #14 - json.property("scc_sweep_max_pause", sccLongest, - JSONPrinter::MILLISECONDS); // #15 + json.property("scc_sweep_total", sccTotal, JSONPrinter::MILLISECONDS); + json.property("scc_sweep_max_pause", sccLongest, JSONPrinter::MILLISECONDS); - if (nonincrementalReason_ != AbortReason::None) { + if (nonincrementalReason_ != GCAbortReason::None) { json.property("nonincremental_reason", - ExplainAbortReason(nonincrementalReason_)); // #16 - } - json.property("allocated_bytes", preHeapSize); // #17 - if (use == Statistics::JSONUse::PROFILER) { - json.property("post_heap_size", postHeapSize); + ExplainAbortReason(nonincrementalReason_)); } + json.property("allocated_bytes", preHeapSize); + json.property("post_heap_size", postHeapSize); uint32_t addedChunks = getCount(COUNT_NEW_CHUNK); if (addedChunks) { - json.property("added_chunks", addedChunks); // #18 + json.property("added_chunks", addedChunks); } uint32_t removedChunks = getCount(COUNT_DESTROY_CHUNK); if (removedChunks) { - json.property("removed_chunks", removedChunks); // #19 + json.property("removed_chunks", removedChunks); } - json.property("major_gc_number", startingMajorGCNumber); // #20 - json.property("minor_gc_number", startingMinorGCNumber); // #21 - json.property("slice_number", startingSliceNumber); // #22 + json.property("major_gc_number", startingMajorGCNumber); + json.property("minor_gc_number", startingMinorGCNumber); + json.property("slice_number", startingSliceNumber); } void Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice, JSONPrinter& json) const { // If you change JSON properties here, please update: - // Telemetry ping code: - // toolkit/components/telemetry/other/GCTelemetry.jsm - // Telemetry documentation: - // toolkit/components/telemetry/docs/data/main-ping.rst - // Telemetry tests: - // toolkit/components/telemetry/tests/browser/browser_TelemetryGC.js, - // toolkit/components/telemetry/tests/unit/test_TelemetryGC.js // Firefox Profiler: // https://github.com/firefox-devtools/profiler // @@ -739,24 +708,24 @@ void Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice, slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1); TimeStamp originTime = TimeStamp::ProcessCreation(); - json.property("slice", i); // JSON Property #1 - json.property("pause", slice.duration(), JSONPrinter::MILLISECONDS); // #2 - json.property("reason", ExplainGCReason(slice.reason)); // #3 - json.property("initial_state", gc::StateName(slice.initialState)); // #4 - json.property("final_state", gc::StateName(slice.finalState)); // #5 - json.property("budget", budgetDescription); // #6 - json.property("major_gc_number", startingMajorGCNumber); // #7 + json.property("slice", i); + json.property("pause", slice.duration(), JSONPrinter::MILLISECONDS); + json.property("reason", ExplainGCReason(slice.reason)); + json.property("initial_state", gc::StateName(slice.initialState)); + json.property("final_state", gc::StateName(slice.finalState)); + json.property("budget", budgetDescription); + json.property("major_gc_number", startingMajorGCNumber); if (slice.trigger) { Trigger trigger = slice.trigger.value(); - json.property("trigger_amount", trigger.amount); // #8 - json.property("trigger_threshold", trigger.threshold); // #9 + json.property("trigger_amount", trigger.amount); + json.property("trigger_threshold", trigger.threshold); } int64_t numFaults = slice.endFaults - slice.startFaults; if (numFaults != 0) { - json.property("page_faults", numFaults); // #10 + json.property("page_faults", numFaults); } json.property("start_timestamp", slice.start - originTime, - JSONPrinter::SECONDS); // #11 + JSONPrinter::SECONDS); } void Statistics::formatJsonPhaseTimes(const PhaseTimeTable& phaseTimes, @@ -773,7 +742,7 @@ Statistics::Statistics(GCRuntime* gc) : gc(gc), gcTimerFile(nullptr), gcDebugFile(nullptr), - nonincrementalReason_(gc::AbortReason::None), + nonincrementalReason_(GCAbortReason::None), allocsSinceMinorGC({0, 0}), preHeapSize(0), postHeapSize(0), @@ -1018,7 +987,7 @@ void Statistics::beginGC(JSGCInvocationKind kind) { slices_.clearAndFree(); sccTimes.clearAndFree(); gckind = kind; - nonincrementalReason_ = gc::AbortReason::None; + nonincrementalReason_ = GCAbortReason::None; preHeapSize = gc->heapSize.bytes(); startingMajorGCNumber = gc->majorGCCount(); @@ -1039,14 +1008,11 @@ void Statistics::endGC() { size_t markCount = gc->marker.getMarkCount(); double markRate = markCount / markTime; runtime->addTelemetry(JS_TELEMETRY_GC_MARK_MS, markTime); - runtime->addTelemetry(JS_TELEMETRY_GC_MARK_RATE, markRate); runtime->addTelemetry(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[Phase::SWEEP])); if (gc->didCompactZones()) { runtime->addTelemetry(JS_TELEMETRY_GC_COMPACT_MS, t(phaseTimes[Phase::COMPACT])); } - runtime->addTelemetry(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(markRootsTotal)); - runtime->addTelemetry(JS_TELEMETRY_GC_MARK_GRAY_MS, t(markGrayTotal)); runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL, nonincremental()); if (nonincremental()) { runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, @@ -1153,7 +1119,6 @@ void Statistics::endSlice() { if (slice.budget.isTimeBudget()) { int64_t budget_ms = slice.budget.timeBudget.budget; - runtime->addTelemetry(JS_TELEMETRY_GC_BUDGET_MS, budget_ms); if (budget_ms == runtime->gc.defaultSliceBudgetMS()) { runtime->addTelemetry(JS_TELEMETRY_GC_ANIMATION_MS, t(sliceTime)); } @@ -1531,8 +1496,8 @@ void Statistics::printSliceProfile() { maybePrintProfileHeaders(); bool shrinking = gckind == GC_SHRINK; - bool reset = slice.resetReason != AbortReason::None; - bool nonIncremental = nonincrementalReason_ != AbortReason::None; + bool reset = slice.resetReason != GCAbortReason::None; + bool nonIncremental = nonincrementalReason_ != GCAbortReason::None; bool full = zoneStats.isFullCollection(); fprintf(stderr, "MajorGC: %20s %1d -> %1d %1s%1s%1s%1s ", diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index d3e1e0bd36..10ef1cf204 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -116,7 +116,7 @@ struct Trigger { _(EvictNursery, "evict", PhaseKind::EVICT_NURSERY) \ _(Barriers, "brrier", PhaseKind::BARRIER) -const char* ExplainAbortReason(gc::AbortReason reason); +const char* ExplainAbortReason(GCAbortReason reason); const char* ExplainInvocationKind(JSGCInvocationKind gckind); /* @@ -184,21 +184,21 @@ struct Statistics { void sweptZone() { ++zoneStats.sweptZoneCount; } void sweptCompartment() { ++zoneStats.sweptCompartmentCount; } - void reset(gc::AbortReason reason) { - MOZ_ASSERT(reason != gc::AbortReason::None); + void reset(GCAbortReason reason) { + MOZ_ASSERT(reason != GCAbortReason::None); if (!aborted) { slices_.back().resetReason = reason; } } - void nonincremental(gc::AbortReason reason) { - MOZ_ASSERT(reason != gc::AbortReason::None); + void nonincremental(GCAbortReason reason) { + MOZ_ASSERT(reason != GCAbortReason::None); nonincrementalReason_ = reason; writeLogMessage("Non-incremental reason: %s", nonincrementalReason()); } bool nonincremental() const { - return nonincrementalReason_ != gc::AbortReason::None; + return nonincrementalReason_ != GCAbortReason::None; } const char* nonincrementalReason() const { @@ -264,7 +264,7 @@ struct Statistics { mozilla::Maybe trigger; gc::State initialState = gc::State::NotActive; gc::State finalState = gc::State::NotActive; - gc::AbortReason resetReason = gc::AbortReason::None; + GCAbortReason resetReason = GCAbortReason::None; TimeStamp start; TimeStamp end; size_t startFaults = 0; @@ -273,7 +273,7 @@ struct Statistics { PhaseTimeTable maxParallelTimes; TimeDuration duration() const { return end - start; } - bool wasReset() const { return resetReason != gc::AbortReason::None; } + bool wasReset() const { return resetReason != GCAbortReason::None; } }; typedef Vector SliceDataVector; @@ -293,11 +293,11 @@ struct Statistics { // Print total profile times on shutdown. void printTotalProfileTimes(); - enum JSONUse { TELEMETRY, PROFILER }; + // These JSON strings are used by the firefox profiler to display the GC + // markers. - // Return JSON for a whole major GC. If use == PROFILER then - // detailed per-slice data and some other fields will be included. - UniqueChars renderJsonMessage(uint64_t timestamp, JSONUse use) const; + // Return JSON for a whole major GC + UniqueChars renderJsonMessage() const; // Return JSON for the timings of just the given slice. UniqueChars renderJsonSlice(size_t sliceNum) const; @@ -325,7 +325,7 @@ struct Statistics { JSGCInvocationKind gckind; - gc::AbortReason nonincrementalReason_; + GCAbortReason nonincrementalReason_; SliceDataVector slices_; @@ -448,7 +448,7 @@ struct Statistics { UniqueChars formatDetailedPhaseTimes(const PhaseTimeTable& phaseTimes) const; UniqueChars formatDetailedTotals() const; - void formatJsonDescription(uint64_t timestamp, JSONPrinter&, JSONUse) const; + void formatJsonDescription(JSONPrinter&) const; void formatJsonSliceDescription(unsigned i, const SliceData& slice, JSONPrinter&) const; void formatJsonPhaseTimes(const PhaseTimeTable& phaseTimes, diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index c44d63d90d..7437e281be 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -28,7 +28,8 @@ JS_PUBLIC_API void js::gc::UnlockStoreBuffer(StoreBuffer* sb) { } bool StoreBuffer::WholeCellBuffer::init() { - MOZ_ASSERT(!head_); + MOZ_ASSERT(!stringHead_); + MOZ_ASSERT(!nonStringHead_); if (!storage_) { storage_ = MakeUnique(LifoAllocBlockSize); // This prevents LifoAlloc::Enum from crashing with a release @@ -82,7 +83,8 @@ StoreBuffer::StoreBuffer(JSRuntime* rt, const Nursery& nursery) mayHavePointersToDeadCells_(false) #ifdef DEBUG , - mEntered(false) + mEntered(false), + markingNondeduplicatable(false) #endif { } @@ -185,14 +187,21 @@ ArenaCellSet* StoreBuffer::WholeCellBuffer::allocateCellSet(Arena* arena) { return nullptr; } + // Maintain separate lists for strings and non-strings, so that all buffered + // string whole cells will be processed before anything else (to prevent them + // from being deduplicated when their chars are used by a tenured string.) + bool isString = + MapAllocToTraceKind(arena->getAllocKind()) == JS::TraceKind::String; + AutoEnterOOMUnsafeRegion oomUnsafe; - auto cells = storage_->new_(arena, head_); + ArenaCellSet*& head = isString ? stringHead_ : nonStringHead_; + auto cells = storage_->new_(arena, head); if (!cells) { oomUnsafe.crash("Failed to allocate ArenaCellSet"); } arena->bufferedCells() = cells; - head_ = cells; + head = cells; if (isAboutToOverflow()) { rt->gc.storeBuffer().setAboutToOverflow( @@ -203,10 +212,12 @@ ArenaCellSet* StoreBuffer::WholeCellBuffer::allocateCellSet(Arena* arena) { } void StoreBuffer::WholeCellBuffer::clear() { - for (ArenaCellSet* set = head_; set; set = set->next) { - set->arena->bufferedCells() = &ArenaCellSet::Empty; + for (auto** headPtr : { &stringHead_, &nonStringHead_ }) { + for (auto* set = *headPtr; set; set = set->next) { + set->arena->bufferedCells() = &ArenaCellSet::Empty; + } + *headPtr = nullptr; } - head_ = nullptr; if (storage_) { storage_->used() ? storage_->releaseAll() : storage_->freeAll(); diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 287557f731..f30e4781b8 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -20,8 +20,33 @@ #include "threading/Mutex.h" namespace js { + +#ifdef DEBUG +extern bool CurrentThreadIsGCMarking(); +#endif + namespace gc { +// Map from all trace kinds to the base GC type. +template +struct MapTraceKindToType {}; + +#define DEFINE_TRACE_KIND_MAP(name, type, _, _1) \ + template <> \ + struct MapTraceKindToType { \ + using Type = type; \ + }; +JS_FOR_EACH_TRACEKIND(DEFINE_TRACE_KIND_MAP); +#undef DEFINE_TRACE_KIND_MAP + +// Map from a possibly-derived type to the base GC type. +template +struct BaseGCType { + using type = + typename MapTraceKindToType::kind>::Type; + static_assert(std::is_base_of_v, "Failed to find base type"); +}; + class Arena; class ArenaCellSet; @@ -143,11 +168,15 @@ class StoreBuffer { struct WholeCellBuffer { UniquePtr storage_; - ArenaCellSet* head_; + ArenaCellSet* stringHead_; + ArenaCellSet* nonStringHead_; StoreBuffer* owner_; explicit WholeCellBuffer(StoreBuffer* owner) - : storage_(nullptr), head_(nullptr), owner_(owner) {} + : storage_(nullptr), + stringHead_(nullptr), + nonStringHead_(nullptr), + owner_(owner) {} MOZ_MUST_USE bool init(); @@ -167,8 +196,9 @@ class StoreBuffer { } bool isEmpty() const { - MOZ_ASSERT_IF(!head_, !storage_ || storage_->isEmpty()); - return !head_; + MOZ_ASSERT_IF(!stringHead_ && !nonStringHead_, + !storage_ || storage_->isEmpty()); + return !stringHead_ && !nonStringHead_; } private: @@ -387,8 +417,8 @@ class StoreBuffer { inline void CheckAccess() const { #ifdef DEBUG if (JS::RuntimeHeapIsBusy()) { - MOZ_ASSERT((CurrentThreadCanAccessRuntime(runtime_) && !lock_.isHeld()) || - lock_.ownedByCurrentThread()); + MOZ_ASSERT(!CurrentThreadIsGCMarking()); + MOZ_ASSERT(lock_.ownedByCurrentThread()); } else { MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime_)); } @@ -440,6 +470,10 @@ class StoreBuffer { #endif public: +#ifdef DEBUG + bool markingNondeduplicatable; +#endif + explicit StoreBuffer(JSRuntime* rt, const Nursery& nursery); MOZ_MUST_USE bool enable(); @@ -583,6 +617,8 @@ class ArenaCellSet { WordT getWord(size_t wordIndex) const { return bits.getWord(wordIndex); } + void trace(TenuringTracer& mover); + // Sentinel object used for all empty sets. // // We use a sentinel because it simplifies the JIT code slightly as we can @@ -601,6 +637,49 @@ class ArenaCellSet { static size_t offsetOfBits() { return offsetof(ArenaCellSet, bits); } }; +// Post-write barrier implementation for GC cells. + +// Implement the post-write barrier for nursery allocateable cell type |T|. Call +// this from |T::postWriteBarrier|. +template +MOZ_ALWAYS_INLINE void PostWriteBarrierImpl(void* cellp, T* prev, T* next) { + MOZ_ASSERT(cellp); + + // If the target needs an entry, add it. + js::gc::StoreBuffer* buffer; + if (next && (buffer = next->storeBuffer())) { + // If we know that the prev has already inserted an entry, we can skip + // doing the lookup to add the new entry. Note that we cannot safely + // assert the presence of the entry because it may have been added + // via a different store buffer. + if (prev && prev->storeBuffer()) { + return; + } + buffer->putCell(static_cast(cellp)); + return; + } + + // Remove the prev entry if the new value does not need it. There will only + // be a prev entry if the prev value was in the nursery. + if (prev && (buffer = prev->storeBuffer())) { + buffer->unputCell(static_cast(cellp)); + } +} + +template +MOZ_ALWAYS_INLINE void PostWriteBarrier(T** vp, T* prev, T* next) { + static_assert(std::is_base_of_v); + static_assert(!std::is_same_v && !std::is_same_v); + + if constexpr (!std::is_base_of_v) { + using BaseT = typename gc::BaseGCType::type; + gc::PostWriteBarrierImpl(vp, prev, next); + return; + } + + MOZ_ASSERT(!IsInsideNursery(next)); +} + } /* namespace gc */ } /* namespace js */ diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index b84d11ef00..3f20a9fbe8 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -96,14 +96,14 @@ void js::TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind) { MOZ_ASSERT(thing); ApplyGCThingTyped(thing, kind, [trc](auto t) { MOZ_ASSERT_IF(t->runtimeFromAnyThread() != trc->runtime(), - ThingIsPermanentAtomOrWellKnownSymbol(t) || + t->isPermanentAndMayBeShared() || t->zoneFromAnyThread()->isSelfHostingZone()); t->traceChildren(trc); }); } -JS_PUBLIC_API void JS::TraceIncomingCCWs( - JSTracer* trc, const JS::CompartmentSet& compartments) { +void js::gc::TraceIncomingCCWs(JSTracer* trc, + const JS::CompartmentSet& compartments) { for (CompartmentsIter source(trc->runtime()); !source.done(); source.next()) { if (compartments.has(source)) { continue; @@ -310,7 +310,7 @@ JS_PUBLIC_API void JS_GetTraceThingInfo(char* buf, size_t bufsize, } case JS::TraceKind::Script: { - js::BaseScript* script = static_cast(thing); + auto* script = static_cast(thing); snprintf(buf, bufsize, " %s:%u", script->filename(), script->lineno()); break; } @@ -339,7 +339,7 @@ JS_PUBLIC_API void JS_GetTraceThingInfo(char* buf, size_t bufsize, } case JS::TraceKind::Symbol: { - JS::Symbol* sym = static_cast(thing); + auto* sym = static_cast(thing); if (JSAtom* desc = sym->description()) { *buf++ = ' '; bufsize--; @@ -351,7 +351,7 @@ JS_PUBLIC_API void JS_GetTraceThingInfo(char* buf, size_t bufsize, } case JS::TraceKind::Scope: { - js::Scope* scope = static_cast(thing); + auto* scope = static_cast(thing); snprintf(buf, bufsize, " %s", js::ScopeKindString(scope->kind())); break; } diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index 41fe57b4c3..5ffa62fed3 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -5,9 +5,14 @@ #ifndef js_Tracer_h #define js_Tracer_h -#include "jsfriendapi.h" - #include "gc/Barrier.h" +#include "js/HashTable.h" + +namespace JS { +using CompartmentSet = + js::HashSet, + js::SystemAllocPolicy>; +} // namespace JS namespace js { @@ -49,26 +54,6 @@ namespace js { namespace gc { -// Map from all trace kinds to the base GC type. -template -struct MapTraceKindToType {}; - -#define DEFINE_TRACE_KIND_MAP(name, type, _, _1) \ - template <> \ - struct MapTraceKindToType { \ - using Type = type; \ - }; -JS_FOR_EACH_TRACEKIND(DEFINE_TRACE_KIND_MAP); -#undef DEFINE_TRACE_KIND_MAP - -// Map from a possibly-derived type to the base GC type. -template -struct BaseGCType { - using type = - typename MapTraceKindToType::kind>::Type; - static_assert(std::is_base_of_v, "Failed to find base type"); -}; - // Our barrier templates are parameterized on the pointer types so that we can // share the definitions with Value and jsid. Thus, we need to strip the // pointer before sending the type to BaseGCType and re-add it on the other @@ -120,23 +105,23 @@ inline void AssertRootMarkingPhase(JSTracer* trc) {} template inline void TraceEdge(JSTracer* trc, const WriteBarriered* thingp, const char* name) { - gc::TraceEdgeInternal( - trc, gc::ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name); + gc::TraceEdgeInternal(trc, gc::ConvertToBase(thingp->unbarrieredAddress()), + name); } template inline void TraceEdge(JSTracer* trc, WeakHeapPtr* thingp, const char* name) { - gc::TraceEdgeInternal(trc, gc::ConvertToBase(thingp->unsafeGet()), name); + gc::TraceEdgeInternal(trc, gc::ConvertToBase(thingp->unbarrieredAddress()), name); } -template -inline void TraceEdge(JSTracer* trc, - gc::CellHeaderWithTenuredGCPointer* thingp, - const char* name) { - T* thing = thingp->ptr(); +template +inline void TraceCellHeaderEdge(JSTracer* trc, + gc::CellWithTenuredGCPointer* thingp, + const char* name) { + T* thing = thingp->headerPtr(); gc::TraceEdgeInternal(trc, gc::ConvertToBase(&thing), name); - if (thing != thingp->ptr()) { - thingp->unsafeSetPtr(thing); + if (thing != thingp->headerPtr()) { + thingp->unbarrieredSetHeaderPtr(thing); } } @@ -159,15 +144,15 @@ inline void TraceNullableEdge(JSTracer* trc, WeakHeapPtr* thingp, } } -template -inline void TraceNullableEdge(JSTracer* trc, - gc::CellHeaderWithTenuredGCPointer* thingp, - const char* name) { - T* thing = thingp->ptr(); +template +inline void TraceNullableCellHeaderEdge( + JSTracer* trc, gc::CellWithTenuredGCPointer* thingp, + const char* name) { + T* thing = thingp->headerPtr(); if (thing) { gc::TraceEdgeInternal(trc, gc::ConvertToBase(&thing), name); - if (thing != thingp->ptr()) { - thingp->unsafeSetPtr(thing); + if (thing != thingp->headerPtr()) { + thingp->unbarrieredSetHeaderPtr(thing); } } } @@ -184,7 +169,7 @@ inline void TraceRoot(JSTracer* trc, T* thingp, const char* name) { template inline void TraceRoot(JSTracer* trc, WeakHeapPtr* thingp, const char* name) { - TraceRoot(trc, thingp->unsafeGet(), name); + TraceRoot(trc, thingp->unbarrieredAddress(), name); } // Idential to TraceRoot, except that this variant will not crash if |*thingp| @@ -201,7 +186,7 @@ inline void TraceNullableRoot(JSTracer* trc, T* thingp, const char* name) { template inline void TraceNullableRoot(JSTracer* trc, WeakHeapPtr* thingp, const char* name) { - TraceNullableRoot(trc, thingp->unsafeGet(), name); + TraceNullableRoot(trc, thingp->unbarrieredAddress(), name); } // Like TraceEdge, but for edges that do not use one of the automatic barrier @@ -227,16 +212,16 @@ template inline bool TraceWeakEdge(JSTracer* trc, BarrieredBase* thingp, const char* name) { return gc::TraceEdgeInternal( - trc, gc::ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name); + trc, gc::ConvertToBase(thingp->unbarrieredAddress()), name); } // Trace all edges contained in the given array. template -void TraceRange(JSTracer* trc, size_t len, WriteBarriered* vec, +void TraceRange(JSTracer* trc, size_t len, BarrieredBase* vec, const char* name) { - gc::TraceRangeInternal( - trc, len, gc::ConvertToBase(vec[0].unsafeUnbarrieredForTracing()), name); + gc::TraceRangeInternal(trc, len, + gc::ConvertToBase(vec[0].unbarrieredAddress()), name); } // Trace all root edges in the given array. @@ -258,7 +243,7 @@ template void TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src, const WriteBarriered* dst, const char* name) { TraceManuallyBarrieredCrossCompartmentEdge( - trc, src, gc::ConvertToBase(dst->unsafeUnbarrieredForTracing()), name); + trc, src, gc::ConvertToBase(dst->unbarrieredAddress()), name); } // Trace a weak map key. For debugger weak maps these may be cross compartment, @@ -272,8 +257,7 @@ inline void TraceWeakMapKeyEdge(JSTracer* trc, Zone* weakMapZone, const WriteBarriered* thingp, const char* name) { TraceWeakMapKeyEdgeInternal( - trc, weakMapZone, - gc::ConvertToBase(thingp->unsafeUnbarrieredForTracing()), name); + trc, weakMapZone, gc::ConvertToBase(thingp->unbarrieredAddress()), name); } // Permanent atoms and well-known symbols are shared between runtimes and must @@ -304,6 +288,13 @@ namespace gc { void TraceCycleCollectorChildren(JS::CallbackTracer* trc, Shape* shape); void TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group); +/** + * Trace every value within |compartments| that is wrapped by a + * cross-compartment wrapper from a compartment that is not an element of + * |compartments|. + */ +void TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments); + } // namespace gc } // namespace js diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 43c816623a..a1241088e2 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -4,10 +4,10 @@ #include "mozilla/DebugOnly.h" #include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/Move.h" #include "mozilla/Sprintf.h" #include +#include #ifdef MOZ_VALGRIND # include @@ -18,6 +18,7 @@ #include "gc/PublicIterators.h" #include "gc/WeakMap.h" #include "gc/Zone.h" +#include "js/friend/DumpFunctions.h" // js::DumpObject #include "js/HashTable.h" #include "vm/JSContext.h" @@ -184,7 +185,7 @@ void gc::GCRuntime::startVerifyPreBarriers() { JSContext* cx = rt->mainContextFromOwnThread(); - if (IsIncrementalGCUnsafe(rt) != AbortReason::None || + if (IsIncrementalGCUnsafe(rt) != GCAbortReason::None || rt->hasHelperThreadZones()) { return; } @@ -305,7 +306,7 @@ bool CheckEdgeTracer::onChild(const JS::GCCellPtr& thing) { return true; } -void js::gc::AssertSafeToSkipBarrier(TenuredCell* thing) { +void js::gc::AssertSafeToSkipPreWriteBarrier(TenuredCell* thing) { mozilla::DebugOnly zone = thing->zoneFromAnyThread(); MOZ_ASSERT(!zone->needsIncrementalBarrier() || zone->isAtomsZone()); } @@ -362,7 +363,7 @@ void gc::GCRuntime::endVerifyPreBarriers() { MOZ_ASSERT(incrementalState == State::Mark); incrementalState = State::NotActive; - if (!compartmentCreated && IsIncrementalGCUnsafe(rt) == AbortReason::None && + if (!compartmentCreated && IsIncrementalGCUnsafe(rt) == GCAbortReason::None && !rt->hasHelperThreadZones()) { CheckEdgeTracer cetrc(rt); @@ -498,7 +499,7 @@ void js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) { MOZ_ASSERT(!gcmarker->isWeakMarking()); /* Wait for off-thread parsing which can allocate. */ - HelperThreadState().waitForAllThreads(); + WaitForAllHelperThreads(); gc->waitBackgroundAllocEnd(); gc->waitBackgroundSweepEnd(); @@ -631,8 +632,14 @@ void js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) { for (auto chunk = gc->allNonEmptyChunks(lock); !chunk.done(); chunk.next()) { ChunkBitmap* bitmap = &chunk->bitmap; - ChunkBitmap* entry = map.lookup(chunk)->value().get(); - mozilla::Swap(*entry, *bitmap); + auto ptr = map.lookup(chunk); + MOZ_RELEASE_ASSERT(ptr, "Chunk not found in map"); + ChunkBitmap* entry = ptr->value().get(); + for (size_t i = 0; i < ChunkBitmap::WordCount; i++) { + uintptr_t v = entry->bitmap[i]; + entry->bitmap[i] = uintptr_t(bitmap->bitmap[i]); + bitmap->bitmap[i] = v; + } } } @@ -698,7 +705,7 @@ void js::gc::MarkingValidator::validate() { uintptr_t thing = arena->thingsStart(); uintptr_t end = arena->thingsEnd(); while (thing < end) { - auto cell = reinterpret_cast(thing); + auto* cell = reinterpret_cast(thing); /* * If a non-incremental GC wouldn't have collected a cell, then @@ -1084,3 +1091,24 @@ bool js::gc::CheckWeakMapEntryMarking(const WeakMapBase* map, Cell* key, } #endif // defined(JS_GC_ZEAL) || defined(DEBUG) + +#ifdef DEBUG +// Return whether an arbitrary pointer is within a cell with the given +// traceKind. Only for assertions. +bool GCRuntime::isPointerWithinTenuredCell(void* ptr, JS::TraceKind traceKind) { + AutoLockGC lock(this); + for (auto chunk = allNonEmptyChunks(lock); !chunk.done(); chunk.next()) { + MOZ_ASSERT(!chunk->isNurseryChunk()); + if (ptr >= &chunk->arenas[0] && ptr < &chunk->arenas[ArenasPerChunk]) { + auto* arena = reinterpret_cast(uintptr_t(ptr) & ~ArenaMask); + if (!arena->allocated()) { + return false; + } + + return MapAllocToTraceKind(arena->getAllocKind()) == traceKind; + } + } + + return false; +} +#endif // DEBUG diff --git a/js/src/gc/WeakMap-inl.h b/js/src/gc/WeakMap-inl.h index 07004ca7f4..f5caf18b52 100644 --- a/js/src/gc/WeakMap-inl.h +++ b/js/src/gc/WeakMap-inl.h @@ -81,6 +81,22 @@ inline JSObject* GetDelegate(gc::Cell* const&) = delete; } /* namespace detail */ } /* namespace gc */ +// Weakmap entry -> value edges are only visible if the map is traced, which +// only happens if the map zone is being collected. If the map and the value +// were in different zones, then we could have a case where the map zone is not +// collecting but the value zone is, and incorrectly free a value that is +// reachable solely through weakmaps. +template +void WeakMap::assertMapIsSameZoneWithValue(const V& v) { +#ifdef DEBUG + gc::Cell* cell = gc::ToMarkable(v); + if (cell) { + Zone* cellZone = cell->zoneFromAnyThread(); + MOZ_ASSERT(zone() == cellZone || cellZone->isAtomsZone()); + } +#endif +} + template WeakMap::WeakMap(JSContext* cx, JSObject* memOf) : Base(cx->zone()), WeakMapBase(memOf, cx->zone()) { diff --git a/js/src/gc/WeakMap.h b/js/src/gc/WeakMap.h index 96e35e2f32..d4ab68abd0 100644 --- a/js/src/gc/WeakMap.h +++ b/js/src/gc/WeakMap.h @@ -13,6 +13,7 @@ #include "gc/ZoneAllocator.h" #include "js/HashTable.h" #include "js/HeapAPI.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone namespace js { @@ -339,6 +340,7 @@ class WeakMap inline void forgetKey(UnbarrieredKey key); void barrierForInsert(Key k, const Value& v) { + assertMapIsSameZoneWithValue(v); if (!mapColor) { return; } @@ -353,6 +355,8 @@ class WeakMap MOZ_ASSERT(tmp == v); } + inline void assertMapIsSameZoneWithValue(const Value& v); + bool markEntries(GCMarker* marker) override; protected: diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 6fa8b9cdba..866b4d77d9 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gc/Zone-inl.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone #include @@ -165,8 +166,6 @@ JS::Zone::Zone(JSRuntime* rt) atomCache_(this), externalStringCache_(this), functionToStringCache_(this), - keepAtomsCount(this, 0), - purgeAtomsDeferred(this, 0), propertyTree_(this, this), baseShapes_(this, this), initialShapes_(this, this), @@ -483,7 +482,7 @@ void Zone::discardJitCode(JSFreeOp* fop, } void JS::Zone::beforeClearDelegateInternal(JSObject* wrapper, - JSObject* delegate) { + JSObject* delegate) { MOZ_ASSERT(js::gc::detail::GetDelegate(wrapper) == delegate); MOZ_ASSERT(needsIncrementalBarrier()); GCMarker::fromTracer(barrierTracer())->severWeakDelegate(wrapper, delegate); @@ -626,30 +625,7 @@ bool Zone::ownedByCurrentHelperThread() { return helperThreadOwnerContext_ == TlsContext.get(); } -void Zone::releaseAtoms() { - MOZ_ASSERT(hasKeptAtoms()); - - keepAtomsCount--; - - if (!hasKeptAtoms() && purgeAtomsDeferred) { - purgeAtomsDeferred = false; - purgeAtomCache(); - } -} - -void Zone::purgeAtomCacheOrDefer() { - if (hasKeptAtoms()) { - purgeAtomsDeferred = true; - return; - } - - purgeAtomCache(); -} - void Zone::purgeAtomCache() { - MOZ_ASSERT(!hasKeptAtoms()); - MOZ_ASSERT(!purgeAtomsDeferred); - atomCache().clearAndCompact(); // Also purge the dtoa caches so that subsequent lookups populate atom @@ -659,15 +635,6 @@ void Zone::purgeAtomCache() { } } -void Zone::traceAtomCache(JSTracer* trc) { - MOZ_ASSERT(hasKeptAtoms()); - for (auto r = atomCache().all(); !r.empty(); r.popFront()) { - JSAtom* atom = r.front().asPtrUnbarriered(); - TraceRoot(trc, &atom, "kept atom"); - MOZ_ASSERT(r.front().asPtrUnbarriered() == atom); - } -} - void Zone::addSizeOfIncludingThis( mozilla::MallocSizeOf mallocSizeOf, JS::CodeSizes* code, size_t* typePool, size_t* regexpZone, size_t* jitZone, size_t* baselineStubsOptimized, diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index 5bd7aad73a..26e075931e 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -57,9 +57,13 @@ using FinalizationRecordVector = GCVector; } // namespace gc +// If two different nursery strings are wrapped into the same zone, and have +// the same contents, then deduplication may make them duplicates. +// `DuplicatesPossible` will allow this and map both wrappers to the same (now +// tenured) source string. using StringWrapperMap = NurseryAwareHashMap, - ZoneAllocPolicy>; + ZoneAllocPolicy, DuplicatesPossible>; class MOZ_NON_TEMPORARY_CLASS ExternalStringCache { static const size_t NumEntries = 4; @@ -119,7 +123,7 @@ class WeakRefMap using GCHashMap::GCHashMap; using Base = GCHashMap, ZoneAllocPolicy>; - void sweep(); + void sweep(gc::StoreBuffer* sbToLock); }; } // namespace js @@ -275,8 +279,7 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase { // Bitmap of atoms marked by this zone. js::ZoneOrGCTaskData markedAtoms_; - // Set of atoms recently used by this Zone. Purged on GC unless - // keepAtomsCount is non-zero. + // Set of atoms recently used by this Zone. Purged on GC. js::ZoneOrGCTaskData atomCache_; // Cache storing allocated external strings. Purged on GC. @@ -285,21 +288,6 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase { // Cache for Function.prototype.toString. Purged on GC. js::ZoneOrGCTaskData functionToStringCache_; - // Count of AutoKeepAtoms instances for this zone. When any instances exist, - // atoms in the runtime will be marked from this zone's atom mark bitmap, - // rather than when traced in the normal way. Threads parsing off the main - // thread do not increment this value, but the presence of any such threads - // also inhibits collection of atoms. We don't scan the stacks of exclusive - // threads, so we need to avoid collecting their objects in another way. The - // only GC thing pointers they have are to their exclusive compartment - // (which is not collected) or to the atoms compartment. Therefore, we avoid - // collecting the atoms zone when exclusive threads are running. - js::ZoneOrGCTaskData keepAtomsCount; - - // Whether purging atoms was deferred due to keepAtoms being set. If this - // happen then the cache will be purged when keepAtoms drops to zero. - js::ZoneOrGCTaskData purgeAtomsDeferred; - // Shared Shape property tree. js::ZoneData propertyTree_; @@ -442,8 +430,7 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase { void setPreservingCode(bool preserving) { gcPreserveCode_ = preserving; } bool isPreservingCode() const { return gcPreserveCode_; } - // Whether this zone can currently be collected. This doesn't take account - // of AutoKeepAtoms for the atoms zone. + // Whether this zone can currently be collected. bool canCollect(); void changeGCState(GCState prev, GCState next) { @@ -597,16 +584,10 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase { bool addTypeDescrObject(JSContext* cx, HandleObject obj); - void keepAtoms() { keepAtomsCount++; } - void releaseAtoms(); - bool hasKeptAtoms() const { return keepAtomsCount; } - js::SparseBitmap& markedAtoms() { return markedAtoms_.ref(); } js::AtomSet& atomCache() { return atomCache_.ref(); } - void traceAtomCache(JSTracer* trc); - void purgeAtomCacheOrDefer(); void purgeAtomCache(); js::ExternalStringCache& externalStringCache() { diff --git a/js/src/gc/ZoneAllocator.h b/js/src/gc/ZoneAllocator.h index 2e8671ad0d..60a301388b 100644 --- a/js/src/gc/ZoneAllocator.h +++ b/js/src/gc/ZoneAllocator.h @@ -14,6 +14,7 @@ #include "gc/Scheduling.h" #include "js/GCAPI.h" #include "js/HeapAPI.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone #include "vm/MallocProvider.h" namespace JS { diff --git a/js/src/gdb/moz.build b/js/src/gdb/moz.build index a1883d5263..3409090ecb 100644 --- a/js/src/gdb/moz.build +++ b/js/src/gdb/moz.build @@ -41,6 +41,12 @@ if CONFIG['CC_TYPE'] != 'clang-cl': # this option. SOURCES['tests/test-prettyprinters.cpp'].flags += ['-fno-eliminate-unused-debug-types'] +if CONFIG['CC_TYPE'] == 'clang': + # clang has poor debuginfo when optimized. Some of the test files have + # unrecoverable values even with -Og. gcc is far better about making + # optimized code debuggable. + CXXFLAGS += ['-O0'] + DEFINES['EXPORT_JS_API'] = True LOCAL_INCLUDES += [ diff --git a/js/src/gdb/mozilla/CellHeader.py b/js/src/gdb/mozilla/CellHeader.py index 38b7816c53..fbd5aa095d 100644 --- a/js/src/gdb/mozilla/CellHeader.py +++ b/js/src/gdb/mozilla/CellHeader.py @@ -6,17 +6,15 @@ def get_header_ptr(value, ptr_t): - # Return the pointer stored in a CellHeader subclass that wraps a pointer. - assert value.type.strip_typedefs().tag.startswith('js::gc::CellHeaderWith') - return value['header_'].cast(ptr_t) + # Return the pointer stored in Cell::header_ for subclasses of + # TenuredCellWithNonGCPointer and CellWithTenuredGCPointer. + return value['header_']['mValue'].cast(ptr_t) -def get_header_length_and_flags(value): - # Return the contents of a CellHeaderWithLengthAndFlags. - assert value.type.strip_typedefs().tag == \ - 'js::gc::CellHeaderWithLengthAndFlags' - header = value['header_'] - flags = header['header_'] +def get_header_length_and_flags(value, cache): + # Return the length and flags values for subclasses of + # CellWithLengthAndFlags. + flags = value['header_']['mValue'].cast(cache.uintptr_t) try: length = value['length_'] except gdb.error: diff --git a/js/src/gdb/mozilla/Interpreter.py b/js/src/gdb/mozilla/Interpreter.py index 85cba6dbbb..aae7d90881 100644 --- a/js/src/gdb/mozilla/Interpreter.py +++ b/js/src/gdb/mozilla/Interpreter.py @@ -16,7 +16,14 @@ class InterpreterTypeCache(object): # Cache information about the Interpreter types for this objfile. def __init__(self): self.tValue = gdb.lookup_type('JS::Value') - self.tScriptFrameIterData = gdb.lookup_type('js::ScriptFrameIter::Data') + self.tJSOp = gdb.lookup_type('JSOp') + try: + self.tScriptFrameIterData = gdb.lookup_type('js::ScriptFrameIter::Data') + except gdb.error: + # Work around problem with gcc optimized debuginfo where it doesn't + # seem to be able to see that ScriptFrameIter inherits the + # FrameIter::Data type. + self.tScriptFrameIterData = gdb.lookup_type('js::FrameIter::Data') self.tInterpreterFrame = gdb.lookup_type('js::InterpreterFrame') self.tBaselineFrame = gdb.lookup_type('js::jit::BaselineFrame') self.tRematerializedFrame = gdb.lookup_type('js::jit::RematerializedFrame') diff --git a/js/src/gdb/mozilla/JSObject.py b/js/src/gdb/mozilla/JSObject.py index 702631e1ba..35655381f9 100644 --- a/js/src/gdb/mozilla/JSObject.py +++ b/js/src/gdb/mozilla/JSObject.py @@ -43,10 +43,8 @@ def __init__(self, value, cache): self.otc = cache.mod_JSObject def summary(self): - group = get_header_ptr(self.value['headerAndGroup_'], - self.otc.ObjectGroup_ptr_t) - classp = get_header_ptr(group['headerAndClasp_'], - self.otc.JSClass_ptr_t) + group = get_header_ptr(self.value, self.otc.ObjectGroup_ptr_t) + classp = get_header_ptr(group, self.otc.JSClass_ptr_t) non_native = classp['flags'] & self.otc.class_NON_NATIVE # Use GDB to format the class name, but then strip off the address @@ -61,8 +59,7 @@ def summary(self): else: native = self.value.cast(self.otc.NativeObject_ptr_t) shape = deref(native['shape_']) - baseshape = get_header_ptr(shape['headerAndBase_'], - self.otc.BaseShape_ptr_t) + baseshape = get_header_ptr(shape, self.otc.BaseShape_ptr_t) flags = baseshape['flags'] is_delegate = bool(flags & self.otc.flag_DELEGATE) name = None diff --git a/js/src/gdb/mozilla/JSString.py b/js/src/gdb/mozilla/JSString.py index e115cda6db..5b8a967cb2 100644 --- a/js/src/gdb/mozilla/JSString.py +++ b/js/src/gdb/mozilla/JSString.py @@ -44,7 +44,7 @@ def display_hint(self): def chars(self): d = self.value['d'] - length, flags = get_header_length_and_flags(self.value['header_']) + length, flags = get_header_length_and_flags(self.value, self.cache) corrupt = { 0x2f2f2f2f: 'JS_FRESH_NURSERY_PATTERN', diff --git a/js/src/gdb/mozilla/JSSymbol.py b/js/src/gdb/mozilla/JSSymbol.py index 61e409a576..37be8b9697 100644 --- a/js/src/gdb/mozilla/JSSymbol.py +++ b/js/src/gdb/mozilla/JSSymbol.py @@ -25,8 +25,7 @@ def __init__(self, value, cache): def to_string(self): code = int(self.value['code_']) & 0xffffffff - desc = str(get_header_ptr(self.value['headerAndDescription_'], - self.cache.JSString_ptr_t)) + desc = str(get_header_ptr(self.value, self.cache.JSString_ptr_t)) if code == InSymbolRegistry: return "Symbol.for({})".format(desc) elif code == UniqueSymbol: diff --git a/js/src/gdb/mozilla/jsid.py b/js/src/gdb/mozilla/PropertyKey.py similarity index 51% rename from js/src/gdb/mozilla/jsid.py rename to js/src/gdb/mozilla/PropertyKey.py index a2991abbb7..8cb63ac1b3 100644 --- a/js/src/gdb/mozilla/jsid.py +++ b/js/src/gdb/mozilla/PropertyKey.py @@ -4,7 +4,6 @@ # Pretty-printers for JSID values. -import gdb import mozilla.prettyprinters import mozilla.Root @@ -14,8 +13,8 @@ mozilla.prettyprinters.clear_module_printers(__name__) -@pretty_printer('jsid') -class jsid(object): +@pretty_printer('JS::PropertyKey') +class PropertyKey(object): # Since people don't always build with macro debugging info, I can't # think of any way to avoid copying these values here, short of using # inferior calls for every operation (which, I hear, is broken from @@ -32,31 +31,19 @@ def __init__(self, value, cache): self.cache = cache self.concrete_type = self.value.type.strip_typedefs() - # SpiderMonkey has two alternative definitions of jsid: a typedef for - # ptrdiff_t, and a struct with == and != operators defined on it. - # Extract the bits from either one. - def as_bits(self): - if self.concrete_type.code == gdb.TYPE_CODE_STRUCT: - return self.value['asBits'] - elif self.concrete_type.code == gdb.TYPE_CODE_INT: - return self.value - else: - raise RuntimeError("definition of SpiderMonkey 'jsid' type" - "neither struct nor integral type") - def to_string(self): - bits = self.as_bits() - tag = bits & jsid.TYPE_MASK - if tag == jsid.TYPE_STRING: + bits = self.value['asBits'] + tag = bits & PropertyKey.TYPE_MASK + if tag == PropertyKey.TYPE_STRING: body = bits.cast(self.cache.JSString_ptr_t) - elif tag & jsid.TYPE_INT: + elif tag & PropertyKey.TYPE_INT: body = bits >> 1 - elif tag == jsid.TYPE_VOID: + elif tag == PropertyKey.TYPE_VOID: return "JSID_VOID" - elif tag == jsid.TYPE_SYMBOL: - body = ((bits & ~jsid.TYPE_MASK) + elif tag == PropertyKey.TYPE_SYMBOL: + body = ((bits & ~PropertyKey.TYPE_MASK) .cast(self.cache.JSSymbol_ptr_t)) - elif tag == jsid.TYPE_EMPTY: + elif tag == PropertyKey.TYPE_EMPTY: return "JSID_EMPTY" else: body = "" @@ -64,22 +51,17 @@ def to_string(self): @pretty_printer('JS::Rooted') -def RootedJSID(value, cache): - # Hard-code the referent type pretty-printer for jsid roots and handles. - # See the comment for mozilla.Root.Common.__init__. - return mozilla.Root.Rooted(value, cache, jsid) +def RootedPropertyKey(value, cache): + # Hard-code the referent type pretty-printer for PropertyKey roots and + # handles. See the comment for mozilla.Root.Common.__init__. + return mozilla.Root.Rooted(value, cache, PropertyKey) @pretty_printer('JS::Handle') -def HandleJSID(value, cache): - return mozilla.Root.Handle(value, cache, jsid) +def HandlePropertyKey(value, cache): + return mozilla.Root.Handle(value, cache, PropertyKey) @pretty_printer('JS::MutableHandle') -def MutableHandleJSID(value, cache): - return mozilla.Root.MutableHandle(value, cache, jsid) - - -@pretty_printer('JS::PropertyKey') -def PropertyKey(value, cache): - return mozilla.jsid.jsid(value, cache) +def MutableHandlePropertyKey(value, cache): + return mozilla.Root.MutableHandle(value, cache, PropertyKey) diff --git a/js/src/gdb/mozilla/autoload.py b/js/src/gdb/mozilla/autoload.py index 44ac2ccdf8..23f248762d 100644 --- a/js/src/gdb/mozilla/autoload.py +++ b/js/src/gdb/mozilla/autoload.py @@ -20,7 +20,7 @@ import mozilla.JSString import mozilla.JSSymbol import mozilla.Root -import mozilla.jsid +import mozilla.PropertyKey import mozilla.jsop import mozilla.jsval import mozilla.unwind diff --git a/js/src/gdb/mozilla/prettyprinters.py b/js/src/gdb/mozilla/prettyprinters.py index 27a74d1db5..c7754e13fb 100644 --- a/js/src/gdb/mozilla/prettyprinters.py +++ b/js/src/gdb/mozilla/prettyprinters.py @@ -204,6 +204,7 @@ def __init__(self, objfile): # enough. self.void_t = gdb.lookup_type('void') self.void_ptr_t = self.void_t.pointer() + self.uintptr_t = gdb.lookup_type('uintptr_t') try: self.JSString_ptr_t = gdb.lookup_type('JSString').pointer() self.JSSymbol_ptr_t = gdb.lookup_type('JS::Symbol').pointer() diff --git a/js/src/gdb/tests/test-JSObject.cpp b/js/src/gdb/tests/test-JSObject.cpp index 08cecaa074..392c0be5ba 100644 --- a/js/src/gdb/tests/test-JSObject.cpp +++ b/js/src/gdb/tests/test-JSObject.cpp @@ -1,5 +1,6 @@ #include "gdb-tests.h" #include "jsapi.h" +#include "js/Object.h" // JS::GetClass FRAGMENT(JSObject, simple) { AutoSuppressHazardsForTest noanalysis; @@ -35,6 +36,7 @@ FRAGMENT(JSObject, simple) { use(funcPtr); use(&plainRef); use(&funcRef); + use(JS::GetClass((JSObject*)&funcRef)); use(plainRaw); use(funcRaw); } diff --git a/js/src/gdb/tests/test-jsid.py b/js/src/gdb/tests/test-jsid.py index 1a2da9f3a2..81f4637792 100644 --- a/js/src/gdb/tests/test-jsid.py +++ b/js/src/gdb/tests/test-jsid.py @@ -1,7 +1,7 @@ # Tests for jsid pretty-printing # flake8: noqa: F821 -assert_subprinter_registered('SpiderMonkey', 'jsid') +assert_subprinter_registered('SpiderMonkey', 'JS::PropertyKey') run_fragment('jsid.simple') diff --git a/js/src/gdb/tests/test-unwind.cpp b/js/src/gdb/tests/test-unwind.cpp index 7346669781..13a82bf790 100644 --- a/js/src/gdb/tests/test-unwind.cpp +++ b/js/src/gdb/tests/test-unwind.cpp @@ -1,5 +1,6 @@ #include "gdb-tests.h" #include "jsapi.h" // sundry symbols not moved to more-specific headers yet +#include "jsfriendapi.h" // JSFunctionSpecWithHelp #include "jit/JitOptions.h" // js::jit::JitOptions #include "js/CallArgs.h" // JS::CallArgs, JS::CallArgsFromVp diff --git a/js/src/irregexp/RegExpAPI.cpp b/js/src/irregexp/RegExpAPI.cpp index 8862c18a2b..088962750d 100644 --- a/js/src/irregexp/RegExpAPI.cpp +++ b/js/src/irregexp/RegExpAPI.cpp @@ -23,6 +23,7 @@ #include "irregexp/imported/regexp.h" #include "irregexp/RegExpShim.h" #include "jit/JitCommon.h" +#include "js/friend/StackLimits.h" // js::ReportOverRecursed #include "util/StringBuffer.h" #include "vm/MatchPairs.h" #include "vm/RegExpShared.h" @@ -32,7 +33,9 @@ namespace irregexp { using mozilla::AssertedCast; using mozilla::Maybe; +using mozilla::Nothing; using mozilla::PointerRangeSize; +using mozilla::Some; using frontend::DummyTokenStream; using frontend::TokenStreamAnyChars; @@ -137,7 +140,16 @@ Isolate* CreateIsolate(JSContext* cx) { return isolate.release(); } -void DestroyIsolate(Isolate* isolate) { js_delete(isolate); } +void DestroyIsolate(Isolate* isolate) { + MOZ_ASSERT(isolate->liveHandles() == 0); + MOZ_ASSERT(isolate->livePseudoHandles() == 0); + js_delete(isolate); +} + +size_t IsolateSizeOfIncludingThis(Isolate* isolate, + mozilla::MallocSizeOf mallocSizeOf) { + return isolate->sizeOfIncludingThis(mallocSizeOf); +} static size_t ComputeColumn(const Latin1Char* begin, const Latin1Char* end) { return PointerRangeSize(begin, end); @@ -151,8 +163,12 @@ static size_t ComputeColumn(const char16_t* begin, const char16_t* end) { // We never call it with additional arguments. template static void ReportSyntaxError(TokenStreamAnyChars& ts, + mozilla::Maybe line, + mozilla::Maybe column, RegExpCompileData& result, CharT* start, size_t length, ...) { + MOZ_ASSERT(line.isSome() == column.isSome()); + gc::AutoSuppressGC suppressGC(ts.context()); uint32_t errorNumber = ErrorNumber(result.error); @@ -171,13 +187,25 @@ static void ReportSyntaxError(TokenStreamAnyChars& ts, // a line of context based on the expression source. uint32_t location = ts.currentToken().pos.begin; if (ts.fillExceptingContext(&err, location)) { - // Line breaks are not significant in pattern text in the same way as - // in source text, so act as though pattern text is a single line, then - // compute a column based on "code point" count (treating a lone - // surrogate as a "code point" in UTF-16). Gak. - err.lineNumber = 1; - err.columnNumber = + uint32_t columnNumber = AssertedCast(ComputeColumn(start, start + offset)); + if (line.isSome()) { + // If this pattern is being checked by the frontend Parser instead + // of other API entry points like |new RegExp|, then the parser will + // have provided both a line and column pointing at the *beginning* + // of the RegExp literal inside the source text. + // We adjust the columnNumber to point to the actual syntax error + // inside the literal. + err.lineNumber = *line; + err.columnNumber = *column + columnNumber; + } else { + // Line breaks are not significant in pattern text in the same way as + // in source text, so act as though pattern text is a single line, then + // compute a column based on "code point" count (treating a lone + // surrogate as a "code point" in UTF-16). Gak. + err.lineNumber = 1; + err.columnNumber = columnNumber; + } } // For most error reporting, the line of context derives from the token @@ -231,11 +259,11 @@ static void ReportSyntaxError(TokenStreamAnyChars& ts, RegExpCompileData& result, HandleAtom pattern) { JS::AutoCheckCannotGC nogc_; if (pattern->hasLatin1Chars()) { - ReportSyntaxError(ts, result, pattern->latin1Chars(nogc_), - pattern->length()); + ReportSyntaxError(ts, Nothing(), Nothing(), result, + pattern->latin1Chars(nogc_), pattern->length()); } else { - ReportSyntaxError(ts, result, pattern->twoByteChars(nogc_), - pattern->length()); + ReportSyntaxError(ts, Nothing(), Nothing(), result, + pattern->twoByteChars(nogc_), pattern->length()); } } @@ -253,11 +281,13 @@ static bool CheckPatternSyntaxImpl(JSContext* cx, FlatStringReader* pattern, bool CheckPatternSyntax(JSContext* cx, TokenStreamAnyChars& ts, const mozilla::Range chars, - JS::RegExpFlags flags) { + JS::RegExpFlags flags, mozilla::Maybe line, + mozilla::Maybe column) { FlatStringReader reader(chars); RegExpCompileData result; if (!CheckPatternSyntaxImpl(cx, &reader, flags, &result)) { - ReportSyntaxError(ts, result, chars.begin().get(), chars.length()); + ReportSyntaxError(ts, line, column, result, chars.begin().get(), + chars.length()); return false; } return true; @@ -532,6 +562,7 @@ bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, RootedAtom pattern(cx, re->getSource()); JS::RegExpFlags flags = re->getFlags(); LifoAllocScope allocScope(&cx->tempLifoAlloc()); + HandleScope handleScope(cx->isolate); Zone zone(allocScope.alloc()); RegExpCompileData data; @@ -591,7 +622,6 @@ bool CompilePattern(JSContext* cx, MutableHandleRegExpShared re, MOZ_ASSERT(re->kind() == RegExpShared::Kind::RegExp); - HandleScope handleScope(cx->isolate); RegExpCompiler compiler(cx->isolate, &zone, data.capture_count, input->hasLatin1Chars()); diff --git a/js/src/irregexp/RegExpAPI.h b/js/src/irregexp/RegExpAPI.h index f0c6b25739..20acbf0118 100644 --- a/js/src/irregexp/RegExpAPI.h +++ b/js/src/irregexp/RegExpAPI.h @@ -7,6 +7,9 @@ #ifndef regexp_RegExpAPI_h #define regexp_RegExpAPI_h +#include "mozilla/Maybe.h" +#include "mozilla/MemoryReporting.h" + #include "frontend/TokenStream.h" #include "vm/JSContext.h" #include "vm/RegExpShared.h" @@ -17,9 +20,14 @@ namespace irregexp { Isolate* CreateIsolate(JSContext* cx); void DestroyIsolate(Isolate* isolate); +size_t IsolateSizeOfIncludingThis(Isolate* isolate, + mozilla::MallocSizeOf mallocSizeOf); + bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, const mozilla::Range chars, - JS::RegExpFlags flags); + JS::RegExpFlags flags, + mozilla::Maybe line = mozilla::Nothing(), + mozilla::Maybe column = mozilla::Nothing()); bool CheckPatternSyntax(JSContext* cx, frontend::TokenStreamAnyChars& ts, HandleAtom pattern, JS::RegExpFlags flags); diff --git a/js/src/irregexp/RegExpShim.cpp b/js/src/irregexp/RegExpShim.cpp index 18716cbdb1..5cc4040f13 100644 --- a/js/src/irregexp/RegExpShim.cpp +++ b/js/src/irregexp/RegExpShim.cpp @@ -8,6 +8,8 @@ #include "irregexp/RegExpShim.h" +#include "mozilla/MemoryReporting.h" + #include #include "irregexp/imported/regexp-macro-assembler.h" @@ -136,6 +138,21 @@ void Isolate::trace(JSTracer* trc) { } } +size_t Isolate::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { + size_t size = mallocSizeOf(this); + + // The RegExpStack code is imported from V8, so we peek inside it to + // measure its memory from here. + size += mallocSizeOf(regexpStack_); + if (regexpStack_->thread_local_.owns_memory_) { + size += mallocSizeOf(regexpStack_->thread_local_.memory_); + } + + size += handleArena_.SizeOfExcludingThis(mallocSizeOf); + size += uniquePtrArena_.SizeOfExcludingThis(mallocSizeOf); + return size; +} + /*static*/ Handle String::Flatten(Isolate* isolate, Handle string) { if (string->IsFlat()) { diff --git a/js/src/irregexp/RegExpShim.h b/js/src/irregexp/RegExpShim.h index a3682905b5..44fc747f0c 100644 --- a/js/src/irregexp/RegExpShim.h +++ b/js/src/irregexp/RegExpShim.h @@ -26,6 +26,7 @@ #include "irregexp/util/ZoneShim.h" #include "jit/Label.h" #include "jit/shared/Assembler-shared.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit{,Conservative}DontReport #include "js/Value.h" #include "threading/ExclusiveData.h" #include "vm/MutexIDs.h" @@ -981,6 +982,8 @@ class Isolate { ~Isolate(); bool init(); + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + //********** Isolate code **********// RegExpStack* regexp_stack() const { return regexpStack_; } byte* top_of_regexp_stack() const; @@ -1045,8 +1048,8 @@ class Isolate { JS::Value* getHandleLocation(const JS::Value& value); private: - mozilla::SegmentedVector handleArena_; - mozilla::SegmentedVector> uniquePtrArena_; + mozilla::SegmentedVector handleArena_; + mozilla::SegmentedVector, 256> uniquePtrArena_; void* allocatePseudoHandle(size_t bytes); @@ -1054,6 +1057,9 @@ class Isolate { template PseudoHandle takeOwnership(void* ptr); + uint32_t liveHandles() const { return handleArena_.Length(); } + uint32_t livePseudoHandles() const { return uniquePtrArena_.Length(); } + private: void openHandleScope(HandleScope& scope) { scope.level_ = handleArena_.Length(); diff --git a/js/src/jit-test/etc/wasm-spec-tests.patch b/js/src/jit-test/etc/wasm-spec-tests.patch deleted file mode 100644 index 2e30f332ac..0000000000 --- a/js/src/jit-test/etc/wasm-spec-tests.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/js/src/jit-test/tests/wasm/spec/type.wast.js b/js/src/jit-test/tests/wasm/spec/type.wast.js -index 15518b4d7f60..9184b46010a4 100644 ---- a/js/src/jit-test/tests/wasm/spec/type.wast.js -+++ b/js/src/jit-test/tests/wasm/spec/type.wast.js -@@ -8,6 +8,14 @@ assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x - // type.wast:47 - assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); - -+// These last two tests check that function types returning more than 2 -+// results are invalid, but with multi-value of course that's no longer -+// the case. Until the feature fully lands and we can import from -+// upstream, skip these tests. -+if (wasmMultiValueEnabled()) { -+ quit(); -+} -+ - // type.wast:52 - assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f"); diff --git a/js/src/jit-test/etc/wasm/Makefile b/js/src/jit-test/etc/wasm/Makefile new file mode 100644 index 0000000000..688aeb83da --- /dev/null +++ b/js/src/jit-test/etc/wasm/Makefile @@ -0,0 +1,26 @@ +.PHONY: update run expectations + +warning = '\# Wasm Spec Tests\n\nThese tests are autogenerated using a tool, do not edit.\n\nSee `jit-test/etc/wasm/` for more information.' + +update: + [ -d ./wasm-generate-testsuite ] || git clone https://github.com/eqrion/wasm-generate-testsuite ./wasm-generate-testsuite + cp ./config.toml ./wasm-generate-testsuite/config.toml + cp ./config-lock.toml ./wasm-generate-testsuite/config-lock.toml + (cd ./wasm-generate-testsuite && RUST_LOG=info cargo run) + cp ./wasm-generate-testsuite/config-lock.toml ./config-lock.toml + rm -r ../../tests/wasm/spec + cp -R wasm-generate-testsuite/tests/js ../../tests/wasm/spec + echo $(warning) > ../../tests/wasm/spec/README.md + [ ! -d ./spec-tests.patch ] || (cd ../../tests/wasm/spec && patch -u -p7 < ../../../etc/wasm/spec-tests.patch) + rm -r ../../../../../testing/web-platform/mozilla/tests/wasm + cp -R wasm-generate-testsuite/tests/wpt ../../../../../testing/web-platform/mozilla/tests/wasm + echo $(warning) > ../../../../../testing/web-platform/mozilla/tests/wasm/README.md + +run: + @[ -z $(MOZCONFIG) ] && echo "You need to define the MOZCONFIG env variable first." + @[ -z $(MOZCONFIG) ] || ../../../../../mach wpt /_mozilla/wasm + +expectations: + @[ -z $(MOZCONFIG) ] && echo "You need to define the MOZCONFIG env variable first." || true + @[ -z $(MOZCONFIG) ] || ../../../../../mach wpt /_mozilla/wasm --log-raw /tmp/expectations.log || true + @[ -z $(MOZCONFIG) ] || ../../../../../mach wpt-update /tmp/expectations.log --no-patch diff --git a/js/src/jit-test/etc/wasm/README.md b/js/src/jit-test/etc/wasm/README.md new file mode 100644 index 0000000000..bc1ad8bdac --- /dev/null +++ b/js/src/jit-test/etc/wasm/README.md @@ -0,0 +1,113 @@ +# Wasm Spec Tests + +This directory contains scripts and configs to manage the in-tree import of the +wasm spec testsuite. + +## Format of tests + +Spec tests are given in `test/core` of the `spec` repository as `.wast` files. +A `.wast` file is a superset of the `.wat` format with commands for running +tests. + +The spec interpreter can natively consume `.wast` files to run the tests, or +generate `.js` files which rely on the WebAssembly JS-API plus a harness file +to implement unit-test functionality. + +We rely on the spec interpreter to generate `.js` files for us to run. + +## Running tests + +Tests are imported to `jit-test` and `wpt` to be run in both the JS shell or the +browser. + +To run under `jit-test`: +```bash +cd js/src +./jit-test.py path_to_build/dist/bin/js wasm/spec/ +``` + +To run under `wpt` (generally not necessary): +```bash +./mach web-platform-test testing/web-platform/mozilla/tests/wasm/ +``` + +## Test importing + +There are many proposals in addition to the canonical spec. Each proposal is a +fork of the canonical spec and may modify any amount of files. + +This causes a challenge for any engine implementing multiple proposals, as any +proposal may conflict (and often will) with each other. This makes it +infeasible to merge all spec and proposal repos together. + +Testing each proposal separately in full isn't an attractive option either, as +most tests are unchanged and that would cause a significant amount of wasted +computation time. + +For this reason, we use a tool [1] to generate a set of separate test-suites +that are 'pruned' to obtain a minimal set of tests. The tool works by merging +each proposal with the proposal it is based off of and removing tests that +have not changed. + +[1] https://github.com/eqrion/wasm-generate-testsuite + +### Configuration + +The import tool relies on `config.toml` for the list of proposals to import, +and `config-lock.toml` for a list of commits to use for each proposal. + +The lock file makes test importing deterministic and controllable. This is +useful as proposals often make inconvenient and breaking changes. + +### Operation + +```bash +# Add, remove, or modify proposals +vim config.toml +# Remove locks for any proposals you wish to pull the latest changes on +vim config-lock.toml +# Import the tests +make update +# View the tests that were imported +hg stat +# Run the imported tests and note failures +./jit-test.py dist/bin/js wasm/spec/ +# Exclude test failures +vim config.toml +# Re-import the tests to exclude failing tests +make update +# Commit the changes +hg commit +``` + +### Debugging test failures + +Imported tests use the binary format, which is inconvenient for understanding +why a test is failing. + +Luckily, each assertion in an imported test contains the line of the source file +that it corresponds with. + +Unfortunately, the '.wast' files are not commited in the tree and so you must +use the import tool to get the original source. + +Follow the steps in 'Operation' to get a `wasm-generate-testsuite` repo with +the '.wast' files of each proposal. All proposals are stored in a single git +repo named `specs/`. Each proposal is a branch, and you can find all tests +under `test/core`. + +### Debugging import failures + +Proposals can often have conflicts with their upstream proposals. This is okay, +and the test importer will fallback to building tests on an unmerged tree. + +This will likely result in extra tests being imported due to spurious +differences between the proposal and upstream, but generally is okay. + +It's also possible that a proposal is 'broken' and fails to generate '.js' test +files with the spec interpreter. The best way to debug this is to check out the +proposal repo and debug why `./test/build.py` is failing. + +The import tool uses `RUST_LOG` to output debug information. `Makefile` +automatically uses `RUST_LOG=info`. Change that to `RUST_LOG=debug` to get +verbose output of all the commands run. diff --git a/js/src/jit-test/etc/wasm/config-lock.toml b/js/src/jit-test/etc/wasm/config-lock.toml new file mode 100644 index 0000000000..f68914a19f --- /dev/null +++ b/js/src/jit-test/etc/wasm/config-lock.toml @@ -0,0 +1,15 @@ +[[repos]] +name = 'threads' +commit = 'dfdcb81a' + +[[repos]] +name = 'bulk-memory-operations' +commit = '66d90a7d' + +[[repos]] +name = 'reference-types' +commit = 'c90e289a' + +[[repos]] +name = 'spec' +commit = '7c4cbf32' diff --git a/js/src/jit-test/etc/wasm/config.toml b/js/src/jit-test/etc/wasm/config.toml new file mode 100644 index 0000000000..778e360753 --- /dev/null +++ b/js/src/jit-test/etc/wasm/config.toml @@ -0,0 +1,66 @@ +# Standard 'directives.txt' prologues for jit-tests +harness_directive = "|jit-test| skip-if: true" +directive = "|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemoryIsSupported(); include:wasm-testharness.js; local-include:harness/sync_index.js" + +# Failing tests across all testsuites +excluded_tests = [ + # false-positive windows-specific failures + "align.wast", + # bulk-memory-operations/issues/133 (data.wast:161) + "data.wast", + # testing that multiple tables fail (imports.wast:309) + "imports.wast", + # bulk-memory-operations/issues/133 (linking.wast:206) + "linking.wast", + # bulk-memory-operations/issues/133 (elem.wast:142) + "elem.wast", + # test harness doesn't acquire global values correctly + "exports.wast", + # false-positive windows-specific failure + "memory_trap.wast", + # false-positive error on duplicate export name (names.wast:19) + "names.wast", + # false-positive error on invalid UTF-8 custom section name (utf8-custom-section-id.wast:6) + "utf8-custom-section-id.wast", + # invalid table maximum length for web embeddings + "table.wast", +] + +[[repos]] +name = "spec" +url = "https://github.com/WebAssembly/spec" +excluded_tests = [] + +[[repos]] +name = "threads" +url = "https://github.com/WebAssembly/threads" +parent = "spec" +excluded_tests = [ + "atomic.wast", + # testing that multi-value isn't implemented (func.wast:492) + "func.wast", + # testing that multi-value isn't implemented (type.wast:52) + "type.wast" +] +# Skip in WPT where we can't guard on features being enabled +skip_wpt = true +# Skip in jit-test when it's not enabled +directive = "; skip-if: !wasmThreadsSupported()" + +[[repos]] +name = "bulk-memory-operations" +url = "https://github.com/WebAssembly/bulk-memory-operations" +parent = "spec" +excluded_tests = [] +# Skip in WPT where we can't guard on features being enabled +skip_wpt = true + +[[repos]] +name = "reference-types" +url = "https://github.com/WebAssembly/reference-types" +parent = "spec" +excluded_tests = [] +# Skip in WPT where we can't guard on features being enabled +skip_wpt = true +# Skip in jit-test when it's not enabled +directive = "; skip-if: !wasmReftypesEnabled()" diff --git a/js/src/jit-test/jit_test.py b/js/src/jit-test/jit_test.py index 2808d2fa54..bf531351ed 100644 --- a/js/src/jit-test/jit_test.py +++ b/js/src/jit-test/jit_test.py @@ -15,19 +15,23 @@ import traceback -def add_libdir_to_path(): +def add_tests_dir_to_path(): from os.path import dirname, exists, join, realpath js_src_dir = dirname(dirname(realpath(sys.argv[0]))) assert exists(join(js_src_dir, 'jsapi.h')) - sys.path.insert(0, join(js_src_dir, 'lib')) - sys.path.insert(0, join(js_src_dir, 'tests', 'lib')) + sys.path.insert(0, join(js_src_dir, 'tests')) -add_libdir_to_path() +add_tests_dir_to_path() -import jittests -from tests import get_jitflags, valid_jitflags, get_cpu_count, get_environment_overlay, \ - change_env +from lib import jittests +from lib.tests import ( + get_jitflags, + valid_jitflags, + get_cpu_count, + get_environment_overlay, + change_env, +) def which(name): @@ -66,135 +70,127 @@ def choose_item(jobs, max_items, display): def main(argv): # The [TESTS] optional arguments are paths of test files relative # to the jit-test/tests directory. - from optparse import OptionParser, SUPPRESS_HELP - op = OptionParser(usage='%prog [options] JS_SHELL [TESTS]') - op.add_option('-s', '--show-cmd', dest='show_cmd', action='store_true', - help='show js shell command run') - op.add_option('-f', '--show-failed-cmd', dest='show_failed', - action='store_true', - help='show command lines of failed tests') - op.add_option('-o', '--show-output', dest='show_output', - action='store_true', - help='show output from js shell') - op.add_option('-F', '--failed-only', dest='failed_only', - action='store_true', - help="if --show-output is given, only print output for" - " failed tests") - op.add_option('--no-show-failed', dest='no_show_failed', - action='store_true', - help="don't print output for failed tests" - " (no-op with --show-output)") - op.add_option('-x', '--exclude', dest='exclude', - default=[], action='append', - help='exclude given test dir or path') - op.add_option('--exclude-from', dest='exclude_from', type=str, - help='exclude each test dir or path in FILE') - op.add_option('--slow', dest='run_slow', action='store_true', - help='also run tests marked as slow') - op.add_option('--no-slow', dest='run_slow', action='store_false', - help='do not run tests marked as slow (the default)') - op.add_option('-t', '--timeout', dest='timeout', type=float, default=150.0, - help='set test timeout in seconds') - op.add_option('--no-progress', dest='hide_progress', action='store_true', - help='hide progress bar') - op.add_option('--tinderbox', dest='format', action='store_const', - const='automation', - help='Use automation-parseable output format') - op.add_option('--format', dest='format', default='none', type='choice', - choices=['automation', 'none'], - help='Output format. Either automation or none' - ' (default %default).') - op.add_option('--args', dest='shell_args', metavar='ARGS', default='', - help='extra args to pass to the JS shell') - op.add_option('--feature-args', dest='feature_args', metavar='ARGS', - default='', - help='even more args to pass to the JS shell ' - '(for compatibility with jstests.py)') - op.add_option('-w', '--write-failures', dest='write_failures', - metavar='FILE', - help='Write a list of failed tests to [FILE]') - op.add_option('-C', '--check-output', action='store_true', dest='check_output', - help='Run tests to check output for different jit-flags') - op.add_option('-r', '--read-tests', dest='read_tests', metavar='FILE', - help='Run test files listed in [FILE]') - op.add_option('-R', '--retest', dest='retest', metavar='FILE', - help='Retest using test list file [FILE]') - op.add_option('-g', '--debug', action='store_const', const='gdb', dest='debugger', - help='Run a single test under the gdb debugger') - op.add_option('-G', '--debug-rr', action='store_const', const='rr', dest='debugger', - help='Run a single test under the rr debugger') - op.add_option('--debugger', type='string', - help='Run a single test under the specified debugger') - op.add_option('--valgrind', dest='valgrind', action='store_true', - help='Enable the |valgrind| flag, if valgrind is in $PATH.') - op.add_option('--unusable-error-status', action='store_true', - help='Ignore incorrect exit status on tests that should return nonzero.') - op.add_option('--valgrind-all', dest='valgrind_all', action='store_true', - help='Run all tests with valgrind, if valgrind is in $PATH.') - op.add_option('--avoid-stdio', dest='avoid_stdio', action='store_true', - help='Use js-shell file indirection instead of piping stdio.') - op.add_option('--write-failure-output', dest='write_failure_output', - action='store_true', - help='With --write-failures=FILE, additionally write the' - ' output of failed tests to [FILE]') - op.add_option('--jitflags', dest='jitflags', default='none', - choices=valid_jitflags(), - help='IonMonkey option combinations. One of %s.' % ', '.join(valid_jitflags())) - op.add_option('--ion', dest='jitflags', action='store_const', const='ion', - help='Run tests once with --ion-eager and once with' - ' --baseline-eager (equivalent to --jitflags=ion)') - op.add_option('--tbpl', dest='jitflags', action='store_const', const='all', - help='Run tests with all IonMonkey option combinations' - ' (equivalent to --jitflags=all)') - op.add_option('-j', '--worker-count', dest='max_jobs', type=int, - default=max(1, get_cpu_count()), - help='Number of tests to run in parallel (default %default)') - op.add_option('--remote', action='store_true', - help='Run tests on a remote device') - op.add_option('--deviceIP', action='store', - type='string', dest='device_ip', - help='IP address of remote device to test') - op.add_option('--devicePort', action='store', - type=int, dest='device_port', default=20701, - help='port of remote device to test') - op.add_option('--deviceSerial', action='store', - type='string', dest='device_serial', default=None, - help='ADB device serial number of remote device to test') - op.add_option('--remoteTestRoot', dest='remote_test_root', action='store', - type='string', default='/data/local/tests', - help='The remote directory to use as test root' - ' (eg. /data/local/tests)') - op.add_option('--localLib', dest='local_lib', action='store', - type='string', - help='The location of libraries to push -- preferably' - ' stripped') - op.add_option('--repeat', type=int, default=1, - help='Repeat tests the given number of times.') - op.add_option('--this-chunk', type=int, default=1, - help='The test chunk to run.') - op.add_option('--total-chunks', type=int, default=1, - help='The total number of test chunks.') - op.add_option('--ignore-timeouts', dest='ignore_timeouts', metavar='FILE', - help='Ignore timeouts of tests listed in [FILE]') - op.add_option('--test-reflect-stringify', dest="test_reflect_stringify", - help="instead of running tests, use them to test the " - "Reflect.stringify code in specified file") - op.add_option('--run-binast', action='store_true', - dest="run_binast", - help="By default BinAST testcases encoded from JS " - "testcases are skipped. If specified, BinAST testcases " - "are also executed.") + import argparse + op = argparse.ArgumentParser(description='Run jit-test JS shell tests') + op.add_argument('-s', '--show-cmd', dest='show_cmd', action='store_true', + help='show js shell command run') + op.add_argument('-f', '--show-failed-cmd', dest='show_failed', + action='store_true', + help='show command lines of failed tests') + op.add_argument('-o', '--show-output', dest='show_output', + action='store_true', + help='show output from js shell') + op.add_argument('-F', '--failed-only', dest='failed_only', + action='store_true', + help="if --show-output is given, only print output for" + " failed tests") + op.add_argument('--no-show-failed', dest='no_show_failed', + action='store_true', + help="don't print output for failed tests" + " (no-op with --show-output)") + op.add_argument('-x', '--exclude', dest='exclude', + default=[], action='append', + help='exclude given test dir or path') + op.add_argument('--exclude-from', dest='exclude_from', type=str, + help='exclude each test dir or path in FILE') + op.add_argument('--slow', dest='run_slow', action='store_true', + help='also run tests marked as slow') + op.add_argument('--no-slow', dest='run_slow', action='store_false', + help='do not run tests marked as slow (the default)') + op.add_argument('-t', '--timeout', dest='timeout', type=float, default=150.0, + help='set test timeout in seconds') + op.add_argument('--no-progress', dest='hide_progress', action='store_true', + help='hide progress bar') + op.add_argument('--tinderbox', dest='format', action='store_const', + const='automation', + help='Use automation-parseable output format') + op.add_argument('--format', dest='format', default='none', + choices=('automation', 'none'), + help='Output format (default %(default)s).') + op.add_argument('--args', dest='shell_args', metavar='ARGS', default='', + help='extra args to pass to the JS shell') + op.add_argument('--feature-args', dest='feature_args', metavar='ARGS', + default='', + help='even more args to pass to the JS shell ' + '(for compatibility with jstests.py)') + op.add_argument('-w', '--write-failures', dest='write_failures', + metavar='FILE', + help='Write a list of failed tests to [FILE]') + op.add_argument('-C', '--check-output', action='store_true', dest='check_output', + help='Run tests to check output for different jit-flags') + op.add_argument('-r', '--read-tests', dest='read_tests', metavar='FILE', + help='Run test files listed in [FILE]') + op.add_argument('-R', '--retest', dest='retest', metavar='FILE', + help='Retest using test list file [FILE]') + op.add_argument('-g', '--debug', action='store_const', const='gdb', dest='debugger', + help='Run a single test under the gdb debugger') + op.add_argument('-G', '--debug-rr', action='store_const', const='rr', dest='debugger', + help='Run a single test under the rr debugger') + op.add_argument('--debugger', type=str, + help='Run a single test under the specified debugger') + op.add_argument('--valgrind', dest='valgrind', action='store_true', + help='Enable the |valgrind| flag, if valgrind is in $PATH.') + op.add_argument('--unusable-error-status', action='store_true', + help='Ignore incorrect exit status on tests that should return nonzero.') + op.add_argument('--valgrind-all', dest='valgrind_all', action='store_true', + help='Run all tests with valgrind, if valgrind is in $PATH.') + op.add_argument('--avoid-stdio', dest='avoid_stdio', action='store_true', + help='Use js-shell file indirection instead of piping stdio.') + op.add_argument('--write-failure-output', dest='write_failure_output', + action='store_true', + help='With --write-failures=FILE, additionally write the' + ' output of failed tests to [FILE]') + op.add_argument('--jitflags', dest='jitflags', default='none', + choices=valid_jitflags(), + help='IonMonkey option combinations (default %(default)s).') + op.add_argument('--ion', dest='jitflags', action='store_const', const='ion', + help='Run tests once with --ion-eager and once with' + ' --baseline-eager (equivalent to --jitflags=ion)') + op.add_argument('--tbpl', dest='jitflags', action='store_const', const='all', + help='Run tests with all IonMonkey option combinations' + ' (equivalent to --jitflags=all)') + op.add_argument('-j', '--worker-count', dest='max_jobs', type=int, + default=max(1, get_cpu_count()), + help='Number of tests to run in parallel (default %(default)s).') + op.add_argument('--remote', action='store_true', + help='Run tests on a remote device') + op.add_argument('--deviceIP', action='store', + type=str, dest='device_ip', + help='IP address of remote device to test') + op.add_argument('--devicePort', action='store', + type=int, dest='device_port', default=20701, + help='port of remote device to test') + op.add_argument('--deviceSerial', action='store', + type=str, dest='device_serial', default=None, + help='ADB device serial number of remote device to test') + op.add_argument('--remoteTestRoot', dest='remote_test_root', action='store', + type=str, default='/data/local/tests', + help='The remote directory to use as test root' + ' (eg. /data/local/tests)') + op.add_argument('--localLib', dest='local_lib', action='store', + type=str, + help='The location of libraries to push -- preferably' + ' stripped') + op.add_argument('--repeat', type=int, default=1, + help='Repeat tests the given number of times.') + op.add_argument('--this-chunk', type=int, default=1, + help='The test chunk to run.') + op.add_argument('--total-chunks', type=int, default=1, + help='The total number of test chunks.') + op.add_argument('--ignore-timeouts', dest='ignore_timeouts', metavar='FILE', + help='Ignore timeouts of tests listed in [FILE]') + op.add_argument('--test-reflect-stringify', dest="test_reflect_stringify", + help="instead of running tests, use them to test the " + "Reflect.stringify code in specified file") # --enable-webrender is ignored as it is not relevant for JIT # tests, but is required for harness compatibility. - op.add_option('--enable-webrender', action='store_true', - dest="enable_webrender", default=False, - help=SUPPRESS_HELP) - - options, args = op.parse_args(argv) - if len(args) < 1: - op.error('missing JS_SHELL argument') - js_shell = which(args[0]) - test_args = args[1:] + op.add_argument('--enable-webrender', action='store_true', + dest="enable_webrender", default=False, + help=argparse.SUPPRESS) + op.add_argument('js_shell', metavar='JS_SHELL', help='JS shell to run tests with') + + options, test_args = op.parse_known_args(argv) + js_shell = which(options.js_shell) test_environment = get_environment_overlay(js_shell) if not (os.path.isfile(js_shell) and os.access(js_shell, os.X_OK)): @@ -221,20 +217,10 @@ def main(argv): test_list = [] read_all = True - if options.run_binast: - code = 'print(getBuildConfiguration().binast)' - is_binast_enabled = subprocess.check_output([js_shell, '-e', code]) - if not is_binast_enabled.startswith('true'): - print("While --run-binast is specified, BinAST is not enabled.", - file=sys.stderr) - print("BinAST testcases will be skipped.", - file=sys.stderr) - options.run_binast = False - if test_args: read_all = False for arg in test_args: - test_list += jittests.find_tests(arg, run_binast=options.run_binast) + test_list += jittests.find_tests(arg) if options.read_tests: read_all = False @@ -254,7 +240,7 @@ def main(argv): sys.stderr.write('---\n') if read_all: - test_list = jittests.find_tests(run_binast=options.run_binast) + test_list = jittests.find_tests() if options.exclude_from: with open(options.exclude_from) as fh: @@ -266,7 +252,7 @@ def main(argv): if options.exclude: exclude_list = [] for exclude in options.exclude: - exclude_list += jittests.find_tests(exclude, run_binast=options.run_binast) + exclude_list += jittests.find_tests(exclude) test_list = [test for test in test_list if test not in set(exclude_list)] @@ -318,11 +304,6 @@ def main(argv): for line in f.readlines(): path = line.strip('\n') ignore.add(path) - - binjs_path = path.replace('.js', '.binjs') - # Do not use os.path.join to always use '/'. - ignore.add('binast/nonlazy/{}'.format(binjs_path)) - ignore.add('binast/lazy/{}'.format(binjs_path)) options.ignore_timeouts = ignore except IOError: sys.exit("Error reading file: " + options.ignore_timeouts) diff --git a/js/src/jit-test/lib/bytecode-cache.js b/js/src/jit-test/lib/bytecode-cache.js index fb4da93931..965202f691 100644 --- a/js/src/jit-test/lib/bytecode-cache.js +++ b/js/src/jit-test/lib/bytecode-cache.js @@ -11,11 +11,13 @@ function evalWithCache(code, ctx) { // We create a new global ... if (!("global" in ctx)) - ctx.global = newGlobal({cloneSingletons: !incremental, - newCompartment: ctx.newCompartment}); + ctx.global = newGlobal({newCompartment: ctx.newCompartment}); + // NOTE: Run-once scripts must use incremental mode since they may use + // singleton objects that are mutated by the time the bytecode is captured in + // non-incremental mode. if (!("isRunOnce" in ctx)) - ctx.isRunOnce = true; + ctx.isRunOnce = incremental; var ctx_save; if (incremental) diff --git a/js/src/jit-test/lib/dummyModuleResolveHook.js b/js/src/jit-test/lib/dummyModuleResolveHook.js deleted file mode 100644 index 594ec94320..0000000000 --- a/js/src/jit-test/lib/dummyModuleResolveHook.js +++ /dev/null @@ -1,14 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// A dummy implementation of the module resolve hook used by module tests. This -// implements the bare minimum necessary to allow modules to refer to each -// other. - -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; -}); diff --git a/js/src/jit-test/lib/syntax.js b/js/src/jit-test/lib/syntax.js index 6a190cd5bd..5afd1405fb 100644 --- a/js/src/jit-test/lib/syntax.js +++ b/js/src/jit-test/lib/syntax.js @@ -443,6 +443,13 @@ function test_syntax(postfixes, check_error, ignore_opts) { test("export * from 'a' ", opts); test("export * from 'a'; ", opts); + test("export * ", opts); + test("export * as ", opts); + test("export * as ns ", opts); + test("export * as ns from ", opts); + test("export * as ns from 'a' ", opts); + test("export * as ns from 'a'; ", opts); + test("export function ", opts); test("export function f ", opts); test("export function f( ", opts); diff --git a/js/src/jit-test/lib/wasm-testharness.js b/js/src/jit-test/lib/wasm-testharness.js index ca79f90290..8f8ab6e5e9 100644 --- a/js/src/jit-test/lib/wasm-testharness.js +++ b/js/src/jit-test/lib/wasm-testharness.js @@ -1,22 +1,6 @@ if (!wasmIsSupported()) quit(); -// We need to find the absolute path that ends like this: -// -// js/src/jit-test/tests/wasm/spec/harness/ -// -// because that's where the test harness lives. Fortunately we are provided -// with |libdir|, which is a path that ends thusly -// -// js/src/jit-test/lib/ -// -// That is, it has a fixed offset relative to what we need. So we can -// simply do this: - -let harnessdir = libdir + "../tests/wasm/spec/harness/"; - -load(harnessdir + 'sync_index.js'); - function test(func, description) { let maybeErr; try { @@ -67,3 +51,8 @@ function assert_not_equals(actual, not_expected, description) { }; assertEq(caught, true, "assert_not_equals failed: " + description); } + +// Make it possible to run wasm spec tests with --fuzzing-safe +if (typeof console == 'undefined') { + console = { log() {} } +} diff --git a/js/src/jit-test/lib/wasm.js b/js/src/jit-test/lib/wasm.js index 056fe82a82..57b6891046 100644 --- a/js/src/jit-test/lib/wasm.js +++ b/js/src/jit-test/lib/wasm.js @@ -21,7 +21,12 @@ function wasmEvalText(str, imports) { } function wasmValidateText(str) { - assertEq(WebAssembly.validate(wasmTextToBinary(str)), true); + let binary = wasmTextToBinary(str); + let valid = WebAssembly.validate(binary); + if (!valid) { + new WebAssembly.Module(binary); + } + assertEq(valid, true); } function wasmFailValidateText(str, pattern) { @@ -322,3 +327,7 @@ WasmHelpers.assertEqPreciseStacks = (observed, expectedStacks) => { Expected one of: ${expectedStacks.map(stacks => stacks.join("/")).join('\n')}`); } + +function fuzzingSafe() { + return typeof getErrorNotes == 'undefined'; +} diff --git a/js/src/jit-test/modules/export-ns.js b/js/src/jit-test/modules/export-ns.js new file mode 100644 index 0000000000..0d2e499088 --- /dev/null +++ b/js/src/jit-test/modules/export-ns.js @@ -0,0 +1 @@ +export * as ns from "module1.js"; diff --git a/js/src/jit-test/tests/1659595.js b/js/src/jit-test/tests/1659595.js new file mode 100644 index 0000000000..663fa3017c --- /dev/null +++ b/js/src/jit-test/tests/1659595.js @@ -0,0 +1,70 @@ + +// Impliclitly converting regular numeric properties to computed numeric +// properties in the parser means checking there's no semantic changes. + +let a = { + 0: 0, + 1n: 1n, + + get 2() { + return 2; + }, + set 2(o) {}, + + get 3n() { + return 3n; + }, + set 3n(o) {} +}; + +assertEq(a[0], 0); +assertEq(a[1n], 1n); +assertEq(a[2], 2); +assertEq(a[3n], 3n); + +function getterName(x) { + return Object.getOwnPropertyDescriptor(a, x).get.name +} +function setterName(x) { + return Object.getOwnPropertyDescriptor(a, x).set.name +} + +assertEq(/get 2/.test(getterName(2)), true) +assertEq(/get 3/.test(getterName(3n)), true) + +assertEq(/set 2/.test(setterName(2)), true) +assertEq(/set 3/.test(setterName(3n)), true) + +let b = { + 0: 0, + [0]: 'dupe', + 1n: 1, + [1n]: 'dupe', + [2]: 2, + 2: 'dupe', + [3n]: 3, + 3n: 'dupe' +}; +assertEq(b[0], 'dupe'); +assertEq(b[1n], 'dupe'); +assertEq(b[2], 'dupe'); +assertEq(b[3n], 'dupe'); + +let c = { + 0: 0, + 0.0: 'dupe', +}; +assertEq(c[0], 'dupe'); + +let d = { + 0: 0, + '0': 'dupe', +}; +assertEq(d[0], 'dupe'); + +// Test numeric property destructuring. +let {1: x} = {1: 1}; +let {1n: y} = {1n: 1n}; + +assertEq(x, 1); +assertEq(y, 1n); diff --git a/js/src/jit-test/tests/TypedObject/bug1655906.js b/js/src/jit-test/tests/TypedObject/bug1655906.js new file mode 100644 index 0000000000..14fe456141 --- /dev/null +++ b/js/src/jit-test/tests/TypedObject/bug1655906.js @@ -0,0 +1,11 @@ +var S = new TypedObject.StructType({foo: TypedObject.bigint64}); +var to = new S(); +function g(b) { + to.foo = !b; +} +function f() { + for (var i = 0; i < 1500; i++) { + g(i < 1000); + } +} +f(); diff --git a/js/src/jit-test/tests/arguments/inline-transpile.js b/js/src/jit-test/tests/arguments/inline-transpile.js new file mode 100644 index 0000000000..0720256593 --- /dev/null +++ b/js/src/jit-test/tests/arguments/inline-transpile.js @@ -0,0 +1,17 @@ +function foo(i) { + return i; +} + +function bar(n) { + return foo.apply({}, arguments); +} + +function baz(a, n) { + return bar(n); +} + +var sum = 0; +for (var i = 0; i < 10000; i++) { + sum += baz(0, 1); +} +assertEq(sum, 10000); diff --git a/js/src/jit-test/tests/arrays/bug1673221.js b/js/src/jit-test/tests/arrays/bug1673221.js new file mode 100644 index 0000000000..497c4befec --- /dev/null +++ b/js/src/jit-test/tests/arrays/bug1673221.js @@ -0,0 +1,5 @@ +let x = [7]; +x.splice(0, {valueOf() { x.length = 2; return 0; }}, 5); +assertEq(x.length, 2); +assertEq(x[0], 5); +assertEq(x[1], 7); diff --git a/js/src/jit-test/tests/asm.js/bug1357048.js b/js/src/jit-test/tests/asm.js/bug1357048.js deleted file mode 100644 index 60a515d1fb..0000000000 --- a/js/src/jit-test/tests/asm.js/bug1357048.js +++ /dev/null @@ -1,21 +0,0 @@ -// |jit-test| -load(libdir + "asm.js"); - -function runTest() { - var code = USE_ASM + ` - function f() { - var x = 0; - var y = 0; - x = (((0x77777777 - 0xcccccccc) | 0) % -1) | 1; - y = (((0x7FFFFFFF + 0x7FFFFFFF) | 0) % -1) | 0; - return (x + y) | 0; - } - return f; - `; - - assertEq(asmLink(asmCompile(code))(), 1); -} - -runTest(); -setARMHwCapFlags('vfp'); -runTest(); diff --git a/js/src/jit-test/tests/asm.js/nested-rewind.js b/js/src/jit-test/tests/asm.js/nested-rewind.js new file mode 100644 index 0000000000..231eef1f6a --- /dev/null +++ b/js/src/jit-test/tests/asm.js/nested-rewind.js @@ -0,0 +1,9 @@ +function g(x = + function() { + "use asm"; + function f(){} + return f; + } +) { + "use asm"; +} diff --git a/js/src/jit-test/tests/basic/bug-1663741.js b/js/src/jit-test/tests/basic/bug-1663741.js new file mode 100644 index 0000000000..866bd083a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1663741.js @@ -0,0 +1,29 @@ +const thisGlobal = this; +const otherGlobalSameCompartment = newGlobal({sameCompartmentAs: thisGlobal}); +const otherGlobalNewCompartment = newGlobal({newCompartment: true}); + +const globals = [thisGlobal, otherGlobalSameCompartment, otherGlobalNewCompartment]; + +function testProperties(global, count) { + let {object: source, transplant} = transplantableObject(); + + // Create a bunch properties on |source|, which force allocation of dynamic + // slots. + for (let i = 0; i < count; i++) { + source["foo" + i] = i; + } + + // Calling |transplant| transplants the object and then returns undefined. + transplant(global); + + // Check the properties were copied over to the swapped object. + for (let i = 0; i < count; i++) { + assertEq(source["foo" + i], i); + } +} + +for (let global of globals) { + for (let count of [0, 10, 30]) { + testProperties(global, count); + } +} diff --git a/js/src/jit-test/tests/basic/bug1033946.js b/js/src/jit-test/tests/basic/bug1033946.js index a9dda468cb..e2f07a8532 100644 --- a/js/src/jit-test/tests/basic/bug1033946.js +++ b/js/src/jit-test/tests/basic/bug1033946.js @@ -1,3 +1,2 @@ - assertEq((/(?!(?!(?!6)[\Wc]))/i).test(), false); assertEq("foobar\xff5baz\u1200".search(/bar\u0178\d/i), 3); diff --git a/js/src/jit-test/tests/basic/bug1057571.js b/js/src/jit-test/tests/basic/bug1057571.js index 0e5e905377..740febd3e6 100644 --- a/js/src/jit-test/tests/basic/bug1057571.js +++ b/js/src/jit-test/tests/basic/bug1057571.js @@ -8,8 +8,8 @@ test = (function () { evalWithCache(test, {}); function evalWithCache(code, ctx) { code = cacheEntry(code); - ctx.global = newGlobal({ cloneSingletons: true }); + ctx.global = newGlobal(); ctx.isRunOnce = true; - var res1 = evaluate(code, Object.create(ctx, {saveBytecode: { value: true } })); - var res2 = evaluate(code, Object.create(ctx, {loadBytecode: { value: true }, saveBytecode: { value: true } })); + var res1 = evaluate(code, Object.create(ctx, {saveIncrementalBytecode: { value: true } })); + var res2 = evaluate(code, Object.create(ctx, {loadBytecode: { value: true }, saveIncrementalBytecode: { value: true } })); } diff --git a/js/src/jit-test/tests/basic/bug1292858.js b/js/src/jit-test/tests/basic/bug1292858.js index 8077d17a99..f6f2d9cf39 100644 --- a/js/src/jit-test/tests/basic/bug1292858.js +++ b/js/src/jit-test/tests/basic/bug1292858.js @@ -2,50 +2,59 @@ setJitCompilerOption("ion.warmup.trigger", 50); setJitCompilerOption("offthread-compilation.enable", 0); gcPreserveCode(); -var caughtInvalidArguments = false; -var a = -1 -try { - var buf = new Uint8ClampedArray(a); - throw new Error("didn't throw"); -} catch (e) { - assertEq(e instanceof RangeError, true, - "expected RangeError, instead threw: " + e); - caughtInvalidArguments = true; -} -assertEq(caughtInvalidArguments, true); - -var caughtInvalidArguments = false; -var i = 0; -while (true) { - i = (i + 1) | 0; - var a = inIon() ? -1 : 300; +function test1() { + var caughtInvalidArguments = false; + var a = -1 try { var buf = new Uint8ClampedArray(a); - assertEq(buf.length, 300); + throw new Error("didn't throw"); } catch (e) { - assertEq(a, -1); assertEq(e instanceof RangeError, true, "expected RangeError, instead threw: " + e); caughtInvalidArguments = true; - break; } + assertEq(caughtInvalidArguments, true); } -assertEq(caughtInvalidArguments, true); +test1(); -var caughtInvalidArguments = false; -var i = 0; -while (true) { - i = (i + 1) | 0; - var a = inIon() ? -1 : 0; - try { - var buf = new Uint8ClampedArray(a); - assertEq(buf.length, 0); - } catch (e) { - assertEq(a, -1); - assertEq(e instanceof RangeError, true, - "expected RangeError, instead threw: " + e); - caughtInvalidArguments = true; - break; +function test2() { + var caughtInvalidArguments = false; + var i = 0; + while (true) { + i = (i + 1) | 0; + var a = inIon() ? -1 : 300; + try { + var buf = new Uint8ClampedArray(a); + assertEq(buf.length, 300); + } catch (e) { + assertEq(a, -1); + assertEq(e instanceof RangeError, true, + "expected RangeError, instead threw: " + e); + caughtInvalidArguments = true; + break; + } + } + assertEq(caughtInvalidArguments, true); +} +test2(); + +function test3() { + var caughtInvalidArguments = false; + var i = 0; + while (true) { + i = (i + 1) | 0; + var a = inIon() ? -1 : 0; + try { + var buf = new Uint8ClampedArray(a); + assertEq(buf.length, 0); + } catch (e) { + assertEq(a, -1); + assertEq(e instanceof RangeError, true, + "expected RangeError, instead threw: " + e); + caughtInvalidArguments = true; + break; + } } + assertEq(caughtInvalidArguments, true); } -assertEq(caughtInvalidArguments, true); +test3(); diff --git a/js/src/jit-test/tests/basic/bug1344265.js b/js/src/jit-test/tests/basic/bug1344265.js index e0ee7f77a4..2ffc2f7e5c 100644 --- a/js/src/jit-test/tests/basic/bug1344265.js +++ b/js/src/jit-test/tests/basic/bug1344265.js @@ -1,3 +1,3 @@ // |jit-test| allow-unhandlable-oom; allow-oom; skip-if: !('oomAfterAllocations' in this) oomAfterAllocations(1); -newExternalString("a"); +newString("a", {external: true}); diff --git a/js/src/jit-test/tests/basic/bug1656744.js b/js/src/jit-test/tests/basic/bug1656744.js new file mode 100644 index 0000000000..b1fd7cfc61 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1656744.js @@ -0,0 +1,8 @@ +Array.prototype[0] = 'x'; +Array.prototype[1] = 'x'; +var arr = []; +for (var p in arr) { + arr[0] = 0; + arr[1] = 1; + arr.reverse(); +} diff --git a/js/src/jit-test/tests/basic/bug663338.js b/js/src/jit-test/tests/basic/bug663338.js index 7f511b3143..efc038972b 100644 --- a/js/src/jit-test/tests/basic/bug663338.js +++ b/js/src/jit-test/tests/basic/bug663338.js @@ -21,6 +21,6 @@ assertEq(parseInt(-0, 10), 0); assertEq(parseInt('0', 10), 0); assertEq(parseInt('-0', 10), -0); -/* this is not very hacky, but we try to get a double value of 0, instead of int */ -assertEq(parseInt(Math.asin(0), 10), 0); -assertEq(parseInt(Math.asin(-0), 10), 0); +// Test with 0 typed as a double instead of int. +assertEq(parseInt(numberToDouble(0), 10), 0); +assertEq(parseInt(numberToDouble(-0), 10), 0); diff --git a/js/src/jit-test/tests/basic/expr-decompiler-bug1475953.js b/js/src/jit-test/tests/basic/expr-decompiler-bug1475953.js index 5cd4cd0844..5b1b93b75e 100644 --- a/js/src/jit-test/tests/basic/expr-decompiler-bug1475953.js +++ b/js/src/jit-test/tests/basic/expr-decompiler-bug1475953.js @@ -1,5 +1,4 @@ Object.defineProperty(this, "fuzzutils", { value:{} }); -setModuleResolveHook(function(module, specifier) {}); try { evaluate(` var f = 396684; var src = "return f(" +Array(10*1000).join("0,")+"Math.atan2());"; diff --git a/js/src/jit-test/tests/basic/external-strings-cgc.js b/js/src/jit-test/tests/basic/external-strings-cgc.js index 5519f68820..aa64172122 100644 --- a/js/src/jit-test/tests/basic/external-strings-cgc.js +++ b/js/src/jit-test/tests/basic/external-strings-cgc.js @@ -3,5 +3,5 @@ startgc(1, "shrinking"); for (var i=0; i<100; i++) { gcslice(100000); var s = "abcdefghi0"; - assertEq(newMaybeExternalString(s), s); + assertEq(newString(s, {maybeExternal: true}), s); } diff --git a/js/src/jit-test/tests/basic/external-strings.js b/js/src/jit-test/tests/basic/external-strings.js index 81951e83c9..fd5faa27ef 100644 --- a/js/src/jit-test/tests/basic/external-strings.js +++ b/js/src/jit-test/tests/basic/external-strings.js @@ -1,17 +1,17 @@ -assertEq(newExternalString(""), ""); -assertEq(newExternalString("abc"), "abc"); -assertEq(newExternalString("abc\0def\u1234"), "abc\0def\u1234"); +assertEq(newString("", {external: true}), ""); +assertEq(newString("abc", {external: true}), "abc"); +assertEq(newString("abc\0def\u1234", {external: true}), "abc\0def\u1234"); var o = {foo: 2, "foo\0": 4}; -var ext = newExternalString("foo"); +var ext = newString("foo", {external: true}); assertEq(o[ext], 2); -var ext2 = newExternalString("foo\0"); +var ext2 = newString("foo\0", {external: true}); assertEq(o[ext2], 4); -eval(newExternalString("assertEq(1, 1)")); +eval(newString("assertEq(1, 1)", {external: true})); // Make sure ensureLinearString does the right thing for external strings. -ext = newExternalString("abc\0defg\0"); +ext = newString("abc\0defg\0", {external: true}); assertEq(ensureLinearString(ext), "abc\0defg\0"); assertEq(ensureLinearString(ext), "abc\0defg\0"); @@ -19,7 +19,7 @@ for (var s of representativeStringArray()) assertEq(ensureLinearString(s), s); for (var s of representativeStringArray()) - assertEq(newExternalString(s), s); + assertEq(newString(s, {external: true}), s); function testQuote() { for (var data of [["abc", "abc"], @@ -27,7 +27,7 @@ function testQuote() { ["abc\t\t\0", "abc\\t\\t\\x00"], ["abc\\def", "abc\\\\def"]]) { try { - assertEq(newExternalString(data[0]), false); + assertEq(newString(data[0], {external: true}), false); } catch(e) { assertEq(e.toString().includes('got "' + data[1] + '",'), true) } @@ -38,9 +38,9 @@ testQuote(); function testMaybeExternal() { for (var i=0; i<10; i++) { var s = "abcdef4321" + i; - assertEq(newMaybeExternalString(s), s); + assertEq(newString(s, {maybeExternal: true}), s); if ((i % 2) === 0) - assertEq(ensureLinearString(newMaybeExternalString(s)), s); + assertEq(ensureLinearString(newString(s, {maybeExternal: true})), s); } } testMaybeExternal(); diff --git a/js/src/jit-test/tests/basic/for-in-densified-elements.js b/js/src/jit-test/tests/basic/for-in-densified-elements.js new file mode 100644 index 0000000000..4874901f17 --- /dev/null +++ b/js/src/jit-test/tests/basic/for-in-densified-elements.js @@ -0,0 +1,21 @@ +function test() { + // An array with sparse elements... + var arr = []; + arr[10_000] = 1; + arr[10_001] = 1; + + for (var prop in arr) { + assertEq(prop, "10000"); + assertEq(arr.length, 10_002); + + // Densify the elements. + for (var i = 0; i < arr.length; i++) { + arr[i] = 1; + } + + // Delete the last dense element (10001). It should not be visited by the + // active for-in (checked above). + arr.length = 10_001; + } +} +test(); diff --git a/js/src/jit-test/tests/basic/for-in-replace-sparse.js b/js/src/jit-test/tests/basic/for-in-replace-sparse.js new file mode 100644 index 0000000000..2a89ec6679 --- /dev/null +++ b/js/src/jit-test/tests/basic/for-in-replace-sparse.js @@ -0,0 +1,12 @@ +// Array with sparse element (because non-writable). +var arr = []; +Object.defineProperty(arr, 0, {writable: false, configurable: true, enumerable: true, value: 0}); + +for (var p in arr) { + // Replace sparse element with dense element. + assertEq(p, "0"); + delete arr[0]; + arr[0] = 0; + arr[1] = 1; + arr.reverse(); +} diff --git a/js/src/jit-test/tests/basic/number-methods-this-error.js b/js/src/jit-test/tests/basic/number-methods-this-error.js new file mode 100644 index 0000000000..6d5a710bb1 --- /dev/null +++ b/js/src/jit-test/tests/basic/number-methods-this-error.js @@ -0,0 +1,12 @@ +load(libdir + "asserts.js"); + +let methods = Object.getOwnPropertyNames(Number.prototype) + .filter(n => n != "constructor"); + +for (let method of methods) { + assertTypeErrorMessage(() => Number.prototype[method].call(new Map), + `Number.prototype.${method} called on incompatible Map`); + + assertTypeErrorMessage(() => Number.prototype[method].call(false), + `Number.prototype.${method} called on incompatible boolean`); +} diff --git a/js/src/jit-test/tests/basic/object-tostring.js b/js/src/jit-test/tests/basic/object-tostring.js new file mode 100644 index 0000000000..5f6204d6dd --- /dev/null +++ b/js/src/jit-test/tests/basic/object-tostring.js @@ -0,0 +1,60 @@ + +function doTest(expected, v) { + assertEq(Object.prototype.toString.call(v), expected) +} + +function Dummy() {} + +// Basic primitive cases +doTest("[object Undefined]", undefined); +doTest("[object Null]", null); +doTest("[object String]", ""); +doTest("[object Number]", 12); +doTest("[object Number]", 12.34); +doTest("[object Boolean]", true); +doTest("[object Symbol]", Symbol()); +doTest("[object BigInt]", 1234n); + +// Exotic objects with builtinTag +doTest("[object Array]", []); +(function() { + doTest("[object Arguments]", arguments); +})(); +doTest("[object Function]", () => {}); +doTest("[object Error]", new Error); +doTest("[object Date]", new Date); +doTest("[object RegExp]", /i/); + +// Exotic objects with @@toStringTag +doTest("[object Map]", new Map); +doTest("[object Set]", new Set); +doTest("[object JSON]", JSON); +doTest("[object Math]", Math); + +// Normal object cases +doTest("[object Object]", {}); +doTest("[object Object]", new Dummy); +doTest("[object Foo]", { [Symbol.toStringTag]: "Foo" }); + +// Test the receiver of Symbol.toStringTag +let receiver1; +let object1 = { + __proto__: { + get [Symbol.toStringTag]() { + receiver1 = this; + } + } +}; +doTest("[object Object]", object1); +assertEq(receiver1, object1); + +//// BELOW THIS LINE TAMPERS WITH GLOBAL + +// Set a toStringTag on the global String.prototype +let receiver2; +Object.defineProperty(String.prototype, Symbol.toStringTag, { get: function() { + receiver2 = this; + return "XString"; +}}); +doTest("[object XString]", ""); +assertEq(Object.getPrototypeOf(receiver2), String.prototype); diff --git a/js/src/jit-test/tests/basic/packed-arrays.js b/js/src/jit-test/tests/basic/packed-arrays.js new file mode 100644 index 0000000000..a6814d47aa --- /dev/null +++ b/js/src/jit-test/tests/basic/packed-arrays.js @@ -0,0 +1,51 @@ +var isPacked = getSelfHostedValue("IsPackedArray"); + +function test() { + var arr; + + // basic + arr = []; + assertEq(isPacked(arr), true); + arr[0] = 0; + assertEq(isPacked(arr), true); + arr[2] = 2; + assertEq(isPacked(arr), false); + + // delete + arr = [1, 2, 3]; + assertEq(isPacked(arr), true); + delete arr[1]; + assertEq(isPacked(arr), false); + + // setting .length + arr = [1]; + arr.length = 0; + assertEq(isPacked(arr), true); + arr.length = 1; + assertEq(isPacked(arr), false); + + // slice + arr = [1, 2, , 3]; + assertEq(isPacked(arr), false); + assertEq(isPacked(arr.slice(0, 2)), true); + assertEq(isPacked(arr.slice(0, 3)), false); + assertEq(isPacked(arr.slice(2, 3)), false); + assertEq(isPacked(arr.slice(3, 4)), true); + + // splice + arr = [1, 2, 3]; + assertEq(isPacked(arr.splice(0)), true); + arr = [1, , 2]; + assertEq(isPacked(arr.splice(0)), false); + arr = [1, , 2]; + assertEq(isPacked(arr.splice(0, 1)), true); + assertEq(arr.length, 2); + assertEq(isPacked(arr.splice(0, 1)), false); + assertEq(arr.length, 1); + assertEq(isPacked(arr.splice(0, 1)), true); + assertEq(arr.length, 0); + assertEq(isPacked(arr.splice(0)), true); +} +for (var i = 0; i < 5; i++) { + test(); +} diff --git a/js/src/jit-test/tests/basic/plain-object-prototypes-error.js b/js/src/jit-test/tests/basic/plain-object-prototypes-error.js index 317fa1acc9..472e9f0c4f 100644 --- a/js/src/jit-test/tests/basic/plain-object-prototypes-error.js +++ b/js/src/jit-test/tests/basic/plain-object-prototypes-error.js @@ -1,17 +1,37 @@ -// Make sure the real class name is not exposed by Errors. -function assertThrowsObjectError(f) { +// Make sure the error has a sensible error message. +function assertThrowsObjectError(f, name) { try { f(); assertEq(true, false); } catch (e) { assertEq(e instanceof TypeError, true); - assertEq(e.message.includes("called on incompatible Object"), true); + assertEq(e.message.includes("called on incompatible " + name), true, e.message); } } -assertThrowsObjectError(() => Map.prototype.has(0)); -assertThrowsObjectError(() => Set.prototype.has(0)); -assertThrowsObjectError(() => WeakMap.prototype.has({})); -assertThrowsObjectError(() => WeakSet.prototype.has({})); -assertThrowsObjectError(() => Date.prototype.getSeconds()); -assertThrowsObjectError(() => RegExp.prototype.compile()); +// Call methods on the prototypes where the methods themselves are defined. +assertThrowsObjectError(() => Map.prototype.has(0), "Map.prototype"); +assertThrowsObjectError(() => Set.prototype.has(0), "Set.prototype"); +assertThrowsObjectError(() => WeakMap.prototype.has({}), "WeakMap.prototype"); +assertThrowsObjectError(() => WeakSet.prototype.has({}), "WeakSet.prototype"); +assertThrowsObjectError(() => Date.prototype.getSeconds(), "Date.prototype"); +assertThrowsObjectError(() => RegExp.prototype.compile(), "RegExp.prototype"); + +// Call methods with different prototype objects. +assertThrowsObjectError(() => Map.prototype.has.call(ArrayBuffer.prototype), "ArrayBuffer.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(BigInt.prototype), "BigInt.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(DataView.prototype), "DataView.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(Date.prototype), "Date.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(FinalizationRegistry.prototype), "FinalizationRegistry.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(Int32Array.prototype), "Int32Array.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(Promise.prototype), "Promise.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(ReadableStream.prototype), "ReadableStream.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(RegExp.prototype), "RegExp.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(Set.prototype), "Set.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(TypeError.prototype), "TypeError.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(WeakMap.prototype), "WeakMap.prototype"); +assertThrowsObjectError(() => Map.prototype.has.call(WeakRef.prototype), "WeakRef.prototype"); + +// Call methods with different objects. +assertThrowsObjectError(() => Map.prototype.has.call(new Error), "Error"); +assertThrowsObjectError(() => Map.prototype.has.call(new TypeError), "Error"); diff --git a/js/src/jit-test/tests/basic/str-atom-cache-extensible.js b/js/src/jit-test/tests/basic/str-atom-cache-extensible.js new file mode 100644 index 0000000000..bee8f13847 --- /dev/null +++ b/js/src/jit-test/tests/basic/str-atom-cache-extensible.js @@ -0,0 +1,15 @@ +// Create an extensible string. +var extensible = "foo".repeat(50); +extensible += "bar"; +extensible.indexOf("X"); + +// Ensure it's in the StringToAtomCache. +var obj = {}; +obj[extensible] = 1; + +// Make it a dependent string. +var other = extensible + "baz"; +other.indexOf("X"); + +// Must still be in the cache. +obj[extensible] = 1; diff --git a/js/src/jit-test/tests/basic/test-jitinfo.js b/js/src/jit-test/tests/basic/test-jitinfo.js index 389029dd76..606f277794 100644 --- a/js/src/jit-test/tests/basic/test-jitinfo.js +++ b/js/src/jit-test/tests/basic/test-jitinfo.js @@ -1,24 +1,26 @@ // Test for the shell's FakeDOMObject constructor. This test // ensures the fuzzers know about this object. function f() { - var res = 0; - var d = new FakeDOMObject(); - assertEq(d !== new FakeDOMObject(), true); + var res = 0; + var d = new FakeDOMObject(); + assertEq(d !== new FakeDOMObject(), true); - for (var i=0; i<100; i++) { - var x = d.x; - assertEq(typeof x, "number"); + for (var i = 0; i < 100; i++) { + assertEq(d.slot, 42); - d.x = 10; - d.x = undefined; + var x = d.x; + assertEq(typeof x, "number"); - d.x = FakeDOMObject.prototype.x; - FakeDOMObject.prototype.x = d.x; - FakeDOMObject.prototype.doFoo(); + d.x = 10; + d.x = undefined; - assertEq(d.doFoo(), 0); - assertEq(d.doFoo(1), 1); - assertEq(d.doFoo(1, 2), 2); - } + d.x = FakeDOMObject.prototype.x; + FakeDOMObject.prototype.x = d.x; + FakeDOMObject.prototype.doFoo(); + + assertEq(d.doFoo(), 0); + assertEq(d.doFoo(1), 1); + assertEq(d.doFoo(1, 2), 2); + } } f(); diff --git a/js/src/jit-test/tests/basic/testBug604210.js b/js/src/jit-test/tests/basic/testBug604210.js index 1983541b15..146eaf1801 100644 --- a/js/src/jit-test/tests/basic/testBug604210.js +++ b/js/src/jit-test/tests/basic/testBug604210.js @@ -6,6 +6,6 @@ function f() { } catch (e) { ex = e; } - assertEq(ex.message.endsWith(`x is undefined`), true); + assertEq(/(x is|"foo" of) undefined/.test(ex.message), true); } f(); diff --git a/js/src/jit-test/tests/basic/testInitSingletons.js b/js/src/jit-test/tests/basic/testInitSingletons.js index fb8dd641c2..82ca54c81c 100644 --- a/js/src/jit-test/tests/basic/testInitSingletons.js +++ b/js/src/jit-test/tests/basic/testInitSingletons.js @@ -28,7 +28,9 @@ assertEq(q[4294967295], 2); try { [1,2,3,{a:0,b:1}].foo.bar; -} catch (e) { assertEq(e.message.search("\.foo is undefined") != -1, true); } +} catch (e) { + assertEq(/(.foo is|"bar" of) undefined/.test(e.message), true); +} var a = [1 + 1, 3 * 2, 6 - 5, 14 % 6, 15 / 5, 1 << 3, 8 >> 2, 5 | 2, 5 ^ 3, ~3, -3,"a" + "b", !true, !false]; diff --git a/js/src/jit-test/tests/basic/testMathClz32.js b/js/src/jit-test/tests/basic/testMathClz32.js index 0cc4aae890..61cd1f91a2 100644 --- a/js/src/jit-test/tests/basic/testMathClz32.js +++ b/js/src/jit-test/tests/basic/testMathClz32.js @@ -23,6 +23,16 @@ function h() { return x; } +function k() { + var x = 0; + for (var i = -1000; i < 1000; i++) { + x += Math.clz32(i); + x += Math.clz32(i + 0.5); + } + return x; +} + assertEq(f(), 13048543); assertEq(g(), 13048543); -assertEq(h(), 13048575); \ No newline at end of file +assertEq(h(), 13048575); +assertEq(k(), 46078); diff --git a/js/src/jit-test/tests/basic/transplant-dom-slot2.js b/js/src/jit-test/tests/basic/transplant-dom-slot2.js new file mode 100644 index 0000000000..c4c2e8c482 --- /dev/null +++ b/js/src/jit-test/tests/basic/transplant-dom-slot2.js @@ -0,0 +1,7 @@ +// Make sure to transplant DOM_OBJECT_SLOT2 for FakeDOMObject +let source = new FakeDOMObject(); +assertEq(source.slot, 42); +let {object: target, transplant} = transplantableObject({object: source}); +transplant(this); +assertEq(source.slot, 42); +assertEq(target.slot, 42); diff --git a/js/src/jit-test/tests/binast/lazy/basic/external-strings-cgc.binjs b/js/src/jit-test/tests/binast/lazy/basic/external-strings-cgc.binjs index 4853a5bbdd..4090cde64e 100644 Binary files a/js/src/jit-test/tests/binast/lazy/basic/external-strings-cgc.binjs and b/js/src/jit-test/tests/binast/lazy/basic/external-strings-cgc.binjs differ diff --git a/js/src/jit-test/tests/binast/nonlazy/basic/external-strings-cgc.binjs b/js/src/jit-test/tests/binast/nonlazy/basic/external-strings-cgc.binjs index 4853a5bbdd..4090cde64e 100644 Binary files a/js/src/jit-test/tests/binast/nonlazy/basic/external-strings-cgc.binjs and b/js/src/jit-test/tests/binast/nonlazy/basic/external-strings-cgc.binjs differ diff --git a/js/src/jit-test/tests/cacheir/add-dense-element-non-extensible.js b/js/src/jit-test/tests/cacheir/add-dense-element-non-extensible.js new file mode 100644 index 0000000000..2958ce2283 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/add-dense-element-non-extensible.js @@ -0,0 +1,160 @@ +// Add dense elements to packed and non-packed arrays. Cover both mono- and +// polymorphic call sites. Change array to non-extensible during execution. + +function testAddDenseEmpty() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseEmpty(); + +function testAddDensePacked() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDensePacked(); + +function testAddDenseNonPacked() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + store(array, i); + } + + assertEq(array.length, 5); + assertEq(0 in array, false); + for (var i = 1; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseNonPacked(); + +function testAddDenseEmptyPoly() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseEmptyPoly(); + +function testAddDensePackedPoly() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDensePackedPoly(); + +function testAddDenseNonPackedPoly() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + assertEq(0 in array, false); + for (var i = 1; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseNonPackedPoly(); diff --git a/js/src/jit-test/tests/cacheir/add-dense-element-non-writable-length.js b/js/src/jit-test/tests/cacheir/add-dense-element-non-writable-length.js new file mode 100644 index 0000000000..635ee07186 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/add-dense-element-non-writable-length.js @@ -0,0 +1,160 @@ +// Add dense elements to packed and non-packed arrays. Cover both mono- and +// polymorphic call sites. Change array length to non-writable during execution. + +function testAddDenseEmpty() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseEmpty(); + +function testAddDensePacked() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDensePacked(); + +function testAddDenseNonPacked() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + store(array, i); + } + + assertEq(array.length, 5); + assertEq(0 in array, false); + for (var i = 1; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseNonPacked(); + +function testAddDenseEmptyPoly() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseEmptyPoly(); + +function testAddDensePackedPoly() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDensePackedPoly(); + +function testAddDenseNonPackedPoly() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + assertEq(0 in array, false); + for (var i = 1; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testAddDenseNonPackedPoly(); diff --git a/js/src/jit-test/tests/cacheir/add-dense-element.js b/js/src/jit-test/tests/cacheir/add-dense-element.js new file mode 100644 index 0000000000..099e941648 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/add-dense-element.js @@ -0,0 +1,124 @@ +// Add dense elements to packed and non-packed arrays. Cover both mono- and +// polymorphic call sites. + +function testAddDenseEmpty() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + store(array, i); + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDenseEmpty(); + +function testAddDensePacked() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + store(array, i); + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDensePacked(); + +function testAddDenseNonPacked() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 2; i < 10; ++i) { + store(array, i); + } + + assertEq(array.length, 10); + assertEq(0 in array, false); + for (var i = 1; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDenseNonPacked(); + +function testAddDenseEmptyPoly() { + var array = []; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDenseEmptyPoly(); + +function testAddDensePackedPoly() { + var array = [0, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDensePackedPoly(); + +function testAddDenseNonPackedPoly() { + var array = [/* hole */, 1]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 2; i < 10; ++i) { + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 10); + assertEq(0 in array, false); + for (var i = 1; i < 10; ++i) { + assertEq(array[i], i); + } +} +testAddDenseNonPackedPoly(); diff --git a/js/src/jit-test/tests/cacheir/array-slice.js b/js/src/jit-test/tests/cacheir/array-slice.js new file mode 100644 index 0000000000..2ed43926ff --- /dev/null +++ b/js/src/jit-test/tests/cacheir/array-slice.js @@ -0,0 +1,39 @@ +function packed() { + var a = [0, 1, 2, 3]; + for (var i = 0; i <= 100; ++i) { + var r = a.slice(0); + assertEq(r.length, 4); + } +} + +for (var i = 0; i < 2; ++i) { + packed(); +} + +function packedThenUnpacked() { + var a = [0, 1, 2, 3]; + var q = 0; + for (var i = 0; i <= 100; ++i) { + if (i === 100) a[10] = 0; + + var r = a.slice(0); + assertEq(r.length, i < 100 ? 4 : 11); + } +} + +for (var i = 0; i < 2; ++i) { + packedThenUnpacked(); +} + +function unpacked() { + var a = [0, 1, /* hole */ , 3]; + for (var i = 0; i <= 100; ++i) { + var r = a.slice(0); + assertEq(r.length, 4); + assertEq(2 in r, false); + } +} + +for (var i = 0; i < 2; ++i) { + unpacked(); +} diff --git a/js/src/jit-test/tests/cacheir/bigint-compare-double.js b/js/src/jit-test/tests/cacheir/bigint-compare-double.js index 14f6c89355..ea61e4c558 100644 --- a/js/src/jit-test/tests/cacheir/bigint-compare-double.js +++ b/js/src/jit-test/tests/cacheir/bigint-compare-double.js @@ -59,8 +59,8 @@ var xs = [ ]; function Double(x) { - // Math.hypot always returns a Double valued number. - return x < 0 ? -Math.hypot(x) : Math.hypot(x); + // numberToDouble always returns a Double valued number. + return numberToDouble(x); } // Compute the Double approximation of the BigInt values. diff --git a/js/src/jit-test/tests/cacheir/binaryarith.js b/js/src/jit-test/tests/cacheir/binaryarith.js index 24effff0ad..1746aad963 100644 --- a/js/src/jit-test/tests/cacheir/binaryarith.js +++ b/js/src/jit-test/tests/cacheir/binaryarith.js @@ -150,6 +150,14 @@ warmup(funBitOr1, [[1, 1, 1], [8, 1, 9], [0, 1233, 1233], [5, 0, 5], var funBitOr3 = (a, b) => { return a | b; } warmup(funBitOr3, [[1, true, 1], [8, true, 9], [false, 1233, 1233], [5, false, 5]]); +//BitOr null w/ Int32 +var funBitOr4 = (a, b) => { return a | b; } +warmup(funBitOr4, [[1, null, 1], [8, null, 8], [null, 1233, 1233], [5, null, 5]]); + +//BitOr undefined w/ Int32 +var funBitOr5 = (a, b) => { return a | b; } +warmup(funBitOr5, [[1, void 0, 1], [8, void 0, 8], [void 0, 1233, 1233], [5, void 0, 5]]); + //BitXOr Int32 var funBitXOr1 = (a, b) => { return a ^ b; } warmup(funBitXOr1, [[1, 1, 0], [5, 1, 4], [63, 31, 32], [4294967295, 2147483647, -2147483648 ] ]); @@ -170,6 +178,14 @@ warmup(funBitXOr4, [[54772703898, 2890608493, 1828589047], [-18446744073709551615, 54772703898, -1061870950], [4294967295, -1, 0]]); +//BitXOr null+int32 +var funBitXOr5 = (a, b) => { return a ^ b; } +warmup(funBitXOr5, [[1, null, 1], [5, null, 5], [5, null, 5], [null, 1, 1]]); + +//BitXOr undefined+int32 +var funBitXOr6 = (a, b) => { return a ^ b; } +warmup(funBitXOr6, [[1, void 0, 1], [5, void 0, 5], [5, void 0, 5], [void 0, 1, 1]]); + //BitAnd Int32 var funBitAnd1 = (a, b) => { return a & b; } warmup(funBitAnd1, [[1,1,1], [5,1,1], [63,31,31], [4294967295,2147483647,2147483647], @@ -184,6 +200,14 @@ warmup(funBitAnd2, [[1.2 ,1, 1], [5, 1.4, 1], [63,31.99,31], var funBitAnd1 = (a, b) => { return a & b; } warmup(funBitAnd1, [[1,true,1], [5,false,0], [true, 6, 0], [false, 12, 0]]); +//BitAnd Int32 + null +var funBitAnd4 = (a, b) => { return a & b; } +warmup(funBitAnd4, [[1, null, 0], [5, null, 0], [null, 6, 0], [null, 12, 0]]); + +//BitAnd Int32 + undefined +var funBitAnd5 = (a, b) => { return a & b; } +warmup(funBitAnd5, [[1, void 0, 0], [5, void 0, 0], [void 0, 6, 0], [void 0, 12, 0]]); + //Lsh Int32 var funLsh1 = (a, b) => { return a << b; } warmup(funLsh1, [[5,1,10], [1,1,2], [63,31,-2147483648], @@ -198,6 +222,14 @@ warmup(funLsh2, [[5,true,10], [true,1,2], [63,false,63], [false, 12, 0]]); var funLsh3 = (a, b) => { return a << b; } warmup(funLsh3, [[54772703898, 1, -2123741900],[2147483658, 0, -2147483638]]); +//Lsh Boolean w/ null +var funLsh4 = (a, b) => { return a << b; } +warmup(funLsh4, [[5, null, 5], [null, 1, 0], [63, null, 63], [null, 12, 0]]); + +//Lsh Boolean w/ undefined +var funLsh5 = (a, b) => { return a << b; } +warmup(funLsh5, [[5, void 0, 5], [void 0, 1, 0], [63, void 0, 63], [void 0, 12, 0]]); + //Rsh Int32 var funRsh1 = (a, b) => { return a >> b; } warmup(funRsh1, [[1,1,0], [5,1,2], [63,31,0], [4294967295,2147483647,-1], [-2,10,-1], @@ -211,6 +243,14 @@ warmup(funRsh2, [[true,1,0], [1,true,0], [false, 3, 0], [3, false, 3]]); var funRsh3 = (a, b) => { return a >> b; } warmup(funRsh3, [[54772703898, 11, -518492 ], [2147483658, 0, -2147483638]]); +//Rsh Int32 null +var funRsh4 = (a, b) => { return a >> b; } +warmup(funRsh4, [[null, 1, 0], [1, null, 1], [null, 3, 0], [3, null, 3]]); + +//Rsh Int32 undefined +var funRsh5 = (a, b) => { return a >> b; } +warmup(funRsh5, [[void 0, 1, 0], [1, void 0, 1], [void 0, 3, 0], [3, void 0, 3]]); + //URsh Int32 var funURsh1 = (a, b) => { return a >>> b; } warmup(funURsh1, [[1,1,0], [5,1,2], [63,31,0], [4294967295,2147483647,1], [-2,10,4194303], @@ -230,6 +270,14 @@ var funURsh4 = (a, b) => { return a >>> b; } warmup(funURsh4, [[54772703898, 11, 1578660], [2147483658, 11, 1048576], [4294967295, 0, 4294967295]]); +//URsh null Int32 +var funURsh5 = (a, b) => { return a >>> b; } +warmup(funURsh5, [[null, 1, 0], [5, null, 5], [63, null, 63], [null, 20, 0]]); + +//URsh undefined Int32 +var funURsh6 = (a, b) => { return a >>> b; } +warmup(funURsh6, [[void 0, 1, 0], [5, void 0, 5], [63, void 0, 63], [void 0, 20, 0]]); + // Other Test cases that Have been useful: for (var k=0; k < 30; k++) { diff --git a/js/src/jit-test/tests/cacheir/boolean-call.js b/js/src/jit-test/tests/cacheir/boolean-call.js new file mode 100644 index 0000000000..7c6d94f3d4 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/boolean-call.js @@ -0,0 +1,67 @@ +function wrapper(values) { + function test(values) { + var expected = values.map(v => !!v); + + for (var i = 0; i < 100; ++i) { + var ix = i % values.length; + var val = values[ix]; + var actual = Boolean(val); + assertEq(actual, expected[ix]); + } + } + + for (var i = 0; i < 2; ++i) { + test(values); + } +} + +function makeTest() { + // Create a copy to avoid type pollution. + return Function(`return ${wrapper}`)(); +} + +// Use a new compartment to create a wrapper. +var g = newGlobal({newCompartment: true}); + +var testValues = { + boolean: [true, false], + int32: [-2147483648, -1, 0, 1, 2147483647], + double: [-Infinity, -1.5, -1, -0.5, -0, +0, +0.5, +1, +1.5, Infinity, NaN], + string: ["", "true", "false", "0", "1", "hello"], + symbol: [Symbol(), Symbol("desc"), Symbol.iterator], + bigint: [ + -(2n ** 1000n), + -18446744073709551616n, // -(2n**64n) + -9223372036854775808n, // -(2n**63n) + -4294967296n, // -(2**32) + -2147483648n, // -(2**31) + -1n, 0n, 1n, + 2147483648n, // 2**31 + 4294967296n, // 2**32 + 9223372036854775808n, // 2n**63n + 18446744073709551616n, // 2n**64n + 2n ** 1000n, + ], + object: [{}, [], function(){}, new Proxy({}, {}), createIsHTMLDDA(), g.eval("createIsHTMLDDA()")], + null: [null], + undefined: [undefined], +}; + +for (var values of Object.values(testValues)) { + makeTest()(values); +} + +// boolean and int32 +makeTest()([].concat(testValues.boolean, testValues.int32)); + +// int32 and double +makeTest()([].concat(testValues.int32, testValues.double)); + +// null and undefined +makeTest()([].concat(testValues.null, testValues.undefined)); + +// null, undefined, and object +makeTest()([].concat(testValues.null, testValues.undefined, testValues.object)); + +// all values +makeTest()(Object.values(testValues).flat()); diff --git a/js/src/jit-test/tests/cacheir/boolean-compare-string-or-double.js b/js/src/jit-test/tests/cacheir/boolean-compare-string-or-double.js index 51a67a757c..13da6000f1 100644 --- a/js/src/jit-test/tests/cacheir/boolean-compare-string-or-double.js +++ b/js/src/jit-test/tests/cacheir/boolean-compare-string-or-double.js @@ -31,8 +31,8 @@ var ys = [ ]; function Double(x) { - // Math.hypot always returns a Double valued number. - return x < 0 ? -Math.hypot(x) : Math.hypot(x); + // numberToDouble always returns a Double valued number. + return numberToDouble(x); } var zs = [ diff --git a/js/src/jit-test/tests/cacheir/bug1488786.js b/js/src/jit-test/tests/cacheir/bug1488786.js index e0ae7911df..656f1f0d2e 100644 --- a/js/src/jit-test/tests/cacheir/bug1488786.js +++ b/js/src/jit-test/tests/cacheir/bug1488786.js @@ -16,9 +16,9 @@ for (var i = 0; i < 30; i++) { get_thee(A, i % A.length); } -// Math.hypot currently always returns a Number, so helps -// us ensure we're accessing the array with a Number index. -var y = Math.hypot(1,0); +// numberToDouble always returns a double-typed Number, so helps +// us ensure we're accessing the array with a double-typed Number index. +var y = numberToDouble(1); var z = 2**31-1; // Ensure we handle negative indices. var a = -1; diff --git a/js/src/jit-test/tests/cacheir/bug1651732-ionic-getprop-super.js b/js/src/jit-test/tests/cacheir/bug1651732-ionic-getprop-super.js new file mode 100644 index 0000000000..a64e2aabb0 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1651732-ionic-getprop-super.js @@ -0,0 +1,28 @@ +class Base { + static a = 0; + static [Symbol.iterator] = 0; +} + +class Derived extends Base { + static m(key) { + // Attach an IC through IonGetPropSuperIC. + return super[key]; + } +} + +var key = { + value: "a", + + [Symbol.toPrimitive]() { + return this.value; + } +}; + +for (var i = 0; i < 100; ++i) { + // Change key[Symbol.toPrimitive] to return a symbol after some warm-up. + if (i > 80) { + key.value = Symbol.iterator; + } + + assertEq(Derived.m(key), 0); +} diff --git a/js/src/jit-test/tests/cacheir/bug1651732-proxy-get.js b/js/src/jit-test/tests/cacheir/bug1651732-proxy-get.js new file mode 100644 index 0000000000..9a4362f410 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1651732-proxy-get.js @@ -0,0 +1,23 @@ +// An object with a custom [Symbol.toPrimitive] function. +var key = { + value: "a", + + [Symbol.toPrimitive]() { + return this.value; + } +}; + +var target = {}; +var obj = new Proxy(target, {}); + +for (var i = 0; i < 100; ++i) { + // Change key[Symbol.toPrimitive] to return a symbol after some warm-up. + if (i > 80) { + key.value = Symbol.iterator; + } + + target[key.value] = i; + + // Attach an IC for JSOp::GetElem on proxies. + assertEq(obj[key], i); +} diff --git a/js/src/jit-test/tests/cacheir/bug1651732-proxy-has.js b/js/src/jit-test/tests/cacheir/bug1651732-proxy-has.js new file mode 100644 index 0000000000..004b5982d8 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1651732-proxy-has.js @@ -0,0 +1,24 @@ +// An object with a custom [Symbol.toPrimitive] function. +var key = { + value: "a", + + [Symbol.toPrimitive]() { + return this.value; + } +}; + +var target = { + a: 0, + [Symbol.iterator]: 0, +}; +var obj = new Proxy(target, {}); + +for (var i = 0; i < 100; ++i) { + // Change key[Symbol.toPrimitive] to return a symbol after some warm-up. + if (i > 80) { + key.value = Symbol.iterator; + } + + // Attach an IC for JSOp::In on proxies. + assertEq(key in obj, true); +} diff --git a/js/src/jit-test/tests/cacheir/bug1651732-proxy-hasOwn.js b/js/src/jit-test/tests/cacheir/bug1651732-proxy-hasOwn.js new file mode 100644 index 0000000000..90f94a4e48 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1651732-proxy-hasOwn.js @@ -0,0 +1,24 @@ +// An object with a custom [Symbol.toPrimitive] function. +var key = { + value: "a", + + [Symbol.toPrimitive]() { + return this.value; + } +}; + +var target = { + a: 0, + [Symbol.iterator]: 0, +}; +var obj = new Proxy(target, {}); + +for (var i = 0; i < 100; ++i) { + // Change key[Symbol.toPrimitive] to return a symbol after some warm-up. + if (i > 80) { + key.value = Symbol.iterator; + } + + // Attach an IC for JSOp::HasOwn on proxies. + assertEq(Object.prototype.hasOwnProperty.call(obj, key), true); +} diff --git a/js/src/jit-test/tests/cacheir/bug1651732-proxy-set.js b/js/src/jit-test/tests/cacheir/bug1651732-proxy-set.js new file mode 100644 index 0000000000..a52362a91f --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1651732-proxy-set.js @@ -0,0 +1,23 @@ +// An object with a custom [Symbol.toPrimitive] function. +var key = { + value: "a", + + [Symbol.toPrimitive]() { + return this.value; + } +}; + +var target = {}; +var obj = new Proxy(target, {}); + +for (var i = 0; i < 100; ++i) { + // Change key[Symbol.toPrimitive] to return a symbol after some warm-up. + if (i > 80) { + key.value = Symbol.iterator; + } + + obj[key] = i; + + // Attach an IC for JSOp::SetElem on proxies. + assertEq(target[key.value], i); +} diff --git a/js/src/jit-test/tests/cacheir/bug1654947.js b/js/src/jit-test/tests/cacheir/bug1654947.js new file mode 100644 index 0000000000..673e5fd0c2 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1654947.js @@ -0,0 +1,11 @@ +function f() { + let g = x => (x >>> {} >>> x, x); + let arr = [0, 0xffff, undefined]; + for (let i = 0; i < 10; i++) { + for (let j = 0; j < 3; j++) { + let y = g(arr[j]); + assertEq(y, arr[j]); + } + } +} +f(); diff --git a/js/src/jit-test/tests/cacheir/function-name.js b/js/src/jit-test/tests/cacheir/function-name.js new file mode 100644 index 0000000000..43b603c362 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/function-name.js @@ -0,0 +1,59 @@ +function interpreted() { + for (var i = 0; i < 50; i++) { + var f = (0, function () {}); + assertEq(f.name, ""); + } + + for (var i = 0; i < 50; i++) { + var f = function () {}; + assertEq(f.name, "f"); + } + + for (var i = 0; i < 50; i++) { + var f = function a () {}; + assertEq(f.name, "a"); + } +} + +function bound() { + for (var i = 0; i < 50; i++) { + var f = (function () {}).bind({}); + assertEq(f.name, "bound "); + } + + for (var i = 0; i < 50; i++) { + var f = (function a () {}).bind({}); + assertEq(f.name, "bound a"); + } +} + +function native() { + for (var i = 0; i < 50; i++) { + // Use the interpreted function for getting the IC generated in the first place. + var f = function () {}; + + var name = "f"; + if (i == 15) { + f = Math.sin; + name = "sin"; + } else if (i == 20) { + f = Math.cos; + name = "cos"; + } else if (i == 25) { + f = Math.ceil; + name = "ceil"; + } else if (i == 30) { + f = Math.tan; + name = "tan"; + } else if (i == 35) { + f = Math.tanh; + name = "tanh"; + } + + assertEq(f.name, name); + } +} + +interpreted(); +bound(); +native(); diff --git a/js/src/jit-test/tests/cacheir/number-toString.js b/js/src/jit-test/tests/cacheir/number-toString.js new file mode 100644 index 0000000000..ed076a6753 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/number-toString.js @@ -0,0 +1,44 @@ +function int32() { + var n = 42; + for (var i = 0; i < 100; i++) { + assertEq(n.toString(), "42"); + } +} + +function double() { + var n = 3.14; + for (var i = 0; i < 100; i++) { + assertEq(n.toString(), "3.14"); + } +} + +function number() { + var n = 1; + for (var i = 0; i < 100; i++) { + assertEq(n.toString(), i > 50 ? "3.14" : "1"); + if (i == 50) { + n = 3.14; + } + } +} + +function obj() { + var o = new Number(42); + for (var i = 0; i < 100; i++) { + assertEq(o.toString(), "42"); + } +} + +function overwritten() { + Number.prototype.toString = () => "haha"; + var n = 42; + for (var i = 0; i < 100; i++) { + assertEq(n.toString(), "haha"); + } +} + +int32(); +double(); +number(); +obj(); +overwritten(); diff --git a/js/src/jit-test/tests/cacheir/object-is-prototype-of.js b/js/src/jit-test/tests/cacheir/object-is-prototype-of.js new file mode 100644 index 0000000000..1ecc441f47 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/object-is-prototype-of.js @@ -0,0 +1,41 @@ +function testPrimitive() { + for (var i = 0; i < 100; ++i) { + // Null and undefined. + assertEq(Object.prototype.isPrototypeOf(null), false); + assertEq(Object.prototype.isPrototypeOf(void 0), false); + + // Primitive wrappers. + assertEq(String.prototype.isPrototypeOf(""), false); + assertEq(Number.prototype.isPrototypeOf(0), false); + assertEq(Boolean.prototype.isPrototypeOf(true), false); + assertEq(BigInt.prototype.isPrototypeOf(0n), false); + assertEq(Symbol.prototype.isPrototypeOf(Symbol.hasInstance), false); + } +} +testPrimitive(); + +function testObject() { + for (var i = 0; i < 100; ++i) { + assertEq(Object.prototype.isPrototypeOf({}), true); + assertEq(Object.prototype.isPrototypeOf([]), true); + + assertEq(Array.prototype.isPrototypeOf({}), false); + assertEq(Array.prototype.isPrototypeOf([]), true); + } +} +testObject(); + +function testProxy() { + var proxy = new Proxy({}, new Proxy({}, { + get(t, pk, r) { + assertEq(pk, "getPrototypeOf"); + return Reflect.get(t, pk, r); + } + })); + + for (var i = 0; i < 100; ++i) { + assertEq(Object.prototype.isPrototypeOf(proxy), true); + assertEq(Array.prototype.isPrototypeOf(proxy), false); + } +} +testProxy(); diff --git a/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-extensible.js b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-extensible.js new file mode 100644 index 0000000000..21ad5f5164 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-extensible.js @@ -0,0 +1,55 @@ +// Store an element into a previous hole value and later add more elements +// exceeding the initialised length. Cover both mono- and polymorphic call +// sites. Change array length to non-extensible during execution. + +function testStoreDenseHole() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHole(); + +function testStoreDenseHolePoly() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.preventExtensions(array); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHolePoly(); diff --git a/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length-at-start.js b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length-at-start.js new file mode 100644 index 0000000000..513fd6bc08 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length-at-start.js @@ -0,0 +1,55 @@ +// Store an element into a previous hole value and later add more elements +// exceeding the initialised length. Cover both mono- and polymorphic call +// sites. The array has a non-writable length at the start. + +function testStoreDenseHole() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + Object.defineProperty(array, "length", { + writable: false + }); + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + store(array, i); + } + + assertEq(array.length, 4); + for (var i = 0; i < 4; ++i) { + assertEq(array[i], i); + } + for (var i = 4; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHole(); + +function testStoreDenseHolePoly() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + Object.defineProperty(array, "length", { + writable: false + }); + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 4); + for (var i = 0; i < 4; ++i) { + assertEq(array[i], i); + } + for (var i = 4; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHolePoly(); diff --git a/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length.js b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length.js new file mode 100644 index 0000000000..468976332f --- /dev/null +++ b/js/src/jit-test/tests/cacheir/store-dense-element-hole-non-writable-length.js @@ -0,0 +1,55 @@ +// Store an element into a previous hole value and later add more elements +// exceeding the initialised length. Cover both mono- and polymorphic call +// sites. Change array length to non-writable during execution. + +function testStoreDenseHole() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + store(array, i); + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHole(); + +function testStoreDenseHolePoly() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + if (i === 5) { + Object.defineProperty(array, "length", {writable: false}); + } + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 5); + for (var i = 0; i < 5; ++i) { + assertEq(array[i], i); + } + for (var i = 5; i < 10; ++i) { + assertEq(i in array, false); + } +} +testStoreDenseHolePoly(); diff --git a/js/src/jit-test/tests/cacheir/store-dense-element-hole.js b/js/src/jit-test/tests/cacheir/store-dense-element-hole.js new file mode 100644 index 0000000000..fece420056 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/store-dense-element-hole.js @@ -0,0 +1,43 @@ +// Store an element into a previous hole value and later add more elements +// exceeding the initialised length. Cover both mono- and polymorphic call +// sites. + +function testStoreDenseHole() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + for (var i = 0; i < 10; ++i) { + store(array, i); + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testStoreDenseHole(); + +function testStoreDenseHolePoly() { + var array = [/* hole */, /* hole */, /* hole */, /* hole */, ]; + + function store(ar, index) { + ar[index] = index; + } + + var objects = [array, {}]; + + for (var i = 0; i < 10; ++i) { + for (var j = 0; j < objects.length; ++j) { + store(objects[j], i); + } + } + + assertEq(array.length, 10); + for (var i = 0; i < 10; ++i) { + assertEq(array[i], i); + } +} +testStoreDenseHolePoly(); diff --git a/js/src/jit-test/tests/cacheir/string-fromcodepoint.js b/js/src/jit-test/tests/cacheir/string-fromcodepoint.js new file mode 100644 index 0000000000..254f41fd85 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/string-fromcodepoint.js @@ -0,0 +1,15 @@ +function f() { + for (var i = 0x10F000; i <= 0x10FFFF + 1; ++i) { + String.fromCodePoint(i); + } +} + +for (var i = 0; i < 2; ++i) { + var err; + try { + f(); + } catch (e) { + err = e; + } + assertEq(err instanceof RangeError, true); +} diff --git a/js/src/jit-test/tests/cacheir/string-int32-arith.js b/js/src/jit-test/tests/cacheir/string-int32-arith.js index 21de7e0d29..8f39d3e124 100644 --- a/js/src/jit-test/tests/cacheir/string-int32-arith.js +++ b/js/src/jit-test/tests/cacheir/string-int32-arith.js @@ -16,6 +16,36 @@ function test(zero, one) { assertEq(10 ** one, 10); assertEq(one ** 4, 1); + + assertEq(10 & zero, 0); + assertEq(zero & 10, 0); + assertEq(10 & one, 0); + assertEq(one & 10, 0); + + assertEq(10 | zero, 10); + assertEq(zero | 10, 10); + assertEq(10 | one, 11); + assertEq(one | 10, 11); + + assertEq(10 ^ zero, 10); + assertEq(zero ^ 10, 10); + assertEq(10 ^ one, 11); + assertEq(one ^ 10, 11); + + assertEq(10 << zero, 10); + assertEq(zero << 10, 0); + assertEq(10 << one, 20); + assertEq(one << 10, 1024); + + assertEq(10 >> zero, 10); + assertEq(zero >> 10, 0); + assertEq(10 >> one, 5); + assertEq(one >> 10, 0); + + assertEq(10 >>> zero, 10); + assertEq(zero >>> 10, 0); + assertEq(10 >>> one, 5); + assertEq(one >>> 10, 0); } for (var i = 0; i < 10; i++) { diff --git a/js/src/jit-test/tests/cacheir/string-loadchar.js b/js/src/jit-test/tests/cacheir/string-loadchar.js new file mode 100644 index 0000000000..f89c1d8b33 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/string-loadchar.js @@ -0,0 +1,44 @@ +// Load Latin-1 and Two-Byte strings. +function latin1AndTwoByte() { + for (var i = 0; i <= 0x03FF; ++i) { + var s = String.fromCodePoint(i); + assertEq(s[0], s); + assertEq(s.charAt(0), s); + } +} + +for (var i = 0; i < 2; ++i) { + latin1AndTwoByte(); +} + +// Test bi-morphic loads. +function stringAndArray() { + var xs = [["\u0100"], "\u0100"]; + for (var i = 0; i < 200; ++i) { + var x = xs[i & 1]; + var s = x[0]; + assertEq(s.length, 1); + assertEq(s, "\u0100"); + } +} + +for (var i = 0; i < 2; ++i) { + stringAndArray(); +} + +function outOfBoundsFailureThenException() { + var name = "Object"; + + var j = 0; + while (true) { + // Access out-of-bounds character and then trigger an exception, + // when accessing a property on the undefined value. + name[j++].does_not_exist; + } +} + +for (var i = 0; i < 2; ++i) { + try { + outOfBoundsFailureThenException(); + } catch {} +} diff --git a/js/src/jit-test/tests/cacheir/string-toString-valueOf.js b/js/src/jit-test/tests/cacheir/string-toString-valueOf.js new file mode 100644 index 0000000000..af50c50256 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/string-toString-valueOf.js @@ -0,0 +1,23 @@ +function simple(str) { + assertEq(str.toString(), "abc"); + assertEq(str.valueOf(), "abc"); +} + +function obj(str) { + var obj = new String(str); + assertEq(obj.toString(), "xyz"); + assertEq(obj.valueOf(), "xyz"); +} + +function mixed() { + for (var v of ["abc", new String("abc")]) { + assertEq(v.toString(), "abc"); + assertEq(v.valueOf(), "abc"); + } +} + +for (var i = 0; i < 100; i++) { + simple("abc"); + obj("xyz"); + mixed(); +} \ No newline at end of file diff --git a/js/src/jit-test/tests/cacheir/typed-array-intrinsics.js b/js/src/jit-test/tests/cacheir/typed-array-intrinsics.js new file mode 100644 index 0000000000..0b1ee76f3b --- /dev/null +++ b/js/src/jit-test/tests/cacheir/typed-array-intrinsics.js @@ -0,0 +1,93 @@ +var ab = new ArrayBuffer(128); +var uint8c = new Uint8ClampedArray(ab, 3); +var int16 = new Int16Array(ab, 2); +var int32 = new Int32Array(ab, 4); +var float32 = new Float32Array(ab, 0); +var float64 = new Float64Array(ab, 64); +var bigInt64 = new BigInt64Array(ab, 32); + +var uint8cProxy = new Proxy(uint8c, {}); +var g = newGlobal({newCompartment: true}); +var uint8cWrapped = g.evaluate("new Uint8ClampedArray(10)"); + +var TypedArrayElementShift = getSelfHostedValue("TypedArrayElementShift"); +var TypedArrayByteOffset = getSelfHostedValue("TypedArrayByteOffset"); +var IsTypedArray = getSelfHostedValue("IsTypedArray"); +var IsPossiblyWrappedTypedArray = getSelfHostedValue("IsPossiblyWrappedTypedArray"); +var TypedArrayLength = getSelfHostedValue("TypedArrayLength"); + +function testElementShift() { + function getShift(ta) { + return TypedArrayElementShift(ta); + } + assertEq(getShift(uint8c), 0); + assertEq(getShift(int16), 1); + assertEq(getShift(int32), 2); + assertEq(getShift(float32), 2); + assertEq(getShift(float64), 3); + assertEq(getShift(bigInt64), 3); +} + +function testByteOffset() { + function getOffset(ta) { + return TypedArrayByteOffset(ta); + } + assertEq(getOffset(uint8c), 3); + assertEq(getOffset(int16), 2); + assertEq(getOffset(int32), 4); + assertEq(getOffset(float32), 0); + assertEq(getOffset(float64), 64); + assertEq(getOffset(bigInt64), 32); +} + +function testIsTypedArray() { + function isTA(obj) { + return IsTypedArray(obj); + } + assertEq(isTA(uint8c), true); + assertEq(isTA(int16), true); + assertEq(isTA(int32), true); + assertEq(isTA(float32), true); + assertEq(isTA(float64), true); + assertEq(isTA(bigInt64), true); + assertEq(isTA(Math), false); + assertEq(isTA(ab), false); + assertEq(isTA(uint8cProxy), false); + assertEq(isTA(uint8cWrapped), false); +} + +function testIsPossiblyWrappedTypedArray() { + function isTA(obj) { + return IsPossiblyWrappedTypedArray(obj); + } + assertEq(isTA(uint8c), true); + assertEq(isTA(int16), true); + assertEq(isTA(int32), true); + assertEq(isTA(float32), true); + assertEq(isTA(float64), true); + assertEq(isTA(bigInt64), true); + assertEq(isTA(Math), false); + assertEq(isTA(ab), false); + assertEq(isTA(uint8cProxy), false); + assertEq(isTA(uint8cWrapped), true); +} + +function testTypedArrayLength() { + function getLength(obj) { + return TypedArrayLength(obj); + } + assertEq(getLength(uint8c), 125); + assertEq(getLength(int16), 63); + assertEq(getLength(int32), 31); + assertEq(getLength(float32), 32); + assertEq(getLength(float64), 8); + assertEq(getLength(bigInt64), 12); +} + +for (var i = 0; i < 40; i++) { + testElementShift(); + testByteOffset(); + testIsTypedArray(); + testIsPossiblyWrappedTypedArray(); + testTypedArrayLength(); +} diff --git a/js/src/jit-test/tests/cacheir/typedarray-constructor-objects.js b/js/src/jit-test/tests/cacheir/typedarray-constructor-objects.js new file mode 100644 index 0000000000..5733bc4c29 --- /dev/null +++ b/js/src/jit-test/tests/cacheir/typedarray-constructor-objects.js @@ -0,0 +1,60 @@ +function testArrayBufferThenOther() { + var buf = new ArrayBuffer(4); + var other = [1, 2]; + for (var i = 0; i < 150; i++) { + var arg = i < 100 ? buf : other; + var ta = new Int32Array(arg); + assertEq(ta.length, arg === buf ? 1 : 2); + } +} +testArrayBufferThenOther(); + +function testSharedArrayBufferThenOther() { + if (!this.SharedArrayBuffer) { + return; + } + var buf = new SharedArrayBuffer(4); + var other = [1, 2]; + for (var i = 0; i < 150; i++) { + var arg = i < 100 ? buf : other; + var ta = new Int32Array(arg); + assertEq(ta.length, arg === buf ? 1 : 2); + } +} +testSharedArrayBufferThenOther(); + +function testArrayThenArrayBuffer() { + var arr = [1, 2, 3]; + var buf = new ArrayBuffer(5); + for (var i = 0; i < 150; i++) { + var arg = i < 100 ? arr : buf; + var ta = new Int8Array(arg); + assertEq(ta.length, arg === arr ? 3 : 5); + } +} +testArrayThenArrayBuffer(); + +function testArrayThenSharedArrayBuffer() { + if (!this.SharedArrayBuffer) { + return; + } + var arr = [1, 2, 3]; + var buf = new SharedArrayBuffer(5); + for (var i = 0; i < 150; i++) { + var arg = i < 100 ? arr : buf; + var ta = new Int8Array(arg); + assertEq(ta.length, arg === arr ? 3 : 5); + } +} +testArrayThenSharedArrayBuffer(); + +function testArrayThenWrapper() { + var arr = [1, 2, 3]; + var wrapper = newGlobal({newCompartment: true}).evaluate("[1, 2]"); + for (var i = 0; i < 150; i++) { + var arg = i < 100 ? arr : wrapper; + var ta = new Int8Array(arg); + assertEq(ta.length, arg === arr ? 3 : 2); + } +} +testArrayThenWrapper(); diff --git a/js/src/jit-test/tests/cacheir/unaryarith.js b/js/src/jit-test/tests/cacheir/unaryarith.js index 6cd242f074..39dda5b0ee 100644 --- a/js/src/jit-test/tests/cacheir/unaryarith.js +++ b/js/src/jit-test/tests/cacheir/unaryarith.js @@ -16,9 +16,11 @@ function warmup(fun, input_array, output_array) { var fun_neg_int32_double = (x) => { return -x; } var fun_neg_double_int32 = (x) => { return -x; } -// Unary ~ operator using either int32 or double. +// Unary ~ operator using either int32, double, null, or undefined. var fun_bitnot_int32 = (x) => { return ~x; } var fun_bitnot_double = (x) => { return ~x; } +var fun_bitnot_null = (x) => { return ~x; } +var fun_bitnot_undefined = (x) => { return ~x; } // Unary ++ operator using either int32 or double. var fun_inc_int32 = (x) => { return ++x; } @@ -44,6 +46,8 @@ warmup(fun_neg_int32_double, [1.2, 1.4], [-1.2, -1.4]); warmup(fun_bitnot_int32, [-1, 0], [0, -1]); warmup(fun_bitnot_double, [-1.0, 0.0, 1.2, 3], [0, -1, -2, -4]); +warmup(fun_bitnot_null, [null], [-1]); +warmup(fun_bitnot_undefined, [void 0], [-1]); warmup(fun_inc_int32, [-1, 0], [0, 1]); warmup(fun_inc_double, [-1.0, 0.0, 1.2, 3], [0, 1, 2.2, 4]); diff --git a/js/src/jit-test/tests/coverage/off-thread-01.js b/js/src/jit-test/tests/coverage/off-thread-01.js new file mode 100644 index 0000000000..0175297a2e --- /dev/null +++ b/js/src/jit-test/tests/coverage/off-thread-01.js @@ -0,0 +1,22 @@ +// |jit-test| --code-coverage; --no-ion; skip-if: helperThreadCount() === 0 + +assertEq(isLcovEnabled(), true); + +offThreadCompileScript(` + let hitCount = 0; + function offThreadFun() { + hitCount += 1; + } + + offThreadFun(); + offThreadFun(); + offThreadFun(); + offThreadFun(); +`); +runOffThreadScript(); +assertEq(hitCount, 4); + +let report = getLcovInfo(); + +const expected = "FNDA:4,offThreadFun"; +assertEq(report.includes(expected), true); diff --git a/js/src/jit-test/tests/coverage/off-thread-02.js b/js/src/jit-test/tests/coverage/off-thread-02.js new file mode 100644 index 0000000000..12f925903d --- /dev/null +++ b/js/src/jit-test/tests/coverage/off-thread-02.js @@ -0,0 +1,24 @@ +// |jit-test| --code-coverage; --no-ion; skip-if: helperThreadCount() === 0 + +assertEq(isLcovEnabled(), true); + +offThreadCompileModule(` + globalThis.hitCount = 0; + function offThreadFun() { + globalThis.hitCount += 1; + } + + offThreadFun(); + offThreadFun(); + offThreadFun(); + offThreadFun(); +`); +let mod = finishOffThreadModule(); +mod.declarationInstantiation(); +mod.evaluation(); +assertEq(hitCount, 4); + +const expected = "FNDA:4,offThreadFun"; + +let report = getLcovInfo(); +assertEq(report.includes(expected), true); diff --git a/js/src/jit-test/tests/ctypes/typedarrays.js b/js/src/jit-test/tests/ctypes/typedarrays.js new file mode 100644 index 0000000000..aef7b3622c --- /dev/null +++ b/js/src/jit-test/tests/ctypes/typedarrays.js @@ -0,0 +1,99 @@ +load(libdir + 'asserts.js'); + +function typedArrayMatchesString(ta, str, uptoStringLength = false) { + if (ta.length != str.length && !uptoStringLength) + return false; + for (let i = 0; i < str.length; i++) { + if (ta[i] != str.charCodeAt(i)) + return false; + } + return true; +} + +function test() { + + // Check that {signed,unsigned} -> {Int*Array, Uint*Array} for string types. + + const shortU8 = ctypes.unsigned_char.array(10)("abc\0\0\0\0\0\0\0").readTypedArray(); + assertEq(shortU8 instanceof Uint8Array, true); + assertEq(typedArrayMatchesString(shortU8, "abc\0\0\0\0\0\0\0"), true); + + const shortI8 = ctypes.signed_char.array(10)("abc\0\0\0\0\0\0\0").readTypedArray(); + assertEq(shortI8 instanceof Int8Array, true); + assertEq(typedArrayMatchesString(shortI8, "abc\0\0\0\0\0\0\0"), true); + + const shortU16 = ctypes.char16_t.array(10)("千").readTypedArray(); + assertEq(shortU16 instanceof Uint16Array, true); + assertEq(typedArrayMatchesString(shortU16, "千", 'ignore zero-padding, please'), true); + + // ...and for (other) numeric types. + + const I16 = ctypes.int16_t.array(10)().readTypedArray(); + assertEq(I16 instanceof Int16Array, true); + + const U32 = ctypes.uint32_t.array(10)().readTypedArray(); + assertEq(U32 instanceof Uint32Array, true); + + const I32 = ctypes.int32_t.array(10)().readTypedArray(); + assertEq(I32 instanceof Int32Array, true); + + // Check that pointers without associated length get truncated to strlen(). + + const shortU8cs = ctypes.unsigned_char.array(10)("abc\0\0\0").addressOfElement(0).readTypedArray(); + assertEq(shortU8cs instanceof Uint8Array, true); + assertEq(shortU8cs.length, 3); + assertEq(typedArrayMatchesString(shortU8cs, "abc", 'stop at NUL, please'), true); + + const shortI8cs = ctypes.signed_char.array(10)("abc\0\0\0").addressOfElement(0).readTypedArray(); + assertEq(shortI8cs instanceof Int8Array, true); + assertEq(shortI8cs.length, 3); + assertEq(typedArrayMatchesString(shortI8cs, "abc", 'stop at NUL, please'), true); + + const shortU16cs = ctypes.char16_t.array(10)("千\0").addressOfElement(0).readTypedArray(); + assertEq(shortU16cs instanceof Uint16Array, true); + assertEq(shortU16cs.length, 1); + assertEq(typedArrayMatchesString(shortU16cs, "千", 'ignore zero-padding, please'), true); + + // Other types should just fail if the length is not known. + + assertTypeErrorMessage(() => { ctypes.int32_t.array(3)().addressOfElement(0).readTypedArray(); }, + /base type .* is not an 8-bit or 16-bit integer or character type/); + assertTypeErrorMessage(() => { ctypes.float.array(3)().addressOfElement(0).readTypedArray(); }, + /base type .* is not an 8-bit or 16-bit integer or character type/); + assertTypeErrorMessage(() => { ctypes.double.array(3)().addressOfElement(0).readTypedArray(); }, + /base type .* is not an 8-bit or 16-bit integer or character type/); + // char16_t is unsigned, so this is not a string type. + assertTypeErrorMessage(() => { ctypes.int16_t.array(3)().addressOfElement(0).readTypedArray(); }, + /base type .* is not an 8-bit or 16-bit integer or character type/); + + // Wide string -> bytes -> UTF-8 encoded string in typed array + + const input2 = "千千千千千千千千千千千千千千千千千千千千千千千千千"; + const encoded = ctypes.char.array(input2.length * 3)(input2).readTypedArray(); + // Each 千 character is encoded as 3 bytes. + assertEq(encoded.length, input2.length * 3); + + // Wide string -> char16_t -> 16-bit encoded string in typed array + + const encoded16 = ctypes.char16_t.array(input2.length)(input2).readTypedArray(); + assertEq(encoded16.length, input2.length); + + // Floats + + const floats = ctypes.float.array(3)([10, 20, 30]).readTypedArray(); + assertEq(floats instanceof Float32Array, true); + assertEq(floats.toString(), "10,20,30"); + + const doubles = ctypes.double.array(3)([10, 20, 30]).readTypedArray(); + assertEq(doubles instanceof Float64Array, true); + assertEq(doubles.toString(), "10,20,30"); + + // Invalid + + assertTypeErrorMessage(() => { ctypes.int64_t.array(3)([10, 20, 30]).readTypedArray() }, + /base type ctypes.int64_t.array.*is not compatible with a typed array element type/); + +} + +if (typeof ctypes === "object") + test(); diff --git a/js/src/jit-test/tests/debug/Debugger-clearAllBreakpoints-02.js b/js/src/jit-test/tests/debug/Debugger-clearAllBreakpoints-02.js new file mode 100644 index 0000000000..c201f90d02 --- /dev/null +++ b/js/src/jit-test/tests/debug/Debugger-clearAllBreakpoints-02.js @@ -0,0 +1,31 @@ +// |jit-test| skip-if: !wasmDebuggingIsSupported() +// clearAllBreakpoints should clear breakpoints for WASM scripts. + +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); + +g.eval(` + var wasm = wasmTextToBinary( + '(module (func (nop) (nop)) (export "test" (func 0)))'); + var m = new WebAssembly.Instance(new WebAssembly.Module(wasm)); + var offsets = wasmCodeOffsets(wasm); +`); +var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0]; + +let count = 0; +wasmScript.setBreakpoint(g.offsets[0], { + hit: () => { + count++; + }, +}); + +g.m.exports.test(); +assertEq(count, 1); + +g.m.exports.test(); +assertEq(count, 2); + +dbg.clearAllBreakpoints(); + +g.m.exports.test(); +assertEq(count, 2); diff --git a/js/src/jit-test/tests/debug/Debugger-findScripts-09.js b/js/src/jit-test/tests/debug/Debugger-findScripts-09.js index 468f332055..b485415e9f 100644 --- a/js/src/jit-test/tests/debug/Debugger-findScripts-09.js +++ b/js/src/jit-test/tests/debug/Debugger-findScripts-09.js @@ -19,7 +19,7 @@ assertThrowsInstanceOf(function () { dbg.findScripts({url:4}); }, TypeError); assertThrowsInstanceOf(function () { dbg.findScripts({url:{}}); }, TypeError); assertEq(dbg.findScripts({url:"", line:1}).length, 0); -assertEq(dbg.findScripts({url:"", line:Math.sqrt(4)}).length, 0); +assertEq(dbg.findScripts({url:"", line:numberToDouble(2)}).length, 0); // A 'line' property without a 'url' property is verboten. assertThrowsInstanceOf(function () { dbg.findScripts({line:1}); }, TypeError); diff --git a/js/src/jit-test/tests/debug/Environment-calleeScript-01.js b/js/src/jit-test/tests/debug/Environment-calleeScript-01.js new file mode 100644 index 0000000000..a5417b9070 --- /dev/null +++ b/js/src/jit-test/tests/debug/Environment-calleeScript-01.js @@ -0,0 +1,48 @@ +// Debugger.Environment.prototype.calleeScript reveals the script of function +// environments. + +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); + +function check(code, expectedType, expectedCallee) { + print("check(" + JSON.stringify(code) + ")"); + var hits; + dbg.onDebuggerStatement = function (frame) { + hits++; + var env = frame.environment; + assertEq(env.type, expectedType); + assertEq(env.calleeScript, expectedCallee ? expectedCallee.script : null); + }; + hits = 0; + g.eval(code); + assertEq(hits, 1); +} + +check('debugger;', 'declarative', null); +check('with({}) { debugger; };', 'with', null); +check('{ let x=1; debugger; };', 'declarative', null); + +g.eval('function f() { debugger; }'); +check('f()', 'declarative', gw.makeDebuggeeValue(g.f)); + +g.eval('function g() { h(); }'); +g.eval('function h() { debugger; }'); +check('g()', 'declarative', gw.makeDebuggeeValue(g.h)); + +// All evals get a lexical scope. +check('"use strict"; eval("debugger");', 'declarative', null); +g.eval('function j() { "use strict"; eval("debugger;"); }'); +check('j()', 'declarative', null); + +// All evals get a lexical scope. +check('eval("debugger");', 'declarative', null); + +g.eval('function* m() { debugger; yield true; }'); +check('m().next();', 'declarative', gw.makeDebuggeeValue(g.m)); + +g.eval('function n() { { let x = 1; debugger; } }'); +check('n()', 'declarative', null); + +g.eval('function* o() { debugger; yield true; }'); +check('o().next();', 'declarative', gw.makeDebuggeeValue(g.o)); diff --git a/js/src/jit-test/tests/debug/Environment-calleeScript-02.js b/js/src/jit-test/tests/debug/Environment-calleeScript-02.js new file mode 100644 index 0000000000..d518c4b8a0 --- /dev/null +++ b/js/src/jit-test/tests/debug/Environment-calleeScript-02.js @@ -0,0 +1,25 @@ +// Debugger.Environment.prototype.calleeScript gets the right script. + +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); + +g.eval('function f(x) { return function (y) { eval(""); debugger; return x + y; } }'); +g.eval('var g = f(2);'); +g.eval('var h = f(3);'); + +function check(fun, label) { + print("check(" + label + ")"); + var hits; + dbg.onDebuggerStatement = function (frame) { + hits++; + var env = frame.environment; + assertEq(env.calleeScript, gw.makeDebuggeeValue(fun).script); + }; + hits = 0; + fun(); + assertEq(hits, 1); +} + +check(g.g, 'g.g'); +check(g.h, 'g.h'); diff --git a/js/src/jit-test/tests/debug/Environment-calleeScript-03.js b/js/src/jit-test/tests/debug/Environment-calleeScript-03.js new file mode 100644 index 0000000000..f21522b4cc --- /dev/null +++ b/js/src/jit-test/tests/debug/Environment-calleeScript-03.js @@ -0,0 +1,25 @@ +// Environments of different instances of the same generator have the same +// calleeScript. + +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger; +var gw = dbg.addDebuggee(g); + +function check(gen, label) { + print("check(" + label + ")"); + var hits; + dbg.onDebuggerStatement = function (frame) { + hits++; + var env = frame.environment; + assertEq(env.calleeScript, gw.makeDebuggeeValue(g.f).script); + }; + hits = 0; + gen.next(); + assertEq(hits, 1); +} + +g.eval('function* f(x) { debugger; yield x; }'); +g.eval('var g = f(2);'); +g.eval('var h = f(3);'); +check(g.g, 'g.g'); +check(g.h, 'g.h'); diff --git a/js/src/jit-test/tests/debug/Environment-getVariable-02.js b/js/src/jit-test/tests/debug/Environment-getVariable-02.js index 30623668cb..9d76a03957 100644 --- a/js/src/jit-test/tests/debug/Environment-getVariable-02.js +++ b/js/src/jit-test/tests/debug/Environment-getVariable-02.js @@ -9,10 +9,10 @@ dbg.onDebuggerStatement = function (frame) { assertEq(varEnv.getVariable("a"), 1); assertEq(varEnv.getVariable("b"), 2); assertEq(varEnv.getVariable("c"), 3); - assertEq(varEnv.getVariable("d"), 4); - assertEq(lexicalEnv.getVariable("e"), 5); + assertEq(varEnv.getVariable("d"), 7); + assertEq(lexicalEnv.getVariable("e"), 8); hits++; }; -g.eval("function f(a, [b, c]) { var d = c + 1; let e = d + 1; debugger; }"); +g.eval("function f(a, [b, c]) { var d = a + b + c + 1; let e = d + 1; debugger; }"); g.f(1, [2, 3]); assertEq(hits, 1); diff --git a/js/src/jit-test/tests/debug/Environment-getVariable-13.js b/js/src/jit-test/tests/debug/Environment-getVariable-13.js index 4d0569908a..43e69ea8e0 100644 --- a/js/src/jit-test/tests/debug/Environment-getVariable-13.js +++ b/js/src/jit-test/tests/debug/Environment-getVariable-13.js @@ -32,7 +32,7 @@ withJitOptions(Opts_Ion2NoOffthreadCompilation, function () { g.eval("" + function f(d, x) { g(d, x); }); g.eval("" + function g(d, x) { - for (var i = 0; i < 200; i++); + for (var i = 0; i < 100; i++); function inner() { i = 42; }; toggle(d); // Use x so it doesn't get optimized out. @@ -40,7 +40,7 @@ withJitOptions(Opts_Ion2NoOffthreadCompilation, function () { }); g.eval("(" + function test() { - for (i = 0; i < 5; i++) + for (i = 0; i < 15; i++) f(false, 42); f(true, 42); } + ")();"); diff --git a/js/src/jit-test/tests/debug/Frame-eval-24.js b/js/src/jit-test/tests/debug/Frame-eval-24.js index 6074042b53..e3a9096d10 100644 --- a/js/src/jit-test/tests/debug/Frame-eval-24.js +++ b/js/src/jit-test/tests/debug/Frame-eval-24.js @@ -1,16 +1,17 @@ // Make sure the getVariable/setVariable/eval functions work correctly with // unaliased locals. var g = newGlobal({newCompartment: true}); -g.eval('\ -function g() { debugger; };\ -function f(arg) {\ - var y = arg - 3;\ - var a1 = 1;\ - var a2 = 1;\ - var b = arg + 9;\ - var z = function() { return a1 + a2; };\ - g();\ -};'); +g.eval(` +function g() { debugger; }; +function f(arg) { + var y = arg - 3; + var a1 = 1; + var a2 = 1; + var b = arg + 9; + var z = function() { return a1 + a2; }; + g(); + return y * b; // To prevent the JIT from optimizing out y and b. +};`); var dbg = new Debugger(g); diff --git a/js/src/jit-test/tests/debug/Frame-eval-33.js b/js/src/jit-test/tests/debug/Frame-eval-33.js index dd4e5d2174..d5d3f94804 100644 --- a/js/src/jit-test/tests/debug/Frame-eval-33.js +++ b/js/src/jit-test/tests/debug/Frame-eval-33.js @@ -21,6 +21,7 @@ evalInFrame(0, "globalFun(true, expectedGlobalFunThis)"); } var expectedInnerFunThis = innerFun(false); evalInFrame(0, "innerFun(true, expectedInnerFunThis)"); + return [innerFun, expectedInnerFunThis]; // To prevent the JIT from optimizing out vars. })(); (function testWith() { diff --git a/js/src/jit-test/tests/debug/Frame-onPop-generators-08.js b/js/src/jit-test/tests/debug/Frame-onPop-generators-08.js new file mode 100644 index 0000000000..a76576d5ea --- /dev/null +++ b/js/src/jit-test/tests/debug/Frame-onPop-generators-08.js @@ -0,0 +1,15 @@ +// Creating a new generator frame after the generator is closed. + +var g = newGlobal({ newCompartment: true }); +g.eval("function* gen(x) { debugger; }"); +var dbg = new Debugger(g); +dbg.onDebuggerStatement = frame => { + frame.onPop = completion => { + assertEq(frame.callee.name, "gen"); + assertEq(frame.eval("x").return, 3); + var f2 = (new Debugger(g)).getNewestFrame(); + assertEq(f2.callee.name, "gen"); + assertEq(f2.eval("x").return, 3); + }; +}; +g.gen(3).next(); diff --git a/js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js b/js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js index 79be436f71..8b7599c73d 100644 --- a/js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js +++ b/js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js @@ -7,7 +7,7 @@ dbg.memory.trackingAllocationSites = true; root.eval("(" + function immediate() { this.tests = [ - ({}), + {x: 1}, [], /(two|2)\s*problems/, new function Ctor(){}, diff --git a/js/src/jit-test/tests/debug/Memory-takeCensus-04.js b/js/src/jit-test/tests/debug/Memory-takeCensus-04.js index d516c646d6..33fbeaa163 100644 --- a/js/src/jit-test/tests/debug/Memory-takeCensus-04.js +++ b/js/src/jit-test/tests/debug/Memory-takeCensus-04.js @@ -9,6 +9,7 @@ g.eval(` (function () { var onStack = allocationMarker(); f(); + return onStack; // To prevent the JIT from optimizing out onStack. }()) } `); diff --git a/js/src/jit-test/tests/debug/Memory-takeCensus-11.js b/js/src/jit-test/tests/debug/Memory-takeCensus-11.js index 15ca314076..51423dce5c 100644 --- a/js/src/jit-test/tests/debug/Memory-takeCensus-11.js +++ b/js/src/jit-test/tests/debug/Memory-takeCensus-11.js @@ -1,3 +1,8 @@ +// |jit-test| skip-if: isLcovEnabled() + +// NOTE: Code coverage keeps top-level script alive even if normally it would be +// GC'd. Skip this test in that case. + // Check byte counts produced by takeCensus. const g = newGlobal({newCompartment: true}); diff --git a/js/src/jit-test/tests/debug/Object-defineProperty-non-primitive-key.js b/js/src/jit-test/tests/debug/Object-defineProperty-non-primitive-key.js new file mode 100644 index 0000000000..c3c503968f --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-defineProperty-non-primitive-key.js @@ -0,0 +1,41 @@ +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); +var gw = dbg.addDebuggee(g); + +g.eval(` + var obj = { + p: 0, + [Symbol.iterator]: 0, + }; +`); + +// Return |key| as an object. +function toObject(key) { + return { + [Symbol.toPrimitive]() { + return key; + } + }; +} + +let obj = gw.getProperty("obj").return; + +for (let key of obj.getOwnPropertyNames()) { + let keyObject = toObject(key); + + obj.defineProperty(key, {value: 1}); + assertEq(g.obj[key], 1); + + obj.defineProperty(keyObject, {value: 1}); + assertEq(g.obj[key], 1); +} + +for (let key of obj.getOwnPropertySymbols()) { + let keyObject = toObject(key); + + obj.defineProperty(key, {value: 1}); + assertEq(g.obj[key], 1); + + obj.defineProperty(keyObject, {value: 1}); + assertEq(g.obj[key], 1); +} diff --git a/js/src/jit-test/tests/debug/Object-deleteProperty-non-primitive-key.js b/js/src/jit-test/tests/debug/Object-deleteProperty-non-primitive-key.js new file mode 100644 index 0000000000..83a10b89eb --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-deleteProperty-non-primitive-key.js @@ -0,0 +1,49 @@ +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); +var gw = dbg.addDebuggee(g); + +g.eval(` + var obj = { + p: 0, + [Symbol.iterator]: 0, + }; +`); + +// Return |key| as an object. +function toObject(key) { + return { + [Symbol.toPrimitive]() { + return key; + } + }; +} + +let obj = gw.getProperty("obj").return; + +for (let key of obj.getOwnPropertyNames()) { + let keyObject = toObject(key); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.deleteProperty(key), true); + assertEq(g.obj[key], undefined); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.deleteProperty(keyObject), true); + assertEq(g.obj[key], undefined); +} + +for (let key of obj.getOwnPropertySymbols()) { + let keyObject = toObject(key); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.deleteProperty(key), true); + assertEq(g.obj[key], undefined); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.deleteProperty(keyObject), true); + assertEq(g.obj[key], undefined); +} diff --git a/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js b/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js index 4b558fb30f..7550d15ef0 100644 --- a/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js +++ b/js/src/jit-test/tests/debug/Object-forceLexicalInitializationByName.js @@ -18,7 +18,7 @@ function evalErrorStr(global, evalString) { assertEq(evalErrorStr(g, "let y = IDONTEXIST;"), "ReferenceError: IDONTEXIST is not defined"); assertEq(evalErrorStr(g, "y = 1;"), - "ReferenceError: can't access lexical declaration `y' before initialization"); + "ReferenceError: can't access lexical declaration 'y' before initialization"); // Here we flip the uninitialized binding to undfined. assertEq(gw.forceLexicalInitializationByName("y"), true); diff --git a/js/src/jit-test/tests/debug/Object-getOwnPropertyDescriptor-non-primitive-key.js b/js/src/jit-test/tests/debug/Object-getOwnPropertyDescriptor-non-primitive-key.js new file mode 100644 index 0000000000..71b177aa63 --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-getOwnPropertyDescriptor-non-primitive-key.js @@ -0,0 +1,37 @@ +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); +var gw = dbg.addDebuggee(g); + +g.eval(` + var obj = { + p: 1, + [Symbol.iterator]: 2, + }; +`); + +// Return |key| as an object. +function toObject(key) { + return { + [Symbol.toPrimitive]() { + return key; + } + }; +} + +let obj = gw.getProperty("obj").return; + +for (let key of obj.getOwnPropertyNames()) { + let keyObject = toObject(key); + let value = g.obj[key]; + + assertEq(obj.getOwnPropertyDescriptor(key).value, value); + assertEq(obj.getOwnPropertyDescriptor(keyObject).value, value); +} + +for (let key of obj.getOwnPropertySymbols()) { + let keyObject = toObject(key); + let value = g.obj[key]; + + assertEq(obj.getOwnPropertyDescriptor(key).value, value); + assertEq(obj.getOwnPropertyDescriptor(keyObject).value, value); +} diff --git a/js/src/jit-test/tests/debug/Object-getProperty-non-primitive-key.js b/js/src/jit-test/tests/debug/Object-getProperty-non-primitive-key.js new file mode 100644 index 0000000000..649764322e --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-getProperty-non-primitive-key.js @@ -0,0 +1,37 @@ +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); +var gw = dbg.addDebuggee(g); + +g.eval(` + var obj = { + p: 1, + [Symbol.iterator]: 2, + }; +`); + +// Return |key| as an object. +function toObject(key) { + return { + [Symbol.toPrimitive]() { + return key; + } + }; +} + +let obj = gw.getProperty("obj").return; + +for (let key of obj.getOwnPropertyNames()) { + let keyObject = toObject(key); + let value = g.obj[key]; + + assertEq(obj.getProperty(key).return, value); + assertEq(obj.getProperty(keyObject).return, value); +} + +for (let key of obj.getOwnPropertySymbols()) { + let keyObject = toObject(key); + let value = g.obj[key]; + + assertEq(obj.getProperty(key).return, value); + assertEq(obj.getProperty(keyObject).return, value); +} diff --git a/js/src/jit-test/tests/debug/Object-setProperty-non-primitive-key.js b/js/src/jit-test/tests/debug/Object-setProperty-non-primitive-key.js new file mode 100644 index 0000000000..e6aaa138a4 --- /dev/null +++ b/js/src/jit-test/tests/debug/Object-setProperty-non-primitive-key.js @@ -0,0 +1,49 @@ +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger(g); +var gw = dbg.addDebuggee(g); + +g.eval(` + var obj = { + p: 0, + [Symbol.iterator]: 0, + }; +`); + +// Return |key| as an object. +function toObject(key) { + return { + [Symbol.toPrimitive]() { + return key; + } + }; +} + +let obj = gw.getProperty("obj").return; + +for (let key of obj.getOwnPropertyNames()) { + let keyObject = toObject(key); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.setProperty(key, 2).return, true); + assertEq(g.obj[key], 2); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.setProperty(keyObject, 2).return, true); + assertEq(g.obj[key], 2); +} + +for (let key of obj.getOwnPropertySymbols()) { + let keyObject = toObject(key); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.setProperty(key, 2).return, true); + assertEq(g.obj[key], 2); + + g.obj[key] = 1; + assertEq(g.obj[key], 1); + assertEq(obj.setProperty(keyObject, 2).return, true); + assertEq(g.obj[key], 2); +} diff --git a/js/src/jit-test/tests/debug/Script-parameterNames.js b/js/src/jit-test/tests/debug/Script-parameterNames.js new file mode 100644 index 0000000000..1557a97e22 --- /dev/null +++ b/js/src/jit-test/tests/debug/Script-parameterNames.js @@ -0,0 +1,36 @@ +load(libdir + "asserts.js"); + +var g = newGlobal({newCompartment: true}); +var dbg = new Debugger; +var gDO = dbg.addDebuggee(g); + +function check(expr, expected) { + let completion = gDO.executeInGlobal(expr); + if (completion.throw) + throw completion.throw.unsafeDereference(); + + let fn = completion.return; + if (expected === undefined) + assertEq(fn.script.parameterNames, undefined); + else + assertDeepEq(fn.script.parameterNames, expected); +} + +check('(function () {})', []); +check('(function (x) {})', ["x"]); +check('(function (x = 1) {})', ["x"]); +check('(function (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) {})', + ["a","b","c","d","e","f","g","h","i","j","k","l","m", + "n","o","p","q","r","s","t","u","v","w","x","y","z"]); +check('(function (a, [b, c], {d, e:f}) { })', + ["a", undefined, undefined]); +check('(async function (a, b, c) {})', ["a", "b", "c"]); +check('(async function* (d, e, f) {})', ["d", "e", "f"]); + +// Non-function scripts have |undefined| parameterNames. +var log = []; +dbg.onEnterFrame = function(frame) { + log.push(frame.script.parameterNames); +}; +g.evaluate("function foo(a, b) { return eval('1'); }; foo();"); +assertDeepEq(log, [undefined, ["a", "b"], undefined]); // global, function, eval diff --git a/js/src/jit-test/tests/debug/bug-1444604-reduced.js b/js/src/jit-test/tests/debug/bug-1444604-reduced.js index 6e84fef194..23bf419cdb 100644 --- a/js/src/jit-test/tests/debug/bug-1444604-reduced.js +++ b/js/src/jit-test/tests/debug/bug-1444604-reduced.js @@ -1,3 +1,6 @@ +// |jit-test| --no-warp +// This is hitting bug 1505387 with WarpBuilder and eager compilation. + // LiveSavedFrameCache should not be confused by eval-in-frame-prev links. const g = newGlobal({newCompartment: true}); diff --git a/js/src/jit-test/tests/debug/bug1275001.js b/js/src/jit-test/tests/debug/bug1275001.js index c3666ff9ad..0cfa7a50f8 100644 --- a/js/src/jit-test/tests/debug/bug1275001.js +++ b/js/src/jit-test/tests/debug/bug1275001.js @@ -11,7 +11,7 @@ function check_one(expected, f, err) { f() } catch (ex) { s = ex.message; - assertEq(s.slice(-(err.length + expected.length), -err.length), expected) + assertEq(s.includes("undefined"), true); } } ieval = eval diff --git a/js/src/jit-test/tests/debug/bug1397385.js b/js/src/jit-test/tests/debug/bug1397385.js index 9518bce679..eea2c0c01e 100644 --- a/js/src/jit-test/tests/debug/bug1397385.js +++ b/js/src/jit-test/tests/debug/bug1397385.js @@ -4,6 +4,7 @@ g.evaluate(` function testInnerFun(defaultArg = 1) { function innerFun(expectedThis) { return this; } h(); + return innerFun; // To prevent the JIT from optimizing out innerFun. } `); diff --git a/js/src/jit-test/tests/debug/isError.js b/js/src/jit-test/tests/debug/isError.js new file mode 100644 index 0000000000..253d2c76d4 --- /dev/null +++ b/js/src/jit-test/tests/debug/isError.js @@ -0,0 +1,19 @@ +let g = newGlobal({newCompartment: true}); +let dbg = new Debugger(); +let gw = dbg.addDebuggee(g); + +g.error1 = new Error() +g.error2 = new g.Error() +g.error3 = new g.TypeError(); + +let error1DO = gw.getOwnPropertyDescriptor('error1').value; +let error2DO = gw.getOwnPropertyDescriptor('error2').value; +let error3DO = gw.getOwnPropertyDescriptor('error3').value; + +assertEq(error1DO.isError, true); +assertEq(error2DO.isError, true); +assertEq(error3DO.isError, true); + +g.nonError = new Array(); +let nonErrorDO = gw.getOwnPropertyDescriptor('nonError').value; +assertEq(nonErrorDO.isError, false); diff --git a/js/src/jit-test/tests/debug/optimized-out-01.js b/js/src/jit-test/tests/debug/optimized-out-01.js index df9bfada1c..cb0210dcbf 100644 --- a/js/src/jit-test/tests/debug/optimized-out-01.js +++ b/js/src/jit-test/tests/debug/optimized-out-01.js @@ -35,12 +35,12 @@ withJitOptions(Opts_Ion2NoOffthreadCompilation, function () { g.eval("" + function g(d, x) { "use strict"; - for (var i = 0; i < 200; i++); + for (var i = 0; i < 100; i++); toggle(d); }); g.eval("(" + function test() { - for (i = 0; i < 5; i++) + for (i = 0; i < 15; i++) f(false, 42); f(true, 42); } + ")();"); diff --git a/js/src/jit-test/tests/debug/optimized-out-02.js b/js/src/jit-test/tests/debug/optimized-out-02.js index fefe6b8431..c7690cca7a 100644 --- a/js/src/jit-test/tests/debug/optimized-out-02.js +++ b/js/src/jit-test/tests/debug/optimized-out-02.js @@ -9,7 +9,7 @@ function outer(unaliasedArg) { var aliasedVar = unaliasedArg; inner(); - return; + return unaliasedVar; // To prevent the JIT from optimizing out unaliasedVar. function inner() { aliasedVar++; diff --git a/js/src/jit-test/tests/debug/optimized-out-03.js b/js/src/jit-test/tests/debug/optimized-out-03.js index 663dddaddb..aada963326 100644 --- a/js/src/jit-test/tests/debug/optimized-out-03.js +++ b/js/src/jit-test/tests/debug/optimized-out-03.js @@ -12,20 +12,20 @@ withJitOptions(Opts_IonEagerNoOffthreadCompilation, function() { function f() { assertEq(dbg.getNewestFrame().older.eval("print(a)").throw.unsafeDereference().toString(), - "Error: variable `a' has been optimized out"); + "Error: variable 'a' has been optimized out"); } // Test optimized out binding in function scope. (function () { - function a() {} - for (var i = 0; i < 1; i++) f(); + var a = 1; + for (var i = 0; i < 1; i++) { f(); a = 2; } })(); // Test optimized out binding in block scope. (function () { { - function a() {} - for (var i = 0; i < 1; i++) f(); + let a = 1; + for (var i = 0; i < 1; i++) { f(); a = 2; } } })(); }); diff --git a/js/src/jit-test/tests/debug/optimized-out-arrow-this.js b/js/src/jit-test/tests/debug/optimized-out-arrow-this.js index 2a31e1205d..adc1702fa1 100644 --- a/js/src/jit-test/tests/debug/optimized-out-arrow-this.js +++ b/js/src/jit-test/tests/debug/optimized-out-arrow-this.js @@ -35,4 +35,4 @@ g.f(); assertEq(errors.length, 1); assertEq(errors[0].unsafeDereference().toString(), - "Error: variable `this' has been optimized out"); + "Error: variable 'this' has been optimized out"); diff --git a/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js b/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js new file mode 100644 index 0000000000..a8fd1d9583 --- /dev/null +++ b/js/src/jit-test/tests/debug/private-methods-eval-in-frame.js @@ -0,0 +1,25 @@ +// |jit-test| --enable-private-fields; --enable-private-methods; +load(libdir + 'asserts.js'); +load(libdir + 'evalInFrame.js'); + +class B { + #priv() { + return 12; + } + + #val = ''; + set #x(x) { + this.#val = x + ' haha'; + } + get #x() { + return this.#val; + } + + ef(str) { + return evalInFrame(0, str); + } +} + +var b = new B(); +assertEq(b.ef(`this.#priv();`), 12); +assertEq(b.ef(`this.#x = 'Hi'; this.#x`), 'Hi haha'); diff --git a/js/src/jit-test/tests/debug/wasm-04.js b/js/src/jit-test/tests/debug/wasm-04.js index 40d1216623..bd8ebdcb82 100644 --- a/js/src/jit-test/tests/debug/wasm-04.js +++ b/js/src/jit-test/tests/debug/wasm-04.js @@ -16,6 +16,7 @@ g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(m assertEq(s.format, "wasm"); assertThrowsInstanceOf(() => s.displayName, Error); +assertThrowsInstanceOf(() => s.parameterNames, Error); assertThrowsInstanceOf(() => s.url, Error); assertThrowsInstanceOf(() => s.sourceStart, Error); assertThrowsInstanceOf(() => s.sourceLength, Error); diff --git a/js/src/jit-test/tests/debug/wasm-13.js b/js/src/jit-test/tests/debug/wasm-13.js index 116c358517..6f9ebed8e2 100644 --- a/js/src/jit-test/tests/debug/wasm-13.js +++ b/js/src/jit-test/tests/debug/wasm-13.js @@ -80,7 +80,7 @@ monitorGlobalValues( monitorGlobalValues( `(module\ (global i32 (i32.const 1))(global i64 (i64.const 2))(global f32 (f32.const 3.5))(global f64 (f64.const 42.25))\ - ${wasmReftypesEnabled() ? '(global anyref (ref.null))' : ''}\ + ${wasmReftypesEnabled() ? '(global externref (ref.null extern))' : ''}\ (func (export "test") (nop)))`, undefined, [(function () { @@ -92,11 +92,11 @@ monitorGlobalValues( monitorGlobalValues( `(module (global (mut i32) (i32.const 1))(global (mut i64) (i64.const 2))\ (global (mut f32) (f32.const 3.5))(global (mut f64) (f64.const 42.25))\ - ${wasmReftypesEnabled() ? '(global (mut anyref) (ref.null))' : ''}\ + ${wasmReftypesEnabled() ? '(global (mut externref) (ref.null extern))' : ''}\ (func (export "test")\ (i32.const 2)(global.set 0)(i64.const 1)(global.set 1)\ (f32.const 42.25)(global.set 2)(f64.const 3.5)(global.set 3)\ - ${wasmReftypesEnabled() ? '(ref.null)(global.set 4)' : ''}))`, + ${wasmReftypesEnabled() ? '(ref.null extern)(global.set 4)' : ''}))`, undefined, [(function () { let x = {global0: [1, 2], global1: [2, 1], global2: [3.5, 42.25], global3: [42.25, 3.5]}; diff --git a/js/src/jit-test/tests/fields/bug1664550.js b/js/src/jit-test/tests/fields/bug1664550.js new file mode 100644 index 0000000000..8c6e98b5e0 --- /dev/null +++ b/js/src/jit-test/tests/fields/bug1664550.js @@ -0,0 +1,15 @@ +// |jit-test| --enable-private-methods; + +class OverrideBase { + constructor(o30) { + return o30; + } +}; + +class A3 extends OverrideBase { + get #m() {} +} + +var obj = {}; +Object.seal(obj); +new A3(obj); diff --git a/js/src/jit-test/tests/fields/error.js b/js/src/jit-test/tests/fields/error.js index 18a2ac2b5a..12d392425e 100644 --- a/js/src/jit-test/tests/fields/error.js +++ b/js/src/jit-test/tests/fields/error.js @@ -1,4 +1,4 @@ -load(libdir + "asserts.js"); +load(libdir + 'asserts.js'); let source = `class C { x = @@ -21,15 +21,19 @@ source = `class C { }`; assertErrorMessage(() => Function(source), SyntaxError, /./); -source = `class C { +// The following stop being syntax errors if private fields are +// enabled. +if (!getRealmConfiguration()['privateFields']) { + source = `class C { #x; -}`; -assertErrorMessage(() => Function(source), SyntaxError, /./); + }`; + assertErrorMessage(() => Function(source), SyntaxError, /./); -source = `class C { + source = `class C { #y = 2; -}`; -assertErrorMessage(() => Function(source), SyntaxError, /./); + }`; + assertErrorMessage(() => Function(source), SyntaxError, /./); +} source = `class C { #["h" + "i"]; @@ -69,8 +73,8 @@ class C { assertErrorMessage(() => Function(source), SyntaxError, /./); // TODO -//source = `#outside;`; -//assertErrorMessage(() => eval(source), SyntaxError); +// source = `#outside;`; +// assertErrorMessage(() => eval(source), SyntaxError); source = `class C { x = super(); @@ -124,5 +128,4 @@ assertThrowsInstanceOf(() => Function(source), SyntaxError); source = `class C { x get f() {} }`; assertThrowsInstanceOf(() => Function(source), SyntaxError); -if (typeof reportCompare === "function") - reportCompare(true, true); +if (typeof reportCompare === 'function') reportCompare(true, true); diff --git a/js/src/jit-test/tests/fields/ion-private-idempotent.js b/js/src/jit-test/tests/fields/ion-private-idempotent.js new file mode 100644 index 0000000000..24d7c1793e --- /dev/null +++ b/js/src/jit-test/tests/fields/ion-private-idempotent.js @@ -0,0 +1,33 @@ +// |jit-test| --enable-private-fields; + +var acc = 0; +const loopCount = 100; + +class A { + #x = 1; + static loopRead(o) { + for (var i = 0; i < loopCount; i++) { + // If this getelem were hoisted out of the loop, + // we need the IC that is attached to that to + // correctly throw if .#x is not in o. + var b = o.#x; + acc += 1; + } + } +}; + +// Two non-A objects, because we're concerned not about the first +// attempt to read .#x from a non A, but the second, because if +// we attach the wrong IC, we'll attach an IC that provides +// regular object semantics, which would be to return undefined. +var array = [new A, new A, new A, {}, {}]; +for (var e of array) { + acc = 0; + try { + A.loopRead(e); + assertEq(acc, loopCount); + } catch (e) { + assertEq(e instanceof TypeError, true); + assertEq(acc, 0); + } +} diff --git a/js/src/jit-test/tests/fields/private-error-location.js b/js/src/jit-test/tests/fields/private-error-location.js new file mode 100644 index 0000000000..af90ba4868 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-error-location.js @@ -0,0 +1,9 @@ +// Bug 1770609 - Ensure the line number reported is correctly the source of the +// syntax error, not just the first observation of the name. +try { + eval(`class A { #declared; } + m.#declared;`) +} catch (e) { + assertEq(e instanceof SyntaxError, true) + assertEq(e.lineNumber, 2); +} diff --git a/js/src/jit-test/tests/fields/private-eval-in-frame.js b/js/src/jit-test/tests/fields/private-eval-in-frame.js new file mode 100644 index 0000000000..e9dea6957e --- /dev/null +++ b/js/src/jit-test/tests/fields/private-eval-in-frame.js @@ -0,0 +1,15 @@ +// |jit-test| --enable-private-fields; +load(libdir + 'asserts.js'); +load(libdir + 'evalInFrame.js'); + +class B { + #x = 12; + x = 'his'; + ef(str) { + return evalInFrame(0, str); + } +} + +var b = new B(); +assertEq(b.ef(`this.x`), 'his'); +assertEq(b.ef(`this.#x`), 12); diff --git a/js/src/jit-test/tests/fields/private-field-basics.js b/js/src/jit-test/tests/fields/private-field-basics.js new file mode 100644 index 0000000000..9b1fb2431c --- /dev/null +++ b/js/src/jit-test/tests/fields/private-field-basics.js @@ -0,0 +1,236 @@ +// |jit-test| --enable-private-fields; + + +class A { + #x = 10 + + x() { + return this.#x; + } + ix() { + this.#x++; + } + static readx(o) { + return o.#x; + } + static optionalx(o) { + return o?.#x; + } + + #y = () => 'hi'; + invoke() { + return this.#y(); + } + + static #z = 'static'; + gz() { + return A.#z; + } + + sz(o) { + A.#z = o; + } + + static sgz() { + return this.#z; + } + + static ssz(o) { + this.#z = o; + } + + static six(o) { + o.#x++; + } + + static dix(o) { + o.#x--; + } +}; + +for (var i = 0; i < 1000; i++) { + var a = new A(); + assertEq(a.x(), 10); + a.ix(); + assertEq(a.x(), 11); + assertEq(A.readx(a), 11); + assertEq(a.invoke(), 'hi'); + assertEq(a.gz(), 'static'); + assertEq(A.sgz(), 'static'); + A.ssz(i); + assertEq(A.sgz(), i); + a.sz(i + 1); + assertEq(A.sgz(), i + 1); + A.ssz('static'); // reset for next iteration! + + assertEq(A.optionalx(a), 11); + assertEq(A.optionalx(null), undefined); + try { + A.optionalx({}); // Should throw type error + assertEq(0, 1); + } catch (TypeError) { + } +} + +function assertThrows(fun, errorType) { + try { + fun(); + throw 'Expected error, but none was thrown'; + } catch (e) { + if (!(e instanceof errorType)) { + throw 'Wrong error type thrown'; + } + } +} + +function testTypeErrors(v) { + assertThrows(() => A.readx(v), TypeError); // Read value + assertThrows(() => A.six(v), TypeError); // increment + assertThrows(() => A.dix(v), TypeError); // decrement +} + +testTypeErrors(undefined); // Undefined +testTypeErrors({}); // Random object +testTypeErrors(1); // Random primitive + +assertThrows( + () => eval('class B extends class { #x; } { g() { return super.#x; } }'), + SyntaxError); // Access super.#private +assertThrows( + () => eval('class C { #x = 10; static #x = 14; }'), + SyntaxError); // Duplicate name declaration. +assertThrows( + () => eval('delete this.#x'), + SyntaxError); // deleting a private field in non-strict mode. + +class B extends class { + constructor(o) { + return o; + } +} +{ + #x = 12; + static gx(o) { + return o.#x; + } + static sx(o) { + o.#x++; + } +} + +var bn = new B(1); +var bu = new B(undefined); + +// Test we can read an outer classes private fields. +class Outer { + #outer = 3; + test() { + let outerThis = this; + class Inner { + #inner = 2; + test() { + return outerThis.#outer; + } + } + return new Inner().test(); + } +} + +var o = new Outer; +assertEq(o.test(), 3); + +// IC tests: + +var alreadyConstructedB = new B(); +assertEq(B.gx(alreadyConstructedB), 12); + +function initIC(o) { + new B(o); +} +var array = []; +// warm up init IC +for (var i = 1; i < 1000; i++) { + var newB = {}; + initIC(newB); +} + +// Successfully catch double initialization type error. +assertThrows(() => initIC(alreadyConstructedB), TypeError); +// Do it again, to make sure we didn't attach a stub that is invalid. +assertThrows(() => initIC(alreadyConstructedB), TypeError); + +// Test getters work, and ICs can't be tricked. Setup an array of +// +// [B, B, B, B, ..., {}, {}] +// +// Then test that as we execute the sudden appearance of {} doesn't +// trick our ICs into setting or getting anything -- do it twice +// to make sure that we didn't get a stub that is invalid. +var elements = []; +for (var i = 0; i < 99; i++) { + elements.push(new B); +} +elements.push({}); +elements.push({}); + +function getterCheck(e) { + assertEq(B.gx(e), 12); +} + +function setterCheck(e) { + B.sx(e); +} + +var checksPassed = 0; +try { + for (var e of elements) { + getterCheck(e); + checksPassed++; + } + throw `Shouldn't arrive here`; +} catch (e) { + if (!(e instanceof TypeError)) { + throw e; + } + // All but last element should have done the right thing. + assertEq(checksPassed, elements.length - 2); +} + +checksPassed = 0; +try { + for (var e of elements) { + setterCheck(e); + checksPassed++; + } + throw `Shouldn't arrive here`; +} catch (e) { + if (!(e instanceof TypeError)) { + throw e; + } + // All but last element should have done the right thing. + assertEq(checksPassed, elements.length - 2); +} + +// Verify setter did the thing, but throws in the correct places +for (var index in elements) { + if (index < elements.length - 2) { + assertEq(B.gx(elements[index]), 13); + } else { + assertThrows(() => { + B.gx(elements[index]); + }, TypeError); + } +} + +// Megamorphic Cache Testing: +for (var i = 0; i < 100; i++) { + var inputs = [{a: 1}, {b: 2}, {c: 3}, {d: 4}, {e: 5}, new Proxy({}, {})]; + for (var o of inputs) { + assertThrows(() => B.gx(o), TypeError); + assertThrows(() => B.sx(o), TypeError); + new B(o); + assertEq(B.gx(o), 12); + B.sx(o); + assertEq(B.gx(o), 13); + } +} diff --git a/js/src/jit-test/tests/fields/private-field-destructuring.js b/js/src/jit-test/tests/fields/private-field-destructuring.js new file mode 100644 index 0000000000..6f1aeacf94 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-field-destructuring.js @@ -0,0 +1,43 @@ +// |jit-test| --enable-private-fields; + +function assertThrows(fun, errorType) { + try { + fun(); + throw 'Expected error, but none was thrown'; + } catch (e) { + if (!(e instanceof errorType)) { + throw 'Wrong error type thrown'; + } + } +} + +class A { + #a; + #b; + #c; + #d; + #e; + static destructure(o, x) { + [o.#a, o.#b, o.#c, o.#d, ...o.#e] = x; + } + + static get(o) { + return {a: o.#a, b: o.#b, c: o.#c, d: o.#d, e: o.#e}; + } +}; + +for (var i = 0; i < 1000; i++) { + var a = new A(); + A.destructure(a, [1, 2, 3, 4, 5]); + var res = A.get(a); + assertEq(res.a, 1); + assertEq(res.b, 2); + assertEq(res.c, 3); + assertEq(res.d, 4); + assertEq(res.e.length, 1); + assertEq(res.e[0], 5); + + var obj = {}; + assertThrows(() => A.destructure(obj, [1, 2, 3, 4, 5]), TypeError); + assertThrows(() => A.get(obj), TypeError); +} \ No newline at end of file diff --git a/js/src/jit-test/tests/fields/private-field-details.js b/js/src/jit-test/tests/fields/private-field-details.js new file mode 100644 index 0000000000..4d63e21d47 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-field-details.js @@ -0,0 +1,41 @@ +// |jit-test| --enable-private-fields; + +var shouldBeThis; + +class A { + #nullReturn = false; + constructor(nullReturn) { + this.#nullReturn = nullReturn; + } + + #calls = 0; + + #z = + () => { + assertEq(this, shouldBeThis); + this.#calls++; + + // To test the second optional below. + if (this.#nullReturn && this.#calls == 2) { + return null; + } + + return this; + } + + static chainTest(o) { + o?.#z().#z()?.#z(); + } +}; + +for (var i = 0; i < 1000; i++) { + var a = new A(); + shouldBeThis = a; + + A.chainTest(a); + A.chainTest(null); + + var b = new A(true); + shouldBeThis = b; + A.chainTest(b); +} diff --git a/js/src/jit-test/tests/fields/private-ic.js b/js/src/jit-test/tests/fields/private-ic.js new file mode 100644 index 0000000000..35df63cba9 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-ic.js @@ -0,0 +1,71 @@ +// |jit-test| skip-if: !this.TypedObject; --enable-private-fields; +// More complicated IC testing. + +class Base { + constructor(o) { + return o; + } +} + +class B extends Base { + #x = 12; + static gx(o) { + return o.#x; + } + static sx(o) { + o.#x++; + } +} + +function assertThrows(fun, errorType) { + try { + fun(); + throw 'Expected error, but none was thrown'; + } catch (e) { + if (!(e instanceof errorType)) { + throw 'Wrong error type thrown ' + e.name + ' ' + e.message; + } + } +} + +var OneDPoint = new TypedObject.StructType({x: TypedObject.uint8}); +var point = new OneDPoint; + +var objects = [{}, {}, {}, {}, point, {}, point]; +// The points with x in them will throw. +var throw_results = objects.map((value) => 'x' in value); + +function test(objects, throws) { + function testThing(thing, throws) { + // Not yet stamped. + assertThrows(() => B.gx(thing), TypeError); + assertThrows(() => B.sx(thing), TypeError); + var threw = true; + var error = undefined; + // Stamp; + try { + new B(thing); + threw = false; + } catch (e) { + threw = true; + error = e; + } + if (throws) { + assertEq(threw, true); + assertEq(error instanceof TypeError, true); + } else { + assertEq(threw, false); + assertEq(error, undefined); + assertEq(B.gx(thing), 12); + B.sx(thing); + assertEq(B.gx(thing), 13); + } + } + + assertEq(objects.length, throws.length) + for (i in objects) { + testThing(objects[i], throws[i]); + } +} + +test(objects, throw_results) \ No newline at end of file diff --git a/js/src/jit-test/tests/fields/private-proxy-oom.js b/js/src/jit-test/tests/fields/private-proxy-oom.js new file mode 100644 index 0000000000..75e63b7864 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-proxy-oom.js @@ -0,0 +1,48 @@ +// |jit-test| skip-if: !('oomTest' in this); --enable-private-fields +// Check for proxy expando OOM issues. + +function assertThrowsTypeError(f) { + assertThrowsInstanceOf(f, TypeError); +} + + +function testing() { + var target = {}; + var p1 = new Proxy(target, {}); + var p2 = new Proxy(target, {}); + + class A extends class { + constructor(o) { + return o; + } + } + { + #field = 10; + static gf(o) { + return o.#field; + } + static sf(o) { + o.#field = 15; + } + } + + // Verify field handling on the proxy we install it on. + new A(p1); + assertEq(A.gf(p1), 10); + A.sf(p1) + assertEq(A.gf(p1), 15); + + // Should't be on the target + assertThrowsTypeError(() => A.gf(target)); + + // Can't set the field, doesn't exist + assertThrowsTypeError(() => A.sf(p2)); + + // Definitely can't get the field, doesn't exist. + assertThrowsTypeError(() => A.gf(p2)); + + // Still should't be on the target. + assertThrowsTypeError(() => A.gf(target)); +} + +oomTest(testing); \ No newline at end of file diff --git a/js/src/jit-test/tests/fields/private-reflect-01.js b/js/src/jit-test/tests/fields/private-reflect-01.js new file mode 100644 index 0000000000..5a85cbcfd8 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-reflect-01.js @@ -0,0 +1,49 @@ +// |jit-test| --enable-private-fields; + +function rp(x) { + return Reflect.parse(x); +}; + +rp(`( + class { + static #m = 'test262'; + } + )`); + +rp(`( + class { + #m = 'test262'; + } + )`); + +rp(`( + class { + #m = 'test262'; + gm() { + this.#m++; + this.#m--; + this.#m?.x; + o[this.#m]; + return this.#m; + } + sm() { + this.#m = 12; + } + } + )`); + +rp(`( + class { + static #m = 'test262'; + static gm() { + this.#m++; + this.#m--; + this.#m?.x; + o[this.#m]; + return this.#m; + } + static sm() { + this.#m = 12; + } + } + )`); diff --git a/js/src/jit-test/tests/fields/private-right-side-1.js b/js/src/jit-test/tests/fields/private-right-side-1.js new file mode 100644 index 0000000000..4c881a2ff0 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-right-side-1.js @@ -0,0 +1,20 @@ +// |jit-test| --enable-private-fields; + +let hit = false; + +function f() { + hit = true; +} + +class C { + #f = 1; + static m(x) { + x.#f = f(); // f() should be called before the brand check for x.#f + } +} + +try { + C.m({}); // throws a TypeError +} catch {} + +assertEq(hit, true); diff --git a/js/src/jit-test/tests/fields/private-right-side-2.js b/js/src/jit-test/tests/fields/private-right-side-2.js new file mode 100644 index 0000000000..f9fe5d38bc --- /dev/null +++ b/js/src/jit-test/tests/fields/private-right-side-2.js @@ -0,0 +1,15 @@ +// |jit-test| --enable-private-fields; + +class B { + constructor(obj) { return obj; } +} + +class C extends B { + #f = 1; + static m(obj) { + obj.#f = new C(obj); // ok, obj.#f brand check happens after RHS is evaluated + assertEq(obj.#f, obj); + } +} + +C.m({}); diff --git a/js/src/jit-test/tests/fields/private-throwing-initializer.js b/js/src/jit-test/tests/fields/private-throwing-initializer.js new file mode 100644 index 0000000000..ac5d94b343 --- /dev/null +++ b/js/src/jit-test/tests/fields/private-throwing-initializer.js @@ -0,0 +1,64 @@ +// |jit-test| --enable-private-fields; + +// Ensure private fields are stamped in order and that +// we can successfully partially initialize objects. + +class Base { + constructor(o) { + return o; + } +} + +let constructorThrow = false; + +function maybeThrow() { + if (constructorThrow) { + throw 'fail' + } + return 'sometimes' +} + +class A extends Base { + constructor(o) { + super(o); + constructorThrow = !constructorThrow; + } + + #x = 'always'; + #y = maybeThrow(); + + static gx(o) { + return o.#x; + } + + static gy(o) { + return o.#y; + } +}; + +var obj1 = {}; +var obj2 = {}; + +new A(obj1); + +var threw = true; +try { + new A(obj2); + threw = false; +} catch (e) { + assertEq(e, 'fail'); +} +assertEq(threw, true); + +A.gx(obj1) +A.gx(obj2); // Both objects get x; +A.gy(obj1); // obj1 gets y + +try { + A.gy(obj2); // shouldn't have x. + threw = false; +} catch (e) { + assertEq(e instanceof TypeError, true); +} + +assertEq(threw, true); diff --git a/js/src/jit-test/tests/fields/transplant.js b/js/src/jit-test/tests/fields/transplant.js new file mode 100644 index 0000000000..477994912a --- /dev/null +++ b/js/src/jit-test/tests/fields/transplant.js @@ -0,0 +1,51 @@ +// |jit-test| --enable-private-fields; + + +class Base { + constructor(o) { + return o; + } +} + +class A extends Base { + #x = 10; + static gx(o) { + return o.#x + } + static sx(o, v) { + o.#x = v; + } +} + +function transplantTest(transplantOptions, global) { + var {object, transplant} = transplantableObject(transplantOptions); + + new A(object); + assertEq(A.gx(object), 10); + A.sx(object, 15); + assertEq(A.gx(object), 15); + + transplant(global); + + assertEq(A.gx(object), 15); + A.sx(object, 29); + assertEq(A.gx(object), 29); +} + +// Structure helpfully provided by bug1403679.js +const thisGlobal = this; +const otherGlobalSameCompartment = newGlobal({sameCompartmentAs: thisGlobal}); +const otherGlobalNewCompartment = newGlobal({newCompartment: true}); + +const globals = + [thisGlobal, otherGlobalSameCompartment, otherGlobalNewCompartment]; + +function testWithOptions(fn) { + for (let global of globals) { + for (let options of [{}, {proxy: true}, {object: new FakeDOMObject()}, ]) { + fn(options, global); + } + } +} + +testWithOptions(transplantTest) \ No newline at end of file diff --git a/js/src/jit-test/tests/gc/bug-1321597.js b/js/src/jit-test/tests/gc/bug-1321597.js index ff8efe530c..d5d96ddab6 100644 --- a/js/src/jit-test/tests/gc/bug-1321597.js +++ b/js/src/jit-test/tests/gc/bug-1321597.js @@ -3,4 +3,4 @@ function test(s, okLine) { }; var dbg = new Debugger; dbg.onNewGlobalObject = function(global) {}; x = evalcx(test()); -shortestPaths(this, ["\$4"], 5); +shortestPaths(["\$4"], { start: this, maxNumPaths: 5 }); diff --git a/js/src/jit-test/tests/gc/bug-1531626.js b/js/src/jit-test/tests/gc/bug-1531626.js index d4c9ce921b..c0d0af8ebd 100644 --- a/js/src/jit-test/tests/gc/bug-1531626.js +++ b/js/src/jit-test/tests/gc/bug-1531626.js @@ -1,8 +1,14 @@ // Test that setting the nursery size works as expected. +// +// It's an error to set the minimum size greater than the maximum +// size. Parameter values are rounded to the nearest legal nursery +// size. load(libdir + "asserts.js"); -var testSizesKB = [128, 129, 255, 256, 1023, 1024, 3*1024, 4*1024+1, 16*1024]; +const chunkSizeKB = gcparam('chunkBytes') / 1024; + +var testSizesKB = [128, 129, 255, 256, 516, 1023, 1024, 3*1024, 4*1024+1, 16*1024]; // Valid maximum sizes must be >= 1MB. var testMaxSizesKB = testSizesKB.filter(x => x >= 1024); @@ -19,7 +25,7 @@ for (var max of testMaxSizesKB) { gcparam('minNurseryBytes', 256*1024); // need to avoid min > max; setMinMax(256, 1024); -// try an invalid configuration. +// Try an invalid configuration. assertErrorMessage( () => setMinMax(2*1024, 1024), Object, @@ -29,8 +35,8 @@ function setMinMax(min, max) { // Set the maximum first so that we don't hit a case where max < min. gcparam('maxNurseryBytes', max * 1024); gcparam('minNurseryBytes', min * 1024); - assertEq(max * 1024, gcparam('maxNurseryBytes')); - assertEq(min * 1024, gcparam('minNurseryBytes')); + assertEq(gcparam('maxNurseryBytes'), nearestLegalSize(max) * 1024); + assertEq(gcparam('minNurseryBytes'), nearestLegalSize(min) * 1024); allocateSomeThings(); gc(); } @@ -41,3 +47,12 @@ function allocateSomeThings() { } } +function nearestLegalSize(sizeKB) { + let step = sizeKB >= chunkSizeKB ? chunkSizeKB : 4; + return round(sizeKB, step); +} + +function round(x, y) { + x += y / 2; + return x - (x % y); +} diff --git a/js/src/jit-test/tests/gc/bug-1571439.js b/js/src/jit-test/tests/gc/bug-1571439.js new file mode 100644 index 0000000000..8a77988481 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1571439.js @@ -0,0 +1,23 @@ +// |jit-test| --ion-offthread-compile=off; --blinterp-warmup-threshold=1; error:TypeError + +gcparam("maxBytes", 1024*1024); +function complex(aReal, aImag) { + this.r35 = aReal; + gczeal(4, 10); + this.square = function() { + return new complex(this.r35 * this.r35 - this.i14 * this.i14, 2 * this.r35 * this.i14); + } +} +function mandelbrotValueOO(aC, aIterMax) { + let Z90 = new complex(0.0, 0.0); + Z90 = Z90.square().add(aC); +} +const width = 60; +const height = 60; +const max_iters = 50; +for (let img_x = 0; img_x < width; img_x++) { + for (let img_y = 0; img_y < height; img_y++) { + let C57 = new complex(-2 + (img_x / width) * 3, -1.5 + (img_y / height) * 3); + var res = mandelbrotValueOO(C57, max_iters); + } +} diff --git a/js/src/jit-test/tests/gc/bug-1597970.js b/js/src/jit-test/tests/gc/bug-1597970.js index 461338c620..5b384a399f 100644 --- a/js/src/jit-test/tests/gc/bug-1597970.js +++ b/js/src/jit-test/tests/gc/bug-1597970.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs enableShellAllocationMetadataBuilder(); evaluate(` gczeal(9,3); diff --git a/js/src/jit-test/tests/gc/bug-1600238.js b/js/src/jit-test/tests/gc/bug-1600238.js index 6322f496b4..6b6aeb85ac 100644 --- a/js/src/jit-test/tests/gc/bug-1600238.js +++ b/js/src/jit-test/tests/gc/bug-1600238.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - gczeal(0); newGlobal(); nukeAllCCWs(); diff --git a/js/src/jit-test/tests/gc/bug-1602741.js b/js/src/jit-test/tests/gc/bug-1602741.js index a80b528ffc..5f1cc7eca8 100644 --- a/js/src/jit-test/tests/gc/bug-1602741.js +++ b/js/src/jit-test/tests/gc/bug-1602741.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - // Test that drainJobQueue() drains all jobs, including those queued // by FinalizationRegistry callbacks. diff --git a/js/src/jit-test/tests/gc/bug-1603330.js b/js/src/jit-test/tests/gc/bug-1603330.js new file mode 100644 index 0000000000..888ae40a07 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1603330.js @@ -0,0 +1,16 @@ +// Allocate the object in the function to prevent marked as a singleton so the +// object won't be kept alive by IC stub. +function allocObj() { return {}; } + +let wr; +{ + let obj = allocObj(); + wr = new WeakRef(obj); +} + +assertEq(wr.deref() !== undefined, true); + +clearKeptObjects(); +gc(); + +assertEq(wr.deref(), undefined); diff --git a/js/src/jit-test/tests/gc/bug-1603917.js b/js/src/jit-test/tests/gc/bug-1603917.js index d1dc3866ac..c1b58f9a28 100644 --- a/js/src/jit-test/tests/gc/bug-1603917.js +++ b/js/src/jit-test/tests/gc/bug-1603917.js @@ -1,2 +1,2 @@ -// |jit-test| --enable-weak-refs; skip-if: helperThreadCount() === 0 +// |jit-test| skip-if: helperThreadCount() === 0 evalInWorker("new WeakRef({});"); diff --git a/js/src/jit-test/tests/gc/bug-1605348.js b/js/src/jit-test/tests/gc/bug-1605348.js index 2a88e33691..f55b13af32 100644 --- a/js/src/jit-test/tests/gc/bug-1605348.js +++ b/js/src/jit-test/tests/gc/bug-1605348.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs fullcompartmentchecks(true); var g37 = newGlobal({ newCompartment: true diff --git a/js/src/jit-test/tests/gc/bug-1605633.js b/js/src/jit-test/tests/gc/bug-1605633.js index fec996f650..c2de45d8b7 100644 --- a/js/src/jit-test/tests/gc/bug-1605633.js +++ b/js/src/jit-test/tests/gc/bug-1605633.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs newGlobal(); nukeAllCCWs(); var g28 = newGlobal({ diff --git a/js/src/jit-test/tests/gc/bug-1607495.js b/js/src/jit-test/tests/gc/bug-1607495.js index 15fc56a903..a759f27dff 100644 --- a/js/src/jit-test/tests/gc/bug-1607495.js +++ b/js/src/jit-test/tests/gc/bug-1607495.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs gczeal(14, 2); var g32 = newGlobal(); let wr6 = new g32.WeakRef(newGlobal({ diff --git a/js/src/jit-test/tests/gc/bug-1620195.js b/js/src/jit-test/tests/gc/bug-1620195.js index aaae1d585c..7ee5540e26 100644 --- a/js/src/jit-test/tests/gc/bug-1620195.js +++ b/js/src/jit-test/tests/gc/bug-1620195.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs var g99 = newGlobal({}); nukeAllCCWs(); let group = new FinalizationRegistry(x90 => 0); diff --git a/js/src/jit-test/tests/gc/bug-1620196.js b/js/src/jit-test/tests/gc/bug-1620196.js index 79f98e073e..34fda22c80 100644 --- a/js/src/jit-test/tests/gc/bug-1620196.js +++ b/js/src/jit-test/tests/gc/bug-1620196.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - gczeal(4); let heldValues = []; registry = new FinalizationRegistry(value => { diff --git a/js/src/jit-test/tests/gc/bug-1620209.js b/js/src/jit-test/tests/gc/bug-1620209.js new file mode 100644 index 0000000000..26327deda9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1620209.js @@ -0,0 +1,5 @@ +// |jit-test| skip-if: helperThreadCount() === 0 +verifyprebarriers(); +offThreadCompileScript(''); +var dbg = new Debugger(); +var objects = dbg.findObjects(); diff --git a/js/src/jit-test/tests/gc/bug-1628440.js b/js/src/jit-test/tests/gc/bug-1628440.js index 4e24ae8c3b..e128fcb7ac 100644 --- a/js/src/jit-test/tests/gc/bug-1628440.js +++ b/js/src/jit-test/tests/gc/bug-1628440.js @@ -6,4 +6,4 @@ let fg = new FinalizationRegistry(cleanup); let object = {}; fg.register(object, {}, key); let success = fg.unregister(key); -throw "x"; +throw new ReferenceError(); diff --git a/js/src/jit-test/tests/gc/bug-1643913.js b/js/src/jit-test/tests/gc/bug-1643913.js index 8717024eb3..2f51b786eb 100644 --- a/js/src/jit-test/tests/gc/bug-1643913.js +++ b/js/src/jit-test/tests/gc/bug-1643913.js @@ -1,21 +1,34 @@ -// |jit-test| --enable-weak-refs; --no-ti +for (let p of [false, true]) { + f(p); -for (let i = 70; i > 50; i--) { - gc(); - gczeal(10, i); - - f(true, false, false); - f(true, false, true); + // Run an incremental GC to completion. + startgc(1); + while (gcstate() !== 'NotActive') { + gcslice(10000, { dontStart: true }); + } } function ccwToObject() { return evalcx('({})', newGlobal({newCompartment: true})); } -function f(x, y, z) { - let registry = new FinalizationRegistry(value => {}); - let target = x ? ccwToObject() : {}; - let heldValue = y ? ccwToObject() : {}; - let token = z ? ccwToObject() : {}; - registry.register(target, heldValue, token); +function ccwToRegistry() { + return evalcx('new FinalizationRegistry(value => {})', + newGlobal({newCompartment: true})); +} + +function f(p) { + let registry = ccwToRegistry(); + let target = ccwToObject(); + registry.register(target, undefined); + + // Add a CCW from registry to target zone or vice versa to control + // the order the zones are swept in. + if (p) { + registry.ptr = target; + } else { + target.ptr = registry; + } + + gc(); } diff --git a/js/src/jit-test/tests/gc/bug-1644985-2.js b/js/src/jit-test/tests/gc/bug-1644985-2.js new file mode 100644 index 0000000000..fbb00b59de --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1644985-2.js @@ -0,0 +1,4 @@ +let fr = new FinalizationRegistry(x => 1); +fr.register(evalcx('({})', newGlobal({newCompartment: true}))); +nukeAllCCWs(); +gc(); diff --git a/js/src/jit-test/tests/gc/bug-1644985.js b/js/src/jit-test/tests/gc/bug-1644985.js new file mode 100644 index 0000000000..aac0e99277 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1644985.js @@ -0,0 +1,4 @@ +let wr = new WeakRef(evalcx('({})', newGlobal({newCompartment: true}))); +nukeAllCCWs(); +clearKeptObjects(); +gc(); diff --git a/js/src/jit-test/tests/gc/bug-1648901.js b/js/src/jit-test/tests/gc/bug-1648901.js new file mode 100644 index 0000000000..13e4895068 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1648901.js @@ -0,0 +1,7 @@ +// |jit-test| skip-if: !('gczeal' in this) + +gczeal(15); +enableShellAllocationMetadataBuilder(); +var registry = new FinalizationRegistry(x => 0); +gczeal(9, 3); +registry.register({}, 1, {}); diff --git a/js/src/jit-test/tests/gc/bug-1651345.js b/js/src/jit-test/tests/gc/bug-1651345.js new file mode 100644 index 0000000000..54187c5d55 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1651345.js @@ -0,0 +1,7 @@ +function main() { + const v3 = {get:Object}; + const v5 = Object.defineProperty(Object,0,v3); + addMarkObservers(Object) + gc(); +} +main(); diff --git a/js/src/jit-test/tests/gc/bug-1652492.js b/js/src/jit-test/tests/gc/bug-1652492.js new file mode 100644 index 0000000000..a64f541a12 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1652492.js @@ -0,0 +1,17 @@ +function f1() { + arr = f2; + var p = arr[(gczeal(9))|0]; +} +f2 = f1; +f2(); +try { + function allocObj() { return {}; } + { + let obj = allocObj(); + wr = new WeakRef(obj); + } + clearKeptObjects(); +(new obj); +} catch(exc) {} +let obj = allocObj(); +wr = new WeakRef(obj); diff --git a/js/src/jit-test/tests/gc/bug-1654186.js b/js/src/jit-test/tests/gc/bug-1654186.js new file mode 100644 index 0000000000..562938d8f8 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1654186.js @@ -0,0 +1,8 @@ +// |jit-test| allow-oom; skip-if: !('oomAfterAllocations' in this) + +gczeal(14, 5); +var g = newGlobal(); +g.eval("(" + function() { + oomAfterAllocations(100); +} + ")()"); +f.x(""); diff --git a/js/src/jit-test/tests/gc/bug-1655917.js b/js/src/jit-test/tests/gc/bug-1655917.js new file mode 100644 index 0000000000..5805958ed7 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1655917.js @@ -0,0 +1,10 @@ +var g = newGlobal({ newCompartment: true }); +g.eval(` + var obj = {}; + var ref = new WeakRef(obj); + Promise.resolve().then(() => { + assertEq(ref.deref(), obj); + }); +`); +nukeCCW(g.ref); +drainJobQueue(); diff --git a/js/src/jit-test/tests/gc/bug-1657554.js b/js/src/jit-test/tests/gc/bug-1657554.js new file mode 100644 index 0000000000..f751d442b9 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1657554.js @@ -0,0 +1,2 @@ +// |jit-test| skip-if: !('oomTest' in this) +oomTest(() => eval("new WeakRef({});")); diff --git a/js/src/jit-test/tests/gc/bug-1660293.js b/js/src/jit-test/tests/gc/bug-1660293.js new file mode 100644 index 0000000000..a2c953c11f --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1660293.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !('oomAfterAllocations' in this) + +try { +function varying(mapColor, keyColor) { + enqueueMark(`set-color-${keyColor}`); + enqueueMark("yield"); + startgc(100000); +} +for (const mapColor of ['gray', 'black']) + varying(mapColor, 0x7fff); +} catch (exc) {} +oomAfterAllocations(100); diff --git a/js/src/jit-test/tests/gc/bug-1666880.js b/js/src/jit-test/tests/gc/bug-1666880.js new file mode 100644 index 0000000000..90aca56f28 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1666880.js @@ -0,0 +1,11 @@ +// |jit-test| error: ReferenceError + +var T84 = TypedObject; +ValueStruct = new T84.StructType({ + g89: T84.Any +}); +var v82 = new ValueStruct; +a20 = BigInt(-1); +var c18 = v82.g89 = a20; +gczeal(2); +if (line == null) {} diff --git a/js/src/jit-test/tests/gc/bug-1667336.js b/js/src/jit-test/tests/gc/bug-1667336.js new file mode 100644 index 0000000000..b4d065a711 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-1667336.js @@ -0,0 +1,17 @@ +// |jit-test| --ion-offthread-compile=off; --warp; skip-if: helperThreadCount() === 0 + +var g = newGlobal(); +gczeal(9, 1); +gczeal(11, 2); +g.offThreadCompileScript("") +setJitCompilerOption("offthread-compilation.enable", 1); + +for (let i = 0 ; i < 3000; i++) { + loadFile(); +} + +function loadFile() { + try { + x; + } catch(exc) {} +} diff --git a/js/src/jit-test/tests/gc/bug1600017.js b/js/src/jit-test/tests/gc/bug1600017.js index db58c735fb..c7a748009f 100644 --- a/js/src/jit-test/tests/gc/bug1600017.js +++ b/js/src/jit-test/tests/gc/bug1600017.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - var registry = new FinalizationRegistry(x => { if (target1 === null) { return; diff --git a/js/src/jit-test/tests/gc/bug1600488-1.js b/js/src/jit-test/tests/gc/bug1600488-1.js index b15bb2f291..a0fb8e5ee5 100644 --- a/js/src/jit-test/tests/gc/bug1600488-1.js +++ b/js/src/jit-test/tests/gc/bug1600488-1.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - const token = {}; let cleanedUpValue; const finalizationRegistry = new FinalizationRegistry(value => { diff --git a/js/src/jit-test/tests/gc/bug1600488-2.js b/js/src/jit-test/tests/gc/bug1600488-2.js index f25714703a..c7de44f1a0 100644 --- a/js/src/jit-test/tests/gc/bug1600488-2.js +++ b/js/src/jit-test/tests/gc/bug1600488-2.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - const token = {}; let iterated; const finalizationRegistry = new FinalizationRegistry(items => { diff --git a/js/src/jit-test/tests/gc/dedupe-02.js b/js/src/jit-test/tests/gc/dedupe-02.js new file mode 100644 index 0000000000..72b2f97f9c --- /dev/null +++ b/js/src/jit-test/tests/gc/dedupe-02.js @@ -0,0 +1,39 @@ +// AutoStableStringChars needs to prevent the owner of its chars from being +// deduplicated, even if they are held by a different string. + +gczeal(0); + +function makeExtensibleStrFrom(str) { + var left = str.substr(0, str.length/2); + var right = str.substr(str.length/2, str.length); + var ropeStr = left + right; + return ensureLinearString(ropeStr); +} + +// Make a string to deduplicate to. +var original = makeExtensibleStrFrom('{ "phbbbbbbbbbbbbbbttt!!!!??": [1] }\n\n'); + +// Construct D2 -> D1 -> base +var D2 = makeExtensibleStrFrom('{ "phbbbbbbbbbbbbbbttt!!!!??": [1] }'); +var D1 = newRope(D2, '\n', {nursery: true}); +ensureLinearString(D1); +var base = newRope(D1, '\n', {nursery: true}); +ensureLinearString(base); + +// Make an AutoStableStringChars(D2) and do a minor GC within it. (This will do +// a major GC, but it'll start out with a minor GC.) `base` would get +// deduplicated to `original`, if it weren't for AutoStableStringChars marking +// all of D2, D1, and base non-deduplicatable. + +// The first time JSON.parse runs, it will create several (14 in my test) GC +// things before getting to the point where it does an allocation while holding +// the chars pointer. Get them out of the way now. +JSON.parse(D2); + +// Cause a minor GC to happen during JSON.parse after AutoStableStringChars +// gives up its pointer. +schedulegc(1); +JSON.parse(D2); + +// Access `D2` to verify that it is not using the deduplicated chars. +print(D2); diff --git a/js/src/jit-test/tests/gc/dedupe.js b/js/src/jit-test/tests/gc/dedupe.js new file mode 100644 index 0000000000..2e2c578abf --- /dev/null +++ b/js/src/jit-test/tests/gc/dedupe.js @@ -0,0 +1,44 @@ +function str(c) { + let s = c; + for (let i = 0; i < 30; i++) + s += c; + ensureLinearString(s); + return s; +} + +function f() { + // Create some slots to write into. + const o = {owner: 'short1', s: 'short2'}; + + // Make a tenured rope. + const r1 = str("a") + str("b"); + gc(); + + // Write the first instance of our duplicate string into one of the slots + // (`owner`). This will be scanned first, and entered into deDupSet when + // tenured. + o.owner = ensureLinearString(str("a") + str("b") + str("c")); + + // Make another rope with identical contents, with a tenured subtree. + const r2 = r1 + str("c"); + + // Linearize the new rope, creating a new extensible string and a bunch of + // dependent strings replacing the rest of the rope nodes. + ensureLinearString(r2); + + // Write the new rope into a slot, so that it will be scanned next during the + // minor GC during traceSlots(). + o.s = r2; + + // Do a nursery collection. o.owner will be tenured and inserted into + // deDupSet. Then o.s aka r2 will be tenured. If things work correctly, r2 + // will be marked non-deduplicatable because it is the base of a tenured + // string r1. If not, it will be deduplicated to o.owner. + minorgc(); + + // Extract out that r1 child node. If its base was deduplicated, this will + // assert because its chars have been freed. + const s1 = r1.substr(0, 31); +} + +f(); diff --git a/js/src/jit-test/tests/gc/dedupeTenuredBase.js b/js/src/jit-test/tests/gc/dedupeTenuredBase.js new file mode 100644 index 0000000000..5dbb25df45 --- /dev/null +++ b/js/src/jit-test/tests/gc/dedupeTenuredBase.js @@ -0,0 +1,45 @@ +function str(c) { + let s = c; + for (let i = 0; i < 30; i++) { + s += c; + } + ensureLinearString(s); + return s; +} + +function f() { + // Create some slots to write into. + const o = { owner: "short1", s: "short2" }; + + // Make a tenured rope. + const r1 = str("a") + str("b"); + gc(); + + // Write the first instance of our duplicate string into one of the slots + // (`owner`). This will be scanned first, and entered into deDupSet when + // tenured. + o.owner = ensureLinearString(str("a") + str("b") + str("c")); + + // Make another rope with identical contents, with a tenured subtree. + const r2 = r1 + str("c"); + + // Linearize the new rope, creating a new extensible string and a bunch of + // dependent strings replacing the rest of the rope nodes. + ensureLinearString(r2); + + // Write the new rope into a slot, so that it will be scanned next during the + // minor GC during traceSlots(). + o.s = r2; + + // Do a nursery collection. o.owner will be tenured and inserted into + // deDupSet. Then o.s aka r2 will be tenured. If things work correctly, r2 + // will be marked non-deduplicatable because it is the base of a tenured + // string r1. If not, it will be deduplicated to o.owner. + minorgc(); + + // Extract out that r1 child node. If its base was deduplicated, this will + // assert because its chars have been freed. + const s1 = r1.substr(0, 31); +} + +f(); diff --git a/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js b/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js new file mode 100644 index 0000000000..9cb384756e --- /dev/null +++ b/js/src/jit-test/tests/gc/deduplicateTenuringStrings.js @@ -0,0 +1,205 @@ +// |jit-test| skip-if: !('stringRepresentation' in this) + +// This is to test the correctness of the string deduplication algorithm during +// the tenuring phase. Same strings below refer to the same character encoding +// (either latin1 or twobyte) and the same characters. + +// Tests: +// 1. Same strings with same flags and zones should be deduplicated for +// all linear strings except atoms and external strings. +// 2. Same strings, but from different zones should not be deduplicated. +// 3. Same strings, but with different flags should not be deduplicated. + +// We require predictable GC timing to make sure the correct +// strings are tenured together. +gczeal(0); + +var helperCode = ` +function makeInlineStr(isLatin1) { + var s = isLatin1 ? "123456789*1" : "一二三"; + return s + s; +} + +// Generic linear strings are non-atom, non-extensible, non-inline +// linear strings. +// Generic linear strings can only have latin1 characters. +function makeGenericLinearStr() { + return notes(() => 1); +} + +function makeRopeStr(isLatin1) { + var left = isLatin1 ? "1" : "一"; + var right = isLatin1 ? "123456789*123456789*123456" : + "一二三四五六七八九*一二三四五六七八"; + return left + right; +} + +function makeExtensibleStr(isLatin1) { + var r = makeRopeStr(isLatin1); + ensureLinearString(r); + return r; +} + +function makeExtensibleStrFrom(str) { + var left = str.substr(0, str.length/2); + var right = str.substr(str.length/2, str.length); + var ropeStr = left + right; + return ensureLinearString(ropeStr); +} + +function makeDependentStr(isLatin1) { + var e = makeExtensibleStr(isLatin1); + var r1 = e + "!"; + var r2 = e + r1; + ensureLinearString(r2); + return r1; +} + +function makeDependentStrFrom(str) { + var e = makeExtensibleStrFrom(str); + var r1 = e.substr(0, e.length/2) + e.substr(e.length/2, e.length); + var r2 = e + r1; + ensureLinearString(r2); + return r1; +} + +function makeExternalStr(isLatin1) { + return isLatin1 ? newString("12345678", {external: true}) : + newString("一二三", {external: true}); +} + +function tenureStringsWithSameChars(str1, str2, isDeduplicatable) { + minorgc(); + assertEq(stringRepresentation(str1) == stringRepresentation(str2), + isDeduplicatable); +} + +function assertDiffStrRepAfterMinorGC(g1, g2) { + minorgc(); + g1.eval(\`strRep = stringRepresentation(str);\`); + g2.eval(\`strRep = stringRepresentation(str);\`); + assertEq(g1.strRep == g2.strRep, false); +} +`; + +eval(helperCode); + +// test1: +// Same strings with same flags and zones should be deduplicated for all linear +// strings except atoms, external strings. +function test1(isLatin1) { + const isDeduplicatable = true; + + // Deduplicatable: + // --> Inline Strings + var str1 = makeInlineStr(isLatin1); + var str2 = makeInlineStr(isLatin1); + tenureStringsWithSameChars(str1, str2, isDeduplicatable); + + // --> Extensible Strings + str1 = makeExtensibleStr(isLatin1); + str2 = makeExtensibleStr(isLatin1); + tenureStringsWithSameChars(str1, str2, isDeduplicatable); + + // --> Dependent Strings + str1 = makeDependentStr(isLatin1); + str2 = makeDependentStr(isLatin1); + tenureStringsWithSameChars(str1, str2, isDeduplicatable); + + // --> Generic Linear Strings + if (isLatin1) { + var str1 = makeGenericLinearStr(); + var str2 = makeGenericLinearStr(); + tenureStringsWithSameChars(str1, str2, isDeduplicatable); + } + + // Non-Deduplicatable: + // --> Rope Strings + str1 = makeRopeStr(isLatin1); + str2 = makeRopeStr(isLatin1); + tenureStringsWithSameChars(str1, str2, !isDeduplicatable); + + // --> Atom strings are deduplicated already but not through string + // deduplication during tenuring. + + // --> External strings are not nursery allocated. +} + +// test2: +// Same strings, but from different zones should not be deduplicated. +function test2(isLatin1) { + var g1 = newGlobal({ newCompartment: true }); + var g2 = newGlobal({ newCompartment: true }); + + g1.eval(helperCode); + g2.eval(helperCode); + + // --> Inline Strings + g1.eval(`var str = makeInlineStr(${isLatin1}); `); + g2.eval(`var str = makeInlineStr(${isLatin1}); `); + assertDiffStrRepAfterMinorGC(g1, g2); + + // --> Extensible Strings + g1.eval(`str = makeExtensibleStr(${isLatin1}); `); + g2.eval(`str = makeExtensibleStr(${isLatin1}); `); + assertDiffStrRepAfterMinorGC(g1, g2); + + // --> Dependent Strings + g1.eval(`str = makeDependentStr(${isLatin1}); `); + g2.eval(`str = makeDependentStr(${isLatin1}); `); + assertDiffStrRepAfterMinorGC(g1, g2); + + // --> Generic Linear Strings + if (isLatin1) { + g1.eval(`str = makeGenericLinearStr();`); + g2.eval(`str = makeGenericLinearStr();`); + assertDiffStrRepAfterMinorGC(g1, g2); + } +} + +// test3: +// Same strings, but with different flags should not be deduplicated. +function test3(isLatin1) { + const isDeduplicatable = true; + + // --> Dependent String and Extensible String + var dependentStr = makeDependentStr(isLatin1); + var extensibleStr = makeExtensibleStrFrom(dependentStr); + tenureStringsWithSameChars(dependentStr, extensibleStr, !isDeduplicatable); + + if (isLatin1) { + // --> Generic Linear String and Extensible String + var genericLinearStr = makeGenericLinearStr(); + var extensibleStr = makeExtensibleStrFrom(genericLinearStr); + tenureStringsWithSameChars( + genericLinearStr, + extensibleStr, + !isDeduplicatable + ); + + // --> Generic Linear String and Dependent String + var dependentStr = makeDependentStrFrom(genericLinearStr); + tenureStringsWithSameChars( + dependentStr, + genericLinearStr, + !isDeduplicatable + ); + } + + // --> Inline strings are too short to have the same chars as the extensible + // strings, generic linear strings and dependent strings +} + +function runTests() { + var charEncoding = { TWOBYTE: 0, LATIN1: 1 }; + + test1(charEncoding.TWOBYTE); + test2(charEncoding.TWOBYTE); + test3(charEncoding.TWOBYTE); + + test1(charEncoding.LATIN1); + test2(charEncoding.LATIN1); + test3(charEncoding.LATIN1); +} + +runTests(); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js b/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js index da4faffc40..88c98519ca 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-ccw.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - // Test combinations of arguments in different compartments. gczeal(0); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-cleanupSome-recursive.js b/js/src/jit-test/tests/gc/finalizationRegistry-cleanupSome-recursive.js index 2f38b8b899..5ff69d990a 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-cleanupSome-recursive.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-cleanupSome-recursive.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - // Test trying to call cleanupSome recursively in callback. // 0: Initial state. diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-gray.js b/js/src/jit-test/tests/gc/finalizationRegistry-gray.js index 0746ad07cd..5411a1a9ad 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-gray.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-gray.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - // Test gray finalization registry is correctly barrired. target = {}; registry = new FinalizationRegistry(value => undefined); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-oom1.js b/js/src/jit-test/tests/gc/finalizationRegistry-oom1.js index 617b4e1095..753448a650 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-oom1.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-oom1.js @@ -1,4 +1,4 @@ -// |jit-test| --enable-weak-refs; skip-if: !('oomTest' in this) +// |jit-test| skip-if: !('oomTest' in this) // Don't test prototype initialization etc. new FinalizationRegistry(x => 0); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-oom2.js b/js/src/jit-test/tests/gc/finalizationRegistry-oom2.js index 69785aa753..9d9b2a7db8 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-oom2.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-oom2.js @@ -1,4 +1,4 @@ -// |jit-test| --enable-weak-refs; skip-if: !('oomTest' in this) +// |jit-test| skip-if: !('oomTest' in this) let registry = new FinalizationRegistry(x => 0); let token = {}; oomTest(() => registry.register({}, 1, token)); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-oom3.js b/js/src/jit-test/tests/gc/finalizationRegistry-oom3.js index 59dce5a16d..d606ad8ba8 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-oom3.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-oom3.js @@ -1,4 +1,4 @@ -// |jit-test| --enable-weak-refs; skip-if: !('oomTest' in this) +// |jit-test| skip-if: !('oomTest' in this) let registry = new FinalizationRegistry(x => 0); registry.register({}, 1, {}); let token = {}; diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-oom4.js b/js/src/jit-test/tests/gc/finalizationRegistry-oom4.js index dc39633572..4b7ef66ba0 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-oom4.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-oom4.js @@ -1,4 +1,4 @@ -// |jit-test| --enable-weak-refs; skip-if: !('oomTest' in this) +// |jit-test| skip-if: !('oomTest' in this) let registry = new FinalizationRegistry(x => 0); let target = {}; let token = {}; diff --git a/js/src/jit-test/tests/gc/finalizationRegistry-records-not-initialized.js b/js/src/jit-test/tests/gc/finalizationRegistry-records-not-initialized.js index 0b0476a673..327988ddc7 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry-records-not-initialized.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry-records-not-initialized.js @@ -1,4 +1,3 @@ -// |jit-test| --enable-weak-refs enableShellAllocationMetadataBuilder(); evaluate(` var registry = new FinalizationRegistry(x => 0); diff --git a/js/src/jit-test/tests/gc/finalizationRegistry.js b/js/src/jit-test/tests/gc/finalizationRegistry.js index f35e5014ce..fab47b0f93 100644 --- a/js/src/jit-test/tests/gc/finalizationRegistry.js +++ b/js/src/jit-test/tests/gc/finalizationRegistry.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - function checkPropertyDescriptor(obj, property, writable, enumerable, configurable) { let desc = Object.getOwnPropertyDescriptor(obj, property); diff --git a/js/src/jit-test/tests/gc/helper-thread-params.js b/js/src/jit-test/tests/gc/helper-thread-params.js new file mode 100644 index 0000000000..282ea82a54 --- /dev/null +++ b/js/src/jit-test/tests/gc/helper-thread-params.js @@ -0,0 +1,34 @@ +// |jit-test| skip-if: helperThreadCount() === 0 + +function assertError(thunk) { + let threw = false; + try { + thunk(); + } catch (e) { + threw = true; + } + assertEq(threw, true); +} + +let initialHelperThreads = helperThreadCount(); + +// Test that setting maxHelperThreads limits the number of threads. +gcparam("helperThreadRatio", 100); +for (let i = 1; i <= initialHelperThreads; i++) { + gcparam("maxHelperThreads", i); + assertEq(gcparam("helperThreadCount"), i); +} + +// Test that setting helperThreadRatio works as expected. +gcparam("maxHelperThreads", 1000); +for (let i = 25; i <= 400; i *= 2) { + gcparam("helperThreadRatio", i); + let ratio = i / 100; + let expected = Math.max(Math.floor(initialHelperThreads * ratio), 1); + assertEq(gcparam("helperThreadCount"), expected); + assertEq(helperThreadCount(), Math.max(initialHelperThreads, expected)); +} + +// Test that illegal settings are checked. +assertError(() => gcparam("helperThreadRatio", 0)); +assertError(() => gcparam("maxHelperThreads", 0)); diff --git a/js/src/jit-test/tests/gc/str-atom-dedupe.js b/js/src/jit-test/tests/gc/str-atom-dedupe.js new file mode 100644 index 0000000000..587f879db5 --- /dev/null +++ b/js/src/jit-test/tests/gc/str-atom-dedupe.js @@ -0,0 +1,16 @@ +// Create Latin1 string + atom. +var latin1S = "foo".repeat(50); +var obj = {}; +obj[latin1S] = 3; +assertEq(obj[latin1S], 3); + +// Create a TwoByte version, ensure it's in the StringToAtomCache. +var twoByteS = newString(latin1S, {twoByte: true}); +assertEq(obj[twoByteS], 3); + +// Create a dependent TwoByte string. +var depTwoByteS = twoByteS.slice(1); + +// Deduplication shouldn't get confused about Latin1 atom vs TwoByte strings. +minorgc(); +assertEq(obj["f" + depTwoByteS], 3); diff --git a/js/src/jit-test/tests/gc/weak-marking-03.js b/js/src/jit-test/tests/gc/weak-marking-03.js index 9edaa3452e..e0de8bc58b 100644 --- a/js/src/jit-test/tests/gc/weak-marking-03.js +++ b/js/src/jit-test/tests/gc/weak-marking-03.js @@ -366,6 +366,8 @@ function grayMarkingMapLast() { clearMarkObservers(); grayRoot().length = 0; g.eval("grayRoot().length = 0"); + + return vals; // To prevent the JIT from optimizing out vals. } if (this.enqueueMark) diff --git a/js/src/jit-test/tests/gc/weakRef_in_promise.js b/js/src/jit-test/tests/gc/weakRef_in_promise.js index d21938d916..8accdc354e 100644 --- a/js/src/jit-test/tests/gc/weakRef_in_promise.js +++ b/js/src/jit-test/tests/gc/weakRef_in_promise.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs -// // https://github.com/tc39/proposal-weakrefs/issues/39 // Weakref should keep the target until the end of current Job, that includes // microtask(Promise). diff --git a/js/src/jit-test/tests/gc/weakRefs-basic.js b/js/src/jit-test/tests/gc/weakRefs-basic.js index 57fe236454..6099d3c9e0 100644 --- a/js/src/jit-test/tests/gc/weakRefs-basic.js +++ b/js/src/jit-test/tests/gc/weakRefs-basic.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs - assertEq('WeakRef' in this, true); function checkPropertyDescriptor(obj, property, writable, enumerable, diff --git a/js/src/jit-test/tests/gc/weakRefs-disabled.js b/js/src/jit-test/tests/gc/weakRefs-disabled.js deleted file mode 100644 index 2ea7e416a9..0000000000 --- a/js/src/jit-test/tests/gc/weakRefs-disabled.js +++ /dev/null @@ -1,3 +0,0 @@ -// Weak references are disabled by default. -assertEq('WeakRef' in this, false); -assertEq('FinalizationRegistry' in this, false); diff --git a/js/src/jit-test/tests/gc/weakRefs.js b/js/src/jit-test/tests/gc/weakRefs.js index bf0a76948e..c0e4630551 100644 --- a/js/src/jit-test/tests/gc/weakRefs.js +++ b/js/src/jit-test/tests/gc/weakRefs.js @@ -1,5 +1,3 @@ -// |jit-test| --enable-weak-refs -// // https://tc39.es/proposal-weakrefs/#sec-keepduringjob // When the abstract operation KeepDuringJob is called with a target object // reference, it adds the target to an identity Set that will point strongly at @@ -44,17 +42,17 @@ var that = this; gc(); let wr1; -(function() { - let obj = {}; +// Allocate the object in the function to prevent marked as a singleton so the +// object won't be kept alive by IC stub. +function allocObj() { return {}; } + +(function () { + let obj = allocObj(); wr1 = new WeakRef(obj); obj = null; })(); -// TODO: -// Bug 1603330: WeakRef.deref() makes the target being kept even -// ClearKeptObjects() is called. -// -// don't call wr1.deref() here to prevent the target of wr1 is kept. +assertEq(undefined === wr1.deref(), false); gc(); diff --git a/js/src/jit-test/tests/heap-analysis/bug-1249107.js b/js/src/jit-test/tests/heap-analysis/bug-1249107.js index 81792398b1..0ee1871a5c 100644 --- a/js/src/jit-test/tests/heap-analysis/bug-1249107.js +++ b/js/src/jit-test/tests/heap-analysis/bug-1249107.js @@ -1 +1 @@ -shortestPaths(this, [this], 5) +shortestPaths([this], {start: this, maxNumPaths: 5}) diff --git a/js/src/jit-test/tests/heap-analysis/bug-1252912.js b/js/src/jit-test/tests/heap-analysis/bug-1252912.js index 1240b45456..409ef59006 100644 --- a/js/src/jit-test/tests/heap-analysis/bug-1252912.js +++ b/js/src/jit-test/tests/heap-analysis/bug-1252912.js @@ -3,4 +3,4 @@ try { toSource = (function() { }) } catch (foo) {} -shortestPaths(this, ["$4"], 5) +shortestPaths(["$4"], {start: this, maxNumPaths: 5}) diff --git a/js/src/jit-test/tests/heap-analysis/bug-1254105.js b/js/src/jit-test/tests/heap-analysis/bug-1254105.js index 5d6ff8ba64..f1bae6b152 100644 --- a/js/src/jit-test/tests/heap-analysis/bug-1254105.js +++ b/js/src/jit-test/tests/heap-analysis/bug-1254105.js @@ -1,3 +1,3 @@ // |jit-test| error:Error: Each target must be an object, string, or symbol -shortestPaths(this, [, , , undefined], 5) +shortestPaths([, , , undefined], {start: this, maxNumPaths: 5}) diff --git a/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js b/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js index 6f907aa5a0..1c14e9ff6e 100644 --- a/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js +++ b/js/src/jit-test/tests/heap-analysis/byteSize-of-string.js @@ -235,18 +235,18 @@ assertEq(byteSize(rope16), s(Nurser // cases. Also note that on Windows mozmalloc's smallest allocation size is // two words compared to one word on other platforms. if (config['windows']) { - assertEq(byteSize(newExternalString("")), s(EN+8, EN+16)); - assertEq(byteSize(newExternalString("1")), s(EN+8, EN+16)); - assertEq(byteSize(newExternalString("12")), s(EN+8, EN+16)); - assertEq(byteSize(newExternalString("123")), s(EN+8, EN+16)); - assertEq(byteSize(newExternalString("1234")), s(EN+8, EN+16)); + assertEq(byteSize(newString("", {external: true})), s(EN+8, EN+16)); + assertEq(byteSize(newString("1", {external: true})), s(EN+8, EN+16)); + assertEq(byteSize(newString("12", {external: true})), s(EN+8, EN+16)); + assertEq(byteSize(newString("123", {external: true})), s(EN+8, EN+16)); + assertEq(byteSize(newString("1234", {external: true})), s(EN+8, EN+16)); } else { - assertEq(byteSize(newExternalString("")), s(EN+4, EN+8)); - assertEq(byteSize(newExternalString("1")), s(EN+4, EN+8)); - assertEq(byteSize(newExternalString("12")), s(EN+4, EN+8)); - assertEq(byteSize(newExternalString("123")), s(EN+8, EN+8)); - assertEq(byteSize(newExternalString("1234")), s(EN+8, EN+8)); + assertEq(byteSize(newString("", {external: true})), s(EN+4, EN+8)); + assertEq(byteSize(newString("1", {external: true})), s(EN+4, EN+8)); + assertEq(byteSize(newString("12", {external: true})), s(EN+4, EN+8)); + assertEq(byteSize(newString("123", {external: true})), s(EN+8, EN+8)); + assertEq(byteSize(newString("1234", {external: true})), s(EN+8, EN+8)); } -assertEq(byteSize(newExternalString("12345")), s(EN+16, EN+16)); -assertEq(byteSize(newExternalString("123456789.123456789.1234")), s(EN+48, EN+48)); -assertEq(byteSize(newExternalString("123456789.123456789.12345")), s(EN+64, EN+64)); +assertEq(byteSize(newString("12345", {external: true})), s(EN+16, EN+16)); +assertEq(byteSize(newString("123456789.123456789.1234", {external: true})), s(EN+48, EN+48)); +assertEq(byteSize(newString("123456789.123456789.12345", {external: true})), s(EN+64, EN+64)); diff --git a/js/src/jit-test/tests/heap-analysis/shortestPaths.js b/js/src/jit-test/tests/heap-analysis/shortestPaths.js index d0c050c297..e4cd3faced 100644 --- a/js/src/jit-test/tests/heap-analysis/shortestPaths.js +++ b/js/src/jit-test/tests/heap-analysis/shortestPaths.js @@ -1,5 +1,6 @@ // The shortestPaths function exists solely to let the fuzzers go to town and -// exercise the code paths it calls into, hence there is nothing to assert here. +// exercise the code paths it calls into, hence the only things to assert +// relate to the shortestPaths test function API. // // The actual behavior of JS::ubi::ShortestPaths is tested in // js/src/jsapi-tests/testUbiNode.cpp, where we can actually control the @@ -15,30 +16,60 @@ var o = { p: g }; +function describe(v) { + return v === undefined ? "(undefined)" + : v === null ? "(null)" + : typeof(v) === "object" ? Object.prototype.toString.call(v) + : typeof(v); +} + function dumpPaths(results) { - results = results.map(paths => { - return paths.map(path => { - return path.map(part => { - return { - predecessor: Object.prototype.toString.call(part.predecessor), - edge: part.edge - }; - }); - }); - }); + results = results.map(paths => + paths.map(path => + path.map(({predecessor, edge}) => + predecessor !== undefined ? + { predecessor: describe(predecessor), edge } + : + { edge } + ) + ) + ); print(JSON.stringify(results, null, 2)); } -print("shortestPaths(this, [Object, f, o.p], 5)"); -var paths = shortestPaths(this, [Object, f, o.p], 5); +print("shortestPaths([Object, f, o.p], {start: this, maxNumPaths: 5})"); +var paths = shortestPaths([Object, f, o.p], {start: this, maxNumPaths: 5}); +dumpPaths(paths); + +print(); +print("shortestPaths([f], {start: o, maxNumPaths: 1})") +paths = shortestPaths([f], {start: o, maxNumPaths: 1}); dumpPaths(paths); print(); -print("shortestPaths(o, [f], 1)") -paths = shortestPaths(o, [f], 1); +print("shortestPaths([f], {start: this, maxNumPaths: 5})") +paths = shortestPaths([f], {start: this, maxNumPaths: 5}); dumpPaths(paths); print(); -print("shortestPaths(this, [f], 5)") -paths = shortestPaths(this, [f], 5); +print("shortestPaths([f], {maxNumPaths: 5})") +paths = shortestPaths([f], {maxNumPaths: 5}); dumpPaths(paths); +assertEq(paths[0].length <= 5, true, "Too many paths reported"); + +paths = shortestPaths([f, g]); +assertEq(paths.length, 2, "Two sets of paths expected"); + +paths = shortestPaths([f], {maxNumPaths: 1}); +assertEq(paths[0].length, 1, "Single path expected"); + +var exc; + +try { paths = shortestPaths(); } catch (exc) { e = ""+exc; }; +assertEq(e.includes("TypeError") && e.includes("1 argument required"), true); + +try { paths = shortestPaths(100, {}); } catch (exc) { e = ""+exc; }; +assertEq(e, "TypeError: 100 is not an array object"); + +try { paths = shortestPaths([f], {start: 200}); } catch (exc) { e = ""+exc; }; +assertEq(e, "TypeError: 200 is not a GC thing"); diff --git a/js/src/jit-test/tests/ion/array-push-multiple-frozen.js b/js/src/jit-test/tests/ion/array-push-multiple-frozen.js index 1cc1f73883..271f6cb07a 100644 --- a/js/src/jit-test/tests/ion/array-push-multiple-frozen.js +++ b/js/src/jit-test/tests/ion/array-push-multiple-frozen.js @@ -58,7 +58,7 @@ while(true) { if (res == 0) { limit = 1024 * 1024 * 1024; } else if (res == 1) { // Started and finished in Ion. - if (limit == 0) // If we are not in the Jit. + if (limit <= 1) // If we are not in the Jit. break; // We want to converge quickly to a state where the memory is limited // enough to cause failures in array.prototype.push. diff --git a/js/src/jit-test/tests/ion/array-push-multiple.js b/js/src/jit-test/tests/ion/array-push-multiple.js index dcc0564610..19c1a93e70 100644 --- a/js/src/jit-test/tests/ion/array-push-multiple.js +++ b/js/src/jit-test/tests/ion/array-push-multiple.js @@ -53,7 +53,7 @@ while(true) { if (res == 0) { limit = 1024 * 1024 * 1024; } else if (res == 1) { // Started and finished in Ion. - if (limit == 0) // If we are not in the Jit. + if (limit <= 1) // If we are not in the Jit. break; // We want to converge quickly to a state where the memory is limited // enough to cause failures in array.prototype.push. diff --git a/js/src/jit-test/tests/ion/bug1216157.js b/js/src/jit-test/tests/ion/bug1216157.js index bf0f500350..1ec9497e40 100644 --- a/js/src/jit-test/tests/ion/bug1216157.js +++ b/js/src/jit-test/tests/ion/bug1216157.js @@ -1,4 +1,4 @@ -// |jit-test| skip-if: !('oomAfterAllocations' in this) +// |jit-test| skip-if: !('oomAfterAllocations' in this); allow-oom gcslice(0); // Start IGC, but don't mark anything. function f(str) { diff --git a/js/src/jit-test/tests/ion/bug1354275.js b/js/src/jit-test/tests/ion/bug1354275.js index 7d87d93092..3d8d74af46 100644 --- a/js/src/jit-test/tests/ion/bug1354275.js +++ b/js/src/jit-test/tests/ion/bug1354275.js @@ -12,5 +12,5 @@ function f(t) { } } } - +f(1); f(-1); diff --git a/js/src/jit-test/tests/ion/bug1568397.js b/js/src/jit-test/tests/ion/bug1568397.js index 9c098d2e36..c03bb0283d 100644 --- a/js/src/jit-test/tests/ion/bug1568397.js +++ b/js/src/jit-test/tests/ion/bug1568397.js @@ -1,4 +1,4 @@ -// |jit-test| error:tmp is undefined +// |jit-test| error:TypeError: can't access property let obj = {x: 1}; obj.x = 1.1; diff --git a/js/src/jit-test/tests/ion/bug1647293.js b/js/src/jit-test/tests/ion/bug1647293.js new file mode 100644 index 0000000000..4c474f5f9a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1647293.js @@ -0,0 +1,12 @@ +function f() { + var i = 0; + while (i != 3000) { + if (typeof i !== "number") { + var x = i || 8; + } + var next = i + 1; + i = arguments; + i = next; + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1655940-1.js b/js/src/jit-test/tests/ion/bug1655940-1.js new file mode 100644 index 0000000000..34880823cc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-1.js @@ -0,0 +1,14 @@ +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + new Int32Array(1); + x = 2; + new Int32Array(t); + } catch (e) { + assertEq(x, 2); + } + } +} +f(1); +f(-1); diff --git a/js/src/jit-test/tests/ion/bug1655940-2.js b/js/src/jit-test/tests/ion/bug1655940-2.js new file mode 100644 index 0000000000..d24a065f5f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-2.js @@ -0,0 +1,15 @@ +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + var {} = {}; + x = 2; + var {} = t; + } catch (e) { + assertEq(x, 2); + } + } +} +for (var t of [{}, null]) { + f(t); +} diff --git a/js/src/jit-test/tests/ion/bug1655940-3.js b/js/src/jit-test/tests/ion/bug1655940-3.js new file mode 100644 index 0000000000..a9d984dd68 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-3.js @@ -0,0 +1,21 @@ +var ToObject = getSelfHostedValue("ToObject"); + +function f(arr) { + for (var i = 0; i < arr.length; i++) { + var v = arr[i]; + try { + var x = 1; + ToObject({}); + x = 2; + ToObject(v); + } catch (e) { + assertEq(x, 2); + } + } +} + +var a = []; +for (var i = 0; i < 50; i++) { + a.push({}, null); +} +f(a); diff --git a/js/src/jit-test/tests/ion/bug1870756.js b/js/src/jit-test/tests/ion/bug1870756.js new file mode 100644 index 0000000000..5dca232399 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1870756.js @@ -0,0 +1,8 @@ +// |jit-test| --fast-warmup; --no-threads; --arm-hwcap=vfp + +function foo(n) { return n % 2; } + +with ({}) {} +for (var i = 0; i < 1000; i++) { + foo(0); +} diff --git a/js/src/jit-test/tests/ion/callobj-tdz.js b/js/src/jit-test/tests/ion/callobj-tdz.js new file mode 100644 index 0000000000..fff872a23e --- /dev/null +++ b/js/src/jit-test/tests/ion/callobj-tdz.js @@ -0,0 +1,14 @@ +// CallObject with TDZ arguments +function test( + a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, + {} = () => { + with ({}) {}; + return a00; + }) { +} + +// Warm-up JITs +for (var i = 0; i < 2000; ++i) { + test(); +} diff --git a/js/src/jit-test/tests/ion/dce-with-rinstructions.js b/js/src/jit-test/tests/ion/dce-with-rinstructions.js index 2c626feace..f4084b2c44 100644 --- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js +++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js @@ -5,6 +5,8 @@ setJitCompilerOption("ion.warmup.trigger", 20); setJitCompilerOption("ion.full.warmup.trigger", 20); var i; +var warp = getJitCompilerOptions()["warp.enable"]; + // Prevent GC from cancelling/discarding Ion compilations. gczeal(0); @@ -1336,8 +1338,15 @@ function rrandom(i) { if(config.debug) setRNGState(2, 1+i); var x = Math.random(); - if (uceFault_random(i) || uceFault_random(i)) - assertEq(x, config.debug ? setRNGState(2, 1+i) || Math.random() : x); + if (uceFault_random(i) || uceFault_random(i)) { + // TODO(Warp): Conditional operator ?: prevents recovering operands. + // assertEq(x, config.debug ? setRNGState(2, 1+i) || Math.random() : x); + if (config.debug) { + assertEq(x, setRNGState(2, 1+i) || Math.random()); + } else { + assertEq(x, x); + } + } assertRecoveredOnBailout(x, true); return i; } @@ -1479,7 +1488,13 @@ for (j = 100 - max; j < 100; j++) { rsqrt_object(i); ratan2_number(i); ratan2_object(i); - rstr_split(i); + if (!warp) { + // TODO(Warp): Warp doesn't currently support a compiler constraints like + // system to elide checks for modified built-ins. Additionally this test + // requires to inline the self-hosted function and to elide all type + // checks before the StringSplitString intrinsic is called. + rstr_split(i); + } rregexp_exec(i); rregexp_y_exec(i); rregexp_y_literal_exec(i); @@ -1517,7 +1532,10 @@ for (j = 100 - max; j < 100; j++) { rtofloat32_object(i); rtrunc_to_int32_number(i); rtrunc_to_int32_object(i); - rtrunc_to_int32_string(i); + if (!warp) { + // TODO(Warp): Bitwise operations on strings not optimised in Warp. + rtrunc_to_int32_string(i); + } rhypot_number_2args(i); rhypot_number_3args(i); rhypot_number_4args(i); diff --git a/js/src/jit-test/tests/ion/for-in-iterator-1.js b/js/src/jit-test/tests/ion/for-in-iterator-1.js index 925aa4e1b1..a963641143 100644 --- a/js/src/jit-test/tests/ion/for-in-iterator-1.js +++ b/js/src/jit-test/tests/ion/for-in-iterator-1.js @@ -1,3 +1,7 @@ +// |jit-test| skip-if: !isTypeInferenceEnabled() +// With trial inlining enabled, this test loops infinitely +// waiting for a trial-inlined function to be recompiled. + gczeal(0); var values = { @@ -24,7 +28,6 @@ for (var i = 1; i < 6; i++) { // Run until the end is running within Ion, or skip if we are unable to run // in Ion. - while (!res.start) + while (!res.start || !res.end) res = test(values); - assertEq(!res.start || !res.end, false); } diff --git a/js/src/jit-test/tests/ion/known-class.js b/js/src/jit-test/tests/ion/known-class.js new file mode 100644 index 0000000000..61e6f2afe2 --- /dev/null +++ b/js/src/jit-test/tests/ion/known-class.js @@ -0,0 +1,121 @@ +var IsRegExpObject = getSelfHostedValue("IsRegExpObject"); +var IsCallable = getSelfHostedValue("IsCallable"); +var NewArrayIterator = getSelfHostedValue("NewArrayIterator"); +var GuardToArrayIterator = getSelfHostedValue("GuardToArrayIterator"); + +function array() { + var a = [0]; + assertEq(Array.isArray(a), true); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), false); + assertEq(IsCallable(a), false); +} + +function array2(x) { + var a; + if (x) { + a = [0]; + } else { + a = [1]; + } + assertEq(Array.isArray(a), true); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), false); + assertEq(IsCallable(a), false); +} + +function object() { + var o = {a: 1}; + assertEq(Array.isArray(o), false); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function object2(x) { + var o; + if (x) { + o = {a: 1}; + } else { + o = {b: 1}; + } + assertEq(Array.isArray(o), false); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function mixed(x) { + var o; + if (x) { + o = [1]; + } else { + o = {a: 1}; + } + assertEq(Array.isArray(o), x); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function lambda() { + function f() {} + assertEq(Array.isArray(f), false); + assertEq(typeof f, "function"); + assertEq(IsRegExpObject(f), false); + assertEq(IsCallable(f), true); +} + +function arrow() { + var f = () => {}; + assertEq(Array.isArray(f), false); + assertEq(typeof f, "function"); + assertEq(IsRegExpObject(f), false); + assertEq(IsCallable(f), true); +} + +function regexp() { + var r = /a/; + assertEq(Array.isArray(r), false); + assertEq(typeof r, "object"); + assertEq(IsRegExpObject(r), true); + assertEq(IsCallable(r), false); +} + +function regexp2(x) { + var a; + if (x) { + a = /a/; + } else { + a = /b/; + } + assertEq(Array.isArray(a), false); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), true); + assertEq(IsCallable(a), false); +} + +function iterator() { + var i = NewArrayIterator(); + assertEq(Array.isArray(i), false); + assertEq(typeof i, "object"); + assertEq(IsRegExpObject(i), false); + assertEq(IsCallable(i), false); + assertEq(GuardToArrayIterator(i), i); +} + +var b = true; +for (var i = 0; i < 1e4; i++) { + array(); + array2(b); + object(); + object2(b); + mixed(b); + lambda(); + arrow(); + regexp() + regexp2(b); + iterator(); + + b = !b; +} diff --git a/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js b/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js index 7f6f2b8fae..34e7ed406f 100644 --- a/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js +++ b/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js @@ -21,8 +21,8 @@ function test(x) { } function double(v) { - // NB: Math.cbrt() always returns a double value. - return Math.cbrt(v * v * v) + // NB: numberToDouble() always returns a double value. + return numberToDouble(v); } // Find the first power which will exceed the Int32 range by computing ⌈log_x(2 ^ 31)⌉. diff --git a/js/src/jit-test/tests/ion/pow-base-power-of-two.js b/js/src/jit-test/tests/ion/pow-base-power-of-two.js index 52c89c32fe..35ae52a28d 100644 --- a/js/src/jit-test/tests/ion/pow-base-power-of-two.js +++ b/js/src/jit-test/tests/ion/pow-base-power-of-two.js @@ -21,8 +21,8 @@ function test(x, y, z) { } function double(v) { - // NB: Math.cbrt() always returns a double value. - return `Math.cbrt(${v * v * v})`; + // NB: numberToDouble() always returns a double value. + return `numberToDouble(${v})`; } function addTests(fn) { diff --git a/js/src/jit-test/tests/ion/pow-constant-power.js b/js/src/jit-test/tests/ion/pow-constant-power.js index f4cdfd8486..9382348052 100644 --- a/js/src/jit-test/tests/ion/pow-constant-power.js +++ b/js/src/jit-test/tests/ion/pow-constant-power.js @@ -19,8 +19,8 @@ function test(x, y, z) { } function double(v) { - // NB: Math.cbrt() always returns a double value. - return `Math.cbrt(${v * v * v})`; + // NB: numberToDouble() always returns a double value. + return `numberToDouble(${v})`; } function addTests(fn) { diff --git a/js/src/jit-test/tests/ion/recover-arrays.js b/js/src/jit-test/tests/ion/recover-arrays.js index f3e118119b..d1185d788c 100644 --- a/js/src/jit-test/tests/ion/recover-arrays.js +++ b/js/src/jit-test/tests/ion/recover-arrays.js @@ -1,3 +1,8 @@ +// |jit-test| --no-warp + +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. + // Ion eager fails the test below because we have not yet created any // template object in baseline before running the content of the top-level // function. @@ -10,6 +15,9 @@ if (getJitCompilerOptions()["ion.warmup.trigger"] <= 100) if (getJitCompilerOptions()["ion.forceinlineCaches"]) setJitCompilerOption("ion.forceinlineCaches", 0); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + // This function is used to force a bailout when it is inlined, and to recover // the frame which is inlining this function. var resumeHere = function (i) { if (i >= 99) bailout(); }; diff --git a/js/src/jit-test/tests/ion/recover-cow-arrays.js b/js/src/jit-test/tests/ion/recover-cow-arrays.js index 801b81e909..bc25bf3f98 100644 --- a/js/src/jit-test/tests/ion/recover-cow-arrays.js +++ b/js/src/jit-test/tests/ion/recover-cow-arrays.js @@ -1,3 +1,8 @@ +// |jit-test| --no-warp + +// Warp has COW arrays disabled (bug 1626854). Re-evaluate after that bug has +// been fixed. + // Ion eager fails the test below because we have not yet created any // template object in baseline before running the content of the top-level // function. @@ -10,6 +15,9 @@ if (getJitCompilerOptions()["ion.warmup.trigger"] <= 100) if (getJitCompilerOptions()["ion.forceinlineCaches"]) setJitCompilerOption("ion.forceinlineCaches", 0); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + // This function is used to force a bailout when it is inlined, and to recover // the frame of the function in which this function is inlined. var resumeHere = function (i) { if (i >= 99) bailout(); }; diff --git a/js/src/jit-test/tests/ion/recover-empty-new-object.js b/js/src/jit-test/tests/ion/recover-empty-new-object.js index a34f0d36fb..e8fbbec063 100644 --- a/js/src/jit-test/tests/ion/recover-empty-new-object.js +++ b/js/src/jit-test/tests/ion/recover-empty-new-object.js @@ -1,8 +1,7 @@ -// |jit-test| test-join=--no-unboxed-objects -// -// Unboxed object optimization might not trigger in all cases, thus we ensure -// that Sink optimization is working well independently of the -// object representation. +// |jit-test| --no-warp + +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. // Ion eager fails the test below because we have not yet created any // template object in baseline before running the content of the top-level @@ -10,6 +9,9 @@ if (getJitCompilerOptions()["ion.warmup.trigger"] <= 20) setJitCompilerOption("ion.warmup.trigger", 20); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + // These arguments have to be computed by baseline, and thus captured in a // resume point. The next function checks that we can remove the computation of // these arguments. diff --git a/js/src/jit-test/tests/ion/recover-lambdas.js b/js/src/jit-test/tests/ion/recover-lambdas.js index 612a02fd1b..6e5a00c933 100644 --- a/js/src/jit-test/tests/ion/recover-lambdas.js +++ b/js/src/jit-test/tests/ion/recover-lambdas.js @@ -1,9 +1,15 @@ -// |jit-test| --ion-osr=off +// |jit-test| --no-warp; --ion-osr=off + +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. var max = 40; setJitCompilerOption("ion.warmup.trigger", max - 10); setJitCompilerOption("ion.full.warmup.trigger", max - 10); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + // This function is used to escape "g" which is a non-escaped inner function. // As it is not escaped within "f", the lambda for "g" would be computed on the // bailout path. Resolving the first ".caller" implies that we have to recover diff --git a/js/src/jit-test/tests/ion/recover-newarrayiterator.js b/js/src/jit-test/tests/ion/recover-newarrayiterator.js index 7947ac77c9..3d98640a2c 100644 --- a/js/src/jit-test/tests/ion/recover-newarrayiterator.js +++ b/js/src/jit-test/tests/ion/recover-newarrayiterator.js @@ -1,6 +1,9 @@ var max = 40; setJitCompilerOption("ion.warmup.trigger", max - 10); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + function selfhosted() { if (typeof getSelfHostedValue === "undefined") return; diff --git a/js/src/jit-test/tests/ion/recover-newstringiterator.js b/js/src/jit-test/tests/ion/recover-newstringiterator.js index 472e7aaefb..14a7d46b6e 100644 --- a/js/src/jit-test/tests/ion/recover-newstringiterator.js +++ b/js/src/jit-test/tests/ion/recover-newstringiterator.js @@ -1,6 +1,9 @@ var max = 40; setJitCompilerOption("ion.warmup.trigger", max - 10); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + function selfhosted() { if (typeof getSelfHostedValue === "undefined") return; diff --git a/js/src/jit-test/tests/ion/recover-object-bug1175233.js b/js/src/jit-test/tests/ion/recover-object-bug1175233.js index 12e080fd3b..aaec613512 100644 --- a/js/src/jit-test/tests/ion/recover-object-bug1175233.js +++ b/js/src/jit-test/tests/ion/recover-object-bug1175233.js @@ -16,6 +16,9 @@ if (getJitCompilerOptions()["ion.warmup.trigger"] <= 130) if (getJitCompilerOptions()["ion.forceinlineCaches"]) setJitCompilerOption("ion.forceinlineCaches", 0); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + var uceFault = function (j) { if (j >= max) uceFault = function (j) { return true; }; diff --git a/js/src/jit-test/tests/ion/recover-objects.js b/js/src/jit-test/tests/ion/recover-objects.js index 18e5fd98f1..0eb16c7f9b 100644 --- a/js/src/jit-test/tests/ion/recover-objects.js +++ b/js/src/jit-test/tests/ion/recover-objects.js @@ -1,8 +1,7 @@ -// |jit-test| test-join=--no-unboxed-objects; --ion-pgo=on -// -// Unboxed object optimization might not trigger in all cases, thus we ensure -// that Scalar Replacement optimization is working well independently of the -// object representation. +// |jit-test| --no-warp; --ion-pgo=on + +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. var max = 200; @@ -22,6 +21,9 @@ setJitCompilerOption("ion.warmup.trigger", getJitCompilerOptions()["ion.warmup.t if (getJitCompilerOptions()["ion.forceinlineCaches"]) setJitCompilerOption("ion.forceinlineCaches", 0); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + function resumeHere() {} var uceFault = function (i) { if (i > max - 2) diff --git a/js/src/jit-test/tests/ion/rinstructions-no-sse4.js b/js/src/jit-test/tests/ion/rinstructions-no-sse4.js index 6997ed3f2b..3fc764d7e2 100644 --- a/js/src/jit-test/tests/ion/rinstructions-no-sse4.js +++ b/js/src/jit-test/tests/ion/rinstructions-no-sse4.js @@ -6,6 +6,9 @@ setJitCompilerOption("baseline.warmup.trigger", 10); setJitCompilerOption("ion.warmup.trigger", 20); +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + const max = 200; // Check that we are able to remove the operation inside recover test diff --git a/js/src/jit-test/tests/ion/try-catch-7.js b/js/src/jit-test/tests/ion/try-catch-7.js index 4a36d5de2d..ed07cfe7e1 100644 --- a/js/src/jit-test/tests/ion/try-catch-7.js +++ b/js/src/jit-test/tests/ion/try-catch-7.js @@ -7,4 +7,4 @@ for (;;) { break; } } -for (var i = 0; i < 15; i++) {} +for (var i = 0; i < 1500; i++) {} diff --git a/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js b/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js index 9d78ab5c69..9d1e0ca531 100644 --- a/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js +++ b/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js @@ -7,8 +7,8 @@ function f(n) { // for the TypedArray index conversion. const r = n === 0 ? undefined : 0; - // Math.cbrt always returns a double number. - const k = Math.cbrt(0); + // numberToDouble always returns a double number. + const k = numberToDouble(0); for (var i = 0; i < 10; ++i) { assertEq(ta[k], r); diff --git a/js/src/jit-test/tests/modules/ambiguous-star-export.js b/js/src/jit-test/tests/modules/ambiguous-star-export.js index 94aa7ac4af..2542714061 100644 --- a/js/src/jit-test/tests/modules/ambiguous-star-export.js +++ b/js/src/jit-test/tests/modules/ambiguous-star-export.js @@ -3,7 +3,6 @@ "use strict"; load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); function checkModuleEval(source) { let m = parseModule(source); @@ -17,9 +16,9 @@ function checkModuleSyntaxError(source) { assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError); } -let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); -let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); -let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); +let a = registerModule('a', parseModule("export var a = 1; export var b = 2;")); +let b = registerModule('b', parseModule("export var b = 3; export var c = 4;")); +let c = registerModule('c', parseModule("export * from 'a'; export * from 'b';")); c.declarationInstantiation(); c.evaluation(); diff --git a/js/src/jit-test/tests/modules/bad-namespace-created.js b/js/src/jit-test/tests/modules/bad-namespace-created.js index 7d17546a40..cc4a6e46a8 100644 --- a/js/src/jit-test/tests/modules/bad-namespace-created.js +++ b/js/src/jit-test/tests/modules/bad-namespace-created.js @@ -5,13 +5,11 @@ "use strict"; load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); -moduleRepo['A'] = parseModule('import "B"; export {x} from "C"'); -moduleRepo['B'] = parseModule('import * as a from "A"'); -moduleRepo['C'] = parseModule('export * from "D"; export * from "E"'); -moduleRepo['D'] = parseModule('export let x'); -moduleRepo['E'] = parseModule('export let x'); +let a = registerModule('A', parseModule('import "B"; export {x} from "C"')); +registerModule('B', parseModule('import * as a from "A"')); +registerModule('C', parseModule('export * from "D"; export * from "E"')); +registerModule('D', parseModule('export let x')); +registerModule('E', parseModule('export let x')); -let m = moduleRepo['A']; -assertThrowsInstanceOf(() => m.declarationInstantiation(), SyntaxError); +assertThrowsInstanceOf(() => a.declarationInstantiation(), SyntaxError); diff --git a/js/src/jit-test/tests/modules/bug-1247934.js b/js/src/jit-test/tests/modules/bug-1247934.js index a58d78fe3c..666607d1f5 100644 --- a/js/src/jit-test/tests/modules/bug-1247934.js +++ b/js/src/jit-test/tests/modules/bug-1247934.js @@ -1,9 +1,5 @@ -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - return moduleRepo[specifier]; -}); setJitCompilerOption("ion.warmup.trigger", 50); s = ""; for (i = 0; i < 1024; i++) s += "export let e" + i + "\n"; -moduleRepo['a'] = parseModule(s); +registerModule('a', parseModule(s)); parseModule("import * as ns from 'a'").declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/bug-1283448.js b/js/src/jit-test/tests/modules/bug-1283448.js index 9ee6217abf..9be2828ea4 100644 --- a/js/src/jit-test/tests/modules/bug-1283448.js +++ b/js/src/jit-test/tests/modules/bug-1283448.js @@ -1,10 +1,6 @@ // |jit-test| error: TypeError -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - return moduleRepo[specifier]; -}); -let a = moduleRepo['a'] = parseModule("var x = 1; export { x };"); -let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';"); +let a = registerModule('a', parseModule("var x = 1; export { x };")); +let b = registerModule('b', parseModule("import { x as y } from 'a';")); a.__proto__ = {15: 1337}; b.declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/bug-1284486-2.js b/js/src/jit-test/tests/modules/bug-1284486-2.js index 62d765fd08..54270caa59 100644 --- a/js/src/jit-test/tests/modules/bug-1284486-2.js +++ b/js/src/jit-test/tests/modules/bug-1284486-2.js @@ -1,16 +1,15 @@ -// This tests that attempting to perform ModuleDeclarationInstantation a second -// time after a failure re-throws the same error. +// This tests that attempting to perform ModuleDeclarationInstantation a +// second time after a failure still fails. (It no longer stores and rethrows +// the same error; the spec changed in that regard and the implementation was +// updated in bug 1420420). // -// The first attempt fails becuase module 'a' is not available. The second -// attempt fails because of the previous failure. +// The attempts fails becuase module 'a' is not available. // // This test exercises the path where the previously instantiated module is // re-instantiated directly. -load(libdir + "dummyModuleResolveHook.js"); - -let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); -let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); +let b = registerModule('b', parseModule("export var b = 3; export var c = 4;")); +let c = registerModule('c', parseModule("export * from 'a'; export * from 'b';")); let e1; let threw = false; @@ -32,4 +31,4 @@ try { e2 = exc; } assertEq(threw, true); -assertEq(e1, e2); +assertEq(e1.toString(), e2.toString()); diff --git a/js/src/jit-test/tests/modules/bug-1284486.js b/js/src/jit-test/tests/modules/bug-1284486.js index 61c7cafaa2..7489b5eb56 100644 --- a/js/src/jit-test/tests/modules/bug-1284486.js +++ b/js/src/jit-test/tests/modules/bug-1284486.js @@ -7,10 +7,8 @@ // This test exercises the path where the previously instantiated module is // encountered as an import. -load(libdir + "dummyModuleResolveHook.js"); - -let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); -let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); +let b = registerModule('b', parseModule("export var b = 3; export var c = 4;")); +let c = registerModule('c', parseModule("export * from 'a'; export * from 'b';")); let e1; let threw = false; @@ -23,8 +21,8 @@ try { assertEq(threw, true); assertEq(typeof e1 === "undefined", false); -let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); -let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;"); +let a = registerModule('a', parseModule("export var a = 1; export var b = 2;")); +let d = registerModule('d', parseModule("import { a } from 'c'; a;")); threw = false; try { diff --git a/js/src/jit-test/tests/modules/bug-1287410.js b/js/src/jit-test/tests/modules/bug-1287410.js index 0d36fe444a..14df1b14e4 100644 --- a/js/src/jit-test/tests/modules/bug-1287410.js +++ b/js/src/jit-test/tests/modules/bug-1287410.js @@ -1,21 +1,15 @@ // |jit-test| error: InternalError -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; -}); -let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); -let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); -let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); +let a = registerModule('a', parseModule("export var a = 1; export var b = 2;")); +let b = registerModule('b', parseModule("export var b = 3; export var c = 4;")); +let c = registerModule('c', parseModule("export * from 'a'; export * from 'b';")); c.declarationInstantiation(); // Module 'a' is replaced with another module that has not been instantiated. // This should not happen and would be a bug in the module loader. -a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); +a = registerModule('a', parseModule("export var a = 1; export var b = 2;")); -let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;"); +let d = registerModule('d', parseModule("import { a } from 'c'; a;")); // Attempting to instantiate 'd' throws an error because depdency 'a' of // instantiated module 'c' is not instantiated. diff --git a/js/src/jit-test/tests/modules/bug-1372258.js b/js/src/jit-test/tests/modules/bug-1372258.js index d1c79c2435..2764d38075 100644 --- a/js/src/jit-test/tests/modules/bug-1372258.js +++ b/js/src/jit-test/tests/modules/bug-1372258.js @@ -10,18 +10,16 @@ function parseModule(source) { // Test importing an import many times. -load(libdir + "dummyModuleResolveHook.js"); - const count = 1024; -let a = moduleRepo['a'] = parseModule("export let a = 1;"); +let a = registerModule('a', parseModule("export let a = 1;")); let s = ""; for (let i = 0; i < count; i++) { s += "import { a as i" + i + " } from 'a';\n"; s += "assertEq(i" + i + ", 1);\n"; } -let b = moduleRepo['b'] = parseModule(s); +let b = registerModule('b', parseModule(s)); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/modules/bug-1420420-2.js b/js/src/jit-test/tests/modules/bug-1420420-2.js index e7de4eff4c..e67882300b 100644 --- a/js/src/jit-test/tests/modules/bug-1420420-2.js +++ b/js/src/jit-test/tests/modules/bug-1420420-2.js @@ -1,18 +1,17 @@ // Test re-instantiation module after failure. load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); -moduleRepo["good"] = parseModule(`export let x`); +registerModule("good", parseModule(`export let x`)); -moduleRepo["y1"] = parseModule(`export let y`); -moduleRepo["y2"] = parseModule(`export let y`); -moduleRepo["bad"] = parseModule(`export* from "y1"; export* from "y2";`); +registerModule("y1", parseModule(`export let y`)); +registerModule("y2", parseModule(`export let y`)); +registerModule("bad", parseModule(`export* from "y1"; export* from "y2";`)); -moduleRepo["a"] = parseModule(`import* as ns from "good"; import {y} from "bad";`); +registerModule("a", parseModule(`import* as ns from "good"; import {y} from "bad";`)); -let b = moduleRepo["b"] = parseModule(`import "a";`); -let c = moduleRepo["c"] = parseModule(`import "a";`); +let b = registerModule("b", parseModule(`import "a";`)); +let c = registerModule("c", parseModule(`import "a";`)); assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError); diff --git a/js/src/jit-test/tests/modules/bug-1420420-4.js b/js/src/jit-test/tests/modules/bug-1420420-4.js index f6ae8f2f69..b150c7584d 100644 --- a/js/src/jit-test/tests/modules/bug-1420420-4.js +++ b/js/src/jit-test/tests/modules/bug-1420420-4.js @@ -1,10 +1,9 @@ load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); -moduleRepo["a"] = parseModule(`throw undefined`); +registerModule("a", parseModule(`throw undefined`)); -let b = moduleRepo["b"] = parseModule(`import "a";`); -let c = moduleRepo["c"] = parseModule(`import "a";`); +let b = registerModule("b", parseModule(`import "a";`)); +let c = registerModule("c", parseModule(`import "a";`)); b.declarationInstantiation(); c.declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/bug-1420420.js b/js/src/jit-test/tests/modules/bug-1420420.js index b1eda3aead..3764d71a7a 100644 --- a/js/src/jit-test/tests/modules/bug-1420420.js +++ b/js/src/jit-test/tests/modules/bug-1420420.js @@ -1,18 +1,17 @@ // Test re-instantiation module after failure. load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); -moduleRepo["good"] = parseModule(`export let x`); +registerModule("good", parseModule(`export let x`)); -moduleRepo["y1"] = parseModule(`export let y`); -moduleRepo["y2"] = parseModule(`export let y`); -moduleRepo["bad"] = parseModule(`export* from "y1"; export* from "y2";`); +registerModule("y1", parseModule(`export let y`)); +registerModule("y2", parseModule(`export let y`)); +registerModule("bad", parseModule(`export* from "y1"; export* from "y2";`)); -moduleRepo["a"] = parseModule(`import {x} from "good"; import {y} from "bad";`); +registerModule("a", parseModule(`import {x} from "good"; import {y} from "bad";`)); -let b = moduleRepo["b"] = parseModule(`import "a";`); -let c = moduleRepo["c"] = parseModule(`import "a";`); +let b = registerModule("b", parseModule(`import "a";`)); +let c = registerModule("c", parseModule(`import "a";`)); assertThrowsInstanceOf(() => b.declarationInstantiation(), SyntaxError); assertThrowsInstanceOf(() => c.declarationInstantiation(), SyntaxError); diff --git a/js/src/jit-test/tests/modules/bug-1435327.js b/js/src/jit-test/tests/modules/bug-1435327.js index ce965e4597..356ccab31e 100644 --- a/js/src/jit-test/tests/modules/bug-1435327.js +++ b/js/src/jit-test/tests/modules/bug-1435327.js @@ -1,12 +1,8 @@ // |jit-test| skip-if: !('oomTest' in this) lfLogBuffer = ` - let moduleRepo = {}; - setModuleResolveHook(function(x, specifier) { - return moduleRepo[specifier]; - }); - let c = moduleRepo['c'] = parseModule(""); - let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;"); + let c = registerModule('c', parseModule("")); + let d = registerModule('d', parseModule("import { a } from 'c'; a;")); d.declarationInstantiation(); `; lfLogBuffer = lfLogBuffer.split('\n'); diff --git a/js/src/jit-test/tests/modules/bug-1443555.js b/js/src/jit-test/tests/modules/bug-1443555.js index c9ee406685..cbb1c5f5dd 100644 --- a/js/src/jit-test/tests/modules/bug-1443555.js +++ b/js/src/jit-test/tests/modules/bug-1443555.js @@ -4,13 +4,6 @@ setJitCompilerOption("baseline.warmup.trigger", 0); -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; -}); - let mainSrc = ` import A from "A"; @@ -29,7 +22,7 @@ let ASrc = ` export default 1; `; -moduleRepo['A'] = parseModule(ASrc); +registerModule('A', parseModule(ASrc)); let m = parseModule(mainSrc); m.declarationInstantiation() diff --git a/js/src/jit-test/tests/modules/bug-1462286.js b/js/src/jit-test/tests/modules/bug-1462286.js index b1da5727c2..312d2f34b0 100644 --- a/js/src/jit-test/tests/modules/bug-1462286.js +++ b/js/src/jit-test/tests/modules/bug-1462286.js @@ -1,8 +1,6 @@ -load(libdir + "dummyModuleResolveHook.js"); - -let a = moduleRepo['a'] = parseModule(` +let a = registerModule('a', parseModule(` export var { ... get } = { x: "foo" }; -`); +`)); let m = parseModule("import { get } from 'a'; export { get };"); m.declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/bug-1463371.js b/js/src/jit-test/tests/modules/bug-1463371.js deleted file mode 100644 index f0e8782e8e..0000000000 --- a/js/src/jit-test/tests/modules/bug-1463371.js +++ /dev/null @@ -1,10 +0,0 @@ -// |jit-test| error: Error - -var g = newGlobal(); -g.eval(` - setModuleResolveHook(function(module, specifier) { return module; }); -`); -let m = parseModule(` - import {} from './foo.js'; -`); -m.declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/bug-1463373.js b/js/src/jit-test/tests/modules/bug-1463373.js deleted file mode 100644 index 2319091660..0000000000 --- a/js/src/jit-test/tests/modules/bug-1463373.js +++ /dev/null @@ -1,11 +0,0 @@ -// |jit-test| error: InternalError - -let m = parseModule(` - let c = parseModule(\` - import "a"; - \`); - c.declarationInstantiation(); -`); -setModuleResolveHook(function(module, specifier) { return m; }); -m.declarationInstantiation(); -m.evaluation(); diff --git a/js/src/jit-test/tests/modules/bug-1476921.js b/js/src/jit-test/tests/modules/bug-1476921.js index 319b1ae0ec..cbe9c75806 100644 --- a/js/src/jit-test/tests/modules/bug-1476921.js +++ b/js/src/jit-test/tests/modules/bug-1476921.js @@ -1,17 +1,16 @@ "use strict"; load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); class UniqueError extends Error {} -let a = moduleRepo['a'] = parseModule(` +let a = registerModule('a', parseModule(` throw new UniqueError(); -`); +`)); -let b = moduleRepo['b'] = parseModule(` +let b = registerModule('b', parseModule(` import * as ns0 from "a"; -`); +`)); a.declarationInstantiation(); assertThrowsInstanceOf(() => a.evaluation(), UniqueError); diff --git a/js/src/jit-test/tests/modules/bug-1510598.js b/js/src/jit-test/tests/modules/bug-1510598.js index bd18b7d534..e9fe2dd08a 100644 --- a/js/src/jit-test/tests/modules/bug-1510598.js +++ b/js/src/jit-test/tests/modules/bug-1510598.js @@ -1,12 +1,8 @@ -setModuleResolveHook(function(module, specifier) { - throw "Module '" + specifier + "' not found"; -}); g = newGlobal({newCompartment: true}); g.parent = this; -g.eval("new Debugger(parent).onExceptionUnwind = () => null;"); - +g.eval(`new Debugger(parent).onExceptionUnwind = () => null;`); let exc = "fail"; -// This import fails because no such file exists, so we fire the onExceptionUnwind hook. -import("javascript: ").catch(e => { exc = e; }); +// Module evaluation throws so we fire the onExceptionUnwind hook. +import("javascript: throw 'foo'").catch(e => { exc = e; }); drainJobQueue(); assertEq(exc, undefined); diff --git a/js/src/jit-test/tests/modules/bug-1657066.js b/js/src/jit-test/tests/modules/bug-1657066.js new file mode 100644 index 0000000000..22c828ca68 --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1657066.js @@ -0,0 +1,3 @@ +let g = newGlobal({newCompartment: true}); +new Debugger(g).onExceptionUnwind = () => null; +g.eval(`import("javascript: throw 1")`).catch(() => 0); diff --git a/js/src/jit-test/tests/modules/bug1210391.js b/js/src/jit-test/tests/modules/bug1210391.js index 78874a3c1f..e9006bf16f 100644 --- a/js/src/jit-test/tests/modules/bug1210391.js +++ b/js/src/jit-test/tests/modules/bug1210391.js @@ -1,8 +1,7 @@ -load(libdir + "dummyModuleResolveHook.js"); -let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;"); -let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;"); -let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';"); -let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;"); +let a = registerModule('a', parseModule("export var a = 1; export var b = 2;")); +let b = registerModule('b', parseModule("export var b = 3; export var c = 4;")); +let c = registerModule('c', parseModule("export * from 'a'; export * from 'b';")); +let d = registerModule('d', parseModule("import { a } from 'c'; a;")); d.declarationInstantiation(); d.evaluation(); diff --git a/js/src/jit-test/tests/modules/bug1429031.js b/js/src/jit-test/tests/modules/bug1429031.js index 20079428ef..95e0d4e375 100644 --- a/js/src/jit-test/tests/modules/bug1429031.js +++ b/js/src/jit-test/tests/modules/bug1429031.js @@ -1,18 +1,14 @@ // |jit-test| error: ReferenceError -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - return moduleRepo[specifier]; -}); assertEq = function(a, b) {} evaluate(` -let a = moduleRepo['a'] = parseModule( +let a = registerModule('a', parseModule( 'export var a = 1;' -); -let b = moduleRepo['b'] = parseModule( +)); +let b = registerModule('b', parseModule( \`import * as ns from 'a'; export var x = ns.a + ns.b;\` -); +)); b.declarationInstantiation(); let ns = getModuleEnvironmentValue(b, "ns"); assertEq(ns.a, 1); diff --git a/js/src/jit-test/tests/modules/bug1449153.js b/js/src/jit-test/tests/modules/bug1449153.js index 96c7ecfb77..234a2a4393 100644 --- a/js/src/jit-test/tests/modules/bug1449153.js +++ b/js/src/jit-test/tests/modules/bug1449153.js @@ -14,23 +14,18 @@ function assertThrowsMyError(f) assertEq(caught, true); } -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - return moduleRepo[specifier]; -}); - -moduleRepo["a"] = parseModule(` +registerModule("a", parseModule(` throw new MyError(); -`); +`)); -let c = moduleRepo["c"] = parseModule(` +let c = registerModule("c", parseModule(` import "a"; -`); +`)); c.declarationInstantiation(); assertThrowsMyError(() => c.evaluation()); -let b = moduleRepo['b'] = parseModule(` +let b = registerModule('b', parseModule(` import * as ns0 from 'a' -`); +`)); b.declarationInstantiation(); assertThrowsMyError(() => b.evaluation(b)); diff --git a/js/src/jit-test/tests/modules/bug1586599.js b/js/src/jit-test/tests/modules/bug1586599.js index 556868d04e..a38f53037f 100644 --- a/js/src/jit-test/tests/modules/bug1586599.js +++ b/js/src/jit-test/tests/modules/bug1586599.js @@ -1,5 +1,3 @@ -load(libdir + "dummyModuleResolveHook.js"); - let m1 = parseModule(` function x() { return 1; @@ -11,7 +9,8 @@ export { x, y }; `); m1.declarationInstantiation(); m1.evaluation(); -moduleRepo.m1 = m1; + +registerModule('m1', m1); let m2 = parseModule(` import {x, y} from "m1"; diff --git a/js/src/jit-test/tests/modules/debugger-frames.js b/js/src/jit-test/tests/modules/debugger-frames.js index a1701824aa..209be74242 100644 --- a/js/src/jit-test/tests/modules/debugger-frames.js +++ b/js/src/jit-test/tests/modules/debugger-frames.js @@ -57,21 +57,14 @@ dbg.onDebuggerStatement = function (frame) { f = g2.eval( ` - let moduleRepo = {}; - setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; - }); - // Set up a module to import from. - a = moduleRepo['a'] = parseModule( + a = registerModule('a', parseModule( \` export var a = 1; export let b = 2; export const c = 3; export function f(x) { return x + 1; } - \`); + \`)); a.declarationInstantiation(); a.evaluation(); diff --git a/js/src/jit-test/tests/modules/debugger-vars-function.js b/js/src/jit-test/tests/modules/debugger-vars-function.js index 3c6851970d..215953295c 100644 --- a/js/src/jit-test/tests/modules/debugger-vars-function.js +++ b/js/src/jit-test/tests/modules/debugger-vars-function.js @@ -15,13 +15,6 @@ dbg.onDebuggerStatement = function (frame) { g.eval( ` - let moduleRepo = {}; - setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; - }); - let m = parseModule( \` var a = 1; diff --git a/js/src/jit-test/tests/modules/debugger-vars-toplevel.js b/js/src/jit-test/tests/modules/debugger-vars-toplevel.js index 21e1180d21..5d657ca5a1 100644 --- a/js/src/jit-test/tests/modules/debugger-vars-toplevel.js +++ b/js/src/jit-test/tests/modules/debugger-vars-toplevel.js @@ -15,13 +15,6 @@ dbg.onDebuggerStatement = function (frame) { g.eval( ` - let moduleRepo = {}; - setModuleResolveHook(function(module, specifier) { - if (specifier in moduleRepo) - return moduleRepo[specifier]; - throw "Module '" + specifier + "' not found"; - }); - let m = parseModule( \` var a = 1; diff --git a/js/src/jit-test/tests/modules/eval-module-oom.js b/js/src/jit-test/tests/modules/eval-module-oom.js index 38868e04f8..cd693105e1 100644 --- a/js/src/jit-test/tests/modules/eval-module-oom.js +++ b/js/src/jit-test/tests/modules/eval-module-oom.js @@ -2,8 +2,6 @@ // OOM tests for module parsing. -load(libdir + "dummyModuleResolveHook.js"); - const sa = `export default 20; export let a = 22; @@ -18,8 +16,8 @@ const sb = `; oomTest(() => { - let a = moduleRepo['a'] = parseModule(sa); - let b = moduleRepo['b'] = parseModule(sb); + let a = registerModule('a', parseModule(sa)); + let b = registerModule('b', parseModule(sb)); b.declarationInstantiation(); assertEq(b.evaluation(), 42); }); diff --git a/js/src/jit-test/tests/modules/export-destructuring.js b/js/src/jit-test/tests/modules/export-destructuring.js index 5e26b9c640..115cec41a9 100644 --- a/js/src/jit-test/tests/modules/export-destructuring.js +++ b/js/src/jit-test/tests/modules/export-destructuring.js @@ -1,5 +1,3 @@ -load(libdir + "dummyModuleResolveHook.js"); - function assertArrayEq(value, expected) { assertEq(value instanceof Array, true); @@ -8,7 +6,7 @@ function assertArrayEq(value, expected) assertEq(value[i], expected[i]); } -moduleRepo['a'] = parseModule(` +registerModule('a', parseModule(` export const [] = []; export const [a=0] = []; export const [b] = [1]; @@ -19,7 +17,7 @@ moduleRepo['a'] = parseModule(` export const [...k] = [14, 15, 16]; export const [l, ...m] = [17, 18, 19]; export const [,, ...n] = [20, 21, 22]; -`); +`)); m = parseModule(` import * as a from 'a'; @@ -43,7 +41,7 @@ m = parseModule(` m.declarationInstantiation(); m.evaluation(); -moduleRepo['o'] = parseModule(` +registerModule('o', parseModule(` export const {} = {}; export const {x: a=0} = {}; export const {x: b=0} = {x: 1}; @@ -51,7 +49,7 @@ moduleRepo['o'] = parseModule(` export const {x: f} = {x: 5}; export const {g} = {}; export const {h=6} = {}; -`); +`)); m = parseModule(` import * as o from 'o'; @@ -69,7 +67,7 @@ m = parseModule(` m.declarationInstantiation(); m.evaluation(); -moduleRepo['ao'] = parseModule(` +registerModule('ao', parseModule(` export const [{x: a}, {x: b}] = [{x: 1}, {x: 2}]; export const [{c}, {d}] = [{c: 3}, {d: 4}]; export const [,, {e}, ...f] = [5, 6, {e: 7}, 8, 9]; @@ -79,7 +77,7 @@ moduleRepo['ao'] = parseModule(` export const [[], [...j], [, k, l]] = [[], [13, 14], [15, 16, 17]]; export const {x: {m, n, o=20}, y: {z: p}} = {x: {m: 18, n: 19}, y: {z: 21}}; -`); +`)); m = parseModule(` import * as ao from 'ao'; diff --git a/js/src/jit-test/tests/modules/export-ns-from.js b/js/src/jit-test/tests/modules/export-ns-from.js new file mode 100644 index 0000000000..2e79d77f42 --- /dev/null +++ b/js/src/jit-test/tests/modules/export-ns-from.js @@ -0,0 +1,10 @@ +// |jit-test| module + +import { ns } from "export-ns.js"; + +load(libdir + 'asserts.js'); + +assertEq(isProxy(ns), true); +assertEq(ns.a, 1); +assertThrowsInstanceOf(function() { eval("delete ns"); }, SyntaxError); +assertThrowsInstanceOf(function() { ns = null; }, TypeError); diff --git a/js/src/jit-test/tests/modules/import-namespace.js b/js/src/jit-test/tests/modules/import-namespace.js index 0287f7a60e..504f295707 100644 --- a/js/src/jit-test/tests/modules/import-namespace.js +++ b/js/src/jit-test/tests/modules/import-namespace.js @@ -4,7 +4,6 @@ load(libdir + "asserts.js"); load(libdir + "iteration.js"); -load(libdir + "dummyModuleResolveHook.js"); function parseAndEvaluate(source) { let m = parseModule(source); @@ -28,17 +27,17 @@ function testEqualArrays(actual, expected) { } } -let a = moduleRepo['a'] = parseModule( +let a = registerModule('a', parseModule( `// Reflection methods should return these exports alphabetically sorted. export var b = 2; export var a = 1;` -); +)); -let b = moduleRepo['b'] = parseModule( +let b = registerModule('b', parseModule( `import * as ns from 'a'; export { ns }; export var x = ns.a + ns.b;` -); +)); b.declarationInstantiation(); b.evaluation(); @@ -85,19 +84,19 @@ testEqualArrays(Object.getOwnPropertyNames(ns), ["a", "b"]); testEqualArrays(Object.getOwnPropertySymbols(ns), [Symbol.toStringTag]); // Test cyclic namespace import and access in module evaluation. -let c = moduleRepo['c'] = - parseModule("export let c = 1; import * as ns from 'd'; let d = ns.d;"); -let d = moduleRepo['d'] = - parseModule("export let d = 2; import * as ns from 'c'; let c = ns.c;"); +let c = registerModule('c', + parseModule("export let c = 1; import * as ns from 'd'; let d = ns.d;")); +let d = registerModule('d', + parseModule("export let d = 2; import * as ns from 'c'; let c = ns.c;")); c.declarationInstantiation(); d.declarationInstantiation(); assertThrowsInstanceOf(() => c.evaluation(), ReferenceError); // Test cyclic namespace import. -let e = moduleRepo['e'] = - parseModule("export let e = 1; import * as ns from 'f'; export function f() { return ns.f }"); -let f = moduleRepo['f'] = - parseModule("export let f = 2; import * as ns from 'e'; export function e() { return ns.e }"); +let e = registerModule('e', + parseModule("export let e = 1; import * as ns from 'f'; export function f() { return ns.f }")); +let f = registerModule('f', + parseModule("export let f = 2; import * as ns from 'e'; export function e() { return ns.e }")); e.declarationInstantiation(); f.declarationInstantiation(); e.evaluation(); diff --git a/js/src/jit-test/tests/modules/instanceof-error-message.js b/js/src/jit-test/tests/modules/instanceof-error-message.js new file mode 100644 index 0000000000..d78eb333b3 --- /dev/null +++ b/js/src/jit-test/tests/modules/instanceof-error-message.js @@ -0,0 +1,14 @@ +function getInstanceOfErrorMessage(x) { + try { + var result = {} instanceof x; + } + catch (e) { + return e.message; + } +} + +// Error message for a Module Namespace Exotic Object should be same as normal +// non-callable when using 'instanceof' +import('empty.js').then( + m => assertEq(getInstanceOfErrorMessage(m), + getInstanceOfErrorMessage({}))); diff --git a/js/src/jit-test/tests/modules/many-exports.js b/js/src/jit-test/tests/modules/many-exports.js index 8e32d34fc1..4ade0d957b 100644 --- a/js/src/jit-test/tests/modules/many-exports.js +++ b/js/src/jit-test/tests/modules/many-exports.js @@ -1,15 +1,13 @@ // Test many exports. -load(libdir + "dummyModuleResolveHook.js"); - const count = 1024; let s = ""; for (let i = 0; i < count; i++) s += "export let e" + i + " = " + (i * i) + ";\n"; -let a = moduleRepo['a'] = parseModule(s); +let a = registerModule('a', parseModule(s)); -let b = moduleRepo['b'] = parseModule("import * as ns from 'a'"); +let b = registerModule('b', parseModule("import * as ns from 'a'")); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/modules/many-imports.js b/js/src/jit-test/tests/modules/many-imports.js index 14ed6b8107..d8ff18d311 100644 --- a/js/src/jit-test/tests/modules/many-imports.js +++ b/js/src/jit-test/tests/modules/many-imports.js @@ -1,17 +1,15 @@ // Test importing an import many times. -load(libdir + "dummyModuleResolveHook.js"); - const count = 1024; -let a = moduleRepo['a'] = parseModule("export let a = 1;"); +let a = registerModule('a', parseModule("export let a = 1;")); let s = ""; for (let i = 0; i < count; i++) { s += "import { a as i" + i + " } from 'a';\n"; s += "assertEq(i" + i + ", 1);\n"; } -let b = moduleRepo['b'] = parseModule(s); +let b = registerModule('b', parseModule(s)); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/modules/many-namespace-imports.js b/js/src/jit-test/tests/modules/many-namespace-imports.js index bfcac8eef4..d6b23f7cd4 100644 --- a/js/src/jit-test/tests/modules/many-namespace-imports.js +++ b/js/src/jit-test/tests/modules/many-namespace-imports.js @@ -1,17 +1,15 @@ // Test importing a namespace many times. -load(libdir + "dummyModuleResolveHook.js"); - const count = 1024; -let a = moduleRepo['a'] = parseModule("export let a = 1;"); +let a = registerModule('a', parseModule("export let a = 1;")); let s = ""; for (let i = 0; i < count; i++) { s += "import * as ns" + i + " from 'a';\n"; s += "assertEq(ns" + i + ".a, 1);\n"; } -let b = moduleRepo['b'] = parseModule(s); +let b = registerModule('b', parseModule(s)); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/modules/module-declaration-instantiation.js b/js/src/jit-test/tests/modules/module-declaration-instantiation.js index de820ae5b7..8fb557d58a 100644 --- a/js/src/jit-test/tests/modules/module-declaration-instantiation.js +++ b/js/src/jit-test/tests/modules/module-declaration-instantiation.js @@ -1,7 +1,5 @@ // Exercise ModuleDeclarationInstantiation() operation. -load(libdir + "dummyModuleResolveHook.js"); - function testModuleEnvironment(module, expected) { var actual = getModuleEnvironmentNames(module).sort(); assertEq(actual.length, expected.length); @@ -15,8 +13,8 @@ let m = parseModule(""); m.declarationInstantiation(); testModuleEnvironment(m, []); -let a = moduleRepo['a'] = parseModule("var x = 1; export { x };"); -let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';"); +let a = registerModule('a', parseModule("var x = 1; export { x };")); +let b = registerModule('b', parseModule("import { x as y } from 'a';")); a.declarationInstantiation(); b.declarationInstantiation(); diff --git a/js/src/jit-test/tests/modules/module-evaluation.js b/js/src/jit-test/tests/modules/module-evaluation.js index 1b2f2c9990..dab6fa22ad 100644 --- a/js/src/jit-test/tests/modules/module-evaluation.js +++ b/js/src/jit-test/tests/modules/module-evaluation.js @@ -1,7 +1,6 @@ // Exercise ModuleEvaluation() concrete method. load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); function parseAndEvaluate(source) { let m = parseModule(source); @@ -32,11 +31,11 @@ m.evaluation(); assertEq(getModuleEnvironmentValue(m, "x"), 6); // Set up a module to import from. -let a = moduleRepo['a'] = -parseModule(`var x = 1; - export { x }; - export default 2; - export function f(x) { return x + 1; }`); +let a = registerModule('a', + parseModule(`var x = 1; + export { x }; + export default 2; + export function f(x) { return x + 1; }`)); // Check we can evaluate top level definitions. parseAndEvaluate("var foo = 1;"); @@ -79,13 +78,13 @@ m.evaluation(); assertEq(getModuleEnvironmentValue(m, "x"), 4); // Test importing an indirect export -moduleRepo['b'] = parseModule("export { x as z } from 'a';"); +registerModule('b', parseModule("export { x as z } from 'a';")); m = parseAndEvaluate("import { z } from 'b'; export { z }"); assertEq(getModuleEnvironmentValue(m, "z"), 1); // Test cyclic dependencies -moduleRepo['c1'] = parseModule("export var x = 1; export {y} from 'c2'"); -moduleRepo['c2'] = parseModule("export var y = 2; export {x} from 'c1'"); +registerModule('c1', parseModule("export var x = 1; export {y} from 'c2'")); +registerModule('c2', parseModule("export var y = 2; export {x} from 'c1'")); m = parseAndEvaluate(`import { x as x1, y as y1 } from 'c1'; import { x as x2, y as y2 } from 'c2'; export let z = [x1, y1, x2, y2]`), diff --git a/js/src/jit-test/tests/modules/off-thread-compile.js b/js/src/jit-test/tests/modules/off-thread-compile.js index 1aacf627ed..65d85fe8fe 100644 --- a/js/src/jit-test/tests/modules/off-thread-compile.js +++ b/js/src/jit-test/tests/modules/off-thread-compile.js @@ -3,7 +3,6 @@ // Test off thread module compilation. load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); function offThreadParseAndEvaluate(source) { offThreadCompileModule(source); diff --git a/js/src/jit-test/tests/parser/bug-1263881-1.js b/js/src/jit-test/tests/parser/bug-1263881-1.js index 5b9cf622c3..f105946098 100644 --- a/js/src/jit-test/tests/parser/bug-1263881-1.js +++ b/js/src/jit-test/tests/parser/bug-1263881-1.js @@ -1,8 +1,4 @@ -let moduleRepo = {}; -setModuleResolveHook(function(module, specifier) { - return moduleRepo[specifier]; -}); -moduleRepo['a'] = parseModule("export let a = 1;"); +registerModule('a', parseModule("export let a = 1;")); let s = ""; let max = 65536; for (let i = 0; i < max; i++) diff --git a/js/src/jit-test/tests/parser/bug1657557.js b/js/src/jit-test/tests/parser/bug1657557.js new file mode 100644 index 0000000000..1cb38667ed --- /dev/null +++ b/js/src/jit-test/tests/parser/bug1657557.js @@ -0,0 +1,6 @@ +setImmutablePrototype(Function.__proto__); + +if (helperThreadCount() > 0) { + offThreadCompileScript("function f() {}"); + runOffThreadScript(); +} diff --git a/js/src/jit-test/tests/parser/bug1661454.js b/js/src/jit-test/tests/parser/bug1661454.js new file mode 100644 index 0000000000..ca7792f4bc --- /dev/null +++ b/js/src/jit-test/tests/parser/bug1661454.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !('oomTest' in this) + +function oomTestEval(lfVarx) { + oomTest(() => eval(lfVarx)); +} + +oomTestEval(``); +oomTestEval(` + { + function bug1661454() { } + } +`); diff --git a/js/src/jit-test/tests/parser/dumpStencil-01.js b/js/src/jit-test/tests/parser/dumpStencil-01.js new file mode 100644 index 0000000000..54a5bd40e2 --- /dev/null +++ b/js/src/jit-test/tests/parser/dumpStencil-01.js @@ -0,0 +1,3 @@ +dumpStencil("x"); +dumpStencil("function y() {}"); +dumpStencil("export var z;", { module : true }); diff --git a/js/src/jit-test/tests/parser/redeclaration-message.js b/js/src/jit-test/tests/parser/redeclaration-message.js index 2f582328e9..29de3cf7ba 100644 --- a/js/src/jit-test/tests/parser/redeclaration-message.js +++ b/js/src/jit-test/tests/parser/redeclaration-message.js @@ -6,5 +6,5 @@ try { // We use assertEq here to catch non-throwing case. assertEq(true, false); } catch (e) { - assertEq(e.message, "can't access lexical declaration `aLet' before initialization"); + assertEq(e.message, "can't access lexical declaration 'aLet' before initialization"); } diff --git a/js/src/jit-test/tests/parser/regexp-error-location.js b/js/src/jit-test/tests/parser/regexp-error-location.js new file mode 100644 index 0000000000..4f9b11e4f5 --- /dev/null +++ b/js/src/jit-test/tests/parser/regexp-error-location.js @@ -0,0 +1,16 @@ +// Check that error location for RegExp points to the actual line/column inside +// the script instead of inside the pattern. +var line, column; +try { + eval(` + + /aaa(/; +012345678; +`); +} catch (e) { + line = e.lineNumber; + column = e.columnNumber; +} + +assertEq(line, 3); +assertEq(column, 6); diff --git a/js/src/jit-test/tests/parser/strict-with-asi-and-deprecated-octal.js b/js/src/jit-test/tests/parser/strict-with-asi-and-deprecated-octal.js new file mode 100644 index 0000000000..8ffd192820 --- /dev/null +++ b/js/src/jit-test/tests/parser/strict-with-asi-and-deprecated-octal.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError +"use strict" +010 diff --git a/js/src/jit-test/tests/realms/array-ctor.js b/js/src/jit-test/tests/realms/array-ctor.js new file mode 100644 index 0000000000..b2e0497ae5 --- /dev/null +++ b/js/src/jit-test/tests/realms/array-ctor.js @@ -0,0 +1,35 @@ +function testArrayRealm() { + var g = newGlobal(); + var A = g.Array; + for (var i = 0; i < 100; i++) { + var a; + a = new A(); + assertEq(isSameCompartment(a, g), true); + assertEq(Object.getPrototypeOf(a), A.prototype); + + a = new A(i); + assertEq(isSameCompartment(a, g), true); + assertEq(Object.getPrototypeOf(a), A.prototype); + } +} +testArrayRealm(); + +function testErrorRealm() { + var g = newGlobal(); + var A = g.Array; + for (var i = 50; i > -50; i--) { + var a = null; + var ex = null; + try { + a = new A(i); + } catch (e) { + ex = e; + } + if (i >= 0) { + assertEq(Object.getPrototypeOf(a), A.prototype); + } else { + assertEq(ex instanceof g.RangeError, true); + } + } +} +testErrorRealm(); diff --git a/js/src/jit-test/tests/realms/array-species-create.js b/js/src/jit-test/tests/realms/array-species-create.js index 4c52a04d0a..e6bfd61c97 100644 --- a/js/src/jit-test/tests/realms/array-species-create.js +++ b/js/src/jit-test/tests/realms/array-species-create.js @@ -24,8 +24,12 @@ function testIntrinsic() { var IsCrossRealmArrayConstructor = getSelfHostedValue("IsCrossRealmArrayConstructor"); for (var i = 0; i < 20; i++) { assertEq(IsCrossRealmArrayConstructor(Array), false); + assertEq(IsCrossRealmArrayConstructor(Math), false); + assertEq(IsCrossRealmArrayConstructor(() => 1), false); assertEq(IsCrossRealmArrayConstructor(g1.Array), true); assertEq(IsCrossRealmArrayConstructor(g2.Array), true); + assertEq(IsCrossRealmArrayConstructor(g1.assertEq), false); + assertEq(IsCrossRealmArrayConstructor(g2.assertEq), false); } } testIntrinsic(); diff --git a/js/src/jit-test/tests/self-hosting/getbuiltinconstructor.js b/js/src/jit-test/tests/self-hosting/getbuiltinconstructor.js deleted file mode 100644 index 57134875a5..0000000000 --- a/js/src/jit-test/tests/self-hosting/getbuiltinconstructor.js +++ /dev/null @@ -1,13 +0,0 @@ -let getCtor = getSelfHostedValue('GetBuiltinConstructor'); - -assertEq(getCtor('Array'), Array); - -let origArray = Array; -Array = function(){}; -assertEq(getCtor('Array') == Array, false); -assertEq(getCtor('Array'), origArray); - -let origMap = Map; -Map = function(){}; -assertEq(getCtor('Map') == Map, false); -assertEq(getCtor('Map'), origMap); diff --git a/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js b/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js index fd2244be21..fa90dac643 100644 --- a/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js +++ b/js/src/jit-test/tests/self-hosting/is-possibly-wrapped-typed-array.js @@ -1,3 +1,7 @@ +// |jit-test| skip-if: !isTypeInferenceEnabled() +// With trial inlining enabled, this test loops infinitely +// waiting for a trial-inlined function to be recompiled. + var IsPossiblyWrappedTypedArray = getSelfHostedValue("IsPossiblyWrappedTypedArray"); var declareSamples = ` diff --git a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js index 39466f648b..47f538b5f3 100644 --- a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js +++ b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-0.js @@ -1,3 +1,6 @@ +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + function f () { var o = {}; var x = assertRecoveredOnBailout(o, true); diff --git a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js index 7e0ce588bf..2843312f88 100644 --- a/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js +++ b/js/src/jit-test/tests/self-test/assertRecoveredOnBailout-1.js @@ -11,6 +11,9 @@ if (!opts['ion.enable'] || !opts['baseline.enable'] || crash("Cannot test assertRecoveredOnBailout"); } +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + function g() { return inIon(); } diff --git a/js/src/jit-test/tests/warp/arguments-object-load-arg.js b/js/src/jit-test/tests/warp/arguments-object-load-arg.js new file mode 100644 index 0000000000..0598c3b1d6 --- /dev/null +++ b/js/src/jit-test/tests/warp/arguments-object-load-arg.js @@ -0,0 +1,109 @@ +// Test transpiling of LoadArgumentsObjectArgResult and cover all possible bailout conditions. + +function blackhole() { + // Direct eval prevents any compile-time optimisations. + eval(""); +} + +function testConstantArgAccess() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + assertEq(arguments[0], 1); + } +} +for (var i = 0; i < 20; ++i) testConstantArgAccess(1); + +function testDynamicArgAccess() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + assertEq(arguments[i & 1], 1 + (i & 1)); + } +} +for (var i = 0; i < 20; ++i) testDynamicArgAccess(1, 2); + +function markElementOveriddenIf(args, cond, value) { + with ({}) ; // Don't Warp compile to avoid cold code bailouts. + if (cond) { + Object.defineProperty(args, 0, {value}); + } +} + +function testBailoutElementReified() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + markElementOveriddenIf(arguments, i === 25, 2); + + var expected = 1 + (i >= 25); + assertEq(arguments[0], expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutElementReified(1); + +function markLengthOveriddenIf(args, cond, value) { + with ({}) ; // Don't Warp compile to avoid cold code bailouts. + if (cond) { + args.length = value; + } +} + +function testBailoutLengthReified() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + markLengthOveriddenIf(arguments, i === 25, 0); + + assertEq(arguments[0], 1); + } +} +for (var i = 0; i < 20; ++i) testBailoutLengthReified(1); + +function deleteElementIf(args, cond) { + with ({}) ; // Don't Warp compile to avoid cold code bailouts. + if (cond) { + delete args[0]; + } +} + +function testBailoutElementDeleted() { + blackhole(arguments); // Create an arguments object. + + // Load expected values from an array to avoid possible cold code bailouts. + var values = [1, undefined]; + + for (var i = 0; i < 50; ++i) { + deleteElementIf(arguments, i === 25); + + var expected = values[0 + (i >= 25)]; + assertEq(arguments[0], expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutElementDeleted(1); + +function testBailoutOutOfBounds() { + blackhole(arguments); // Create an arguments object. + + // Load expected values from an array to avoid possible cold code bailouts. + var values = [1, undefined]; + + for (var i = 0; i < 50; ++i) { + var index = 0 + (i >= 25); + var expected = values[index]; + assertEq(arguments[index], expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutOutOfBounds(1); + +function testBailoutArgForwarded(arg1, arg2) { + blackhole(arguments); // Create an arguments object. + blackhole(() => arg2); // Ensure |arg2| is marked as "forwarded". + + for (var i = 0; i < 50; ++i) { + var index = 0 + (i >= 25); + var expected = 1 + (i >= 25); + assertEq(arguments[index], expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutArgForwarded(1, 2); diff --git a/js/src/jit-test/tests/warp/arguments-object-load-length.js b/js/src/jit-test/tests/warp/arguments-object-load-length.js new file mode 100644 index 0000000000..935c406ac0 --- /dev/null +++ b/js/src/jit-test/tests/warp/arguments-object-load-length.js @@ -0,0 +1,57 @@ +// Test transpiling of LoadArgumentsObjectLengthResult and cover all possible bailout conditions. + +function blackhole() { + // Direct eval prevents any compile-time optimisations. + eval(""); +} + +function testLengthAccess() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + assertEq(arguments.length, 1); + } +} +for (var i = 0; i < 20; ++i) testLengthAccess(1); + +function markLengthOveriddenIf(args, cond, value) { + with ({}) ; // Don't Warp compile to avoid cold code bailouts. + if (cond) { + args.length = value; + } +} + +function testBailoutLengthReified() { + blackhole(arguments); // Create an arguments object. + + for (var i = 0; i < 50; ++i) { + markLengthOveriddenIf(arguments, i === 25, 0); + + var expected = 0 + (i < 25); + assertEq(arguments.length, expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutLengthReified(1); + + +function deleteLengthIf(args, cond) { + with ({}) ; // Don't Warp compile to avoid cold code bailouts. + if (cond) { + delete args.length; + } +} + +function testBailoutLengthDeleted() { + blackhole(arguments); // Create an arguments object. + + // Load expected values from an array to avoid possible cold code bailouts. + var values = [1, undefined]; + + for (var i = 0; i < 50; ++i) { + deleteLengthIf(arguments, i === 25); + + var expected = values[0 + (i >= 25)]; + assertEq(arguments.length, expected); + } +} +for (var i = 0; i < 20; ++i) testBailoutLengthDeleted(1); diff --git a/js/src/jit-test/tests/warp/booleantostring.js b/js/src/jit-test/tests/warp/booleantostring.js new file mode 100644 index 0000000000..39ff0b1b6d --- /dev/null +++ b/js/src/jit-test/tests/warp/booleantostring.js @@ -0,0 +1,9 @@ +var a = [true, false]; +for (var i = 0; i < 1e4; i++) { + var str = "x: " + a[i & 1]; + if (i & 1) { + assertEq(str, "x: false"); + } else { + assertEq(str, "x: true"); + } +} diff --git a/js/src/jit-test/tests/warp/bug1646302.js b/js/src/jit-test/tests/warp/bug1646302.js new file mode 100644 index 0000000000..bf86fe702c --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1646302.js @@ -0,0 +1,9 @@ +function f(x) { + function fnc() {} + fnc.prototype = 3; + new fnc; + if (x < 50) { + new new.target(x + 1); + } +} +new f(0); diff --git a/js/src/jit-test/tests/warp/bug1652049.js b/js/src/jit-test/tests/warp/bug1652049.js new file mode 100644 index 0000000000..a28e35d353 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1652049.js @@ -0,0 +1,7 @@ +function f() { + var o = {__proto__: null}; + for (var i = 0; i < 15; i++) { + assertEq("foo" in o, false); + } +} +f(); diff --git a/js/src/jit-test/tests/warp/bug1652732.js b/js/src/jit-test/tests/warp/bug1652732.js new file mode 100644 index 0000000000..f5df3bc648 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1652732.js @@ -0,0 +1,8 @@ +function test() { + var obj = {}; + obj[{}] = 1; + f = () => { for (var x of obj) {} }; +} +for (var i = 0; i < 5; i++) { + test(); +} diff --git a/js/src/jit-test/tests/warp/bug1653913.js b/js/src/jit-test/tests/warp/bug1653913.js new file mode 100644 index 0000000000..adaaf3c7c8 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1653913.js @@ -0,0 +1,3 @@ +var s = "aaaaaaaaaaaa"; +var a = [, [...s]]; +assertEq(a.toString(), ",a,a,a,a,a,a,a,a,a,a,a,a"); diff --git a/js/src/jit-test/tests/warp/bug1661530.js b/js/src/jit-test/tests/warp/bug1661530.js new file mode 100644 index 0000000000..c4ea7fdb92 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1661530.js @@ -0,0 +1,7 @@ +Function.prototype.call = function() {}; +var sum = 0; +function foo() { sum++; } +for (var i = 0; i < 1000; i++) { + foo.call({}, 0); +} +assertEq(sum, 0); diff --git a/js/src/jit-test/tests/warp/bug1661728.js b/js/src/jit-test/tests/warp/bug1661728.js new file mode 100644 index 0000000000..ac4ad86552 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1661728.js @@ -0,0 +1,43 @@ +with ({}) {} // Don't inline anything into the top-level script. + +function foo() {} + +function inline_foo_into_bar() { + with ({}) {} // Don't inline anything into this function. + for (var i = 0; i < 10; i++) { + bar(2); + } + +} + +function bar(x) { + switch (x) { + case 1: + inline_foo_into_bar(); + + // Trigger a compacting gc to discard foo's jitscript. + // Do it while bar is on the stack to keep bar's jitscript alive. + gc(foo, 'shrinking'); + break; + case 2: + foo(); + break; + case 3: + break; + } +} + +// Warm up foo and bar. +for (var i = 0; i < 10; i++) { + foo(); + bar(3); +} + +// Inline and discard foo's jitscript. +bar(1); + +// Warp-compile bar +for (var i = 0; i < 50; i++) { + foo(); // ensure that foo has a new jitscript + bar(3); +} diff --git a/js/src/jit-test/tests/warp/bug1662146.js b/js/src/jit-test/tests/warp/bug1662146.js new file mode 100644 index 0000000000..cfc62b98f2 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1662146.js @@ -0,0 +1,12 @@ +var sum = 0; +function f1(a) { + try { + not_a_function(); + } catch (e) { + sum++; + } +} +for (var i = 0; i < 50; ++i) { + f1.call(); +} +assertEq(sum, 50); diff --git a/js/src/jit-test/tests/warp/bug1664007.js b/js/src/jit-test/tests/warp/bug1664007.js new file mode 100644 index 0000000000..de5d8d1233 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1664007.js @@ -0,0 +1,12 @@ +function f(depth) { + function Obj() { + this.prop = null; + this.prop = this; + } + var o = new Obj(); + assertEq(o.prop, o); + if (depth < 1000) { + f(depth + 1); + } +} +f(0); diff --git a/js/src/jit-test/tests/warp/bug1665303.js b/js/src/jit-test/tests/warp/bug1665303.js new file mode 100644 index 0000000000..b2c26e01cf --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1665303.js @@ -0,0 +1,20 @@ +// |jit-test| skip-if: !('oomTest' in this); --fast-warmup + +// Prevent slowness with --ion-eager. +setJitCompilerOption("ion.warmup.trigger", 100); + +function f() { return 1; } +function test() { + oomTest(function() { + function foo() { + for (var i = 0; i < 10; i++) { + f(); + trialInline(); + } + } + evaluate(foo.toString() + "foo()"); + }); +} +for (var i = 0; i < 3; i++) { + test(); +} diff --git a/js/src/jit-test/tests/warp/bug1666142-1.js b/js/src/jit-test/tests/warp/bug1666142-1.js new file mode 100644 index 0000000000..b5bb0aca77 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1666142-1.js @@ -0,0 +1,19 @@ +// |jit-test| --fast-warmup + +// This test triggers a GC in CreateThisForIC, +// without using the arguments rectifier. +var records = []; +function Record() { + return Object.create(null); +} +function init() { + records.push(new Record()); +} +function f() { + for (var i = 0; i < 100; i++) { + init(); + } +} + +gczeal(14,25); +f(); diff --git a/js/src/jit-test/tests/warp/bug1666142-2.js b/js/src/jit-test/tests/warp/bug1666142-2.js new file mode 100644 index 0000000000..9fa94e8f20 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1666142-2.js @@ -0,0 +1,19 @@ +// |jit-test| --fast-warmup + +// This test triggers a GC in CreateThisForIC, +// while using the arguments rectifier. +var records = []; +function Record(val) { + return Object.create(null); +} +function init() { + records.push(new Record()); +} +function f() { + for (var i = 0; i < 100; i++) { + init(); + } +} + +gczeal(14,25); +f(); diff --git a/js/src/jit-test/tests/warp/bug1667680.js b/js/src/jit-test/tests/warp/bug1667680.js new file mode 100644 index 0000000000..8e1b8c0097 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1667680.js @@ -0,0 +1,8 @@ +// |jit-test| --ion-limit-script-size=off +function f() { + var s = "for (var i = 0; i < 100; i++) {}; return 2;"; + s += "var x = [" + "9,".repeat(100_000) + "];"; + var g = Function(s); + assertEq(g(), 2); +} +f(); diff --git a/js/src/jit-test/tests/warp/bug1667685.js b/js/src/jit-test/tests/warp/bug1667685.js new file mode 100644 index 0000000000..2b9e392d24 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1667685.js @@ -0,0 +1,27 @@ +// |jit-test| skip-if: !('oomTest' in this); --fast-warmup + +// Prevent slowness with --ion-eager. +setJitCompilerOption("ion.warmup.trigger", 100); + +function h() { + return 1; +} +function g() { + for (var j = 0; j < 10; j++) { + h(); + } + trialInline(); +} +function f() { + for (var i = 0; i < 2; i++) { + var fun = Function(g.toString() + "g()"); + try { + fun(); + } catch {} + try { + fun(); + } catch {} + } + +} +oomTest(f); diff --git a/js/src/jit-test/tests/warp/bug1668197.js b/js/src/jit-test/tests/warp/bug1668197.js new file mode 100644 index 0000000000..2dcd6cb376 --- /dev/null +++ b/js/src/jit-test/tests/warp/bug1668197.js @@ -0,0 +1,6 @@ +// |jit-test| skip-if: !('oomTest' in this) +function f(x, y) { + return ~Math.hypot(x >>> 0, 2 - x >>> 0); +} +f(2, Math); +oomTest(f); diff --git a/js/src/jit-test/tests/warp/function-load-length.js b/js/src/jit-test/tests/warp/function-load-length.js new file mode 100644 index 0000000000..c3ef3552eb --- /dev/null +++ b/js/src/jit-test/tests/warp/function-load-length.js @@ -0,0 +1,86 @@ +// Test transpiling of LoadFunctionLengthResult and cover possible bailout conditions. + +function empty() {} + +// Note: Typically won't use LoadFunctionLengthResult, because the "length" +// property will be resolved on the first access. +function testGlobalFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(empty.length, 0); + } +} +testGlobalFunction(); + +// Note: Typically won't use LoadFunctionLengthResult, because the "length" +// property will be resolved on the first access. +function testInnerFunction() { + function f() {} + for (var i = 0; i < 200; ++i) { + assertEq(f.length, 0); + } +} +testInnerFunction(); + +function testPerLoopFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(function(){}.length, 0); + } +} +testPerLoopFunction(); + +// Note: Typically won't use LoadFunctionLengthResult, because the "length" +// property will be resolved on the first access. +function testNativeFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(Math.max.length, 2); + } +} +testNativeFunction(); + +// Note: Typically won't use LoadFunctionLengthResult, because the "length" +// property will be resolved on the first access. +function testSelfHostedFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(Array.prototype.forEach.length, 1); + } +} +testSelfHostedFunction(); + +// Bailout when the length doesn't fit into int32. +function testBailoutLength() { + var values = [0, 0x80000000]; + var bound = empty.bind(); + + for (var i = 0; i < 10; ++i) { + var value = values[0 + (i >= 5)]; + + // Define on each iteration to get the same shape. + Object.defineProperty(bound, "length", {value}); + + for (var j = 0; j < 100; ++j) { + var f = bound.bind(); + assertEq(f.length, value); + } + } +} +testBailoutLength(); + +// Bailout when trying to read "length" from a property with a lazy script. +function testBailoutLazyFunction() { + for (var i = 0; i < 200; ++i) { + var values = [function(){}, function(a){}]; + var index = 0 + (i >= 100); + assertEq(values[index].length, index); + } +} +testBailoutLazyFunction(); + +// Bailout when trying to read "length" from a property with a lazy self-hosted script. +function testBailoutLazySelfHostedFunction() { + for (var i = 0; i < 200; ++i) { + var values = [function(){}, Array.prototype.map]; + var index = 0 + (i >= 100); + assertEq(values[index].length, index); + } +} +testBailoutLazySelfHostedFunction(); diff --git a/js/src/jit-test/tests/warp/function-load-name.js b/js/src/jit-test/tests/warp/function-load-name.js new file mode 100644 index 0000000000..686ed32629 --- /dev/null +++ b/js/src/jit-test/tests/warp/function-load-name.js @@ -0,0 +1,100 @@ +// Test transpiling of LoadFunctionNameResult and cover possible bailout conditions. + +function empty() {} + +// Note: Typically won't use LoadFunctionNameResult, because the "name" +// property will be resolved on the first access. +function testGlobalFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(empty.name, "empty"); + } +} +testGlobalFunction(); + +// Note: Typically won't use LoadFunctionNameResult, because the "name" +// property will be resolved on the first access. +function testInnerFunction() { + function f() {} + for (var i = 0; i < 200; ++i) { + assertEq(f.name, "f"); + } +} +testInnerFunction(); + +function testPerLoopFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(function f(){}.name, "f"); + } +} +testPerLoopFunction(); + +// Note: Typically won't use LoadFunctionNameResult, because the "name" +// property will be resolved on the first access. +function testNativeFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(Math.max.name, "max"); + } +} +testNativeFunction(); + +// Note: Typically won't use LoadFunctionNameResult, because the "name" +// property will be resolved on the first access. +function testSelfHostedFunction() { + for (var i = 0; i < 200; ++i) { + assertEq(Array.prototype.forEach.name, "forEach"); + } +} +testSelfHostedFunction(); + +// Bailout when the name property is resolved. +function testBailoutResolvedName() { + function f1() {} + + // Ensure the name property of |f1| is resolved. + assertEq(f1.name, "f1"); + + var names = ["f", "f1"]; + + for (var i = 0; i < 10; ++i) { + var name = names[0 + (i >= 5)]; + + for (var j = 0; j < 100; ++j) { + var values = [function f(){}, f1]; + var value = values[0 + (i >= 5)]; + + assertEq(value.name, name); + } + } +} +testBailoutResolvedName(); + +// Bailout when the HAS_BOUND_FUNCTION_NAME_PREFIX isn't set. +function testBailoutBoundName() { + function f1() {} + function f2() {} + + var bound = f1.bind(); + + // Ensure the name property of |bound| is resolved. That way new functions + // created through |bound().bind()| will have the HAS_BOUND_FUNCTION_NAME_PREFIX + // flag set. + assertEq(bound.name, "bound f1"); + + // |bound1| and |bound2| have the same shape, but different function flags. + var bound1 = bound.bind(); // HAS_BOUND_FUNCTION_NAME_PREFIX + var bound2 = f2.bind(); // ! HAS_BOUND_FUNCTION_NAME_PREFIX + + var values = [bound1, bound2]; + var names = ["bound bound bound f1", "bound bound f2"]; + + for (var i = 0; i < 10; ++i) { + var value = values[0 + (i >= 5)]; + var name = names[0 + (i >= 5)]; + + for (var j = 0; j < 100; ++j) { + var f = value.bind(); + assertEq(f.name, name); + } + } +} +testBailoutBoundName(); diff --git a/js/src/jit-test/tests/warp/guardproto-nursery.js b/js/src/jit-test/tests/warp/guardproto-nursery.js new file mode 100644 index 0000000000..5093298e88 --- /dev/null +++ b/js/src/jit-test/tests/warp/guardproto-nursery.js @@ -0,0 +1,13 @@ +function f() { + var o = {x: 1, y: 3}; + o.__proto__ = {x: 2}; + var p = Math; + p.__proto__ = o; + p.__proto__ = {__proto__: o}; + + for (var i = 0; i < 3000; i++) { + assertEq(p.x, 1); + assertEq(p.y, 3); + } +} +f(); diff --git a/js/src/jit-test/tests/warp/non-int32-array-length.js b/js/src/jit-test/tests/warp/non-int32-array-length.js new file mode 100644 index 0000000000..4213f1991c --- /dev/null +++ b/js/src/jit-test/tests/warp/non-int32-array-length.js @@ -0,0 +1,10 @@ +function f(arr, len) { + for (var i = 0; i < 2000; i++) { + assertEq(arr.length, len); + } +} +var arr = [0]; +f(arr, 1); + +arr.length = 0xffff_ffff; +f(arr, 0xffff_ffff); diff --git a/js/src/jit-test/tests/warp/property-add-shape.js b/js/src/jit-test/tests/warp/property-add-shape.js new file mode 100644 index 0000000000..88348200bf --- /dev/null +++ b/js/src/jit-test/tests/warp/property-add-shape.js @@ -0,0 +1,98 @@ +function simple() { + var o = {a: 1}; + o.b = 2; + + assertEq(o.a, 1); + assertEq(o.b, 2); +} + +function condition1(b) { + var o = {a: 1}; + + if (b) { + o.b = 2; + } + + o.c = 3; + + assertEq(o.a, 1); + if (b) { + assertEq(o.b, 2); + } else { + assertEq('b' in o, false); + } + assertEq(o.c, 3); +} + +function condition2(b) { + var o = {a: 1}; + + if (b) { + o.b = 2; + } else { + o.b = 3; + } + + o.c = 3; + + assertEq(o.a, 1); + assertEq(o.b, b ? 2 : 3); + assertEq(o.c, 3); +} + +function condition3(b) { + var o = {a: 1}; + + if (b) { + o.b = 2; + } else { + o.b = 2; + } + + o.c = 3; + + assertEq(o.a, 1); + assertEq(o.b, 2); + assertEq(o.c, 3); +} + +function condition4(b) { + var o = {a: 1}; + + o.bla = 2; + o.bla2 = 2; + o.bla3 = 2; + o.bla4 = 2; + + if (b) { + o.b = 2; + } else { + o.c = 2; + } + + o.d = 3; + + assertEq(o.a, 1); + if (b) { + assertEq(o.b, 2); + assertEq('c' in o, false); + } else { + assertEq('b' in o, false); + assertEq(o.c, 2); + } + assertEq(o.d, 3); +} + +function f() { + for (var i = 0; i < 10; i++) { + simple(); + condition1(i % 2 == 0) + condition2(i % 2 == 0) + condition3(i % 2 == 0) + condition4(i % 2 == 0) + } +} + +for (var i = 0; i < 10; i++) { + f(); +} diff --git a/js/src/jit-test/tests/warp/super-native-newtarget.js b/js/src/jit-test/tests/warp/super-native-newtarget.js new file mode 100644 index 0000000000..3f9fb24a3a --- /dev/null +++ b/js/src/jit-test/tests/warp/super-native-newtarget.js @@ -0,0 +1,20 @@ +class A {} + +class B extends A { + constructor() { + super(); + } +} + +function h() {} +h = h.bind(); + +function f() { + for (var i = 0; i < 1000; ++i) { + var o = Reflect.construct(B, [], h); + } +} + +for (var i = 0; i < 5; ++i) { + f(); +} diff --git a/js/src/jit-test/tests/warp/typedarray-element-exists.js b/js/src/jit-test/tests/warp/typedarray-element-exists.js new file mode 100644 index 0000000000..623ad672cb --- /dev/null +++ b/js/src/jit-test/tests/warp/typedarray-element-exists.js @@ -0,0 +1,46 @@ +function inBounds() { + var ta = new Int32Array(10); + + for (var i = 0; i < 100; ++i) { + var index = i & 7; + assertEq(index in ta, true); + } +} +inBounds(); + +function outOfBounds() { + var ta = new Int32Array(10); + + for (var i = 0; i < 100; ++i) { + var index = 10 + (i & 7); + assertEq(index in ta, false); + + var largeIndex = 2147483647 - (i & 1); + assertEq(largeIndex in ta, false); + } +} +outOfBounds(); + +function negativeIndex() { + var ta = new Int32Array(10); + + for (var i = 0; i < 100; ++i) { + var index = -(1 + (i & 7)); + assertEq(index in ta, false); + + var largeIndex = -2147483647 - (i & 1); + assertEq(largeIndex in ta, false); + } +} +negativeIndex(); + +function emptyArray() { + var ta = new Int32Array(0); + + for (var i = 0; i < 100; ++i) { + var index = i & 7; + assertEq(index in ta, false); + assertEq(-index in ta, false); + } +} +emptyArray(); diff --git a/js/src/jit-test/tests/warp/typedarrayindextoint32.js b/js/src/jit-test/tests/warp/typedarrayindextoint32.js new file mode 100644 index 0000000000..5333ada53e --- /dev/null +++ b/js/src/jit-test/tests/warp/typedarrayindextoint32.js @@ -0,0 +1,10 @@ +function f(ta, i) { + var x = i + 0.2; + return ta[i] + ta[i | 0] + ta[x - 0.2]; +} + +var ta = new Int32Array(10); +var xs = [0, 1, 2, -1]; +for (var i = 0; i < 100_000; ++i) { + assertEq(f(ta, xs[i & 3]), (i & 3) == 3 ? NaN : 0); +} diff --git a/js/src/jit-test/tests/wasm/arm-hwcap-madness.js b/js/src/jit-test/tests/wasm/arm-hwcap-madness.js new file mode 100644 index 0000000000..cb3b281619 --- /dev/null +++ b/js/src/jit-test/tests/wasm/arm-hwcap-madness.js @@ -0,0 +1,31 @@ +// |jit-test| skip-if: !getBuildConfiguration().arm; test-also=--arm-hwcap=armv7,vfp + +// The command line options disable the idiv instruction and thus make the +// baseline compiler unavailable, so we must be prepared for a run-time error +// below in the baseline-only configuration. + +// The flags above should be sufficient for there to be a WebAssembly object. +assertEq(typeof WebAssembly, "object"); + +try { + var i = new WebAssembly.Instance( + new WebAssembly.Module( + wasmTextToBinary('(module (func (export "") (result i32) (i32.const 42)))'))); + assertEq(i.exports[""](), 42); +} catch (e) { + if (String(e).match(/no WebAssembly compiler available/)) { + switch (wasmCompileMode()) { + case "none": + // This is fine: the limited feature set combined with command line + // compiler selection caused all compilers to be disabled. + break; + default: + // This is not fine: if there's a compiler available then we should + // not get an error. + throw e; + } + } else { + // Some other error, propagate it. + throw e; + } +} diff --git a/js/src/jit-test/tests/wasm/atomic.js b/js/src/jit-test/tests/wasm/atomic.js index 7f0b64d850..c4533f2867 100644 --- a/js/src/jit-test/tests/wasm/atomic.js +++ b/js/src/jit-test/tests/wasm/atomic.js @@ -4,85 +4,92 @@ const oob = /index out of bounds/; const unaligned = /unaligned memory access/; const RuntimeError = WebAssembly.RuntimeError; -// Check that the output of wasmTextToBinary verifies correctly. +function valText(text) { + return WebAssembly.validate(wasmTextToBinary(text)); +} -let SHARED = 'shared'; -let UNSHARED = ''; -let sharedError = 'memory with atomic operations without shared memory'; +function assertNum(a, b) { + if (typeof a == "number" && typeof b == "number") + assertEq(a, b); + else if (typeof a == "number") { + assertEq(a, b.low); + assertEq(0, b.high); + } else if (typeof b == "number") { + assertEq(a.low, b); + assertEq(a.high, 0); + } else { + assertEq(a.high, b.high); + assertEq(a.low, b.low); + } +} -for (let [type,width,view] of [['i32','8', '_u'],['i32','16','_u'],['i32','',''],['i64','8','_u'],['i64','16','_u'],['i64','32','_u'],['i64','','']]) { - { - let text = (shared) => `(module (memory 1 1 ${shared}) +// Check that the output of wasmTextToBinary verifies correctly. + +for ( let shared of ['shared', ''] ) { + for (let [type,width,view] of [['i32','8', '_u'],['i32','16','_u'],['i32','',''],['i64','8','_u'],['i64','16','_u'],['i64','32','_u'],['i64','','']]) { + { + let text = (shared) => `(module (memory 1 1 ${shared}) (func (result ${type}) (${type}.atomic.load${width}${view} (i32.const 0))) (export "" (func 0)))`; - assertEq(valText(text(SHARED)), true); - assertEq(valText(text(UNSHARED)), false); - } + assertEq(valText(text(shared)), true); + } - { - let text = (shared) => `(module (memory 1 1 ${shared}) + { + let text = (shared) => `(module (memory 1 1 ${shared}) (func (${type}.atomic.store${width} (i32.const 0) (${type}.const 1))) (export "" (func 0)))`; - assertEq(valText(text(SHARED)), true); - assertEq(valText(text(UNSHARED)), false); - } + assertEq(valText(text(shared)), true); + } - { - let text = (shared) => `(module (memory 1 1 ${shared}) + { + let text = (shared) => `(module (memory 1 1 ${shared}) (func (result ${type}) (${type}.atomic.rmw${width}.cmpxchg${view} (i32.const 0) (${type}.const 1) (${type}.const 2))) (export "" (func 0)))`; - assertEq(valText(text(SHARED)), true); - assertEq(valText(text(UNSHARED)), false); - } + assertEq(valText(text(shared)), true); + } - for (let op of ['add','and','or','sub','xor','xchg']) { - // Operate with appropriately-typed value 1 on address 0 - let text = (shared) => `(module (memory 1 1 ${shared}) + for (let op of ['add','and','or','sub','xor','xchg']) { + // Operate with appropriately-typed value 1 on address 0 + let text = (shared) => `(module (memory 1 1 ${shared}) (func (result ${type}) (${type}.atomic.rmw${width}.${op}${view} (i32.const 0) (${type}.const 1))) (export "" (func 0)))`; - assertEq(valText(text(SHARED)), true); - assertEq(valText(text(UNSHARED)), false); + assertEq(valText(text(shared)), true); + } } -} -for (let type of ['i32', 'i64']) { - let text = (shared) => `(module (memory 1 1 ${shared}) + for (let type of ['i32', 'i64']) { + let text = (shared) => `(module (memory 1 1 ${shared}) (func (result i32) (${type}.atomic.wait (i32.const 0) (${type}.const 1) (i64.const -1))) (export "" (func 0)))`; - assertEq(valText(text(SHARED)), true); - assertEq(valText(text(UNSHARED)), false); -} + assertEq(valText(text(shared)), true); + } -let text = (shared) => `(module (memory 1 1 ${shared}) + let text = (shared) => `(module (memory 1 1 ${shared}) (func (result i32) (atomic.notify (i32.const 0) (i32.const 1))) (export "" (func 0)))`; -assertEq(valText(text(SHARED)), true); -assertEq(valText(text(UNSHARED)), false); + assertEq(valText(text(shared)), true); -// Required explicit alignment for WAIT is the size of the datum + // Required explicit alignment for WAIT is the size of the datum -for (let [type,align,good] of [['i32',1,false],['i32',2,false],['i32',4,true],['i32',8,false], - ['i64',1,false],['i64',2,false],['i64',4,false],['i64',8,true]]) -{ - let text = `(module (memory 1 1 shared) + for (let [type,align,good] of [['i32',1,false],['i32',2,false],['i32',4,true],['i32',8,false], + ['i64',1,false],['i64',2,false],['i64',4,false],['i64',8,true]]) + { + let text = `(module (memory 1 1 shared) (func (result i32) (${type}.atomic.wait align=${align} (i32.const 0) (${type}.const 1) (i64.const -1))) (export "" (func 0)))`; - assertEq(valText(text), good); -} + assertEq(valText(text), good); + } -// Required explicit alignment for NOTIFY is 4 + // Required explicit alignment for NOTIFY is 4 -for (let align of [1, 2, 4, 8]) { - let text = `(module (memory 1 1 shared) + for (let align of [1, 2, 4, 8]) { + let text = `(module (memory 1 1 shared) (func (result i32) (atomic.notify align=${align} (i32.const 0) (i32.const 1))) (export "" (func 0)))`; - assertEq(valText(text), align == 4); -} - -function valText(text) { - return WebAssembly.validate(wasmTextToBinary(text)); + assertEq(valText(text), align == 4); + } } // Test that atomic operations work. @@ -163,309 +170,299 @@ function widen(TA, value, complement = true) { // both. Also, there may be different paths for constant addresses/operands and // variable ditto, so test as many combinations as possible. -var RMWOperation = -{ - loadStoreModule(type, width, view, address, operand) { - let bin = wasmTextToBinary( - `(module - (memory (import "" "memory") 1 1 shared) +for ( let shared of ['shared',''] ) { + let RMWOperation = { + loadStoreModule(type, width, view, address, operand) { + let bin = wasmTextToBinary( + `(module + (memory (import "" "memory") 1 1 ${shared}) (func (export "st") (param i32) (${type}.atomic.store${width} ${address} ${operand})) (func $ld (param i32) (result ${type}) (${type}.atomic.load${width}${view} ${address})) (func (export "ld") (param i32) (result i32) (${type}.eq (call $ld (local.get 0)) ${operand})))`); - let mod = new WebAssembly.Module(bin); - let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true}); - let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); - return [mem, ins.exports.ld, ins.exports.st]; - }, - - opModuleEffect(type, width, view, address, op, operand, ignored) { - let bin = wasmTextToBinary( - `(module - (memory (import "" "memory") 1 1 shared) + let mod = new WebAssembly.Module(bin); + let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared}); + let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); + return [mem, ins.exports.ld, ins.exports.st]; + }, + + opModuleEffect(type, width, view, address, op, operand, ignored) { + let bin = wasmTextToBinary( + `(module + (memory (import "" "memory") 1 1 ${shared}) (func (export "f") (param i32) (result i32) (drop (${type}.atomic.rmw${width}.${op}${view} ${address} ${operand})) (i32.const 1)))`); - let mod = new WebAssembly.Module(bin); - let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true}); - let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); - return [mem, ins.exports.f]; - }, - - opModuleReturned(type, width, view, address, op, operand, expected) { - let bin = wasmTextToBinary( - `(module - (memory (import "" "memory") 1 1 shared) + let mod = new WebAssembly.Module(bin); + let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared}); + let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); + return [mem, ins.exports.f]; + }, + + opModuleReturned(type, width, view, address, op, operand, expected) { + let bin = wasmTextToBinary( + `(module + (memory (import "" "memory") 1 1 ${shared}) (func $_f (param i32) (result ${type}) (${type}.atomic.rmw${width}.${op}${view} ${address} ${operand})) (func (export "f") (param i32) (result i32) (${type}.eq (call $_f (local.get 0)) (${type}.const ${expected}))))`); - let mod = new WebAssembly.Module(bin); - let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true}); - let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); - return [mem, ins.exports.f]; - }, - - cmpxchgModuleEffect(type, width, view, address, operand1, operand2, ignored) { - let bin = wasmTextToBinary( - `(module - (memory (import "" "memory") 1 1 shared) + let mod = new WebAssembly.Module(bin); + let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared}); + let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); + return [mem, ins.exports.f]; + }, + + cmpxchgModuleEffect(type, width, view, address, operand1, operand2, ignored) { + let bin = wasmTextToBinary( + `(module + (memory (import "" "memory") 1 1 ${shared}) (func (export "f") (param i32) (drop (${type}.atomic.rmw${width}.cmpxchg${view} ${address} ${operand1} ${operand2}))))`); - let mod = new WebAssembly.Module(bin); - let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true}); - let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); - return [mem, ins.exports.f]; - }, - - cmpxchgModuleReturned(type, width, view, address, operand1, operand2, expected) { - let bin = wasmTextToBinary( - `(module - (memory (import "" "memory") 1 1 shared) + let mod = new WebAssembly.Module(bin); + let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared}); + let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); + return [mem, ins.exports.f]; + }, + + cmpxchgModuleReturned(type, width, view, address, operand1, operand2, expected) { + let bin = wasmTextToBinary( + `(module + (memory (import "" "memory") 1 1 ${shared}) (func $_f (param i32) (result ${type}) (${type}.atomic.rmw${width}.cmpxchg${view} ${address} ${operand1} ${operand2})) (func (export "f") (param i32) (result i32) (${type}.eq (call $_f (local.get 0)) (${type}.const ${expected}))))`); - let mod = new WebAssembly.Module(bin); - let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true}); - let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); - return [mem, ins.exports.f]; - }, - - assertZero(array, LOC) { - for ( let i=0 ; i < 100 ; i++ ) { - if (i != LOC) - assertNum(array.read(i), 0); - } - }, - - run() { - const LOC = 13; // The cell we operate on - const OPD1 = 37; // Sometimes we'll put an operand here - const OPD2 = 42; // Sometimes we'll put another operand here - - for ( let [type, variations] of + let mod = new WebAssembly.Module(bin); + let mem = new WebAssembly.Memory({initial: 1, maximum: 1, shared}); + let ins = new WebAssembly.Instance(mod, {"": {memory: mem}}); + return [mem, ins.exports.f]; + }, + + assertZero(array, LOC) { + for ( let i=0 ; i < 100 ; i++ ) { + if (i != LOC) + assertNum(array.read(i), 0); + } + }, + + run() { + const LOC = 13; // The cell we operate on + const OPD1 = 37; // Sometimes we'll put an operand here + const OPD2 = 42; // Sometimes we'll put another operand here + + for ( let [type, variations] of [["i32", [[Uint8Array,"8", "_u"], [Uint16Array,"16", "_u"], [Uint32Array,"",""]]], ["i64", [[Uint8Array,"8","_u"], [Uint16Array,"16","_u"], [Uint32Array,"32","_u"], [Uint64Array,"",""]]]] ) - { - for ( let [TA, width, view] of variations ) { - for ( let addr of [`(i32.const ${LOC * TA.BYTES_PER_ELEMENT})`, - `(local.get 0)`] ) - { - for ( let [initial, operand] of [[0x12, 0x37]] ) - { - let [opd_str, opd_num] = widen(TA, operand); - for ( let rhs of [`(${type}.const ${opd_str})`, - `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) - { - let [mem, ld, st] = this.loadStoreModule(type, width, view, addr, rhs); - let array = new TA(mem.buffer); - array.write(OPD1, opd_num); - array.write(LOC, initial); - st(LOC * TA.BYTES_PER_ELEMENT); - let res = ld(LOC * TA.BYTES_PER_ELEMENT); - assertEq(res, 1); - assertNum(array.read(LOC), opd_num); - array.write(OPD1, 0); - this.assertZero(array, LOC); - } - } - - for ( let [op, initial, operand, expected] of [["add", 37, 5, 42], - ["sub", 42, 5, 37], - ["and", 0x45, 0x13, 0x01], - ["or", 0x45, 0x13, 0x57], - ["xor", 0x45, 0x13, 0x56], - ["xchg", 0x45, 0x13, 0x13]] ) + for ( let [TA, width, view] of variations ) + { + for ( let addr of [`(i32.const ${LOC * TA.BYTES_PER_ELEMENT})`, + `(local.get 0)`] ) { - let complement = op == "xchg"; - let [ini_str, ini_num] = widen(TA, initial, complement); - let [opd_str, opd_num] = widen(TA, operand, complement); - let [exp_str, exp_num] = widen(TA, expected, complement); - for ( let rhs of [`(${type}.const ${opd_str})`, - `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) - { - for ( let [generateIt, checkIt] of [["opModuleEffect", false], ["opModuleReturned", true]] ) + for ( let [initial, operand] of [[0x12, 0x37]] ) + { + let [opd_str, opd_num] = widen(TA, operand); + for ( let rhs of [`(${type}.const ${opd_str})`, + `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) { - let [mem, f] = this[generateIt](type, width, view, addr, op, rhs, ini_str); - let array = new TA(mem.buffer); - array.write(OPD1, opd_num); - array.write(LOC, ini_num); - let res = f(LOC * TA.BYTES_PER_ELEMENT); - if (checkIt) - assertEq(res, 1); - assertNum(array.read(LOC), exp_num); - array.write(OPD1, 0); - this.assertZero(array, LOC); + let [mem, ld, st] = this.loadStoreModule(type, width, view, addr, rhs); + let array = new TA(mem.buffer); + array.write(OPD1, opd_num); + array.write(LOC, initial); + st(LOC * TA.BYTES_PER_ELEMENT); + let res = ld(LOC * TA.BYTES_PER_ELEMENT); + assertEq(res, 1); + assertNum(array.read(LOC), opd_num); + array.write(OPD1, 0); + this.assertZero(array, LOC); } - } - } - - for ( let [initial, operand1, operand2, expected] of [[33, 33, 44, 44], [33, 44, 55, 33]] ) - { - let [ini_str, ini_num] = widen(TA, initial); - let [opd1_str, opd1_num] = widen(TA, operand1); - let [opd2_str, opd2_num] = widen(TA, operand2); - let [exp_str, exp_num] = widen(TA, expected); - for ( let op1 of [`(${type}.const ${opd1_str})`, - `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) - { - for ( let op2 of [`(${type}.const ${opd2_str})`, - `(${type}.load${width}${view} (i32.const ${OPD2 * TA.BYTES_PER_ELEMENT}))`] ) + } + + for ( let [op, initial, operand, expected] of [["add", 37, 5, 42], + ["sub", 42, 5, 37], + ["and", 0x45, 0x13, 0x01], + ["or", 0x45, 0x13, 0x57], + ["xor", 0x45, 0x13, 0x56], + ["xchg", 0x45, 0x13, 0x13]] ) + { + let complement = op == "xchg"; + let [ini_str, ini_num] = widen(TA, initial, complement); + let [opd_str, opd_num] = widen(TA, operand, complement); + let [exp_str, exp_num] = widen(TA, expected, complement); + for ( let rhs of [`(${type}.const ${opd_str})`, + `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) { - for ( let [generateIt, checkIt] of [["cmpxchgModuleEffect", false], ["cmpxchgModuleReturned", true]] ) - { - let [mem, f] = this[generateIt](type, width, view, addr, op1, op2, ini_str); + for ( let [generateIt, checkIt] of [["opModuleEffect", false], ["opModuleReturned", true]] ) + { + let [mem, f] = this[generateIt](type, width, view, addr, op, rhs, ini_str); let array = new TA(mem.buffer); - array.write(OPD1, opd1_num); - array.write(OPD2, opd2_num); + array.write(OPD1, opd_num); array.write(LOC, ini_num); let res = f(LOC * TA.BYTES_PER_ELEMENT); if (checkIt) - assertEq(res, 1); - assertNum(array.read(13), exp_num); + assertEq(res, 1); + assertNum(array.read(LOC), exp_num); array.write(OPD1, 0); - array.write(OPD2, 0); this.assertZero(array, LOC); - } + } + } + } + + for ( let [initial, operand1, operand2, expected] of [[33, 33, 44, 44], [33, 44, 55, 33]] ) + { + let [ini_str, ini_num] = widen(TA, initial); + let [opd1_str, opd1_num] = widen(TA, operand1); + let [opd2_str, opd2_num] = widen(TA, operand2); + let [exp_str, exp_num] = widen(TA, expected); + for ( let op1 of [`(${type}.const ${opd1_str})`, + `(${type}.load${width}${view} (i32.const ${OPD1 * TA.BYTES_PER_ELEMENT}))`] ) + { + for ( let op2 of [`(${type}.const ${opd2_str})`, + `(${type}.load${width}${view} (i32.const ${OPD2 * TA.BYTES_PER_ELEMENT}))`] ) + { + for ( let [generateIt, checkIt] of [["cmpxchgModuleEffect", false], ["cmpxchgModuleReturned", true]] ) + { + let [mem, f] = this[generateIt](type, width, view, addr, op1, op2, ini_str); + let array = new TA(mem.buffer); + array.write(OPD1, opd1_num); + array.write(OPD2, opd2_num); + array.write(LOC, ini_num); + let res = f(LOC * TA.BYTES_PER_ELEMENT); + if (checkIt) + assertEq(res, 1); + assertNum(array.read(13), exp_num); + array.write(OPD1, 0); + array.write(OPD2, 0); + this.assertZero(array, LOC); + } + } } - } + } } - } + } } - } - } -}; - -RMWOperation.run(); + } + }; -function assertNum(a, b) { - if (typeof a == "number" && typeof b == "number") - assertEq(a, b); - else if (typeof a == "number") { - assertEq(a, b.low); - assertEq(0, b.high); - } else if (typeof b == "number") { - assertEq(a.low, b); - assertEq(a.high, 0); - } else { - assertEq(a.high, b.high); - assertEq(a.low, b.low); - } + RMWOperation.run(); } // Test bounds and alignment checking on atomic ops -var BoundsAndAlignment = -{ - loadModule(type, view, width, offset) { - return wasmEvalText( - `(module - (memory 1 1 shared) +for ( let shared of ['shared',''] ) { + var BoundsAndAlignment = { + loadModule(type, view, width, offset) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func $0 (param i32) (result ${type}) (${type}.atomic.load${width}${view} offset=${offset} (local.get 0))) (func (export "f") (param i32) (drop (call $0 (local.get 0))))) `).exports.f; - }, + }, - loadModuleIgnored(type, view, width, offset) { - return wasmEvalText( - `(module - (memory 1 1 shared) + loadModuleIgnored(type, view, width, offset) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func (export "f") (param i32) (drop (${type}.atomic.load${width}${view} offset=${offset} (local.get 0))))) `).exports.f; - }, + }, - storeModule(type, view, width, offset) { - return wasmEvalText( - `(module - (memory 1 1 shared) + storeModule(type, view, width, offset) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func (export "f") (param i32) (${type}.atomic.store${width} offset=${offset} (local.get 0) (${type}.const 37)))) `).exports.f; - }, + }, - opModule(type, view, width, offset, op) { - return wasmEvalText( - `(module - (memory 1 1 shared) + opModule(type, view, width, offset, op) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func $0 (param i32) (result ${type}) (${type}.atomic.rmw${width}.${op}${view} offset=${offset} (local.get 0) (${type}.const 37))) (func (export "f") (param i32) (drop (call $0 (local.get 0))))) `).exports.f; - }, + }, - opModuleForEffect(type, view, width, offset, op) { - return wasmEvalText( - `(module - (memory 1 1 shared) + opModuleForEffect(type, view, width, offset, op) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func (export "f") (param i32) (drop (${type}.atomic.rmw${width}.${op}${view} offset=${offset} (local.get 0) (${type}.const 37))))) `).exports.f; - }, + }, - cmpxchgModule(type, view, width, offset) { - return wasmEvalText( - `(module - (memory 1 1 shared) + cmpxchgModule(type, view, width, offset) { + return wasmEvalText( + `(module + (memory 1 1 ${shared}) (func $0 (param i32) (result ${type}) (${type}.atomic.rmw${width}.cmpxchg${view} offset=${offset} (local.get 0) (${type}.const 37) (${type}.const 42))) (func (export "f") (param i32) (drop (call $0 (local.get 0))))) `).exports.f; - }, + }, - run() { - for ( let [type, variations] of [["i32", [["8","_u", 1], ["16","_u", 2], ["","", 4]]], - ["i64", [["8","_u",1], ["16","_u",2], ["32","_u",4], ["","",8]]]] ) - { - for ( let [width,view,size] of variations ) + run() { + for ( let [type, variations] of [["i32", [["8","_u", 1], ["16","_u", 2], ["","", 4]]], + ["i64", [["8","_u",1], ["16","_u",2], ["32","_u",4], ["","",8]]]] ) { - // Aligned but out-of-bounds - let addrs = [[65536, 0, oob], [65536*2, 0, oob], [65532, 4, oob], - [65533, 3, oob], [65534, 2, oob], [65535, 1, oob]]; - if (type == "i64") - addrs.push([65536-8, 8, oob]); - - // In-bounds but unaligned - for ( let i=1 ; i < size ; i++ ) - addrs.push([65520, i, unaligned]); - - // Both out-of-bounds and unaligned. The spec leaves it unspecified - // whether we see the OOB message or the unaligned message (they are - // both "traps"). In Firefox, the unaligned check comes first. - for ( let i=1 ; i < size ; i++ ) - addrs.push([65536, i, unaligned]); - - // GC to prevent TSan builds from running out of memory. - gc(); - - for ( let [ base, offset, re ] of addrs ) - { - assertErrorMessage(() => this.loadModule(type, view, width, offset)(base), RuntimeError, re); - assertErrorMessage(() => this.loadModuleIgnored(type, view, width, offset)(base), RuntimeError, re); - assertErrorMessage(() => this.storeModule(type, view, width, offset)(base), RuntimeError, re); - for ( let op of [ "add", "sub", "and", "or", "xor", "xchg" ]) { - assertErrorMessage(() => this.opModule(type, view, width, offset, op)(base), RuntimeError, re); - assertErrorMessage(() => this.opModuleForEffect(type, view, width, offset, op)(base), RuntimeError, re); + for ( let [width,view,size] of variations ) + { + // Aligned but out-of-bounds + let addrs = [[65536, 0, oob], [65536*2, 0, oob], [65532, 4, oob], + [65533, 3, oob], [65534, 2, oob], [65535, 1, oob]]; + if (type == "i64") + addrs.push([65536-8, 8, oob]); + + // In-bounds but unaligned + for ( let i=1 ; i < size ; i++ ) + addrs.push([65520, i, unaligned]); + + // Both out-of-bounds and unaligned. The spec leaves it unspecified + // whether we see the OOB message or the unaligned message (they are + // both "traps"). In Firefox, the unaligned check comes first. + for ( let i=1 ; i < size ; i++ ) + addrs.push([65536, i, unaligned]); + + // GC to prevent TSan builds from running out of memory. + gc(); + + for ( let [ base, offset, re ] of addrs ) + { + assertErrorMessage(() => this.loadModule(type, view, width, offset)(base), RuntimeError, re); + assertErrorMessage(() => this.loadModuleIgnored(type, view, width, offset)(base), RuntimeError, re); + assertErrorMessage(() => this.storeModule(type, view, width, offset)(base), RuntimeError, re); + for ( let op of [ "add", "sub", "and", "or", "xor", "xchg" ]) { + assertErrorMessage(() => this.opModule(type, view, width, offset, op)(base), RuntimeError, re); + assertErrorMessage(() => this.opModuleForEffect(type, view, width, offset, op)(base), RuntimeError, re); + } + assertErrorMessage(() => this.cmpxchgModule(type, view, width, offset)(base), RuntimeError, re); } - assertErrorMessage(() => this.cmpxchgModule(type, view, width, offset)(base), RuntimeError, re); - } + } } - } + } } -} -BoundsAndAlignment.run(); + BoundsAndAlignment.run(); +} // Bounds and alignment checks on wait and notify +// For 'wait', we check bounds and alignment after sharedness, so the memory +// must be shared always. + assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 shared) (func (param i32) (result i32) (i32.atomic.wait (local.get 0) (i32.const 1) (i64.const -1))) @@ -490,20 +487,41 @@ assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 shared) (export "" (func 0)))`).exports[""](65501), RuntimeError, unaligned); -assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 shared) +// For 'notify', we check bounds and alignment before returning 0 in the case of +// non-shared memory, so both shared and non-shared memories must be checked. + +for ( let shared of ['shared',''] ) { + assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 ${shared}) (func (param i32) (result i32) (atomic.notify (local.get 0) (i32.const 1))) (export "" (func 0)))`).exports[""](65536), RuntimeError, oob); -// Minimum run-time alignment for NOTIFY is 4 -for (let addr of [1,2,3,5,6,7]) { - assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 shared) + // Minimum run-time alignment for NOTIFY is 4 + for (let addr of [1,2,3,5,6,7]) { + assertErrorMessage(() => wasmEvalText(`(module (memory 1 1 ${shared}) (func (export "f") (param i32) (result i32) (atomic.notify (local.get 0) (i32.const 1))))`).exports.f(addr), - RuntimeError, unaligned); + RuntimeError, unaligned); + } } +// Sharedness check for wait + +assertErrorMessage(() => wasmEvalText(`(module (memory 1 1) + (func (param i32) (result i32) + (i32.atomic.wait (local.get 0) (i32.const 1) (i64.const -1))) + (export "" (func 0)))`).exports[""](0), + RuntimeError, /atomic wait on non-shared memory/); + +// Ensure that notify works on non-shared memories and returns zero. + +assertEq(wasmEvalText(` +(module (memory 1 1) + (func (export "f") (param i32) (result i32) + (atomic.notify (local.get 0) (i32.const 1)))) +`).exports.f(256), 0); + // Ensure alias analysis works even if atomic and non-atomic accesses are // mixed. assertErrorMessage(() => wasmEvalText(`(module diff --git a/js/src/jit-test/tests/wasm/basic.js b/js/src/jit-test/tests/wasm/basic.js index 2b3d8e68d0..8d1166f6b4 100644 --- a/js/src/jit-test/tests/wasm/basic.js +++ b/js/src/jit-test/tests/wasm/basic.js @@ -119,18 +119,6 @@ wasmEvalText('(module (import "a" "" (func $foo (result f64))))', {a:{"":()=>{}} wasmValidateText('(module (memory 0))'); wasmValidateText('(module (memory 1))'); -wasmValidateText('(module (memory 16384))'); -wasmFailValidateText('(module (memory 16385))', /initial memory size too big/); - -wasmEvalText('(module (memory 0 65536))') -wasmFailValidateText('(module (memory 0 65537))', /maximum memory size too big/); - -// May OOM, but must not crash: -try { - wasmEvalText('(module (memory 16384))'); -} catch (e) { - assertEq(String(e).indexOf("out of memory") !== -1, true); -} var buf = wasmEvalText('(module (memory 1) (export "memory" (memory 0)))').exports.memory.buffer; assertEq(buf instanceof ArrayBuffer, true); diff --git a/js/src/jit-test/tests/wasm/bench/wasm_box2d.js b/js/src/jit-test/tests/wasm/bench/wasm_box2d.js index 968a78536e..9a2cb851be 100644 --- a/js/src/jit-test/tests/wasm/bench/wasm_box2d.js +++ b/js/src/jit-test/tests/wasm/bench/wasm_box2d.js @@ -3049,7 +3049,9 @@ drainJobQueue(); const bytecode = os.file.readFile(scriptdir + 'wasm_box2d.wasm', 'binary'); -setBufferStreamParams(/* delayMillis = */ 1, /* chunkSize = */ 1000); +if (typeof setBufferStreamParams == 'function') { + setBufferStreamParams(/* delayMillis = */ 1, /* chunkSize = */ 1000); +} const cacheEntry = streamCacheEntry(bytecode); runBox2d(cacheEntry); diff --git a/js/src/jit-test/tests/wasm/bigint/bigint.js b/js/src/jit-test/tests/wasm/bigint/bigint.js index 6ef492d481..79e7e416b1 100644 --- a/js/src/jit-test/tests/wasm/bigint/bigint.js +++ b/js/src/jit-test/tests/wasm/bigint/bigint.js @@ -37,6 +37,10 @@ function testId() { assertEq(f(2n ** 63n, 1n), -(2n ** 63n)); assertEq(f(2n ** 64n + 123n, 1n), 123n); assertEq(f("5", 1n), 5n); + assertEq(f(true, 1n), 1n); + assertEq(f(false, 1n), 0n); + assertEq(f({ toString() { return "5"; }, }, 1n), 5n); + assertEq(f({ valueOf() { return 5n; }, }, 1n), 5n); assertEq(f2(1n, 0n), 0n); assertEq(f2(1n, -0n), -0n); @@ -45,12 +49,44 @@ function testId() { assertEq(f2(1n, 2n ** 63n), -(2n ** 63n)); assertEq(f2(1n, 2n ** 64n + 123n), 123n); assertEq(f2(1n, "5"), 5n); - - assertErrorMessage(() => f(5, 1n), TypeError, "can't convert 5 to BigInt"); - assertErrorMessage(() => f2(1n, 5), TypeError, "can't convert 5 to BigInt"); + assertEq(f2(1n, true), 1n); + assertEq(f2(1n, false), 0n); + assertEq(f2(1n, { toString() { return "5"; }, }), 5n); + assertEq(f2(1n, { valueOf() { return 5n; }, }), 5n); }); } +function testNonBigIntArgs() { + var f = wasmEvalText(`(module + (func (export "f") (param i64) (result i64) + (local.get 0) + ) + )`).exports.f; + + assertErrorMessage(() => f(5), TypeError, "can't convert 5 to BigInt"); + assertErrorMessage(() => f({ valueOf() { return 5; }, }), + TypeError, + "can't convert 5 to BigInt"); + assertErrorMessage(() => f(5.3), TypeError, "can't convert 5.3 to BigInt"); + assertErrorMessage(() => f(), TypeError, "can't convert undefined to BigInt"); + assertErrorMessage( + () => f(undefined), + TypeError, + "can't convert undefined to BigInt" + ); + assertErrorMessage(() => f(null), TypeError, "can't convert null to BigInt"); + assertErrorMessage( + () => f(Symbol("foo")), + TypeError, + 'can\'t convert Symbol("foo") to BigInt' + ); + assertErrorMessage(() => f({}), SyntaxError, "invalid BigInt syntax"); + assertErrorMessage(() => f({ valueof() { return "foo"; }, }), + SyntaxError, + "invalid BigInt syntax"); + assertErrorMessage(() => f("x"), SyntaxError, "invalid BigInt syntax"); +} + function testIdPlus() { var f = wasmEvalText(`(module (func (export "f") (param i64) (result i64) @@ -66,9 +102,32 @@ function testIdPlus() { }); } -// Test functions with many parameters to stress ABI cases. +// Test functions with many parameters to stress ABI cases. We want to test +// spilled arguments both under and over the Ion call inlining limit. function testManyArgs() { - var f = wasmEvalText(`(module + var f1 = wasmEvalText(`(module + (func (export "f") + (param i64 i64 i64 i64 i64 i64 i64 i64) + (result i64) + (get_local 0) + (get_local 1) + (get_local 2) + (get_local 3) + (get_local 4) + (get_local 5) + (get_local 6) + (get_local 7) + (i64.add) + (i64.add) + (i64.add) + (i64.add) + (i64.add) + (i64.add) + (i64.add) + ) + )`).exports.f; + + var f2 = wasmEvalText(`(module (func (export "f") (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) (result i64) @@ -103,7 +162,8 @@ function testManyArgs() { )`).exports.f; testWithJit(() => { - assertEq(f(1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n), 14n); + assertEq(f1(1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n), 8n); + assertEq(f2(1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n, 1n), 14n); }); } @@ -206,13 +266,13 @@ function testGlobalImport() { (export "b" (global $b)) (export "c" (global $c)) )`, - { g: { a: 1n, b: 2n ** 63n, c: "123" } } + { g: { a: 1n, b: 2n ** 63n, c: -100n } } ).exports; testWithJit(() => { assertEq(exports.a.value, 1n); assertEq(exports.b.value, -(2n ** 63n)); - assertEq(exports.c.value, 123n); + assertEq(exports.c.value, -100n); }); } @@ -276,14 +336,13 @@ function testGlobalBadImportLiteral() { )`, { g: { a: "foo" } } ), - SyntaxError, - "invalid BigInt syntax" + WebAssembly.LinkError, + "import object field 'a' is not a BigInt" ); } -// This exercises error code paths that can be taken when -// HasI64BigIntSupport() is true, though the test does not directly deal -// with I64 types. +// This exercises error code paths that were added due to BigInt/I64 +// conversion, though the test does not directly deal with I64 types. function testGlobalBadImportNumber() { assertErrorMessage( () => @@ -394,6 +453,7 @@ function testGlobalI64SetWrongType() { testRet(); testId(); testIdPlus(); +testNonBigIntArgs(); testManyArgs(); testImportExport(); testMixedArgs(); diff --git a/js/src/jit-test/tests/wasm/bigint/directives.txt b/js/src/jit-test/tests/wasm/bigint/directives.txt index 68175c6e75..4f8539df45 100644 --- a/js/src/jit-test/tests/wasm/bigint/directives.txt +++ b/js/src/jit-test/tests/wasm/bigint/directives.txt @@ -1 +1 @@ -|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; skip-if: !wasmBigIntEnabled(); include:wasm.js +|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; include:wasm.js diff --git a/js/src/jit-test/tests/wasm/bigint/disabled.js b/js/src/jit-test/tests/wasm/bigint/disabled.js deleted file mode 100644 index fd9123b532..0000000000 --- a/js/src/jit-test/tests/wasm/bigint/disabled.js +++ /dev/null @@ -1,104 +0,0 @@ -// |jit-test| --no-wasm-bigint -// -// Tests code paths that are taken when BigInt/I64 conversion is disabled. - -// Test i64 signature failures. - -var f = wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" (func 0)))').exports[""]; -assertErrorMessage(f, TypeError, /i64/); -var f = wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" (func 0)))').exports[""]; -assertErrorMessage(f, TypeError, /i64/); - -var f = wasmEvalText('(module (import $imp "a" "b" (param i64) (result i32)) (func $f (result i32) (call $imp (i64.const 0))) (export "" (func $f)))', {a:{b:()=>{}}}).exports[""]; -assertErrorMessage(f, TypeError, /i64/); -var f = wasmEvalText('(module (import $imp "a" "b" (result i64)) (func $f (result i64) (call $imp)) (export "" (func $f)))', {a:{b:()=>{}}}).exports[""]; -assertErrorMessage(f, TypeError, /i64/); - -// Import and export related tests. -// -// i64 is disallowed when called from JS and will cause calls to fail before -// arguments are coerced (when BigInt/I64 conversion is off). - -var sideEffect = false; -var i = wasmEvalText('(module (func (export "f") (param i64) (result i32) (i32.const 42)))').exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -i = wasmEvalText('(module (func (export "f") (param i32) (param i64) (result i32) (i32.const 42)))').exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }, 0), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -i = wasmEvalText('(module (func (export "f") (param i32) (result i64) (i64.const 42)))').exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -i = wasmEvalText('(module (import "i64" "func" (param i64)) (export "f" (func 0)))', { i64: { func() {} } }).exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -i = wasmEvalText('(module (import "i64" "func" (param i32) (param i64)) (export "f" (func 0)))', { i64: { func() {} } }).exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }, 0), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -i = wasmEvalText('(module (import "i64" "func" (result i64)) (export "f" (func 0)))', { i64: { func() {} } }).exports; -assertErrorMessage(() => i.f({ valueOf() { sideEffect = true; return 42; } }), TypeError, 'cannot pass i64 to or from JS'); -assertEq(sideEffect, false); - -// Global related tests. -// -// The test for a Number value dominates the guard against int64. -assertErrorMessage(() => wasmEvalText(`(module - (import "globals" "x" (global i64)))`, - {globals: {x:false}}), - LinkError, - /import object field 'x' is not a Number/); - -// The imported value is a Number, so the int64 guard should stop us. -assertErrorMessage(() => wasmEvalText(`(module - (import "globals" "x" (global i64)))`, - {globals: {x:42}}), - LinkError, - /cannot pass i64 to or from JS/); - -{ - // We can import and export i64 globals as cells. They cannot be created - // from JS because there's no way to specify a non-zero initial value; that - // restriction is tested later. But we can export one from a module and - // import it into another. - - let i = wasmEvalText(`(module - (global (export "g") i64 (i64.const 37)) - (global (export "h") (mut i64) (i64.const 37)))`); - - let j = wasmEvalText(`(module - (import "globals" "g" (global i64)) - (func (export "f") (result i32) - (i64.eq (global.get 0) (i64.const 37))))`, - {globals: {g: i.exports.g}}); - - assertEq(j.exports.f(), 1); - - // We cannot read or write i64 global values from JS. - - let g = i.exports.g; - - assertErrorMessage(() => i.exports.g.value, TypeError, /cannot pass i64 to or from JS/); - - // Mutability check comes before i64 check. - assertErrorMessage(() => i.exports.g.value = 12, TypeError, /can't set value of immutable global/); - assertErrorMessage(() => i.exports.h.value = 12, TypeError, /cannot pass i64 to or from JS/); -} - -// WebAssembly.Global tests. -// These types should not work: -assertErrorMessage(() => new Global({}), TypeError, /bad type for a WebAssembly.Global/); -assertErrorMessage(() => new Global({value: "fnord"}), TypeError, /bad type for a WebAssembly.Global/); -assertErrorMessage(() => new Global(), TypeError, /Global requires at least 1 argument/); -assertErrorMessage(() => new Global({value: "i64"}, 0), TypeError, /bad type for a WebAssembly.Global/); // Initial value does not work - -// Check against i64 import before matching mutability -let m = new Module(wasmTextToBinary(`(module - (import "m" "g" (global (mut i64))))`)); -assertErrorMessage(() => new Instance(m, {m: {g: 42}}), - LinkError, - i64Err); diff --git a/js/src/jit-test/tests/wasm/bigint/stubs.js b/js/src/jit-test/tests/wasm/bigint/stubs.js index cbfbe59b79..89f7d78413 100644 --- a/js/src/jit-test/tests/wasm/bigint/stubs.js +++ b/js/src/jit-test/tests/wasm/bigint/stubs.js @@ -107,38 +107,36 @@ })(); // Test JIT entry stub -if (wasmBigIntEnabled()) { - (function testJitEntry() { - let options = getJitCompilerOptions(); - if (!options["baseline.enable"]) return; +(function testJitEntry() { + let options = getJitCompilerOptions(); + if (!options["baseline.enable"]) return; - let baselineTrigger = options["baseline.warmup.trigger"]; + let baselineTrigger = options["baseline.warmup.trigger"]; - i = wasmEvalText( - `(module - (func (export "foo") (param i64) (result i64) - local.get 0 - i64.const 1 - i64.add - return - ) - )`, - {} - ).exports; + i = wasmEvalText( + `(module + (func (export "foo") (param i64) (result i64) + local.get 0 + i64.const 1 + i64.add + return + ) + )`, + {} + ).exports; - function caller(n) { - return i.foo(42n); - } + function caller(n) { + return i.foo(42n); + } - // Baseline compile ffis. - for (let i = baselineTrigger + 1; i-- > 0; ) { - caller(i); - } + // Baseline compile ffis. + for (let i = baselineTrigger + 1; i-- > 0; ) { + caller(i); + } - // Enable the jit entry. - assertEq(caller(0), 43n); + // Enable the jit entry. + assertEq(caller(0), 43n); - // Test the jit exit under normal conditions. - assertEq(caller(0), 43n); - })(); -} + // Test the jit exit under normal conditions. + assertEq(caller(0), 43n); +})(); diff --git a/js/src/jit-test/tests/wasm/bug1645310/README.md b/js/src/jit-test/tests/wasm/bug1645310/README.md new file mode 100644 index 0000000000..9687e7a9b6 --- /dev/null +++ b/js/src/jit-test/tests/wasm/bug1645310/README.md @@ -0,0 +1 @@ +DO NOT ADD A directives.txt FILE IN THIS DIRECTORY. THE TEST CASE MUST RUN WITH MINIMAL PRELIMINARIES. diff --git a/js/src/jit-test/tests/wasm/bug1645310/bug1645310.js b/js/src/jit-test/tests/wasm/bug1645310/bug1645310.js new file mode 100644 index 0000000000..1d7258df89 --- /dev/null +++ b/js/src/jit-test/tests/wasm/bug1645310/bug1645310.js @@ -0,0 +1,61 @@ +// |jit-test| --wasm-compiler=ion; skip-if: !wasmIsSupported() + +// In this case we're setting things up so that wasm can't be compiled, as the +// only available compiler is Ion, and enabling the Debugger will disable Ion. +// +// The test tests that the lazy creation of the WebAssembly object is not +// dependent on whether WebAssembly can be compiled or not: if wasm is supported +// then the WebAssembly object should always be created. The fact that wasm +// can't be compiled is a separate matter. +// +// IT'S IMPORTANT NOT TO MENTION THE WEBASSEMBLY OBJECT UNTIL AFTER THE DEBUGGER +// HAS BEEN CREATED, AND NOT TO LOAD lib/wasm.js OR OTHER WASM CODE HERE. + +var g7 = newGlobal({newCompartment: true}); +g7.parent = this; +g7.eval("Debugger(parent)"); +assertEq(typeof WebAssembly, "object"); + +// Test that validation works even if compilers are not available. + +WebAssembly.validate(wasmTextToBinary('(module (func))')); + +// Test that compilation fails with a sensible error. + +var bits = wasmTextToBinary('(module (func))'); +var msg = /no WebAssembly compiler available/ +var exn; + +exn = null; +try { new WebAssembly.Module(bits); } catch (e) { exn = e; } +assertEq(Boolean(exn), true); +assertEq(Boolean(String(exn).match(msg)), true); + +exn = null; +try { WebAssembly.compile(bits); } catch (e) { exn = e; } +assertEq(Boolean(exn), true); +assertEq(Boolean(String(exn).match(msg)), true); + +exn = null; +try { WebAssembly.instantiate(bits); } catch (e) { exn = e; } +assertEq(Boolean(exn), true); +assertEq(Boolean(String(exn).match(msg)), true); + +// We do not use wasmStreamingIsSupported() here because that checks whether +// compilers are available, and that is precisely what we want to be checking +// ourselves. But streaming compilation is available only if there are helper +// threads, so that's an OK proxy. + +if (helperThreadCount() > 0) { + exn = null; + WebAssembly.compileStreaming(bits).catch(e => { exn = e; }); + drainJobQueue(); + assertEq(Boolean(exn), true); + assertEq(Boolean(String(exn).match(msg)), true); + + exn = null; + WebAssembly.instantiateStreaming(bits).catch(e => { exn = e; }); + drainJobQueue(); + assertEq(Boolean(exn), true); + assertEq(Boolean(String(exn).match(msg)), true); +} diff --git a/js/src/jit-test/tests/wasm/declared-segs.js b/js/src/jit-test/tests/wasm/declared-segs.js index a68bb90c50..f40048fb75 100644 --- a/js/src/jit-test/tests/wasm/declared-segs.js +++ b/js/src/jit-test/tests/wasm/declared-segs.js @@ -1,32 +1,35 @@ -// |jit-test| skip-if: !wasmBulkMemSupported() || !wasmReftypesEnabled() +// |jit-test| skip-if: !wasmReftypesEnabled() // Declared segments parse and validate wasmFullPass(` (module (func $f1) (elem declare $f1) - (elem declare funcref (ref.null)) + (elem declare funcref (ref.null func)) (func $run) (export "run" (func $run)) ) `); -// Declared segments cannot be used by bulk-memory operations -function test(ins) { - assertErrorMessage( - () => wasmEvalText(` - (module - (func $f1) - (table 1 1 funcref) - (elem declare $f1) - (func $start ${ins}) - (start $start) - ) - `), - WebAssembly.RuntimeError, - 'index out of bounds'); -} -test('(table.init 0 (i32.const 0) (i32.const 0) (i32.const 1))'); +// Declared segments can be used with externref +wasmFullPass(` + (module + (elem declare externref (ref.null extern)) + (func $run) + (export "run" (func $run)) + ) +`); + +// Declared segments can be used by bulk-memory operations +wasmEvalText(` + (module + (func $f1) + (table 1 1 funcref) + (elem declare $f1) + (func $start (table.init 0 (i32.const 0) (i32.const 0) (i32.const 1))) + (start $start) + ) +`); // Declared segments don't cause initialization of a table wasmAssert(` @@ -37,7 +40,7 @@ wasmAssert(` (func $at (param i32) (result i32) local.get 0 table.get 0 - ref.is_null + ref.is_null func ) (export "at" (func $at)) ) diff --git a/js/src/jit-test/tests/wasm/features.js b/js/src/jit-test/tests/wasm/features.js new file mode 100644 index 0000000000..62db342692 --- /dev/null +++ b/js/src/jit-test/tests/wasm/features.js @@ -0,0 +1,51 @@ +// |jit-test| test-also=--wasm-gc; + +// Test that if a feature is 'experimental' then we must be in a nightly build, +// and if a feature is 'released' then it must be enabled on release and beta. +// +// An experimental feature is allowed to be disabled by platform/feature flags, +// we only require that it can never be enabled on release/beta builds. +// +// A released feature is allowed to be disabled on nightly. This is useful for +// if we're testing out a new compiler/configuration where a released feature +// is not supported yet. We only require that on release/beta, the feature must +// be enabled. +// +// As features are advanced, this test must be manually updated. +// +// NOTE0: The |jit-test| directive must be updated with all opt-in shell flags +// for experimental features for this to work correctly. +// NOTE1: This test relies on feature functions accurately guarding use of the +// feature to work correctly. All features should have a 'disabled.js' +// test to verify this. Basic testing for this is included with each +// feature in this test for sanity. + +let { release_or_beta } = getBuildConfiguration(); +let nightly = !release_or_beta; + +let nightlyOnlyFeatures = [ + ['gc', wasmGcEnabled(), `(module (type $s (struct)) (func (param (ref opt $s))))`], + ['simd', wasmSimdSupported(), `(module (memory 1 1) (func i32.const 0 i8x16.splat drop))`], +]; + +for (let [name, enabled, test] of nightlyOnlyFeatures) { + if (enabled) { + assertEq(nightly, true, `${name} must be enabled only on nightly`); + wasmEvalText(test); + } else { + assertErrorMessage(() => wasmEvalText(test), WebAssembly.CompileError, /./); + } +} + +let releasedFeatures = [ + ['multi-value', wasmMultiValueEnabled(), `(module (func (result i32 i32) i32.const 0 i32.const 0))`], + ['threads', wasmThreadsSupported(), `(module (memory 1 1 shared))`], + ['reference-types', wasmReftypesEnabled(), `(module (func (param externref)))`], +]; + +for (let [name, enabled, test] of releasedFeatures) { + if (release_or_beta) { + assertEq(enabled, true, `${name} must be enabled on release and beta`); + wasmEvalText(test); + } +} diff --git a/js/src/jit-test/tests/wasm/gc/TypedObject.js b/js/src/jit-test/tests/wasm/gc/TypedObject.js index 7379179de9..b5f539f004 100644 --- a/js/src/jit-test/tests/wasm/gc/TypedObject.js +++ b/js/src/jit-test/tests/wasm/gc/TypedObject.js @@ -46,10 +46,10 @@ (type $r (struct (field (mut anyref)))) (func (export "mkp") (result anyref) - (struct.new $p (ref.null))) + (struct.new $p (ref.null opt $q))) (func (export "mkr") (result anyref) - (struct.new $r (ref.null))))`).exports; + (struct.new $r (ref.null extern))))`).exports; assertEq(typeof ins.mkp().constructor, "function"); assertErrorMessage(() => new (ins.mkp().constructor)({_0:null}), @@ -75,7 +75,7 @@ (struct.new $q (f64.const 1.5))) (func (export "mkp") (result anyref) - (struct.new $p (ref.null) (ref.null))))`).exports; + (struct.new $p (ref.null opt $q) (ref.null extern))))`).exports; let q = ins.mkq(); assertEq(typeof q, "object"); assertEq(q._0, 1.5); @@ -127,9 +127,9 @@ (type $p (struct (field i64))) (type $q (struct (field i32) (field i32))) (func $f (param anyref) (result i32) - (ref.is_null (struct.narrow anyref (ref opt $q) (local.get 0)))) + (ref.is_null extern (struct.narrow anyref (ref opt $q) (local.get 0)))) (func $g (param anyref) (result i32) - (ref.is_null (struct.narrow anyref (ref opt $p) (local.get 0)))) + (ref.is_null extern (struct.narrow anyref (ref opt $p) (local.get 0)))) (func (export "t1") (result i32) (call $f (struct.new $p (i64.const 0)))) (func (export "t2") (result i32) diff --git a/js/src/jit-test/tests/wasm/gc/anyref-boxing-struct.js b/js/src/jit-test/tests/wasm/gc/anyref-boxing-struct.js index 55350f92d3..949b3e64c0 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-boxing-struct.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-boxing-struct.js @@ -59,7 +59,7 @@ for (let v of VALUES) `(module (type $S (struct (field $S.x (mut anyref)))) (func (export "make") (result anyref) - (struct.new $S (ref.null))) + (struct.new $S (ref.null extern))) (func (export "get") (param $o anyref) (result anyref) (struct.get $S 0 (struct.narrow anyref (ref opt $S) (local.get $o)))))`); let x = ins.exports.make(); @@ -75,7 +75,7 @@ for (let v of VALUES) `(module (type $S (struct (field $S.x (mut anyref)))) (func (export "make") (result anyref) - (struct.new $S (ref.null))) + (struct.new $S (ref.null extern))) (func (export "get") (param $o anyref) (result anyref) (struct.get $S 0 (struct.narrow anyref (ref opt $S) (local.get $o)))))`); let constructor = ins.exports.make().constructor; @@ -108,7 +108,7 @@ for (let v of VALUES) { `(module (type $S (struct (field $S.x (mut anyref)))) (func (export "make") (result anyref) - (struct.new $S (ref.null))))`); + (struct.new $S (ref.null extern))))`); let constructor = ins.exports.make().constructor; let x = new constructor(); assertEq(x._0, null); @@ -122,7 +122,7 @@ for (let v of VALUES) { `(module (type $S (struct (field $S.x (mut anyref)))) (func (export "make") (result anyref) - (struct.new $S (ref.null))))`); + (struct.new $S (ref.null extern))))`); let constructor = ins.exports.make().constructor; let x = new constructor({}); assertEq(x._0, undefined); diff --git a/js/src/jit-test/tests/wasm/gc/anyref-boxing.js b/js/src/jit-test/tests/wasm/gc/anyref-boxing.js index 5486e758ed..dd62a3cac5 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-boxing.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-boxing.js @@ -39,7 +39,7 @@ let VALUES = [null, for (let v of VALUES) { - let g = new WebAssembly.Global({value: "anyref"}, v); + let g = new WebAssembly.Global({value: "externref"}, v); assertEq(g.value, v); } @@ -47,7 +47,7 @@ for (let v of VALUES) for (let v of VALUES) { - let g = new WebAssembly.Global({value: "anyref", mutable: true}); + let g = new WebAssembly.Global({value: "externref", mutable: true}); g.value = v; assertEq(g.value, v); } @@ -56,7 +56,7 @@ for (let v of VALUES) for (let v of VALUES) { - let g = new WebAssembly.Global({value: "anyref"}, v); + let g = new WebAssembly.Global({value: "externref"}, v); let ins = wasmEvalText( `(module (import "m" "g" (global $glob anyref)) @@ -70,7 +70,7 @@ for (let v of VALUES) for (let v of VALUES) { - let g = new WebAssembly.Global({value: "anyref", mutable: true}); + let g = new WebAssembly.Global({value: "externref", mutable: true}); let ins = wasmEvalText( `(module (import "m" "g" (global $glob (mut anyref))) @@ -99,7 +99,7 @@ for (let v of VALUES) for (let v of VALUES) { - let t = new WebAssembly.Table({element: "anyref", initial: 10}); + let t = new WebAssembly.Table({element: "externref", initial: 10}); t.set(3, v); assertEq(t.get(3), v); } @@ -108,7 +108,7 @@ for (let v of VALUES) for (let v of VALUES) { - let t = new WebAssembly.Table({element: "anyref", initial: 10}); + let t = new WebAssembly.Table({element: "externref", initial: 10}); let ins = wasmEvalText( `(module (import "m" "t" (table $t 10 anyref)) @@ -123,7 +123,7 @@ for (let v of VALUES) for (let v of VALUES) { - let t = new WebAssembly.Table({element: "anyref", initial: 10}); + let t = new WebAssembly.Table({element: "externref", initial: 10}); let ins = wasmEvalText( `(module (import "m" "t" (table $t 10 anyref)) diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-object.js b/js/src/jit-test/tests/wasm/gc/anyref-global-object.js index 0c7020437b..6561477f3b 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-object.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-object.js @@ -5,53 +5,53 @@ function Baguette(calories) { this.calories = calories; } -assertEq(new WebAssembly.Global({value: "anyref"}) instanceof WebAssembly.Global, true); +assertEq(new WebAssembly.Global({value: "externref"}) instanceof WebAssembly.Global, true); (function() { // Test initialization without a value. - let g = new WebAssembly.Global({value: "anyref"}); + let g = new WebAssembly.Global({value: "externref"}); assertEq(g.value, null); assertErrorMessage(() => g.value = 42, TypeError, /immutable global/); })(); (function() { // Test initialization with a value. - let g = new WebAssembly.Global({value: "anyref"}, null); + let g = new WebAssembly.Global({value: "externref"}, null); assertEq(g.value, null); assertErrorMessage(() => g.value = 42, TypeError, /immutable global/); let obj = {}; - g = new WebAssembly.Global({value: "anyref"}, obj); + g = new WebAssembly.Global({value: "externref"}, obj); assertEq(g.value, obj); assertErrorMessage(() => g.value = 42, TypeError, /immutable global/); - g = new WebAssembly.Global({value: "anyref"}, 1337); + g = new WebAssembly.Global({value: "externref"}, 1337); assertEq(typeof g.value, "number"); assertEq(+g.value, 1337); - g = new WebAssembly.Global({value: "anyref"}, 13.37); + g = new WebAssembly.Global({value: "externref"}, 13.37); assertEq(typeof g.value, "number"); assertEq(+g.value, 13.37); - g = new WebAssembly.Global({value: "anyref"}, "string"); + g = new WebAssembly.Global({value: "externref"}, "string"); assertEq(typeof g.value, "string"); assertEq(g.value.toString(), "string"); - g = new WebAssembly.Global({value: "anyref"}, true); + g = new WebAssembly.Global({value: "externref"}, true); assertEq(typeof g.value, "boolean"); assertEq(!!g.value, true); - g = new WebAssembly.Global({value: "anyref"}, Symbol("status")); + g = new WebAssembly.Global({value: "externref"}, Symbol("status")); assertEq(typeof g.value, "symbol"); assertEq(g.value.toString(), "Symbol(status)"); - g = new WebAssembly.Global({value: "anyref"}, undefined); + g = new WebAssembly.Global({value: "externref"}, undefined); assertEq(g.value, undefined); })(); (function() { // Test mutable property and assignment. - let g = new WebAssembly.Global({value: "anyref", mutable: true}, null); + let g = new WebAssembly.Global({value: "externref", mutable: true}, null); assertEq(g.value, null); let obj = { x: 42 }; @@ -70,13 +70,13 @@ assertEq(new WebAssembly.Global({value: "anyref"}) instanceof WebAssembly.Global (function() { // Test tracing. let nom = new Baguette(1); - let g = new WebAssembly.Global({value: "anyref"}, nom); + let g = new WebAssembly.Global({value: "externref"}, nom); nom = null; gc(); assertEq(g.value.calories, 1); })(); -var global = new WebAssembly.Global({ value: "anyref", mutable: true }, null); +var global = new WebAssembly.Global({ value: "externref", mutable: true }, null); // GCZeal mode 2 implies that every allocation (second parameter = every single // allocation) will trigger a full GC. diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js index fa34a32c70..e305a2bce6 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-postbarrier.js @@ -10,10 +10,10 @@ function Baguette(calories) { // Ensure the baseline compiler sync's before the postbarrier. (function() { wasmEvalText(`(module - (global (mut anyref) (ref.null)) + (global (mut anyref) (ref.null extern)) (func (export "f") global.get 0 - ref.null + ref.null extern global.set 0 global.set 0 ) @@ -22,13 +22,13 @@ function Baguette(calories) { let exportsPlain = wasmEvalText(`(module (global i32 (i32.const 42)) - (global $g (mut anyref) (ref.null)) + (global $g (mut anyref) (ref.null extern)) (func (export "set") (param anyref) local.get 0 global.set $g) (func (export "get") (result anyref) global.get $g) )`).exports; let exportsObj = wasmEvalText(`(module - (global $g (export "g") (mut anyref) (ref.null)) + (global $g (export "g") (mut anyref) (ref.null extern)) (func (export "set") (param anyref) local.get 0 global.set $g) (func (export "get") (result anyref) global.get $g) )`).exports; diff --git a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js index 2da30df1a5..fdc9eb7bbd 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-global-prebarrier.js @@ -10,7 +10,7 @@ if (opts['ion.enable'] || opts['baseline.enable']) const { startProfiling, endProfiling, assertEqPreciseStacks, isSingleStepProfilingEnabled } = WasmHelpers; let e = wasmEvalText(`(module - (global $g (mut anyref) (ref.null)) + (global $g (mut anyref) (ref.null extern)) (func (export "set") (param anyref) local.get 0 global.set $g) )`).exports; diff --git a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js index af0f76a6be..13203b79aa 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js +++ b/js/src/jit-test/tests/wasm/gc/anyref-val-tracing.js @@ -2,11 +2,11 @@ gczeal(14, 1); let { exports } = wasmEvalText(`(module - (global $anyref (import "glob" "anyref") anyref) + (global $anyref (import "glob" "externref") anyref) (func (export "get") (result anyref) global.get $anyref) )`, { glob: { - anyref: { sentinel: "lol" }, + externref: { sentinel: "lol" }, } }); assertEq(exports.get().sentinel, "lol"); diff --git a/js/src/jit-test/tests/wasm/gc/anyref.js b/js/src/jit-test/tests/wasm/gc/anyref.js index 0a171d2a7c..303d2e87ac 100644 --- a/js/src/jit-test/tests/wasm/gc/anyref.js +++ b/js/src/jit-test/tests/wasm/gc/anyref.js @@ -13,12 +13,12 @@ assertErrorMessage(() => wasmEvalText(`(module (func (result anyref) i32.const 42 ) -)`), CompileError, mismatchError('i32', 'anyref')); +)`), CompileError, mismatchError('i32', 'externref')); assertErrorMessage(() => wasmEvalText(`(module (func (result anyref) i32.const 0 - ref.null + ref.null extern i32.const 42 select (result anyref) ) @@ -26,27 +26,27 @@ assertErrorMessage(() => wasmEvalText(`(module assertErrorMessage(() => wasmEvalText(`(module (func (result i32) - ref.null + ref.null extern if i32.const 42 end ) -)`), CompileError, mismatchError('nullref', 'i32')); +)`), CompileError, mismatchError('externref', 'i32')); // Basic compilation tests. let simpleTests = [ - "(module (func (drop (ref.null))))", + "(module (func (drop (ref.null extern))))", "(module (func $test (local anyref)))", "(module (func $test (param anyref)))", - "(module (func $test (result anyref) (ref.null)))", + "(module (func $test (result anyref) (ref.null extern)))", "(module (func $test (block (result anyref) (unreachable)) unreachable))", - "(module (func $test (result i32) (local anyref) (ref.is_null (local.get 0))))", + "(module (func $test (result i32) (local anyref) (ref.is_null extern (local.get 0))))", `(module (import "a" "b" (func (param anyref))))`, `(module (import "a" "b" (func (result anyref))))`, - `(module (global anyref (ref.null)))`, - `(module (global (mut anyref) (ref.null)))`, + `(module (global anyref (ref.null extern)))`, + `(module (global (mut anyref) (ref.null extern)))`, ]; for (let src of simpleTests) { @@ -58,8 +58,8 @@ for (let src of simpleTests) { let { exports } = wasmEvalText(`(module (func (export "is_null") (result i32) - ref.null - ref.is_null + ref.null extern + ref.is_null extern ) (func $sum (param i32) (result i32) @@ -69,21 +69,21 @@ let { exports } = wasmEvalText(`(module ) (func (export "is_null_spill") (result i32) - ref.null + ref.null extern i32.const 58 call $sum drop - ref.is_null + ref.is_null extern ) (func (export "is_null_local") (result i32) (local anyref) - ref.null + ref.null extern local.set 0 i32.const 58 call $sum drop local.get 0 - ref.is_null + ref.is_null extern ) )`); @@ -96,12 +96,12 @@ assertEq(exports.is_null_local(), 1); exports = wasmEvalText(`(module (func (export "is_null") (param $ref anyref) (result i32) local.get $ref - ref.is_null + ref.is_null extern ) (func (export "ref_or_null") (param $ref anyref) (param $selector i32) (result anyref) local.get $ref - ref.null + ref.null extern local.get $selector select (result anyref) ) @@ -397,7 +397,7 @@ assertEq(exports.count_g(), 1); // Anyref globals in wasm modules. -assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "anyref") anyref))`, { glob: { anyref: new WebAssembly.Global({ value: 'i32' }, 42) } }), +assertErrorMessage(() => wasmEvalText(`(module (global (import "glob" "externref") anyref))`, { glob: { externref: new WebAssembly.Global({ value: 'i32' }, 42) } }), WebAssembly.LinkError, /imported global type mismatch/); @@ -409,8 +409,8 @@ imports = { constants: { imm_null: null, imm_bread: new Baguette(321), - mut_null: new WebAssembly.Global({ value: "anyref", mutable: true }, null), - mut_bread: new WebAssembly.Global({ value: "anyref", mutable: true }, new Baguette(123)) + mut_null: new WebAssembly.Global({ value: "externref", mutable: true }, null), + mut_bread: new WebAssembly.Global({ value: "externref", mutable: true }, new Baguette(123)) } }; @@ -421,9 +421,9 @@ exports = wasmEvalText(`(module (global $g_imp_mut_null (import "constants" "mut_null") (mut anyref)) (global $g_imp_mut_bread (import "constants" "mut_bread") (mut anyref)) - (global $g_imm_null anyref (ref.null)) + (global $g_imm_null anyref (ref.null extern)) (global $g_imm_getglob anyref (global.get $g_imp_imm_bread)) - (global $g_mut (mut anyref) (ref.null)) + (global $g_mut (mut anyref) (ref.null extern)) (func (export "imm_null") (result anyref) global.get $g_imm_null) (func (export "imm_getglob") (result anyref) global.get $g_imm_getglob) @@ -469,7 +469,7 @@ wasmEvalText( `(module (func (return) - (ref.null) + (ref.null extern) (drop) ) )`); @@ -478,7 +478,7 @@ wasmEvalText( `(module (func (param anyref) (return) - (ref.is_null (get_local 0)) + (ref.is_null extern (get_local 0)) (drop) ) )`); diff --git a/js/src/jit-test/tests/wasm/gc/binary.js b/js/src/jit-test/tests/wasm/gc/binary.js index 753896f5e5..577502f4b7 100644 --- a/js/src/jit-test/tests/wasm/gc/binary.js +++ b/js/src/jit-test/tests/wasm/gc/binary.js @@ -1,4 +1,4 @@ -// |jit-test| skip-if: !wasmReftypesEnabled() +// |jit-test| skip-if: !wasmGcEnabled() load(libdir + "wasm-binary.js"); diff --git a/js/src/jit-test/tests/wasm/gc/disabled.js b/js/src/jit-test/tests/wasm/gc/disabled.js index 6dc4865f38..7add165122 100644 --- a/js/src/jit-test/tests/wasm/gc/disabled.js +++ b/js/src/jit-test/tests/wasm/gc/disabled.js @@ -5,12 +5,12 @@ const { CompileError, validate } = WebAssembly; const UNRECOGNIZED_OPCODE_OR_BAD_TYPE = /unrecognized opcode|(Structure|reference) types not enabled|invalid inline block type|bad type/; let simpleTests = [ - "(module (func (drop (ref.null))))", + "(module (func (drop (ref.null extern))))", "(module (func $test (local anyref)))", "(module (func $test (param anyref)))", - "(module (func $test (result anyref) (ref.null)))", + "(module (func $test (result anyref) (ref.null extern)))", "(module (func $test (block (result anyref) (unreachable)) unreachable))", - "(module (func $test (result i32) (local anyref) (ref.is_null (local.get 0))))", + "(module (func $test (result i32) (local anyref) (ref.is_null extern (local.get 0))))", `(module (import "a" "b" (func (param anyref))))`, `(module (import "a" "b" (func (result anyref))))`, `(module (type $s (struct)))`, diff --git a/js/src/jit-test/tests/wasm/gc/funcref.js b/js/src/jit-test/tests/wasm/gc/funcref.js index c8b6bc8196..47201b2ccb 100644 --- a/js/src/jit-test/tests/wasm/gc/funcref.js +++ b/js/src/jit-test/tests/wasm/gc/funcref.js @@ -8,22 +8,22 @@ const typeErr = /type mismatch/; // Validation: -wasmEvalText(`(module (func (local anyref funcref) (local.set 0 (local.get 1))))`); +wasmFailValidateText(`(module (func (local anyref funcref) (local.set 0 (local.get 1))))`, typeErr); wasmEvalText(`(module (func (local funcref funcref) (local.set 0 (local.get 1))))`); -wasmEvalText(`(module (func (local funcref) (local.set 0 (ref.null))))`); +wasmEvalText(`(module (func (local funcref) (local.set 0 (ref.null func))))`); wasmFailValidateText(`(module (func (local funcref anyref) (local.set 0 (local.get 1))))`, typeErr); -wasmEvalText(`(module (global (mut funcref) (ref.null)) (func (param funcref) (global.set 0 (local.get 0))))`); -wasmEvalText(`(module (global (mut anyref) (ref.null)) (func (param funcref) (global.set 0 (local.get 0))))`); -wasmFailValidateText(`(module (global (mut funcref) (ref.null)) (func (param anyref) (global.set 0 (local.get 0))))`, typeErr); +wasmEvalText(`(module (global (mut funcref) (ref.null func)) (func (param funcref) (global.set 0 (local.get 0))))`); +wasmFailValidateText(`(module (global (mut anyref) (ref.null extern)) (func (param funcref) (global.set 0 (local.get 0))))`, typeErr); +wasmFailValidateText(`(module (global (mut funcref) (ref.null func)) (func (param anyref) (global.set 0 (local.get 0))))`, typeErr); wasmEvalText(`(module (func (param funcref)) (func (param funcref) (call 0 (local.get 0))))`); -wasmEvalText(`(module (func (param anyref)) (func (param funcref) (call 0 (local.get 0))))`); +wasmFailValidateText(`(module (func (param anyref)) (func (param funcref) (call 0 (local.get 0))))`, typeErr); wasmFailValidateText(`(module (func (param funcref)) (func (param anyref) (call 0 (local.get 0))))`, typeErr); wasmEvalText(`(module (func (param funcref) (result funcref) (block (result funcref) (local.get 0) (br 0))))`); -wasmEvalText(`(module (func (param funcref) (result anyref) (block (result anyref) (local.get 0) (br 0))))`); +wasmFailValidateText(`(module (func (param funcref) (result anyref) (block (result anyref) (local.get 0) (br 0))))`, typeErr); wasmFailValidateText(`(module (func (param anyref) (result anyref) (block (result funcref) (local.get 0) (br 0))))`, typeErr); wasmEvalText(`(module (func (param funcref funcref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`); -wasmEvalText(`(module (func (param anyref funcref) (result anyref) (select (result anyref) (local.get 0) (local.get 1) (i32.const 0))))`); -wasmEvalText(`(module (func (param funcref anyref) (result anyref) (select (result anyref)(local.get 0) (local.get 1) (i32.const 0))))`); +wasmFailValidateText(`(module (func (param anyref funcref) (result anyref) (select (result anyref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); +wasmFailValidateText(`(module (func (param funcref anyref) (result anyref) (select (result anyref)(local.get 0) (local.get 1) (i32.const 0))))`, typeErr); wasmFailValidateText(`(module (func (param anyref funcref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); wasmFailValidateText(`(module (func (param funcref anyref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); @@ -36,7 +36,7 @@ const wasmFun2 = new Instance(m).exports.wasmFun; const wasmFun3 = new Instance(m).exports.wasmFun; var run = wasmEvalText(`(module - (global (mut funcref) (ref.null)) + (global (mut funcref) (ref.null func)) (func (param $x funcref) (param $test i32) (result funcref) local.get $x global.get 0 @@ -65,43 +65,36 @@ assertEq(run(wasmFun1, wasmFun2, wasmFun3, false, true), wasmFun3); var run = wasmEvalText(`(module (type $t0 (func (param anyref) (result anyref))) (type $t1 (func (param funcref) (result anyref))) - (type $t2 (func (param anyref) (result funcref))) - (type $t3 (func (param funcref funcref) (result funcref))) - (func $f0 (type $t0) ref.null) - (func $f1 (type $t1) ref.null) - (func $f2 (type $t2) ref.null) - (func $f3 (type $t3) ref.null) - (table funcref (elem $f0 $f1 $f2 $f3)) + (type $t2 (func (param funcref funcref) (result anyref))) + (func $f0 (type $t0) ref.null extern) + (func $f1 (type $t1) ref.null extern) + (func $f2 (type $t2) ref.null extern) + (table funcref (elem $f0 $f1 $f2)) (func (export "run") (param i32 i32) (result anyref) - block $b3 block $b2 block $b1 block $b0 + block $b2 block $b1 block $b0 local.get 0 - br_table $b0 $b1 $b2 $b3 + br_table $b0 $b1 $b2 end $b0 - ref.null + ref.null extern local.get 1 call_indirect (type $t0) return end $b1 - ref.null + ref.null func local.get 1 call_indirect (type $t1) return end $b2 - ref.null + ref.null func + ref.null func local.get 1 call_indirect (type $t2) return - end $b3 - ref.null - ref.null - local.get 1 - call_indirect (type $t3) - return ) )`).exports.run; -for (var i = 0; i < 4; i++) { - for (var j = 0; j < 4; j++) { +for (var i = 0; i < 3; i++) { + for (var j = 0; j < 3; j++) { if (i == j) assertEq(run(i, j), null); else diff --git a/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js b/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js index baba2ec8d6..eef652cc9b 100644 --- a/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js +++ b/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js @@ -30,10 +30,10 @@ var refmod = new WebAssembly.Module(wasmTextToBinary( (func $g (result anyref) (call $print (i32.const 2)) - (ref.null)) + (ref.null extern)) (func (export "test_h") - (call_indirect (type $htype) (ref.null) (i32.const 2))) + (call_indirect (type $htype) (ref.null extern) (i32.const 2))) (func (export "test_i") (drop (call_indirect (type $itype) (i32.const 3)))) diff --git a/js/src/jit-test/tests/wasm/gc/nullref.js b/js/src/jit-test/tests/wasm/gc/nullref.js deleted file mode 100644 index 93ab617e49..0000000000 --- a/js/src/jit-test/tests/wasm/gc/nullref.js +++ /dev/null @@ -1,307 +0,0 @@ -// |jit-test| skip-if: !wasmReftypesEnabled() - -// Note, passing a non-null value from JS to a wasm anyref in any way generates -// an error; it does not run valueOf or toString, nor are nullish values such as -// undefined or 0 coerced to null. - -let effect = false; -let effectful = { valueOf() { effect = true; }, - toString() { effect = true; } } - -// Parameters, returns, locals, exported functions -{ - let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (func (export "f") (param $p nullref) (result nullref) - (local $l nullref) - (local.set $l (local.get $p)) - (local.get $l)))`))); - assertEq(ins.exports.f(null), null); - assertErrorMessage(() => ins.exports.f(0), TypeError, /nullref requires a null value/); - assertErrorMessage(() => ins.exports.f(undefined), TypeError, /nullref requires a null value/); - effect = false; - assertErrorMessage(() => ins.exports.f(effectful), TypeError, /nullref requires a null value/); - assertEq(effect, false); -} - -// Imported functions -{ - let valueToReturn; - let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "g" (func $g (result nullref))) - (func (export "f") - (call $g) - (drop)))`)), - {m:{g: () => valueToReturn}}); - valueToReturn = null; - ins.exports.f(); // Should work - valueToReturn = 0; - assertErrorMessage(() => ins.exports.f(), TypeError, /nullref requires a null value/); - valueToReturn = undefined; - assertErrorMessage(() => ins.exports.f(), TypeError, /nullref requires a null value/); - valueToReturn = effectful; - effect = false; - assertErrorMessage(() => ins.exports.f(), TypeError, /nullref requires a null value/); - assertEq(effect, false); -} - -// Linking functions -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (func (export "f") (param nullref) (result nullref) - (local.get 0)))`))); - - // This should just work - let ins2 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "f" (func (param nullref) (result nullref))))`)), - {m:ins1.exports}); - - // Type matching at linking - assertErrorMessage(() => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "f" (func (param anyref) (result nullref))))`)), - {m:ins1.exports}), - WebAssembly.LinkError, - /signature mismatch/); - - assertErrorMessage(() => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "f" (func (param nullref) (result anyref))))`)), - {m:ins1.exports}), - WebAssembly.LinkError, - /signature mismatch/); -} - -// Tables and segments -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (elem (table $t) (i32.const 4) nullref (ref.null) (ref.null) (ref.null)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (func $f) - (elem (table $t) (i32.const 4) nullref (ref.func $f) (ref.null) (ref.null)))`)), - WebAssembly.CompileError, - /initializer type must be subtype of element type/); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (func $f) - (elem (table $t) (i32.const 4) func $f))`)), - WebAssembly.CompileError, - /segment's element type must be subtype of table's element type/); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (func $f) - (elem nullref (ref.func $f) (ref.null) (ref.null)))`)), - WebAssembly.CompileError, - /initializer type must be subtype of element type/); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (elem nullref (ref.null) (ref.null) (ref.null)) - (func (export "f") - (table.init $t 0 (i32.const 0) (i32.const 0) (i32.const 2))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (elem anyref (ref.null) (ref.null) (ref.null)) - (func (export "f") - (table.init $t 0 (i32.const 0) (i32.const 0) (i32.const 2))))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (func (export "f") (result nullref) - (table.get $t (i32.const 0))) - (func (export "g") (result anyref) - (table.get $t (i32.const 0))) - (func (export "h") (param $p nullref) - (table.set $t (i32.const 0) (local.get $p))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 anyref) - (func (export "f") (result nullref) - (table.get $t (i32.const 0))))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (func (export "f") (param $p anyref) - (table.set $t (i32.const 0) (local.get $p))))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (table $u 10 nullref) - (func (export "f") - (table.copy $u $t (i32.const 0) (i32.const 0) (i32.const 2))))`)); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (table $u 10 anyref) - (func (export "f") - (table.copy $u $t (i32.const 0) (i32.const 0) (i32.const 2))))`)); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 nullref) - (table $u 10 funcref) - (func (export "f") - (table.copy $u $t (i32.const 0) (i32.const 0) (i32.const 2))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $t 10 anyref) - (table $u 10 nullref) - (func (export "f") - (table.copy $u $t (i32.const 0) (i32.const 0) (i32.const 2))))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $u 10 nullref) - (func (export "f") - (table.fill $u (i32.const 0) (ref.null) (i32.const 2))))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $u 10 nullref) - (func (export "f") (param $r anyref) - (table.fill $u (i32.const 0) (local.get $r) (i32.const 2))))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -new WebAssembly.Module(wasmTextToBinary(` - (module - (table $u 10 nullref) - (func (export "f") - (table.grow $u (ref.null) (i32.const 2)) - (drop)))`)); - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (table $u 10 nullref) - (func (export "f") (param $r anyref) - (table.grow $u (local.get $r) (i32.const 2)) - (drop)))`)), - WebAssembly.CompileError, - /expression has type anyref but expected nullref/); - -{ - let tab = new WebAssembly.Table({element:"nullref", initial:10}); - assertEq(tab.get(0), null); - tab.set(5, null); - assertErrorMessage(() => tab.set(5, 0), TypeError, /nullref requires a null value/); - assertErrorMessage(() => tab.set(5, undefined), TypeError, /nullref requires a null value/); - effect = false; - assertErrorMessage(() => tab.set(5, effectful), TypeError, /nullref requires a null value/); - assertEq(effect, false); - - assertEq(tab.grow(5, null), 10); - assertEq(tab.length, 15); - assertErrorMessage(() => tab.grow(1, "abracadabra"), TypeError, /nullref requires a null value/); -} - -new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "t" (table 10 nullref)))`)), - {m:{t:new WebAssembly.Table({element:"nullref", initial:10})}}); - -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (table (export "t") 10 nullref))`))); - new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "t" (table 10 nullref)))`)), - {m:ins1.exports}); -} - -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (table (export "t") 10 anyref))`))); - assertErrorMessage(() => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "t" (table 10 nullref)))`)), - {m:ins1.exports}), - WebAssembly.LinkError, - /imported table type mismatch/); -} - -// Globals -new WebAssembly.Module(wasmTextToBinary(` - (module - (global nullref (ref.null)))`)) - -assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(` - (module - (func (export "f")) - (global nullref (ref.func 0)))`)), - WebAssembly.CompileError, - /initializer type and expected type don't match/); - -new WebAssembly.Global({ value: "nullref", mutable: true }); - -assertEq(new WebAssembly.Global({ value: "nullref", mutable: true }, null).value, - null); - -effect = false; -assertErrorMessage(() => new WebAssembly.Global({ value: "nullref", mutable: true }, effectful), - TypeError, - /nullref requires a null value/); -assertEq(effect, false); - -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (global (export "g") (mut nullref) (ref.null)))`))); - new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "g" (global (mut nullref))))`)), - {m:ins1.exports}); -} - -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (global (export "g") (mut anyref) (ref.null)))`))); - assertErrorMessage(() => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "g" (global (mut nullref))))`)), - {m:ins1.exports}), - WebAssembly.LinkError, - /imported global type mismatch/); -} - -{ - let ins1 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (global (export "g") (mut nullref) (ref.null)))`))); - assertErrorMessage(() => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` - (module - (import "m" "g" (global (mut anyref))))`)), - {m:ins1.exports}), - WebAssembly.LinkError, - /imported global type mismatch/); -} diff --git a/js/src/jit-test/tests/wasm/gc/ref-func.js b/js/src/jit-test/tests/wasm/gc/ref-func.js index 563b687052..b69512cc5a 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-func.js +++ b/js/src/jit-test/tests/wasm/gc/ref-func.js @@ -11,7 +11,7 @@ wasmFullPass(` (elem declare $run) (func $run (result i32) ref.func $run - ref.is_null + ref.is_null func ) (export "run" (func $run)) ) @@ -88,24 +88,25 @@ function validFuncRefText(forwardDeclare, tbl_type) { } // referenced function must be forward declared somehow -assertErrorMessage(() => validFuncRefText('', 'funcref'), WebAssembly.CompileError, /function index is not in an element segment/); +assertErrorMessage(() => validFuncRefText('', 'funcref'), WebAssembly.CompileError, /function index is not declared in a section before the code section/); // referenced function can be forward declared via segments assertEq(validFuncRefText('(elem 0 (i32.const 0) func $referenced)', 'funcref') instanceof WebAssembly.Instance, true); assertEq(validFuncRefText('(elem func $referenced)', 'funcref') instanceof WebAssembly.Instance, true); assertEq(validFuncRefText('(elem declare $referenced)', 'funcref') instanceof WebAssembly.Instance, true); -// also when the segment is passive or active 'anyref' -assertEq(validFuncRefText('(elem 0 (i32.const 0) anyref (ref.func $referenced))', 'anyref') instanceof WebAssembly.Instance, true); -assertEq(validFuncRefText('(elem anyref (ref.func $referenced))', 'anyref') instanceof WebAssembly.Instance, true); +// also when the segment is passive or active 'funcref' +assertEq(validFuncRefText('(elem 0 (i32.const 0) funcref (ref.func $referenced))', 'funcref') instanceof WebAssembly.Instance, true); +assertEq(validFuncRefText('(elem funcref (ref.func $referenced))', 'funcref') instanceof WebAssembly.Instance, true); -// referenced function cannot be forward declared via start section or export -assertErrorMessage(() => validFuncRefText('(start $referenced)', 'funcref'), - WebAssembly.CompileError, - /function index is not in an element segment/); -assertErrorMessage(() => validFuncRefText('(export "referenced" (func $referenced))', 'funcref'), - WebAssembly.CompileError, - /function index is not in an element segment/); +// reference function can be forward declared via globals +assertEq(validFuncRefText('(global funcref (ref.func $referenced))', 'anyref') instanceof WebAssembly.Instance, true); + +// reference function can be forward declared via export +assertEq(validFuncRefText('(export "referenced" (func $referenced))', 'anyref') instanceof WebAssembly.Instance, true); + +// reference function cannot be forward declared via start +assertErrorMessage(() => validFuncRefText('(start $referenced)', 'anyref'), WebAssembly.CompileError, /function index is not declared in a section before the code section/); // Tests not expressible in the text format. @@ -119,15 +120,6 @@ assertErrorMessage(() => new WebAssembly.Module( WebAssembly.CompileError, /segments with element expressions can only contain references/); -// declared element segment with elemexpr can carry type anyref, but this must be rejected. - -assertErrorMessage(() => new WebAssembly.Module( - moduleWithSections([generalElemSection([{ flag: DeclaredElemExpr, - typeCode: AnyrefCode, - elems: [] }])])), - WebAssembly.CompileError, - /declared segment's element type must be subtype of funcref/); - // Test case for bug 1596026: when taking the ref.func of an imported function, // the value obtained should not be the JS function. This would assert (even in // a release build), so the test is merely that the code runs. @@ -190,7 +182,7 @@ checkPassiveElemSegment("end", /failed to read end of initializer expression/); (elem (i32.const 3) $m) (elem (i32.const 6) $m) (elem (i32.const 8) $m) - (elem funcref (ref.func $f) (ref.null) (ref.func $g) (ref.null) (ref.func $h)) + (elem funcref (ref.func $f) (ref.null func) (ref.func $g) (ref.null func) (ref.func $h)) (func $m) (func $f) (func $g) @@ -249,4 +241,4 @@ for (let mutable of [true, false]) { } } } -} \ No newline at end of file +} diff --git a/js/src/jit-test/tests/wasm/gc/ref-global.js b/js/src/jit-test/tests/wasm/gc/ref-global.js index efaf1a9fa2..b4cce7eb70 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-global.js +++ b/js/src/jit-test/tests/wasm/gc/ref-global.js @@ -10,9 +10,9 @@ (field $x f64) (field $y f64))) - (global $g1 (mut (ref opt $point)) (ref.null)) - (global $g2 (mut (ref opt $point)) (ref.null)) - (global $g3 (ref opt $point) (ref.null)) + (global $g1 (mut (ref opt $point)) (ref.null opt $point)) + (global $g2 (mut (ref opt $point)) (ref.null opt $point)) + (global $g3 (ref opt $point) (ref.null opt $point)) ;; Restriction: cannot expose Refs outside the module, not even ;; as a return value. See ref-restrict.js. @@ -25,7 +25,7 @@ (func (export "clear") (global.set $g1 (global.get $g3)) - (global.set $g2 (ref.null))))`); + (global.set $g2 (ref.null opt $point))))`); let mod = new WebAssembly.Module(bin); let ins = new WebAssembly.Instance(mod).exports; @@ -44,7 +44,7 @@ (field $x f64) (field $y f64))) - (global $glob (mut (ref opt $point)) (ref.null)) + (global $glob (mut (ref opt $point)) (ref.null opt $point)) (func (export "init") (global.set $glob (struct.new $point (f64.const 0.5) (f64.const 2.75)))) @@ -53,7 +53,7 @@ (global.set $glob (struct.new $point (f64.const 3.5) (f64.const 37.25)))) (func (export "clear") - (global.set $glob (ref.null))) + (global.set $glob (ref.null opt $point))) (func (export "x") (result f64) (struct.get $point 0 (global.get $glob))) @@ -90,7 +90,7 @@ let mod = new WebAssembly.Module(bin); let obj = {zappa:37}; - let g = new WebAssembly.Global({value: "anyref"}, obj); + let g = new WebAssembly.Global({value: "externref"}, obj); let ins = new WebAssembly.Instance(mod, {"":{g}}).exports; assertEq(ins.get(), obj); } @@ -115,7 +115,7 @@ let bin = wasmTextToBinary( `(module (type $box (struct (field $val i32))) - (global $boxg (export "box") (mut (ref opt $box)) (ref.null)))`); + (global $boxg (export "box") (mut (ref opt $box)) (ref.null opt $box)))`); assertErrorMessage(() => new WebAssembly.Module(bin), WebAssembly.CompileError, /cannot expose indexed reference type/); diff --git a/js/src/jit-test/tests/wasm/gc/ref-restrict.js b/js/src/jit-test/tests/wasm/gc/ref-restrict.js index b1000f834d..9d034a43e6 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-restrict.js +++ b/js/src/jit-test/tests/wasm/gc/ref-restrict.js @@ -66,13 +66,13 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module (type $box (struct (field $x i32))) - (func (export "f") (result (ref opt $box)) (ref.null)))`), + (func (export "f") (result (ref opt $box)) (ref.null opt $box)))`), WebAssembly.CompileError, /cannot expose indexed reference type/); assertEq(typeof wasmCompile( `(module - (func (export "f") (result anyref) (ref.null)))`), + (func (export "f") (result anyref) (ref.null extern)))`), "object"); // Imported function can't take ref parameter, but anyref is OK. @@ -134,25 +134,25 @@ assertEq(typeof wasmCompile( assertErrorMessage(() => wasmCompile( `(module (type $box (struct (field $val i32))) - (global $boxg (export "box") (mut (ref opt $box)) (ref.null)))`), + (global $boxg (export "box") (mut (ref opt $box)) (ref.null opt $box)))`), WebAssembly.CompileError, /cannot expose indexed reference type/); assertErrorMessage(() => wasmCompile( `(module (type $box (struct (field $val i32))) - (global $boxg (export "box") (ref opt $box) (ref.null)))`), + (global $boxg (export "box") (ref opt $box) (ref.null opt $box)))`), WebAssembly.CompileError, /cannot expose indexed reference type/); assertEq(typeof wasmCompile( `(module - (global $boxg (export "box") (mut anyref) (ref.null)))`), + (global $boxg (export "box") (mut anyref) (ref.null extern)))`), "object"); assertEq(typeof wasmCompile( `(module - (global $boxg (export "box") anyref (ref.null)))`), + (global $boxg (export "box") anyref (ref.null extern)))`), "object"); // Exported table cannot reference functions that are exposed for Ref, but anyref is OK. @@ -171,7 +171,7 @@ assertErrorMessage(() => wasmCompile( (type $box (struct (field $val i32))) (table (export "tbl") 1 funcref) (elem (i32.const 0) $f1) - (func $f1 (result (ref opt $box)) (ref.null)))`), + (func $f1 (result (ref opt $box)) (ref.null opt $box)))`), WebAssembly.CompileError, /cannot expose indexed reference type/); @@ -186,7 +186,7 @@ assertEq(typeof wasmCompile( `(module (table (export "tbl") 1 funcref) (elem (i32.const 0) $f1) - (func $f1 (result anyref) (ref.null)))`), + (func $f1 (result anyref) (ref.null extern)))`), "object"); // Imported table cannot reference functions that are exposed for Ref, though anyref is OK. @@ -205,7 +205,7 @@ assertErrorMessage(() => wasmCompile( (type $box (struct (field $val i32))) (import "m" "tbl" (table 1 funcref)) (elem (i32.const 0) $f1) - (func $f1 (result (ref opt $box)) (ref.null)))`), + (func $f1 (result (ref opt $box)) (ref.null opt $box)))`), WebAssembly.CompileError, /cannot expose indexed reference type/); @@ -220,7 +220,7 @@ assertEq(typeof wasmCompile( `(module (import "m" "tbl" (table 1 funcref)) (elem (i32.const 0) $f1) - (func $f1 (result anyref) (ref.null)))`), + (func $f1 (result anyref) (ref.null extern)))`), "object"); // Can't call via exported table with type that is exposed for Ref, though anyref is OK. @@ -231,7 +231,7 @@ assertErrorMessage(() => wasmCompile( (type $fn (func (param (ref opt $box)))) (table (export "tbl") 1 funcref) (func (param i32) - (call_indirect (type $fn) (ref.null) (local.get 0))))`), + (call_indirect (type $fn) (ref.null opt $box) (local.get 0))))`), WebAssembly.CompileError, /cannot expose indexed reference type/); @@ -250,7 +250,7 @@ assertEq(typeof wasmCompile( (type $fn (func (param anyref))) (table (export "tbl") 1 funcref) (func (param i32) - (call_indirect (type $fn) (ref.null) (local.get 0))))`), + (call_indirect (type $fn) (ref.null extern) (local.get 0))))`), "object"); assertEq(typeof wasmCompile( @@ -269,7 +269,7 @@ assertErrorMessage(() => wasmCompile( (type $fn (func (param (ref opt $box)))) (import "m" "tbl" (table 1 funcref)) (func (param i32) - (call_indirect (type $fn) (ref.null) (local.get 0))))`), + (call_indirect (type $fn) (ref.null opt $box) (local.get 0))))`), WebAssembly.CompileError, /cannot expose indexed reference type/); @@ -288,7 +288,7 @@ assertEq(typeof wasmCompile( (type $fn (func (param anyref))) (import "m" "tbl" (table 1 funcref)) (func (param i32) - (call_indirect (type $fn) (ref.null) (local.get 0))))`), + (call_indirect (type $fn) (ref.null extern) (local.get 0))))`), "object"); assertEq(typeof wasmCompile( @@ -310,7 +310,7 @@ assertEq(typeof wasmCompile( (elem (i32.const 0) $f1) (func $f1 (param (ref opt $box)) (result i32) (i32.const 37)) (func (export "f") (param i32) (result i32) - (call_indirect (type $fn) (ref.null) (local.get 0))))`); + (call_indirect (type $fn) (ref.null opt $box) (local.get 0))))`); let i = new WebAssembly.Instance(m).exports; assertEq(i.f(0), 37); } diff --git a/js/src/jit-test/tests/wasm/gc/ref-struct.js b/js/src/jit-test/tests/wasm/gc/ref-struct.js index 273d9c10c6..67adef6f92 100644 --- a/js/src/jit-test/tests/wasm/gc/ref-struct.js +++ b/js/src/jit-test/tests/wasm/gc/ref-struct.js @@ -30,7 +30,7 @@ function checkInvalid(body, errorMessage) { (field $left (mut (ref opt $wabbit))) (field $right (mut (ref opt $wabbit))))) - (global $g (mut (ref opt $wabbit)) (ref.null)) + (global $g (mut (ref opt $wabbit)) (ref.null opt $wabbit)) (global $k (mut i32) (i32.const 0)) @@ -42,7 +42,7 @@ function checkInvalid(body, errorMessage) { (local.set $tmp (global.get $k)) (global.set $k (i32.add (local.get $tmp) (i32.const 1))) (if (result (ref opt $wabbit)) (i32.le_s (local.get $n) (i32.const 2)) - (struct.new $wabbit (local.get $tmp) (ref.null) (ref.null)) + (struct.new $wabbit (local.get $tmp) (ref.null opt $wabbit) (ref.null opt $wabbit)) (block (result (ref opt $wabbit)) (struct.new $wabbit (local.get $tmp) @@ -53,7 +53,7 @@ function checkInvalid(body, errorMessage) { (call $accum (global.get $g))) (func $accum (param $w (ref opt $wabbit)) (result i32) - (if (result i32) (ref.is_null (local.get $w)) + (if (result i32) (ref.is_null opt $wabbit (local.get $w)) (i32.const 0) (i32.add (struct.get $wabbit 0 (local.get $w)) (i32.sub (call $accum (struct.get $wabbit 1 (local.get $w))) @@ -64,7 +64,7 @@ function checkInvalid(body, errorMessage) { (func $reverse (param $w (ref opt $wabbit)) (local $tmp (ref opt $wabbit)) - (if (i32.eqz (ref.is_null (local.get $w))) + (if (i32.eqz (ref.is_null opt $wabbit (local.get $w))) (block (struct.set $wabbit 0 (local.get $w) (i32.mul (i32.const 2) (struct.get $wabbit 0 (local.get $w)))) (local.set $tmp (struct.get $wabbit 1 (local.get $w))) @@ -77,7 +77,7 @@ function checkInvalid(body, errorMessage) { (call $pr (global.get $g))) (func $pr (param $w (ref opt $wabbit)) - (if (i32.eqz (ref.is_null (local.get $w))) + (if (i32.eqz (ref.is_null opt $wabbit (local.get $w))) (block (call $print_lp) (call $print_int (struct.get $wabbit 0 (local.get $w))) @@ -130,7 +130,7 @@ assertEq(wasmEvalText( (func $f (param $p (ref opt $node)) (result (ref opt $node2)) (struct.narrow (ref opt $node) (ref opt $node2) (local.get $p))) (func (export "test") (result anyref) - (call $f (ref.null))))`).exports.test(), + (call $f (ref.null opt $node))))`).exports.test(), null); // struct.narrow: if the downcast succeeds we get the original pointer @@ -181,7 +181,7 @@ assertEq(wasmEvalText( (func (export "test") (result i32) (local $n (ref opt $node)) - (local.set $n (struct.new $node2a (i32.const 0) (ref.null))) + (local.set $n (struct.new $node2a (i32.const 0) (ref.null opt $node))) (ref.eq (call $f (local.get $n)) (local.get $n))))`).exports.test(), 1); @@ -197,7 +197,7 @@ assertEq(wasmEvalText( (func (export "test") (result i32) (local $n (ref opt $node)) - (local.set $n (struct.new $node2a (i32.const 0) (ref.null))) + (local.set $n (struct.new $node2a (i32.const 0) (ref.null opt $node2a))) (ref.eq (call $f (local.get $n)) (local.get $n))))`).exports.test(), 0); @@ -262,7 +262,7 @@ assertEq(wasmEvalText( (func (export "make") (param $n i32) (result anyref) (struct.new $node (local.get $n))) (func (export "coerce") (param $p anyref) (result i32) - (ref.is_null (struct.narrow anyref (ref opt $node) (local.get $p)))))`; + (ref.is_null opt $node (struct.narrow anyref (ref opt $node) (local.get $p)))))`; let mod = new WebAssembly.Module(wasmTextToBinary(txt)); let ins1 = new WebAssembly.Instance(mod).exports; let ins2 = new WebAssembly.Instance(mod).exports; @@ -390,6 +390,7 @@ assertErrorMessage(() => wasmEvalText( checkInvalid(funcBody({locals:[], body:[ RefNullCode, + AnyrefCode, GcPrefix, StructNarrow, I32Code, AnyrefCode, DropCode ]}), @@ -398,6 +399,7 @@ checkInvalid(funcBody({locals:[], checkInvalid(funcBody({locals:[], body:[ RefNullCode, + AnyrefCode, GcPrefix, StructNarrow, AnyrefCode, I32Code, DropCode ]}), @@ -431,7 +433,7 @@ assertErrorMessage(function() { `(module (type $node (struct (field i32))) (func (export "test") - (drop (call $f (ref.null)))) + (drop (call $f (ref.null opt $node)))) (func $f (param $p (ref opt $node)) (result i32) (struct.get $node 0 (local.get $p))))`); ins.exports.test(); @@ -446,7 +448,7 @@ assertErrorMessage(function() { `(module (type $node (struct (field (mut i32)))) (func (export "test") - (call $f (ref.null))) + (call $f (ref.null opt $node))) (func $f (param $p (ref opt $node)) (struct.set $node 0 (local.get $p) (i32.const 0))))`); ins.exports.test(); diff --git a/js/src/jit-test/tests/wasm/gc/ref.js b/js/src/jit-test/tests/wasm/gc/ref.js index a165313a67..b6b354dc29 100644 --- a/js/src/jit-test/tests/wasm/gc/ref.js +++ b/js/src/jit-test/tests/wasm/gc/ref.js @@ -2,8 +2,7 @@ // Parsing and resolving. -var bin = wasmTextToBinary( - `(module +var text = `(module (type $cons (struct (field $car i32) (field $cdr (ref opt $cons)))) @@ -29,7 +28,7 @@ var bin = wasmTextToBinary( (func $cdr (param $p (ref opt $cons)) (result (ref opt $cons)) (local $l (ref opt $cons)) ;; store null value of correct type - (local.set $l (ref.null)) + (local.set $l (ref.null opt $cons)) ;; store local of correct type (local.set $l (local.get $p)) ;; store call result of correct type @@ -39,13 +38,13 @@ var bin = wasmTextToBinary( (block (result (ref opt $cons)) (if (result (ref opt $cons)) (i32.eqz (i32.const 0)) (unreachable) - (ref.null)))) + (ref.null opt $cons)))) (func (param (ref opt $even)) (result (ref opt $odd)) - (ref.null)) + (ref.null opt $odd)) (func (param (ref opt $odd)) (result (ref opt $even)) - (ref.null)) + (ref.null opt $even)) (func (param (ref opt $cons)) (call $cdr (local.get 0)) @@ -54,15 +53,15 @@ var bin = wasmTextToBinary( drop) (func (param (ref opt $cons)) - (drop (ref.eq (local.get 0) (ref.null))) - (drop (ref.eq (ref.null) (local.get 0))) - (drop (ref.eq (local.get 0) (ref.null))) - (drop (ref.eq (ref.null) (local.get 0)))) - )`); + (drop (ref.eq (local.get 0) (ref.null opt $cons))) + (drop (ref.eq (ref.null opt $cons) (local.get 0))) + (drop (ref.eq (local.get 0) (ref.null opt $cons))) + (drop (ref.eq (ref.null opt $cons) (local.get 0)))) + )`; // Validation -assertEq(WebAssembly.validate(bin), true); +wasmValidateText(text); // ref.is_null should work on any reference type @@ -70,7 +69,7 @@ new WebAssembly.Module(wasmTextToBinary(` (module (type $s (struct)) (func $null (param (ref opt $s)) (result i32) - (ref.is_null (local.get 0)))) + (ref.is_null opt $s (local.get 0)))) `)) // Automatic upcast to anyref @@ -108,7 +107,7 @@ assertErrorMessage(() => wasmEvalText(` (func $f (param (ref opt $s)) (unreachable)) (func $g (param (ref opt $t)) (call $f (local.get 0))) )`), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); assertErrorMessage(() => wasmEvalText(` (module @@ -117,7 +116,7 @@ assertErrorMessage(() => wasmEvalText(` (func $f (param (ref opt $s)) (unreachable)) (func $g (param (ref opt $t)) (call $f (local.get 0))) )`), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); // Ref type mismatch in assignment to local but the prefix rule allows // the assignment to succeed if the structs are the same. @@ -135,7 +134,7 @@ assertErrorMessage(() => wasmEvalText(` (type $t (struct (field f32))) (func $f (param (ref opt $s)) (local (ref opt $t)) (local.set 1 (local.get 0)))) `), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); assertErrorMessage(() => wasmEvalText(` (module @@ -144,7 +143,7 @@ assertErrorMessage(() => wasmEvalText(` (func $f (param (ref opt $s)) (unreachable)) (func $g (param (ref opt $t)) (call $f (local.get 0))) )`), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); // Ref type mismatch in return but the prefix rule allows the return // to succeed if the structs are the same. @@ -162,7 +161,7 @@ assertErrorMessage(() => wasmEvalText(` (type $t (struct (field f32))) (func $f (param (ref opt $s)) (result (ref opt $t)) (local.get 0))) `), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); assertErrorMessage(() => wasmEvalText(` (module @@ -170,7 +169,7 @@ assertErrorMessage(() => wasmEvalText(` (type $t (struct (field (mut i32)))) (func $f (param (ref opt $s)) (result (ref opt $t)) (local.get 0))) `), -WebAssembly.CompileError, /expression has type ref.*but expected ref/); +WebAssembly.CompileError, /expression has type optref.*but expected optref/); // Ref type can't reference a function type @@ -196,4 +195,4 @@ assertErrorMessage(() => wasmEvalText(` (func $f (param anyref) (call $g (local.get 0))) (func $g (param (ref opt $s)) (unreachable))) `), -WebAssembly.CompileError, /expression has type anyref but expected ref/); +WebAssembly.CompileError, /expression has type externref but expected optref/); diff --git a/js/src/jit-test/tests/wasm/gc/regress-1633355.js b/js/src/jit-test/tests/wasm/gc/regress-1633355.js index 0f3b31e6d6..ed20be9fc4 100644 --- a/js/src/jit-test/tests/wasm/gc/regress-1633355.js +++ b/js/src/jit-test/tests/wasm/gc/regress-1633355.js @@ -13,13 +13,13 @@ let bin = wasmTextToBinary(` (field $left (mut (ref opt $wabbit))) (field $right (mut (ref opt $wabbit))) )) - (global $g (mut (ref opt $wabbit)) (ref.null)) + (global $g (mut (ref opt $wabbit)) (ref.null opt $wabbit)) (func (export "init") (param $n i32) (global.set $g (call $make (local.get $n))) ) (func $make (param $n i32) (result (ref opt $wabbit)) (local $tmp i32) - (struct.new $wabbit (local.get $tmp) (ref.null) (ref.null)) + (struct.new $wabbit (local.get $tmp) (ref.null opt $wabbit) (ref.null opt $wabbit)) ) `); let mod = new WebAssembly.Module(bin); diff --git a/js/src/jit-test/tests/wasm/gc/regress-outline-repr.js b/js/src/jit-test/tests/wasm/gc/regress-outline-repr.js index f9d8f28c47..a41835b512 100644 --- a/js/src/jit-test/tests/wasm/gc/regress-outline-repr.js +++ b/js/src/jit-test/tests/wasm/gc/regress-outline-repr.js @@ -51,7 +51,7 @@ const wat = ` (i64.const 0) (i64.const 0) (i64.const 0) - (ref.null)) + (ref.null extern)) (struct.new $S2))) (start $main)) ` diff --git a/js/src/jit-test/tests/wasm/gc/stackmaps3.js b/js/src/jit-test/tests/wasm/gc/stackmaps3.js index 44e6686acd..c10f8cc681 100644 --- a/js/src/jit-test/tests/wasm/gc/stackmaps3.js +++ b/js/src/jit-test/tests/wasm/gc/stackmaps3.js @@ -28,7 +28,7 @@ let t = (import "" "mkBoxedInt" (func $mkBoxedInt (result anyref))) (func $mkNil (result anyref) - ref.null + ref.null extern ) (func $mkConsIgnoringScalar diff --git a/js/src/jit-test/tests/wasm/gc/structs.js b/js/src/jit-test/tests/wasm/gc/structs.js index 74bc8b9580..a7e5b53ad9 100644 --- a/js/src/jit-test/tests/wasm/gc/structs.js +++ b/js/src/jit-test/tests/wasm/gc/structs.js @@ -314,7 +314,7 @@ assertEq(the_list, null); (field (mut i64)) (field (mut i32)))) - (global $g (mut (ref opt $big)) (ref.null)) + (global $g (mut (ref opt $big)) (ref.null opt $big)) (func (export "make") (result anyref) (global.set $g @@ -384,7 +384,7 @@ var bin = wasmTextToBinary( `(module (type $cons (struct (field i32) (field (ref opt $cons)))) - (global $g (mut (ref opt $cons)) (ref.null)) + (global $g (mut (ref opt $cons)) (ref.null opt $cons)) (func (export "push") (param i32) (global.set $g (struct.new $cons (local.get 0) (global.get $g)))) @@ -396,7 +396,7 @@ var bin = wasmTextToBinary( (global.set $g (struct.get $cons 1 (global.get $g)))) (func (export "is_empty") (result i32) - (ref.is_null (global.get $g))) + (ref.is_null opt $cons (global.get $g))) )`); diff --git a/js/src/jit-test/tests/wasm/gc/tables-fill.js b/js/src/jit-test/tests/wasm/gc/tables-fill.js index 182fefcf4e..d0e8a6bb18 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-fill.js +++ b/js/src/jit-test/tests/wasm/gc/tables-fill.js @@ -134,13 +134,12 @@ function testTableFill(tbl_type, val_type, obj) { var objs = []; for (var i = 0; i < N; i++) objs[i] = {n:i}; -testTableFill('anyref', 'anyref', objs); +testTableFill('externref', 'externref', objs); var funcs = []; for (var i = 0; i < N; i++) funcs[i] = wasmEvalText(`(module (func (export "x") (result i32) (i32.const ${i})))`).exports.x; testTableFill('funcref', 'funcref', funcs); -testTableFill('anyref', 'funcref', funcs); // funcref <: anyref so implicit upcast on fill // Type errors. Required sig is: (i32, anyref, i32) -> void @@ -165,7 +164,7 @@ assertErrorMessage(() => wasmEvalText( `(module (table $t 10 anyref) (func $expected-3-args-got-2 - (table.fill $t (ref.null) (i32.const 0)) + (table.fill $t (ref.null extern) (i32.const 0)) ))`), WebAssembly.CompileError, /popping value from empty stack/); @@ -173,7 +172,7 @@ assertErrorMessage(() => wasmEvalText( `(module (table $t 10 anyref) (func $argty-1-wrong - (table.fill $t (i32.const 0) (ref.null) (f64.const 0)) + (table.fill $t (i32.const 0) (ref.null extern) (f64.const 0)) ))`), WebAssembly.CompileError, /type mismatch: expression has type f64 but expected i32/); @@ -185,13 +184,13 @@ assertErrorMessage(() => wasmEvalText( (table.fill $t (i32.const 0) (f32.const 0) (i32.const 0)) ))`), WebAssembly.CompileError, - /type mismatch: expression has type f32 but expected anyref/); + /type mismatch: expression has type f32 but expected externref/); assertErrorMessage(() => wasmEvalText( `(module (table $t 10 anyref) (func $argty-3-wrong - (table.fill $t (i64.const 0) (ref.null) (i32.const 0)) + (table.fill $t (i64.const 0) (ref.null extern) (i32.const 0)) ))`), WebAssembly.CompileError, /type mismatch: expression has type i64 but expected i32/); @@ -200,7 +199,7 @@ assertErrorMessage(() => wasmEvalText( `(module (table $t 10 anyref) (func $retty-wrong (result i32) - (table.fill $t (i32.const 0) (ref.null) (i32.const 0)) + (table.fill $t (i32.const 0) (ref.null extern) (i32.const 0)) ))`), WebAssembly.CompileError, /popping value from empty stack/); @@ -212,4 +211,4 @@ assertErrorMessage(() => wasmEvalText( (table.fill (i32.const 0) (local.get $v) (i32.const 0))) )`), WebAssembly.CompileError, - /expression has type anyref but expected funcref/); + /expression has type externref but expected funcref/); diff --git a/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js b/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js index b3dbd5e631..7ddc571c6b 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js +++ b/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js @@ -1,6 +1,6 @@ // |jit-test| skip-if: wasmReftypesEnabled() -assertErrorMessage(() => new WebAssembly.Table({element:"anyref", initial:10}), +assertErrorMessage(() => new WebAssembly.Table({element:"externref", initial:10}), TypeError, /"element" property of table descriptor must be "funcref"/); diff --git a/js/src/jit-test/tests/wasm/gc/tables-generalized-struct.js b/js/src/jit-test/tests/wasm/gc/tables-generalized-struct.js index 61fc401281..51d5e5444b 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-generalized-struct.js +++ b/js/src/jit-test/tests/wasm/gc/tables-generalized-struct.js @@ -13,7 +13,7 @@ (func (export "set_anyref") (param i32) (param anyref) (table.set (local.get 0) (local.get 1))) (func (export "set_null") (param i32) - (table.set (local.get 0) (ref.null))) + (table.set (local.get 0) (ref.null extern))) (func (export "set_ref") (param i32) (param anyref) (table.set (local.get 0) (struct.narrow anyref (ref opt $dummy) (local.get 1)))) (func (export "make_struct") (result anyref) diff --git a/js/src/jit-test/tests/wasm/gc/tables-generalized.js b/js/src/jit-test/tests/wasm/gc/tables-generalized.js index edc86a0a69..828e2e5011 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-generalized.js +++ b/js/src/jit-test/tests/wasm/gc/tables-generalized.js @@ -16,12 +16,12 @@ new WebAssembly.Module(wasmTextToBinary( new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( `(module (table (import "m" "t") 10 anyref))`)), - {m:{t: new WebAssembly.Table({element:"anyref", initial:10})}}); + {m:{t: new WebAssembly.Table({element:"externref", initial:10})}}); new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( `(module (import "m" "t" (table 10 anyref)))`)), - {m:{t: new WebAssembly.Table({element:"anyref", initial:10})}}); + {m:{t: new WebAssembly.Table({element:"externref", initial:10})}}); // Wasm: Export table-of-anyref, initial values shall be null @@ -77,33 +77,22 @@ new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( assertEq(t.get(9), objs[9]); } -// Wasm: table.copy from table(funcref) to table(anyref) should work +// Wasm: table.copy from table(funcref) to table(anyref) should not work -{ - let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( - `(module - (table (export "t") 10 anyref) - (func $f1) - (func $f2) - (func $f3) - (func $f4) - (func $f5) - (table 5 funcref) - (elem (table 1) (i32.const 0) func $f1 $f2 $f3 $f4 $f5) - (func (export "f") - (table.copy 0 1 (i32.const 5) (i32.const 0) (i32.const 5))))`))); - ins.exports.f(); - let t = ins.exports.t; - let xs = []; - for (let i=0; i < 5; i++) { - xs[i] = t.get(i+5); - assertEq(typeof xs[i], "function"); - } - for (let i=0; i < 5; i++) { - for (j=i+1; j < 5; j++) - assertEq(xs[i] != xs[j], true); - } -} +assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( + `(module + (table (export "t") 10 anyref) + (func $f1) + (func $f2) + (func $f3) + (func $f4) + (func $f5) + (table 5 funcref) + (elem (table 1) (i32.const 0) func $f1 $f2 $f3 $f4 $f5) + (func (export "f") + (table.copy 0 1 (i32.const 5) (i32.const 0) (i32.const 5))))`)), + WebAssembly.CompileError, + /expression has type funcref but expected externref/); // Wasm: table.copy from table(anyref) to table(funcref) should not work @@ -114,49 +103,41 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( (func (export "f") (table.copy 0 1 (i32.const 0) (i32.const 0) (i32.const 5))))`)), WebAssembly.CompileError, - /expression has type anyref but expected funcref/); + /expression has type externref but expected funcref/); -// Wasm: Element segments can target tables of anyref whether the element type -// is anyref or funcref. +// Wasm: Element segments of funcref can't target tables of anyref -for (let elem_ty of ["funcref", "anyref"]) { - let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( +assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module - (func $f1 (export "f") (result i32) (i32.const 0)) - (func $f2 (result i32) (i32.const 0)) ;; on purpose not exported + (func $f1 (result i32) (i32.const 0)) (table (export "t") 10 anyref) - (elem (table 0) (i32.const 0) ${elem_ty} (ref.func $f1) (ref.func $f2)) - )`))); - let t = ins.exports.t; - let f = ins.exports.f; - assertEq(t.get(0), f); - assertEq(t.get(2), null); // not much of a test since that's the default value -} + (elem 0 (i32.const 0) funcref (ref.func $f1)))`)), + WebAssembly.CompileError, + /segment's element type must be subtype of table's element type/); + // Wasm: Element segments of anyref can't target tables of funcref assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module - (func $f1 (result i32) (i32.const 0)) (table (export "t") 10 funcref) - (elem 0 (i32.const 0) anyref (ref.func $f1)))`)), + (elem 0 (i32.const 0) anyref (ref.null extern)))`)), WebAssembly.CompileError, /segment's element type must be subtype of table's element type/); -// Wasm: table.init on table-of-anyref is allowed whether the segment has -// anyrefs or funcrefs. +// Wasm: table.init on table-of-anyref is not allowed when the segment has +// funcref. -for (let elem_ty of ["funcref", "anyref"]) { - let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( +assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (func $f1 (result i32) (i32.const 0)) - (table (export "t") 10 anyref) - (elem ${elem_ty} (ref.func $f1)) - (func (export "f") - (table.init 0 (i32.const 2) (i32.const 0) (i32.const 1))))`))); - ins.exports.f(); - assertEq(typeof ins.exports.t.get(2), "function"); -} + (table 10 anyref) + (elem funcref (ref.func $f1)) + (func + (table.init 0 (i32.const 0) (i32.const 0) (i32.const 0))))`)), + WebAssembly.CompileError, + /expression has type funcref but expected externref/); + // Wasm: table.init on table-of-funcref is not allowed when the segment has // anyref. @@ -164,11 +145,11 @@ for (let elem_ty of ["funcref", "anyref"]) { assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (table 10 funcref) - (elem anyref (ref.null)) + (elem anyref (ref.null extern)) (func (table.init 0 (i32.const 0) (i32.const 0) (i32.const 0))))`)), WebAssembly.CompileError, - /expression has type anyref but expected funcref/); + /expression has type externref but expected funcref/); // Wasm: table types must match at link time @@ -196,7 +177,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( // additional js api tests { - let tbl = new WebAssembly.Table({element:"anyref", initial:10}); + let tbl = new WebAssembly.Table({element:"externref", initial:10}); // Initial value. assertEq(tbl.get(0), null); @@ -242,7 +223,7 @@ function testTableGet(type, x) { assertErrorMessage(() => ins.exports.f(10), WebAssembly.RuntimeError, /index out of bounds/); assertErrorMessage(() => ins.exports.f(-5), WebAssembly.RuntimeError, /index out of bounds/); } -testTableGet('anyref', {}); +testTableGet('externref', {}); testTableGet('funcref', wasmFun); // table.get with non-i32 index - fails validation @@ -268,14 +249,14 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( // table.set with null - works // table.set out of bounds - fails -function testTableSet(lhs_type, rhs_type, x) { +function testTableSet(lhs_type, rhs_type, rhs_reftype, x) { let ins = wasmEvalText( `(module (table (export "t") 10 ${lhs_type}) (func (export "set_ref") (param i32) (param ${rhs_type}) (table.set (local.get 0) (local.get 1))) (func (export "set_null") (param i32) - (table.set (local.get 0) (ref.null))))`); + (table.set (local.get 0) (ref.null ${rhs_reftype}))))`); ins.exports.set_ref(3, x); assertEq(ins.exports.t.get(3), x); ins.exports.set_null(3); @@ -284,9 +265,8 @@ function testTableSet(lhs_type, rhs_type, x) { assertErrorMessage(() => ins.exports.set_ref(10, x), WebAssembly.RuntimeError, /index out of bounds/); assertErrorMessage(() => ins.exports.set_ref(-1, x), WebAssembly.RuntimeError, /index out of bounds/); } -testTableSet('anyref', 'anyref', {}); -testTableSet('funcref', 'funcref', wasmFun); -testTableSet('anyref', 'funcref', wasmFun); +testTableSet('externref', 'externref', 'extern', {}); +testTableSet('funcref', 'funcref', 'func', wasmFun); // Wasm: table.set on table(funcref) with anyref value should fail @@ -296,7 +276,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( (func (export "set_ref") (param i32) (param anyref) (table.set (local.get 0) (local.get 1))))`)), WebAssembly.CompileError, - /type mismatch: expression has type anyref but expected funcref/); + /type mismatch: expression has type externref but expected funcref/); // table.set with non-i32 index - fails validation @@ -304,7 +284,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (table 10 anyref) (func (export "f") (param f64) - (table.set (local.get 0) (ref.null))))`)), + (table.set (local.get 0) (ref.null extern))))`)), WebAssembly.CompileError, /type mismatch/); @@ -334,12 +314,12 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( WebAssembly.CompileError, /table index out of range for table.set/); -function testTableGrow(lhs_type, rhs_type, x) { +function testTableGrow(lhs_type, lhs_reftype, rhs_type, x) { let ins = wasmEvalText( `(module (table (export "t") 10 20 ${lhs_type}) (func (export "grow") (param i32) (result i32) - (table.grow (ref.null) (local.get 0))) + (table.grow (ref.null ${lhs_reftype}) (local.get 0))) (func (export "grow2") (param i32) (param ${rhs_type}) (result i32) (table.grow (local.get 1) (local.get 0))))`); @@ -369,9 +349,8 @@ function testTableGrow(lhs_type, rhs_type, x) { assertEq(ins.exports.grow(-1), -1); assertEq(ins.exports.t.length, 20) } -testTableGrow('anyref', 'anyref', 42); -testTableGrow('funcref', 'funcref', wasmFun); -testTableGrow('anyref', 'funcref', wasmFun); +testTableGrow('externref', 'extern', 'externref', 42); +testTableGrow('funcref', 'func', 'funcref', wasmFun); // Wasm: table.grow on table(funcref) with anyref initializer should fail @@ -381,7 +360,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( (func (export "grow2") (param i32) (param anyref) (result i32) (table.grow (local.get 1) (local.get 0))))`)), WebAssembly.CompileError, - /type mismatch: expression has type anyref but expected funcref/); + /type mismatch: expression has type externref but expected funcref/); // Special case for private tables without a maximum @@ -390,7 +369,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (table 10 anyref) (func (export "grow") (param i32) (result i32) - (table.grow (ref.null) (local.get 0))))`); + (table.grow (ref.null extern) (local.get 0))))`); assertEq(ins.exports.grow(0), 10); assertEq(ins.exports.grow(1), 10); assertEq(ins.exports.grow(9), 11); @@ -403,7 +382,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (table 10 anyref) (func (export "f") (param f64) - (table.grow (ref.null) (local.get 0))))`)), + (table.grow (ref.null extern) (local.get 0))))`)), WebAssembly.CompileError, /type mismatch/); @@ -412,21 +391,21 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary( `(module (func (export "f") (param i32) - (table.grow (ref.null) (local.get 0))))`)), + (table.grow (ref.null extern) (local.get 0))))`)), WebAssembly.CompileError, /table index out of range for table.grow/); // table.size on table of anyref for (let visibility of ['', '(export "t")', '(import "m" "t")']) { - let exp = {m:{t: new WebAssembly.Table({element:"anyref", + let exp = {m:{t: new WebAssembly.Table({element:"externref", initial: 10, maximum: 20})}}; let ins = wasmEvalText( `(module (table ${visibility} 10 20 anyref) (func (export "grow") (param i32) (result i32) - (table.grow (ref.null) (local.get 0))) + (table.grow (ref.null extern) (local.get 0))) (func (export "size") (result i32) (table.size)))`, exp); @@ -469,7 +448,7 @@ let VALUES = [null, () => 1337]; { - let t = new WebAssembly.Table({element:"anyref", initial:0}); + let t = new WebAssembly.Table({element:"externref", initial:0}); t.grow(1); assertEq(t.get(t.length-1), null); let prev = null; @@ -499,7 +478,7 @@ let VALUES = [null, // If growing by zero elements there are no spurious writes { - let t = new WebAssembly.Table({element:"anyref", initial:1}); + let t = new WebAssembly.Table({element:"externref", initial:1}); t.set(0, 1337); t.grow(0, 1789); assertEq(t.get(0), 1337); diff --git a/js/src/jit-test/tests/wasm/gc/tables-multiple.js b/js/src/jit-test/tests/wasm/gc/tables-multiple.js index cd8f06d0a3..9dffc29d45 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-multiple.js +++ b/js/src/jit-test/tests/wasm/gc/tables-multiple.js @@ -57,9 +57,9 @@ assertEq(ins.t2.length, 3); // - table.get and table.set can point to a table var exp = {m:{t0: new WebAssembly.Table({element:"funcref", initial:2}), - t1: new WebAssembly.Table({element:"anyref", initial:3}), + t1: new WebAssembly.Table({element:"externref", initial:3}), t2: new WebAssembly.Table({element:"funcref", initial:4}), - t3: new WebAssembly.Table({element:"anyref", initial:5})}}; + t3: new WebAssembly.Table({element:"externref", initial:5})}}; var ins = wasmEvalText( `(module (table $t0 (import "m" "t0") 2 funcref) @@ -105,14 +105,14 @@ assertEq(exp.m.t3.get(4), x); // - growing a table grows the right table but not the others // - table.size on tables other than table 0 -var exp = {m:{t0: new WebAssembly.Table({element:"anyref", initial:2}), - t1: new WebAssembly.Table({element:"anyref", initial:3})}}; +var exp = {m:{t0: new WebAssembly.Table({element:"externref", initial:2}), + t1: new WebAssembly.Table({element:"externref", initial:3})}}; var ins = wasmEvalText( `(module (table $t0 (import "m" "t0") 2 anyref) (table $t1 (import "m" "t1") 3 anyref) (func (export "f") (result i32) - (table.grow $t1 (ref.null) (i32.const 5))) + (table.grow $t1 (ref.null extern) (i32.const 5))) (func (export "size0") (result i32) (table.size $t0)) (func (export "size1") (result i32) @@ -126,8 +126,8 @@ assertEq(ins.exports.size1(), 8); // - table.copy can point to tables -var exp = {m:{t0: new WebAssembly.Table({element:"anyref", initial:2}), - t1: new WebAssembly.Table({element:"anyref", initial:3})}}; +var exp = {m:{t0: new WebAssembly.Table({element:"externref", initial:2}), + t1: new WebAssembly.Table({element:"externref", initial:3})}}; var ins = wasmEvalText( `(module (table $t0 (import "m" "t0") 2 anyref) @@ -214,7 +214,7 @@ for (let [a,b,x,y,result,init] of [['$t0', '$t1', '(export "t")', '', arg*13, tr // - test the (import "m" "t" (table ...)) syntax // - if table is grown from JS, wasm can observe the growth -var tbl = new WebAssembly.Table({element:"anyref", initial:1}); +var tbl = new WebAssembly.Table({element:"externref", initial:1}); var exp = {m: {t0: tbl, t1:tbl}}; var ins = wasmEvalText( @@ -223,9 +223,9 @@ var ins = wasmEvalText( (import "m" "t1" (table $t1 1 anyref)) (table $t2 (export "t2") 1 funcref) (func (export "f") (result i32) - (table.grow $t0 (ref.null) (i32.const 1))) + (table.grow $t0 (ref.null extern) (i32.const 1))) (func (export "g") (result i32) - (table.grow $t1 (ref.null) (i32.const 1))) + (table.grow $t1 (ref.null extern) (i32.const 1))) (func (export "size") (result i32) (table.size $t2)))`, exp); @@ -369,7 +369,7 @@ assertErrorMessage(() => wasmEvalText( (table $t0 2 anyref) (table $t1 2 anyref) (func $f (result i32) - (table.grow 2 (ref.null) (i32.const 1))))`), + (table.grow 2 (ref.null extern) (i32.const 1))))`), WebAssembly.CompileError, /table index out of range for table.grow/); diff --git a/js/src/jit-test/tests/wasm/gc/tables-stress.js b/js/src/jit-test/tests/wasm/gc/tables-stress.js index 929cfe8c25..9d52f906c7 100644 --- a/js/src/jit-test/tests/wasm/gc/tables-stress.js +++ b/js/src/jit-test/tests/wasm/gc/tables-stress.js @@ -12,7 +12,7 @@ for ( let prefix of ['', '(table $prefix 0 32 funcref)']) { (local $last i32) (local $iters i32) (local $tmp anyref) - (local.set $last (table.grow $tbl (ref.null) (i32.const 1))) + (local.set $last (table.grow $tbl (ref.null extern) (i32.const 1))) (table.set $tbl (local.get $last) (call $item)) (loop $iter_continue (local.set $i (i32.const 0)) diff --git a/js/src/jit-test/tests/wasm/globals.js b/js/src/jit-test/tests/wasm/globals.js index 689d1d5a39..eaa9885424 100644 --- a/js/src/jit-test/tests/wasm/globals.js +++ b/js/src/jit-test/tests/wasm/globals.js @@ -428,7 +428,6 @@ wasmAssert(`(module // Mutability of import declaration and imported value have to match { const mutErr = /imported global mutability mismatch/; - const i64Err = /cannot pass i64 to or from JS/; let m1 = new Module(wasmTextToBinary(`(module (import "m" "g" (global i32)))`)); diff --git a/js/src/jit-test/tests/wasm/import-export-sigs.js b/js/src/jit-test/tests/wasm/import-export-sigs.js index c3b6b52202..8765d56b15 100644 --- a/js/src/jit-test/tests/wasm/import-export-sigs.js +++ b/js/src/jit-test/tests/wasm/import-export-sigs.js @@ -1,3 +1,5 @@ +// |jit-test| skip-if: fuzzingSafe() + // Tests that function imports and function exports descriptors have // signatures, in the test mode only, for fuzzers. diff --git a/js/src/jit-test/tests/wasm/import-export.js b/js/src/jit-test/tests/wasm/import-export.js index e7058d4f64..2db72ceb1e 100644 --- a/js/src/jit-test/tests/wasm/import-export.js +++ b/js/src/jit-test/tests/wasm/import-export.js @@ -16,34 +16,9 @@ const tab3Elem = new Table({initial:3, element:"funcref"}); const tab4Elem = new Table({initial:4, element:"funcref"}); function assertSegmentFitError(f) { - if (wasmBulkMemSupported()) { - assertErrorMessage(f, RuntimeError, /out of bounds/); - } else { - assertErrorMessage(f, LinkError, /segment does not fit/); - } + assertErrorMessage(f, RuntimeError, /out of bounds/); } -// Memory size consistency and internal limits. -assertErrorMessage(() => new Memory({initial:2, maximum:1}), RangeError, /bad Memory maximum size/); - -try { - new Memory({initial:16384}); -} catch(e) { - assertEq(String(e).indexOf("out of memory") !== -1, true); -} - -assertErrorMessage(() => new Memory({initial: 16385}), RangeError, /bad Memory initial size/); - -new Memory({initial: 0, maximum: 65536}); -assertErrorMessage(() => new Memory({initial: 0, maximum: 65537}), RangeError, /bad Memory maximum size/); - -// Table size consistency and internal limits. -assertErrorMessage(() => new Table({initial:2, maximum:1, element:"funcref"}), RangeError, /bad Table maximum size/); -new Table({ initial: 10000000, element:"funcref" }); -assertErrorMessage(() => new Table({initial:10000001, element:"funcref"}), RangeError, /bad Table initial size/); -new Table({ initial: 0, maximum: 10000000, element:"funcref" }); -assertErrorMessage(() => new Table({initial:0, maximum: 10000001, element:"funcref"}), RangeError, /bad Table maximum size/); - const m1 = new Module(wasmTextToBinary('(module (import "foo" "bar" (func)) (import "baz" "quux" (func)))')); assertErrorMessage(() => new Instance(m1), TypeError, /second argument must be an object/); assertErrorMessage(() => new Instance(m1, {foo:null}), TypeError, /import object field 'foo' is not an Object/); @@ -525,15 +500,11 @@ var mem8 = new Uint8Array(mem.buffer); var tbl = new Table({initial:2, element:"funcref"}); assertSegmentFitError(() => new Instance(m, {a:{mem, tbl, memOff:1, tblOff:2}})); -if (wasmBulkMemSupported()) { - // The first active element segment is applied, but the second active - // element segment is completely OOB. - assertEq(typeof tbl.get(0), "function"); - assertEq(tbl.get(1), null); -} else if (!wasmCompileMode().match("cranelift")) { - assertEq(tbl.get(0), null); - assertEq(tbl.get(1), null); -} +// The first active element segment is applied, but the second active +// element segment is completely OOB. +assertEq(typeof tbl.get(0), "function"); +assertEq(tbl.get(1), null); + assertEq(mem8[0], 0); assertEq(mem8[1], 0); @@ -541,17 +512,11 @@ tbl.set(0, null); tbl.set(1, null); assertSegmentFitError(() => new Instance(m, {a:{mem, tbl, memOff:npages*64*1024, tblOff:1}})); -if (wasmBulkMemSupported()) { - // The first and second active element segments are applied fully. The - // first active data segment applies, but the second one is completely OOB. - assertEq(typeof tbl.get(0), "function"); - assertEq(typeof tbl.get(1), "function"); - assertEq(mem8[0], 1); -} else if (!wasmCompileMode().match("cranelift")) { - assertEq(tbl.get(0), null); - assertEq(tbl.get(1), null); - assertEq(mem8[0], 0); -} +// The first and second active element segments are applied fully. The +// first active data segment applies, but the second one is completely OOB. +assertEq(typeof tbl.get(0), "function"); +assertEq(typeof tbl.get(1), "function"); +assertEq(mem8[0], 1); tbl.set(0, null); tbl.set(1, null); @@ -568,44 +533,40 @@ assertEq(tbl.get(1), i.exports.g); // Element segment doesn't apply and prevents subsequent elem segment and // data segment from being applied. -if (wasmBulkMemSupported()) { - let m = new Module(wasmTextToBinary( - `(module - (import "" "mem" (memory 1)) - (import "" "tbl" (table 3 funcref)) - (elem (i32.const 1) $f $g $h) ;; fails after $f and $g - (elem (i32.const 0) $f) ;; is not applied - (data (i32.const 0) "\\01") ;; is not applied - (func $f) - (func $g) - (func $h))`)); - let mem = new Memory({initial:1}); - let tbl = new Table({initial:3, element:"funcref"}); - assertSegmentFitError(() => new Instance(m, {"":{mem, tbl}})); - assertEq(tbl.get(0), null); - assertEq(tbl.get(1), null); - assertEq(tbl.get(2), null); - let v = new Uint8Array(mem.buffer); - assertEq(v[0], 0); -} +var m = new Module(wasmTextToBinary( + `(module + (import "" "mem" (memory 1)) + (import "" "tbl" (table 3 funcref)) + (elem (i32.const 1) $f $g $h) ;; fails after $f and $g + (elem (i32.const 0) $f) ;; is not applied + (data (i32.const 0) "\\01") ;; is not applied + (func $f) + (func $g) + (func $h))`)); +var mem = new Memory({initial:1}); +var tbl = new Table({initial:3, element:"funcref"}); +assertSegmentFitError(() => new Instance(m, {"":{mem, tbl}})); +assertEq(tbl.get(0), null); +assertEq(tbl.get(1), null); +assertEq(tbl.get(2), null); +var v = new Uint8Array(mem.buffer); +assertEq(v[0], 0); // Data segment doesn't apply and prevents subsequent data segment from // being applied. -if (wasmBulkMemSupported()) { - let m = new Module(wasmTextToBinary( - `(module - (import "" "mem" (memory 1)) - (data (i32.const 65534) "\\01\\02\\03") ;; fails after 1 and 2 - (data (i32.const 0) "\\04") ;; is not applied - )`)); - let mem = new Memory({initial:1}); - assertSegmentFitError(() => new Instance(m, {"":{mem}})); - let v = new Uint8Array(mem.buffer); - assertEq(v[65534], 0); - assertEq(v[65535], 0); - assertEq(v[0], 0); -} +var m = new Module(wasmTextToBinary( + `(module + (import "" "mem" (memory 1)) + (data (i32.const 65534) "\\01\\02\\03") ;; fails after 1 and 2 + (data (i32.const 0) "\\04") ;; is not applied + )`)); +var mem = new Memory({initial:1}); +assertSegmentFitError(() => new Instance(m, {"":{mem}})); +var v = new Uint8Array(mem.buffer); +assertEq(v[65534], 0); +assertEq(v[65535], 0); +assertEq(v[0], 0); // Elem segments on imported tables diff --git a/js/src/jit-test/tests/wasm/ion-error-i64.js b/js/src/jit-test/tests/wasm/ion-error-i64.js deleted file mode 100644 index d74b19fc7a..0000000000 --- a/js/src/jit-test/tests/wasm/ion-error-i64.js +++ /dev/null @@ -1,97 +0,0 @@ -// |jit-test| skip-if: !getJitCompilerOptions()['baseline.enable'] || wasmBigIntEnabled() -// These tests need at least baseline to make sense. - -const { nextLineNumber, startProfiling, endProfiling, assertEqPreciseStacks } = WasmHelpers; - -const options = getJitCompilerOptions(); -const TRIGGER = options['ion.warmup.trigger'] + 10; -const ITER = 2 * TRIGGER; -const EXCEPTION_ITER = ITER - 2; - -var instance = wasmEvalText(`(module - (func (export "add") (param i32) (param i32) (result i32) - local.get 0 - local.get 1 - i32.add - ) - - (func (export "add64") (param i32) (param i32) (result i64) - local.get 0 - local.get 1 - call 0 - i64.extend_s/i32 - ) - - (func (export "add_two_i64") (param i64) (param i64) (result i64) - local.get 0 - local.get 1 - i64.add - ) -)`).exports; - -(function() { - // In ion-eager mode, make sure we don't try to inline a function that - // takes or returns i64 arguments. - assertErrorMessage(() => instance.add_two_i64(0n, 1n), TypeError, /cannot pass i64 to or from JS/); -})(); - -enableGeckoProfiling(); - -var callToMain; - -function main() { - var arrayCallLine = nextLineNumber(13); - for (var i = 0; i < ITER; i++) { - var arr = [instance.add, (x,y)=>x+y]; - if (i === EXCEPTION_ITER) { - arr[0] = instance.add64; - } else if (i === EXCEPTION_ITER + 1) { - arr[0] = instance.add; - } - - var caught = null; - - startProfiling(); - try { - arr[i%2](i, i); - } catch(e) { - caught = e; - } - let profilingStack = endProfiling(); - - assertEq(!!caught, i === EXCEPTION_ITER); - if (caught) { - assertEqPreciseStacks(profilingStack, [ - // Error stack: control flow is redirected to a builtin thunk - // then calling into C++ from the wasm entry before jumping to - // the wasm jit entry exception handler. - ['', '>', '<,>', 'i64>,>', '<,>', '>', ''], - [''] // the jit path wasn't taken (interpreter/baseline only). - ]); - - assertEq(caught.message, 'cannot pass i64 to or from JS'); - - let stack = caught.stack.split('\n'); - - // Which callsites appear on the error stack. - let callsites = stack.map(s => s.split('@')[0]); - assertEq(callsites[0], 'main'); - assertEq(callsites[1], ''); // global scope - - // Which line numbers appear in the error stack. - let lines = stack.map(s => s.split(':')[1]); - assertEq(+lines[0], arrayCallLine); - assertEq(+lines[1], callToMain); - } else if ((i % 2) == 0) { - // Regular call to wasm add on 32 bits integers. - assertEqPreciseStacks(profilingStack, [ - ['', '0', ''], // supa-dupa fast path - ['', '>', '0,>', '>', ''], // fast path - ['', '!>', '0,!>', '!>', ''], // slow path - ]); - } - } -} - -callToMain = nextLineNumber(); -main(); diff --git a/js/src/jit-test/tests/wasm/limits.js b/js/src/jit-test/tests/wasm/limits.js new file mode 100644 index 0000000000..152f7d25bc --- /dev/null +++ b/js/src/jit-test/tests/wasm/limits.js @@ -0,0 +1,230 @@ +// Tests of limits of memory and table types + +const PageSize = 65536; +const MemoryMaxValid = 65536; +const MemoryMaxRuntime = Math.floor(0x7fff_ffff / PageSize); + +const TableMaxValid = 0xffff_ffff; +const TableMaxRuntime = 10_000_000; + +// Test that a memory type is valid within a module +function testMemoryValidate(initial, maximum, shared) { + wasmValidateText(`(module + (memory ${initial} ${maximum || ''} ${shared ? 'shared' : ''}) + )`); +} + +testMemoryValidate(0, undefined, false); +testMemoryValidate(1, undefined, false); +testMemoryValidate(0, 1, false); +testMemoryValidate(0, 1, true); +testMemoryValidate(1, 1, false); +testMemoryValidate(1, 1, true); +testMemoryValidate(MemoryMaxValid, undefined, false); +testMemoryValidate(MemoryMaxValid, MemoryMaxValid, false); +testMemoryValidate(MemoryMaxValid, MemoryMaxValid, true); + +// Test that a memory type is not valid within a module +function testMemoryFailValidate(initial, maximum, shared, pattern) { + wasmFailValidateText(`(module + (memory ${initial} ${maximum || ''} ${shared ? 'shared' : ''}) + )`, pattern); +} + +testMemoryFailValidate(2, 1, false, /size minimum must not be greater than maximum/); +testMemoryFailValidate(1, undefined, true, /maximum length required for shared memory/); +testMemoryFailValidate(MemoryMaxValid + 1, undefined, false, /initial memory size too big/); +testMemoryFailValidate(MemoryMaxValid, MemoryMaxValid + 1, false, /maximum memory size too big/); +testMemoryFailValidate(MemoryMaxValid, MemoryMaxValid + 1, true, /maximum memory size too big/); + +// Test that a memory type is invalid for constructing a WebAssembly.Memory +function testMemoryFailConstruct(initial, maximum, shared, pattern) { + assertErrorMessage(() => new WebAssembly.Memory({ + initial, + maximum, + shared + }), RangeError, pattern); +} + +testMemoryFailConstruct(MemoryMaxValid + 1, undefined, false, /bad Memory initial size/); +testMemoryFailConstruct(0, MemoryMaxValid + 1, false, /bad Memory maximum size/); +testMemoryFailConstruct(MemoryMaxValid + 1, undefined, true, /bad Memory initial size/); +testMemoryFailConstruct(0, MemoryMaxValid + 1, true, /bad Memory maximum size/); + +// Test that a memory type can be instantiated within a module or constructed +// with a WebAssembly.Memory +function testMemoryCreate(initial, maximum, shared) { + // May OOM, but must not fail to validate + try { + wasmEvalText(`(module + (memory ${initial} ${maximum || ''} ${shared ? 'shared' : ''}) + )`); + } catch (e) { + assertEq(String(e).indexOf("out of memory") !== -1, true, `${e}`); + } + try { + new WebAssembly.Memory({initial, maximum, shared}); + } catch (e) { + assertEq(String(e).indexOf("out of memory") !== -1, true, `${e}`); + } +} + +testMemoryCreate(0, undefined, false); +testMemoryCreate(1, undefined, false); +testMemoryCreate(0, 1, false); +testMemoryCreate(0, 1, true); +testMemoryCreate(1, 1, false); +testMemoryCreate(1, 1, true); +testMemoryCreate(MemoryMaxRuntime, undefined, false); +testMemoryCreate(MemoryMaxRuntime, MemoryMaxValid, false); +testMemoryCreate(MemoryMaxRuntime, MemoryMaxValid, true); + +// Test that a memory type cannot be instantiated within a module or constructed +// with a WebAssembly.Memory +function testMemoryFailCreate(initial, maximum, shared, pattern) { + assertErrorMessage(() => wasmEvalText(`(module + (memory ${initial} ${maximum || ''} ${shared ? 'shared' : ''}) + )`), WebAssembly.RuntimeError, pattern); + assertErrorMessage(() => new WebAssembly.Memory({ + initial, + maximum, + shared + }), WebAssembly.RuntimeError, pattern); +} + +testMemoryFailCreate(MemoryMaxRuntime + 1, undefined, false, /too many memory pages/); +testMemoryFailCreate(MemoryMaxRuntime + 1, MemoryMaxValid, false, /too many memory pages/); +testMemoryFailCreate(MemoryMaxRuntime + 1, MemoryMaxValid, true, /too many memory pages/); + +// Test that a memory type cannot be grown from initial to a target due to an +// implementation limit +function testMemoryFailGrow(initial, maximum, target, shared) { + let {run} = wasmEvalText(`(module + (memory ${initial} ${maximum || ''} ${shared ? 'shared' : ''}) + (func (export "run") (result i32) + i32.const ${target - initial} + memory.grow + ) + )`).exports; + assertEq(run(), -1, 'failed to grow'); + + let mem = new WebAssembly.Memory({ + initial, + maximum, + shared + }); + assertErrorMessage(() => mem.grow(target - initial), RangeError, /failed to grow memory/); +} + +testMemoryFailGrow(1, undefined, MemoryMaxRuntime + 1, false); +testMemoryFailGrow(1, MemoryMaxValid, MemoryMaxRuntime + 1, false); +testMemoryFailGrow(1, MemoryMaxValid, MemoryMaxRuntime + 1, true); + +// Test that a table type is valid within a module +function testTableValidate(initial, maximum) { + wasmValidateText(`(module + (table ${initial} ${maximum || ''} anyfunc) + )`); +} + +testTableValidate(0, undefined); +testTableValidate(1, undefined); +testTableValidate(0, 1); +testTableValidate(1, 1); +testTableValidate(TableMaxValid, undefined); +testTableValidate(TableMaxValid, TableMaxValid); + +// Test that a table type is not valid within a module +function testTableFailValidate(initial, maximum, pattern) { + wasmFailValidateText(`(module + (table ${initial} ${maximum || ''} anyfunc) + )`, pattern); +} + +testTableFailValidate(2, 1, /size minimum must not be greater than maximum/); +// The maximum valid table value is equivalent to the maximum encodable limit +// value, so we cannot test too large of a table limit in a module. +assertEq(TableMaxValid + 1 > 0xffffffff, true); + +// Test that a table type is invalid for constructing a WebAssembly.Table +function testTableFailConstruct(initial, maximum, pattern) { + assertErrorMessage(() => new WebAssembly.Table({ + initial, + maximum, + element: 'anyfunc', + }), TypeError, pattern); +} + +testTableFailConstruct(TableMaxValid + 1, undefined, /bad Table initial size/); +testTableFailConstruct(0, TableMaxValid + 1, /bad Table maximum size/); + +// Test that a table type can be instantiated within a module or constructed +// with a WebAssembly.Table +function testTableCreate(initial, maximum) { + // May OOM, but must not fail to validate + try { + wasmEvalText(`(module + (table ${initial} ${maximum || ''} anyfunc) + )`); + } catch (e) { + assertEq(String(e).indexOf("out of memory") !== -1, true, `${e}`); + } + try { + new WebAssembly.Table({ + initial, + maximum, + element: 'anyfunc', + }); + } catch (e) { + assertEq(String(e).indexOf("out of memory") !== -1, true, `${e}`); + } +} + +testTableCreate(0, undefined); +testTableCreate(1, undefined); +testTableCreate(0, 1); +testTableCreate(1, 1); +testTableCreate(TableMaxRuntime, undefined); +testTableCreate(TableMaxRuntime, TableMaxValid); + +// Test that a table type cannot be instantiated within a module or constructed +// with a WebAssembly.Table +function testTableFailCreate(initial, maximum, pattern) { + assertErrorMessage(() => wasmEvalText(`(module + (table ${initial} ${maximum || ''} anyfunc) + )`), WebAssembly.RuntimeError, pattern); + assertErrorMessage(() => new WebAssembly.Table({ + initial, + maximum, + element: 'anyfunc', + }), WebAssembly.RuntimeError, pattern); +} + +testTableFailCreate(TableMaxRuntime + 1, undefined, /too many table elements/); +testTableFailCreate(TableMaxRuntime + 1, TableMaxValid, /too many table elements/); + +if (wasmReftypesEnabled()) { + // Test that a table type cannot be grown from initial to a target due to an + // implementation limit + function testTableFailGrow(initial, maximum, target) { + let {run} = wasmEvalText(`(module + (table ${initial} ${maximum || ''} externref) + (func (export "run") (result i32) + ref.null extern + i32.const ${target - initial} + table.grow + ) + )`).exports; + assertEq(run(), -1, 'failed to grow'); + + let tab = new WebAssembly.Table({ + initial, + maximum, + element: 'externref', + }); + assertErrorMessage(() => tab.grow(target - initial), RangeError, /failed to grow table/); + } + + testTableFailGrow(1, undefined, TableMaxRuntime + 1); + testTableFailGrow(1, TableMaxValid, TableMaxRuntime + 1); +} diff --git a/js/src/jit-test/tests/wasm/multi-value/call-js.js b/js/src/jit-test/tests/wasm/multi-value/call-js.js index f7bf554b4a..7af031e5f0 100644 --- a/js/src/jit-test/tests/wasm/multi-value/call-js.js +++ b/js/src/jit-test/tests/wasm/multi-value/call-js.js @@ -9,17 +9,15 @@ wasmFullPass(` 42, { env: { f: () => [52, 10, 0] } }); -if (wasmBigIntEnabled()) { - wasmFullPass(` - (module - (import "env" "f" (func $f (result i64 i64 i64))) - (func (export "run") (result i64) - (call $f) - i64.sub - i64.sub))`, - 42n, - { env: { f: () => [52n, 10n, 0n] } }); -} +wasmFullPass(` + (module + (import "env" "f" (func $f (result i64 i64 i64))) + (func (export "run") (result i64) + (call $f) + i64.sub + i64.sub))`, + 42n, + { env: { f: () => [52n, 10n, 0n] } }); wasmFullPass(` (module @@ -120,23 +118,21 @@ expectMultiValueResult(` (f64.const 52.5) (f64.const 10.5)))`, [0.5, 52.5, 10.5]); -if (wasmBigIntEnabled()) { - expectMultiValueResult(` - (module - (func (export "run") (result i32 i64 i32) - (i32.const 0) - (i64.const 52) - (i32.const 10)))`, [0, 52n, 10]); - expectMultiValueResult(` - (module - (func (export "run") (result i64 i32 i64) - (i64.const 0) - (i32.const 52) - (i64.const 10)))`, [0n, 52, 10n]); - expectMultiValueResult(` - (module - (func (export "run") (result i64 i64 i64) - (i64.const 0) - (i64.const 52) - (i64.const 10)))`, [0n, 52n, 10n]); -} +expectMultiValueResult(` + (module + (func (export "run") (result i32 i64 i32) + (i32.const 0) + (i64.const 52) + (i32.const 10)))`, [0, 52n, 10]); +expectMultiValueResult(` + (module + (func (export "run") (result i64 i32 i64) + (i64.const 0) + (i32.const 52) + (i64.const 10)))`, [0n, 52, 10n]); +expectMultiValueResult(` + (module + (func (export "run") (result i64 i64 i64) + (i64.const 0) + (i64.const 52) + (i64.const 10)))`, [0n, 52n, 10n]); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js b/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js new file mode 100644 index 0000000000..4ba4b3b116 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js @@ -0,0 +1,19 @@ +wasmFullPass(` + ;; Iterative factorial without locals. + (func $pick0 (param i64) (result i64 i64) + (local.get 0) (local.get 0) + ) + (func $pick1 (param i64 i64) (result i64 i64 i64) + (local.get 0) (local.get 1) (local.get 0) + ) + (func (export "run") (param i64) (result i64) + (i64.const 1) (local.get 0) + (loop $l (param i64 i64) (result i64) + (call $pick1) (call $pick1) (i64.mul) + (call $pick1) (i64.const 1) (i64.sub) + (call $pick0) (i64.const 0) (i64.gt_u) + (br_if $l) + (drop) (return) + ) + )`, + 7034535277573963776n, {}, 25n); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js b/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js new file mode 100644 index 0000000000..dc9aaf264c --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js @@ -0,0 +1,20 @@ +wasmFullPass(` +(module + (func $f (result i64 i64 i64 i64 i64 + i64 i64 i64 i64 i64) + (i64.const 0) + (i64.const 1) + (i64.const 2) + (i64.const 3) + (i64.const 4) + (i64.const 5) + (i64.const 6) + (i64.const 7) + (i64.const 8) + (i64.const 9)) + (func (export "run") (result i32) + (call $f) + (i64.add) (i64.add) (i64.add) (i64.add) (i64.add) + (i64.add) (i64.add) (i64.add) (i64.add) + (i32.wrap_i64)))`, + 45); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js b/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js index ed0c185b78..486b980a6d 100644 --- a/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js @@ -1,7 +1,9 @@ +// |jit-test| skip-if: !wasmReftypesEnabled() + let instance = wasmEvalText(` (func $twoRefs (result anyref anyref) - (ref.null) - (ref.null)) + (ref.null extern) + (ref.null extern)) (func $fourRefs (export "run") (result anyref anyref anyref anyref anyref anyref) call $twoRefs call $twoRefs diff --git a/js/src/jit-test/tests/wasm/no-movwt.js b/js/src/jit-test/tests/wasm/no-movwt.js deleted file mode 100644 index ce6ba064f4..0000000000 --- a/js/src/jit-test/tests/wasm/no-movwt.js +++ /dev/null @@ -1,8 +0,0 @@ -setARMHwCapFlags('vfp'); - -if (typeof WebAssembly !== "undefined") { - var i = new WebAssembly.Instance( - new WebAssembly.Module( - wasmTextToBinary('(module (func (export "") (result i32) (i32.const 42)))'))); - assertEq(i.exports[""](), 42); -} diff --git a/js/src/jit-test/tests/wasm/passive-segs-boundary.js b/js/src/jit-test/tests/wasm/passive-segs-boundary.js index 9d0a1e1188..5a9c29ebc3 100644 --- a/js/src/jit-test/tests/wasm/passive-segs-boundary.js +++ b/js/src/jit-test/tests/wasm/passive-segs-boundary.js @@ -1,5 +1,3 @@ -// |jit-test| skip-if: !wasmBulkMemSupported() - // Perform a test which, // // * if errKind is defined, is expected to fail with an exception diff --git a/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js b/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js index 314e7af246..4cbb9615b3 100644 --- a/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js +++ b/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js @@ -1,5 +1,3 @@ -// |jit-test| skip-if: !wasmBulkMemSupported() - load(libdir + "wasm-binary.js"); const v2vSig = {args:[], ret:VoidCode}; diff --git a/js/src/jit-test/tests/wasm/passive-segs-partial-mem.js b/js/src/jit-test/tests/wasm/passive-segs-partial-mem.js index 5344e4dbc1..5e9351ef8a 100644 --- a/js/src/jit-test/tests/wasm/passive-segs-partial-mem.js +++ b/js/src/jit-test/tests/wasm/passive-segs-partial-mem.js @@ -1,5 +1,3 @@ -// |jit-test| skip-if: !wasmBulkMemSupported() - let conf = getBuildConfiguration(); if (conf.debug && (conf["arm-simulator"] || conf["arm64-simulator"] || diff --git a/js/src/jit-test/tests/wasm/passive-segs-partial-table.js b/js/src/jit-test/tests/wasm/passive-segs-partial-table.js index 1a02a22663..2d2e8fcf72 100644 --- a/js/src/jit-test/tests/wasm/passive-segs-partial-table.js +++ b/js/src/jit-test/tests/wasm/passive-segs-partial-table.js @@ -1,5 +1,3 @@ -// |jit-test| skip-if: !wasmBulkMemSupported() - // Sundry test cases for the "partial write" bounds checking semantics. // table.init: out of bounds of the table or the element segment, and should diff --git a/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js b/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js new file mode 100644 index 0000000000..6bd88e95bc --- /dev/null +++ b/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js @@ -0,0 +1,15 @@ +// |jit-test| --fuzzing-safe; skip-if: this.getErrorNotes +// +// The meaning of the line above is that the test case is to be run only with +// --fuzzing-safe and only if that setting (or similar settings) is effectful. + +WebAssembly.Module.exports(new WebAssembly.Module(wasmTextToBinary(` +(module + (func (;0;)) + (func (;1;)) + (func (;2;)) + (func (;3;) (result i32) + i32.const 42) + (export "memo" (func 3)) + (export "main" (func 3))) +`))); diff --git a/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js b/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js index 0fb2625483..f7592b14fb 100644 --- a/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js +++ b/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js @@ -1,5 +1,3 @@ -// |jit-test| --no-wasm-bigint - (function coerceinplace() { var { table } = wasmEvalText(`(module (func $add (param i32) (param i32) (result i32) @@ -13,45 +11,3 @@ table.get(0)((true).get++, i*2+1); } })(); - -(function reporti64() { - var instance = wasmEvalText(`(module - (func $add (export "add") (param i32) (param i32) (result i32) - local.get 0 - local.get 1 - i32.add - ) - - (func $addi64 (param i32) (param i32) (result i64) - local.get 0 - local.get 1 - call $add - i64.extend_s/i32 - ) - - (table (export "table") 10 funcref) - (elem (i32.const 0) $add $addi64) - )`).exports; - - const EXCEPTION_ITER = 50; - - for (var i = 0; i < 100; i++) { - var caught = null; - - var arr = [instance.add, (x,y)=>x+y]; - if (i === EXCEPTION_ITER) { - arr[0] = instance.table.get(1); - } else if (i === EXCEPTION_ITER + 1) { - arr[0] = instance.add; - } - - try { - arr[i%2](i, i); - } catch(e) { - caught = e; - print(e); - } - - assertEq(!!caught, i === EXCEPTION_ITER); - } -})(); diff --git a/js/src/jit-test/tests/wasm/resizing.js b/js/src/jit-test/tests/wasm/resizing.js index d2a25e3fdc..544efdc37e 100644 --- a/js/src/jit-test/tests/wasm/resizing.js +++ b/js/src/jit-test/tests/wasm/resizing.js @@ -125,6 +125,10 @@ assertEq(mem.buffer.byteLength, 2 * 64*1024); assertErrorMessage(() => mem.grow(1), RangeError, /failed to grow memory/); assertEq(mem.buffer.byteLength, 2 * 64*1024); +// Do not misinterpret the maximum @ max for the current size. + +(new WebAssembly.Memory({initial: 1, maximum: 65536})).grow(1) + // ====== // TABLE // ====== diff --git a/js/src/jit-test/tests/wasm/spec/README.md b/js/src/jit-test/tests/wasm/spec/README.md new file mode 100644 index 0000000000..56e9623ef7 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/README.md @@ -0,0 +1 @@ +# Wasm Spec Tests\n\nThese tests are autogenerated using a tool, do not edit.\n\nSee `jit-test/etc/wasm/` for more information. diff --git a/js/src/jit-test/tests/wasm/spec/br_table.wast.js b/js/src/jit-test/tests/wasm/spec/br_table.wast.js deleted file mode 100644 index 9b96a19a67..0000000000 --- a/js/src/jit-test/tests/wasm/spec/br_table.wast.js +++ /dev/null @@ -1,504 +0,0 @@ - -// br_table.wast:3 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x08\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x01\x7f\x03\xc6\x80\x80\x80\x00\x45\x01\x01\x01\x01\x01\x02\x03\x04\x05\x06\x06\x06\x06\x06\x06\x06\x01\x01\x01\x02\x02\x02\x02\x02\x01\x02\x02\x01\x02\x02\x03\x02\x07\x07\x07\x07\x02\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x04\x03\x02\x02\x02\x02\x04\x02\x03\x02\x02\x02\x02\x02\x06\x06\x06\x06\x06\x06\x06\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xaa\x89\x80\x80\x00\x43\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x01\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x02\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x03\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x04\x0e\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x05\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x06\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x07\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x08\x05\x65\x6d\x70\x74\x79\x00\x09\x0b\x65\x6d\x70\x74\x79\x2d\x76\x61\x6c\x75\x65\x00\x0a\x09\x73\x69\x6e\x67\x6c\x65\x74\x6f\x6e\x00\x0b\x0f\x73\x69\x6e\x67\x6c\x65\x74\x6f\x6e\x2d\x76\x61\x6c\x75\x65\x00\x0c\x08\x6d\x75\x6c\x74\x69\x70\x6c\x65\x00\x0d\x0e\x6d\x75\x6c\x74\x69\x70\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x0e\x05\x6c\x61\x72\x67\x65\x00\x0f\x0e\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x66\x69\x72\x73\x74\x00\x10\x0c\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6d\x69\x64\x00\x11\x0d\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6c\x61\x73\x74\x00\x12\x0e\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x61\x6c\x75\x65\x00\x13\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x14\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x15\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x16\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x17\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x63\x6f\x6e\x64\x00\x18\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x19\x13\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x1a\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x69\x6e\x64\x65\x78\x00\x1b\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x1c\x17\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x1d\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x1e\x0a\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x00\x1f\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x20\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x21\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x22\x10\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x73\x65\x63\x6f\x6e\x64\x00\x23\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x63\x6f\x6e\x64\x00\x24\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x66\x69\x72\x73\x74\x00\x26\x0b\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6d\x69\x64\x00\x27\x0c\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6c\x61\x73\x74\x00\x28\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x29\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x2a\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x2b\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x75\x6e\x63\x00\x2c\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x2d\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x2e\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x2f\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x30\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x31\x10\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x32\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x76\x61\x6c\x75\x65\x00\x33\x11\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x34\x0f\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x76\x61\x6c\x75\x65\x00\x35\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x36\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x37\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x38\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x39\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x3a\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x3b\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x3c\x13\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x73\x69\x7a\x65\x00\x3d\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x61\x6c\x75\x65\x00\x3e\x0f\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x3f\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x40\x17\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x41\x15\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x42\x1b\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x43\x1a\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x6f\x6f\x70\x2d\x62\x6c\x6f\x63\x6b\x00\x44\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x25\x0a\xe7\xcd\x81\x80\x00\x45\x82\x80\x80\x80\x00\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0e\x01\x00\x00\x68\x1a\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0e\x01\x00\x00\x7a\x1a\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0e\x01\x00\x00\x8c\x1a\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0e\x01\x00\x00\x9a\x1a\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x00\x0e\x01\x00\x00\x68\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7e\x42\x02\x41\x00\x0e\x01\x00\x00\x7a\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x40\x40\x41\x00\x0e\x01\x00\x00\x8c\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7c\x44\x00\x00\x00\x00\x00\x00\x10\x40\x41\x00\x0e\x01\x00\x00\x9a\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x40\x20\x00\x0e\x00\x00\x41\x15\x0f\x0b\x41\x16\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x21\x20\x00\x0e\x00\x00\x41\x1f\x0b\x0b\x96\x80\x80\x80\x00\x00\x02\x40\x02\x40\x20\x00\x0e\x01\x01\x00\x41\x15\x0f\x0b\x41\x14\x0f\x0b\x41\x16\x0b\x96\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x21\x20\x00\x0e\x01\x00\x01\x41\x1f\x0f\x0b\x1a\x41\x20\x0b\x0b\xb1\x80\x80\x80\x00\x00\x02\x40\x02\x40\x02\x40\x02\x40\x02\x40\x20\x00\x0e\x04\x03\x02\x01\x00\x04\x41\xe3\x00\x0f\x0b\x41\xe4\x00\x0f\x0b\x41\xe5\x00\x0f\x0b\x41\xe6\x00\x0f\x0b\x41\xe7\x00\x0f\x0b\x41\xe8\x00\x0b\xcd\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x41\xc8\x01\x20\x00\x0e\x04\x03\x02\x01\x00\x04\x20\x01\x41\xe3\x00\x6a\x0f\x0b\x21\x01\x20\x01\x41\x0a\x6a\x0f\x0b\x21\x01\x20\x01\x41\x0b\x6a\x0f\x0b\x21\x01\x20\x01\x41\x0c\x6a\x0f\x0b\x21\x01\x20\x01\x41\x0d\x6a\x0f\x0b\x21\x01\x20\x01\x41\x0e\x6a\x0b\xbf\xc0\x81\x80\x00\x00\x02\x40\x02\x40\x20\x00\x0e\xa7\xc0\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x41\x7f\x0f\x0b\x41\x00\x0f\x0b\x41\x01\x0f\x0b\x8e\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0e\x02\x00\x00\x00\x10\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x40\x10\x00\x41\x00\x0e\x02\x00\x00\x00\x10\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x40\x01\x10\x00\x41\x00\x0e\x02\x00\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x01\x10\x00\x41\x02\x41\x00\x0e\x02\x00\x00\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x03\x7f\x41\x03\x41\x00\x0e\x01\x01\x01\x41\x01\x0b\x0b\x92\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x41\x04\x41\x7f\x0e\x02\x01\x01\x01\x41\x02\x0b\x0b\x91\x80\x80\x80\x00\x00\x03\x7f\x01\x10\x00\x41\x05\x41\x01\x0e\x02\x01\x01\x01\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x09\x41\x00\x0e\x00\x00\x0c\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x02\x00\x00\x00\x0d\x00\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x08\x41\x00\x0e\x00\x00\x41\x01\x0d\x00\x1a\x41\x07\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x09\x41\x00\x0e\x01\x00\x00\x0d\x00\x1a\x41\x07\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x00\x00\x0e\x02\x00\x00\x00\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x00\x0e\x00\x00\x41\x01\x0e\x02\x00\x00\x00\x41\x07\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x0b\x41\x01\x0e\x00\x00\x0e\x01\x00\x00\x41\x07\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7e\x42\x07\x41\x00\x0e\x00\x00\x0f\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x0e\x00\x00\x04\x7f\x41\x00\x05\x41\x01\x0b\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x41\x03\x41\x00\x0e\x00\x01\x05\x20\x01\x0b\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x20\x01\x05\x41\x04\x41\x00\x0e\x01\x01\x00\x0b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x05\x41\x00\x0e\x00\x00\x20\x00\x20\x01\x1b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x41\x06\x41\x01\x0e\x00\x00\x20\x01\x1b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x07\x41\x01\x0e\x00\x00\x1b\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x7f\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x0c\x41\x01\x0e\x00\x00\x41\x02\x41\x03\x10\x25\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x0d\x41\x01\x0e\x00\x00\x41\x03\x10\x25\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x0e\x41\x01\x0e\x00\x00\x10\x25\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x41\x14\x41\x01\x0e\x00\x00\x41\x01\x41\x02\x41\x03\x11\x00\x00\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x15\x41\x01\x0e\x00\x00\x41\x02\x41\x03\x11\x00\x00\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x16\x41\x01\x0e\x00\x00\x41\x03\x11\x00\x00\x0b\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x02\x41\x17\x41\x01\x0e\x00\x00\x11\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x01\x01\x7d\x02\x7f\x41\x11\x41\x01\x0e\x00\x00\x21\x00\x41\x7f\x0b\x0b\x92\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x01\x41\x01\x0e\x00\x00\x21\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0e\x00\x00\x24\x00\x41\x7f\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7d\x43\x9a\x99\xd9\x3f\x41\x01\x0e\x00\x00\x2a\x02\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7e\x42\x1e\x41\x01\x0e\x00\x00\x30\x00\x00\x0b\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x41\x1e\x41\x01\x0e\x00\x00\x44\x00\x00\x00\x00\x00\x00\x1c\x40\x39\x03\x00\x41\x7f\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x1f\x41\x01\x0e\x00\x00\x37\x03\x00\x41\x7f\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x20\x41\x00\x0e\x00\x00\x41\x07\x3a\x00\x00\x41\x7f\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x21\x41\x00\x0e\x00\x00\x3d\x01\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7d\x43\x9a\x99\x59\x40\x41\x00\x0e\x00\x00\x8c\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x03\x41\x00\x0e\x01\x00\x00\x41\x0a\x6a\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7e\x42\x0a\x42\x2d\x41\x00\x0e\x00\x00\x7d\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x2c\x41\x00\x0e\x00\x00\x45\x0b\x0b\x97\x80\x80\x80\x00\x00\x02\x7f\x41\x2b\x41\x00\x0e\x01\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x65\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x43\x00\x00\x20\x41\x41\x2a\x41\x00\x0e\x00\x00\x5c\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x29\x41\x00\x0e\x00\x00\xa7\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x28\x41\x00\x0e\x00\x00\x40\x00\x0b\x0b\xa3\x80\x80\x80\x00\x00\x02\x7f\x41\x7f\x1a\x41\x01\x02\x7f\x41\x02\x02\x7f\x41\x04\x1a\x41\x08\x41\x10\x20\x00\x0e\x02\x00\x01\x02\x6a\x0b\x6a\x0b\x6a\x0b\x0b\xa2\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x20\x00\x0e\x02\x02\x01\x00\x0c\x00\x0b\x1a\x41\x10\x0b\x6a\x0b\x0b\xa7\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x20\x00\x0e\x02\x00\x01\x02\x41\x01\x0d\x00\x1a\x41\x20\x0b\x1a\x41\x10\x0b\x6a\x0b\x0b\x9e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x41\x08\x20\x00\x0e\x02\x00\x01\x00\x0d\x00\x1a\x41\x10\x0b\x6a\x0b\x0b\xa7\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x20\x00\x0e\x02\x00\x01\x02\x41\x01\x0e\x00\x00\x41\x20\x0b\x1a\x41\x10\x0b\x6a\x0b\x0b\x9e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x41\x08\x20\x00\x0e\x02\x00\x01\x00\x0e\x00\x00\x41\x10\x0b\x6a\x0b\x0b\xa2\x80\x80\x80\x00\x00\x03\x7f\x02\x40\x20\x00\x0e\x02\x01\x00\x00\x0b\x41\x00\x0b\x21\x00\x03\x7f\x02\x40\x20\x00\x0e\x02\x00\x01\x01\x0b\x41\x03\x0b\x0b"); - -// br_table.wast:1247 -assert_return(() => call($1, "type-i32", [])); - -// br_table.wast:1248 -assert_return(() => call($1, "type-i64", [])); - -// br_table.wast:1249 -assert_return(() => call($1, "type-f32", [])); - -// br_table.wast:1250 -assert_return(() => call($1, "type-f64", [])); - -// br_table.wast:1252 -assert_return(() => call($1, "type-i32-value", []), 1); - -// br_table.wast:1253 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i64-value", []), int64("2")) - -// br_table.wast:1254 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f32-value", []), 3.) - -// br_table.wast:1255 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64-value", []), 4.) - -// br_table.wast:1257 -assert_return(() => call($1, "empty", [0]), 22); - -// br_table.wast:1258 -assert_return(() => call($1, "empty", [1]), 22); - -// br_table.wast:1259 -assert_return(() => call($1, "empty", [11]), 22); - -// br_table.wast:1260 -assert_return(() => call($1, "empty", [-1]), 22); - -// br_table.wast:1261 -assert_return(() => call($1, "empty", [-100]), 22); - -// br_table.wast:1262 -assert_return(() => call($1, "empty", [-1]), 22); - -// br_table.wast:1264 -assert_return(() => call($1, "empty-value", [0]), 33); - -// br_table.wast:1265 -assert_return(() => call($1, "empty-value", [1]), 33); - -// br_table.wast:1266 -assert_return(() => call($1, "empty-value", [11]), 33); - -// br_table.wast:1267 -assert_return(() => call($1, "empty-value", [-1]), 33); - -// br_table.wast:1268 -assert_return(() => call($1, "empty-value", [-100]), 33); - -// br_table.wast:1269 -assert_return(() => call($1, "empty-value", [-1]), 33); - -// br_table.wast:1271 -assert_return(() => call($1, "singleton", [0]), 22); - -// br_table.wast:1272 -assert_return(() => call($1, "singleton", [1]), 20); - -// br_table.wast:1273 -assert_return(() => call($1, "singleton", [11]), 20); - -// br_table.wast:1274 -assert_return(() => call($1, "singleton", [-1]), 20); - -// br_table.wast:1275 -assert_return(() => call($1, "singleton", [-100]), 20); - -// br_table.wast:1276 -assert_return(() => call($1, "singleton", [-1]), 20); - -// br_table.wast:1278 -assert_return(() => call($1, "singleton-value", [0]), 32); - -// br_table.wast:1279 -assert_return(() => call($1, "singleton-value", [1]), 33); - -// br_table.wast:1280 -assert_return(() => call($1, "singleton-value", [11]), 33); - -// br_table.wast:1281 -assert_return(() => call($1, "singleton-value", [-1]), 33); - -// br_table.wast:1282 -assert_return(() => call($1, "singleton-value", [-100]), 33); - -// br_table.wast:1283 -assert_return(() => call($1, "singleton-value", [-1]), 33); - -// br_table.wast:1285 -assert_return(() => call($1, "multiple", [0]), 103); - -// br_table.wast:1286 -assert_return(() => call($1, "multiple", [1]), 102); - -// br_table.wast:1287 -assert_return(() => call($1, "multiple", [2]), 101); - -// br_table.wast:1288 -assert_return(() => call($1, "multiple", [3]), 100); - -// br_table.wast:1289 -assert_return(() => call($1, "multiple", [4]), 104); - -// br_table.wast:1290 -assert_return(() => call($1, "multiple", [5]), 104); - -// br_table.wast:1291 -assert_return(() => call($1, "multiple", [6]), 104); - -// br_table.wast:1292 -assert_return(() => call($1, "multiple", [10]), 104); - -// br_table.wast:1293 -assert_return(() => call($1, "multiple", [-1]), 104); - -// br_table.wast:1294 -assert_return(() => call($1, "multiple", [-1]), 104); - -// br_table.wast:1296 -assert_return(() => call($1, "multiple-value", [0]), 213); - -// br_table.wast:1297 -assert_return(() => call($1, "multiple-value", [1]), 212); - -// br_table.wast:1298 -assert_return(() => call($1, "multiple-value", [2]), 211); - -// br_table.wast:1299 -assert_return(() => call($1, "multiple-value", [3]), 210); - -// br_table.wast:1300 -assert_return(() => call($1, "multiple-value", [4]), 214); - -// br_table.wast:1301 -assert_return(() => call($1, "multiple-value", [5]), 214); - -// br_table.wast:1302 -assert_return(() => call($1, "multiple-value", [6]), 214); - -// br_table.wast:1303 -assert_return(() => call($1, "multiple-value", [10]), 214); - -// br_table.wast:1304 -assert_return(() => call($1, "multiple-value", [-1]), 214); - -// br_table.wast:1305 -assert_return(() => call($1, "multiple-value", [-1]), 214); - -// br_table.wast:1307 -assert_return(() => call($1, "large", [0]), 0); - -// br_table.wast:1308 -assert_return(() => call($1, "large", [1]), 1); - -// br_table.wast:1309 -assert_return(() => call($1, "large", [100]), 0); - -// br_table.wast:1310 -assert_return(() => call($1, "large", [101]), 1); - -// br_table.wast:1311 -assert_return(() => call($1, "large", [10_000]), 0); - -// br_table.wast:1312 -assert_return(() => call($1, "large", [10_001]), 1); - -// br_table.wast:1313 -assert_return(() => call($1, "large", [1_000_000]), 1); - -// br_table.wast:1314 -assert_return(() => call($1, "large", [1_000_001]), 1); - -// br_table.wast:1316 -assert_return(() => call($1, "as-block-first", [])); - -// br_table.wast:1317 -assert_return(() => call($1, "as-block-mid", [])); - -// br_table.wast:1318 -assert_return(() => call($1, "as-block-last", [])); - -// br_table.wast:1319 -assert_return(() => call($1, "as-block-value", []), 2); - -// br_table.wast:1321 -assert_return(() => call($1, "as-loop-first", []), 3); - -// br_table.wast:1322 -assert_return(() => call($1, "as-loop-mid", []), 4); - -// br_table.wast:1323 -assert_return(() => call($1, "as-loop-last", []), 5); - -// br_table.wast:1325 -assert_return(() => call($1, "as-br-value", []), 9); - -// br_table.wast:1327 -assert_return(() => call($1, "as-br_if-cond", [])); - -// br_table.wast:1328 -assert_return(() => call($1, "as-br_if-value", []), 8); - -// br_table.wast:1329 -assert_return(() => call($1, "as-br_if-value-cond", []), 9); - -// br_table.wast:1331 -assert_return(() => call($1, "as-br_table-index", [])); - -// br_table.wast:1332 -assert_return(() => call($1, "as-br_table-value", []), 10); - -// br_table.wast:1333 -assert_return(() => call($1, "as-br_table-value-index", []), 11); - -// br_table.wast:1335 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-return-value", []), int64("7")) - -// br_table.wast:1337 -assert_return(() => call($1, "as-if-cond", []), 2); - -// br_table.wast:1338 -assert_return(() => call($1, "as-if-then", [1, 6]), 3); - -// br_table.wast:1339 -assert_return(() => call($1, "as-if-then", [0, 6]), 6); - -// br_table.wast:1340 -assert_return(() => call($1, "as-if-else", [0, 6]), 4); - -// br_table.wast:1341 -assert_return(() => call($1, "as-if-else", [1, 6]), 6); - -// br_table.wast:1343 -assert_return(() => call($1, "as-select-first", [0, 6]), 5); - -// br_table.wast:1344 -assert_return(() => call($1, "as-select-first", [1, 6]), 5); - -// br_table.wast:1345 -assert_return(() => call($1, "as-select-second", [0, 6]), 6); - -// br_table.wast:1346 -assert_return(() => call($1, "as-select-second", [1, 6]), 6); - -// br_table.wast:1347 -assert_return(() => call($1, "as-select-cond", []), 7); - -// br_table.wast:1349 -assert_return(() => call($1, "as-call-first", []), 12); - -// br_table.wast:1350 -assert_return(() => call($1, "as-call-mid", []), 13); - -// br_table.wast:1351 -assert_return(() => call($1, "as-call-last", []), 14); - -// br_table.wast:1353 -assert_return(() => call($1, "as-call_indirect-first", []), 20); - -// br_table.wast:1354 -assert_return(() => call($1, "as-call_indirect-mid", []), 21); - -// br_table.wast:1355 -assert_return(() => call($1, "as-call_indirect-last", []), 22); - -// br_table.wast:1356 -assert_return(() => call($1, "as-call_indirect-func", []), 23); - -// br_table.wast:1358 -assert_return(() => call($1, "as-local.set-value", []), 17); - -// br_table.wast:1359 -assert_return(() => call($1, "as-local.tee-value", []), 1); - -// br_table.wast:1360 -assert_return(() => call($1, "as-global.set-value", []), 1); - -// br_table.wast:1362 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x9a\x99\xd9\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-load-address", []), 1.70000004768) - -// br_table.wast:1363 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x1e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-loadN-address", []), int64("30")) - -// br_table.wast:1365 -assert_return(() => call($1, "as-store-address", []), 30); - -// br_table.wast:1366 -assert_return(() => call($1, "as-store-value", []), 31); - -// br_table.wast:1367 -assert_return(() => call($1, "as-storeN-address", []), 32); - -// br_table.wast:1368 -assert_return(() => call($1, "as-storeN-value", []), 33); - -// br_table.wast:1370 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x9a\x99\x59\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 3.40000009537) - -// br_table.wast:1372 -assert_return(() => call($1, "as-binary-left", []), 3); - -// br_table.wast:1373 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x2d\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-binary-right", []), int64("45")) - -// br_table.wast:1375 -assert_return(() => call($1, "as-test-operand", []), 44); - -// br_table.wast:1377 -assert_return(() => call($1, "as-compare-left", []), 43); - -// br_table.wast:1378 -assert_return(() => call($1, "as-compare-right", []), 42); - -// br_table.wast:1380 -assert_return(() => call($1, "as-convert-operand", []), 41); - -// br_table.wast:1382 -assert_return(() => call($1, "as-memory.grow-size", []), 40); - -// br_table.wast:1384 -assert_return(() => call($1, "nested-block-value", [0]), 19); - -// br_table.wast:1385 -assert_return(() => call($1, "nested-block-value", [1]), 17); - -// br_table.wast:1386 -assert_return(() => call($1, "nested-block-value", [2]), 16); - -// br_table.wast:1387 -assert_return(() => call($1, "nested-block-value", [10]), 16); - -// br_table.wast:1388 -assert_return(() => call($1, "nested-block-value", [-1]), 16); - -// br_table.wast:1389 -assert_return(() => call($1, "nested-block-value", [100_000]), 16); - -// br_table.wast:1391 -assert_return(() => call($1, "nested-br-value", [0]), 8); - -// br_table.wast:1392 -assert_return(() => call($1, "nested-br-value", [1]), 9); - -// br_table.wast:1393 -assert_return(() => call($1, "nested-br-value", [2]), 17); - -// br_table.wast:1394 -assert_return(() => call($1, "nested-br-value", [11]), 17); - -// br_table.wast:1395 -assert_return(() => call($1, "nested-br-value", [-4]), 17); - -// br_table.wast:1396 -assert_return(() => call($1, "nested-br-value", [10_213_210]), 17); - -// br_table.wast:1398 -assert_return(() => call($1, "nested-br_if-value", [0]), 17); - -// br_table.wast:1399 -assert_return(() => call($1, "nested-br_if-value", [1]), 9); - -// br_table.wast:1400 -assert_return(() => call($1, "nested-br_if-value", [2]), 8); - -// br_table.wast:1401 -assert_return(() => call($1, "nested-br_if-value", [9]), 8); - -// br_table.wast:1402 -assert_return(() => call($1, "nested-br_if-value", [-9]), 8); - -// br_table.wast:1403 -assert_return(() => call($1, "nested-br_if-value", [999_999]), 8); - -// br_table.wast:1405 -assert_return(() => call($1, "nested-br_if-value-cond", [0]), 9); - -// br_table.wast:1406 -assert_return(() => call($1, "nested-br_if-value-cond", [1]), 8); - -// br_table.wast:1407 -assert_return(() => call($1, "nested-br_if-value-cond", [2]), 9); - -// br_table.wast:1408 -assert_return(() => call($1, "nested-br_if-value-cond", [3]), 9); - -// br_table.wast:1409 -assert_return(() => call($1, "nested-br_if-value-cond", [-1_000_000]), 9); - -// br_table.wast:1410 -assert_return(() => call($1, "nested-br_if-value-cond", [9_423_975]), 9); - -// br_table.wast:1412 -assert_return(() => call($1, "nested-br_table-value", [0]), 17); - -// br_table.wast:1413 -assert_return(() => call($1, "nested-br_table-value", [1]), 9); - -// br_table.wast:1414 -assert_return(() => call($1, "nested-br_table-value", [2]), 8); - -// br_table.wast:1415 -assert_return(() => call($1, "nested-br_table-value", [9]), 8); - -// br_table.wast:1416 -assert_return(() => call($1, "nested-br_table-value", [-9]), 8); - -// br_table.wast:1417 -assert_return(() => call($1, "nested-br_table-value", [999_999]), 8); - -// br_table.wast:1419 -assert_return(() => call($1, "nested-br_table-value-index", [0]), 9); - -// br_table.wast:1420 -assert_return(() => call($1, "nested-br_table-value-index", [1]), 8); - -// br_table.wast:1421 -assert_return(() => call($1, "nested-br_table-value-index", [2]), 9); - -// br_table.wast:1422 -assert_return(() => call($1, "nested-br_table-value-index", [3]), 9); - -// br_table.wast:1423 -assert_return(() => call($1, "nested-br_table-value-index", [-1_000_000]), 9); - -// br_table.wast:1424 -assert_return(() => call($1, "nested-br_table-value-index", [9_423_975]), 9); - -// br_table.wast:1426 -assert_return(() => call($1, "nested-br_table-loop-block", [1]), 3); - -// br_table.wast:1428 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1435 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x0e\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1442 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x01\x41\x01\x0e\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1448 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x41\x01\x0e\x02\x00\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1456 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x02\x7d\x43\x00\x00\x00\x00\x41\x00\x0e\x01\x00\x01\x0b\x1a\x0b\x0b"); - -// br_table.wast:1468 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x01\x0e\x02\x00\x00\x00\x0b\x0b"); - -// br_table.wast:1474 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x00\x0e\x00\x00\x0b\x0b"); - -// br_table.wast:1480 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x01\x0e\x01\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1486 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x02\x40\x41\x00\x0e\x00\x01\x0b\x0b\x0b"); - -// br_table.wast:1492 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x42\x00\x0e\x01\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1501 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x00\x00\x41\x01\x0b\x0b"); - -// br_table.wast:1508 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x04\x7f\x0e\x00\x00\x0b\x0b\x45\x1a\x0b"); - -// br_table.wast:1520 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x04\x7f\x41\x01\x0e\x00\x00\x0b\x0b\x45\x1a\x0b"); - -// br_table.wast:1532 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x0e\x00\x00\x0f\x0b\x45\x1a\x0b"); - -// br_table.wast:1543 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0e\x00\x00\x0f\x0b\x45\x1a\x0b"); - -// br_table.wast:1556 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x01\x02\x01\x0b\x0b"); - -// br_table.wast:1562 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x01\x0e\x01\x00\x05\x0b\x0b\x0b"); - -// br_table.wast:1568 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x02\x00\x81\x80\x80\x80\x01\x00\x0b\x0b"); - -// br_table.wast:1575 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x01\x01\x02\x0b\x0b"); - -// br_table.wast:1581 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x01\x0e\x01\x00\x05\x0b\x0b\x0b"); - -// br_table.wast:1587 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0e\x02\x00\x00\x81\x80\x80\x80\x01\x0b\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/binary.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/binary.wast.js new file mode 100644 index 0000000000..a5b5921d9b --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/binary.wast.js @@ -0,0 +1,359 @@ + +// binary.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:2 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:3 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M1 = $3; + +// binary.wast:4 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M2 = $4; + +// binary.wast:6 +assert_malformed(""); + +// binary.wast:7 +assert_malformed("\x01"); + +// binary.wast:8 +assert_malformed("\x00\x61\x73"); + +// binary.wast:9 +assert_malformed("\x61\x73\x6d\x00"); + +// binary.wast:10 +assert_malformed("\x6d\x73\x61\x00"); + +// binary.wast:11 +assert_malformed("\x6d\x73\x61\x00\x01\x00\x00\x00"); + +// binary.wast:12 +assert_malformed("\x6d\x73\x61\x00\x00\x00\x00\x01"); + +// binary.wast:13 +assert_malformed("\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// binary.wast:14 +assert_malformed("\x77\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:15 +assert_malformed("\x7f\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:16 +assert_malformed("\x80\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:17 +assert_malformed("\x82\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:18 +assert_malformed("\xff\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:21 +assert_malformed("\x00\x00\x00\x01\x6d\x73\x61\x00"); + +// binary.wast:24 +assert_malformed("\x61\x00\x6d\x73\x00\x01\x00\x00"); + +// binary.wast:25 +assert_malformed("\x73\x6d\x00\x61\x00\x00\x01\x00"); + +// binary.wast:28 +assert_malformed("\x00\x41\x53\x4d\x01\x00\x00\x00"); + +// binary.wast:31 +assert_malformed("\x00\x81\xa2\x94\x01\x00\x00\x00"); + +// binary.wast:34 +assert_malformed("\xef\xbb\xbf\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:37 +assert_malformed("\x00\x61\x73\x6d"); + +// binary.wast:38 +assert_malformed("\x00\x61\x73\x6d\x01"); + +// binary.wast:39 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00"); + +// binary.wast:40 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x00"); + +// binary.wast:41 +assert_malformed("\x00\x61\x73\x6d\x0d\x00\x00\x00"); + +// binary.wast:42 +assert_malformed("\x00\x61\x73\x6d\x0e\x00\x00\x00"); + +// binary.wast:43 +assert_malformed("\x00\x61\x73\x6d\x00\x01\x00\x00"); + +// binary.wast:44 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x01\x00"); + +// binary.wast:45 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x01"); + +// binary.wast:48 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x04\x01\x00\x82\x00"); + +// binary.wast:53 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x00"); + +// binary.wast:60 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7f\x00\x41\x80\x00\x0b"); + +// binary.wast:67 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7f\x00\x41\xff\x7f\x0b"); + +// binary.wast:74 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:81 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:89 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7e\x00\x42\x80\x00\x0b"); + +// binary.wast:96 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7e\x00\x42\xff\x7f\x0b"); + +// binary.wast:103 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:110 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:119 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x00\x0b\x07\x01\x80\x00\x41\x00\x0b\x00"); + +// binary.wast:129 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x04\x01\x70\x00\x00\x09\x09\x01\x02\x80\x00\x41\x00\x0b\x00\x00"); + +// binary.wast:139 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x08\x01\x00\x82\x80\x80\x80\x80\x00"); + +// binary.wast:149 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:159 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:170 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:180 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:192 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x70"); + +// binary.wast:200 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x40"); + +// binary.wast:210 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x70\x0b"); + +// binary.wast:220 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x0f\x0b"); + +// binary.wast:230 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x1f\x0b"); + +// binary.wast:240 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x4f\x0b"); + +// binary.wast:251 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7e\x0b"); + +// binary.wast:261 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x0b"); + +// binary.wast:271 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02\x0b"); + +// binary.wast:281 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x0b"); + +// binary.wast:294 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x09\x01\x07\x00\x41\x00\x11\x00\x01\x0b"); + +// binary.wast:313 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0a\x01\x07\x00\x41\x00\x11\x00\x80\x00\x0b"); + +// binary.wast:332 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0b\x01\x08\x00\x41\x00\x11\x00\x80\x80\x00\x0b"); + +// binary.wast:350 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0c\x01\x09\x00\x41\x00\x11\x00\x80\x80\x80\x00\x0b"); + +// binary.wast:368 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0d\x01\x0a\x00\x41\x00\x11\x00\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:387 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x41\x00\x40\x01\x1a\x0b"); + +// binary.wast:407 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x41\x00\x40\x80\x00\x1a\x0b"); + +// binary.wast:427 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x41\x00\x40\x80\x80\x00\x1a\x0b"); + +// binary.wast:446 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0c\x01\x0a\x00\x41\x00\x40\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:465 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0d\x01\x0b\x00\x41\x00\x40\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:485 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x07\x01\x05\x00\x3f\x01\x1a\x0b"); + +// binary.wast:504 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x08\x01\x06\x00\x3f\x80\x00\x1a\x0b"); + +// binary.wast:523 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x3f\x80\x80\x00\x1a\x0b"); + +// binary.wast:541 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x3f\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:559 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x3f\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:578 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0c\x01\x0a\x02\xff\xff\xff\xff\x0f\x7f\x02\x7e\x0b"); + +// binary.wast:595 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0a\x01\x08\x03\x00\x7f\x00\x7e\x02\x7d\x0b"); + +// binary.wast:610 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00"); + +// binary.wast:620 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:629 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:640 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:651 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x03\x01\x00"); + +// binary.wast:657 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x01\x00"); + +// binary.wast:663 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0c\x01\x03\x0b\x05\x02\x01\x00\x01\x00"); + +// binary.wast:673 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0c\x01\x01\x0b\x05\x02\x01\x00\x01\x00"); + +// binary.wast:683 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0e\x01\x0c\x00\x41\x00\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x03\x01\x01\x00"); + +// binary.wast:705 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x07\x01\x05\x00\xfc\x09\x00\x0b\x0b\x03\x01\x01\x00"); + +// binary.wast:724 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd3\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:750 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x7f\x01\xd2\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:776 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd2\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:800 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd0\x70\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:825 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x01\x00"); + +// binary.wast:831 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x02\x60\x00\x00"); + +// binary.wast:842 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x00\x00\x60\x00\x00"); + +// binary.wast:853 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x01\x00"); + +// binary.wast:861 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x16\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00"); + +// binary.wast:880 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x09\x02\x60\x01\x7f\x00\x60\x01\x7d\x00\x02\x2b\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x66\x33\x32\x00\x01"); + +// binary.wast:905 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x00"); + +// binary.wast:911 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x01"); + +// binary.wast:921 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x00"); + +// binary.wast:927 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x01"); + +// binary.wast:937 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x01\x00"); + +// binary.wast:943 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x06\x02\x7f\x00\x41\x00\x0b"); + +// binary.wast:954 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x00\x0b\x7f\x00\x41\x00\x0b"); + +// binary.wast:965 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:977 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x06\x02\x02\x66\x31\x00\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:998 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x0b\x01\x02\x66\x31\x00\x00\x02\x66\x32\x00\x01\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:1019 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1032 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x07\x02\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1050 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x0d\x01\x00\x41\x00\x0b\x01\x00\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1068 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x01\x00"); + +// binary.wast:1076 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x07\x02\x00\x41\x00\x0b\x01\x61"); + +// binary.wast:1089 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0d\x01\x00\x41\x00\x0b\x01\x61\x00\x41\x01\x0b\x01\x62"); + +// binary.wast:1102 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x03\x0b\x07\x61\x62\x63\x64\x65\x66"); + +// binary.wast:1116 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x00\x0b\x05\x61\x62\x63\x64\x65\x66"); + +// binary.wast:1130 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x11\x01\x0f\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x00\x02\x0b\x0b\x0b"); + +// binary.wast:1147 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x10\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x02\x00\x02\x0b\x0b\x0b"); + +// binary.wast:1169 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x11\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x01\x00\x01\x02\x0b\x0b\x0b"); + +// binary.wast:1191 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1204 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/bulk.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/bulk.wast.js new file mode 100644 index 0000000000..e8046191e5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/bulk.wast.js @@ -0,0 +1,351 @@ + +// bulk.wast:2 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x86\x80\x80\x80\x00\x01\x01\x03\x66\x6f\x6f"); + +// bulk.wast:6 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x03\x09\x8d\x80\x80\x80\x00\x01\x05\x70\x03\xd2\x00\x0b\xd0\x70\x0b\xd2\x01\x0b\x0a\x8f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// bulk.wast:13 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x92\x80\x80\x80\x00\x02\x04\x66\x69\x6c\x6c\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9d\x80\x80\x80\x00\x02\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b"); + +// bulk.wast:27 +run(() => call($3, "fill", [1, 255, 3])); + +// bulk.wast:28 +assert_return(() => call($3, "load8_u", [0]), 0); + +// bulk.wast:29 +assert_return(() => call($3, "load8_u", [1]), 255); + +// bulk.wast:30 +assert_return(() => call($3, "load8_u", [2]), 255); + +// bulk.wast:31 +assert_return(() => call($3, "load8_u", [3]), 255); + +// bulk.wast:32 +assert_return(() => call($3, "load8_u", [4]), 0); + +// bulk.wast:35 +run(() => call($3, "fill", [0, 48_042, 2])); + +// bulk.wast:36 +assert_return(() => call($3, "load8_u", [0]), 170); + +// bulk.wast:37 +assert_return(() => call($3, "load8_u", [1]), 170); + +// bulk.wast:40 +run(() => call($3, "fill", [0, 0, 65_536])); + +// bulk.wast:43 +assert_trap(() => call($3, "fill", [65_280, 1, 257])); + +// bulk.wast:45 +assert_return(() => call($3, "load8_u", [65_280]), 0); + +// bulk.wast:46 +assert_return(() => call($3, "load8_u", [65_535]), 0); + +// bulk.wast:49 +run(() => call($3, "fill", [65_536, 0, 0])); + +// bulk.wast:52 +assert_trap(() => call($3, "fill", [65_537, 0, 0])); + +// bulk.wast:57 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x92\x80\x80\x80\x00\x02\x04\x63\x6f\x70\x79\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x04\xaa\xbb\xcc\xdd"); + +// bulk.wast:71 +run(() => call($4, "copy", [10, 0, 4])); + +// bulk.wast:73 +assert_return(() => call($4, "load8_u", [9]), 0); + +// bulk.wast:74 +assert_return(() => call($4, "load8_u", [10]), 170); + +// bulk.wast:75 +assert_return(() => call($4, "load8_u", [11]), 187); + +// bulk.wast:76 +assert_return(() => call($4, "load8_u", [12]), 204); + +// bulk.wast:77 +assert_return(() => call($4, "load8_u", [13]), 221); + +// bulk.wast:78 +assert_return(() => call($4, "load8_u", [14]), 0); + +// bulk.wast:81 +run(() => call($4, "copy", [8, 10, 4])); + +// bulk.wast:82 +assert_return(() => call($4, "load8_u", [8]), 170); + +// bulk.wast:83 +assert_return(() => call($4, "load8_u", [9]), 187); + +// bulk.wast:84 +assert_return(() => call($4, "load8_u", [10]), 204); + +// bulk.wast:85 +assert_return(() => call($4, "load8_u", [11]), 221); + +// bulk.wast:86 +assert_return(() => call($4, "load8_u", [12]), 204); + +// bulk.wast:87 +assert_return(() => call($4, "load8_u", [13]), 221); + +// bulk.wast:90 +run(() => call($4, "copy", [10, 7, 6])); + +// bulk.wast:91 +assert_return(() => call($4, "load8_u", [10]), 0); + +// bulk.wast:92 +assert_return(() => call($4, "load8_u", [11]), 170); + +// bulk.wast:93 +assert_return(() => call($4, "load8_u", [12]), 187); + +// bulk.wast:94 +assert_return(() => call($4, "load8_u", [13]), 204); + +// bulk.wast:95 +assert_return(() => call($4, "load8_u", [14]), 221); + +// bulk.wast:96 +assert_return(() => call($4, "load8_u", [15]), 204); + +// bulk.wast:97 +assert_return(() => call($4, "load8_u", [16]), 0); + +// bulk.wast:100 +run(() => call($4, "copy", [65_280, 0, 256])); + +// bulk.wast:101 +run(() => call($4, "copy", [65_024, 65_280, 256])); + +// bulk.wast:104 +run(() => call($4, "copy", [65_536, 0, 0])); + +// bulk.wast:105 +run(() => call($4, "copy", [0, 65_536, 0])); + +// bulk.wast:108 +assert_trap(() => call($4, "copy", [65_537, 0, 0])); + +// bulk.wast:110 +assert_trap(() => call($4, "copy", [0, 65_537, 0])); + +// bulk.wast:115 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x92\x80\x80\x80\x00\x02\x04\x69\x6e\x69\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x08\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x01\x04\xaa\xbb\xcc\xdd"); + +// bulk.wast:129 +run(() => call($5, "init", [0, 1, 2])); + +// bulk.wast:130 +assert_return(() => call($5, "load8_u", [0]), 187); + +// bulk.wast:131 +assert_return(() => call($5, "load8_u", [1]), 204); + +// bulk.wast:132 +assert_return(() => call($5, "load8_u", [2]), 0); + +// bulk.wast:135 +run(() => call($5, "init", [65_532, 0, 4])); + +// bulk.wast:138 +assert_trap(() => call($5, "init", [65_534, 0, 3])); + +// bulk.wast:140 +assert_return(() => call($5, "load8_u", [65_534]), 204); + +// bulk.wast:141 +assert_return(() => call($5, "load8_u", [65_535]), 221); + +// bulk.wast:144 +run(() => call($5, "init", [65_536, 0, 0])); + +// bulk.wast:145 +run(() => call($5, "init", [0, 4, 0])); + +// bulk.wast:148 +assert_trap(() => call($5, "init", [65_537, 0, 0])); + +// bulk.wast:150 +assert_trap(() => call($5, "init", [0, 5, 0])); + +// bulk.wast:154 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x85\x80\x80\x80\x00\x04\x00\x01\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xbb\x80\x80\x80\x00\x04\x0c\x64\x72\x6f\x70\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x00\x0c\x69\x6e\x69\x74\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x01\x0b\x64\x72\x6f\x70\x5f\x61\x63\x74\x69\x76\x65\x00\x02\x0b\x69\x6e\x69\x74\x5f\x61\x63\x74\x69\x76\x65\x00\x03\x0c\x81\x80\x80\x80\x00\x02\x0a\xb7\x80\x80\x80\x00\x04\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x08\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x09\x01\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x08\x01\x00\x0b\x0b\x8a\x80\x80\x80\x00\x02\x01\x01\x78\x00\x41\x00\x0b\x01\x78"); + +// bulk.wast:168 +run(() => call($6, "init_passive", [1])); + +// bulk.wast:169 +run(() => call($6, "drop_passive", [])); + +// bulk.wast:170 +run(() => call($6, "drop_passive", [])); + +// bulk.wast:171 +assert_return(() => call($6, "init_passive", [0])); + +// bulk.wast:172 +assert_trap(() => call($6, "init_passive", [1])); + +// bulk.wast:173 +run(() => call($6, "init_passive", [0])); + +// bulk.wast:174 +run(() => call($6, "drop_active", [])); + +// bulk.wast:175 +assert_return(() => call($6, "init_active", [0])); + +// bulk.wast:176 +assert_trap(() => call($6, "init_active", [1])); + +// bulk.wast:177 +run(() => call($6, "init_active", [0])); + +// bulk.wast:181 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0c\x81\x80\x80\x80\x00\x41\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x40\x0b\x0b\x83\x81\x80\x80\x00\x41\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00"); + +// bulk.wast:196 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x01\x07\x67\x6f\x6f\x64\x62\x79\x65"); + +// bulk.wast:199 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x85\x80\x80\x80\x00\x04\x00\x00\x01\x02\x04\x84\x80\x80\x80\x00\x01\x70\x00\x03\x07\x8f\x80\x80\x80\x00\x02\x04\x69\x6e\x69\x74\x00\x02\x04\x63\x61\x6c\x6c\x00\x03\x09\x88\x80\x80\x80\x00\x01\x01\x00\x04\x00\x01\x00\x01\x0a\xb0\x80\x80\x80\x00\x04\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0c\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// bulk.wast:219 +assert_trap(() => call($9, "init", [2, 0, 2])); + +// bulk.wast:221 +assert_trap(() => call($9, "call", [2])); + +// bulk.wast:224 +run(() => call($9, "init", [0, 1, 2])); + +// bulk.wast:225 +assert_return(() => call($9, "call", [0]), 1); + +// bulk.wast:226 +assert_return(() => call($9, "call", [1]), 0); + +// bulk.wast:227 +assert_trap(() => call($9, "call", [2])); + +// bulk.wast:230 +run(() => call($9, "init", [1, 2, 2])); + +// bulk.wast:233 +run(() => call($9, "init", [3, 0, 0])); + +// bulk.wast:234 +run(() => call($9, "init", [0, 4, 0])); + +// bulk.wast:237 +assert_trap(() => call($9, "init", [4, 0, 0])); + +// bulk.wast:239 +assert_trap(() => call($9, "init", [0, 5, 0])); + +// bulk.wast:244 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x86\x80\x80\x80\x00\x05\x00\x00\x01\x00\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x07\xbb\x80\x80\x80\x00\x04\x0c\x64\x72\x6f\x70\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x01\x0c\x69\x6e\x69\x74\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x02\x0b\x64\x72\x6f\x70\x5f\x61\x63\x74\x69\x76\x65\x00\x03\x0b\x69\x6e\x69\x74\x5f\x61\x63\x74\x69\x76\x65\x00\x04\x09\x8b\x80\x80\x80\x00\x02\x01\x00\x01\x00\x00\x41\x00\x0b\x01\x00\x0a\xbe\x80\x80\x80\x00\x05\x82\x80\x80\x80\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x0c\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x01\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x0c\x01\x00\x0b"); + +// bulk.wast:261 +run(() => call($10, "init_passive", [1])); + +// bulk.wast:262 +run(() => call($10, "drop_passive", [])); + +// bulk.wast:263 +run(() => call($10, "drop_passive", [])); + +// bulk.wast:264 +assert_return(() => call($10, "init_passive", [0])); + +// bulk.wast:265 +assert_trap(() => call($10, "init_passive", [1])); + +// bulk.wast:266 +run(() => call($10, "init_passive", [0])); + +// bulk.wast:267 +run(() => call($10, "drop_active", [])); + +// bulk.wast:268 +assert_return(() => call($10, "init_active", [0])); + +// bulk.wast:269 +assert_trap(() => call($10, "init_active", [1])); + +// bulk.wast:270 +run(() => call($10, "init_active", [0])); + +// bulk.wast:274 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\xc4\x81\x80\x80\x00\x41\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x40\x0b"); + +// bulk.wast:297 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b"); + +// bulk.wast:300 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x01\x02\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x8f\x80\x80\x80\x00\x02\x04\x63\x6f\x70\x79\x00\x03\x04\x63\x61\x6c\x6c\x00\x04\x09\x89\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x03\x00\x01\x02\x0a\xb9\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// bulk.wast:319 +run(() => call($13, "copy", [3, 0, 3])); + +// bulk.wast:321 +assert_return(() => call($13, "call", [3]), 0); + +// bulk.wast:322 +assert_return(() => call($13, "call", [4]), 1); + +// bulk.wast:323 +assert_return(() => call($13, "call", [5]), 2); + +// bulk.wast:326 +run(() => call($13, "copy", [0, 1, 3])); + +// bulk.wast:328 +assert_return(() => call($13, "call", [0]), 1); + +// bulk.wast:329 +assert_return(() => call($13, "call", [1]), 2); + +// bulk.wast:330 +assert_return(() => call($13, "call", [2]), 0); + +// bulk.wast:333 +run(() => call($13, "copy", [2, 0, 3])); + +// bulk.wast:335 +assert_return(() => call($13, "call", [2]), 1); + +// bulk.wast:336 +assert_return(() => call($13, "call", [3]), 2); + +// bulk.wast:337 +assert_return(() => call($13, "call", [4]), 0); + +// bulk.wast:340 +run(() => call($13, "copy", [6, 8, 2])); + +// bulk.wast:341 +run(() => call($13, "copy", [8, 6, 2])); + +// bulk.wast:344 +run(() => call($13, "copy", [10, 0, 0])); + +// bulk.wast:345 +run(() => call($13, "copy", [0, 10, 0])); + +// bulk.wast:348 +assert_trap(() => call($13, "copy", [11, 0, 0])); + +// bulk.wast:350 +assert_trap(() => call($13, "copy", [0, 11, 0])); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/custom.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/custom.wast.js new file mode 100644 index 0000000000..2f4c106281 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/custom.wast.js @@ -0,0 +1,33 @@ + +// custom.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x20\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x11\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x00\x10\x00\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x01\x00\x00\x24\x10\x00\x00\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x00\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\xef\xbb\xbf\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\xe2\x8c\xa3\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x1f\x16\x6d\x6f\x64\x75\x6c\x65\x20\x77\x69\x74\x68\x69\x6e\x20\x61\x20\x6d\x6f\x64\x75\x6c\x65\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// custom.wast:14 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x01\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x02\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x03\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x04\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x05\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x06\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x07\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x09\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0a\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0b\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:50 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x1a\x06\x63\x75\x73\x74\x6f\x6d\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x07\x0a\x01\x06\x61\x64\x64\x54\x77\x6f\x00\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:60 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// custom.wast:68 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00"); + +// custom.wast:76 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00\x00\x05\x01\x00\x07\x00\x00"); + +// custom.wast:84 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x26\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:92 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:101 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:114 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// custom.wast:122 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0c\x01\x02\x0b\x06\x01\x00\x41\x00\x0b\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/directives.txt b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/directives.txt new file mode 100644 index 0000000000..ef444e9a95 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemoryIsSupported(); include:wasm-testharness.js; local-include:harness/sync_index.js \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/async_index.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/async_index.js new file mode 100644 index 0000000000..038d6859cd --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/async_index.js @@ -0,0 +1,388 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +"use strict"; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + }; +})(); + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch (e) { + assert_true( + e instanceof err, + `expected ${err.name}, observed ${e.constructor.name}` + ); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error."); +} + +/****************************************************************************** + ***************************** WAST HARNESS ************************************ + ******************************************************************************/ + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +// Default imports. +var registry = {}; + +// All tests run asynchronously and return their results as promises. To ensure +// that all tests execute in the correct order, we chain the promises together +// so that a test is only executed when all previous tests have finished their +// execution. +let chain = Promise.resolve(); + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === "undefined") return; + + chain = chain.then(_ => { + let spectest = { + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({ + initial: 10, + maximum: 20, + element: "anyfunc" + }), + memory: new WebAssembly.Memory({ initial: 1, maximum: 2 }) + }; + let handler = { + get(target, prop) { + return prop in target ? target[prop] : {}; + } + }; + registry = new Proxy({ spectest }, handler); + }); + + // This function is called at the end of every generated js test file. By + // adding the chain as a promise_test here we make sure that the WPT harness + // waits for all tests in the chain to finish. + promise_test(_ => chain, testNum() + "Reinitialize the default imports"); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + const test = valid + ? "Test that WebAssembly compilation succeeds" + : "Test that WebAssembly compilation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + let buffer = binary(bytes); + let validated = WebAssembly.validate(buffer); + + uniqueTest(_ => { + assert_equals(valid, validated); + }, test); + + chain = chain.then(_ => WebAssembly.compile(buffer)).then( + module => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return module; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `WebAssembly.compile failed unexpectedly with ${error} at {loc}` + ); + }, test); + } + ); + return chain; +} + +function assert_invalid(bytes) { + module(bytes, EXPECT_INVALID); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports, valid = true) { + const test = valid + ? "Test that WebAssembly instantiation succeeds" + : "Test that WebAssembly instantiation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([imports, chain]) + .then(values => { + let imports = values[0] ? values[0] : registry; + return WebAssembly.instantiate(binary(bytes), imports); + }) + .then( + pair => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return pair.instance; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `unexpected instantiation error, observed ${error} ${loc}` + ); + }, test); + return error; + } + ); + return chain; +} + +function exports(name, instance) { + return instance.then(inst => { + return { [name]: inst.exports }; + }); +} + +function call(instance, name, args) { + return Promise.all([instance, chain]).then(values => { + return values[0].exports[name](...args); + }); +} + +function run(action) { + const test = "Run a WebAssembly test without special assertions"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + _ => { + uniqueTest(_ => {}, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, "run"); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_trap(action) { + const test = "Test that a WebAssembly code traps"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + result => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof WebAssembly.RuntimeError, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_return(action, ...expected) { + const test = "Test that a WebAssembly code returns a specific result"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + values => { + uniqueTest(_ => { + let actual = values[0]; + if (actual === undefined) { + actual = []; + } else if (!Array.isArray(actual)) { + actual = [actual]; + } + if (actual.length !== expected.length) { + throw new Error(expected.length + " value(s) expected, got " + actual.length); + } + + for (let i = 0; i < actual.length; ++i) { + assert_equals(actual[i], expected[i], loc); + } + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +let StackOverflow; +try { + (function f() { + 1 + f(); + })(); +} catch (e) { + StackOverflow = e.constructor; +} + +function assert_exhaustion(action) { + const test = "Test that a WebAssembly code exhauts the stack space"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof StackOverflow, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_unlinkable(bytes) { + const test = "Test that a WebAssembly module is unlinkable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.LinkError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_uninstantiable(bytes) { + const test = "Test that a WebAssembly module is uninstantiable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.RuntimeError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function register(name, instance) { + const test = + "Test that the exports of a WebAssembly module can be registered"; + const loc = new Error().stack.toString().replace("Error", ""); + let stack = new Error(); + chain = Promise.all([instance, chain]) + .then( + values => { + registry[name] = values[0].exports; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function get(instance, name) { + const test = "Test that an export of a WebAssembly instance can be acquired"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([instance, chain]).then( + values => { + let v = values[0].exports[name]; + return (v instanceof WebAssembly.Global) ? v.value : v; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ); + return chain; +} + diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/directives.txt new file mode 100644 index 0000000000..d41243abbb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/directives.txt @@ -0,0 +1 @@ +|jit-test| skip-if: true \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/sync_index.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/sync_index.js new file mode 100644 index 0000000000..fd4e72326a --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/harness/sync_index.js @@ -0,0 +1,349 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +'use strict'; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + } +})(); + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch(e) { + assert_true(e instanceof err, `expected ${err.name}, observed ${e.constructor.name}`); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error.") +} + +/****************************************************************************** +***************************** WAST HARNESS ************************************ +******************************************************************************/ + +// For assertions internal to our test harness. +function _assert(x) { + if (!x) { + throw new Error(`Assertion failure: ${x}`); + } +} + +// A simple sum type that can either be a valid Value or an Error. +function Result(type, maybeValue) { + this.value = maybeValue; + this.type = type; +}; + +Result.VALUE = 'VALUE'; +Result.ERROR = 'ERROR'; + +function ValueResult(val) { return new Result(Result.VALUE, val); } +function ErrorResult(err) { return new Result(Result.ERROR, err); } + +Result.prototype.isError = function() { return this.type === Result.ERROR; } + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +let $$; + +// Default imports. +var registry = {}; + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === 'undefined') + return; + + let spectest = { + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}), + memory: new WebAssembly.Memory({initial: 1, maximum: 2}) + }; + let handler = { + get(target, prop) { + return (prop in target) ? target[prop] : {}; + } + }; + registry = new Proxy({spectest}, handler); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + let buffer = binary(bytes); + let validated; + + try { + validated = WebAssembly.validate(buffer); + } catch (e) { + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + + if (validated !== valid) { + // Try to get a more precise error message from the WebAssembly.CompileError. + try { + new WebAssembly.Module(buffer); + } catch (e) { + if (e instanceof WebAssembly.CompileError) + throw new WebAssembly.CompileError(`WebAssembly.validate error: ${e.toString()}${e.stack}\n`); + else + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + throw new Error(`WebAssembly.validate was expected to fail, but didn't`); + } + + let module; + try { + module = new WebAssembly.Module(buffer); + } catch(e) { + if (valid) + throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}'); + throw e; + } + + return module; +} + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +function assert_invalid(bytes) { + uniqueTest(() => { + try { + module(bytes, /* valid */ false); + throw new Error('did not fail'); + } catch(e) { + assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:"); + } + }, "A wast module that should be invalid or malformed."); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports = registry, valid = true) { + if (imports instanceof Result) { + if (imports.isError()) + return imports; + imports = imports.value; + } + + let err = null; + + let m, i; + try { + let m = module(bytes); + i = new WebAssembly.Instance(m, imports); + } catch(e) { + err = e; + } + + if (valid) { + uniqueTest(() => { + let instantiated = err === null; + assert_true(instantiated, err); + }, "module successfully instantiated"); + } + + return err !== null ? ErrorResult(err) : ValueResult(i); +} + +function register(name, instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return; + + registry[name] = instance.value.exports; +} + +function call(instance, name, args) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let err = null; + let result; + try { + result = instance.value.exports[name](...args); + } catch(e) { + err = e; + } + + return err !== null ? ErrorResult(err) : ValueResult(result); +}; + +function get(instance, name) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let v = instance.value.exports[name]; + return ValueResult((v instanceof WebAssembly.Global) ? v.value : v); +} + +function exports(name, instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + return ValueResult({ [name]: instance.value.exports }); +} + +function run(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + if (result.isError()) + throw result.value; + }, "A wast test that runs without any special assertion."); +} + +function assert_unlinkable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.LinkError, `expected link error, observed ${e}:`); + } + }, "A wast module that is unlinkable."); +} + +function assert_uninstantiable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that is uninstantiable."); +} + +function assert_trap(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that must trap at runtime."); +} + +let StackOverflow; +try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor } + +function assert_exhaustion(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof StackOverflow, `expected stack overflow error, observed ${e}:`); + } + }, "A wast module that must exhaust the stack space."); +} + +function assert_return(action, ...expected) { + let result = action(); + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), `expected success result, got: ${result.value}.`); + + let actual = result.value; + if (actual === undefined) { + actual = []; + } else if (!Array.isArray(actual)) { + actual = [actual]; + } + if (actual.length !== expected.length) { + throw new Error(expected.length + " value(s) expected, got " + actual.length); + } + + for (let i = 0; i < actual.length; ++i) { + if (expected[i] instanceof Result) { + if (expected[i].isError()) + return; + expected[i] = expected[i].value; + } + assert_equals(actual[i], expected[i]); + } + }, "A wast module that must return a particular value."); +}; + +function assert_return_nan(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), 'expected success result'); + if (!result.isError()) { + assert_true(Number.isNaN(result.value), `expected NaN, observed ${result.value}.`); + }; + }, "A wast module that must return NaN."); +} diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_copy.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_copy.wast.js new file mode 100644 index 0000000000..84b2d690ed --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_copy.wast.js @@ -0,0 +1,13350 @@ + +// memory_copy.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:14 +run(() => call($1, "test", [])); + +// memory_copy.wast:16 +assert_return(() => call($1, "load8_u", [0]), 0); + +// memory_copy.wast:17 +assert_return(() => call($1, "load8_u", [1]), 0); + +// memory_copy.wast:18 +assert_return(() => call($1, "load8_u", [2]), 3); + +// memory_copy.wast:19 +assert_return(() => call($1, "load8_u", [3]), 1); + +// memory_copy.wast:20 +assert_return(() => call($1, "load8_u", [4]), 4); + +// memory_copy.wast:21 +assert_return(() => call($1, "load8_u", [5]), 1); + +// memory_copy.wast:22 +assert_return(() => call($1, "load8_u", [6]), 0); + +// memory_copy.wast:23 +assert_return(() => call($1, "load8_u", [7]), 0); + +// memory_copy.wast:24 +assert_return(() => call($1, "load8_u", [8]), 0); + +// memory_copy.wast:25 +assert_return(() => call($1, "load8_u", [9]), 0); + +// memory_copy.wast:26 +assert_return(() => call($1, "load8_u", [10]), 0); + +// memory_copy.wast:27 +assert_return(() => call($1, "load8_u", [11]), 0); + +// memory_copy.wast:28 +assert_return(() => call($1, "load8_u", [12]), 7); + +// memory_copy.wast:29 +assert_return(() => call($1, "load8_u", [13]), 5); + +// memory_copy.wast:30 +assert_return(() => call($1, "load8_u", [14]), 2); + +// memory_copy.wast:31 +assert_return(() => call($1, "load8_u", [15]), 3); + +// memory_copy.wast:32 +assert_return(() => call($1, "load8_u", [16]), 6); + +// memory_copy.wast:33 +assert_return(() => call($1, "load8_u", [17]), 0); + +// memory_copy.wast:34 +assert_return(() => call($1, "load8_u", [18]), 0); + +// memory_copy.wast:35 +assert_return(() => call($1, "load8_u", [19]), 0); + +// memory_copy.wast:36 +assert_return(() => call($1, "load8_u", [20]), 0); + +// memory_copy.wast:37 +assert_return(() => call($1, "load8_u", [21]), 0); + +// memory_copy.wast:38 +assert_return(() => call($1, "load8_u", [22]), 0); + +// memory_copy.wast:39 +assert_return(() => call($1, "load8_u", [23]), 0); + +// memory_copy.wast:40 +assert_return(() => call($1, "load8_u", [24]), 0); + +// memory_copy.wast:41 +assert_return(() => call($1, "load8_u", [25]), 0); + +// memory_copy.wast:42 +assert_return(() => call($1, "load8_u", [26]), 0); + +// memory_copy.wast:43 +assert_return(() => call($1, "load8_u", [27]), 0); + +// memory_copy.wast:44 +assert_return(() => call($1, "load8_u", [28]), 0); + +// memory_copy.wast:45 +assert_return(() => call($1, "load8_u", [29]), 0); + +// memory_copy.wast:47 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x02\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:56 +run(() => call($2, "test", [])); + +// memory_copy.wast:58 +assert_return(() => call($2, "load8_u", [0]), 0); + +// memory_copy.wast:59 +assert_return(() => call($2, "load8_u", [1]), 0); + +// memory_copy.wast:60 +assert_return(() => call($2, "load8_u", [2]), 3); + +// memory_copy.wast:61 +assert_return(() => call($2, "load8_u", [3]), 1); + +// memory_copy.wast:62 +assert_return(() => call($2, "load8_u", [4]), 4); + +// memory_copy.wast:63 +assert_return(() => call($2, "load8_u", [5]), 1); + +// memory_copy.wast:64 +assert_return(() => call($2, "load8_u", [6]), 0); + +// memory_copy.wast:65 +assert_return(() => call($2, "load8_u", [7]), 0); + +// memory_copy.wast:66 +assert_return(() => call($2, "load8_u", [8]), 0); + +// memory_copy.wast:67 +assert_return(() => call($2, "load8_u", [9]), 0); + +// memory_copy.wast:68 +assert_return(() => call($2, "load8_u", [10]), 0); + +// memory_copy.wast:69 +assert_return(() => call($2, "load8_u", [11]), 0); + +// memory_copy.wast:70 +assert_return(() => call($2, "load8_u", [12]), 7); + +// memory_copy.wast:71 +assert_return(() => call($2, "load8_u", [13]), 3); + +// memory_copy.wast:72 +assert_return(() => call($2, "load8_u", [14]), 1); + +// memory_copy.wast:73 +assert_return(() => call($2, "load8_u", [15]), 4); + +// memory_copy.wast:74 +assert_return(() => call($2, "load8_u", [16]), 6); + +// memory_copy.wast:75 +assert_return(() => call($2, "load8_u", [17]), 0); + +// memory_copy.wast:76 +assert_return(() => call($2, "load8_u", [18]), 0); + +// memory_copy.wast:77 +assert_return(() => call($2, "load8_u", [19]), 0); + +// memory_copy.wast:78 +assert_return(() => call($2, "load8_u", [20]), 0); + +// memory_copy.wast:79 +assert_return(() => call($2, "load8_u", [21]), 0); + +// memory_copy.wast:80 +assert_return(() => call($2, "load8_u", [22]), 0); + +// memory_copy.wast:81 +assert_return(() => call($2, "load8_u", [23]), 0); + +// memory_copy.wast:82 +assert_return(() => call($2, "load8_u", [24]), 0); + +// memory_copy.wast:83 +assert_return(() => call($2, "load8_u", [25]), 0); + +// memory_copy.wast:84 +assert_return(() => call($2, "load8_u", [26]), 0); + +// memory_copy.wast:85 +assert_return(() => call($2, "load8_u", [27]), 0); + +// memory_copy.wast:86 +assert_return(() => call($2, "load8_u", [28]), 0); + +// memory_copy.wast:87 +assert_return(() => call($2, "load8_u", [29]), 0); + +// memory_copy.wast:89 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x0f\x41\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:98 +run(() => call($3, "test", [])); + +// memory_copy.wast:100 +assert_return(() => call($3, "load8_u", [0]), 0); + +// memory_copy.wast:101 +assert_return(() => call($3, "load8_u", [1]), 0); + +// memory_copy.wast:102 +assert_return(() => call($3, "load8_u", [2]), 3); + +// memory_copy.wast:103 +assert_return(() => call($3, "load8_u", [3]), 1); + +// memory_copy.wast:104 +assert_return(() => call($3, "load8_u", [4]), 4); + +// memory_copy.wast:105 +assert_return(() => call($3, "load8_u", [5]), 1); + +// memory_copy.wast:106 +assert_return(() => call($3, "load8_u", [6]), 0); + +// memory_copy.wast:107 +assert_return(() => call($3, "load8_u", [7]), 0); + +// memory_copy.wast:108 +assert_return(() => call($3, "load8_u", [8]), 0); + +// memory_copy.wast:109 +assert_return(() => call($3, "load8_u", [9]), 0); + +// memory_copy.wast:110 +assert_return(() => call($3, "load8_u", [10]), 0); + +// memory_copy.wast:111 +assert_return(() => call($3, "load8_u", [11]), 0); + +// memory_copy.wast:112 +assert_return(() => call($3, "load8_u", [12]), 7); + +// memory_copy.wast:113 +assert_return(() => call($3, "load8_u", [13]), 5); + +// memory_copy.wast:114 +assert_return(() => call($3, "load8_u", [14]), 2); + +// memory_copy.wast:115 +assert_return(() => call($3, "load8_u", [15]), 3); + +// memory_copy.wast:116 +assert_return(() => call($3, "load8_u", [16]), 6); + +// memory_copy.wast:117 +assert_return(() => call($3, "load8_u", [17]), 0); + +// memory_copy.wast:118 +assert_return(() => call($3, "load8_u", [18]), 0); + +// memory_copy.wast:119 +assert_return(() => call($3, "load8_u", [19]), 0); + +// memory_copy.wast:120 +assert_return(() => call($3, "load8_u", [20]), 0); + +// memory_copy.wast:121 +assert_return(() => call($3, "load8_u", [21]), 0); + +// memory_copy.wast:122 +assert_return(() => call($3, "load8_u", [22]), 0); + +// memory_copy.wast:123 +assert_return(() => call($3, "load8_u", [23]), 0); + +// memory_copy.wast:124 +assert_return(() => call($3, "load8_u", [24]), 0); + +// memory_copy.wast:125 +assert_return(() => call($3, "load8_u", [25]), 3); + +// memory_copy.wast:126 +assert_return(() => call($3, "load8_u", [26]), 6); + +// memory_copy.wast:127 +assert_return(() => call($3, "load8_u", [27]), 0); + +// memory_copy.wast:128 +assert_return(() => call($3, "load8_u", [28]), 0); + +// memory_copy.wast:129 +assert_return(() => call($3, "load8_u", [29]), 0); + +// memory_copy.wast:131 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x19\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:140 +run(() => call($4, "test", [])); + +// memory_copy.wast:142 +assert_return(() => call($4, "load8_u", [0]), 0); + +// memory_copy.wast:143 +assert_return(() => call($4, "load8_u", [1]), 0); + +// memory_copy.wast:144 +assert_return(() => call($4, "load8_u", [2]), 3); + +// memory_copy.wast:145 +assert_return(() => call($4, "load8_u", [3]), 1); + +// memory_copy.wast:146 +assert_return(() => call($4, "load8_u", [4]), 4); + +// memory_copy.wast:147 +assert_return(() => call($4, "load8_u", [5]), 1); + +// memory_copy.wast:148 +assert_return(() => call($4, "load8_u", [6]), 0); + +// memory_copy.wast:149 +assert_return(() => call($4, "load8_u", [7]), 0); + +// memory_copy.wast:150 +assert_return(() => call($4, "load8_u", [8]), 0); + +// memory_copy.wast:151 +assert_return(() => call($4, "load8_u", [9]), 0); + +// memory_copy.wast:152 +assert_return(() => call($4, "load8_u", [10]), 0); + +// memory_copy.wast:153 +assert_return(() => call($4, "load8_u", [11]), 0); + +// memory_copy.wast:154 +assert_return(() => call($4, "load8_u", [12]), 7); + +// memory_copy.wast:155 +assert_return(() => call($4, "load8_u", [13]), 0); + +// memory_copy.wast:156 +assert_return(() => call($4, "load8_u", [14]), 0); + +// memory_copy.wast:157 +assert_return(() => call($4, "load8_u", [15]), 0); + +// memory_copy.wast:158 +assert_return(() => call($4, "load8_u", [16]), 6); + +// memory_copy.wast:159 +assert_return(() => call($4, "load8_u", [17]), 0); + +// memory_copy.wast:160 +assert_return(() => call($4, "load8_u", [18]), 0); + +// memory_copy.wast:161 +assert_return(() => call($4, "load8_u", [19]), 0); + +// memory_copy.wast:162 +assert_return(() => call($4, "load8_u", [20]), 0); + +// memory_copy.wast:163 +assert_return(() => call($4, "load8_u", [21]), 0); + +// memory_copy.wast:164 +assert_return(() => call($4, "load8_u", [22]), 0); + +// memory_copy.wast:165 +assert_return(() => call($4, "load8_u", [23]), 0); + +// memory_copy.wast:166 +assert_return(() => call($4, "load8_u", [24]), 0); + +// memory_copy.wast:167 +assert_return(() => call($4, "load8_u", [25]), 0); + +// memory_copy.wast:168 +assert_return(() => call($4, "load8_u", [26]), 0); + +// memory_copy.wast:169 +assert_return(() => call($4, "load8_u", [27]), 0); + +// memory_copy.wast:170 +assert_return(() => call($4, "load8_u", [28]), 0); + +// memory_copy.wast:171 +assert_return(() => call($4, "load8_u", [29]), 0); + +// memory_copy.wast:173 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x14\x41\x16\x41\x04\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:182 +run(() => call($5, "test", [])); + +// memory_copy.wast:184 +assert_return(() => call($5, "load8_u", [0]), 0); + +// memory_copy.wast:185 +assert_return(() => call($5, "load8_u", [1]), 0); + +// memory_copy.wast:186 +assert_return(() => call($5, "load8_u", [2]), 3); + +// memory_copy.wast:187 +assert_return(() => call($5, "load8_u", [3]), 1); + +// memory_copy.wast:188 +assert_return(() => call($5, "load8_u", [4]), 4); + +// memory_copy.wast:189 +assert_return(() => call($5, "load8_u", [5]), 1); + +// memory_copy.wast:190 +assert_return(() => call($5, "load8_u", [6]), 0); + +// memory_copy.wast:191 +assert_return(() => call($5, "load8_u", [7]), 0); + +// memory_copy.wast:192 +assert_return(() => call($5, "load8_u", [8]), 0); + +// memory_copy.wast:193 +assert_return(() => call($5, "load8_u", [9]), 0); + +// memory_copy.wast:194 +assert_return(() => call($5, "load8_u", [10]), 0); + +// memory_copy.wast:195 +assert_return(() => call($5, "load8_u", [11]), 0); + +// memory_copy.wast:196 +assert_return(() => call($5, "load8_u", [12]), 7); + +// memory_copy.wast:197 +assert_return(() => call($5, "load8_u", [13]), 5); + +// memory_copy.wast:198 +assert_return(() => call($5, "load8_u", [14]), 2); + +// memory_copy.wast:199 +assert_return(() => call($5, "load8_u", [15]), 3); + +// memory_copy.wast:200 +assert_return(() => call($5, "load8_u", [16]), 6); + +// memory_copy.wast:201 +assert_return(() => call($5, "load8_u", [17]), 0); + +// memory_copy.wast:202 +assert_return(() => call($5, "load8_u", [18]), 0); + +// memory_copy.wast:203 +assert_return(() => call($5, "load8_u", [19]), 0); + +// memory_copy.wast:204 +assert_return(() => call($5, "load8_u", [20]), 0); + +// memory_copy.wast:205 +assert_return(() => call($5, "load8_u", [21]), 0); + +// memory_copy.wast:206 +assert_return(() => call($5, "load8_u", [22]), 0); + +// memory_copy.wast:207 +assert_return(() => call($5, "load8_u", [23]), 0); + +// memory_copy.wast:208 +assert_return(() => call($5, "load8_u", [24]), 0); + +// memory_copy.wast:209 +assert_return(() => call($5, "load8_u", [25]), 0); + +// memory_copy.wast:210 +assert_return(() => call($5, "load8_u", [26]), 0); + +// memory_copy.wast:211 +assert_return(() => call($5, "load8_u", [27]), 0); + +// memory_copy.wast:212 +assert_return(() => call($5, "load8_u", [28]), 0); + +// memory_copy.wast:213 +assert_return(() => call($5, "load8_u", [29]), 0); + +// memory_copy.wast:215 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x01\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:224 +run(() => call($6, "test", [])); + +// memory_copy.wast:226 +assert_return(() => call($6, "load8_u", [0]), 0); + +// memory_copy.wast:227 +assert_return(() => call($6, "load8_u", [1]), 0); + +// memory_copy.wast:228 +assert_return(() => call($6, "load8_u", [2]), 3); + +// memory_copy.wast:229 +assert_return(() => call($6, "load8_u", [3]), 1); + +// memory_copy.wast:230 +assert_return(() => call($6, "load8_u", [4]), 4); + +// memory_copy.wast:231 +assert_return(() => call($6, "load8_u", [5]), 1); + +// memory_copy.wast:232 +assert_return(() => call($6, "load8_u", [6]), 0); + +// memory_copy.wast:233 +assert_return(() => call($6, "load8_u", [7]), 0); + +// memory_copy.wast:234 +assert_return(() => call($6, "load8_u", [8]), 0); + +// memory_copy.wast:235 +assert_return(() => call($6, "load8_u", [9]), 0); + +// memory_copy.wast:236 +assert_return(() => call($6, "load8_u", [10]), 0); + +// memory_copy.wast:237 +assert_return(() => call($6, "load8_u", [11]), 0); + +// memory_copy.wast:238 +assert_return(() => call($6, "load8_u", [12]), 7); + +// memory_copy.wast:239 +assert_return(() => call($6, "load8_u", [13]), 5); + +// memory_copy.wast:240 +assert_return(() => call($6, "load8_u", [14]), 2); + +// memory_copy.wast:241 +assert_return(() => call($6, "load8_u", [15]), 3); + +// memory_copy.wast:242 +assert_return(() => call($6, "load8_u", [16]), 6); + +// memory_copy.wast:243 +assert_return(() => call($6, "load8_u", [17]), 0); + +// memory_copy.wast:244 +assert_return(() => call($6, "load8_u", [18]), 0); + +// memory_copy.wast:245 +assert_return(() => call($6, "load8_u", [19]), 0); + +// memory_copy.wast:246 +assert_return(() => call($6, "load8_u", [20]), 0); + +// memory_copy.wast:247 +assert_return(() => call($6, "load8_u", [21]), 0); + +// memory_copy.wast:248 +assert_return(() => call($6, "load8_u", [22]), 0); + +// memory_copy.wast:249 +assert_return(() => call($6, "load8_u", [23]), 0); + +// memory_copy.wast:250 +assert_return(() => call($6, "load8_u", [24]), 0); + +// memory_copy.wast:251 +assert_return(() => call($6, "load8_u", [25]), 0); + +// memory_copy.wast:252 +assert_return(() => call($6, "load8_u", [26]), 3); + +// memory_copy.wast:253 +assert_return(() => call($6, "load8_u", [27]), 1); + +// memory_copy.wast:254 +assert_return(() => call($6, "load8_u", [28]), 0); + +// memory_copy.wast:255 +assert_return(() => call($6, "load8_u", [29]), 0); + +// memory_copy.wast:257 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x0c\x41\x07\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:266 +run(() => call($7, "test", [])); + +// memory_copy.wast:268 +assert_return(() => call($7, "load8_u", [0]), 0); + +// memory_copy.wast:269 +assert_return(() => call($7, "load8_u", [1]), 0); + +// memory_copy.wast:270 +assert_return(() => call($7, "load8_u", [2]), 3); + +// memory_copy.wast:271 +assert_return(() => call($7, "load8_u", [3]), 1); + +// memory_copy.wast:272 +assert_return(() => call($7, "load8_u", [4]), 4); + +// memory_copy.wast:273 +assert_return(() => call($7, "load8_u", [5]), 1); + +// memory_copy.wast:274 +assert_return(() => call($7, "load8_u", [6]), 0); + +// memory_copy.wast:275 +assert_return(() => call($7, "load8_u", [7]), 0); + +// memory_copy.wast:276 +assert_return(() => call($7, "load8_u", [8]), 0); + +// memory_copy.wast:277 +assert_return(() => call($7, "load8_u", [9]), 0); + +// memory_copy.wast:278 +assert_return(() => call($7, "load8_u", [10]), 7); + +// memory_copy.wast:279 +assert_return(() => call($7, "load8_u", [11]), 5); + +// memory_copy.wast:280 +assert_return(() => call($7, "load8_u", [12]), 2); + +// memory_copy.wast:281 +assert_return(() => call($7, "load8_u", [13]), 3); + +// memory_copy.wast:282 +assert_return(() => call($7, "load8_u", [14]), 6); + +// memory_copy.wast:283 +assert_return(() => call($7, "load8_u", [15]), 0); + +// memory_copy.wast:284 +assert_return(() => call($7, "load8_u", [16]), 0); + +// memory_copy.wast:285 +assert_return(() => call($7, "load8_u", [17]), 0); + +// memory_copy.wast:286 +assert_return(() => call($7, "load8_u", [18]), 0); + +// memory_copy.wast:287 +assert_return(() => call($7, "load8_u", [19]), 0); + +// memory_copy.wast:288 +assert_return(() => call($7, "load8_u", [20]), 0); + +// memory_copy.wast:289 +assert_return(() => call($7, "load8_u", [21]), 0); + +// memory_copy.wast:290 +assert_return(() => call($7, "load8_u", [22]), 0); + +// memory_copy.wast:291 +assert_return(() => call($7, "load8_u", [23]), 0); + +// memory_copy.wast:292 +assert_return(() => call($7, "load8_u", [24]), 0); + +// memory_copy.wast:293 +assert_return(() => call($7, "load8_u", [25]), 0); + +// memory_copy.wast:294 +assert_return(() => call($7, "load8_u", [26]), 0); + +// memory_copy.wast:295 +assert_return(() => call($7, "load8_u", [27]), 0); + +// memory_copy.wast:296 +assert_return(() => call($7, "load8_u", [28]), 0); + +// memory_copy.wast:297 +assert_return(() => call($7, "load8_u", [29]), 0); + +// memory_copy.wast:299 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x0a\x41\x07\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:308 +run(() => call($8, "test", [])); + +// memory_copy.wast:310 +assert_return(() => call($8, "load8_u", [0]), 0); + +// memory_copy.wast:311 +assert_return(() => call($8, "load8_u", [1]), 0); + +// memory_copy.wast:312 +assert_return(() => call($8, "load8_u", [2]), 3); + +// memory_copy.wast:313 +assert_return(() => call($8, "load8_u", [3]), 1); + +// memory_copy.wast:314 +assert_return(() => call($8, "load8_u", [4]), 4); + +// memory_copy.wast:315 +assert_return(() => call($8, "load8_u", [5]), 1); + +// memory_copy.wast:316 +assert_return(() => call($8, "load8_u", [6]), 0); + +// memory_copy.wast:317 +assert_return(() => call($8, "load8_u", [7]), 0); + +// memory_copy.wast:318 +assert_return(() => call($8, "load8_u", [8]), 0); + +// memory_copy.wast:319 +assert_return(() => call($8, "load8_u", [9]), 0); + +// memory_copy.wast:320 +assert_return(() => call($8, "load8_u", [10]), 0); + +// memory_copy.wast:321 +assert_return(() => call($8, "load8_u", [11]), 0); + +// memory_copy.wast:322 +assert_return(() => call($8, "load8_u", [12]), 0); + +// memory_copy.wast:323 +assert_return(() => call($8, "load8_u", [13]), 0); + +// memory_copy.wast:324 +assert_return(() => call($8, "load8_u", [14]), 7); + +// memory_copy.wast:325 +assert_return(() => call($8, "load8_u", [15]), 5); + +// memory_copy.wast:326 +assert_return(() => call($8, "load8_u", [16]), 2); + +// memory_copy.wast:327 +assert_return(() => call($8, "load8_u", [17]), 3); + +// memory_copy.wast:328 +assert_return(() => call($8, "load8_u", [18]), 6); + +// memory_copy.wast:329 +assert_return(() => call($8, "load8_u", [19]), 0); + +// memory_copy.wast:330 +assert_return(() => call($8, "load8_u", [20]), 0); + +// memory_copy.wast:331 +assert_return(() => call($8, "load8_u", [21]), 0); + +// memory_copy.wast:332 +assert_return(() => call($8, "load8_u", [22]), 0); + +// memory_copy.wast:333 +assert_return(() => call($8, "load8_u", [23]), 0); + +// memory_copy.wast:334 +assert_return(() => call($8, "load8_u", [24]), 0); + +// memory_copy.wast:335 +assert_return(() => call($8, "load8_u", [25]), 0); + +// memory_copy.wast:336 +assert_return(() => call($8, "load8_u", [26]), 0); + +// memory_copy.wast:337 +assert_return(() => call($8, "load8_u", [27]), 0); + +// memory_copy.wast:338 +assert_return(() => call($8, "load8_u", [28]), 0); + +// memory_copy.wast:339 +assert_return(() => call($8, "load8_u", [29]), 0); + +// memory_copy.wast:341 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:349 +assert_trap(() => call($9, "run", [65_516, 0, 40])); + +// memory_copy.wast:352 +assert_return(() => call($9, "load8_u", [0]), 0); + +// memory_copy.wast:353 +assert_return(() => call($9, "load8_u", [1]), 1); + +// memory_copy.wast:354 +assert_return(() => call($9, "load8_u", [2]), 2); + +// memory_copy.wast:355 +assert_return(() => call($9, "load8_u", [3]), 3); + +// memory_copy.wast:356 +assert_return(() => call($9, "load8_u", [4]), 4); + +// memory_copy.wast:357 +assert_return(() => call($9, "load8_u", [5]), 5); + +// memory_copy.wast:358 +assert_return(() => call($9, "load8_u", [6]), 6); + +// memory_copy.wast:359 +assert_return(() => call($9, "load8_u", [7]), 7); + +// memory_copy.wast:360 +assert_return(() => call($9, "load8_u", [8]), 8); + +// memory_copy.wast:361 +assert_return(() => call($9, "load8_u", [9]), 9); + +// memory_copy.wast:362 +assert_return(() => call($9, "load8_u", [10]), 10); + +// memory_copy.wast:363 +assert_return(() => call($9, "load8_u", [11]), 11); + +// memory_copy.wast:364 +assert_return(() => call($9, "load8_u", [12]), 12); + +// memory_copy.wast:365 +assert_return(() => call($9, "load8_u", [13]), 13); + +// memory_copy.wast:366 +assert_return(() => call($9, "load8_u", [14]), 14); + +// memory_copy.wast:367 +assert_return(() => call($9, "load8_u", [15]), 15); + +// memory_copy.wast:368 +assert_return(() => call($9, "load8_u", [16]), 16); + +// memory_copy.wast:369 +assert_return(() => call($9, "load8_u", [17]), 17); + +// memory_copy.wast:370 +assert_return(() => call($9, "load8_u", [18]), 18); + +// memory_copy.wast:371 +assert_return(() => call($9, "load8_u", [19]), 19); + +// memory_copy.wast:372 +assert_return(() => call($9, "load8_u", [218]), 0); + +// memory_copy.wast:373 +assert_return(() => call($9, "load8_u", [417]), 0); + +// memory_copy.wast:374 +assert_return(() => call($9, "load8_u", [616]), 0); + +// memory_copy.wast:375 +assert_return(() => call($9, "load8_u", [815]), 0); + +// memory_copy.wast:376 +assert_return(() => call($9, "load8_u", [1_014]), 0); + +// memory_copy.wast:377 +assert_return(() => call($9, "load8_u", [1_213]), 0); + +// memory_copy.wast:378 +assert_return(() => call($9, "load8_u", [1_412]), 0); + +// memory_copy.wast:379 +assert_return(() => call($9, "load8_u", [1_611]), 0); + +// memory_copy.wast:380 +assert_return(() => call($9, "load8_u", [1_810]), 0); + +// memory_copy.wast:381 +assert_return(() => call($9, "load8_u", [2_009]), 0); + +// memory_copy.wast:382 +assert_return(() => call($9, "load8_u", [2_208]), 0); + +// memory_copy.wast:383 +assert_return(() => call($9, "load8_u", [2_407]), 0); + +// memory_copy.wast:384 +assert_return(() => call($9, "load8_u", [2_606]), 0); + +// memory_copy.wast:385 +assert_return(() => call($9, "load8_u", [2_805]), 0); + +// memory_copy.wast:386 +assert_return(() => call($9, "load8_u", [3_004]), 0); + +// memory_copy.wast:387 +assert_return(() => call($9, "load8_u", [3_203]), 0); + +// memory_copy.wast:388 +assert_return(() => call($9, "load8_u", [3_402]), 0); + +// memory_copy.wast:389 +assert_return(() => call($9, "load8_u", [3_601]), 0); + +// memory_copy.wast:390 +assert_return(() => call($9, "load8_u", [3_800]), 0); + +// memory_copy.wast:391 +assert_return(() => call($9, "load8_u", [3_999]), 0); + +// memory_copy.wast:392 +assert_return(() => call($9, "load8_u", [4_198]), 0); + +// memory_copy.wast:393 +assert_return(() => call($9, "load8_u", [4_397]), 0); + +// memory_copy.wast:394 +assert_return(() => call($9, "load8_u", [4_596]), 0); + +// memory_copy.wast:395 +assert_return(() => call($9, "load8_u", [4_795]), 0); + +// memory_copy.wast:396 +assert_return(() => call($9, "load8_u", [4_994]), 0); + +// memory_copy.wast:397 +assert_return(() => call($9, "load8_u", [5_193]), 0); + +// memory_copy.wast:398 +assert_return(() => call($9, "load8_u", [5_392]), 0); + +// memory_copy.wast:399 +assert_return(() => call($9, "load8_u", [5_591]), 0); + +// memory_copy.wast:400 +assert_return(() => call($9, "load8_u", [5_790]), 0); + +// memory_copy.wast:401 +assert_return(() => call($9, "load8_u", [5_989]), 0); + +// memory_copy.wast:402 +assert_return(() => call($9, "load8_u", [6_188]), 0); + +// memory_copy.wast:403 +assert_return(() => call($9, "load8_u", [6_387]), 0); + +// memory_copy.wast:404 +assert_return(() => call($9, "load8_u", [6_586]), 0); + +// memory_copy.wast:405 +assert_return(() => call($9, "load8_u", [6_785]), 0); + +// memory_copy.wast:406 +assert_return(() => call($9, "load8_u", [6_984]), 0); + +// memory_copy.wast:407 +assert_return(() => call($9, "load8_u", [7_183]), 0); + +// memory_copy.wast:408 +assert_return(() => call($9, "load8_u", [7_382]), 0); + +// memory_copy.wast:409 +assert_return(() => call($9, "load8_u", [7_581]), 0); + +// memory_copy.wast:410 +assert_return(() => call($9, "load8_u", [7_780]), 0); + +// memory_copy.wast:411 +assert_return(() => call($9, "load8_u", [7_979]), 0); + +// memory_copy.wast:412 +assert_return(() => call($9, "load8_u", [8_178]), 0); + +// memory_copy.wast:413 +assert_return(() => call($9, "load8_u", [8_377]), 0); + +// memory_copy.wast:414 +assert_return(() => call($9, "load8_u", [8_576]), 0); + +// memory_copy.wast:415 +assert_return(() => call($9, "load8_u", [8_775]), 0); + +// memory_copy.wast:416 +assert_return(() => call($9, "load8_u", [8_974]), 0); + +// memory_copy.wast:417 +assert_return(() => call($9, "load8_u", [9_173]), 0); + +// memory_copy.wast:418 +assert_return(() => call($9, "load8_u", [9_372]), 0); + +// memory_copy.wast:419 +assert_return(() => call($9, "load8_u", [9_571]), 0); + +// memory_copy.wast:420 +assert_return(() => call($9, "load8_u", [9_770]), 0); + +// memory_copy.wast:421 +assert_return(() => call($9, "load8_u", [9_969]), 0); + +// memory_copy.wast:422 +assert_return(() => call($9, "load8_u", [10_168]), 0); + +// memory_copy.wast:423 +assert_return(() => call($9, "load8_u", [10_367]), 0); + +// memory_copy.wast:424 +assert_return(() => call($9, "load8_u", [10_566]), 0); + +// memory_copy.wast:425 +assert_return(() => call($9, "load8_u", [10_765]), 0); + +// memory_copy.wast:426 +assert_return(() => call($9, "load8_u", [10_964]), 0); + +// memory_copy.wast:427 +assert_return(() => call($9, "load8_u", [11_163]), 0); + +// memory_copy.wast:428 +assert_return(() => call($9, "load8_u", [11_362]), 0); + +// memory_copy.wast:429 +assert_return(() => call($9, "load8_u", [11_561]), 0); + +// memory_copy.wast:430 +assert_return(() => call($9, "load8_u", [11_760]), 0); + +// memory_copy.wast:431 +assert_return(() => call($9, "load8_u", [11_959]), 0); + +// memory_copy.wast:432 +assert_return(() => call($9, "load8_u", [12_158]), 0); + +// memory_copy.wast:433 +assert_return(() => call($9, "load8_u", [12_357]), 0); + +// memory_copy.wast:434 +assert_return(() => call($9, "load8_u", [12_556]), 0); + +// memory_copy.wast:435 +assert_return(() => call($9, "load8_u", [12_755]), 0); + +// memory_copy.wast:436 +assert_return(() => call($9, "load8_u", [12_954]), 0); + +// memory_copy.wast:437 +assert_return(() => call($9, "load8_u", [13_153]), 0); + +// memory_copy.wast:438 +assert_return(() => call($9, "load8_u", [13_352]), 0); + +// memory_copy.wast:439 +assert_return(() => call($9, "load8_u", [13_551]), 0); + +// memory_copy.wast:440 +assert_return(() => call($9, "load8_u", [13_750]), 0); + +// memory_copy.wast:441 +assert_return(() => call($9, "load8_u", [13_949]), 0); + +// memory_copy.wast:442 +assert_return(() => call($9, "load8_u", [14_148]), 0); + +// memory_copy.wast:443 +assert_return(() => call($9, "load8_u", [14_347]), 0); + +// memory_copy.wast:444 +assert_return(() => call($9, "load8_u", [14_546]), 0); + +// memory_copy.wast:445 +assert_return(() => call($9, "load8_u", [14_745]), 0); + +// memory_copy.wast:446 +assert_return(() => call($9, "load8_u", [14_944]), 0); + +// memory_copy.wast:447 +assert_return(() => call($9, "load8_u", [15_143]), 0); + +// memory_copy.wast:448 +assert_return(() => call($9, "load8_u", [15_342]), 0); + +// memory_copy.wast:449 +assert_return(() => call($9, "load8_u", [15_541]), 0); + +// memory_copy.wast:450 +assert_return(() => call($9, "load8_u", [15_740]), 0); + +// memory_copy.wast:451 +assert_return(() => call($9, "load8_u", [15_939]), 0); + +// memory_copy.wast:452 +assert_return(() => call($9, "load8_u", [16_138]), 0); + +// memory_copy.wast:453 +assert_return(() => call($9, "load8_u", [16_337]), 0); + +// memory_copy.wast:454 +assert_return(() => call($9, "load8_u", [16_536]), 0); + +// memory_copy.wast:455 +assert_return(() => call($9, "load8_u", [16_735]), 0); + +// memory_copy.wast:456 +assert_return(() => call($9, "load8_u", [16_934]), 0); + +// memory_copy.wast:457 +assert_return(() => call($9, "load8_u", [17_133]), 0); + +// memory_copy.wast:458 +assert_return(() => call($9, "load8_u", [17_332]), 0); + +// memory_copy.wast:459 +assert_return(() => call($9, "load8_u", [17_531]), 0); + +// memory_copy.wast:460 +assert_return(() => call($9, "load8_u", [17_730]), 0); + +// memory_copy.wast:461 +assert_return(() => call($9, "load8_u", [17_929]), 0); + +// memory_copy.wast:462 +assert_return(() => call($9, "load8_u", [18_128]), 0); + +// memory_copy.wast:463 +assert_return(() => call($9, "load8_u", [18_327]), 0); + +// memory_copy.wast:464 +assert_return(() => call($9, "load8_u", [18_526]), 0); + +// memory_copy.wast:465 +assert_return(() => call($9, "load8_u", [18_725]), 0); + +// memory_copy.wast:466 +assert_return(() => call($9, "load8_u", [18_924]), 0); + +// memory_copy.wast:467 +assert_return(() => call($9, "load8_u", [19_123]), 0); + +// memory_copy.wast:468 +assert_return(() => call($9, "load8_u", [19_322]), 0); + +// memory_copy.wast:469 +assert_return(() => call($9, "load8_u", [19_521]), 0); + +// memory_copy.wast:470 +assert_return(() => call($9, "load8_u", [19_720]), 0); + +// memory_copy.wast:471 +assert_return(() => call($9, "load8_u", [19_919]), 0); + +// memory_copy.wast:472 +assert_return(() => call($9, "load8_u", [20_118]), 0); + +// memory_copy.wast:473 +assert_return(() => call($9, "load8_u", [20_317]), 0); + +// memory_copy.wast:474 +assert_return(() => call($9, "load8_u", [20_516]), 0); + +// memory_copy.wast:475 +assert_return(() => call($9, "load8_u", [20_715]), 0); + +// memory_copy.wast:476 +assert_return(() => call($9, "load8_u", [20_914]), 0); + +// memory_copy.wast:477 +assert_return(() => call($9, "load8_u", [21_113]), 0); + +// memory_copy.wast:478 +assert_return(() => call($9, "load8_u", [21_312]), 0); + +// memory_copy.wast:479 +assert_return(() => call($9, "load8_u", [21_511]), 0); + +// memory_copy.wast:480 +assert_return(() => call($9, "load8_u", [21_710]), 0); + +// memory_copy.wast:481 +assert_return(() => call($9, "load8_u", [21_909]), 0); + +// memory_copy.wast:482 +assert_return(() => call($9, "load8_u", [22_108]), 0); + +// memory_copy.wast:483 +assert_return(() => call($9, "load8_u", [22_307]), 0); + +// memory_copy.wast:484 +assert_return(() => call($9, "load8_u", [22_506]), 0); + +// memory_copy.wast:485 +assert_return(() => call($9, "load8_u", [22_705]), 0); + +// memory_copy.wast:486 +assert_return(() => call($9, "load8_u", [22_904]), 0); + +// memory_copy.wast:487 +assert_return(() => call($9, "load8_u", [23_103]), 0); + +// memory_copy.wast:488 +assert_return(() => call($9, "load8_u", [23_302]), 0); + +// memory_copy.wast:489 +assert_return(() => call($9, "load8_u", [23_501]), 0); + +// memory_copy.wast:490 +assert_return(() => call($9, "load8_u", [23_700]), 0); + +// memory_copy.wast:491 +assert_return(() => call($9, "load8_u", [23_899]), 0); + +// memory_copy.wast:492 +assert_return(() => call($9, "load8_u", [24_098]), 0); + +// memory_copy.wast:493 +assert_return(() => call($9, "load8_u", [24_297]), 0); + +// memory_copy.wast:494 +assert_return(() => call($9, "load8_u", [24_496]), 0); + +// memory_copy.wast:495 +assert_return(() => call($9, "load8_u", [24_695]), 0); + +// memory_copy.wast:496 +assert_return(() => call($9, "load8_u", [24_894]), 0); + +// memory_copy.wast:497 +assert_return(() => call($9, "load8_u", [25_093]), 0); + +// memory_copy.wast:498 +assert_return(() => call($9, "load8_u", [25_292]), 0); + +// memory_copy.wast:499 +assert_return(() => call($9, "load8_u", [25_491]), 0); + +// memory_copy.wast:500 +assert_return(() => call($9, "load8_u", [25_690]), 0); + +// memory_copy.wast:501 +assert_return(() => call($9, "load8_u", [25_889]), 0); + +// memory_copy.wast:502 +assert_return(() => call($9, "load8_u", [26_088]), 0); + +// memory_copy.wast:503 +assert_return(() => call($9, "load8_u", [26_287]), 0); + +// memory_copy.wast:504 +assert_return(() => call($9, "load8_u", [26_486]), 0); + +// memory_copy.wast:505 +assert_return(() => call($9, "load8_u", [26_685]), 0); + +// memory_copy.wast:506 +assert_return(() => call($9, "load8_u", [26_884]), 0); + +// memory_copy.wast:507 +assert_return(() => call($9, "load8_u", [27_083]), 0); + +// memory_copy.wast:508 +assert_return(() => call($9, "load8_u", [27_282]), 0); + +// memory_copy.wast:509 +assert_return(() => call($9, "load8_u", [27_481]), 0); + +// memory_copy.wast:510 +assert_return(() => call($9, "load8_u", [27_680]), 0); + +// memory_copy.wast:511 +assert_return(() => call($9, "load8_u", [27_879]), 0); + +// memory_copy.wast:512 +assert_return(() => call($9, "load8_u", [28_078]), 0); + +// memory_copy.wast:513 +assert_return(() => call($9, "load8_u", [28_277]), 0); + +// memory_copy.wast:514 +assert_return(() => call($9, "load8_u", [28_476]), 0); + +// memory_copy.wast:515 +assert_return(() => call($9, "load8_u", [28_675]), 0); + +// memory_copy.wast:516 +assert_return(() => call($9, "load8_u", [28_874]), 0); + +// memory_copy.wast:517 +assert_return(() => call($9, "load8_u", [29_073]), 0); + +// memory_copy.wast:518 +assert_return(() => call($9, "load8_u", [29_272]), 0); + +// memory_copy.wast:519 +assert_return(() => call($9, "load8_u", [29_471]), 0); + +// memory_copy.wast:520 +assert_return(() => call($9, "load8_u", [29_670]), 0); + +// memory_copy.wast:521 +assert_return(() => call($9, "load8_u", [29_869]), 0); + +// memory_copy.wast:522 +assert_return(() => call($9, "load8_u", [30_068]), 0); + +// memory_copy.wast:523 +assert_return(() => call($9, "load8_u", [30_267]), 0); + +// memory_copy.wast:524 +assert_return(() => call($9, "load8_u", [30_466]), 0); + +// memory_copy.wast:525 +assert_return(() => call($9, "load8_u", [30_665]), 0); + +// memory_copy.wast:526 +assert_return(() => call($9, "load8_u", [30_864]), 0); + +// memory_copy.wast:527 +assert_return(() => call($9, "load8_u", [31_063]), 0); + +// memory_copy.wast:528 +assert_return(() => call($9, "load8_u", [31_262]), 0); + +// memory_copy.wast:529 +assert_return(() => call($9, "load8_u", [31_461]), 0); + +// memory_copy.wast:530 +assert_return(() => call($9, "load8_u", [31_660]), 0); + +// memory_copy.wast:531 +assert_return(() => call($9, "load8_u", [31_859]), 0); + +// memory_copy.wast:532 +assert_return(() => call($9, "load8_u", [32_058]), 0); + +// memory_copy.wast:533 +assert_return(() => call($9, "load8_u", [32_257]), 0); + +// memory_copy.wast:534 +assert_return(() => call($9, "load8_u", [32_456]), 0); + +// memory_copy.wast:535 +assert_return(() => call($9, "load8_u", [32_655]), 0); + +// memory_copy.wast:536 +assert_return(() => call($9, "load8_u", [32_854]), 0); + +// memory_copy.wast:537 +assert_return(() => call($9, "load8_u", [33_053]), 0); + +// memory_copy.wast:538 +assert_return(() => call($9, "load8_u", [33_252]), 0); + +// memory_copy.wast:539 +assert_return(() => call($9, "load8_u", [33_451]), 0); + +// memory_copy.wast:540 +assert_return(() => call($9, "load8_u", [33_650]), 0); + +// memory_copy.wast:541 +assert_return(() => call($9, "load8_u", [33_849]), 0); + +// memory_copy.wast:542 +assert_return(() => call($9, "load8_u", [34_048]), 0); + +// memory_copy.wast:543 +assert_return(() => call($9, "load8_u", [34_247]), 0); + +// memory_copy.wast:544 +assert_return(() => call($9, "load8_u", [34_446]), 0); + +// memory_copy.wast:545 +assert_return(() => call($9, "load8_u", [34_645]), 0); + +// memory_copy.wast:546 +assert_return(() => call($9, "load8_u", [34_844]), 0); + +// memory_copy.wast:547 +assert_return(() => call($9, "load8_u", [35_043]), 0); + +// memory_copy.wast:548 +assert_return(() => call($9, "load8_u", [35_242]), 0); + +// memory_copy.wast:549 +assert_return(() => call($9, "load8_u", [35_441]), 0); + +// memory_copy.wast:550 +assert_return(() => call($9, "load8_u", [35_640]), 0); + +// memory_copy.wast:551 +assert_return(() => call($9, "load8_u", [35_839]), 0); + +// memory_copy.wast:552 +assert_return(() => call($9, "load8_u", [36_038]), 0); + +// memory_copy.wast:553 +assert_return(() => call($9, "load8_u", [36_237]), 0); + +// memory_copy.wast:554 +assert_return(() => call($9, "load8_u", [36_436]), 0); + +// memory_copy.wast:555 +assert_return(() => call($9, "load8_u", [36_635]), 0); + +// memory_copy.wast:556 +assert_return(() => call($9, "load8_u", [36_834]), 0); + +// memory_copy.wast:557 +assert_return(() => call($9, "load8_u", [37_033]), 0); + +// memory_copy.wast:558 +assert_return(() => call($9, "load8_u", [37_232]), 0); + +// memory_copy.wast:559 +assert_return(() => call($9, "load8_u", [37_431]), 0); + +// memory_copy.wast:560 +assert_return(() => call($9, "load8_u", [37_630]), 0); + +// memory_copy.wast:561 +assert_return(() => call($9, "load8_u", [37_829]), 0); + +// memory_copy.wast:562 +assert_return(() => call($9, "load8_u", [38_028]), 0); + +// memory_copy.wast:563 +assert_return(() => call($9, "load8_u", [38_227]), 0); + +// memory_copy.wast:564 +assert_return(() => call($9, "load8_u", [38_426]), 0); + +// memory_copy.wast:565 +assert_return(() => call($9, "load8_u", [38_625]), 0); + +// memory_copy.wast:566 +assert_return(() => call($9, "load8_u", [38_824]), 0); + +// memory_copy.wast:567 +assert_return(() => call($9, "load8_u", [39_023]), 0); + +// memory_copy.wast:568 +assert_return(() => call($9, "load8_u", [39_222]), 0); + +// memory_copy.wast:569 +assert_return(() => call($9, "load8_u", [39_421]), 0); + +// memory_copy.wast:570 +assert_return(() => call($9, "load8_u", [39_620]), 0); + +// memory_copy.wast:571 +assert_return(() => call($9, "load8_u", [39_819]), 0); + +// memory_copy.wast:572 +assert_return(() => call($9, "load8_u", [40_018]), 0); + +// memory_copy.wast:573 +assert_return(() => call($9, "load8_u", [40_217]), 0); + +// memory_copy.wast:574 +assert_return(() => call($9, "load8_u", [40_416]), 0); + +// memory_copy.wast:575 +assert_return(() => call($9, "load8_u", [40_615]), 0); + +// memory_copy.wast:576 +assert_return(() => call($9, "load8_u", [40_814]), 0); + +// memory_copy.wast:577 +assert_return(() => call($9, "load8_u", [41_013]), 0); + +// memory_copy.wast:578 +assert_return(() => call($9, "load8_u", [41_212]), 0); + +// memory_copy.wast:579 +assert_return(() => call($9, "load8_u", [41_411]), 0); + +// memory_copy.wast:580 +assert_return(() => call($9, "load8_u", [41_610]), 0); + +// memory_copy.wast:581 +assert_return(() => call($9, "load8_u", [41_809]), 0); + +// memory_copy.wast:582 +assert_return(() => call($9, "load8_u", [42_008]), 0); + +// memory_copy.wast:583 +assert_return(() => call($9, "load8_u", [42_207]), 0); + +// memory_copy.wast:584 +assert_return(() => call($9, "load8_u", [42_406]), 0); + +// memory_copy.wast:585 +assert_return(() => call($9, "load8_u", [42_605]), 0); + +// memory_copy.wast:586 +assert_return(() => call($9, "load8_u", [42_804]), 0); + +// memory_copy.wast:587 +assert_return(() => call($9, "load8_u", [43_003]), 0); + +// memory_copy.wast:588 +assert_return(() => call($9, "load8_u", [43_202]), 0); + +// memory_copy.wast:589 +assert_return(() => call($9, "load8_u", [43_401]), 0); + +// memory_copy.wast:590 +assert_return(() => call($9, "load8_u", [43_600]), 0); + +// memory_copy.wast:591 +assert_return(() => call($9, "load8_u", [43_799]), 0); + +// memory_copy.wast:592 +assert_return(() => call($9, "load8_u", [43_998]), 0); + +// memory_copy.wast:593 +assert_return(() => call($9, "load8_u", [44_197]), 0); + +// memory_copy.wast:594 +assert_return(() => call($9, "load8_u", [44_396]), 0); + +// memory_copy.wast:595 +assert_return(() => call($9, "load8_u", [44_595]), 0); + +// memory_copy.wast:596 +assert_return(() => call($9, "load8_u", [44_794]), 0); + +// memory_copy.wast:597 +assert_return(() => call($9, "load8_u", [44_993]), 0); + +// memory_copy.wast:598 +assert_return(() => call($9, "load8_u", [45_192]), 0); + +// memory_copy.wast:599 +assert_return(() => call($9, "load8_u", [45_391]), 0); + +// memory_copy.wast:600 +assert_return(() => call($9, "load8_u", [45_590]), 0); + +// memory_copy.wast:601 +assert_return(() => call($9, "load8_u", [45_789]), 0); + +// memory_copy.wast:602 +assert_return(() => call($9, "load8_u", [45_988]), 0); + +// memory_copy.wast:603 +assert_return(() => call($9, "load8_u", [46_187]), 0); + +// memory_copy.wast:604 +assert_return(() => call($9, "load8_u", [46_386]), 0); + +// memory_copy.wast:605 +assert_return(() => call($9, "load8_u", [46_585]), 0); + +// memory_copy.wast:606 +assert_return(() => call($9, "load8_u", [46_784]), 0); + +// memory_copy.wast:607 +assert_return(() => call($9, "load8_u", [46_983]), 0); + +// memory_copy.wast:608 +assert_return(() => call($9, "load8_u", [47_182]), 0); + +// memory_copy.wast:609 +assert_return(() => call($9, "load8_u", [47_381]), 0); + +// memory_copy.wast:610 +assert_return(() => call($9, "load8_u", [47_580]), 0); + +// memory_copy.wast:611 +assert_return(() => call($9, "load8_u", [47_779]), 0); + +// memory_copy.wast:612 +assert_return(() => call($9, "load8_u", [47_978]), 0); + +// memory_copy.wast:613 +assert_return(() => call($9, "load8_u", [48_177]), 0); + +// memory_copy.wast:614 +assert_return(() => call($9, "load8_u", [48_376]), 0); + +// memory_copy.wast:615 +assert_return(() => call($9, "load8_u", [48_575]), 0); + +// memory_copy.wast:616 +assert_return(() => call($9, "load8_u", [48_774]), 0); + +// memory_copy.wast:617 +assert_return(() => call($9, "load8_u", [48_973]), 0); + +// memory_copy.wast:618 +assert_return(() => call($9, "load8_u", [49_172]), 0); + +// memory_copy.wast:619 +assert_return(() => call($9, "load8_u", [49_371]), 0); + +// memory_copy.wast:620 +assert_return(() => call($9, "load8_u", [49_570]), 0); + +// memory_copy.wast:621 +assert_return(() => call($9, "load8_u", [49_769]), 0); + +// memory_copy.wast:622 +assert_return(() => call($9, "load8_u", [49_968]), 0); + +// memory_copy.wast:623 +assert_return(() => call($9, "load8_u", [50_167]), 0); + +// memory_copy.wast:624 +assert_return(() => call($9, "load8_u", [50_366]), 0); + +// memory_copy.wast:625 +assert_return(() => call($9, "load8_u", [50_565]), 0); + +// memory_copy.wast:626 +assert_return(() => call($9, "load8_u", [50_764]), 0); + +// memory_copy.wast:627 +assert_return(() => call($9, "load8_u", [50_963]), 0); + +// memory_copy.wast:628 +assert_return(() => call($9, "load8_u", [51_162]), 0); + +// memory_copy.wast:629 +assert_return(() => call($9, "load8_u", [51_361]), 0); + +// memory_copy.wast:630 +assert_return(() => call($9, "load8_u", [51_560]), 0); + +// memory_copy.wast:631 +assert_return(() => call($9, "load8_u", [51_759]), 0); + +// memory_copy.wast:632 +assert_return(() => call($9, "load8_u", [51_958]), 0); + +// memory_copy.wast:633 +assert_return(() => call($9, "load8_u", [52_157]), 0); + +// memory_copy.wast:634 +assert_return(() => call($9, "load8_u", [52_356]), 0); + +// memory_copy.wast:635 +assert_return(() => call($9, "load8_u", [52_555]), 0); + +// memory_copy.wast:636 +assert_return(() => call($9, "load8_u", [52_754]), 0); + +// memory_copy.wast:637 +assert_return(() => call($9, "load8_u", [52_953]), 0); + +// memory_copy.wast:638 +assert_return(() => call($9, "load8_u", [53_152]), 0); + +// memory_copy.wast:639 +assert_return(() => call($9, "load8_u", [53_351]), 0); + +// memory_copy.wast:640 +assert_return(() => call($9, "load8_u", [53_550]), 0); + +// memory_copy.wast:641 +assert_return(() => call($9, "load8_u", [53_749]), 0); + +// memory_copy.wast:642 +assert_return(() => call($9, "load8_u", [53_948]), 0); + +// memory_copy.wast:643 +assert_return(() => call($9, "load8_u", [54_147]), 0); + +// memory_copy.wast:644 +assert_return(() => call($9, "load8_u", [54_346]), 0); + +// memory_copy.wast:645 +assert_return(() => call($9, "load8_u", [54_545]), 0); + +// memory_copy.wast:646 +assert_return(() => call($9, "load8_u", [54_744]), 0); + +// memory_copy.wast:647 +assert_return(() => call($9, "load8_u", [54_943]), 0); + +// memory_copy.wast:648 +assert_return(() => call($9, "load8_u", [55_142]), 0); + +// memory_copy.wast:649 +assert_return(() => call($9, "load8_u", [55_341]), 0); + +// memory_copy.wast:650 +assert_return(() => call($9, "load8_u", [55_540]), 0); + +// memory_copy.wast:651 +assert_return(() => call($9, "load8_u", [55_739]), 0); + +// memory_copy.wast:652 +assert_return(() => call($9, "load8_u", [55_938]), 0); + +// memory_copy.wast:653 +assert_return(() => call($9, "load8_u", [56_137]), 0); + +// memory_copy.wast:654 +assert_return(() => call($9, "load8_u", [56_336]), 0); + +// memory_copy.wast:655 +assert_return(() => call($9, "load8_u", [56_535]), 0); + +// memory_copy.wast:656 +assert_return(() => call($9, "load8_u", [56_734]), 0); + +// memory_copy.wast:657 +assert_return(() => call($9, "load8_u", [56_933]), 0); + +// memory_copy.wast:658 +assert_return(() => call($9, "load8_u", [57_132]), 0); + +// memory_copy.wast:659 +assert_return(() => call($9, "load8_u", [57_331]), 0); + +// memory_copy.wast:660 +assert_return(() => call($9, "load8_u", [57_530]), 0); + +// memory_copy.wast:661 +assert_return(() => call($9, "load8_u", [57_729]), 0); + +// memory_copy.wast:662 +assert_return(() => call($9, "load8_u", [57_928]), 0); + +// memory_copy.wast:663 +assert_return(() => call($9, "load8_u", [58_127]), 0); + +// memory_copy.wast:664 +assert_return(() => call($9, "load8_u", [58_326]), 0); + +// memory_copy.wast:665 +assert_return(() => call($9, "load8_u", [58_525]), 0); + +// memory_copy.wast:666 +assert_return(() => call($9, "load8_u", [58_724]), 0); + +// memory_copy.wast:667 +assert_return(() => call($9, "load8_u", [58_923]), 0); + +// memory_copy.wast:668 +assert_return(() => call($9, "load8_u", [59_122]), 0); + +// memory_copy.wast:669 +assert_return(() => call($9, "load8_u", [59_321]), 0); + +// memory_copy.wast:670 +assert_return(() => call($9, "load8_u", [59_520]), 0); + +// memory_copy.wast:671 +assert_return(() => call($9, "load8_u", [59_719]), 0); + +// memory_copy.wast:672 +assert_return(() => call($9, "load8_u", [59_918]), 0); + +// memory_copy.wast:673 +assert_return(() => call($9, "load8_u", [60_117]), 0); + +// memory_copy.wast:674 +assert_return(() => call($9, "load8_u", [60_316]), 0); + +// memory_copy.wast:675 +assert_return(() => call($9, "load8_u", [60_515]), 0); + +// memory_copy.wast:676 +assert_return(() => call($9, "load8_u", [60_714]), 0); + +// memory_copy.wast:677 +assert_return(() => call($9, "load8_u", [60_913]), 0); + +// memory_copy.wast:678 +assert_return(() => call($9, "load8_u", [61_112]), 0); + +// memory_copy.wast:679 +assert_return(() => call($9, "load8_u", [61_311]), 0); + +// memory_copy.wast:680 +assert_return(() => call($9, "load8_u", [61_510]), 0); + +// memory_copy.wast:681 +assert_return(() => call($9, "load8_u", [61_709]), 0); + +// memory_copy.wast:682 +assert_return(() => call($9, "load8_u", [61_908]), 0); + +// memory_copy.wast:683 +assert_return(() => call($9, "load8_u", [62_107]), 0); + +// memory_copy.wast:684 +assert_return(() => call($9, "load8_u", [62_306]), 0); + +// memory_copy.wast:685 +assert_return(() => call($9, "load8_u", [62_505]), 0); + +// memory_copy.wast:686 +assert_return(() => call($9, "load8_u", [62_704]), 0); + +// memory_copy.wast:687 +assert_return(() => call($9, "load8_u", [62_903]), 0); + +// memory_copy.wast:688 +assert_return(() => call($9, "load8_u", [63_102]), 0); + +// memory_copy.wast:689 +assert_return(() => call($9, "load8_u", [63_301]), 0); + +// memory_copy.wast:690 +assert_return(() => call($9, "load8_u", [63_500]), 0); + +// memory_copy.wast:691 +assert_return(() => call($9, "load8_u", [63_699]), 0); + +// memory_copy.wast:692 +assert_return(() => call($9, "load8_u", [63_898]), 0); + +// memory_copy.wast:693 +assert_return(() => call($9, "load8_u", [64_097]), 0); + +// memory_copy.wast:694 +assert_return(() => call($9, "load8_u", [64_296]), 0); + +// memory_copy.wast:695 +assert_return(() => call($9, "load8_u", [64_495]), 0); + +// memory_copy.wast:696 +assert_return(() => call($9, "load8_u", [64_694]), 0); + +// memory_copy.wast:697 +assert_return(() => call($9, "load8_u", [64_893]), 0); + +// memory_copy.wast:698 +assert_return(() => call($9, "load8_u", [65_092]), 0); + +// memory_copy.wast:699 +assert_return(() => call($9, "load8_u", [65_291]), 0); + +// memory_copy.wast:700 +assert_return(() => call($9, "load8_u", [65_490]), 0); + +// memory_copy.wast:702 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9b\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x15\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"); + +// memory_copy.wast:710 +assert_trap(() => call($10, "run", [65_515, 0, 39])); + +// memory_copy.wast:713 +assert_return(() => call($10, "load8_u", [0]), 0); + +// memory_copy.wast:714 +assert_return(() => call($10, "load8_u", [1]), 1); + +// memory_copy.wast:715 +assert_return(() => call($10, "load8_u", [2]), 2); + +// memory_copy.wast:716 +assert_return(() => call($10, "load8_u", [3]), 3); + +// memory_copy.wast:717 +assert_return(() => call($10, "load8_u", [4]), 4); + +// memory_copy.wast:718 +assert_return(() => call($10, "load8_u", [5]), 5); + +// memory_copy.wast:719 +assert_return(() => call($10, "load8_u", [6]), 6); + +// memory_copy.wast:720 +assert_return(() => call($10, "load8_u", [7]), 7); + +// memory_copy.wast:721 +assert_return(() => call($10, "load8_u", [8]), 8); + +// memory_copy.wast:722 +assert_return(() => call($10, "load8_u", [9]), 9); + +// memory_copy.wast:723 +assert_return(() => call($10, "load8_u", [10]), 10); + +// memory_copy.wast:724 +assert_return(() => call($10, "load8_u", [11]), 11); + +// memory_copy.wast:725 +assert_return(() => call($10, "load8_u", [12]), 12); + +// memory_copy.wast:726 +assert_return(() => call($10, "load8_u", [13]), 13); + +// memory_copy.wast:727 +assert_return(() => call($10, "load8_u", [14]), 14); + +// memory_copy.wast:728 +assert_return(() => call($10, "load8_u", [15]), 15); + +// memory_copy.wast:729 +assert_return(() => call($10, "load8_u", [16]), 16); + +// memory_copy.wast:730 +assert_return(() => call($10, "load8_u", [17]), 17); + +// memory_copy.wast:731 +assert_return(() => call($10, "load8_u", [18]), 18); + +// memory_copy.wast:732 +assert_return(() => call($10, "load8_u", [19]), 19); + +// memory_copy.wast:733 +assert_return(() => call($10, "load8_u", [20]), 20); + +// memory_copy.wast:734 +assert_return(() => call($10, "load8_u", [219]), 0); + +// memory_copy.wast:735 +assert_return(() => call($10, "load8_u", [418]), 0); + +// memory_copy.wast:736 +assert_return(() => call($10, "load8_u", [617]), 0); + +// memory_copy.wast:737 +assert_return(() => call($10, "load8_u", [816]), 0); + +// memory_copy.wast:738 +assert_return(() => call($10, "load8_u", [1_015]), 0); + +// memory_copy.wast:739 +assert_return(() => call($10, "load8_u", [1_214]), 0); + +// memory_copy.wast:740 +assert_return(() => call($10, "load8_u", [1_413]), 0); + +// memory_copy.wast:741 +assert_return(() => call($10, "load8_u", [1_612]), 0); + +// memory_copy.wast:742 +assert_return(() => call($10, "load8_u", [1_811]), 0); + +// memory_copy.wast:743 +assert_return(() => call($10, "load8_u", [2_010]), 0); + +// memory_copy.wast:744 +assert_return(() => call($10, "load8_u", [2_209]), 0); + +// memory_copy.wast:745 +assert_return(() => call($10, "load8_u", [2_408]), 0); + +// memory_copy.wast:746 +assert_return(() => call($10, "load8_u", [2_607]), 0); + +// memory_copy.wast:747 +assert_return(() => call($10, "load8_u", [2_806]), 0); + +// memory_copy.wast:748 +assert_return(() => call($10, "load8_u", [3_005]), 0); + +// memory_copy.wast:749 +assert_return(() => call($10, "load8_u", [3_204]), 0); + +// memory_copy.wast:750 +assert_return(() => call($10, "load8_u", [3_403]), 0); + +// memory_copy.wast:751 +assert_return(() => call($10, "load8_u", [3_602]), 0); + +// memory_copy.wast:752 +assert_return(() => call($10, "load8_u", [3_801]), 0); + +// memory_copy.wast:753 +assert_return(() => call($10, "load8_u", [4_000]), 0); + +// memory_copy.wast:754 +assert_return(() => call($10, "load8_u", [4_199]), 0); + +// memory_copy.wast:755 +assert_return(() => call($10, "load8_u", [4_398]), 0); + +// memory_copy.wast:756 +assert_return(() => call($10, "load8_u", [4_597]), 0); + +// memory_copy.wast:757 +assert_return(() => call($10, "load8_u", [4_796]), 0); + +// memory_copy.wast:758 +assert_return(() => call($10, "load8_u", [4_995]), 0); + +// memory_copy.wast:759 +assert_return(() => call($10, "load8_u", [5_194]), 0); + +// memory_copy.wast:760 +assert_return(() => call($10, "load8_u", [5_393]), 0); + +// memory_copy.wast:761 +assert_return(() => call($10, "load8_u", [5_592]), 0); + +// memory_copy.wast:762 +assert_return(() => call($10, "load8_u", [5_791]), 0); + +// memory_copy.wast:763 +assert_return(() => call($10, "load8_u", [5_990]), 0); + +// memory_copy.wast:764 +assert_return(() => call($10, "load8_u", [6_189]), 0); + +// memory_copy.wast:765 +assert_return(() => call($10, "load8_u", [6_388]), 0); + +// memory_copy.wast:766 +assert_return(() => call($10, "load8_u", [6_587]), 0); + +// memory_copy.wast:767 +assert_return(() => call($10, "load8_u", [6_786]), 0); + +// memory_copy.wast:768 +assert_return(() => call($10, "load8_u", [6_985]), 0); + +// memory_copy.wast:769 +assert_return(() => call($10, "load8_u", [7_184]), 0); + +// memory_copy.wast:770 +assert_return(() => call($10, "load8_u", [7_383]), 0); + +// memory_copy.wast:771 +assert_return(() => call($10, "load8_u", [7_582]), 0); + +// memory_copy.wast:772 +assert_return(() => call($10, "load8_u", [7_781]), 0); + +// memory_copy.wast:773 +assert_return(() => call($10, "load8_u", [7_980]), 0); + +// memory_copy.wast:774 +assert_return(() => call($10, "load8_u", [8_179]), 0); + +// memory_copy.wast:775 +assert_return(() => call($10, "load8_u", [8_378]), 0); + +// memory_copy.wast:776 +assert_return(() => call($10, "load8_u", [8_577]), 0); + +// memory_copy.wast:777 +assert_return(() => call($10, "load8_u", [8_776]), 0); + +// memory_copy.wast:778 +assert_return(() => call($10, "load8_u", [8_975]), 0); + +// memory_copy.wast:779 +assert_return(() => call($10, "load8_u", [9_174]), 0); + +// memory_copy.wast:780 +assert_return(() => call($10, "load8_u", [9_373]), 0); + +// memory_copy.wast:781 +assert_return(() => call($10, "load8_u", [9_572]), 0); + +// memory_copy.wast:782 +assert_return(() => call($10, "load8_u", [9_771]), 0); + +// memory_copy.wast:783 +assert_return(() => call($10, "load8_u", [9_970]), 0); + +// memory_copy.wast:784 +assert_return(() => call($10, "load8_u", [10_169]), 0); + +// memory_copy.wast:785 +assert_return(() => call($10, "load8_u", [10_368]), 0); + +// memory_copy.wast:786 +assert_return(() => call($10, "load8_u", [10_567]), 0); + +// memory_copy.wast:787 +assert_return(() => call($10, "load8_u", [10_766]), 0); + +// memory_copy.wast:788 +assert_return(() => call($10, "load8_u", [10_965]), 0); + +// memory_copy.wast:789 +assert_return(() => call($10, "load8_u", [11_164]), 0); + +// memory_copy.wast:790 +assert_return(() => call($10, "load8_u", [11_363]), 0); + +// memory_copy.wast:791 +assert_return(() => call($10, "load8_u", [11_562]), 0); + +// memory_copy.wast:792 +assert_return(() => call($10, "load8_u", [11_761]), 0); + +// memory_copy.wast:793 +assert_return(() => call($10, "load8_u", [11_960]), 0); + +// memory_copy.wast:794 +assert_return(() => call($10, "load8_u", [12_159]), 0); + +// memory_copy.wast:795 +assert_return(() => call($10, "load8_u", [12_358]), 0); + +// memory_copy.wast:796 +assert_return(() => call($10, "load8_u", [12_557]), 0); + +// memory_copy.wast:797 +assert_return(() => call($10, "load8_u", [12_756]), 0); + +// memory_copy.wast:798 +assert_return(() => call($10, "load8_u", [12_955]), 0); + +// memory_copy.wast:799 +assert_return(() => call($10, "load8_u", [13_154]), 0); + +// memory_copy.wast:800 +assert_return(() => call($10, "load8_u", [13_353]), 0); + +// memory_copy.wast:801 +assert_return(() => call($10, "load8_u", [13_552]), 0); + +// memory_copy.wast:802 +assert_return(() => call($10, "load8_u", [13_751]), 0); + +// memory_copy.wast:803 +assert_return(() => call($10, "load8_u", [13_950]), 0); + +// memory_copy.wast:804 +assert_return(() => call($10, "load8_u", [14_149]), 0); + +// memory_copy.wast:805 +assert_return(() => call($10, "load8_u", [14_348]), 0); + +// memory_copy.wast:806 +assert_return(() => call($10, "load8_u", [14_547]), 0); + +// memory_copy.wast:807 +assert_return(() => call($10, "load8_u", [14_746]), 0); + +// memory_copy.wast:808 +assert_return(() => call($10, "load8_u", [14_945]), 0); + +// memory_copy.wast:809 +assert_return(() => call($10, "load8_u", [15_144]), 0); + +// memory_copy.wast:810 +assert_return(() => call($10, "load8_u", [15_343]), 0); + +// memory_copy.wast:811 +assert_return(() => call($10, "load8_u", [15_542]), 0); + +// memory_copy.wast:812 +assert_return(() => call($10, "load8_u", [15_741]), 0); + +// memory_copy.wast:813 +assert_return(() => call($10, "load8_u", [15_940]), 0); + +// memory_copy.wast:814 +assert_return(() => call($10, "load8_u", [16_139]), 0); + +// memory_copy.wast:815 +assert_return(() => call($10, "load8_u", [16_338]), 0); + +// memory_copy.wast:816 +assert_return(() => call($10, "load8_u", [16_537]), 0); + +// memory_copy.wast:817 +assert_return(() => call($10, "load8_u", [16_736]), 0); + +// memory_copy.wast:818 +assert_return(() => call($10, "load8_u", [16_935]), 0); + +// memory_copy.wast:819 +assert_return(() => call($10, "load8_u", [17_134]), 0); + +// memory_copy.wast:820 +assert_return(() => call($10, "load8_u", [17_333]), 0); + +// memory_copy.wast:821 +assert_return(() => call($10, "load8_u", [17_532]), 0); + +// memory_copy.wast:822 +assert_return(() => call($10, "load8_u", [17_731]), 0); + +// memory_copy.wast:823 +assert_return(() => call($10, "load8_u", [17_930]), 0); + +// memory_copy.wast:824 +assert_return(() => call($10, "load8_u", [18_129]), 0); + +// memory_copy.wast:825 +assert_return(() => call($10, "load8_u", [18_328]), 0); + +// memory_copy.wast:826 +assert_return(() => call($10, "load8_u", [18_527]), 0); + +// memory_copy.wast:827 +assert_return(() => call($10, "load8_u", [18_726]), 0); + +// memory_copy.wast:828 +assert_return(() => call($10, "load8_u", [18_925]), 0); + +// memory_copy.wast:829 +assert_return(() => call($10, "load8_u", [19_124]), 0); + +// memory_copy.wast:830 +assert_return(() => call($10, "load8_u", [19_323]), 0); + +// memory_copy.wast:831 +assert_return(() => call($10, "load8_u", [19_522]), 0); + +// memory_copy.wast:832 +assert_return(() => call($10, "load8_u", [19_721]), 0); + +// memory_copy.wast:833 +assert_return(() => call($10, "load8_u", [19_920]), 0); + +// memory_copy.wast:834 +assert_return(() => call($10, "load8_u", [20_119]), 0); + +// memory_copy.wast:835 +assert_return(() => call($10, "load8_u", [20_318]), 0); + +// memory_copy.wast:836 +assert_return(() => call($10, "load8_u", [20_517]), 0); + +// memory_copy.wast:837 +assert_return(() => call($10, "load8_u", [20_716]), 0); + +// memory_copy.wast:838 +assert_return(() => call($10, "load8_u", [20_915]), 0); + +// memory_copy.wast:839 +assert_return(() => call($10, "load8_u", [21_114]), 0); + +// memory_copy.wast:840 +assert_return(() => call($10, "load8_u", [21_313]), 0); + +// memory_copy.wast:841 +assert_return(() => call($10, "load8_u", [21_512]), 0); + +// memory_copy.wast:842 +assert_return(() => call($10, "load8_u", [21_711]), 0); + +// memory_copy.wast:843 +assert_return(() => call($10, "load8_u", [21_910]), 0); + +// memory_copy.wast:844 +assert_return(() => call($10, "load8_u", [22_109]), 0); + +// memory_copy.wast:845 +assert_return(() => call($10, "load8_u", [22_308]), 0); + +// memory_copy.wast:846 +assert_return(() => call($10, "load8_u", [22_507]), 0); + +// memory_copy.wast:847 +assert_return(() => call($10, "load8_u", [22_706]), 0); + +// memory_copy.wast:848 +assert_return(() => call($10, "load8_u", [22_905]), 0); + +// memory_copy.wast:849 +assert_return(() => call($10, "load8_u", [23_104]), 0); + +// memory_copy.wast:850 +assert_return(() => call($10, "load8_u", [23_303]), 0); + +// memory_copy.wast:851 +assert_return(() => call($10, "load8_u", [23_502]), 0); + +// memory_copy.wast:852 +assert_return(() => call($10, "load8_u", [23_701]), 0); + +// memory_copy.wast:853 +assert_return(() => call($10, "load8_u", [23_900]), 0); + +// memory_copy.wast:854 +assert_return(() => call($10, "load8_u", [24_099]), 0); + +// memory_copy.wast:855 +assert_return(() => call($10, "load8_u", [24_298]), 0); + +// memory_copy.wast:856 +assert_return(() => call($10, "load8_u", [24_497]), 0); + +// memory_copy.wast:857 +assert_return(() => call($10, "load8_u", [24_696]), 0); + +// memory_copy.wast:858 +assert_return(() => call($10, "load8_u", [24_895]), 0); + +// memory_copy.wast:859 +assert_return(() => call($10, "load8_u", [25_094]), 0); + +// memory_copy.wast:860 +assert_return(() => call($10, "load8_u", [25_293]), 0); + +// memory_copy.wast:861 +assert_return(() => call($10, "load8_u", [25_492]), 0); + +// memory_copy.wast:862 +assert_return(() => call($10, "load8_u", [25_691]), 0); + +// memory_copy.wast:863 +assert_return(() => call($10, "load8_u", [25_890]), 0); + +// memory_copy.wast:864 +assert_return(() => call($10, "load8_u", [26_089]), 0); + +// memory_copy.wast:865 +assert_return(() => call($10, "load8_u", [26_288]), 0); + +// memory_copy.wast:866 +assert_return(() => call($10, "load8_u", [26_487]), 0); + +// memory_copy.wast:867 +assert_return(() => call($10, "load8_u", [26_686]), 0); + +// memory_copy.wast:868 +assert_return(() => call($10, "load8_u", [26_885]), 0); + +// memory_copy.wast:869 +assert_return(() => call($10, "load8_u", [27_084]), 0); + +// memory_copy.wast:870 +assert_return(() => call($10, "load8_u", [27_283]), 0); + +// memory_copy.wast:871 +assert_return(() => call($10, "load8_u", [27_482]), 0); + +// memory_copy.wast:872 +assert_return(() => call($10, "load8_u", [27_681]), 0); + +// memory_copy.wast:873 +assert_return(() => call($10, "load8_u", [27_880]), 0); + +// memory_copy.wast:874 +assert_return(() => call($10, "load8_u", [28_079]), 0); + +// memory_copy.wast:875 +assert_return(() => call($10, "load8_u", [28_278]), 0); + +// memory_copy.wast:876 +assert_return(() => call($10, "load8_u", [28_477]), 0); + +// memory_copy.wast:877 +assert_return(() => call($10, "load8_u", [28_676]), 0); + +// memory_copy.wast:878 +assert_return(() => call($10, "load8_u", [28_875]), 0); + +// memory_copy.wast:879 +assert_return(() => call($10, "load8_u", [29_074]), 0); + +// memory_copy.wast:880 +assert_return(() => call($10, "load8_u", [29_273]), 0); + +// memory_copy.wast:881 +assert_return(() => call($10, "load8_u", [29_472]), 0); + +// memory_copy.wast:882 +assert_return(() => call($10, "load8_u", [29_671]), 0); + +// memory_copy.wast:883 +assert_return(() => call($10, "load8_u", [29_870]), 0); + +// memory_copy.wast:884 +assert_return(() => call($10, "load8_u", [30_069]), 0); + +// memory_copy.wast:885 +assert_return(() => call($10, "load8_u", [30_268]), 0); + +// memory_copy.wast:886 +assert_return(() => call($10, "load8_u", [30_467]), 0); + +// memory_copy.wast:887 +assert_return(() => call($10, "load8_u", [30_666]), 0); + +// memory_copy.wast:888 +assert_return(() => call($10, "load8_u", [30_865]), 0); + +// memory_copy.wast:889 +assert_return(() => call($10, "load8_u", [31_064]), 0); + +// memory_copy.wast:890 +assert_return(() => call($10, "load8_u", [31_263]), 0); + +// memory_copy.wast:891 +assert_return(() => call($10, "load8_u", [31_462]), 0); + +// memory_copy.wast:892 +assert_return(() => call($10, "load8_u", [31_661]), 0); + +// memory_copy.wast:893 +assert_return(() => call($10, "load8_u", [31_860]), 0); + +// memory_copy.wast:894 +assert_return(() => call($10, "load8_u", [32_059]), 0); + +// memory_copy.wast:895 +assert_return(() => call($10, "load8_u", [32_258]), 0); + +// memory_copy.wast:896 +assert_return(() => call($10, "load8_u", [32_457]), 0); + +// memory_copy.wast:897 +assert_return(() => call($10, "load8_u", [32_656]), 0); + +// memory_copy.wast:898 +assert_return(() => call($10, "load8_u", [32_855]), 0); + +// memory_copy.wast:899 +assert_return(() => call($10, "load8_u", [33_054]), 0); + +// memory_copy.wast:900 +assert_return(() => call($10, "load8_u", [33_253]), 0); + +// memory_copy.wast:901 +assert_return(() => call($10, "load8_u", [33_452]), 0); + +// memory_copy.wast:902 +assert_return(() => call($10, "load8_u", [33_651]), 0); + +// memory_copy.wast:903 +assert_return(() => call($10, "load8_u", [33_850]), 0); + +// memory_copy.wast:904 +assert_return(() => call($10, "load8_u", [34_049]), 0); + +// memory_copy.wast:905 +assert_return(() => call($10, "load8_u", [34_248]), 0); + +// memory_copy.wast:906 +assert_return(() => call($10, "load8_u", [34_447]), 0); + +// memory_copy.wast:907 +assert_return(() => call($10, "load8_u", [34_646]), 0); + +// memory_copy.wast:908 +assert_return(() => call($10, "load8_u", [34_845]), 0); + +// memory_copy.wast:909 +assert_return(() => call($10, "load8_u", [35_044]), 0); + +// memory_copy.wast:910 +assert_return(() => call($10, "load8_u", [35_243]), 0); + +// memory_copy.wast:911 +assert_return(() => call($10, "load8_u", [35_442]), 0); + +// memory_copy.wast:912 +assert_return(() => call($10, "load8_u", [35_641]), 0); + +// memory_copy.wast:913 +assert_return(() => call($10, "load8_u", [35_840]), 0); + +// memory_copy.wast:914 +assert_return(() => call($10, "load8_u", [36_039]), 0); + +// memory_copy.wast:915 +assert_return(() => call($10, "load8_u", [36_238]), 0); + +// memory_copy.wast:916 +assert_return(() => call($10, "load8_u", [36_437]), 0); + +// memory_copy.wast:917 +assert_return(() => call($10, "load8_u", [36_636]), 0); + +// memory_copy.wast:918 +assert_return(() => call($10, "load8_u", [36_835]), 0); + +// memory_copy.wast:919 +assert_return(() => call($10, "load8_u", [37_034]), 0); + +// memory_copy.wast:920 +assert_return(() => call($10, "load8_u", [37_233]), 0); + +// memory_copy.wast:921 +assert_return(() => call($10, "load8_u", [37_432]), 0); + +// memory_copy.wast:922 +assert_return(() => call($10, "load8_u", [37_631]), 0); + +// memory_copy.wast:923 +assert_return(() => call($10, "load8_u", [37_830]), 0); + +// memory_copy.wast:924 +assert_return(() => call($10, "load8_u", [38_029]), 0); + +// memory_copy.wast:925 +assert_return(() => call($10, "load8_u", [38_228]), 0); + +// memory_copy.wast:926 +assert_return(() => call($10, "load8_u", [38_427]), 0); + +// memory_copy.wast:927 +assert_return(() => call($10, "load8_u", [38_626]), 0); + +// memory_copy.wast:928 +assert_return(() => call($10, "load8_u", [38_825]), 0); + +// memory_copy.wast:929 +assert_return(() => call($10, "load8_u", [39_024]), 0); + +// memory_copy.wast:930 +assert_return(() => call($10, "load8_u", [39_223]), 0); + +// memory_copy.wast:931 +assert_return(() => call($10, "load8_u", [39_422]), 0); + +// memory_copy.wast:932 +assert_return(() => call($10, "load8_u", [39_621]), 0); + +// memory_copy.wast:933 +assert_return(() => call($10, "load8_u", [39_820]), 0); + +// memory_copy.wast:934 +assert_return(() => call($10, "load8_u", [40_019]), 0); + +// memory_copy.wast:935 +assert_return(() => call($10, "load8_u", [40_218]), 0); + +// memory_copy.wast:936 +assert_return(() => call($10, "load8_u", [40_417]), 0); + +// memory_copy.wast:937 +assert_return(() => call($10, "load8_u", [40_616]), 0); + +// memory_copy.wast:938 +assert_return(() => call($10, "load8_u", [40_815]), 0); + +// memory_copy.wast:939 +assert_return(() => call($10, "load8_u", [41_014]), 0); + +// memory_copy.wast:940 +assert_return(() => call($10, "load8_u", [41_213]), 0); + +// memory_copy.wast:941 +assert_return(() => call($10, "load8_u", [41_412]), 0); + +// memory_copy.wast:942 +assert_return(() => call($10, "load8_u", [41_611]), 0); + +// memory_copy.wast:943 +assert_return(() => call($10, "load8_u", [41_810]), 0); + +// memory_copy.wast:944 +assert_return(() => call($10, "load8_u", [42_009]), 0); + +// memory_copy.wast:945 +assert_return(() => call($10, "load8_u", [42_208]), 0); + +// memory_copy.wast:946 +assert_return(() => call($10, "load8_u", [42_407]), 0); + +// memory_copy.wast:947 +assert_return(() => call($10, "load8_u", [42_606]), 0); + +// memory_copy.wast:948 +assert_return(() => call($10, "load8_u", [42_805]), 0); + +// memory_copy.wast:949 +assert_return(() => call($10, "load8_u", [43_004]), 0); + +// memory_copy.wast:950 +assert_return(() => call($10, "load8_u", [43_203]), 0); + +// memory_copy.wast:951 +assert_return(() => call($10, "load8_u", [43_402]), 0); + +// memory_copy.wast:952 +assert_return(() => call($10, "load8_u", [43_601]), 0); + +// memory_copy.wast:953 +assert_return(() => call($10, "load8_u", [43_800]), 0); + +// memory_copy.wast:954 +assert_return(() => call($10, "load8_u", [43_999]), 0); + +// memory_copy.wast:955 +assert_return(() => call($10, "load8_u", [44_198]), 0); + +// memory_copy.wast:956 +assert_return(() => call($10, "load8_u", [44_397]), 0); + +// memory_copy.wast:957 +assert_return(() => call($10, "load8_u", [44_596]), 0); + +// memory_copy.wast:958 +assert_return(() => call($10, "load8_u", [44_795]), 0); + +// memory_copy.wast:959 +assert_return(() => call($10, "load8_u", [44_994]), 0); + +// memory_copy.wast:960 +assert_return(() => call($10, "load8_u", [45_193]), 0); + +// memory_copy.wast:961 +assert_return(() => call($10, "load8_u", [45_392]), 0); + +// memory_copy.wast:962 +assert_return(() => call($10, "load8_u", [45_591]), 0); + +// memory_copy.wast:963 +assert_return(() => call($10, "load8_u", [45_790]), 0); + +// memory_copy.wast:964 +assert_return(() => call($10, "load8_u", [45_989]), 0); + +// memory_copy.wast:965 +assert_return(() => call($10, "load8_u", [46_188]), 0); + +// memory_copy.wast:966 +assert_return(() => call($10, "load8_u", [46_387]), 0); + +// memory_copy.wast:967 +assert_return(() => call($10, "load8_u", [46_586]), 0); + +// memory_copy.wast:968 +assert_return(() => call($10, "load8_u", [46_785]), 0); + +// memory_copy.wast:969 +assert_return(() => call($10, "load8_u", [46_984]), 0); + +// memory_copy.wast:970 +assert_return(() => call($10, "load8_u", [47_183]), 0); + +// memory_copy.wast:971 +assert_return(() => call($10, "load8_u", [47_382]), 0); + +// memory_copy.wast:972 +assert_return(() => call($10, "load8_u", [47_581]), 0); + +// memory_copy.wast:973 +assert_return(() => call($10, "load8_u", [47_780]), 0); + +// memory_copy.wast:974 +assert_return(() => call($10, "load8_u", [47_979]), 0); + +// memory_copy.wast:975 +assert_return(() => call($10, "load8_u", [48_178]), 0); + +// memory_copy.wast:976 +assert_return(() => call($10, "load8_u", [48_377]), 0); + +// memory_copy.wast:977 +assert_return(() => call($10, "load8_u", [48_576]), 0); + +// memory_copy.wast:978 +assert_return(() => call($10, "load8_u", [48_775]), 0); + +// memory_copy.wast:979 +assert_return(() => call($10, "load8_u", [48_974]), 0); + +// memory_copy.wast:980 +assert_return(() => call($10, "load8_u", [49_173]), 0); + +// memory_copy.wast:981 +assert_return(() => call($10, "load8_u", [49_372]), 0); + +// memory_copy.wast:982 +assert_return(() => call($10, "load8_u", [49_571]), 0); + +// memory_copy.wast:983 +assert_return(() => call($10, "load8_u", [49_770]), 0); + +// memory_copy.wast:984 +assert_return(() => call($10, "load8_u", [49_969]), 0); + +// memory_copy.wast:985 +assert_return(() => call($10, "load8_u", [50_168]), 0); + +// memory_copy.wast:986 +assert_return(() => call($10, "load8_u", [50_367]), 0); + +// memory_copy.wast:987 +assert_return(() => call($10, "load8_u", [50_566]), 0); + +// memory_copy.wast:988 +assert_return(() => call($10, "load8_u", [50_765]), 0); + +// memory_copy.wast:989 +assert_return(() => call($10, "load8_u", [50_964]), 0); + +// memory_copy.wast:990 +assert_return(() => call($10, "load8_u", [51_163]), 0); + +// memory_copy.wast:991 +assert_return(() => call($10, "load8_u", [51_362]), 0); + +// memory_copy.wast:992 +assert_return(() => call($10, "load8_u", [51_561]), 0); + +// memory_copy.wast:993 +assert_return(() => call($10, "load8_u", [51_760]), 0); + +// memory_copy.wast:994 +assert_return(() => call($10, "load8_u", [51_959]), 0); + +// memory_copy.wast:995 +assert_return(() => call($10, "load8_u", [52_158]), 0); + +// memory_copy.wast:996 +assert_return(() => call($10, "load8_u", [52_357]), 0); + +// memory_copy.wast:997 +assert_return(() => call($10, "load8_u", [52_556]), 0); + +// memory_copy.wast:998 +assert_return(() => call($10, "load8_u", [52_755]), 0); + +// memory_copy.wast:999 +assert_return(() => call($10, "load8_u", [52_954]), 0); + +// memory_copy.wast:1000 +assert_return(() => call($10, "load8_u", [53_153]), 0); + +// memory_copy.wast:1001 +assert_return(() => call($10, "load8_u", [53_352]), 0); + +// memory_copy.wast:1002 +assert_return(() => call($10, "load8_u", [53_551]), 0); + +// memory_copy.wast:1003 +assert_return(() => call($10, "load8_u", [53_750]), 0); + +// memory_copy.wast:1004 +assert_return(() => call($10, "load8_u", [53_949]), 0); + +// memory_copy.wast:1005 +assert_return(() => call($10, "load8_u", [54_148]), 0); + +// memory_copy.wast:1006 +assert_return(() => call($10, "load8_u", [54_347]), 0); + +// memory_copy.wast:1007 +assert_return(() => call($10, "load8_u", [54_546]), 0); + +// memory_copy.wast:1008 +assert_return(() => call($10, "load8_u", [54_745]), 0); + +// memory_copy.wast:1009 +assert_return(() => call($10, "load8_u", [54_944]), 0); + +// memory_copy.wast:1010 +assert_return(() => call($10, "load8_u", [55_143]), 0); + +// memory_copy.wast:1011 +assert_return(() => call($10, "load8_u", [55_342]), 0); + +// memory_copy.wast:1012 +assert_return(() => call($10, "load8_u", [55_541]), 0); + +// memory_copy.wast:1013 +assert_return(() => call($10, "load8_u", [55_740]), 0); + +// memory_copy.wast:1014 +assert_return(() => call($10, "load8_u", [55_939]), 0); + +// memory_copy.wast:1015 +assert_return(() => call($10, "load8_u", [56_138]), 0); + +// memory_copy.wast:1016 +assert_return(() => call($10, "load8_u", [56_337]), 0); + +// memory_copy.wast:1017 +assert_return(() => call($10, "load8_u", [56_536]), 0); + +// memory_copy.wast:1018 +assert_return(() => call($10, "load8_u", [56_735]), 0); + +// memory_copy.wast:1019 +assert_return(() => call($10, "load8_u", [56_934]), 0); + +// memory_copy.wast:1020 +assert_return(() => call($10, "load8_u", [57_133]), 0); + +// memory_copy.wast:1021 +assert_return(() => call($10, "load8_u", [57_332]), 0); + +// memory_copy.wast:1022 +assert_return(() => call($10, "load8_u", [57_531]), 0); + +// memory_copy.wast:1023 +assert_return(() => call($10, "load8_u", [57_730]), 0); + +// memory_copy.wast:1024 +assert_return(() => call($10, "load8_u", [57_929]), 0); + +// memory_copy.wast:1025 +assert_return(() => call($10, "load8_u", [58_128]), 0); + +// memory_copy.wast:1026 +assert_return(() => call($10, "load8_u", [58_327]), 0); + +// memory_copy.wast:1027 +assert_return(() => call($10, "load8_u", [58_526]), 0); + +// memory_copy.wast:1028 +assert_return(() => call($10, "load8_u", [58_725]), 0); + +// memory_copy.wast:1029 +assert_return(() => call($10, "load8_u", [58_924]), 0); + +// memory_copy.wast:1030 +assert_return(() => call($10, "load8_u", [59_123]), 0); + +// memory_copy.wast:1031 +assert_return(() => call($10, "load8_u", [59_322]), 0); + +// memory_copy.wast:1032 +assert_return(() => call($10, "load8_u", [59_521]), 0); + +// memory_copy.wast:1033 +assert_return(() => call($10, "load8_u", [59_720]), 0); + +// memory_copy.wast:1034 +assert_return(() => call($10, "load8_u", [59_919]), 0); + +// memory_copy.wast:1035 +assert_return(() => call($10, "load8_u", [60_118]), 0); + +// memory_copy.wast:1036 +assert_return(() => call($10, "load8_u", [60_317]), 0); + +// memory_copy.wast:1037 +assert_return(() => call($10, "load8_u", [60_516]), 0); + +// memory_copy.wast:1038 +assert_return(() => call($10, "load8_u", [60_715]), 0); + +// memory_copy.wast:1039 +assert_return(() => call($10, "load8_u", [60_914]), 0); + +// memory_copy.wast:1040 +assert_return(() => call($10, "load8_u", [61_113]), 0); + +// memory_copy.wast:1041 +assert_return(() => call($10, "load8_u", [61_312]), 0); + +// memory_copy.wast:1042 +assert_return(() => call($10, "load8_u", [61_511]), 0); + +// memory_copy.wast:1043 +assert_return(() => call($10, "load8_u", [61_710]), 0); + +// memory_copy.wast:1044 +assert_return(() => call($10, "load8_u", [61_909]), 0); + +// memory_copy.wast:1045 +assert_return(() => call($10, "load8_u", [62_108]), 0); + +// memory_copy.wast:1046 +assert_return(() => call($10, "load8_u", [62_307]), 0); + +// memory_copy.wast:1047 +assert_return(() => call($10, "load8_u", [62_506]), 0); + +// memory_copy.wast:1048 +assert_return(() => call($10, "load8_u", [62_705]), 0); + +// memory_copy.wast:1049 +assert_return(() => call($10, "load8_u", [62_904]), 0); + +// memory_copy.wast:1050 +assert_return(() => call($10, "load8_u", [63_103]), 0); + +// memory_copy.wast:1051 +assert_return(() => call($10, "load8_u", [63_302]), 0); + +// memory_copy.wast:1052 +assert_return(() => call($10, "load8_u", [63_501]), 0); + +// memory_copy.wast:1053 +assert_return(() => call($10, "load8_u", [63_700]), 0); + +// memory_copy.wast:1054 +assert_return(() => call($10, "load8_u", [63_899]), 0); + +// memory_copy.wast:1055 +assert_return(() => call($10, "load8_u", [64_098]), 0); + +// memory_copy.wast:1056 +assert_return(() => call($10, "load8_u", [64_297]), 0); + +// memory_copy.wast:1057 +assert_return(() => call($10, "load8_u", [64_496]), 0); + +// memory_copy.wast:1058 +assert_return(() => call($10, "load8_u", [64_695]), 0); + +// memory_copy.wast:1059 +assert_return(() => call($10, "load8_u", [64_894]), 0); + +// memory_copy.wast:1060 +assert_return(() => call($10, "load8_u", [65_093]), 0); + +// memory_copy.wast:1061 +assert_return(() => call($10, "load8_u", [65_292]), 0); + +// memory_copy.wast:1062 +assert_return(() => call($10, "load8_u", [65_491]), 0); + +// memory_copy.wast:1064 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:1072 +assert_trap(() => call($11, "run", [0, 65_516, 40])); + +// memory_copy.wast:1075 +assert_return(() => call($11, "load8_u", [198]), 0); + +// memory_copy.wast:1076 +assert_return(() => call($11, "load8_u", [397]), 0); + +// memory_copy.wast:1077 +assert_return(() => call($11, "load8_u", [596]), 0); + +// memory_copy.wast:1078 +assert_return(() => call($11, "load8_u", [795]), 0); + +// memory_copy.wast:1079 +assert_return(() => call($11, "load8_u", [994]), 0); + +// memory_copy.wast:1080 +assert_return(() => call($11, "load8_u", [1_193]), 0); + +// memory_copy.wast:1081 +assert_return(() => call($11, "load8_u", [1_392]), 0); + +// memory_copy.wast:1082 +assert_return(() => call($11, "load8_u", [1_591]), 0); + +// memory_copy.wast:1083 +assert_return(() => call($11, "load8_u", [1_790]), 0); + +// memory_copy.wast:1084 +assert_return(() => call($11, "load8_u", [1_989]), 0); + +// memory_copy.wast:1085 +assert_return(() => call($11, "load8_u", [2_188]), 0); + +// memory_copy.wast:1086 +assert_return(() => call($11, "load8_u", [2_387]), 0); + +// memory_copy.wast:1087 +assert_return(() => call($11, "load8_u", [2_586]), 0); + +// memory_copy.wast:1088 +assert_return(() => call($11, "load8_u", [2_785]), 0); + +// memory_copy.wast:1089 +assert_return(() => call($11, "load8_u", [2_984]), 0); + +// memory_copy.wast:1090 +assert_return(() => call($11, "load8_u", [3_183]), 0); + +// memory_copy.wast:1091 +assert_return(() => call($11, "load8_u", [3_382]), 0); + +// memory_copy.wast:1092 +assert_return(() => call($11, "load8_u", [3_581]), 0); + +// memory_copy.wast:1093 +assert_return(() => call($11, "load8_u", [3_780]), 0); + +// memory_copy.wast:1094 +assert_return(() => call($11, "load8_u", [3_979]), 0); + +// memory_copy.wast:1095 +assert_return(() => call($11, "load8_u", [4_178]), 0); + +// memory_copy.wast:1096 +assert_return(() => call($11, "load8_u", [4_377]), 0); + +// memory_copy.wast:1097 +assert_return(() => call($11, "load8_u", [4_576]), 0); + +// memory_copy.wast:1098 +assert_return(() => call($11, "load8_u", [4_775]), 0); + +// memory_copy.wast:1099 +assert_return(() => call($11, "load8_u", [4_974]), 0); + +// memory_copy.wast:1100 +assert_return(() => call($11, "load8_u", [5_173]), 0); + +// memory_copy.wast:1101 +assert_return(() => call($11, "load8_u", [5_372]), 0); + +// memory_copy.wast:1102 +assert_return(() => call($11, "load8_u", [5_571]), 0); + +// memory_copy.wast:1103 +assert_return(() => call($11, "load8_u", [5_770]), 0); + +// memory_copy.wast:1104 +assert_return(() => call($11, "load8_u", [5_969]), 0); + +// memory_copy.wast:1105 +assert_return(() => call($11, "load8_u", [6_168]), 0); + +// memory_copy.wast:1106 +assert_return(() => call($11, "load8_u", [6_367]), 0); + +// memory_copy.wast:1107 +assert_return(() => call($11, "load8_u", [6_566]), 0); + +// memory_copy.wast:1108 +assert_return(() => call($11, "load8_u", [6_765]), 0); + +// memory_copy.wast:1109 +assert_return(() => call($11, "load8_u", [6_964]), 0); + +// memory_copy.wast:1110 +assert_return(() => call($11, "load8_u", [7_163]), 0); + +// memory_copy.wast:1111 +assert_return(() => call($11, "load8_u", [7_362]), 0); + +// memory_copy.wast:1112 +assert_return(() => call($11, "load8_u", [7_561]), 0); + +// memory_copy.wast:1113 +assert_return(() => call($11, "load8_u", [7_760]), 0); + +// memory_copy.wast:1114 +assert_return(() => call($11, "load8_u", [7_959]), 0); + +// memory_copy.wast:1115 +assert_return(() => call($11, "load8_u", [8_158]), 0); + +// memory_copy.wast:1116 +assert_return(() => call($11, "load8_u", [8_357]), 0); + +// memory_copy.wast:1117 +assert_return(() => call($11, "load8_u", [8_556]), 0); + +// memory_copy.wast:1118 +assert_return(() => call($11, "load8_u", [8_755]), 0); + +// memory_copy.wast:1119 +assert_return(() => call($11, "load8_u", [8_954]), 0); + +// memory_copy.wast:1120 +assert_return(() => call($11, "load8_u", [9_153]), 0); + +// memory_copy.wast:1121 +assert_return(() => call($11, "load8_u", [9_352]), 0); + +// memory_copy.wast:1122 +assert_return(() => call($11, "load8_u", [9_551]), 0); + +// memory_copy.wast:1123 +assert_return(() => call($11, "load8_u", [9_750]), 0); + +// memory_copy.wast:1124 +assert_return(() => call($11, "load8_u", [9_949]), 0); + +// memory_copy.wast:1125 +assert_return(() => call($11, "load8_u", [10_148]), 0); + +// memory_copy.wast:1126 +assert_return(() => call($11, "load8_u", [10_347]), 0); + +// memory_copy.wast:1127 +assert_return(() => call($11, "load8_u", [10_546]), 0); + +// memory_copy.wast:1128 +assert_return(() => call($11, "load8_u", [10_745]), 0); + +// memory_copy.wast:1129 +assert_return(() => call($11, "load8_u", [10_944]), 0); + +// memory_copy.wast:1130 +assert_return(() => call($11, "load8_u", [11_143]), 0); + +// memory_copy.wast:1131 +assert_return(() => call($11, "load8_u", [11_342]), 0); + +// memory_copy.wast:1132 +assert_return(() => call($11, "load8_u", [11_541]), 0); + +// memory_copy.wast:1133 +assert_return(() => call($11, "load8_u", [11_740]), 0); + +// memory_copy.wast:1134 +assert_return(() => call($11, "load8_u", [11_939]), 0); + +// memory_copy.wast:1135 +assert_return(() => call($11, "load8_u", [12_138]), 0); + +// memory_copy.wast:1136 +assert_return(() => call($11, "load8_u", [12_337]), 0); + +// memory_copy.wast:1137 +assert_return(() => call($11, "load8_u", [12_536]), 0); + +// memory_copy.wast:1138 +assert_return(() => call($11, "load8_u", [12_735]), 0); + +// memory_copy.wast:1139 +assert_return(() => call($11, "load8_u", [12_934]), 0); + +// memory_copy.wast:1140 +assert_return(() => call($11, "load8_u", [13_133]), 0); + +// memory_copy.wast:1141 +assert_return(() => call($11, "load8_u", [13_332]), 0); + +// memory_copy.wast:1142 +assert_return(() => call($11, "load8_u", [13_531]), 0); + +// memory_copy.wast:1143 +assert_return(() => call($11, "load8_u", [13_730]), 0); + +// memory_copy.wast:1144 +assert_return(() => call($11, "load8_u", [13_929]), 0); + +// memory_copy.wast:1145 +assert_return(() => call($11, "load8_u", [14_128]), 0); + +// memory_copy.wast:1146 +assert_return(() => call($11, "load8_u", [14_327]), 0); + +// memory_copy.wast:1147 +assert_return(() => call($11, "load8_u", [14_526]), 0); + +// memory_copy.wast:1148 +assert_return(() => call($11, "load8_u", [14_725]), 0); + +// memory_copy.wast:1149 +assert_return(() => call($11, "load8_u", [14_924]), 0); + +// memory_copy.wast:1150 +assert_return(() => call($11, "load8_u", [15_123]), 0); + +// memory_copy.wast:1151 +assert_return(() => call($11, "load8_u", [15_322]), 0); + +// memory_copy.wast:1152 +assert_return(() => call($11, "load8_u", [15_521]), 0); + +// memory_copy.wast:1153 +assert_return(() => call($11, "load8_u", [15_720]), 0); + +// memory_copy.wast:1154 +assert_return(() => call($11, "load8_u", [15_919]), 0); + +// memory_copy.wast:1155 +assert_return(() => call($11, "load8_u", [16_118]), 0); + +// memory_copy.wast:1156 +assert_return(() => call($11, "load8_u", [16_317]), 0); + +// memory_copy.wast:1157 +assert_return(() => call($11, "load8_u", [16_516]), 0); + +// memory_copy.wast:1158 +assert_return(() => call($11, "load8_u", [16_715]), 0); + +// memory_copy.wast:1159 +assert_return(() => call($11, "load8_u", [16_914]), 0); + +// memory_copy.wast:1160 +assert_return(() => call($11, "load8_u", [17_113]), 0); + +// memory_copy.wast:1161 +assert_return(() => call($11, "load8_u", [17_312]), 0); + +// memory_copy.wast:1162 +assert_return(() => call($11, "load8_u", [17_511]), 0); + +// memory_copy.wast:1163 +assert_return(() => call($11, "load8_u", [17_710]), 0); + +// memory_copy.wast:1164 +assert_return(() => call($11, "load8_u", [17_909]), 0); + +// memory_copy.wast:1165 +assert_return(() => call($11, "load8_u", [18_108]), 0); + +// memory_copy.wast:1166 +assert_return(() => call($11, "load8_u", [18_307]), 0); + +// memory_copy.wast:1167 +assert_return(() => call($11, "load8_u", [18_506]), 0); + +// memory_copy.wast:1168 +assert_return(() => call($11, "load8_u", [18_705]), 0); + +// memory_copy.wast:1169 +assert_return(() => call($11, "load8_u", [18_904]), 0); + +// memory_copy.wast:1170 +assert_return(() => call($11, "load8_u", [19_103]), 0); + +// memory_copy.wast:1171 +assert_return(() => call($11, "load8_u", [19_302]), 0); + +// memory_copy.wast:1172 +assert_return(() => call($11, "load8_u", [19_501]), 0); + +// memory_copy.wast:1173 +assert_return(() => call($11, "load8_u", [19_700]), 0); + +// memory_copy.wast:1174 +assert_return(() => call($11, "load8_u", [19_899]), 0); + +// memory_copy.wast:1175 +assert_return(() => call($11, "load8_u", [20_098]), 0); + +// memory_copy.wast:1176 +assert_return(() => call($11, "load8_u", [20_297]), 0); + +// memory_copy.wast:1177 +assert_return(() => call($11, "load8_u", [20_496]), 0); + +// memory_copy.wast:1178 +assert_return(() => call($11, "load8_u", [20_695]), 0); + +// memory_copy.wast:1179 +assert_return(() => call($11, "load8_u", [20_894]), 0); + +// memory_copy.wast:1180 +assert_return(() => call($11, "load8_u", [21_093]), 0); + +// memory_copy.wast:1181 +assert_return(() => call($11, "load8_u", [21_292]), 0); + +// memory_copy.wast:1182 +assert_return(() => call($11, "load8_u", [21_491]), 0); + +// memory_copy.wast:1183 +assert_return(() => call($11, "load8_u", [21_690]), 0); + +// memory_copy.wast:1184 +assert_return(() => call($11, "load8_u", [21_889]), 0); + +// memory_copy.wast:1185 +assert_return(() => call($11, "load8_u", [22_088]), 0); + +// memory_copy.wast:1186 +assert_return(() => call($11, "load8_u", [22_287]), 0); + +// memory_copy.wast:1187 +assert_return(() => call($11, "load8_u", [22_486]), 0); + +// memory_copy.wast:1188 +assert_return(() => call($11, "load8_u", [22_685]), 0); + +// memory_copy.wast:1189 +assert_return(() => call($11, "load8_u", [22_884]), 0); + +// memory_copy.wast:1190 +assert_return(() => call($11, "load8_u", [23_083]), 0); + +// memory_copy.wast:1191 +assert_return(() => call($11, "load8_u", [23_282]), 0); + +// memory_copy.wast:1192 +assert_return(() => call($11, "load8_u", [23_481]), 0); + +// memory_copy.wast:1193 +assert_return(() => call($11, "load8_u", [23_680]), 0); + +// memory_copy.wast:1194 +assert_return(() => call($11, "load8_u", [23_879]), 0); + +// memory_copy.wast:1195 +assert_return(() => call($11, "load8_u", [24_078]), 0); + +// memory_copy.wast:1196 +assert_return(() => call($11, "load8_u", [24_277]), 0); + +// memory_copy.wast:1197 +assert_return(() => call($11, "load8_u", [24_476]), 0); + +// memory_copy.wast:1198 +assert_return(() => call($11, "load8_u", [24_675]), 0); + +// memory_copy.wast:1199 +assert_return(() => call($11, "load8_u", [24_874]), 0); + +// memory_copy.wast:1200 +assert_return(() => call($11, "load8_u", [25_073]), 0); + +// memory_copy.wast:1201 +assert_return(() => call($11, "load8_u", [25_272]), 0); + +// memory_copy.wast:1202 +assert_return(() => call($11, "load8_u", [25_471]), 0); + +// memory_copy.wast:1203 +assert_return(() => call($11, "load8_u", [25_670]), 0); + +// memory_copy.wast:1204 +assert_return(() => call($11, "load8_u", [25_869]), 0); + +// memory_copy.wast:1205 +assert_return(() => call($11, "load8_u", [26_068]), 0); + +// memory_copy.wast:1206 +assert_return(() => call($11, "load8_u", [26_267]), 0); + +// memory_copy.wast:1207 +assert_return(() => call($11, "load8_u", [26_466]), 0); + +// memory_copy.wast:1208 +assert_return(() => call($11, "load8_u", [26_665]), 0); + +// memory_copy.wast:1209 +assert_return(() => call($11, "load8_u", [26_864]), 0); + +// memory_copy.wast:1210 +assert_return(() => call($11, "load8_u", [27_063]), 0); + +// memory_copy.wast:1211 +assert_return(() => call($11, "load8_u", [27_262]), 0); + +// memory_copy.wast:1212 +assert_return(() => call($11, "load8_u", [27_461]), 0); + +// memory_copy.wast:1213 +assert_return(() => call($11, "load8_u", [27_660]), 0); + +// memory_copy.wast:1214 +assert_return(() => call($11, "load8_u", [27_859]), 0); + +// memory_copy.wast:1215 +assert_return(() => call($11, "load8_u", [28_058]), 0); + +// memory_copy.wast:1216 +assert_return(() => call($11, "load8_u", [28_257]), 0); + +// memory_copy.wast:1217 +assert_return(() => call($11, "load8_u", [28_456]), 0); + +// memory_copy.wast:1218 +assert_return(() => call($11, "load8_u", [28_655]), 0); + +// memory_copy.wast:1219 +assert_return(() => call($11, "load8_u", [28_854]), 0); + +// memory_copy.wast:1220 +assert_return(() => call($11, "load8_u", [29_053]), 0); + +// memory_copy.wast:1221 +assert_return(() => call($11, "load8_u", [29_252]), 0); + +// memory_copy.wast:1222 +assert_return(() => call($11, "load8_u", [29_451]), 0); + +// memory_copy.wast:1223 +assert_return(() => call($11, "load8_u", [29_650]), 0); + +// memory_copy.wast:1224 +assert_return(() => call($11, "load8_u", [29_849]), 0); + +// memory_copy.wast:1225 +assert_return(() => call($11, "load8_u", [30_048]), 0); + +// memory_copy.wast:1226 +assert_return(() => call($11, "load8_u", [30_247]), 0); + +// memory_copy.wast:1227 +assert_return(() => call($11, "load8_u", [30_446]), 0); + +// memory_copy.wast:1228 +assert_return(() => call($11, "load8_u", [30_645]), 0); + +// memory_copy.wast:1229 +assert_return(() => call($11, "load8_u", [30_844]), 0); + +// memory_copy.wast:1230 +assert_return(() => call($11, "load8_u", [31_043]), 0); + +// memory_copy.wast:1231 +assert_return(() => call($11, "load8_u", [31_242]), 0); + +// memory_copy.wast:1232 +assert_return(() => call($11, "load8_u", [31_441]), 0); + +// memory_copy.wast:1233 +assert_return(() => call($11, "load8_u", [31_640]), 0); + +// memory_copy.wast:1234 +assert_return(() => call($11, "load8_u", [31_839]), 0); + +// memory_copy.wast:1235 +assert_return(() => call($11, "load8_u", [32_038]), 0); + +// memory_copy.wast:1236 +assert_return(() => call($11, "load8_u", [32_237]), 0); + +// memory_copy.wast:1237 +assert_return(() => call($11, "load8_u", [32_436]), 0); + +// memory_copy.wast:1238 +assert_return(() => call($11, "load8_u", [32_635]), 0); + +// memory_copy.wast:1239 +assert_return(() => call($11, "load8_u", [32_834]), 0); + +// memory_copy.wast:1240 +assert_return(() => call($11, "load8_u", [33_033]), 0); + +// memory_copy.wast:1241 +assert_return(() => call($11, "load8_u", [33_232]), 0); + +// memory_copy.wast:1242 +assert_return(() => call($11, "load8_u", [33_431]), 0); + +// memory_copy.wast:1243 +assert_return(() => call($11, "load8_u", [33_630]), 0); + +// memory_copy.wast:1244 +assert_return(() => call($11, "load8_u", [33_829]), 0); + +// memory_copy.wast:1245 +assert_return(() => call($11, "load8_u", [34_028]), 0); + +// memory_copy.wast:1246 +assert_return(() => call($11, "load8_u", [34_227]), 0); + +// memory_copy.wast:1247 +assert_return(() => call($11, "load8_u", [34_426]), 0); + +// memory_copy.wast:1248 +assert_return(() => call($11, "load8_u", [34_625]), 0); + +// memory_copy.wast:1249 +assert_return(() => call($11, "load8_u", [34_824]), 0); + +// memory_copy.wast:1250 +assert_return(() => call($11, "load8_u", [35_023]), 0); + +// memory_copy.wast:1251 +assert_return(() => call($11, "load8_u", [35_222]), 0); + +// memory_copy.wast:1252 +assert_return(() => call($11, "load8_u", [35_421]), 0); + +// memory_copy.wast:1253 +assert_return(() => call($11, "load8_u", [35_620]), 0); + +// memory_copy.wast:1254 +assert_return(() => call($11, "load8_u", [35_819]), 0); + +// memory_copy.wast:1255 +assert_return(() => call($11, "load8_u", [36_018]), 0); + +// memory_copy.wast:1256 +assert_return(() => call($11, "load8_u", [36_217]), 0); + +// memory_copy.wast:1257 +assert_return(() => call($11, "load8_u", [36_416]), 0); + +// memory_copy.wast:1258 +assert_return(() => call($11, "load8_u", [36_615]), 0); + +// memory_copy.wast:1259 +assert_return(() => call($11, "load8_u", [36_814]), 0); + +// memory_copy.wast:1260 +assert_return(() => call($11, "load8_u", [37_013]), 0); + +// memory_copy.wast:1261 +assert_return(() => call($11, "load8_u", [37_212]), 0); + +// memory_copy.wast:1262 +assert_return(() => call($11, "load8_u", [37_411]), 0); + +// memory_copy.wast:1263 +assert_return(() => call($11, "load8_u", [37_610]), 0); + +// memory_copy.wast:1264 +assert_return(() => call($11, "load8_u", [37_809]), 0); + +// memory_copy.wast:1265 +assert_return(() => call($11, "load8_u", [38_008]), 0); + +// memory_copy.wast:1266 +assert_return(() => call($11, "load8_u", [38_207]), 0); + +// memory_copy.wast:1267 +assert_return(() => call($11, "load8_u", [38_406]), 0); + +// memory_copy.wast:1268 +assert_return(() => call($11, "load8_u", [38_605]), 0); + +// memory_copy.wast:1269 +assert_return(() => call($11, "load8_u", [38_804]), 0); + +// memory_copy.wast:1270 +assert_return(() => call($11, "load8_u", [39_003]), 0); + +// memory_copy.wast:1271 +assert_return(() => call($11, "load8_u", [39_202]), 0); + +// memory_copy.wast:1272 +assert_return(() => call($11, "load8_u", [39_401]), 0); + +// memory_copy.wast:1273 +assert_return(() => call($11, "load8_u", [39_600]), 0); + +// memory_copy.wast:1274 +assert_return(() => call($11, "load8_u", [39_799]), 0); + +// memory_copy.wast:1275 +assert_return(() => call($11, "load8_u", [39_998]), 0); + +// memory_copy.wast:1276 +assert_return(() => call($11, "load8_u", [40_197]), 0); + +// memory_copy.wast:1277 +assert_return(() => call($11, "load8_u", [40_396]), 0); + +// memory_copy.wast:1278 +assert_return(() => call($11, "load8_u", [40_595]), 0); + +// memory_copy.wast:1279 +assert_return(() => call($11, "load8_u", [40_794]), 0); + +// memory_copy.wast:1280 +assert_return(() => call($11, "load8_u", [40_993]), 0); + +// memory_copy.wast:1281 +assert_return(() => call($11, "load8_u", [41_192]), 0); + +// memory_copy.wast:1282 +assert_return(() => call($11, "load8_u", [41_391]), 0); + +// memory_copy.wast:1283 +assert_return(() => call($11, "load8_u", [41_590]), 0); + +// memory_copy.wast:1284 +assert_return(() => call($11, "load8_u", [41_789]), 0); + +// memory_copy.wast:1285 +assert_return(() => call($11, "load8_u", [41_988]), 0); + +// memory_copy.wast:1286 +assert_return(() => call($11, "load8_u", [42_187]), 0); + +// memory_copy.wast:1287 +assert_return(() => call($11, "load8_u", [42_386]), 0); + +// memory_copy.wast:1288 +assert_return(() => call($11, "load8_u", [42_585]), 0); + +// memory_copy.wast:1289 +assert_return(() => call($11, "load8_u", [42_784]), 0); + +// memory_copy.wast:1290 +assert_return(() => call($11, "load8_u", [42_983]), 0); + +// memory_copy.wast:1291 +assert_return(() => call($11, "load8_u", [43_182]), 0); + +// memory_copy.wast:1292 +assert_return(() => call($11, "load8_u", [43_381]), 0); + +// memory_copy.wast:1293 +assert_return(() => call($11, "load8_u", [43_580]), 0); + +// memory_copy.wast:1294 +assert_return(() => call($11, "load8_u", [43_779]), 0); + +// memory_copy.wast:1295 +assert_return(() => call($11, "load8_u", [43_978]), 0); + +// memory_copy.wast:1296 +assert_return(() => call($11, "load8_u", [44_177]), 0); + +// memory_copy.wast:1297 +assert_return(() => call($11, "load8_u", [44_376]), 0); + +// memory_copy.wast:1298 +assert_return(() => call($11, "load8_u", [44_575]), 0); + +// memory_copy.wast:1299 +assert_return(() => call($11, "load8_u", [44_774]), 0); + +// memory_copy.wast:1300 +assert_return(() => call($11, "load8_u", [44_973]), 0); + +// memory_copy.wast:1301 +assert_return(() => call($11, "load8_u", [45_172]), 0); + +// memory_copy.wast:1302 +assert_return(() => call($11, "load8_u", [45_371]), 0); + +// memory_copy.wast:1303 +assert_return(() => call($11, "load8_u", [45_570]), 0); + +// memory_copy.wast:1304 +assert_return(() => call($11, "load8_u", [45_769]), 0); + +// memory_copy.wast:1305 +assert_return(() => call($11, "load8_u", [45_968]), 0); + +// memory_copy.wast:1306 +assert_return(() => call($11, "load8_u", [46_167]), 0); + +// memory_copy.wast:1307 +assert_return(() => call($11, "load8_u", [46_366]), 0); + +// memory_copy.wast:1308 +assert_return(() => call($11, "load8_u", [46_565]), 0); + +// memory_copy.wast:1309 +assert_return(() => call($11, "load8_u", [46_764]), 0); + +// memory_copy.wast:1310 +assert_return(() => call($11, "load8_u", [46_963]), 0); + +// memory_copy.wast:1311 +assert_return(() => call($11, "load8_u", [47_162]), 0); + +// memory_copy.wast:1312 +assert_return(() => call($11, "load8_u", [47_361]), 0); + +// memory_copy.wast:1313 +assert_return(() => call($11, "load8_u", [47_560]), 0); + +// memory_copy.wast:1314 +assert_return(() => call($11, "load8_u", [47_759]), 0); + +// memory_copy.wast:1315 +assert_return(() => call($11, "load8_u", [47_958]), 0); + +// memory_copy.wast:1316 +assert_return(() => call($11, "load8_u", [48_157]), 0); + +// memory_copy.wast:1317 +assert_return(() => call($11, "load8_u", [48_356]), 0); + +// memory_copy.wast:1318 +assert_return(() => call($11, "load8_u", [48_555]), 0); + +// memory_copy.wast:1319 +assert_return(() => call($11, "load8_u", [48_754]), 0); + +// memory_copy.wast:1320 +assert_return(() => call($11, "load8_u", [48_953]), 0); + +// memory_copy.wast:1321 +assert_return(() => call($11, "load8_u", [49_152]), 0); + +// memory_copy.wast:1322 +assert_return(() => call($11, "load8_u", [49_351]), 0); + +// memory_copy.wast:1323 +assert_return(() => call($11, "load8_u", [49_550]), 0); + +// memory_copy.wast:1324 +assert_return(() => call($11, "load8_u", [49_749]), 0); + +// memory_copy.wast:1325 +assert_return(() => call($11, "load8_u", [49_948]), 0); + +// memory_copy.wast:1326 +assert_return(() => call($11, "load8_u", [50_147]), 0); + +// memory_copy.wast:1327 +assert_return(() => call($11, "load8_u", [50_346]), 0); + +// memory_copy.wast:1328 +assert_return(() => call($11, "load8_u", [50_545]), 0); + +// memory_copy.wast:1329 +assert_return(() => call($11, "load8_u", [50_744]), 0); + +// memory_copy.wast:1330 +assert_return(() => call($11, "load8_u", [50_943]), 0); + +// memory_copy.wast:1331 +assert_return(() => call($11, "load8_u", [51_142]), 0); + +// memory_copy.wast:1332 +assert_return(() => call($11, "load8_u", [51_341]), 0); + +// memory_copy.wast:1333 +assert_return(() => call($11, "load8_u", [51_540]), 0); + +// memory_copy.wast:1334 +assert_return(() => call($11, "load8_u", [51_739]), 0); + +// memory_copy.wast:1335 +assert_return(() => call($11, "load8_u", [51_938]), 0); + +// memory_copy.wast:1336 +assert_return(() => call($11, "load8_u", [52_137]), 0); + +// memory_copy.wast:1337 +assert_return(() => call($11, "load8_u", [52_336]), 0); + +// memory_copy.wast:1338 +assert_return(() => call($11, "load8_u", [52_535]), 0); + +// memory_copy.wast:1339 +assert_return(() => call($11, "load8_u", [52_734]), 0); + +// memory_copy.wast:1340 +assert_return(() => call($11, "load8_u", [52_933]), 0); + +// memory_copy.wast:1341 +assert_return(() => call($11, "load8_u", [53_132]), 0); + +// memory_copy.wast:1342 +assert_return(() => call($11, "load8_u", [53_331]), 0); + +// memory_copy.wast:1343 +assert_return(() => call($11, "load8_u", [53_530]), 0); + +// memory_copy.wast:1344 +assert_return(() => call($11, "load8_u", [53_729]), 0); + +// memory_copy.wast:1345 +assert_return(() => call($11, "load8_u", [53_928]), 0); + +// memory_copy.wast:1346 +assert_return(() => call($11, "load8_u", [54_127]), 0); + +// memory_copy.wast:1347 +assert_return(() => call($11, "load8_u", [54_326]), 0); + +// memory_copy.wast:1348 +assert_return(() => call($11, "load8_u", [54_525]), 0); + +// memory_copy.wast:1349 +assert_return(() => call($11, "load8_u", [54_724]), 0); + +// memory_copy.wast:1350 +assert_return(() => call($11, "load8_u", [54_923]), 0); + +// memory_copy.wast:1351 +assert_return(() => call($11, "load8_u", [55_122]), 0); + +// memory_copy.wast:1352 +assert_return(() => call($11, "load8_u", [55_321]), 0); + +// memory_copy.wast:1353 +assert_return(() => call($11, "load8_u", [55_520]), 0); + +// memory_copy.wast:1354 +assert_return(() => call($11, "load8_u", [55_719]), 0); + +// memory_copy.wast:1355 +assert_return(() => call($11, "load8_u", [55_918]), 0); + +// memory_copy.wast:1356 +assert_return(() => call($11, "load8_u", [56_117]), 0); + +// memory_copy.wast:1357 +assert_return(() => call($11, "load8_u", [56_316]), 0); + +// memory_copy.wast:1358 +assert_return(() => call($11, "load8_u", [56_515]), 0); + +// memory_copy.wast:1359 +assert_return(() => call($11, "load8_u", [56_714]), 0); + +// memory_copy.wast:1360 +assert_return(() => call($11, "load8_u", [56_913]), 0); + +// memory_copy.wast:1361 +assert_return(() => call($11, "load8_u", [57_112]), 0); + +// memory_copy.wast:1362 +assert_return(() => call($11, "load8_u", [57_311]), 0); + +// memory_copy.wast:1363 +assert_return(() => call($11, "load8_u", [57_510]), 0); + +// memory_copy.wast:1364 +assert_return(() => call($11, "load8_u", [57_709]), 0); + +// memory_copy.wast:1365 +assert_return(() => call($11, "load8_u", [57_908]), 0); + +// memory_copy.wast:1366 +assert_return(() => call($11, "load8_u", [58_107]), 0); + +// memory_copy.wast:1367 +assert_return(() => call($11, "load8_u", [58_306]), 0); + +// memory_copy.wast:1368 +assert_return(() => call($11, "load8_u", [58_505]), 0); + +// memory_copy.wast:1369 +assert_return(() => call($11, "load8_u", [58_704]), 0); + +// memory_copy.wast:1370 +assert_return(() => call($11, "load8_u", [58_903]), 0); + +// memory_copy.wast:1371 +assert_return(() => call($11, "load8_u", [59_102]), 0); + +// memory_copy.wast:1372 +assert_return(() => call($11, "load8_u", [59_301]), 0); + +// memory_copy.wast:1373 +assert_return(() => call($11, "load8_u", [59_500]), 0); + +// memory_copy.wast:1374 +assert_return(() => call($11, "load8_u", [59_699]), 0); + +// memory_copy.wast:1375 +assert_return(() => call($11, "load8_u", [59_898]), 0); + +// memory_copy.wast:1376 +assert_return(() => call($11, "load8_u", [60_097]), 0); + +// memory_copy.wast:1377 +assert_return(() => call($11, "load8_u", [60_296]), 0); + +// memory_copy.wast:1378 +assert_return(() => call($11, "load8_u", [60_495]), 0); + +// memory_copy.wast:1379 +assert_return(() => call($11, "load8_u", [60_694]), 0); + +// memory_copy.wast:1380 +assert_return(() => call($11, "load8_u", [60_893]), 0); + +// memory_copy.wast:1381 +assert_return(() => call($11, "load8_u", [61_092]), 0); + +// memory_copy.wast:1382 +assert_return(() => call($11, "load8_u", [61_291]), 0); + +// memory_copy.wast:1383 +assert_return(() => call($11, "load8_u", [61_490]), 0); + +// memory_copy.wast:1384 +assert_return(() => call($11, "load8_u", [61_689]), 0); + +// memory_copy.wast:1385 +assert_return(() => call($11, "load8_u", [61_888]), 0); + +// memory_copy.wast:1386 +assert_return(() => call($11, "load8_u", [62_087]), 0); + +// memory_copy.wast:1387 +assert_return(() => call($11, "load8_u", [62_286]), 0); + +// memory_copy.wast:1388 +assert_return(() => call($11, "load8_u", [62_485]), 0); + +// memory_copy.wast:1389 +assert_return(() => call($11, "load8_u", [62_684]), 0); + +// memory_copy.wast:1390 +assert_return(() => call($11, "load8_u", [62_883]), 0); + +// memory_copy.wast:1391 +assert_return(() => call($11, "load8_u", [63_082]), 0); + +// memory_copy.wast:1392 +assert_return(() => call($11, "load8_u", [63_281]), 0); + +// memory_copy.wast:1393 +assert_return(() => call($11, "load8_u", [63_480]), 0); + +// memory_copy.wast:1394 +assert_return(() => call($11, "load8_u", [63_679]), 0); + +// memory_copy.wast:1395 +assert_return(() => call($11, "load8_u", [63_878]), 0); + +// memory_copy.wast:1396 +assert_return(() => call($11, "load8_u", [64_077]), 0); + +// memory_copy.wast:1397 +assert_return(() => call($11, "load8_u", [64_276]), 0); + +// memory_copy.wast:1398 +assert_return(() => call($11, "load8_u", [64_475]), 0); + +// memory_copy.wast:1399 +assert_return(() => call($11, "load8_u", [64_674]), 0); + +// memory_copy.wast:1400 +assert_return(() => call($11, "load8_u", [64_873]), 0); + +// memory_copy.wast:1401 +assert_return(() => call($11, "load8_u", [65_072]), 0); + +// memory_copy.wast:1402 +assert_return(() => call($11, "load8_u", [65_271]), 0); + +// memory_copy.wast:1403 +assert_return(() => call($11, "load8_u", [65_470]), 0); + +// memory_copy.wast:1404 +assert_return(() => call($11, "load8_u", [65_516]), 0); + +// memory_copy.wast:1405 +assert_return(() => call($11, "load8_u", [65_517]), 1); + +// memory_copy.wast:1406 +assert_return(() => call($11, "load8_u", [65_518]), 2); + +// memory_copy.wast:1407 +assert_return(() => call($11, "load8_u", [65_519]), 3); + +// memory_copy.wast:1408 +assert_return(() => call($11, "load8_u", [65_520]), 4); + +// memory_copy.wast:1409 +assert_return(() => call($11, "load8_u", [65_521]), 5); + +// memory_copy.wast:1410 +assert_return(() => call($11, "load8_u", [65_522]), 6); + +// memory_copy.wast:1411 +assert_return(() => call($11, "load8_u", [65_523]), 7); + +// memory_copy.wast:1412 +assert_return(() => call($11, "load8_u", [65_524]), 8); + +// memory_copy.wast:1413 +assert_return(() => call($11, "load8_u", [65_525]), 9); + +// memory_copy.wast:1414 +assert_return(() => call($11, "load8_u", [65_526]), 10); + +// memory_copy.wast:1415 +assert_return(() => call($11, "load8_u", [65_527]), 11); + +// memory_copy.wast:1416 +assert_return(() => call($11, "load8_u", [65_528]), 12); + +// memory_copy.wast:1417 +assert_return(() => call($11, "load8_u", [65_529]), 13); + +// memory_copy.wast:1418 +assert_return(() => call($11, "load8_u", [65_530]), 14); + +// memory_copy.wast:1419 +assert_return(() => call($11, "load8_u", [65_531]), 15); + +// memory_copy.wast:1420 +assert_return(() => call($11, "load8_u", [65_532]), 16); + +// memory_copy.wast:1421 +assert_return(() => call($11, "load8_u", [65_533]), 17); + +// memory_copy.wast:1422 +assert_return(() => call($11, "load8_u", [65_534]), 18); + +// memory_copy.wast:1423 +assert_return(() => call($11, "load8_u", [65_535]), 19); + +// memory_copy.wast:1425 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9d\x80\x80\x80\x00\x01\x00\x41\xeb\xff\x03\x0b\x15\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"); + +// memory_copy.wast:1433 +assert_trap(() => call($12, "run", [0, 65_515, 39])); + +// memory_copy.wast:1436 +assert_return(() => call($12, "load8_u", [198]), 0); + +// memory_copy.wast:1437 +assert_return(() => call($12, "load8_u", [397]), 0); + +// memory_copy.wast:1438 +assert_return(() => call($12, "load8_u", [596]), 0); + +// memory_copy.wast:1439 +assert_return(() => call($12, "load8_u", [795]), 0); + +// memory_copy.wast:1440 +assert_return(() => call($12, "load8_u", [994]), 0); + +// memory_copy.wast:1441 +assert_return(() => call($12, "load8_u", [1_193]), 0); + +// memory_copy.wast:1442 +assert_return(() => call($12, "load8_u", [1_392]), 0); + +// memory_copy.wast:1443 +assert_return(() => call($12, "load8_u", [1_591]), 0); + +// memory_copy.wast:1444 +assert_return(() => call($12, "load8_u", [1_790]), 0); + +// memory_copy.wast:1445 +assert_return(() => call($12, "load8_u", [1_989]), 0); + +// memory_copy.wast:1446 +assert_return(() => call($12, "load8_u", [2_188]), 0); + +// memory_copy.wast:1447 +assert_return(() => call($12, "load8_u", [2_387]), 0); + +// memory_copy.wast:1448 +assert_return(() => call($12, "load8_u", [2_586]), 0); + +// memory_copy.wast:1449 +assert_return(() => call($12, "load8_u", [2_785]), 0); + +// memory_copy.wast:1450 +assert_return(() => call($12, "load8_u", [2_984]), 0); + +// memory_copy.wast:1451 +assert_return(() => call($12, "load8_u", [3_183]), 0); + +// memory_copy.wast:1452 +assert_return(() => call($12, "load8_u", [3_382]), 0); + +// memory_copy.wast:1453 +assert_return(() => call($12, "load8_u", [3_581]), 0); + +// memory_copy.wast:1454 +assert_return(() => call($12, "load8_u", [3_780]), 0); + +// memory_copy.wast:1455 +assert_return(() => call($12, "load8_u", [3_979]), 0); + +// memory_copy.wast:1456 +assert_return(() => call($12, "load8_u", [4_178]), 0); + +// memory_copy.wast:1457 +assert_return(() => call($12, "load8_u", [4_377]), 0); + +// memory_copy.wast:1458 +assert_return(() => call($12, "load8_u", [4_576]), 0); + +// memory_copy.wast:1459 +assert_return(() => call($12, "load8_u", [4_775]), 0); + +// memory_copy.wast:1460 +assert_return(() => call($12, "load8_u", [4_974]), 0); + +// memory_copy.wast:1461 +assert_return(() => call($12, "load8_u", [5_173]), 0); + +// memory_copy.wast:1462 +assert_return(() => call($12, "load8_u", [5_372]), 0); + +// memory_copy.wast:1463 +assert_return(() => call($12, "load8_u", [5_571]), 0); + +// memory_copy.wast:1464 +assert_return(() => call($12, "load8_u", [5_770]), 0); + +// memory_copy.wast:1465 +assert_return(() => call($12, "load8_u", [5_969]), 0); + +// memory_copy.wast:1466 +assert_return(() => call($12, "load8_u", [6_168]), 0); + +// memory_copy.wast:1467 +assert_return(() => call($12, "load8_u", [6_367]), 0); + +// memory_copy.wast:1468 +assert_return(() => call($12, "load8_u", [6_566]), 0); + +// memory_copy.wast:1469 +assert_return(() => call($12, "load8_u", [6_765]), 0); + +// memory_copy.wast:1470 +assert_return(() => call($12, "load8_u", [6_964]), 0); + +// memory_copy.wast:1471 +assert_return(() => call($12, "load8_u", [7_163]), 0); + +// memory_copy.wast:1472 +assert_return(() => call($12, "load8_u", [7_362]), 0); + +// memory_copy.wast:1473 +assert_return(() => call($12, "load8_u", [7_561]), 0); + +// memory_copy.wast:1474 +assert_return(() => call($12, "load8_u", [7_760]), 0); + +// memory_copy.wast:1475 +assert_return(() => call($12, "load8_u", [7_959]), 0); + +// memory_copy.wast:1476 +assert_return(() => call($12, "load8_u", [8_158]), 0); + +// memory_copy.wast:1477 +assert_return(() => call($12, "load8_u", [8_357]), 0); + +// memory_copy.wast:1478 +assert_return(() => call($12, "load8_u", [8_556]), 0); + +// memory_copy.wast:1479 +assert_return(() => call($12, "load8_u", [8_755]), 0); + +// memory_copy.wast:1480 +assert_return(() => call($12, "load8_u", [8_954]), 0); + +// memory_copy.wast:1481 +assert_return(() => call($12, "load8_u", [9_153]), 0); + +// memory_copy.wast:1482 +assert_return(() => call($12, "load8_u", [9_352]), 0); + +// memory_copy.wast:1483 +assert_return(() => call($12, "load8_u", [9_551]), 0); + +// memory_copy.wast:1484 +assert_return(() => call($12, "load8_u", [9_750]), 0); + +// memory_copy.wast:1485 +assert_return(() => call($12, "load8_u", [9_949]), 0); + +// memory_copy.wast:1486 +assert_return(() => call($12, "load8_u", [10_148]), 0); + +// memory_copy.wast:1487 +assert_return(() => call($12, "load8_u", [10_347]), 0); + +// memory_copy.wast:1488 +assert_return(() => call($12, "load8_u", [10_546]), 0); + +// memory_copy.wast:1489 +assert_return(() => call($12, "load8_u", [10_745]), 0); + +// memory_copy.wast:1490 +assert_return(() => call($12, "load8_u", [10_944]), 0); + +// memory_copy.wast:1491 +assert_return(() => call($12, "load8_u", [11_143]), 0); + +// memory_copy.wast:1492 +assert_return(() => call($12, "load8_u", [11_342]), 0); + +// memory_copy.wast:1493 +assert_return(() => call($12, "load8_u", [11_541]), 0); + +// memory_copy.wast:1494 +assert_return(() => call($12, "load8_u", [11_740]), 0); + +// memory_copy.wast:1495 +assert_return(() => call($12, "load8_u", [11_939]), 0); + +// memory_copy.wast:1496 +assert_return(() => call($12, "load8_u", [12_138]), 0); + +// memory_copy.wast:1497 +assert_return(() => call($12, "load8_u", [12_337]), 0); + +// memory_copy.wast:1498 +assert_return(() => call($12, "load8_u", [12_536]), 0); + +// memory_copy.wast:1499 +assert_return(() => call($12, "load8_u", [12_735]), 0); + +// memory_copy.wast:1500 +assert_return(() => call($12, "load8_u", [12_934]), 0); + +// memory_copy.wast:1501 +assert_return(() => call($12, "load8_u", [13_133]), 0); + +// memory_copy.wast:1502 +assert_return(() => call($12, "load8_u", [13_332]), 0); + +// memory_copy.wast:1503 +assert_return(() => call($12, "load8_u", [13_531]), 0); + +// memory_copy.wast:1504 +assert_return(() => call($12, "load8_u", [13_730]), 0); + +// memory_copy.wast:1505 +assert_return(() => call($12, "load8_u", [13_929]), 0); + +// memory_copy.wast:1506 +assert_return(() => call($12, "load8_u", [14_128]), 0); + +// memory_copy.wast:1507 +assert_return(() => call($12, "load8_u", [14_327]), 0); + +// memory_copy.wast:1508 +assert_return(() => call($12, "load8_u", [14_526]), 0); + +// memory_copy.wast:1509 +assert_return(() => call($12, "load8_u", [14_725]), 0); + +// memory_copy.wast:1510 +assert_return(() => call($12, "load8_u", [14_924]), 0); + +// memory_copy.wast:1511 +assert_return(() => call($12, "load8_u", [15_123]), 0); + +// memory_copy.wast:1512 +assert_return(() => call($12, "load8_u", [15_322]), 0); + +// memory_copy.wast:1513 +assert_return(() => call($12, "load8_u", [15_521]), 0); + +// memory_copy.wast:1514 +assert_return(() => call($12, "load8_u", [15_720]), 0); + +// memory_copy.wast:1515 +assert_return(() => call($12, "load8_u", [15_919]), 0); + +// memory_copy.wast:1516 +assert_return(() => call($12, "load8_u", [16_118]), 0); + +// memory_copy.wast:1517 +assert_return(() => call($12, "load8_u", [16_317]), 0); + +// memory_copy.wast:1518 +assert_return(() => call($12, "load8_u", [16_516]), 0); + +// memory_copy.wast:1519 +assert_return(() => call($12, "load8_u", [16_715]), 0); + +// memory_copy.wast:1520 +assert_return(() => call($12, "load8_u", [16_914]), 0); + +// memory_copy.wast:1521 +assert_return(() => call($12, "load8_u", [17_113]), 0); + +// memory_copy.wast:1522 +assert_return(() => call($12, "load8_u", [17_312]), 0); + +// memory_copy.wast:1523 +assert_return(() => call($12, "load8_u", [17_511]), 0); + +// memory_copy.wast:1524 +assert_return(() => call($12, "load8_u", [17_710]), 0); + +// memory_copy.wast:1525 +assert_return(() => call($12, "load8_u", [17_909]), 0); + +// memory_copy.wast:1526 +assert_return(() => call($12, "load8_u", [18_108]), 0); + +// memory_copy.wast:1527 +assert_return(() => call($12, "load8_u", [18_307]), 0); + +// memory_copy.wast:1528 +assert_return(() => call($12, "load8_u", [18_506]), 0); + +// memory_copy.wast:1529 +assert_return(() => call($12, "load8_u", [18_705]), 0); + +// memory_copy.wast:1530 +assert_return(() => call($12, "load8_u", [18_904]), 0); + +// memory_copy.wast:1531 +assert_return(() => call($12, "load8_u", [19_103]), 0); + +// memory_copy.wast:1532 +assert_return(() => call($12, "load8_u", [19_302]), 0); + +// memory_copy.wast:1533 +assert_return(() => call($12, "load8_u", [19_501]), 0); + +// memory_copy.wast:1534 +assert_return(() => call($12, "load8_u", [19_700]), 0); + +// memory_copy.wast:1535 +assert_return(() => call($12, "load8_u", [19_899]), 0); + +// memory_copy.wast:1536 +assert_return(() => call($12, "load8_u", [20_098]), 0); + +// memory_copy.wast:1537 +assert_return(() => call($12, "load8_u", [20_297]), 0); + +// memory_copy.wast:1538 +assert_return(() => call($12, "load8_u", [20_496]), 0); + +// memory_copy.wast:1539 +assert_return(() => call($12, "load8_u", [20_695]), 0); + +// memory_copy.wast:1540 +assert_return(() => call($12, "load8_u", [20_894]), 0); + +// memory_copy.wast:1541 +assert_return(() => call($12, "load8_u", [21_093]), 0); + +// memory_copy.wast:1542 +assert_return(() => call($12, "load8_u", [21_292]), 0); + +// memory_copy.wast:1543 +assert_return(() => call($12, "load8_u", [21_491]), 0); + +// memory_copy.wast:1544 +assert_return(() => call($12, "load8_u", [21_690]), 0); + +// memory_copy.wast:1545 +assert_return(() => call($12, "load8_u", [21_889]), 0); + +// memory_copy.wast:1546 +assert_return(() => call($12, "load8_u", [22_088]), 0); + +// memory_copy.wast:1547 +assert_return(() => call($12, "load8_u", [22_287]), 0); + +// memory_copy.wast:1548 +assert_return(() => call($12, "load8_u", [22_486]), 0); + +// memory_copy.wast:1549 +assert_return(() => call($12, "load8_u", [22_685]), 0); + +// memory_copy.wast:1550 +assert_return(() => call($12, "load8_u", [22_884]), 0); + +// memory_copy.wast:1551 +assert_return(() => call($12, "load8_u", [23_083]), 0); + +// memory_copy.wast:1552 +assert_return(() => call($12, "load8_u", [23_282]), 0); + +// memory_copy.wast:1553 +assert_return(() => call($12, "load8_u", [23_481]), 0); + +// memory_copy.wast:1554 +assert_return(() => call($12, "load8_u", [23_680]), 0); + +// memory_copy.wast:1555 +assert_return(() => call($12, "load8_u", [23_879]), 0); + +// memory_copy.wast:1556 +assert_return(() => call($12, "load8_u", [24_078]), 0); + +// memory_copy.wast:1557 +assert_return(() => call($12, "load8_u", [24_277]), 0); + +// memory_copy.wast:1558 +assert_return(() => call($12, "load8_u", [24_476]), 0); + +// memory_copy.wast:1559 +assert_return(() => call($12, "load8_u", [24_675]), 0); + +// memory_copy.wast:1560 +assert_return(() => call($12, "load8_u", [24_874]), 0); + +// memory_copy.wast:1561 +assert_return(() => call($12, "load8_u", [25_073]), 0); + +// memory_copy.wast:1562 +assert_return(() => call($12, "load8_u", [25_272]), 0); + +// memory_copy.wast:1563 +assert_return(() => call($12, "load8_u", [25_471]), 0); + +// memory_copy.wast:1564 +assert_return(() => call($12, "load8_u", [25_670]), 0); + +// memory_copy.wast:1565 +assert_return(() => call($12, "load8_u", [25_869]), 0); + +// memory_copy.wast:1566 +assert_return(() => call($12, "load8_u", [26_068]), 0); + +// memory_copy.wast:1567 +assert_return(() => call($12, "load8_u", [26_267]), 0); + +// memory_copy.wast:1568 +assert_return(() => call($12, "load8_u", [26_466]), 0); + +// memory_copy.wast:1569 +assert_return(() => call($12, "load8_u", [26_665]), 0); + +// memory_copy.wast:1570 +assert_return(() => call($12, "load8_u", [26_864]), 0); + +// memory_copy.wast:1571 +assert_return(() => call($12, "load8_u", [27_063]), 0); + +// memory_copy.wast:1572 +assert_return(() => call($12, "load8_u", [27_262]), 0); + +// memory_copy.wast:1573 +assert_return(() => call($12, "load8_u", [27_461]), 0); + +// memory_copy.wast:1574 +assert_return(() => call($12, "load8_u", [27_660]), 0); + +// memory_copy.wast:1575 +assert_return(() => call($12, "load8_u", [27_859]), 0); + +// memory_copy.wast:1576 +assert_return(() => call($12, "load8_u", [28_058]), 0); + +// memory_copy.wast:1577 +assert_return(() => call($12, "load8_u", [28_257]), 0); + +// memory_copy.wast:1578 +assert_return(() => call($12, "load8_u", [28_456]), 0); + +// memory_copy.wast:1579 +assert_return(() => call($12, "load8_u", [28_655]), 0); + +// memory_copy.wast:1580 +assert_return(() => call($12, "load8_u", [28_854]), 0); + +// memory_copy.wast:1581 +assert_return(() => call($12, "load8_u", [29_053]), 0); + +// memory_copy.wast:1582 +assert_return(() => call($12, "load8_u", [29_252]), 0); + +// memory_copy.wast:1583 +assert_return(() => call($12, "load8_u", [29_451]), 0); + +// memory_copy.wast:1584 +assert_return(() => call($12, "load8_u", [29_650]), 0); + +// memory_copy.wast:1585 +assert_return(() => call($12, "load8_u", [29_849]), 0); + +// memory_copy.wast:1586 +assert_return(() => call($12, "load8_u", [30_048]), 0); + +// memory_copy.wast:1587 +assert_return(() => call($12, "load8_u", [30_247]), 0); + +// memory_copy.wast:1588 +assert_return(() => call($12, "load8_u", [30_446]), 0); + +// memory_copy.wast:1589 +assert_return(() => call($12, "load8_u", [30_645]), 0); + +// memory_copy.wast:1590 +assert_return(() => call($12, "load8_u", [30_844]), 0); + +// memory_copy.wast:1591 +assert_return(() => call($12, "load8_u", [31_043]), 0); + +// memory_copy.wast:1592 +assert_return(() => call($12, "load8_u", [31_242]), 0); + +// memory_copy.wast:1593 +assert_return(() => call($12, "load8_u", [31_441]), 0); + +// memory_copy.wast:1594 +assert_return(() => call($12, "load8_u", [31_640]), 0); + +// memory_copy.wast:1595 +assert_return(() => call($12, "load8_u", [31_839]), 0); + +// memory_copy.wast:1596 +assert_return(() => call($12, "load8_u", [32_038]), 0); + +// memory_copy.wast:1597 +assert_return(() => call($12, "load8_u", [32_237]), 0); + +// memory_copy.wast:1598 +assert_return(() => call($12, "load8_u", [32_436]), 0); + +// memory_copy.wast:1599 +assert_return(() => call($12, "load8_u", [32_635]), 0); + +// memory_copy.wast:1600 +assert_return(() => call($12, "load8_u", [32_834]), 0); + +// memory_copy.wast:1601 +assert_return(() => call($12, "load8_u", [33_033]), 0); + +// memory_copy.wast:1602 +assert_return(() => call($12, "load8_u", [33_232]), 0); + +// memory_copy.wast:1603 +assert_return(() => call($12, "load8_u", [33_431]), 0); + +// memory_copy.wast:1604 +assert_return(() => call($12, "load8_u", [33_630]), 0); + +// memory_copy.wast:1605 +assert_return(() => call($12, "load8_u", [33_829]), 0); + +// memory_copy.wast:1606 +assert_return(() => call($12, "load8_u", [34_028]), 0); + +// memory_copy.wast:1607 +assert_return(() => call($12, "load8_u", [34_227]), 0); + +// memory_copy.wast:1608 +assert_return(() => call($12, "load8_u", [34_426]), 0); + +// memory_copy.wast:1609 +assert_return(() => call($12, "load8_u", [34_625]), 0); + +// memory_copy.wast:1610 +assert_return(() => call($12, "load8_u", [34_824]), 0); + +// memory_copy.wast:1611 +assert_return(() => call($12, "load8_u", [35_023]), 0); + +// memory_copy.wast:1612 +assert_return(() => call($12, "load8_u", [35_222]), 0); + +// memory_copy.wast:1613 +assert_return(() => call($12, "load8_u", [35_421]), 0); + +// memory_copy.wast:1614 +assert_return(() => call($12, "load8_u", [35_620]), 0); + +// memory_copy.wast:1615 +assert_return(() => call($12, "load8_u", [35_819]), 0); + +// memory_copy.wast:1616 +assert_return(() => call($12, "load8_u", [36_018]), 0); + +// memory_copy.wast:1617 +assert_return(() => call($12, "load8_u", [36_217]), 0); + +// memory_copy.wast:1618 +assert_return(() => call($12, "load8_u", [36_416]), 0); + +// memory_copy.wast:1619 +assert_return(() => call($12, "load8_u", [36_615]), 0); + +// memory_copy.wast:1620 +assert_return(() => call($12, "load8_u", [36_814]), 0); + +// memory_copy.wast:1621 +assert_return(() => call($12, "load8_u", [37_013]), 0); + +// memory_copy.wast:1622 +assert_return(() => call($12, "load8_u", [37_212]), 0); + +// memory_copy.wast:1623 +assert_return(() => call($12, "load8_u", [37_411]), 0); + +// memory_copy.wast:1624 +assert_return(() => call($12, "load8_u", [37_610]), 0); + +// memory_copy.wast:1625 +assert_return(() => call($12, "load8_u", [37_809]), 0); + +// memory_copy.wast:1626 +assert_return(() => call($12, "load8_u", [38_008]), 0); + +// memory_copy.wast:1627 +assert_return(() => call($12, "load8_u", [38_207]), 0); + +// memory_copy.wast:1628 +assert_return(() => call($12, "load8_u", [38_406]), 0); + +// memory_copy.wast:1629 +assert_return(() => call($12, "load8_u", [38_605]), 0); + +// memory_copy.wast:1630 +assert_return(() => call($12, "load8_u", [38_804]), 0); + +// memory_copy.wast:1631 +assert_return(() => call($12, "load8_u", [39_003]), 0); + +// memory_copy.wast:1632 +assert_return(() => call($12, "load8_u", [39_202]), 0); + +// memory_copy.wast:1633 +assert_return(() => call($12, "load8_u", [39_401]), 0); + +// memory_copy.wast:1634 +assert_return(() => call($12, "load8_u", [39_600]), 0); + +// memory_copy.wast:1635 +assert_return(() => call($12, "load8_u", [39_799]), 0); + +// memory_copy.wast:1636 +assert_return(() => call($12, "load8_u", [39_998]), 0); + +// memory_copy.wast:1637 +assert_return(() => call($12, "load8_u", [40_197]), 0); + +// memory_copy.wast:1638 +assert_return(() => call($12, "load8_u", [40_396]), 0); + +// memory_copy.wast:1639 +assert_return(() => call($12, "load8_u", [40_595]), 0); + +// memory_copy.wast:1640 +assert_return(() => call($12, "load8_u", [40_794]), 0); + +// memory_copy.wast:1641 +assert_return(() => call($12, "load8_u", [40_993]), 0); + +// memory_copy.wast:1642 +assert_return(() => call($12, "load8_u", [41_192]), 0); + +// memory_copy.wast:1643 +assert_return(() => call($12, "load8_u", [41_391]), 0); + +// memory_copy.wast:1644 +assert_return(() => call($12, "load8_u", [41_590]), 0); + +// memory_copy.wast:1645 +assert_return(() => call($12, "load8_u", [41_789]), 0); + +// memory_copy.wast:1646 +assert_return(() => call($12, "load8_u", [41_988]), 0); + +// memory_copy.wast:1647 +assert_return(() => call($12, "load8_u", [42_187]), 0); + +// memory_copy.wast:1648 +assert_return(() => call($12, "load8_u", [42_386]), 0); + +// memory_copy.wast:1649 +assert_return(() => call($12, "load8_u", [42_585]), 0); + +// memory_copy.wast:1650 +assert_return(() => call($12, "load8_u", [42_784]), 0); + +// memory_copy.wast:1651 +assert_return(() => call($12, "load8_u", [42_983]), 0); + +// memory_copy.wast:1652 +assert_return(() => call($12, "load8_u", [43_182]), 0); + +// memory_copy.wast:1653 +assert_return(() => call($12, "load8_u", [43_381]), 0); + +// memory_copy.wast:1654 +assert_return(() => call($12, "load8_u", [43_580]), 0); + +// memory_copy.wast:1655 +assert_return(() => call($12, "load8_u", [43_779]), 0); + +// memory_copy.wast:1656 +assert_return(() => call($12, "load8_u", [43_978]), 0); + +// memory_copy.wast:1657 +assert_return(() => call($12, "load8_u", [44_177]), 0); + +// memory_copy.wast:1658 +assert_return(() => call($12, "load8_u", [44_376]), 0); + +// memory_copy.wast:1659 +assert_return(() => call($12, "load8_u", [44_575]), 0); + +// memory_copy.wast:1660 +assert_return(() => call($12, "load8_u", [44_774]), 0); + +// memory_copy.wast:1661 +assert_return(() => call($12, "load8_u", [44_973]), 0); + +// memory_copy.wast:1662 +assert_return(() => call($12, "load8_u", [45_172]), 0); + +// memory_copy.wast:1663 +assert_return(() => call($12, "load8_u", [45_371]), 0); + +// memory_copy.wast:1664 +assert_return(() => call($12, "load8_u", [45_570]), 0); + +// memory_copy.wast:1665 +assert_return(() => call($12, "load8_u", [45_769]), 0); + +// memory_copy.wast:1666 +assert_return(() => call($12, "load8_u", [45_968]), 0); + +// memory_copy.wast:1667 +assert_return(() => call($12, "load8_u", [46_167]), 0); + +// memory_copy.wast:1668 +assert_return(() => call($12, "load8_u", [46_366]), 0); + +// memory_copy.wast:1669 +assert_return(() => call($12, "load8_u", [46_565]), 0); + +// memory_copy.wast:1670 +assert_return(() => call($12, "load8_u", [46_764]), 0); + +// memory_copy.wast:1671 +assert_return(() => call($12, "load8_u", [46_963]), 0); + +// memory_copy.wast:1672 +assert_return(() => call($12, "load8_u", [47_162]), 0); + +// memory_copy.wast:1673 +assert_return(() => call($12, "load8_u", [47_361]), 0); + +// memory_copy.wast:1674 +assert_return(() => call($12, "load8_u", [47_560]), 0); + +// memory_copy.wast:1675 +assert_return(() => call($12, "load8_u", [47_759]), 0); + +// memory_copy.wast:1676 +assert_return(() => call($12, "load8_u", [47_958]), 0); + +// memory_copy.wast:1677 +assert_return(() => call($12, "load8_u", [48_157]), 0); + +// memory_copy.wast:1678 +assert_return(() => call($12, "load8_u", [48_356]), 0); + +// memory_copy.wast:1679 +assert_return(() => call($12, "load8_u", [48_555]), 0); + +// memory_copy.wast:1680 +assert_return(() => call($12, "load8_u", [48_754]), 0); + +// memory_copy.wast:1681 +assert_return(() => call($12, "load8_u", [48_953]), 0); + +// memory_copy.wast:1682 +assert_return(() => call($12, "load8_u", [49_152]), 0); + +// memory_copy.wast:1683 +assert_return(() => call($12, "load8_u", [49_351]), 0); + +// memory_copy.wast:1684 +assert_return(() => call($12, "load8_u", [49_550]), 0); + +// memory_copy.wast:1685 +assert_return(() => call($12, "load8_u", [49_749]), 0); + +// memory_copy.wast:1686 +assert_return(() => call($12, "load8_u", [49_948]), 0); + +// memory_copy.wast:1687 +assert_return(() => call($12, "load8_u", [50_147]), 0); + +// memory_copy.wast:1688 +assert_return(() => call($12, "load8_u", [50_346]), 0); + +// memory_copy.wast:1689 +assert_return(() => call($12, "load8_u", [50_545]), 0); + +// memory_copy.wast:1690 +assert_return(() => call($12, "load8_u", [50_744]), 0); + +// memory_copy.wast:1691 +assert_return(() => call($12, "load8_u", [50_943]), 0); + +// memory_copy.wast:1692 +assert_return(() => call($12, "load8_u", [51_142]), 0); + +// memory_copy.wast:1693 +assert_return(() => call($12, "load8_u", [51_341]), 0); + +// memory_copy.wast:1694 +assert_return(() => call($12, "load8_u", [51_540]), 0); + +// memory_copy.wast:1695 +assert_return(() => call($12, "load8_u", [51_739]), 0); + +// memory_copy.wast:1696 +assert_return(() => call($12, "load8_u", [51_938]), 0); + +// memory_copy.wast:1697 +assert_return(() => call($12, "load8_u", [52_137]), 0); + +// memory_copy.wast:1698 +assert_return(() => call($12, "load8_u", [52_336]), 0); + +// memory_copy.wast:1699 +assert_return(() => call($12, "load8_u", [52_535]), 0); + +// memory_copy.wast:1700 +assert_return(() => call($12, "load8_u", [52_734]), 0); + +// memory_copy.wast:1701 +assert_return(() => call($12, "load8_u", [52_933]), 0); + +// memory_copy.wast:1702 +assert_return(() => call($12, "load8_u", [53_132]), 0); + +// memory_copy.wast:1703 +assert_return(() => call($12, "load8_u", [53_331]), 0); + +// memory_copy.wast:1704 +assert_return(() => call($12, "load8_u", [53_530]), 0); + +// memory_copy.wast:1705 +assert_return(() => call($12, "load8_u", [53_729]), 0); + +// memory_copy.wast:1706 +assert_return(() => call($12, "load8_u", [53_928]), 0); + +// memory_copy.wast:1707 +assert_return(() => call($12, "load8_u", [54_127]), 0); + +// memory_copy.wast:1708 +assert_return(() => call($12, "load8_u", [54_326]), 0); + +// memory_copy.wast:1709 +assert_return(() => call($12, "load8_u", [54_525]), 0); + +// memory_copy.wast:1710 +assert_return(() => call($12, "load8_u", [54_724]), 0); + +// memory_copy.wast:1711 +assert_return(() => call($12, "load8_u", [54_923]), 0); + +// memory_copy.wast:1712 +assert_return(() => call($12, "load8_u", [55_122]), 0); + +// memory_copy.wast:1713 +assert_return(() => call($12, "load8_u", [55_321]), 0); + +// memory_copy.wast:1714 +assert_return(() => call($12, "load8_u", [55_520]), 0); + +// memory_copy.wast:1715 +assert_return(() => call($12, "load8_u", [55_719]), 0); + +// memory_copy.wast:1716 +assert_return(() => call($12, "load8_u", [55_918]), 0); + +// memory_copy.wast:1717 +assert_return(() => call($12, "load8_u", [56_117]), 0); + +// memory_copy.wast:1718 +assert_return(() => call($12, "load8_u", [56_316]), 0); + +// memory_copy.wast:1719 +assert_return(() => call($12, "load8_u", [56_515]), 0); + +// memory_copy.wast:1720 +assert_return(() => call($12, "load8_u", [56_714]), 0); + +// memory_copy.wast:1721 +assert_return(() => call($12, "load8_u", [56_913]), 0); + +// memory_copy.wast:1722 +assert_return(() => call($12, "load8_u", [57_112]), 0); + +// memory_copy.wast:1723 +assert_return(() => call($12, "load8_u", [57_311]), 0); + +// memory_copy.wast:1724 +assert_return(() => call($12, "load8_u", [57_510]), 0); + +// memory_copy.wast:1725 +assert_return(() => call($12, "load8_u", [57_709]), 0); + +// memory_copy.wast:1726 +assert_return(() => call($12, "load8_u", [57_908]), 0); + +// memory_copy.wast:1727 +assert_return(() => call($12, "load8_u", [58_107]), 0); + +// memory_copy.wast:1728 +assert_return(() => call($12, "load8_u", [58_306]), 0); + +// memory_copy.wast:1729 +assert_return(() => call($12, "load8_u", [58_505]), 0); + +// memory_copy.wast:1730 +assert_return(() => call($12, "load8_u", [58_704]), 0); + +// memory_copy.wast:1731 +assert_return(() => call($12, "load8_u", [58_903]), 0); + +// memory_copy.wast:1732 +assert_return(() => call($12, "load8_u", [59_102]), 0); + +// memory_copy.wast:1733 +assert_return(() => call($12, "load8_u", [59_301]), 0); + +// memory_copy.wast:1734 +assert_return(() => call($12, "load8_u", [59_500]), 0); + +// memory_copy.wast:1735 +assert_return(() => call($12, "load8_u", [59_699]), 0); + +// memory_copy.wast:1736 +assert_return(() => call($12, "load8_u", [59_898]), 0); + +// memory_copy.wast:1737 +assert_return(() => call($12, "load8_u", [60_097]), 0); + +// memory_copy.wast:1738 +assert_return(() => call($12, "load8_u", [60_296]), 0); + +// memory_copy.wast:1739 +assert_return(() => call($12, "load8_u", [60_495]), 0); + +// memory_copy.wast:1740 +assert_return(() => call($12, "load8_u", [60_694]), 0); + +// memory_copy.wast:1741 +assert_return(() => call($12, "load8_u", [60_893]), 0); + +// memory_copy.wast:1742 +assert_return(() => call($12, "load8_u", [61_092]), 0); + +// memory_copy.wast:1743 +assert_return(() => call($12, "load8_u", [61_291]), 0); + +// memory_copy.wast:1744 +assert_return(() => call($12, "load8_u", [61_490]), 0); + +// memory_copy.wast:1745 +assert_return(() => call($12, "load8_u", [61_689]), 0); + +// memory_copy.wast:1746 +assert_return(() => call($12, "load8_u", [61_888]), 0); + +// memory_copy.wast:1747 +assert_return(() => call($12, "load8_u", [62_087]), 0); + +// memory_copy.wast:1748 +assert_return(() => call($12, "load8_u", [62_286]), 0); + +// memory_copy.wast:1749 +assert_return(() => call($12, "load8_u", [62_485]), 0); + +// memory_copy.wast:1750 +assert_return(() => call($12, "load8_u", [62_684]), 0); + +// memory_copy.wast:1751 +assert_return(() => call($12, "load8_u", [62_883]), 0); + +// memory_copy.wast:1752 +assert_return(() => call($12, "load8_u", [63_082]), 0); + +// memory_copy.wast:1753 +assert_return(() => call($12, "load8_u", [63_281]), 0); + +// memory_copy.wast:1754 +assert_return(() => call($12, "load8_u", [63_480]), 0); + +// memory_copy.wast:1755 +assert_return(() => call($12, "load8_u", [63_679]), 0); + +// memory_copy.wast:1756 +assert_return(() => call($12, "load8_u", [63_878]), 0); + +// memory_copy.wast:1757 +assert_return(() => call($12, "load8_u", [64_077]), 0); + +// memory_copy.wast:1758 +assert_return(() => call($12, "load8_u", [64_276]), 0); + +// memory_copy.wast:1759 +assert_return(() => call($12, "load8_u", [64_475]), 0); + +// memory_copy.wast:1760 +assert_return(() => call($12, "load8_u", [64_674]), 0); + +// memory_copy.wast:1761 +assert_return(() => call($12, "load8_u", [64_873]), 0); + +// memory_copy.wast:1762 +assert_return(() => call($12, "load8_u", [65_072]), 0); + +// memory_copy.wast:1763 +assert_return(() => call($12, "load8_u", [65_271]), 0); + +// memory_copy.wast:1764 +assert_return(() => call($12, "load8_u", [65_470]), 0); + +// memory_copy.wast:1765 +assert_return(() => call($12, "load8_u", [65_515]), 0); + +// memory_copy.wast:1766 +assert_return(() => call($12, "load8_u", [65_516]), 1); + +// memory_copy.wast:1767 +assert_return(() => call($12, "load8_u", [65_517]), 2); + +// memory_copy.wast:1768 +assert_return(() => call($12, "load8_u", [65_518]), 3); + +// memory_copy.wast:1769 +assert_return(() => call($12, "load8_u", [65_519]), 4); + +// memory_copy.wast:1770 +assert_return(() => call($12, "load8_u", [65_520]), 5); + +// memory_copy.wast:1771 +assert_return(() => call($12, "load8_u", [65_521]), 6); + +// memory_copy.wast:1772 +assert_return(() => call($12, "load8_u", [65_522]), 7); + +// memory_copy.wast:1773 +assert_return(() => call($12, "load8_u", [65_523]), 8); + +// memory_copy.wast:1774 +assert_return(() => call($12, "load8_u", [65_524]), 9); + +// memory_copy.wast:1775 +assert_return(() => call($12, "load8_u", [65_525]), 10); + +// memory_copy.wast:1776 +assert_return(() => call($12, "load8_u", [65_526]), 11); + +// memory_copy.wast:1777 +assert_return(() => call($12, "load8_u", [65_527]), 12); + +// memory_copy.wast:1778 +assert_return(() => call($12, "load8_u", [65_528]), 13); + +// memory_copy.wast:1779 +assert_return(() => call($12, "load8_u", [65_529]), 14); + +// memory_copy.wast:1780 +assert_return(() => call($12, "load8_u", [65_530]), 15); + +// memory_copy.wast:1781 +assert_return(() => call($12, "load8_u", [65_531]), 16); + +// memory_copy.wast:1782 +assert_return(() => call($12, "load8_u", [65_532]), 17); + +// memory_copy.wast:1783 +assert_return(() => call($12, "load8_u", [65_533]), 18); + +// memory_copy.wast:1784 +assert_return(() => call($12, "load8_u", [65_534]), 19); + +// memory_copy.wast:1785 +assert_return(() => call($12, "load8_u", [65_535]), 20); + +// memory_copy.wast:1787 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xce\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:1795 +assert_trap(() => call($13, "run", [65_516, 65_486, 40])); + +// memory_copy.wast:1798 +assert_return(() => call($13, "load8_u", [198]), 0); + +// memory_copy.wast:1799 +assert_return(() => call($13, "load8_u", [397]), 0); + +// memory_copy.wast:1800 +assert_return(() => call($13, "load8_u", [596]), 0); + +// memory_copy.wast:1801 +assert_return(() => call($13, "load8_u", [795]), 0); + +// memory_copy.wast:1802 +assert_return(() => call($13, "load8_u", [994]), 0); + +// memory_copy.wast:1803 +assert_return(() => call($13, "load8_u", [1_193]), 0); + +// memory_copy.wast:1804 +assert_return(() => call($13, "load8_u", [1_392]), 0); + +// memory_copy.wast:1805 +assert_return(() => call($13, "load8_u", [1_591]), 0); + +// memory_copy.wast:1806 +assert_return(() => call($13, "load8_u", [1_790]), 0); + +// memory_copy.wast:1807 +assert_return(() => call($13, "load8_u", [1_989]), 0); + +// memory_copy.wast:1808 +assert_return(() => call($13, "load8_u", [2_188]), 0); + +// memory_copy.wast:1809 +assert_return(() => call($13, "load8_u", [2_387]), 0); + +// memory_copy.wast:1810 +assert_return(() => call($13, "load8_u", [2_586]), 0); + +// memory_copy.wast:1811 +assert_return(() => call($13, "load8_u", [2_785]), 0); + +// memory_copy.wast:1812 +assert_return(() => call($13, "load8_u", [2_984]), 0); + +// memory_copy.wast:1813 +assert_return(() => call($13, "load8_u", [3_183]), 0); + +// memory_copy.wast:1814 +assert_return(() => call($13, "load8_u", [3_382]), 0); + +// memory_copy.wast:1815 +assert_return(() => call($13, "load8_u", [3_581]), 0); + +// memory_copy.wast:1816 +assert_return(() => call($13, "load8_u", [3_780]), 0); + +// memory_copy.wast:1817 +assert_return(() => call($13, "load8_u", [3_979]), 0); + +// memory_copy.wast:1818 +assert_return(() => call($13, "load8_u", [4_178]), 0); + +// memory_copy.wast:1819 +assert_return(() => call($13, "load8_u", [4_377]), 0); + +// memory_copy.wast:1820 +assert_return(() => call($13, "load8_u", [4_576]), 0); + +// memory_copy.wast:1821 +assert_return(() => call($13, "load8_u", [4_775]), 0); + +// memory_copy.wast:1822 +assert_return(() => call($13, "load8_u", [4_974]), 0); + +// memory_copy.wast:1823 +assert_return(() => call($13, "load8_u", [5_173]), 0); + +// memory_copy.wast:1824 +assert_return(() => call($13, "load8_u", [5_372]), 0); + +// memory_copy.wast:1825 +assert_return(() => call($13, "load8_u", [5_571]), 0); + +// memory_copy.wast:1826 +assert_return(() => call($13, "load8_u", [5_770]), 0); + +// memory_copy.wast:1827 +assert_return(() => call($13, "load8_u", [5_969]), 0); + +// memory_copy.wast:1828 +assert_return(() => call($13, "load8_u", [6_168]), 0); + +// memory_copy.wast:1829 +assert_return(() => call($13, "load8_u", [6_367]), 0); + +// memory_copy.wast:1830 +assert_return(() => call($13, "load8_u", [6_566]), 0); + +// memory_copy.wast:1831 +assert_return(() => call($13, "load8_u", [6_765]), 0); + +// memory_copy.wast:1832 +assert_return(() => call($13, "load8_u", [6_964]), 0); + +// memory_copy.wast:1833 +assert_return(() => call($13, "load8_u", [7_163]), 0); + +// memory_copy.wast:1834 +assert_return(() => call($13, "load8_u", [7_362]), 0); + +// memory_copy.wast:1835 +assert_return(() => call($13, "load8_u", [7_561]), 0); + +// memory_copy.wast:1836 +assert_return(() => call($13, "load8_u", [7_760]), 0); + +// memory_copy.wast:1837 +assert_return(() => call($13, "load8_u", [7_959]), 0); + +// memory_copy.wast:1838 +assert_return(() => call($13, "load8_u", [8_158]), 0); + +// memory_copy.wast:1839 +assert_return(() => call($13, "load8_u", [8_357]), 0); + +// memory_copy.wast:1840 +assert_return(() => call($13, "load8_u", [8_556]), 0); + +// memory_copy.wast:1841 +assert_return(() => call($13, "load8_u", [8_755]), 0); + +// memory_copy.wast:1842 +assert_return(() => call($13, "load8_u", [8_954]), 0); + +// memory_copy.wast:1843 +assert_return(() => call($13, "load8_u", [9_153]), 0); + +// memory_copy.wast:1844 +assert_return(() => call($13, "load8_u", [9_352]), 0); + +// memory_copy.wast:1845 +assert_return(() => call($13, "load8_u", [9_551]), 0); + +// memory_copy.wast:1846 +assert_return(() => call($13, "load8_u", [9_750]), 0); + +// memory_copy.wast:1847 +assert_return(() => call($13, "load8_u", [9_949]), 0); + +// memory_copy.wast:1848 +assert_return(() => call($13, "load8_u", [10_148]), 0); + +// memory_copy.wast:1849 +assert_return(() => call($13, "load8_u", [10_347]), 0); + +// memory_copy.wast:1850 +assert_return(() => call($13, "load8_u", [10_546]), 0); + +// memory_copy.wast:1851 +assert_return(() => call($13, "load8_u", [10_745]), 0); + +// memory_copy.wast:1852 +assert_return(() => call($13, "load8_u", [10_944]), 0); + +// memory_copy.wast:1853 +assert_return(() => call($13, "load8_u", [11_143]), 0); + +// memory_copy.wast:1854 +assert_return(() => call($13, "load8_u", [11_342]), 0); + +// memory_copy.wast:1855 +assert_return(() => call($13, "load8_u", [11_541]), 0); + +// memory_copy.wast:1856 +assert_return(() => call($13, "load8_u", [11_740]), 0); + +// memory_copy.wast:1857 +assert_return(() => call($13, "load8_u", [11_939]), 0); + +// memory_copy.wast:1858 +assert_return(() => call($13, "load8_u", [12_138]), 0); + +// memory_copy.wast:1859 +assert_return(() => call($13, "load8_u", [12_337]), 0); + +// memory_copy.wast:1860 +assert_return(() => call($13, "load8_u", [12_536]), 0); + +// memory_copy.wast:1861 +assert_return(() => call($13, "load8_u", [12_735]), 0); + +// memory_copy.wast:1862 +assert_return(() => call($13, "load8_u", [12_934]), 0); + +// memory_copy.wast:1863 +assert_return(() => call($13, "load8_u", [13_133]), 0); + +// memory_copy.wast:1864 +assert_return(() => call($13, "load8_u", [13_332]), 0); + +// memory_copy.wast:1865 +assert_return(() => call($13, "load8_u", [13_531]), 0); + +// memory_copy.wast:1866 +assert_return(() => call($13, "load8_u", [13_730]), 0); + +// memory_copy.wast:1867 +assert_return(() => call($13, "load8_u", [13_929]), 0); + +// memory_copy.wast:1868 +assert_return(() => call($13, "load8_u", [14_128]), 0); + +// memory_copy.wast:1869 +assert_return(() => call($13, "load8_u", [14_327]), 0); + +// memory_copy.wast:1870 +assert_return(() => call($13, "load8_u", [14_526]), 0); + +// memory_copy.wast:1871 +assert_return(() => call($13, "load8_u", [14_725]), 0); + +// memory_copy.wast:1872 +assert_return(() => call($13, "load8_u", [14_924]), 0); + +// memory_copy.wast:1873 +assert_return(() => call($13, "load8_u", [15_123]), 0); + +// memory_copy.wast:1874 +assert_return(() => call($13, "load8_u", [15_322]), 0); + +// memory_copy.wast:1875 +assert_return(() => call($13, "load8_u", [15_521]), 0); + +// memory_copy.wast:1876 +assert_return(() => call($13, "load8_u", [15_720]), 0); + +// memory_copy.wast:1877 +assert_return(() => call($13, "load8_u", [15_919]), 0); + +// memory_copy.wast:1878 +assert_return(() => call($13, "load8_u", [16_118]), 0); + +// memory_copy.wast:1879 +assert_return(() => call($13, "load8_u", [16_317]), 0); + +// memory_copy.wast:1880 +assert_return(() => call($13, "load8_u", [16_516]), 0); + +// memory_copy.wast:1881 +assert_return(() => call($13, "load8_u", [16_715]), 0); + +// memory_copy.wast:1882 +assert_return(() => call($13, "load8_u", [16_914]), 0); + +// memory_copy.wast:1883 +assert_return(() => call($13, "load8_u", [17_113]), 0); + +// memory_copy.wast:1884 +assert_return(() => call($13, "load8_u", [17_312]), 0); + +// memory_copy.wast:1885 +assert_return(() => call($13, "load8_u", [17_511]), 0); + +// memory_copy.wast:1886 +assert_return(() => call($13, "load8_u", [17_710]), 0); + +// memory_copy.wast:1887 +assert_return(() => call($13, "load8_u", [17_909]), 0); + +// memory_copy.wast:1888 +assert_return(() => call($13, "load8_u", [18_108]), 0); + +// memory_copy.wast:1889 +assert_return(() => call($13, "load8_u", [18_307]), 0); + +// memory_copy.wast:1890 +assert_return(() => call($13, "load8_u", [18_506]), 0); + +// memory_copy.wast:1891 +assert_return(() => call($13, "load8_u", [18_705]), 0); + +// memory_copy.wast:1892 +assert_return(() => call($13, "load8_u", [18_904]), 0); + +// memory_copy.wast:1893 +assert_return(() => call($13, "load8_u", [19_103]), 0); + +// memory_copy.wast:1894 +assert_return(() => call($13, "load8_u", [19_302]), 0); + +// memory_copy.wast:1895 +assert_return(() => call($13, "load8_u", [19_501]), 0); + +// memory_copy.wast:1896 +assert_return(() => call($13, "load8_u", [19_700]), 0); + +// memory_copy.wast:1897 +assert_return(() => call($13, "load8_u", [19_899]), 0); + +// memory_copy.wast:1898 +assert_return(() => call($13, "load8_u", [20_098]), 0); + +// memory_copy.wast:1899 +assert_return(() => call($13, "load8_u", [20_297]), 0); + +// memory_copy.wast:1900 +assert_return(() => call($13, "load8_u", [20_496]), 0); + +// memory_copy.wast:1901 +assert_return(() => call($13, "load8_u", [20_695]), 0); + +// memory_copy.wast:1902 +assert_return(() => call($13, "load8_u", [20_894]), 0); + +// memory_copy.wast:1903 +assert_return(() => call($13, "load8_u", [21_093]), 0); + +// memory_copy.wast:1904 +assert_return(() => call($13, "load8_u", [21_292]), 0); + +// memory_copy.wast:1905 +assert_return(() => call($13, "load8_u", [21_491]), 0); + +// memory_copy.wast:1906 +assert_return(() => call($13, "load8_u", [21_690]), 0); + +// memory_copy.wast:1907 +assert_return(() => call($13, "load8_u", [21_889]), 0); + +// memory_copy.wast:1908 +assert_return(() => call($13, "load8_u", [22_088]), 0); + +// memory_copy.wast:1909 +assert_return(() => call($13, "load8_u", [22_287]), 0); + +// memory_copy.wast:1910 +assert_return(() => call($13, "load8_u", [22_486]), 0); + +// memory_copy.wast:1911 +assert_return(() => call($13, "load8_u", [22_685]), 0); + +// memory_copy.wast:1912 +assert_return(() => call($13, "load8_u", [22_884]), 0); + +// memory_copy.wast:1913 +assert_return(() => call($13, "load8_u", [23_083]), 0); + +// memory_copy.wast:1914 +assert_return(() => call($13, "load8_u", [23_282]), 0); + +// memory_copy.wast:1915 +assert_return(() => call($13, "load8_u", [23_481]), 0); + +// memory_copy.wast:1916 +assert_return(() => call($13, "load8_u", [23_680]), 0); + +// memory_copy.wast:1917 +assert_return(() => call($13, "load8_u", [23_879]), 0); + +// memory_copy.wast:1918 +assert_return(() => call($13, "load8_u", [24_078]), 0); + +// memory_copy.wast:1919 +assert_return(() => call($13, "load8_u", [24_277]), 0); + +// memory_copy.wast:1920 +assert_return(() => call($13, "load8_u", [24_476]), 0); + +// memory_copy.wast:1921 +assert_return(() => call($13, "load8_u", [24_675]), 0); + +// memory_copy.wast:1922 +assert_return(() => call($13, "load8_u", [24_874]), 0); + +// memory_copy.wast:1923 +assert_return(() => call($13, "load8_u", [25_073]), 0); + +// memory_copy.wast:1924 +assert_return(() => call($13, "load8_u", [25_272]), 0); + +// memory_copy.wast:1925 +assert_return(() => call($13, "load8_u", [25_471]), 0); + +// memory_copy.wast:1926 +assert_return(() => call($13, "load8_u", [25_670]), 0); + +// memory_copy.wast:1927 +assert_return(() => call($13, "load8_u", [25_869]), 0); + +// memory_copy.wast:1928 +assert_return(() => call($13, "load8_u", [26_068]), 0); + +// memory_copy.wast:1929 +assert_return(() => call($13, "load8_u", [26_267]), 0); + +// memory_copy.wast:1930 +assert_return(() => call($13, "load8_u", [26_466]), 0); + +// memory_copy.wast:1931 +assert_return(() => call($13, "load8_u", [26_665]), 0); + +// memory_copy.wast:1932 +assert_return(() => call($13, "load8_u", [26_864]), 0); + +// memory_copy.wast:1933 +assert_return(() => call($13, "load8_u", [27_063]), 0); + +// memory_copy.wast:1934 +assert_return(() => call($13, "load8_u", [27_262]), 0); + +// memory_copy.wast:1935 +assert_return(() => call($13, "load8_u", [27_461]), 0); + +// memory_copy.wast:1936 +assert_return(() => call($13, "load8_u", [27_660]), 0); + +// memory_copy.wast:1937 +assert_return(() => call($13, "load8_u", [27_859]), 0); + +// memory_copy.wast:1938 +assert_return(() => call($13, "load8_u", [28_058]), 0); + +// memory_copy.wast:1939 +assert_return(() => call($13, "load8_u", [28_257]), 0); + +// memory_copy.wast:1940 +assert_return(() => call($13, "load8_u", [28_456]), 0); + +// memory_copy.wast:1941 +assert_return(() => call($13, "load8_u", [28_655]), 0); + +// memory_copy.wast:1942 +assert_return(() => call($13, "load8_u", [28_854]), 0); + +// memory_copy.wast:1943 +assert_return(() => call($13, "load8_u", [29_053]), 0); + +// memory_copy.wast:1944 +assert_return(() => call($13, "load8_u", [29_252]), 0); + +// memory_copy.wast:1945 +assert_return(() => call($13, "load8_u", [29_451]), 0); + +// memory_copy.wast:1946 +assert_return(() => call($13, "load8_u", [29_650]), 0); + +// memory_copy.wast:1947 +assert_return(() => call($13, "load8_u", [29_849]), 0); + +// memory_copy.wast:1948 +assert_return(() => call($13, "load8_u", [30_048]), 0); + +// memory_copy.wast:1949 +assert_return(() => call($13, "load8_u", [30_247]), 0); + +// memory_copy.wast:1950 +assert_return(() => call($13, "load8_u", [30_446]), 0); + +// memory_copy.wast:1951 +assert_return(() => call($13, "load8_u", [30_645]), 0); + +// memory_copy.wast:1952 +assert_return(() => call($13, "load8_u", [30_844]), 0); + +// memory_copy.wast:1953 +assert_return(() => call($13, "load8_u", [31_043]), 0); + +// memory_copy.wast:1954 +assert_return(() => call($13, "load8_u", [31_242]), 0); + +// memory_copy.wast:1955 +assert_return(() => call($13, "load8_u", [31_441]), 0); + +// memory_copy.wast:1956 +assert_return(() => call($13, "load8_u", [31_640]), 0); + +// memory_copy.wast:1957 +assert_return(() => call($13, "load8_u", [31_839]), 0); + +// memory_copy.wast:1958 +assert_return(() => call($13, "load8_u", [32_038]), 0); + +// memory_copy.wast:1959 +assert_return(() => call($13, "load8_u", [32_237]), 0); + +// memory_copy.wast:1960 +assert_return(() => call($13, "load8_u", [32_436]), 0); + +// memory_copy.wast:1961 +assert_return(() => call($13, "load8_u", [32_635]), 0); + +// memory_copy.wast:1962 +assert_return(() => call($13, "load8_u", [32_834]), 0); + +// memory_copy.wast:1963 +assert_return(() => call($13, "load8_u", [33_033]), 0); + +// memory_copy.wast:1964 +assert_return(() => call($13, "load8_u", [33_232]), 0); + +// memory_copy.wast:1965 +assert_return(() => call($13, "load8_u", [33_431]), 0); + +// memory_copy.wast:1966 +assert_return(() => call($13, "load8_u", [33_630]), 0); + +// memory_copy.wast:1967 +assert_return(() => call($13, "load8_u", [33_829]), 0); + +// memory_copy.wast:1968 +assert_return(() => call($13, "load8_u", [34_028]), 0); + +// memory_copy.wast:1969 +assert_return(() => call($13, "load8_u", [34_227]), 0); + +// memory_copy.wast:1970 +assert_return(() => call($13, "load8_u", [34_426]), 0); + +// memory_copy.wast:1971 +assert_return(() => call($13, "load8_u", [34_625]), 0); + +// memory_copy.wast:1972 +assert_return(() => call($13, "load8_u", [34_824]), 0); + +// memory_copy.wast:1973 +assert_return(() => call($13, "load8_u", [35_023]), 0); + +// memory_copy.wast:1974 +assert_return(() => call($13, "load8_u", [35_222]), 0); + +// memory_copy.wast:1975 +assert_return(() => call($13, "load8_u", [35_421]), 0); + +// memory_copy.wast:1976 +assert_return(() => call($13, "load8_u", [35_620]), 0); + +// memory_copy.wast:1977 +assert_return(() => call($13, "load8_u", [35_819]), 0); + +// memory_copy.wast:1978 +assert_return(() => call($13, "load8_u", [36_018]), 0); + +// memory_copy.wast:1979 +assert_return(() => call($13, "load8_u", [36_217]), 0); + +// memory_copy.wast:1980 +assert_return(() => call($13, "load8_u", [36_416]), 0); + +// memory_copy.wast:1981 +assert_return(() => call($13, "load8_u", [36_615]), 0); + +// memory_copy.wast:1982 +assert_return(() => call($13, "load8_u", [36_814]), 0); + +// memory_copy.wast:1983 +assert_return(() => call($13, "load8_u", [37_013]), 0); + +// memory_copy.wast:1984 +assert_return(() => call($13, "load8_u", [37_212]), 0); + +// memory_copy.wast:1985 +assert_return(() => call($13, "load8_u", [37_411]), 0); + +// memory_copy.wast:1986 +assert_return(() => call($13, "load8_u", [37_610]), 0); + +// memory_copy.wast:1987 +assert_return(() => call($13, "load8_u", [37_809]), 0); + +// memory_copy.wast:1988 +assert_return(() => call($13, "load8_u", [38_008]), 0); + +// memory_copy.wast:1989 +assert_return(() => call($13, "load8_u", [38_207]), 0); + +// memory_copy.wast:1990 +assert_return(() => call($13, "load8_u", [38_406]), 0); + +// memory_copy.wast:1991 +assert_return(() => call($13, "load8_u", [38_605]), 0); + +// memory_copy.wast:1992 +assert_return(() => call($13, "load8_u", [38_804]), 0); + +// memory_copy.wast:1993 +assert_return(() => call($13, "load8_u", [39_003]), 0); + +// memory_copy.wast:1994 +assert_return(() => call($13, "load8_u", [39_202]), 0); + +// memory_copy.wast:1995 +assert_return(() => call($13, "load8_u", [39_401]), 0); + +// memory_copy.wast:1996 +assert_return(() => call($13, "load8_u", [39_600]), 0); + +// memory_copy.wast:1997 +assert_return(() => call($13, "load8_u", [39_799]), 0); + +// memory_copy.wast:1998 +assert_return(() => call($13, "load8_u", [39_998]), 0); + +// memory_copy.wast:1999 +assert_return(() => call($13, "load8_u", [40_197]), 0); + +// memory_copy.wast:2000 +assert_return(() => call($13, "load8_u", [40_396]), 0); + +// memory_copy.wast:2001 +assert_return(() => call($13, "load8_u", [40_595]), 0); + +// memory_copy.wast:2002 +assert_return(() => call($13, "load8_u", [40_794]), 0); + +// memory_copy.wast:2003 +assert_return(() => call($13, "load8_u", [40_993]), 0); + +// memory_copy.wast:2004 +assert_return(() => call($13, "load8_u", [41_192]), 0); + +// memory_copy.wast:2005 +assert_return(() => call($13, "load8_u", [41_391]), 0); + +// memory_copy.wast:2006 +assert_return(() => call($13, "load8_u", [41_590]), 0); + +// memory_copy.wast:2007 +assert_return(() => call($13, "load8_u", [41_789]), 0); + +// memory_copy.wast:2008 +assert_return(() => call($13, "load8_u", [41_988]), 0); + +// memory_copy.wast:2009 +assert_return(() => call($13, "load8_u", [42_187]), 0); + +// memory_copy.wast:2010 +assert_return(() => call($13, "load8_u", [42_386]), 0); + +// memory_copy.wast:2011 +assert_return(() => call($13, "load8_u", [42_585]), 0); + +// memory_copy.wast:2012 +assert_return(() => call($13, "load8_u", [42_784]), 0); + +// memory_copy.wast:2013 +assert_return(() => call($13, "load8_u", [42_983]), 0); + +// memory_copy.wast:2014 +assert_return(() => call($13, "load8_u", [43_182]), 0); + +// memory_copy.wast:2015 +assert_return(() => call($13, "load8_u", [43_381]), 0); + +// memory_copy.wast:2016 +assert_return(() => call($13, "load8_u", [43_580]), 0); + +// memory_copy.wast:2017 +assert_return(() => call($13, "load8_u", [43_779]), 0); + +// memory_copy.wast:2018 +assert_return(() => call($13, "load8_u", [43_978]), 0); + +// memory_copy.wast:2019 +assert_return(() => call($13, "load8_u", [44_177]), 0); + +// memory_copy.wast:2020 +assert_return(() => call($13, "load8_u", [44_376]), 0); + +// memory_copy.wast:2021 +assert_return(() => call($13, "load8_u", [44_575]), 0); + +// memory_copy.wast:2022 +assert_return(() => call($13, "load8_u", [44_774]), 0); + +// memory_copy.wast:2023 +assert_return(() => call($13, "load8_u", [44_973]), 0); + +// memory_copy.wast:2024 +assert_return(() => call($13, "load8_u", [45_172]), 0); + +// memory_copy.wast:2025 +assert_return(() => call($13, "load8_u", [45_371]), 0); + +// memory_copy.wast:2026 +assert_return(() => call($13, "load8_u", [45_570]), 0); + +// memory_copy.wast:2027 +assert_return(() => call($13, "load8_u", [45_769]), 0); + +// memory_copy.wast:2028 +assert_return(() => call($13, "load8_u", [45_968]), 0); + +// memory_copy.wast:2029 +assert_return(() => call($13, "load8_u", [46_167]), 0); + +// memory_copy.wast:2030 +assert_return(() => call($13, "load8_u", [46_366]), 0); + +// memory_copy.wast:2031 +assert_return(() => call($13, "load8_u", [46_565]), 0); + +// memory_copy.wast:2032 +assert_return(() => call($13, "load8_u", [46_764]), 0); + +// memory_copy.wast:2033 +assert_return(() => call($13, "load8_u", [46_963]), 0); + +// memory_copy.wast:2034 +assert_return(() => call($13, "load8_u", [47_162]), 0); + +// memory_copy.wast:2035 +assert_return(() => call($13, "load8_u", [47_361]), 0); + +// memory_copy.wast:2036 +assert_return(() => call($13, "load8_u", [47_560]), 0); + +// memory_copy.wast:2037 +assert_return(() => call($13, "load8_u", [47_759]), 0); + +// memory_copy.wast:2038 +assert_return(() => call($13, "load8_u", [47_958]), 0); + +// memory_copy.wast:2039 +assert_return(() => call($13, "load8_u", [48_157]), 0); + +// memory_copy.wast:2040 +assert_return(() => call($13, "load8_u", [48_356]), 0); + +// memory_copy.wast:2041 +assert_return(() => call($13, "load8_u", [48_555]), 0); + +// memory_copy.wast:2042 +assert_return(() => call($13, "load8_u", [48_754]), 0); + +// memory_copy.wast:2043 +assert_return(() => call($13, "load8_u", [48_953]), 0); + +// memory_copy.wast:2044 +assert_return(() => call($13, "load8_u", [49_152]), 0); + +// memory_copy.wast:2045 +assert_return(() => call($13, "load8_u", [49_351]), 0); + +// memory_copy.wast:2046 +assert_return(() => call($13, "load8_u", [49_550]), 0); + +// memory_copy.wast:2047 +assert_return(() => call($13, "load8_u", [49_749]), 0); + +// memory_copy.wast:2048 +assert_return(() => call($13, "load8_u", [49_948]), 0); + +// memory_copy.wast:2049 +assert_return(() => call($13, "load8_u", [50_147]), 0); + +// memory_copy.wast:2050 +assert_return(() => call($13, "load8_u", [50_346]), 0); + +// memory_copy.wast:2051 +assert_return(() => call($13, "load8_u", [50_545]), 0); + +// memory_copy.wast:2052 +assert_return(() => call($13, "load8_u", [50_744]), 0); + +// memory_copy.wast:2053 +assert_return(() => call($13, "load8_u", [50_943]), 0); + +// memory_copy.wast:2054 +assert_return(() => call($13, "load8_u", [51_142]), 0); + +// memory_copy.wast:2055 +assert_return(() => call($13, "load8_u", [51_341]), 0); + +// memory_copy.wast:2056 +assert_return(() => call($13, "load8_u", [51_540]), 0); + +// memory_copy.wast:2057 +assert_return(() => call($13, "load8_u", [51_739]), 0); + +// memory_copy.wast:2058 +assert_return(() => call($13, "load8_u", [51_938]), 0); + +// memory_copy.wast:2059 +assert_return(() => call($13, "load8_u", [52_137]), 0); + +// memory_copy.wast:2060 +assert_return(() => call($13, "load8_u", [52_336]), 0); + +// memory_copy.wast:2061 +assert_return(() => call($13, "load8_u", [52_535]), 0); + +// memory_copy.wast:2062 +assert_return(() => call($13, "load8_u", [52_734]), 0); + +// memory_copy.wast:2063 +assert_return(() => call($13, "load8_u", [52_933]), 0); + +// memory_copy.wast:2064 +assert_return(() => call($13, "load8_u", [53_132]), 0); + +// memory_copy.wast:2065 +assert_return(() => call($13, "load8_u", [53_331]), 0); + +// memory_copy.wast:2066 +assert_return(() => call($13, "load8_u", [53_530]), 0); + +// memory_copy.wast:2067 +assert_return(() => call($13, "load8_u", [53_729]), 0); + +// memory_copy.wast:2068 +assert_return(() => call($13, "load8_u", [53_928]), 0); + +// memory_copy.wast:2069 +assert_return(() => call($13, "load8_u", [54_127]), 0); + +// memory_copy.wast:2070 +assert_return(() => call($13, "load8_u", [54_326]), 0); + +// memory_copy.wast:2071 +assert_return(() => call($13, "load8_u", [54_525]), 0); + +// memory_copy.wast:2072 +assert_return(() => call($13, "load8_u", [54_724]), 0); + +// memory_copy.wast:2073 +assert_return(() => call($13, "load8_u", [54_923]), 0); + +// memory_copy.wast:2074 +assert_return(() => call($13, "load8_u", [55_122]), 0); + +// memory_copy.wast:2075 +assert_return(() => call($13, "load8_u", [55_321]), 0); + +// memory_copy.wast:2076 +assert_return(() => call($13, "load8_u", [55_520]), 0); + +// memory_copy.wast:2077 +assert_return(() => call($13, "load8_u", [55_719]), 0); + +// memory_copy.wast:2078 +assert_return(() => call($13, "load8_u", [55_918]), 0); + +// memory_copy.wast:2079 +assert_return(() => call($13, "load8_u", [56_117]), 0); + +// memory_copy.wast:2080 +assert_return(() => call($13, "load8_u", [56_316]), 0); + +// memory_copy.wast:2081 +assert_return(() => call($13, "load8_u", [56_515]), 0); + +// memory_copy.wast:2082 +assert_return(() => call($13, "load8_u", [56_714]), 0); + +// memory_copy.wast:2083 +assert_return(() => call($13, "load8_u", [56_913]), 0); + +// memory_copy.wast:2084 +assert_return(() => call($13, "load8_u", [57_112]), 0); + +// memory_copy.wast:2085 +assert_return(() => call($13, "load8_u", [57_311]), 0); + +// memory_copy.wast:2086 +assert_return(() => call($13, "load8_u", [57_510]), 0); + +// memory_copy.wast:2087 +assert_return(() => call($13, "load8_u", [57_709]), 0); + +// memory_copy.wast:2088 +assert_return(() => call($13, "load8_u", [57_908]), 0); + +// memory_copy.wast:2089 +assert_return(() => call($13, "load8_u", [58_107]), 0); + +// memory_copy.wast:2090 +assert_return(() => call($13, "load8_u", [58_306]), 0); + +// memory_copy.wast:2091 +assert_return(() => call($13, "load8_u", [58_505]), 0); + +// memory_copy.wast:2092 +assert_return(() => call($13, "load8_u", [58_704]), 0); + +// memory_copy.wast:2093 +assert_return(() => call($13, "load8_u", [58_903]), 0); + +// memory_copy.wast:2094 +assert_return(() => call($13, "load8_u", [59_102]), 0); + +// memory_copy.wast:2095 +assert_return(() => call($13, "load8_u", [59_301]), 0); + +// memory_copy.wast:2096 +assert_return(() => call($13, "load8_u", [59_500]), 0); + +// memory_copy.wast:2097 +assert_return(() => call($13, "load8_u", [59_699]), 0); + +// memory_copy.wast:2098 +assert_return(() => call($13, "load8_u", [59_898]), 0); + +// memory_copy.wast:2099 +assert_return(() => call($13, "load8_u", [60_097]), 0); + +// memory_copy.wast:2100 +assert_return(() => call($13, "load8_u", [60_296]), 0); + +// memory_copy.wast:2101 +assert_return(() => call($13, "load8_u", [60_495]), 0); + +// memory_copy.wast:2102 +assert_return(() => call($13, "load8_u", [60_694]), 0); + +// memory_copy.wast:2103 +assert_return(() => call($13, "load8_u", [60_893]), 0); + +// memory_copy.wast:2104 +assert_return(() => call($13, "load8_u", [61_092]), 0); + +// memory_copy.wast:2105 +assert_return(() => call($13, "load8_u", [61_291]), 0); + +// memory_copy.wast:2106 +assert_return(() => call($13, "load8_u", [61_490]), 0); + +// memory_copy.wast:2107 +assert_return(() => call($13, "load8_u", [61_689]), 0); + +// memory_copy.wast:2108 +assert_return(() => call($13, "load8_u", [61_888]), 0); + +// memory_copy.wast:2109 +assert_return(() => call($13, "load8_u", [62_087]), 0); + +// memory_copy.wast:2110 +assert_return(() => call($13, "load8_u", [62_286]), 0); + +// memory_copy.wast:2111 +assert_return(() => call($13, "load8_u", [62_485]), 0); + +// memory_copy.wast:2112 +assert_return(() => call($13, "load8_u", [62_684]), 0); + +// memory_copy.wast:2113 +assert_return(() => call($13, "load8_u", [62_883]), 0); + +// memory_copy.wast:2114 +assert_return(() => call($13, "load8_u", [63_082]), 0); + +// memory_copy.wast:2115 +assert_return(() => call($13, "load8_u", [63_281]), 0); + +// memory_copy.wast:2116 +assert_return(() => call($13, "load8_u", [63_480]), 0); + +// memory_copy.wast:2117 +assert_return(() => call($13, "load8_u", [63_679]), 0); + +// memory_copy.wast:2118 +assert_return(() => call($13, "load8_u", [63_878]), 0); + +// memory_copy.wast:2119 +assert_return(() => call($13, "load8_u", [64_077]), 0); + +// memory_copy.wast:2120 +assert_return(() => call($13, "load8_u", [64_276]), 0); + +// memory_copy.wast:2121 +assert_return(() => call($13, "load8_u", [64_475]), 0); + +// memory_copy.wast:2122 +assert_return(() => call($13, "load8_u", [64_674]), 0); + +// memory_copy.wast:2123 +assert_return(() => call($13, "load8_u", [64_873]), 0); + +// memory_copy.wast:2124 +assert_return(() => call($13, "load8_u", [65_072]), 0); + +// memory_copy.wast:2125 +assert_return(() => call($13, "load8_u", [65_271]), 0); + +// memory_copy.wast:2126 +assert_return(() => call($13, "load8_u", [65_470]), 0); + +// memory_copy.wast:2127 +assert_return(() => call($13, "load8_u", [65_486]), 0); + +// memory_copy.wast:2128 +assert_return(() => call($13, "load8_u", [65_487]), 1); + +// memory_copy.wast:2129 +assert_return(() => call($13, "load8_u", [65_488]), 2); + +// memory_copy.wast:2130 +assert_return(() => call($13, "load8_u", [65_489]), 3); + +// memory_copy.wast:2131 +assert_return(() => call($13, "load8_u", [65_490]), 4); + +// memory_copy.wast:2132 +assert_return(() => call($13, "load8_u", [65_491]), 5); + +// memory_copy.wast:2133 +assert_return(() => call($13, "load8_u", [65_492]), 6); + +// memory_copy.wast:2134 +assert_return(() => call($13, "load8_u", [65_493]), 7); + +// memory_copy.wast:2135 +assert_return(() => call($13, "load8_u", [65_494]), 8); + +// memory_copy.wast:2136 +assert_return(() => call($13, "load8_u", [65_495]), 9); + +// memory_copy.wast:2137 +assert_return(() => call($13, "load8_u", [65_496]), 10); + +// memory_copy.wast:2138 +assert_return(() => call($13, "load8_u", [65_497]), 11); + +// memory_copy.wast:2139 +assert_return(() => call($13, "load8_u", [65_498]), 12); + +// memory_copy.wast:2140 +assert_return(() => call($13, "load8_u", [65_499]), 13); + +// memory_copy.wast:2141 +assert_return(() => call($13, "load8_u", [65_500]), 14); + +// memory_copy.wast:2142 +assert_return(() => call($13, "load8_u", [65_501]), 15); + +// memory_copy.wast:2143 +assert_return(() => call($13, "load8_u", [65_502]), 16); + +// memory_copy.wast:2144 +assert_return(() => call($13, "load8_u", [65_503]), 17); + +// memory_copy.wast:2145 +assert_return(() => call($13, "load8_u", [65_504]), 18); + +// memory_copy.wast:2146 +assert_return(() => call($13, "load8_u", [65_505]), 19); + +// memory_copy.wast:2148 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2156 +assert_trap(() => call($14, "run", [65_486, 65_516, 40])); + +// memory_copy.wast:2159 +assert_return(() => call($14, "load8_u", [198]), 0); + +// memory_copy.wast:2160 +assert_return(() => call($14, "load8_u", [397]), 0); + +// memory_copy.wast:2161 +assert_return(() => call($14, "load8_u", [596]), 0); + +// memory_copy.wast:2162 +assert_return(() => call($14, "load8_u", [795]), 0); + +// memory_copy.wast:2163 +assert_return(() => call($14, "load8_u", [994]), 0); + +// memory_copy.wast:2164 +assert_return(() => call($14, "load8_u", [1_193]), 0); + +// memory_copy.wast:2165 +assert_return(() => call($14, "load8_u", [1_392]), 0); + +// memory_copy.wast:2166 +assert_return(() => call($14, "load8_u", [1_591]), 0); + +// memory_copy.wast:2167 +assert_return(() => call($14, "load8_u", [1_790]), 0); + +// memory_copy.wast:2168 +assert_return(() => call($14, "load8_u", [1_989]), 0); + +// memory_copy.wast:2169 +assert_return(() => call($14, "load8_u", [2_188]), 0); + +// memory_copy.wast:2170 +assert_return(() => call($14, "load8_u", [2_387]), 0); + +// memory_copy.wast:2171 +assert_return(() => call($14, "load8_u", [2_586]), 0); + +// memory_copy.wast:2172 +assert_return(() => call($14, "load8_u", [2_785]), 0); + +// memory_copy.wast:2173 +assert_return(() => call($14, "load8_u", [2_984]), 0); + +// memory_copy.wast:2174 +assert_return(() => call($14, "load8_u", [3_183]), 0); + +// memory_copy.wast:2175 +assert_return(() => call($14, "load8_u", [3_382]), 0); + +// memory_copy.wast:2176 +assert_return(() => call($14, "load8_u", [3_581]), 0); + +// memory_copy.wast:2177 +assert_return(() => call($14, "load8_u", [3_780]), 0); + +// memory_copy.wast:2178 +assert_return(() => call($14, "load8_u", [3_979]), 0); + +// memory_copy.wast:2179 +assert_return(() => call($14, "load8_u", [4_178]), 0); + +// memory_copy.wast:2180 +assert_return(() => call($14, "load8_u", [4_377]), 0); + +// memory_copy.wast:2181 +assert_return(() => call($14, "load8_u", [4_576]), 0); + +// memory_copy.wast:2182 +assert_return(() => call($14, "load8_u", [4_775]), 0); + +// memory_copy.wast:2183 +assert_return(() => call($14, "load8_u", [4_974]), 0); + +// memory_copy.wast:2184 +assert_return(() => call($14, "load8_u", [5_173]), 0); + +// memory_copy.wast:2185 +assert_return(() => call($14, "load8_u", [5_372]), 0); + +// memory_copy.wast:2186 +assert_return(() => call($14, "load8_u", [5_571]), 0); + +// memory_copy.wast:2187 +assert_return(() => call($14, "load8_u", [5_770]), 0); + +// memory_copy.wast:2188 +assert_return(() => call($14, "load8_u", [5_969]), 0); + +// memory_copy.wast:2189 +assert_return(() => call($14, "load8_u", [6_168]), 0); + +// memory_copy.wast:2190 +assert_return(() => call($14, "load8_u", [6_367]), 0); + +// memory_copy.wast:2191 +assert_return(() => call($14, "load8_u", [6_566]), 0); + +// memory_copy.wast:2192 +assert_return(() => call($14, "load8_u", [6_765]), 0); + +// memory_copy.wast:2193 +assert_return(() => call($14, "load8_u", [6_964]), 0); + +// memory_copy.wast:2194 +assert_return(() => call($14, "load8_u", [7_163]), 0); + +// memory_copy.wast:2195 +assert_return(() => call($14, "load8_u", [7_362]), 0); + +// memory_copy.wast:2196 +assert_return(() => call($14, "load8_u", [7_561]), 0); + +// memory_copy.wast:2197 +assert_return(() => call($14, "load8_u", [7_760]), 0); + +// memory_copy.wast:2198 +assert_return(() => call($14, "load8_u", [7_959]), 0); + +// memory_copy.wast:2199 +assert_return(() => call($14, "load8_u", [8_158]), 0); + +// memory_copy.wast:2200 +assert_return(() => call($14, "load8_u", [8_357]), 0); + +// memory_copy.wast:2201 +assert_return(() => call($14, "load8_u", [8_556]), 0); + +// memory_copy.wast:2202 +assert_return(() => call($14, "load8_u", [8_755]), 0); + +// memory_copy.wast:2203 +assert_return(() => call($14, "load8_u", [8_954]), 0); + +// memory_copy.wast:2204 +assert_return(() => call($14, "load8_u", [9_153]), 0); + +// memory_copy.wast:2205 +assert_return(() => call($14, "load8_u", [9_352]), 0); + +// memory_copy.wast:2206 +assert_return(() => call($14, "load8_u", [9_551]), 0); + +// memory_copy.wast:2207 +assert_return(() => call($14, "load8_u", [9_750]), 0); + +// memory_copy.wast:2208 +assert_return(() => call($14, "load8_u", [9_949]), 0); + +// memory_copy.wast:2209 +assert_return(() => call($14, "load8_u", [10_148]), 0); + +// memory_copy.wast:2210 +assert_return(() => call($14, "load8_u", [10_347]), 0); + +// memory_copy.wast:2211 +assert_return(() => call($14, "load8_u", [10_546]), 0); + +// memory_copy.wast:2212 +assert_return(() => call($14, "load8_u", [10_745]), 0); + +// memory_copy.wast:2213 +assert_return(() => call($14, "load8_u", [10_944]), 0); + +// memory_copy.wast:2214 +assert_return(() => call($14, "load8_u", [11_143]), 0); + +// memory_copy.wast:2215 +assert_return(() => call($14, "load8_u", [11_342]), 0); + +// memory_copy.wast:2216 +assert_return(() => call($14, "load8_u", [11_541]), 0); + +// memory_copy.wast:2217 +assert_return(() => call($14, "load8_u", [11_740]), 0); + +// memory_copy.wast:2218 +assert_return(() => call($14, "load8_u", [11_939]), 0); + +// memory_copy.wast:2219 +assert_return(() => call($14, "load8_u", [12_138]), 0); + +// memory_copy.wast:2220 +assert_return(() => call($14, "load8_u", [12_337]), 0); + +// memory_copy.wast:2221 +assert_return(() => call($14, "load8_u", [12_536]), 0); + +// memory_copy.wast:2222 +assert_return(() => call($14, "load8_u", [12_735]), 0); + +// memory_copy.wast:2223 +assert_return(() => call($14, "load8_u", [12_934]), 0); + +// memory_copy.wast:2224 +assert_return(() => call($14, "load8_u", [13_133]), 0); + +// memory_copy.wast:2225 +assert_return(() => call($14, "load8_u", [13_332]), 0); + +// memory_copy.wast:2226 +assert_return(() => call($14, "load8_u", [13_531]), 0); + +// memory_copy.wast:2227 +assert_return(() => call($14, "load8_u", [13_730]), 0); + +// memory_copy.wast:2228 +assert_return(() => call($14, "load8_u", [13_929]), 0); + +// memory_copy.wast:2229 +assert_return(() => call($14, "load8_u", [14_128]), 0); + +// memory_copy.wast:2230 +assert_return(() => call($14, "load8_u", [14_327]), 0); + +// memory_copy.wast:2231 +assert_return(() => call($14, "load8_u", [14_526]), 0); + +// memory_copy.wast:2232 +assert_return(() => call($14, "load8_u", [14_725]), 0); + +// memory_copy.wast:2233 +assert_return(() => call($14, "load8_u", [14_924]), 0); + +// memory_copy.wast:2234 +assert_return(() => call($14, "load8_u", [15_123]), 0); + +// memory_copy.wast:2235 +assert_return(() => call($14, "load8_u", [15_322]), 0); + +// memory_copy.wast:2236 +assert_return(() => call($14, "load8_u", [15_521]), 0); + +// memory_copy.wast:2237 +assert_return(() => call($14, "load8_u", [15_720]), 0); + +// memory_copy.wast:2238 +assert_return(() => call($14, "load8_u", [15_919]), 0); + +// memory_copy.wast:2239 +assert_return(() => call($14, "load8_u", [16_118]), 0); + +// memory_copy.wast:2240 +assert_return(() => call($14, "load8_u", [16_317]), 0); + +// memory_copy.wast:2241 +assert_return(() => call($14, "load8_u", [16_516]), 0); + +// memory_copy.wast:2242 +assert_return(() => call($14, "load8_u", [16_715]), 0); + +// memory_copy.wast:2243 +assert_return(() => call($14, "load8_u", [16_914]), 0); + +// memory_copy.wast:2244 +assert_return(() => call($14, "load8_u", [17_113]), 0); + +// memory_copy.wast:2245 +assert_return(() => call($14, "load8_u", [17_312]), 0); + +// memory_copy.wast:2246 +assert_return(() => call($14, "load8_u", [17_511]), 0); + +// memory_copy.wast:2247 +assert_return(() => call($14, "load8_u", [17_710]), 0); + +// memory_copy.wast:2248 +assert_return(() => call($14, "load8_u", [17_909]), 0); + +// memory_copy.wast:2249 +assert_return(() => call($14, "load8_u", [18_108]), 0); + +// memory_copy.wast:2250 +assert_return(() => call($14, "load8_u", [18_307]), 0); + +// memory_copy.wast:2251 +assert_return(() => call($14, "load8_u", [18_506]), 0); + +// memory_copy.wast:2252 +assert_return(() => call($14, "load8_u", [18_705]), 0); + +// memory_copy.wast:2253 +assert_return(() => call($14, "load8_u", [18_904]), 0); + +// memory_copy.wast:2254 +assert_return(() => call($14, "load8_u", [19_103]), 0); + +// memory_copy.wast:2255 +assert_return(() => call($14, "load8_u", [19_302]), 0); + +// memory_copy.wast:2256 +assert_return(() => call($14, "load8_u", [19_501]), 0); + +// memory_copy.wast:2257 +assert_return(() => call($14, "load8_u", [19_700]), 0); + +// memory_copy.wast:2258 +assert_return(() => call($14, "load8_u", [19_899]), 0); + +// memory_copy.wast:2259 +assert_return(() => call($14, "load8_u", [20_098]), 0); + +// memory_copy.wast:2260 +assert_return(() => call($14, "load8_u", [20_297]), 0); + +// memory_copy.wast:2261 +assert_return(() => call($14, "load8_u", [20_496]), 0); + +// memory_copy.wast:2262 +assert_return(() => call($14, "load8_u", [20_695]), 0); + +// memory_copy.wast:2263 +assert_return(() => call($14, "load8_u", [20_894]), 0); + +// memory_copy.wast:2264 +assert_return(() => call($14, "load8_u", [21_093]), 0); + +// memory_copy.wast:2265 +assert_return(() => call($14, "load8_u", [21_292]), 0); + +// memory_copy.wast:2266 +assert_return(() => call($14, "load8_u", [21_491]), 0); + +// memory_copy.wast:2267 +assert_return(() => call($14, "load8_u", [21_690]), 0); + +// memory_copy.wast:2268 +assert_return(() => call($14, "load8_u", [21_889]), 0); + +// memory_copy.wast:2269 +assert_return(() => call($14, "load8_u", [22_088]), 0); + +// memory_copy.wast:2270 +assert_return(() => call($14, "load8_u", [22_287]), 0); + +// memory_copy.wast:2271 +assert_return(() => call($14, "load8_u", [22_486]), 0); + +// memory_copy.wast:2272 +assert_return(() => call($14, "load8_u", [22_685]), 0); + +// memory_copy.wast:2273 +assert_return(() => call($14, "load8_u", [22_884]), 0); + +// memory_copy.wast:2274 +assert_return(() => call($14, "load8_u", [23_083]), 0); + +// memory_copy.wast:2275 +assert_return(() => call($14, "load8_u", [23_282]), 0); + +// memory_copy.wast:2276 +assert_return(() => call($14, "load8_u", [23_481]), 0); + +// memory_copy.wast:2277 +assert_return(() => call($14, "load8_u", [23_680]), 0); + +// memory_copy.wast:2278 +assert_return(() => call($14, "load8_u", [23_879]), 0); + +// memory_copy.wast:2279 +assert_return(() => call($14, "load8_u", [24_078]), 0); + +// memory_copy.wast:2280 +assert_return(() => call($14, "load8_u", [24_277]), 0); + +// memory_copy.wast:2281 +assert_return(() => call($14, "load8_u", [24_476]), 0); + +// memory_copy.wast:2282 +assert_return(() => call($14, "load8_u", [24_675]), 0); + +// memory_copy.wast:2283 +assert_return(() => call($14, "load8_u", [24_874]), 0); + +// memory_copy.wast:2284 +assert_return(() => call($14, "load8_u", [25_073]), 0); + +// memory_copy.wast:2285 +assert_return(() => call($14, "load8_u", [25_272]), 0); + +// memory_copy.wast:2286 +assert_return(() => call($14, "load8_u", [25_471]), 0); + +// memory_copy.wast:2287 +assert_return(() => call($14, "load8_u", [25_670]), 0); + +// memory_copy.wast:2288 +assert_return(() => call($14, "load8_u", [25_869]), 0); + +// memory_copy.wast:2289 +assert_return(() => call($14, "load8_u", [26_068]), 0); + +// memory_copy.wast:2290 +assert_return(() => call($14, "load8_u", [26_267]), 0); + +// memory_copy.wast:2291 +assert_return(() => call($14, "load8_u", [26_466]), 0); + +// memory_copy.wast:2292 +assert_return(() => call($14, "load8_u", [26_665]), 0); + +// memory_copy.wast:2293 +assert_return(() => call($14, "load8_u", [26_864]), 0); + +// memory_copy.wast:2294 +assert_return(() => call($14, "load8_u", [27_063]), 0); + +// memory_copy.wast:2295 +assert_return(() => call($14, "load8_u", [27_262]), 0); + +// memory_copy.wast:2296 +assert_return(() => call($14, "load8_u", [27_461]), 0); + +// memory_copy.wast:2297 +assert_return(() => call($14, "load8_u", [27_660]), 0); + +// memory_copy.wast:2298 +assert_return(() => call($14, "load8_u", [27_859]), 0); + +// memory_copy.wast:2299 +assert_return(() => call($14, "load8_u", [28_058]), 0); + +// memory_copy.wast:2300 +assert_return(() => call($14, "load8_u", [28_257]), 0); + +// memory_copy.wast:2301 +assert_return(() => call($14, "load8_u", [28_456]), 0); + +// memory_copy.wast:2302 +assert_return(() => call($14, "load8_u", [28_655]), 0); + +// memory_copy.wast:2303 +assert_return(() => call($14, "load8_u", [28_854]), 0); + +// memory_copy.wast:2304 +assert_return(() => call($14, "load8_u", [29_053]), 0); + +// memory_copy.wast:2305 +assert_return(() => call($14, "load8_u", [29_252]), 0); + +// memory_copy.wast:2306 +assert_return(() => call($14, "load8_u", [29_451]), 0); + +// memory_copy.wast:2307 +assert_return(() => call($14, "load8_u", [29_650]), 0); + +// memory_copy.wast:2308 +assert_return(() => call($14, "load8_u", [29_849]), 0); + +// memory_copy.wast:2309 +assert_return(() => call($14, "load8_u", [30_048]), 0); + +// memory_copy.wast:2310 +assert_return(() => call($14, "load8_u", [30_247]), 0); + +// memory_copy.wast:2311 +assert_return(() => call($14, "load8_u", [30_446]), 0); + +// memory_copy.wast:2312 +assert_return(() => call($14, "load8_u", [30_645]), 0); + +// memory_copy.wast:2313 +assert_return(() => call($14, "load8_u", [30_844]), 0); + +// memory_copy.wast:2314 +assert_return(() => call($14, "load8_u", [31_043]), 0); + +// memory_copy.wast:2315 +assert_return(() => call($14, "load8_u", [31_242]), 0); + +// memory_copy.wast:2316 +assert_return(() => call($14, "load8_u", [31_441]), 0); + +// memory_copy.wast:2317 +assert_return(() => call($14, "load8_u", [31_640]), 0); + +// memory_copy.wast:2318 +assert_return(() => call($14, "load8_u", [31_839]), 0); + +// memory_copy.wast:2319 +assert_return(() => call($14, "load8_u", [32_038]), 0); + +// memory_copy.wast:2320 +assert_return(() => call($14, "load8_u", [32_237]), 0); + +// memory_copy.wast:2321 +assert_return(() => call($14, "load8_u", [32_436]), 0); + +// memory_copy.wast:2322 +assert_return(() => call($14, "load8_u", [32_635]), 0); + +// memory_copy.wast:2323 +assert_return(() => call($14, "load8_u", [32_834]), 0); + +// memory_copy.wast:2324 +assert_return(() => call($14, "load8_u", [33_033]), 0); + +// memory_copy.wast:2325 +assert_return(() => call($14, "load8_u", [33_232]), 0); + +// memory_copy.wast:2326 +assert_return(() => call($14, "load8_u", [33_431]), 0); + +// memory_copy.wast:2327 +assert_return(() => call($14, "load8_u", [33_630]), 0); + +// memory_copy.wast:2328 +assert_return(() => call($14, "load8_u", [33_829]), 0); + +// memory_copy.wast:2329 +assert_return(() => call($14, "load8_u", [34_028]), 0); + +// memory_copy.wast:2330 +assert_return(() => call($14, "load8_u", [34_227]), 0); + +// memory_copy.wast:2331 +assert_return(() => call($14, "load8_u", [34_426]), 0); + +// memory_copy.wast:2332 +assert_return(() => call($14, "load8_u", [34_625]), 0); + +// memory_copy.wast:2333 +assert_return(() => call($14, "load8_u", [34_824]), 0); + +// memory_copy.wast:2334 +assert_return(() => call($14, "load8_u", [35_023]), 0); + +// memory_copy.wast:2335 +assert_return(() => call($14, "load8_u", [35_222]), 0); + +// memory_copy.wast:2336 +assert_return(() => call($14, "load8_u", [35_421]), 0); + +// memory_copy.wast:2337 +assert_return(() => call($14, "load8_u", [35_620]), 0); + +// memory_copy.wast:2338 +assert_return(() => call($14, "load8_u", [35_819]), 0); + +// memory_copy.wast:2339 +assert_return(() => call($14, "load8_u", [36_018]), 0); + +// memory_copy.wast:2340 +assert_return(() => call($14, "load8_u", [36_217]), 0); + +// memory_copy.wast:2341 +assert_return(() => call($14, "load8_u", [36_416]), 0); + +// memory_copy.wast:2342 +assert_return(() => call($14, "load8_u", [36_615]), 0); + +// memory_copy.wast:2343 +assert_return(() => call($14, "load8_u", [36_814]), 0); + +// memory_copy.wast:2344 +assert_return(() => call($14, "load8_u", [37_013]), 0); + +// memory_copy.wast:2345 +assert_return(() => call($14, "load8_u", [37_212]), 0); + +// memory_copy.wast:2346 +assert_return(() => call($14, "load8_u", [37_411]), 0); + +// memory_copy.wast:2347 +assert_return(() => call($14, "load8_u", [37_610]), 0); + +// memory_copy.wast:2348 +assert_return(() => call($14, "load8_u", [37_809]), 0); + +// memory_copy.wast:2349 +assert_return(() => call($14, "load8_u", [38_008]), 0); + +// memory_copy.wast:2350 +assert_return(() => call($14, "load8_u", [38_207]), 0); + +// memory_copy.wast:2351 +assert_return(() => call($14, "load8_u", [38_406]), 0); + +// memory_copy.wast:2352 +assert_return(() => call($14, "load8_u", [38_605]), 0); + +// memory_copy.wast:2353 +assert_return(() => call($14, "load8_u", [38_804]), 0); + +// memory_copy.wast:2354 +assert_return(() => call($14, "load8_u", [39_003]), 0); + +// memory_copy.wast:2355 +assert_return(() => call($14, "load8_u", [39_202]), 0); + +// memory_copy.wast:2356 +assert_return(() => call($14, "load8_u", [39_401]), 0); + +// memory_copy.wast:2357 +assert_return(() => call($14, "load8_u", [39_600]), 0); + +// memory_copy.wast:2358 +assert_return(() => call($14, "load8_u", [39_799]), 0); + +// memory_copy.wast:2359 +assert_return(() => call($14, "load8_u", [39_998]), 0); + +// memory_copy.wast:2360 +assert_return(() => call($14, "load8_u", [40_197]), 0); + +// memory_copy.wast:2361 +assert_return(() => call($14, "load8_u", [40_396]), 0); + +// memory_copy.wast:2362 +assert_return(() => call($14, "load8_u", [40_595]), 0); + +// memory_copy.wast:2363 +assert_return(() => call($14, "load8_u", [40_794]), 0); + +// memory_copy.wast:2364 +assert_return(() => call($14, "load8_u", [40_993]), 0); + +// memory_copy.wast:2365 +assert_return(() => call($14, "load8_u", [41_192]), 0); + +// memory_copy.wast:2366 +assert_return(() => call($14, "load8_u", [41_391]), 0); + +// memory_copy.wast:2367 +assert_return(() => call($14, "load8_u", [41_590]), 0); + +// memory_copy.wast:2368 +assert_return(() => call($14, "load8_u", [41_789]), 0); + +// memory_copy.wast:2369 +assert_return(() => call($14, "load8_u", [41_988]), 0); + +// memory_copy.wast:2370 +assert_return(() => call($14, "load8_u", [42_187]), 0); + +// memory_copy.wast:2371 +assert_return(() => call($14, "load8_u", [42_386]), 0); + +// memory_copy.wast:2372 +assert_return(() => call($14, "load8_u", [42_585]), 0); + +// memory_copy.wast:2373 +assert_return(() => call($14, "load8_u", [42_784]), 0); + +// memory_copy.wast:2374 +assert_return(() => call($14, "load8_u", [42_983]), 0); + +// memory_copy.wast:2375 +assert_return(() => call($14, "load8_u", [43_182]), 0); + +// memory_copy.wast:2376 +assert_return(() => call($14, "load8_u", [43_381]), 0); + +// memory_copy.wast:2377 +assert_return(() => call($14, "load8_u", [43_580]), 0); + +// memory_copy.wast:2378 +assert_return(() => call($14, "load8_u", [43_779]), 0); + +// memory_copy.wast:2379 +assert_return(() => call($14, "load8_u", [43_978]), 0); + +// memory_copy.wast:2380 +assert_return(() => call($14, "load8_u", [44_177]), 0); + +// memory_copy.wast:2381 +assert_return(() => call($14, "load8_u", [44_376]), 0); + +// memory_copy.wast:2382 +assert_return(() => call($14, "load8_u", [44_575]), 0); + +// memory_copy.wast:2383 +assert_return(() => call($14, "load8_u", [44_774]), 0); + +// memory_copy.wast:2384 +assert_return(() => call($14, "load8_u", [44_973]), 0); + +// memory_copy.wast:2385 +assert_return(() => call($14, "load8_u", [45_172]), 0); + +// memory_copy.wast:2386 +assert_return(() => call($14, "load8_u", [45_371]), 0); + +// memory_copy.wast:2387 +assert_return(() => call($14, "load8_u", [45_570]), 0); + +// memory_copy.wast:2388 +assert_return(() => call($14, "load8_u", [45_769]), 0); + +// memory_copy.wast:2389 +assert_return(() => call($14, "load8_u", [45_968]), 0); + +// memory_copy.wast:2390 +assert_return(() => call($14, "load8_u", [46_167]), 0); + +// memory_copy.wast:2391 +assert_return(() => call($14, "load8_u", [46_366]), 0); + +// memory_copy.wast:2392 +assert_return(() => call($14, "load8_u", [46_565]), 0); + +// memory_copy.wast:2393 +assert_return(() => call($14, "load8_u", [46_764]), 0); + +// memory_copy.wast:2394 +assert_return(() => call($14, "load8_u", [46_963]), 0); + +// memory_copy.wast:2395 +assert_return(() => call($14, "load8_u", [47_162]), 0); + +// memory_copy.wast:2396 +assert_return(() => call($14, "load8_u", [47_361]), 0); + +// memory_copy.wast:2397 +assert_return(() => call($14, "load8_u", [47_560]), 0); + +// memory_copy.wast:2398 +assert_return(() => call($14, "load8_u", [47_759]), 0); + +// memory_copy.wast:2399 +assert_return(() => call($14, "load8_u", [47_958]), 0); + +// memory_copy.wast:2400 +assert_return(() => call($14, "load8_u", [48_157]), 0); + +// memory_copy.wast:2401 +assert_return(() => call($14, "load8_u", [48_356]), 0); + +// memory_copy.wast:2402 +assert_return(() => call($14, "load8_u", [48_555]), 0); + +// memory_copy.wast:2403 +assert_return(() => call($14, "load8_u", [48_754]), 0); + +// memory_copy.wast:2404 +assert_return(() => call($14, "load8_u", [48_953]), 0); + +// memory_copy.wast:2405 +assert_return(() => call($14, "load8_u", [49_152]), 0); + +// memory_copy.wast:2406 +assert_return(() => call($14, "load8_u", [49_351]), 0); + +// memory_copy.wast:2407 +assert_return(() => call($14, "load8_u", [49_550]), 0); + +// memory_copy.wast:2408 +assert_return(() => call($14, "load8_u", [49_749]), 0); + +// memory_copy.wast:2409 +assert_return(() => call($14, "load8_u", [49_948]), 0); + +// memory_copy.wast:2410 +assert_return(() => call($14, "load8_u", [50_147]), 0); + +// memory_copy.wast:2411 +assert_return(() => call($14, "load8_u", [50_346]), 0); + +// memory_copy.wast:2412 +assert_return(() => call($14, "load8_u", [50_545]), 0); + +// memory_copy.wast:2413 +assert_return(() => call($14, "load8_u", [50_744]), 0); + +// memory_copy.wast:2414 +assert_return(() => call($14, "load8_u", [50_943]), 0); + +// memory_copy.wast:2415 +assert_return(() => call($14, "load8_u", [51_142]), 0); + +// memory_copy.wast:2416 +assert_return(() => call($14, "load8_u", [51_341]), 0); + +// memory_copy.wast:2417 +assert_return(() => call($14, "load8_u", [51_540]), 0); + +// memory_copy.wast:2418 +assert_return(() => call($14, "load8_u", [51_739]), 0); + +// memory_copy.wast:2419 +assert_return(() => call($14, "load8_u", [51_938]), 0); + +// memory_copy.wast:2420 +assert_return(() => call($14, "load8_u", [52_137]), 0); + +// memory_copy.wast:2421 +assert_return(() => call($14, "load8_u", [52_336]), 0); + +// memory_copy.wast:2422 +assert_return(() => call($14, "load8_u", [52_535]), 0); + +// memory_copy.wast:2423 +assert_return(() => call($14, "load8_u", [52_734]), 0); + +// memory_copy.wast:2424 +assert_return(() => call($14, "load8_u", [52_933]), 0); + +// memory_copy.wast:2425 +assert_return(() => call($14, "load8_u", [53_132]), 0); + +// memory_copy.wast:2426 +assert_return(() => call($14, "load8_u", [53_331]), 0); + +// memory_copy.wast:2427 +assert_return(() => call($14, "load8_u", [53_530]), 0); + +// memory_copy.wast:2428 +assert_return(() => call($14, "load8_u", [53_729]), 0); + +// memory_copy.wast:2429 +assert_return(() => call($14, "load8_u", [53_928]), 0); + +// memory_copy.wast:2430 +assert_return(() => call($14, "load8_u", [54_127]), 0); + +// memory_copy.wast:2431 +assert_return(() => call($14, "load8_u", [54_326]), 0); + +// memory_copy.wast:2432 +assert_return(() => call($14, "load8_u", [54_525]), 0); + +// memory_copy.wast:2433 +assert_return(() => call($14, "load8_u", [54_724]), 0); + +// memory_copy.wast:2434 +assert_return(() => call($14, "load8_u", [54_923]), 0); + +// memory_copy.wast:2435 +assert_return(() => call($14, "load8_u", [55_122]), 0); + +// memory_copy.wast:2436 +assert_return(() => call($14, "load8_u", [55_321]), 0); + +// memory_copy.wast:2437 +assert_return(() => call($14, "load8_u", [55_520]), 0); + +// memory_copy.wast:2438 +assert_return(() => call($14, "load8_u", [55_719]), 0); + +// memory_copy.wast:2439 +assert_return(() => call($14, "load8_u", [55_918]), 0); + +// memory_copy.wast:2440 +assert_return(() => call($14, "load8_u", [56_117]), 0); + +// memory_copy.wast:2441 +assert_return(() => call($14, "load8_u", [56_316]), 0); + +// memory_copy.wast:2442 +assert_return(() => call($14, "load8_u", [56_515]), 0); + +// memory_copy.wast:2443 +assert_return(() => call($14, "load8_u", [56_714]), 0); + +// memory_copy.wast:2444 +assert_return(() => call($14, "load8_u", [56_913]), 0); + +// memory_copy.wast:2445 +assert_return(() => call($14, "load8_u", [57_112]), 0); + +// memory_copy.wast:2446 +assert_return(() => call($14, "load8_u", [57_311]), 0); + +// memory_copy.wast:2447 +assert_return(() => call($14, "load8_u", [57_510]), 0); + +// memory_copy.wast:2448 +assert_return(() => call($14, "load8_u", [57_709]), 0); + +// memory_copy.wast:2449 +assert_return(() => call($14, "load8_u", [57_908]), 0); + +// memory_copy.wast:2450 +assert_return(() => call($14, "load8_u", [58_107]), 0); + +// memory_copy.wast:2451 +assert_return(() => call($14, "load8_u", [58_306]), 0); + +// memory_copy.wast:2452 +assert_return(() => call($14, "load8_u", [58_505]), 0); + +// memory_copy.wast:2453 +assert_return(() => call($14, "load8_u", [58_704]), 0); + +// memory_copy.wast:2454 +assert_return(() => call($14, "load8_u", [58_903]), 0); + +// memory_copy.wast:2455 +assert_return(() => call($14, "load8_u", [59_102]), 0); + +// memory_copy.wast:2456 +assert_return(() => call($14, "load8_u", [59_301]), 0); + +// memory_copy.wast:2457 +assert_return(() => call($14, "load8_u", [59_500]), 0); + +// memory_copy.wast:2458 +assert_return(() => call($14, "load8_u", [59_699]), 0); + +// memory_copy.wast:2459 +assert_return(() => call($14, "load8_u", [59_898]), 0); + +// memory_copy.wast:2460 +assert_return(() => call($14, "load8_u", [60_097]), 0); + +// memory_copy.wast:2461 +assert_return(() => call($14, "load8_u", [60_296]), 0); + +// memory_copy.wast:2462 +assert_return(() => call($14, "load8_u", [60_495]), 0); + +// memory_copy.wast:2463 +assert_return(() => call($14, "load8_u", [60_694]), 0); + +// memory_copy.wast:2464 +assert_return(() => call($14, "load8_u", [60_893]), 0); + +// memory_copy.wast:2465 +assert_return(() => call($14, "load8_u", [61_092]), 0); + +// memory_copy.wast:2466 +assert_return(() => call($14, "load8_u", [61_291]), 0); + +// memory_copy.wast:2467 +assert_return(() => call($14, "load8_u", [61_490]), 0); + +// memory_copy.wast:2468 +assert_return(() => call($14, "load8_u", [61_689]), 0); + +// memory_copy.wast:2469 +assert_return(() => call($14, "load8_u", [61_888]), 0); + +// memory_copy.wast:2470 +assert_return(() => call($14, "load8_u", [62_087]), 0); + +// memory_copy.wast:2471 +assert_return(() => call($14, "load8_u", [62_286]), 0); + +// memory_copy.wast:2472 +assert_return(() => call($14, "load8_u", [62_485]), 0); + +// memory_copy.wast:2473 +assert_return(() => call($14, "load8_u", [62_684]), 0); + +// memory_copy.wast:2474 +assert_return(() => call($14, "load8_u", [62_883]), 0); + +// memory_copy.wast:2475 +assert_return(() => call($14, "load8_u", [63_082]), 0); + +// memory_copy.wast:2476 +assert_return(() => call($14, "load8_u", [63_281]), 0); + +// memory_copy.wast:2477 +assert_return(() => call($14, "load8_u", [63_480]), 0); + +// memory_copy.wast:2478 +assert_return(() => call($14, "load8_u", [63_679]), 0); + +// memory_copy.wast:2479 +assert_return(() => call($14, "load8_u", [63_878]), 0); + +// memory_copy.wast:2480 +assert_return(() => call($14, "load8_u", [64_077]), 0); + +// memory_copy.wast:2481 +assert_return(() => call($14, "load8_u", [64_276]), 0); + +// memory_copy.wast:2482 +assert_return(() => call($14, "load8_u", [64_475]), 0); + +// memory_copy.wast:2483 +assert_return(() => call($14, "load8_u", [64_674]), 0); + +// memory_copy.wast:2484 +assert_return(() => call($14, "load8_u", [64_873]), 0); + +// memory_copy.wast:2485 +assert_return(() => call($14, "load8_u", [65_072]), 0); + +// memory_copy.wast:2486 +assert_return(() => call($14, "load8_u", [65_271]), 0); + +// memory_copy.wast:2487 +assert_return(() => call($14, "load8_u", [65_470]), 0); + +// memory_copy.wast:2488 +assert_return(() => call($14, "load8_u", [65_516]), 0); + +// memory_copy.wast:2489 +assert_return(() => call($14, "load8_u", [65_517]), 1); + +// memory_copy.wast:2490 +assert_return(() => call($14, "load8_u", [65_518]), 2); + +// memory_copy.wast:2491 +assert_return(() => call($14, "load8_u", [65_519]), 3); + +// memory_copy.wast:2492 +assert_return(() => call($14, "load8_u", [65_520]), 4); + +// memory_copy.wast:2493 +assert_return(() => call($14, "load8_u", [65_521]), 5); + +// memory_copy.wast:2494 +assert_return(() => call($14, "load8_u", [65_522]), 6); + +// memory_copy.wast:2495 +assert_return(() => call($14, "load8_u", [65_523]), 7); + +// memory_copy.wast:2496 +assert_return(() => call($14, "load8_u", [65_524]), 8); + +// memory_copy.wast:2497 +assert_return(() => call($14, "load8_u", [65_525]), 9); + +// memory_copy.wast:2498 +assert_return(() => call($14, "load8_u", [65_526]), 10); + +// memory_copy.wast:2499 +assert_return(() => call($14, "load8_u", [65_527]), 11); + +// memory_copy.wast:2500 +assert_return(() => call($14, "load8_u", [65_528]), 12); + +// memory_copy.wast:2501 +assert_return(() => call($14, "load8_u", [65_529]), 13); + +// memory_copy.wast:2502 +assert_return(() => call($14, "load8_u", [65_530]), 14); + +// memory_copy.wast:2503 +assert_return(() => call($14, "load8_u", [65_531]), 15); + +// memory_copy.wast:2504 +assert_return(() => call($14, "load8_u", [65_532]), 16); + +// memory_copy.wast:2505 +assert_return(() => call($14, "load8_u", [65_533]), 17); + +// memory_copy.wast:2506 +assert_return(() => call($14, "load8_u", [65_534]), 18); + +// memory_copy.wast:2507 +assert_return(() => call($14, "load8_u", [65_535]), 19); + +// memory_copy.wast:2509 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xe2\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2517 +assert_trap(() => call($15, "run", [65_516, 65_506, 40])); + +// memory_copy.wast:2520 +assert_return(() => call($15, "load8_u", [198]), 0); + +// memory_copy.wast:2521 +assert_return(() => call($15, "load8_u", [397]), 0); + +// memory_copy.wast:2522 +assert_return(() => call($15, "load8_u", [596]), 0); + +// memory_copy.wast:2523 +assert_return(() => call($15, "load8_u", [795]), 0); + +// memory_copy.wast:2524 +assert_return(() => call($15, "load8_u", [994]), 0); + +// memory_copy.wast:2525 +assert_return(() => call($15, "load8_u", [1_193]), 0); + +// memory_copy.wast:2526 +assert_return(() => call($15, "load8_u", [1_392]), 0); + +// memory_copy.wast:2527 +assert_return(() => call($15, "load8_u", [1_591]), 0); + +// memory_copy.wast:2528 +assert_return(() => call($15, "load8_u", [1_790]), 0); + +// memory_copy.wast:2529 +assert_return(() => call($15, "load8_u", [1_989]), 0); + +// memory_copy.wast:2530 +assert_return(() => call($15, "load8_u", [2_188]), 0); + +// memory_copy.wast:2531 +assert_return(() => call($15, "load8_u", [2_387]), 0); + +// memory_copy.wast:2532 +assert_return(() => call($15, "load8_u", [2_586]), 0); + +// memory_copy.wast:2533 +assert_return(() => call($15, "load8_u", [2_785]), 0); + +// memory_copy.wast:2534 +assert_return(() => call($15, "load8_u", [2_984]), 0); + +// memory_copy.wast:2535 +assert_return(() => call($15, "load8_u", [3_183]), 0); + +// memory_copy.wast:2536 +assert_return(() => call($15, "load8_u", [3_382]), 0); + +// memory_copy.wast:2537 +assert_return(() => call($15, "load8_u", [3_581]), 0); + +// memory_copy.wast:2538 +assert_return(() => call($15, "load8_u", [3_780]), 0); + +// memory_copy.wast:2539 +assert_return(() => call($15, "load8_u", [3_979]), 0); + +// memory_copy.wast:2540 +assert_return(() => call($15, "load8_u", [4_178]), 0); + +// memory_copy.wast:2541 +assert_return(() => call($15, "load8_u", [4_377]), 0); + +// memory_copy.wast:2542 +assert_return(() => call($15, "load8_u", [4_576]), 0); + +// memory_copy.wast:2543 +assert_return(() => call($15, "load8_u", [4_775]), 0); + +// memory_copy.wast:2544 +assert_return(() => call($15, "load8_u", [4_974]), 0); + +// memory_copy.wast:2545 +assert_return(() => call($15, "load8_u", [5_173]), 0); + +// memory_copy.wast:2546 +assert_return(() => call($15, "load8_u", [5_372]), 0); + +// memory_copy.wast:2547 +assert_return(() => call($15, "load8_u", [5_571]), 0); + +// memory_copy.wast:2548 +assert_return(() => call($15, "load8_u", [5_770]), 0); + +// memory_copy.wast:2549 +assert_return(() => call($15, "load8_u", [5_969]), 0); + +// memory_copy.wast:2550 +assert_return(() => call($15, "load8_u", [6_168]), 0); + +// memory_copy.wast:2551 +assert_return(() => call($15, "load8_u", [6_367]), 0); + +// memory_copy.wast:2552 +assert_return(() => call($15, "load8_u", [6_566]), 0); + +// memory_copy.wast:2553 +assert_return(() => call($15, "load8_u", [6_765]), 0); + +// memory_copy.wast:2554 +assert_return(() => call($15, "load8_u", [6_964]), 0); + +// memory_copy.wast:2555 +assert_return(() => call($15, "load8_u", [7_163]), 0); + +// memory_copy.wast:2556 +assert_return(() => call($15, "load8_u", [7_362]), 0); + +// memory_copy.wast:2557 +assert_return(() => call($15, "load8_u", [7_561]), 0); + +// memory_copy.wast:2558 +assert_return(() => call($15, "load8_u", [7_760]), 0); + +// memory_copy.wast:2559 +assert_return(() => call($15, "load8_u", [7_959]), 0); + +// memory_copy.wast:2560 +assert_return(() => call($15, "load8_u", [8_158]), 0); + +// memory_copy.wast:2561 +assert_return(() => call($15, "load8_u", [8_357]), 0); + +// memory_copy.wast:2562 +assert_return(() => call($15, "load8_u", [8_556]), 0); + +// memory_copy.wast:2563 +assert_return(() => call($15, "load8_u", [8_755]), 0); + +// memory_copy.wast:2564 +assert_return(() => call($15, "load8_u", [8_954]), 0); + +// memory_copy.wast:2565 +assert_return(() => call($15, "load8_u", [9_153]), 0); + +// memory_copy.wast:2566 +assert_return(() => call($15, "load8_u", [9_352]), 0); + +// memory_copy.wast:2567 +assert_return(() => call($15, "load8_u", [9_551]), 0); + +// memory_copy.wast:2568 +assert_return(() => call($15, "load8_u", [9_750]), 0); + +// memory_copy.wast:2569 +assert_return(() => call($15, "load8_u", [9_949]), 0); + +// memory_copy.wast:2570 +assert_return(() => call($15, "load8_u", [10_148]), 0); + +// memory_copy.wast:2571 +assert_return(() => call($15, "load8_u", [10_347]), 0); + +// memory_copy.wast:2572 +assert_return(() => call($15, "load8_u", [10_546]), 0); + +// memory_copy.wast:2573 +assert_return(() => call($15, "load8_u", [10_745]), 0); + +// memory_copy.wast:2574 +assert_return(() => call($15, "load8_u", [10_944]), 0); + +// memory_copy.wast:2575 +assert_return(() => call($15, "load8_u", [11_143]), 0); + +// memory_copy.wast:2576 +assert_return(() => call($15, "load8_u", [11_342]), 0); + +// memory_copy.wast:2577 +assert_return(() => call($15, "load8_u", [11_541]), 0); + +// memory_copy.wast:2578 +assert_return(() => call($15, "load8_u", [11_740]), 0); + +// memory_copy.wast:2579 +assert_return(() => call($15, "load8_u", [11_939]), 0); + +// memory_copy.wast:2580 +assert_return(() => call($15, "load8_u", [12_138]), 0); + +// memory_copy.wast:2581 +assert_return(() => call($15, "load8_u", [12_337]), 0); + +// memory_copy.wast:2582 +assert_return(() => call($15, "load8_u", [12_536]), 0); + +// memory_copy.wast:2583 +assert_return(() => call($15, "load8_u", [12_735]), 0); + +// memory_copy.wast:2584 +assert_return(() => call($15, "load8_u", [12_934]), 0); + +// memory_copy.wast:2585 +assert_return(() => call($15, "load8_u", [13_133]), 0); + +// memory_copy.wast:2586 +assert_return(() => call($15, "load8_u", [13_332]), 0); + +// memory_copy.wast:2587 +assert_return(() => call($15, "load8_u", [13_531]), 0); + +// memory_copy.wast:2588 +assert_return(() => call($15, "load8_u", [13_730]), 0); + +// memory_copy.wast:2589 +assert_return(() => call($15, "load8_u", [13_929]), 0); + +// memory_copy.wast:2590 +assert_return(() => call($15, "load8_u", [14_128]), 0); + +// memory_copy.wast:2591 +assert_return(() => call($15, "load8_u", [14_327]), 0); + +// memory_copy.wast:2592 +assert_return(() => call($15, "load8_u", [14_526]), 0); + +// memory_copy.wast:2593 +assert_return(() => call($15, "load8_u", [14_725]), 0); + +// memory_copy.wast:2594 +assert_return(() => call($15, "load8_u", [14_924]), 0); + +// memory_copy.wast:2595 +assert_return(() => call($15, "load8_u", [15_123]), 0); + +// memory_copy.wast:2596 +assert_return(() => call($15, "load8_u", [15_322]), 0); + +// memory_copy.wast:2597 +assert_return(() => call($15, "load8_u", [15_521]), 0); + +// memory_copy.wast:2598 +assert_return(() => call($15, "load8_u", [15_720]), 0); + +// memory_copy.wast:2599 +assert_return(() => call($15, "load8_u", [15_919]), 0); + +// memory_copy.wast:2600 +assert_return(() => call($15, "load8_u", [16_118]), 0); + +// memory_copy.wast:2601 +assert_return(() => call($15, "load8_u", [16_317]), 0); + +// memory_copy.wast:2602 +assert_return(() => call($15, "load8_u", [16_516]), 0); + +// memory_copy.wast:2603 +assert_return(() => call($15, "load8_u", [16_715]), 0); + +// memory_copy.wast:2604 +assert_return(() => call($15, "load8_u", [16_914]), 0); + +// memory_copy.wast:2605 +assert_return(() => call($15, "load8_u", [17_113]), 0); + +// memory_copy.wast:2606 +assert_return(() => call($15, "load8_u", [17_312]), 0); + +// memory_copy.wast:2607 +assert_return(() => call($15, "load8_u", [17_511]), 0); + +// memory_copy.wast:2608 +assert_return(() => call($15, "load8_u", [17_710]), 0); + +// memory_copy.wast:2609 +assert_return(() => call($15, "load8_u", [17_909]), 0); + +// memory_copy.wast:2610 +assert_return(() => call($15, "load8_u", [18_108]), 0); + +// memory_copy.wast:2611 +assert_return(() => call($15, "load8_u", [18_307]), 0); + +// memory_copy.wast:2612 +assert_return(() => call($15, "load8_u", [18_506]), 0); + +// memory_copy.wast:2613 +assert_return(() => call($15, "load8_u", [18_705]), 0); + +// memory_copy.wast:2614 +assert_return(() => call($15, "load8_u", [18_904]), 0); + +// memory_copy.wast:2615 +assert_return(() => call($15, "load8_u", [19_103]), 0); + +// memory_copy.wast:2616 +assert_return(() => call($15, "load8_u", [19_302]), 0); + +// memory_copy.wast:2617 +assert_return(() => call($15, "load8_u", [19_501]), 0); + +// memory_copy.wast:2618 +assert_return(() => call($15, "load8_u", [19_700]), 0); + +// memory_copy.wast:2619 +assert_return(() => call($15, "load8_u", [19_899]), 0); + +// memory_copy.wast:2620 +assert_return(() => call($15, "load8_u", [20_098]), 0); + +// memory_copy.wast:2621 +assert_return(() => call($15, "load8_u", [20_297]), 0); + +// memory_copy.wast:2622 +assert_return(() => call($15, "load8_u", [20_496]), 0); + +// memory_copy.wast:2623 +assert_return(() => call($15, "load8_u", [20_695]), 0); + +// memory_copy.wast:2624 +assert_return(() => call($15, "load8_u", [20_894]), 0); + +// memory_copy.wast:2625 +assert_return(() => call($15, "load8_u", [21_093]), 0); + +// memory_copy.wast:2626 +assert_return(() => call($15, "load8_u", [21_292]), 0); + +// memory_copy.wast:2627 +assert_return(() => call($15, "load8_u", [21_491]), 0); + +// memory_copy.wast:2628 +assert_return(() => call($15, "load8_u", [21_690]), 0); + +// memory_copy.wast:2629 +assert_return(() => call($15, "load8_u", [21_889]), 0); + +// memory_copy.wast:2630 +assert_return(() => call($15, "load8_u", [22_088]), 0); + +// memory_copy.wast:2631 +assert_return(() => call($15, "load8_u", [22_287]), 0); + +// memory_copy.wast:2632 +assert_return(() => call($15, "load8_u", [22_486]), 0); + +// memory_copy.wast:2633 +assert_return(() => call($15, "load8_u", [22_685]), 0); + +// memory_copy.wast:2634 +assert_return(() => call($15, "load8_u", [22_884]), 0); + +// memory_copy.wast:2635 +assert_return(() => call($15, "load8_u", [23_083]), 0); + +// memory_copy.wast:2636 +assert_return(() => call($15, "load8_u", [23_282]), 0); + +// memory_copy.wast:2637 +assert_return(() => call($15, "load8_u", [23_481]), 0); + +// memory_copy.wast:2638 +assert_return(() => call($15, "load8_u", [23_680]), 0); + +// memory_copy.wast:2639 +assert_return(() => call($15, "load8_u", [23_879]), 0); + +// memory_copy.wast:2640 +assert_return(() => call($15, "load8_u", [24_078]), 0); + +// memory_copy.wast:2641 +assert_return(() => call($15, "load8_u", [24_277]), 0); + +// memory_copy.wast:2642 +assert_return(() => call($15, "load8_u", [24_476]), 0); + +// memory_copy.wast:2643 +assert_return(() => call($15, "load8_u", [24_675]), 0); + +// memory_copy.wast:2644 +assert_return(() => call($15, "load8_u", [24_874]), 0); + +// memory_copy.wast:2645 +assert_return(() => call($15, "load8_u", [25_073]), 0); + +// memory_copy.wast:2646 +assert_return(() => call($15, "load8_u", [25_272]), 0); + +// memory_copy.wast:2647 +assert_return(() => call($15, "load8_u", [25_471]), 0); + +// memory_copy.wast:2648 +assert_return(() => call($15, "load8_u", [25_670]), 0); + +// memory_copy.wast:2649 +assert_return(() => call($15, "load8_u", [25_869]), 0); + +// memory_copy.wast:2650 +assert_return(() => call($15, "load8_u", [26_068]), 0); + +// memory_copy.wast:2651 +assert_return(() => call($15, "load8_u", [26_267]), 0); + +// memory_copy.wast:2652 +assert_return(() => call($15, "load8_u", [26_466]), 0); + +// memory_copy.wast:2653 +assert_return(() => call($15, "load8_u", [26_665]), 0); + +// memory_copy.wast:2654 +assert_return(() => call($15, "load8_u", [26_864]), 0); + +// memory_copy.wast:2655 +assert_return(() => call($15, "load8_u", [27_063]), 0); + +// memory_copy.wast:2656 +assert_return(() => call($15, "load8_u", [27_262]), 0); + +// memory_copy.wast:2657 +assert_return(() => call($15, "load8_u", [27_461]), 0); + +// memory_copy.wast:2658 +assert_return(() => call($15, "load8_u", [27_660]), 0); + +// memory_copy.wast:2659 +assert_return(() => call($15, "load8_u", [27_859]), 0); + +// memory_copy.wast:2660 +assert_return(() => call($15, "load8_u", [28_058]), 0); + +// memory_copy.wast:2661 +assert_return(() => call($15, "load8_u", [28_257]), 0); + +// memory_copy.wast:2662 +assert_return(() => call($15, "load8_u", [28_456]), 0); + +// memory_copy.wast:2663 +assert_return(() => call($15, "load8_u", [28_655]), 0); + +// memory_copy.wast:2664 +assert_return(() => call($15, "load8_u", [28_854]), 0); + +// memory_copy.wast:2665 +assert_return(() => call($15, "load8_u", [29_053]), 0); + +// memory_copy.wast:2666 +assert_return(() => call($15, "load8_u", [29_252]), 0); + +// memory_copy.wast:2667 +assert_return(() => call($15, "load8_u", [29_451]), 0); + +// memory_copy.wast:2668 +assert_return(() => call($15, "load8_u", [29_650]), 0); + +// memory_copy.wast:2669 +assert_return(() => call($15, "load8_u", [29_849]), 0); + +// memory_copy.wast:2670 +assert_return(() => call($15, "load8_u", [30_048]), 0); + +// memory_copy.wast:2671 +assert_return(() => call($15, "load8_u", [30_247]), 0); + +// memory_copy.wast:2672 +assert_return(() => call($15, "load8_u", [30_446]), 0); + +// memory_copy.wast:2673 +assert_return(() => call($15, "load8_u", [30_645]), 0); + +// memory_copy.wast:2674 +assert_return(() => call($15, "load8_u", [30_844]), 0); + +// memory_copy.wast:2675 +assert_return(() => call($15, "load8_u", [31_043]), 0); + +// memory_copy.wast:2676 +assert_return(() => call($15, "load8_u", [31_242]), 0); + +// memory_copy.wast:2677 +assert_return(() => call($15, "load8_u", [31_441]), 0); + +// memory_copy.wast:2678 +assert_return(() => call($15, "load8_u", [31_640]), 0); + +// memory_copy.wast:2679 +assert_return(() => call($15, "load8_u", [31_839]), 0); + +// memory_copy.wast:2680 +assert_return(() => call($15, "load8_u", [32_038]), 0); + +// memory_copy.wast:2681 +assert_return(() => call($15, "load8_u", [32_237]), 0); + +// memory_copy.wast:2682 +assert_return(() => call($15, "load8_u", [32_436]), 0); + +// memory_copy.wast:2683 +assert_return(() => call($15, "load8_u", [32_635]), 0); + +// memory_copy.wast:2684 +assert_return(() => call($15, "load8_u", [32_834]), 0); + +// memory_copy.wast:2685 +assert_return(() => call($15, "load8_u", [33_033]), 0); + +// memory_copy.wast:2686 +assert_return(() => call($15, "load8_u", [33_232]), 0); + +// memory_copy.wast:2687 +assert_return(() => call($15, "load8_u", [33_431]), 0); + +// memory_copy.wast:2688 +assert_return(() => call($15, "load8_u", [33_630]), 0); + +// memory_copy.wast:2689 +assert_return(() => call($15, "load8_u", [33_829]), 0); + +// memory_copy.wast:2690 +assert_return(() => call($15, "load8_u", [34_028]), 0); + +// memory_copy.wast:2691 +assert_return(() => call($15, "load8_u", [34_227]), 0); + +// memory_copy.wast:2692 +assert_return(() => call($15, "load8_u", [34_426]), 0); + +// memory_copy.wast:2693 +assert_return(() => call($15, "load8_u", [34_625]), 0); + +// memory_copy.wast:2694 +assert_return(() => call($15, "load8_u", [34_824]), 0); + +// memory_copy.wast:2695 +assert_return(() => call($15, "load8_u", [35_023]), 0); + +// memory_copy.wast:2696 +assert_return(() => call($15, "load8_u", [35_222]), 0); + +// memory_copy.wast:2697 +assert_return(() => call($15, "load8_u", [35_421]), 0); + +// memory_copy.wast:2698 +assert_return(() => call($15, "load8_u", [35_620]), 0); + +// memory_copy.wast:2699 +assert_return(() => call($15, "load8_u", [35_819]), 0); + +// memory_copy.wast:2700 +assert_return(() => call($15, "load8_u", [36_018]), 0); + +// memory_copy.wast:2701 +assert_return(() => call($15, "load8_u", [36_217]), 0); + +// memory_copy.wast:2702 +assert_return(() => call($15, "load8_u", [36_416]), 0); + +// memory_copy.wast:2703 +assert_return(() => call($15, "load8_u", [36_615]), 0); + +// memory_copy.wast:2704 +assert_return(() => call($15, "load8_u", [36_814]), 0); + +// memory_copy.wast:2705 +assert_return(() => call($15, "load8_u", [37_013]), 0); + +// memory_copy.wast:2706 +assert_return(() => call($15, "load8_u", [37_212]), 0); + +// memory_copy.wast:2707 +assert_return(() => call($15, "load8_u", [37_411]), 0); + +// memory_copy.wast:2708 +assert_return(() => call($15, "load8_u", [37_610]), 0); + +// memory_copy.wast:2709 +assert_return(() => call($15, "load8_u", [37_809]), 0); + +// memory_copy.wast:2710 +assert_return(() => call($15, "load8_u", [38_008]), 0); + +// memory_copy.wast:2711 +assert_return(() => call($15, "load8_u", [38_207]), 0); + +// memory_copy.wast:2712 +assert_return(() => call($15, "load8_u", [38_406]), 0); + +// memory_copy.wast:2713 +assert_return(() => call($15, "load8_u", [38_605]), 0); + +// memory_copy.wast:2714 +assert_return(() => call($15, "load8_u", [38_804]), 0); + +// memory_copy.wast:2715 +assert_return(() => call($15, "load8_u", [39_003]), 0); + +// memory_copy.wast:2716 +assert_return(() => call($15, "load8_u", [39_202]), 0); + +// memory_copy.wast:2717 +assert_return(() => call($15, "load8_u", [39_401]), 0); + +// memory_copy.wast:2718 +assert_return(() => call($15, "load8_u", [39_600]), 0); + +// memory_copy.wast:2719 +assert_return(() => call($15, "load8_u", [39_799]), 0); + +// memory_copy.wast:2720 +assert_return(() => call($15, "load8_u", [39_998]), 0); + +// memory_copy.wast:2721 +assert_return(() => call($15, "load8_u", [40_197]), 0); + +// memory_copy.wast:2722 +assert_return(() => call($15, "load8_u", [40_396]), 0); + +// memory_copy.wast:2723 +assert_return(() => call($15, "load8_u", [40_595]), 0); + +// memory_copy.wast:2724 +assert_return(() => call($15, "load8_u", [40_794]), 0); + +// memory_copy.wast:2725 +assert_return(() => call($15, "load8_u", [40_993]), 0); + +// memory_copy.wast:2726 +assert_return(() => call($15, "load8_u", [41_192]), 0); + +// memory_copy.wast:2727 +assert_return(() => call($15, "load8_u", [41_391]), 0); + +// memory_copy.wast:2728 +assert_return(() => call($15, "load8_u", [41_590]), 0); + +// memory_copy.wast:2729 +assert_return(() => call($15, "load8_u", [41_789]), 0); + +// memory_copy.wast:2730 +assert_return(() => call($15, "load8_u", [41_988]), 0); + +// memory_copy.wast:2731 +assert_return(() => call($15, "load8_u", [42_187]), 0); + +// memory_copy.wast:2732 +assert_return(() => call($15, "load8_u", [42_386]), 0); + +// memory_copy.wast:2733 +assert_return(() => call($15, "load8_u", [42_585]), 0); + +// memory_copy.wast:2734 +assert_return(() => call($15, "load8_u", [42_784]), 0); + +// memory_copy.wast:2735 +assert_return(() => call($15, "load8_u", [42_983]), 0); + +// memory_copy.wast:2736 +assert_return(() => call($15, "load8_u", [43_182]), 0); + +// memory_copy.wast:2737 +assert_return(() => call($15, "load8_u", [43_381]), 0); + +// memory_copy.wast:2738 +assert_return(() => call($15, "load8_u", [43_580]), 0); + +// memory_copy.wast:2739 +assert_return(() => call($15, "load8_u", [43_779]), 0); + +// memory_copy.wast:2740 +assert_return(() => call($15, "load8_u", [43_978]), 0); + +// memory_copy.wast:2741 +assert_return(() => call($15, "load8_u", [44_177]), 0); + +// memory_copy.wast:2742 +assert_return(() => call($15, "load8_u", [44_376]), 0); + +// memory_copy.wast:2743 +assert_return(() => call($15, "load8_u", [44_575]), 0); + +// memory_copy.wast:2744 +assert_return(() => call($15, "load8_u", [44_774]), 0); + +// memory_copy.wast:2745 +assert_return(() => call($15, "load8_u", [44_973]), 0); + +// memory_copy.wast:2746 +assert_return(() => call($15, "load8_u", [45_172]), 0); + +// memory_copy.wast:2747 +assert_return(() => call($15, "load8_u", [45_371]), 0); + +// memory_copy.wast:2748 +assert_return(() => call($15, "load8_u", [45_570]), 0); + +// memory_copy.wast:2749 +assert_return(() => call($15, "load8_u", [45_769]), 0); + +// memory_copy.wast:2750 +assert_return(() => call($15, "load8_u", [45_968]), 0); + +// memory_copy.wast:2751 +assert_return(() => call($15, "load8_u", [46_167]), 0); + +// memory_copy.wast:2752 +assert_return(() => call($15, "load8_u", [46_366]), 0); + +// memory_copy.wast:2753 +assert_return(() => call($15, "load8_u", [46_565]), 0); + +// memory_copy.wast:2754 +assert_return(() => call($15, "load8_u", [46_764]), 0); + +// memory_copy.wast:2755 +assert_return(() => call($15, "load8_u", [46_963]), 0); + +// memory_copy.wast:2756 +assert_return(() => call($15, "load8_u", [47_162]), 0); + +// memory_copy.wast:2757 +assert_return(() => call($15, "load8_u", [47_361]), 0); + +// memory_copy.wast:2758 +assert_return(() => call($15, "load8_u", [47_560]), 0); + +// memory_copy.wast:2759 +assert_return(() => call($15, "load8_u", [47_759]), 0); + +// memory_copy.wast:2760 +assert_return(() => call($15, "load8_u", [47_958]), 0); + +// memory_copy.wast:2761 +assert_return(() => call($15, "load8_u", [48_157]), 0); + +// memory_copy.wast:2762 +assert_return(() => call($15, "load8_u", [48_356]), 0); + +// memory_copy.wast:2763 +assert_return(() => call($15, "load8_u", [48_555]), 0); + +// memory_copy.wast:2764 +assert_return(() => call($15, "load8_u", [48_754]), 0); + +// memory_copy.wast:2765 +assert_return(() => call($15, "load8_u", [48_953]), 0); + +// memory_copy.wast:2766 +assert_return(() => call($15, "load8_u", [49_152]), 0); + +// memory_copy.wast:2767 +assert_return(() => call($15, "load8_u", [49_351]), 0); + +// memory_copy.wast:2768 +assert_return(() => call($15, "load8_u", [49_550]), 0); + +// memory_copy.wast:2769 +assert_return(() => call($15, "load8_u", [49_749]), 0); + +// memory_copy.wast:2770 +assert_return(() => call($15, "load8_u", [49_948]), 0); + +// memory_copy.wast:2771 +assert_return(() => call($15, "load8_u", [50_147]), 0); + +// memory_copy.wast:2772 +assert_return(() => call($15, "load8_u", [50_346]), 0); + +// memory_copy.wast:2773 +assert_return(() => call($15, "load8_u", [50_545]), 0); + +// memory_copy.wast:2774 +assert_return(() => call($15, "load8_u", [50_744]), 0); + +// memory_copy.wast:2775 +assert_return(() => call($15, "load8_u", [50_943]), 0); + +// memory_copy.wast:2776 +assert_return(() => call($15, "load8_u", [51_142]), 0); + +// memory_copy.wast:2777 +assert_return(() => call($15, "load8_u", [51_341]), 0); + +// memory_copy.wast:2778 +assert_return(() => call($15, "load8_u", [51_540]), 0); + +// memory_copy.wast:2779 +assert_return(() => call($15, "load8_u", [51_739]), 0); + +// memory_copy.wast:2780 +assert_return(() => call($15, "load8_u", [51_938]), 0); + +// memory_copy.wast:2781 +assert_return(() => call($15, "load8_u", [52_137]), 0); + +// memory_copy.wast:2782 +assert_return(() => call($15, "load8_u", [52_336]), 0); + +// memory_copy.wast:2783 +assert_return(() => call($15, "load8_u", [52_535]), 0); + +// memory_copy.wast:2784 +assert_return(() => call($15, "load8_u", [52_734]), 0); + +// memory_copy.wast:2785 +assert_return(() => call($15, "load8_u", [52_933]), 0); + +// memory_copy.wast:2786 +assert_return(() => call($15, "load8_u", [53_132]), 0); + +// memory_copy.wast:2787 +assert_return(() => call($15, "load8_u", [53_331]), 0); + +// memory_copy.wast:2788 +assert_return(() => call($15, "load8_u", [53_530]), 0); + +// memory_copy.wast:2789 +assert_return(() => call($15, "load8_u", [53_729]), 0); + +// memory_copy.wast:2790 +assert_return(() => call($15, "load8_u", [53_928]), 0); + +// memory_copy.wast:2791 +assert_return(() => call($15, "load8_u", [54_127]), 0); + +// memory_copy.wast:2792 +assert_return(() => call($15, "load8_u", [54_326]), 0); + +// memory_copy.wast:2793 +assert_return(() => call($15, "load8_u", [54_525]), 0); + +// memory_copy.wast:2794 +assert_return(() => call($15, "load8_u", [54_724]), 0); + +// memory_copy.wast:2795 +assert_return(() => call($15, "load8_u", [54_923]), 0); + +// memory_copy.wast:2796 +assert_return(() => call($15, "load8_u", [55_122]), 0); + +// memory_copy.wast:2797 +assert_return(() => call($15, "load8_u", [55_321]), 0); + +// memory_copy.wast:2798 +assert_return(() => call($15, "load8_u", [55_520]), 0); + +// memory_copy.wast:2799 +assert_return(() => call($15, "load8_u", [55_719]), 0); + +// memory_copy.wast:2800 +assert_return(() => call($15, "load8_u", [55_918]), 0); + +// memory_copy.wast:2801 +assert_return(() => call($15, "load8_u", [56_117]), 0); + +// memory_copy.wast:2802 +assert_return(() => call($15, "load8_u", [56_316]), 0); + +// memory_copy.wast:2803 +assert_return(() => call($15, "load8_u", [56_515]), 0); + +// memory_copy.wast:2804 +assert_return(() => call($15, "load8_u", [56_714]), 0); + +// memory_copy.wast:2805 +assert_return(() => call($15, "load8_u", [56_913]), 0); + +// memory_copy.wast:2806 +assert_return(() => call($15, "load8_u", [57_112]), 0); + +// memory_copy.wast:2807 +assert_return(() => call($15, "load8_u", [57_311]), 0); + +// memory_copy.wast:2808 +assert_return(() => call($15, "load8_u", [57_510]), 0); + +// memory_copy.wast:2809 +assert_return(() => call($15, "load8_u", [57_709]), 0); + +// memory_copy.wast:2810 +assert_return(() => call($15, "load8_u", [57_908]), 0); + +// memory_copy.wast:2811 +assert_return(() => call($15, "load8_u", [58_107]), 0); + +// memory_copy.wast:2812 +assert_return(() => call($15, "load8_u", [58_306]), 0); + +// memory_copy.wast:2813 +assert_return(() => call($15, "load8_u", [58_505]), 0); + +// memory_copy.wast:2814 +assert_return(() => call($15, "load8_u", [58_704]), 0); + +// memory_copy.wast:2815 +assert_return(() => call($15, "load8_u", [58_903]), 0); + +// memory_copy.wast:2816 +assert_return(() => call($15, "load8_u", [59_102]), 0); + +// memory_copy.wast:2817 +assert_return(() => call($15, "load8_u", [59_301]), 0); + +// memory_copy.wast:2818 +assert_return(() => call($15, "load8_u", [59_500]), 0); + +// memory_copy.wast:2819 +assert_return(() => call($15, "load8_u", [59_699]), 0); + +// memory_copy.wast:2820 +assert_return(() => call($15, "load8_u", [59_898]), 0); + +// memory_copy.wast:2821 +assert_return(() => call($15, "load8_u", [60_097]), 0); + +// memory_copy.wast:2822 +assert_return(() => call($15, "load8_u", [60_296]), 0); + +// memory_copy.wast:2823 +assert_return(() => call($15, "load8_u", [60_495]), 0); + +// memory_copy.wast:2824 +assert_return(() => call($15, "load8_u", [60_694]), 0); + +// memory_copy.wast:2825 +assert_return(() => call($15, "load8_u", [60_893]), 0); + +// memory_copy.wast:2826 +assert_return(() => call($15, "load8_u", [61_092]), 0); + +// memory_copy.wast:2827 +assert_return(() => call($15, "load8_u", [61_291]), 0); + +// memory_copy.wast:2828 +assert_return(() => call($15, "load8_u", [61_490]), 0); + +// memory_copy.wast:2829 +assert_return(() => call($15, "load8_u", [61_689]), 0); + +// memory_copy.wast:2830 +assert_return(() => call($15, "load8_u", [61_888]), 0); + +// memory_copy.wast:2831 +assert_return(() => call($15, "load8_u", [62_087]), 0); + +// memory_copy.wast:2832 +assert_return(() => call($15, "load8_u", [62_286]), 0); + +// memory_copy.wast:2833 +assert_return(() => call($15, "load8_u", [62_485]), 0); + +// memory_copy.wast:2834 +assert_return(() => call($15, "load8_u", [62_684]), 0); + +// memory_copy.wast:2835 +assert_return(() => call($15, "load8_u", [62_883]), 0); + +// memory_copy.wast:2836 +assert_return(() => call($15, "load8_u", [63_082]), 0); + +// memory_copy.wast:2837 +assert_return(() => call($15, "load8_u", [63_281]), 0); + +// memory_copy.wast:2838 +assert_return(() => call($15, "load8_u", [63_480]), 0); + +// memory_copy.wast:2839 +assert_return(() => call($15, "load8_u", [63_679]), 0); + +// memory_copy.wast:2840 +assert_return(() => call($15, "load8_u", [63_878]), 0); + +// memory_copy.wast:2841 +assert_return(() => call($15, "load8_u", [64_077]), 0); + +// memory_copy.wast:2842 +assert_return(() => call($15, "load8_u", [64_276]), 0); + +// memory_copy.wast:2843 +assert_return(() => call($15, "load8_u", [64_475]), 0); + +// memory_copy.wast:2844 +assert_return(() => call($15, "load8_u", [64_674]), 0); + +// memory_copy.wast:2845 +assert_return(() => call($15, "load8_u", [64_873]), 0); + +// memory_copy.wast:2846 +assert_return(() => call($15, "load8_u", [65_072]), 0); + +// memory_copy.wast:2847 +assert_return(() => call($15, "load8_u", [65_271]), 0); + +// memory_copy.wast:2848 +assert_return(() => call($15, "load8_u", [65_470]), 0); + +// memory_copy.wast:2849 +assert_return(() => call($15, "load8_u", [65_506]), 0); + +// memory_copy.wast:2850 +assert_return(() => call($15, "load8_u", [65_507]), 1); + +// memory_copy.wast:2851 +assert_return(() => call($15, "load8_u", [65_508]), 2); + +// memory_copy.wast:2852 +assert_return(() => call($15, "load8_u", [65_509]), 3); + +// memory_copy.wast:2853 +assert_return(() => call($15, "load8_u", [65_510]), 4); + +// memory_copy.wast:2854 +assert_return(() => call($15, "load8_u", [65_511]), 5); + +// memory_copy.wast:2855 +assert_return(() => call($15, "load8_u", [65_512]), 6); + +// memory_copy.wast:2856 +assert_return(() => call($15, "load8_u", [65_513]), 7); + +// memory_copy.wast:2857 +assert_return(() => call($15, "load8_u", [65_514]), 8); + +// memory_copy.wast:2858 +assert_return(() => call($15, "load8_u", [65_515]), 9); + +// memory_copy.wast:2859 +assert_return(() => call($15, "load8_u", [65_516]), 10); + +// memory_copy.wast:2860 +assert_return(() => call($15, "load8_u", [65_517]), 11); + +// memory_copy.wast:2861 +assert_return(() => call($15, "load8_u", [65_518]), 12); + +// memory_copy.wast:2862 +assert_return(() => call($15, "load8_u", [65_519]), 13); + +// memory_copy.wast:2863 +assert_return(() => call($15, "load8_u", [65_520]), 14); + +// memory_copy.wast:2864 +assert_return(() => call($15, "load8_u", [65_521]), 15); + +// memory_copy.wast:2865 +assert_return(() => call($15, "load8_u", [65_522]), 16); + +// memory_copy.wast:2866 +assert_return(() => call($15, "load8_u", [65_523]), 17); + +// memory_copy.wast:2867 +assert_return(() => call($15, "load8_u", [65_524]), 18); + +// memory_copy.wast:2868 +assert_return(() => call($15, "load8_u", [65_525]), 19); + +// memory_copy.wast:2870 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2878 +assert_trap(() => call($16, "run", [65_506, 65_516, 40])); + +// memory_copy.wast:2881 +assert_return(() => call($16, "load8_u", [198]), 0); + +// memory_copy.wast:2882 +assert_return(() => call($16, "load8_u", [397]), 0); + +// memory_copy.wast:2883 +assert_return(() => call($16, "load8_u", [596]), 0); + +// memory_copy.wast:2884 +assert_return(() => call($16, "load8_u", [795]), 0); + +// memory_copy.wast:2885 +assert_return(() => call($16, "load8_u", [994]), 0); + +// memory_copy.wast:2886 +assert_return(() => call($16, "load8_u", [1_193]), 0); + +// memory_copy.wast:2887 +assert_return(() => call($16, "load8_u", [1_392]), 0); + +// memory_copy.wast:2888 +assert_return(() => call($16, "load8_u", [1_591]), 0); + +// memory_copy.wast:2889 +assert_return(() => call($16, "load8_u", [1_790]), 0); + +// memory_copy.wast:2890 +assert_return(() => call($16, "load8_u", [1_989]), 0); + +// memory_copy.wast:2891 +assert_return(() => call($16, "load8_u", [2_188]), 0); + +// memory_copy.wast:2892 +assert_return(() => call($16, "load8_u", [2_387]), 0); + +// memory_copy.wast:2893 +assert_return(() => call($16, "load8_u", [2_586]), 0); + +// memory_copy.wast:2894 +assert_return(() => call($16, "load8_u", [2_785]), 0); + +// memory_copy.wast:2895 +assert_return(() => call($16, "load8_u", [2_984]), 0); + +// memory_copy.wast:2896 +assert_return(() => call($16, "load8_u", [3_183]), 0); + +// memory_copy.wast:2897 +assert_return(() => call($16, "load8_u", [3_382]), 0); + +// memory_copy.wast:2898 +assert_return(() => call($16, "load8_u", [3_581]), 0); + +// memory_copy.wast:2899 +assert_return(() => call($16, "load8_u", [3_780]), 0); + +// memory_copy.wast:2900 +assert_return(() => call($16, "load8_u", [3_979]), 0); + +// memory_copy.wast:2901 +assert_return(() => call($16, "load8_u", [4_178]), 0); + +// memory_copy.wast:2902 +assert_return(() => call($16, "load8_u", [4_377]), 0); + +// memory_copy.wast:2903 +assert_return(() => call($16, "load8_u", [4_576]), 0); + +// memory_copy.wast:2904 +assert_return(() => call($16, "load8_u", [4_775]), 0); + +// memory_copy.wast:2905 +assert_return(() => call($16, "load8_u", [4_974]), 0); + +// memory_copy.wast:2906 +assert_return(() => call($16, "load8_u", [5_173]), 0); + +// memory_copy.wast:2907 +assert_return(() => call($16, "load8_u", [5_372]), 0); + +// memory_copy.wast:2908 +assert_return(() => call($16, "load8_u", [5_571]), 0); + +// memory_copy.wast:2909 +assert_return(() => call($16, "load8_u", [5_770]), 0); + +// memory_copy.wast:2910 +assert_return(() => call($16, "load8_u", [5_969]), 0); + +// memory_copy.wast:2911 +assert_return(() => call($16, "load8_u", [6_168]), 0); + +// memory_copy.wast:2912 +assert_return(() => call($16, "load8_u", [6_367]), 0); + +// memory_copy.wast:2913 +assert_return(() => call($16, "load8_u", [6_566]), 0); + +// memory_copy.wast:2914 +assert_return(() => call($16, "load8_u", [6_765]), 0); + +// memory_copy.wast:2915 +assert_return(() => call($16, "load8_u", [6_964]), 0); + +// memory_copy.wast:2916 +assert_return(() => call($16, "load8_u", [7_163]), 0); + +// memory_copy.wast:2917 +assert_return(() => call($16, "load8_u", [7_362]), 0); + +// memory_copy.wast:2918 +assert_return(() => call($16, "load8_u", [7_561]), 0); + +// memory_copy.wast:2919 +assert_return(() => call($16, "load8_u", [7_760]), 0); + +// memory_copy.wast:2920 +assert_return(() => call($16, "load8_u", [7_959]), 0); + +// memory_copy.wast:2921 +assert_return(() => call($16, "load8_u", [8_158]), 0); + +// memory_copy.wast:2922 +assert_return(() => call($16, "load8_u", [8_357]), 0); + +// memory_copy.wast:2923 +assert_return(() => call($16, "load8_u", [8_556]), 0); + +// memory_copy.wast:2924 +assert_return(() => call($16, "load8_u", [8_755]), 0); + +// memory_copy.wast:2925 +assert_return(() => call($16, "load8_u", [8_954]), 0); + +// memory_copy.wast:2926 +assert_return(() => call($16, "load8_u", [9_153]), 0); + +// memory_copy.wast:2927 +assert_return(() => call($16, "load8_u", [9_352]), 0); + +// memory_copy.wast:2928 +assert_return(() => call($16, "load8_u", [9_551]), 0); + +// memory_copy.wast:2929 +assert_return(() => call($16, "load8_u", [9_750]), 0); + +// memory_copy.wast:2930 +assert_return(() => call($16, "load8_u", [9_949]), 0); + +// memory_copy.wast:2931 +assert_return(() => call($16, "load8_u", [10_148]), 0); + +// memory_copy.wast:2932 +assert_return(() => call($16, "load8_u", [10_347]), 0); + +// memory_copy.wast:2933 +assert_return(() => call($16, "load8_u", [10_546]), 0); + +// memory_copy.wast:2934 +assert_return(() => call($16, "load8_u", [10_745]), 0); + +// memory_copy.wast:2935 +assert_return(() => call($16, "load8_u", [10_944]), 0); + +// memory_copy.wast:2936 +assert_return(() => call($16, "load8_u", [11_143]), 0); + +// memory_copy.wast:2937 +assert_return(() => call($16, "load8_u", [11_342]), 0); + +// memory_copy.wast:2938 +assert_return(() => call($16, "load8_u", [11_541]), 0); + +// memory_copy.wast:2939 +assert_return(() => call($16, "load8_u", [11_740]), 0); + +// memory_copy.wast:2940 +assert_return(() => call($16, "load8_u", [11_939]), 0); + +// memory_copy.wast:2941 +assert_return(() => call($16, "load8_u", [12_138]), 0); + +// memory_copy.wast:2942 +assert_return(() => call($16, "load8_u", [12_337]), 0); + +// memory_copy.wast:2943 +assert_return(() => call($16, "load8_u", [12_536]), 0); + +// memory_copy.wast:2944 +assert_return(() => call($16, "load8_u", [12_735]), 0); + +// memory_copy.wast:2945 +assert_return(() => call($16, "load8_u", [12_934]), 0); + +// memory_copy.wast:2946 +assert_return(() => call($16, "load8_u", [13_133]), 0); + +// memory_copy.wast:2947 +assert_return(() => call($16, "load8_u", [13_332]), 0); + +// memory_copy.wast:2948 +assert_return(() => call($16, "load8_u", [13_531]), 0); + +// memory_copy.wast:2949 +assert_return(() => call($16, "load8_u", [13_730]), 0); + +// memory_copy.wast:2950 +assert_return(() => call($16, "load8_u", [13_929]), 0); + +// memory_copy.wast:2951 +assert_return(() => call($16, "load8_u", [14_128]), 0); + +// memory_copy.wast:2952 +assert_return(() => call($16, "load8_u", [14_327]), 0); + +// memory_copy.wast:2953 +assert_return(() => call($16, "load8_u", [14_526]), 0); + +// memory_copy.wast:2954 +assert_return(() => call($16, "load8_u", [14_725]), 0); + +// memory_copy.wast:2955 +assert_return(() => call($16, "load8_u", [14_924]), 0); + +// memory_copy.wast:2956 +assert_return(() => call($16, "load8_u", [15_123]), 0); + +// memory_copy.wast:2957 +assert_return(() => call($16, "load8_u", [15_322]), 0); + +// memory_copy.wast:2958 +assert_return(() => call($16, "load8_u", [15_521]), 0); + +// memory_copy.wast:2959 +assert_return(() => call($16, "load8_u", [15_720]), 0); + +// memory_copy.wast:2960 +assert_return(() => call($16, "load8_u", [15_919]), 0); + +// memory_copy.wast:2961 +assert_return(() => call($16, "load8_u", [16_118]), 0); + +// memory_copy.wast:2962 +assert_return(() => call($16, "load8_u", [16_317]), 0); + +// memory_copy.wast:2963 +assert_return(() => call($16, "load8_u", [16_516]), 0); + +// memory_copy.wast:2964 +assert_return(() => call($16, "load8_u", [16_715]), 0); + +// memory_copy.wast:2965 +assert_return(() => call($16, "load8_u", [16_914]), 0); + +// memory_copy.wast:2966 +assert_return(() => call($16, "load8_u", [17_113]), 0); + +// memory_copy.wast:2967 +assert_return(() => call($16, "load8_u", [17_312]), 0); + +// memory_copy.wast:2968 +assert_return(() => call($16, "load8_u", [17_511]), 0); + +// memory_copy.wast:2969 +assert_return(() => call($16, "load8_u", [17_710]), 0); + +// memory_copy.wast:2970 +assert_return(() => call($16, "load8_u", [17_909]), 0); + +// memory_copy.wast:2971 +assert_return(() => call($16, "load8_u", [18_108]), 0); + +// memory_copy.wast:2972 +assert_return(() => call($16, "load8_u", [18_307]), 0); + +// memory_copy.wast:2973 +assert_return(() => call($16, "load8_u", [18_506]), 0); + +// memory_copy.wast:2974 +assert_return(() => call($16, "load8_u", [18_705]), 0); + +// memory_copy.wast:2975 +assert_return(() => call($16, "load8_u", [18_904]), 0); + +// memory_copy.wast:2976 +assert_return(() => call($16, "load8_u", [19_103]), 0); + +// memory_copy.wast:2977 +assert_return(() => call($16, "load8_u", [19_302]), 0); + +// memory_copy.wast:2978 +assert_return(() => call($16, "load8_u", [19_501]), 0); + +// memory_copy.wast:2979 +assert_return(() => call($16, "load8_u", [19_700]), 0); + +// memory_copy.wast:2980 +assert_return(() => call($16, "load8_u", [19_899]), 0); + +// memory_copy.wast:2981 +assert_return(() => call($16, "load8_u", [20_098]), 0); + +// memory_copy.wast:2982 +assert_return(() => call($16, "load8_u", [20_297]), 0); + +// memory_copy.wast:2983 +assert_return(() => call($16, "load8_u", [20_496]), 0); + +// memory_copy.wast:2984 +assert_return(() => call($16, "load8_u", [20_695]), 0); + +// memory_copy.wast:2985 +assert_return(() => call($16, "load8_u", [20_894]), 0); + +// memory_copy.wast:2986 +assert_return(() => call($16, "load8_u", [21_093]), 0); + +// memory_copy.wast:2987 +assert_return(() => call($16, "load8_u", [21_292]), 0); + +// memory_copy.wast:2988 +assert_return(() => call($16, "load8_u", [21_491]), 0); + +// memory_copy.wast:2989 +assert_return(() => call($16, "load8_u", [21_690]), 0); + +// memory_copy.wast:2990 +assert_return(() => call($16, "load8_u", [21_889]), 0); + +// memory_copy.wast:2991 +assert_return(() => call($16, "load8_u", [22_088]), 0); + +// memory_copy.wast:2992 +assert_return(() => call($16, "load8_u", [22_287]), 0); + +// memory_copy.wast:2993 +assert_return(() => call($16, "load8_u", [22_486]), 0); + +// memory_copy.wast:2994 +assert_return(() => call($16, "load8_u", [22_685]), 0); + +// memory_copy.wast:2995 +assert_return(() => call($16, "load8_u", [22_884]), 0); + +// memory_copy.wast:2996 +assert_return(() => call($16, "load8_u", [23_083]), 0); + +// memory_copy.wast:2997 +assert_return(() => call($16, "load8_u", [23_282]), 0); + +// memory_copy.wast:2998 +assert_return(() => call($16, "load8_u", [23_481]), 0); + +// memory_copy.wast:2999 +assert_return(() => call($16, "load8_u", [23_680]), 0); + +// memory_copy.wast:3000 +assert_return(() => call($16, "load8_u", [23_879]), 0); + +// memory_copy.wast:3001 +assert_return(() => call($16, "load8_u", [24_078]), 0); + +// memory_copy.wast:3002 +assert_return(() => call($16, "load8_u", [24_277]), 0); + +// memory_copy.wast:3003 +assert_return(() => call($16, "load8_u", [24_476]), 0); + +// memory_copy.wast:3004 +assert_return(() => call($16, "load8_u", [24_675]), 0); + +// memory_copy.wast:3005 +assert_return(() => call($16, "load8_u", [24_874]), 0); + +// memory_copy.wast:3006 +assert_return(() => call($16, "load8_u", [25_073]), 0); + +// memory_copy.wast:3007 +assert_return(() => call($16, "load8_u", [25_272]), 0); + +// memory_copy.wast:3008 +assert_return(() => call($16, "load8_u", [25_471]), 0); + +// memory_copy.wast:3009 +assert_return(() => call($16, "load8_u", [25_670]), 0); + +// memory_copy.wast:3010 +assert_return(() => call($16, "load8_u", [25_869]), 0); + +// memory_copy.wast:3011 +assert_return(() => call($16, "load8_u", [26_068]), 0); + +// memory_copy.wast:3012 +assert_return(() => call($16, "load8_u", [26_267]), 0); + +// memory_copy.wast:3013 +assert_return(() => call($16, "load8_u", [26_466]), 0); + +// memory_copy.wast:3014 +assert_return(() => call($16, "load8_u", [26_665]), 0); + +// memory_copy.wast:3015 +assert_return(() => call($16, "load8_u", [26_864]), 0); + +// memory_copy.wast:3016 +assert_return(() => call($16, "load8_u", [27_063]), 0); + +// memory_copy.wast:3017 +assert_return(() => call($16, "load8_u", [27_262]), 0); + +// memory_copy.wast:3018 +assert_return(() => call($16, "load8_u", [27_461]), 0); + +// memory_copy.wast:3019 +assert_return(() => call($16, "load8_u", [27_660]), 0); + +// memory_copy.wast:3020 +assert_return(() => call($16, "load8_u", [27_859]), 0); + +// memory_copy.wast:3021 +assert_return(() => call($16, "load8_u", [28_058]), 0); + +// memory_copy.wast:3022 +assert_return(() => call($16, "load8_u", [28_257]), 0); + +// memory_copy.wast:3023 +assert_return(() => call($16, "load8_u", [28_456]), 0); + +// memory_copy.wast:3024 +assert_return(() => call($16, "load8_u", [28_655]), 0); + +// memory_copy.wast:3025 +assert_return(() => call($16, "load8_u", [28_854]), 0); + +// memory_copy.wast:3026 +assert_return(() => call($16, "load8_u", [29_053]), 0); + +// memory_copy.wast:3027 +assert_return(() => call($16, "load8_u", [29_252]), 0); + +// memory_copy.wast:3028 +assert_return(() => call($16, "load8_u", [29_451]), 0); + +// memory_copy.wast:3029 +assert_return(() => call($16, "load8_u", [29_650]), 0); + +// memory_copy.wast:3030 +assert_return(() => call($16, "load8_u", [29_849]), 0); + +// memory_copy.wast:3031 +assert_return(() => call($16, "load8_u", [30_048]), 0); + +// memory_copy.wast:3032 +assert_return(() => call($16, "load8_u", [30_247]), 0); + +// memory_copy.wast:3033 +assert_return(() => call($16, "load8_u", [30_446]), 0); + +// memory_copy.wast:3034 +assert_return(() => call($16, "load8_u", [30_645]), 0); + +// memory_copy.wast:3035 +assert_return(() => call($16, "load8_u", [30_844]), 0); + +// memory_copy.wast:3036 +assert_return(() => call($16, "load8_u", [31_043]), 0); + +// memory_copy.wast:3037 +assert_return(() => call($16, "load8_u", [31_242]), 0); + +// memory_copy.wast:3038 +assert_return(() => call($16, "load8_u", [31_441]), 0); + +// memory_copy.wast:3039 +assert_return(() => call($16, "load8_u", [31_640]), 0); + +// memory_copy.wast:3040 +assert_return(() => call($16, "load8_u", [31_839]), 0); + +// memory_copy.wast:3041 +assert_return(() => call($16, "load8_u", [32_038]), 0); + +// memory_copy.wast:3042 +assert_return(() => call($16, "load8_u", [32_237]), 0); + +// memory_copy.wast:3043 +assert_return(() => call($16, "load8_u", [32_436]), 0); + +// memory_copy.wast:3044 +assert_return(() => call($16, "load8_u", [32_635]), 0); + +// memory_copy.wast:3045 +assert_return(() => call($16, "load8_u", [32_834]), 0); + +// memory_copy.wast:3046 +assert_return(() => call($16, "load8_u", [33_033]), 0); + +// memory_copy.wast:3047 +assert_return(() => call($16, "load8_u", [33_232]), 0); + +// memory_copy.wast:3048 +assert_return(() => call($16, "load8_u", [33_431]), 0); + +// memory_copy.wast:3049 +assert_return(() => call($16, "load8_u", [33_630]), 0); + +// memory_copy.wast:3050 +assert_return(() => call($16, "load8_u", [33_829]), 0); + +// memory_copy.wast:3051 +assert_return(() => call($16, "load8_u", [34_028]), 0); + +// memory_copy.wast:3052 +assert_return(() => call($16, "load8_u", [34_227]), 0); + +// memory_copy.wast:3053 +assert_return(() => call($16, "load8_u", [34_426]), 0); + +// memory_copy.wast:3054 +assert_return(() => call($16, "load8_u", [34_625]), 0); + +// memory_copy.wast:3055 +assert_return(() => call($16, "load8_u", [34_824]), 0); + +// memory_copy.wast:3056 +assert_return(() => call($16, "load8_u", [35_023]), 0); + +// memory_copy.wast:3057 +assert_return(() => call($16, "load8_u", [35_222]), 0); + +// memory_copy.wast:3058 +assert_return(() => call($16, "load8_u", [35_421]), 0); + +// memory_copy.wast:3059 +assert_return(() => call($16, "load8_u", [35_620]), 0); + +// memory_copy.wast:3060 +assert_return(() => call($16, "load8_u", [35_819]), 0); + +// memory_copy.wast:3061 +assert_return(() => call($16, "load8_u", [36_018]), 0); + +// memory_copy.wast:3062 +assert_return(() => call($16, "load8_u", [36_217]), 0); + +// memory_copy.wast:3063 +assert_return(() => call($16, "load8_u", [36_416]), 0); + +// memory_copy.wast:3064 +assert_return(() => call($16, "load8_u", [36_615]), 0); + +// memory_copy.wast:3065 +assert_return(() => call($16, "load8_u", [36_814]), 0); + +// memory_copy.wast:3066 +assert_return(() => call($16, "load8_u", [37_013]), 0); + +// memory_copy.wast:3067 +assert_return(() => call($16, "load8_u", [37_212]), 0); + +// memory_copy.wast:3068 +assert_return(() => call($16, "load8_u", [37_411]), 0); + +// memory_copy.wast:3069 +assert_return(() => call($16, "load8_u", [37_610]), 0); + +// memory_copy.wast:3070 +assert_return(() => call($16, "load8_u", [37_809]), 0); + +// memory_copy.wast:3071 +assert_return(() => call($16, "load8_u", [38_008]), 0); + +// memory_copy.wast:3072 +assert_return(() => call($16, "load8_u", [38_207]), 0); + +// memory_copy.wast:3073 +assert_return(() => call($16, "load8_u", [38_406]), 0); + +// memory_copy.wast:3074 +assert_return(() => call($16, "load8_u", [38_605]), 0); + +// memory_copy.wast:3075 +assert_return(() => call($16, "load8_u", [38_804]), 0); + +// memory_copy.wast:3076 +assert_return(() => call($16, "load8_u", [39_003]), 0); + +// memory_copy.wast:3077 +assert_return(() => call($16, "load8_u", [39_202]), 0); + +// memory_copy.wast:3078 +assert_return(() => call($16, "load8_u", [39_401]), 0); + +// memory_copy.wast:3079 +assert_return(() => call($16, "load8_u", [39_600]), 0); + +// memory_copy.wast:3080 +assert_return(() => call($16, "load8_u", [39_799]), 0); + +// memory_copy.wast:3081 +assert_return(() => call($16, "load8_u", [39_998]), 0); + +// memory_copy.wast:3082 +assert_return(() => call($16, "load8_u", [40_197]), 0); + +// memory_copy.wast:3083 +assert_return(() => call($16, "load8_u", [40_396]), 0); + +// memory_copy.wast:3084 +assert_return(() => call($16, "load8_u", [40_595]), 0); + +// memory_copy.wast:3085 +assert_return(() => call($16, "load8_u", [40_794]), 0); + +// memory_copy.wast:3086 +assert_return(() => call($16, "load8_u", [40_993]), 0); + +// memory_copy.wast:3087 +assert_return(() => call($16, "load8_u", [41_192]), 0); + +// memory_copy.wast:3088 +assert_return(() => call($16, "load8_u", [41_391]), 0); + +// memory_copy.wast:3089 +assert_return(() => call($16, "load8_u", [41_590]), 0); + +// memory_copy.wast:3090 +assert_return(() => call($16, "load8_u", [41_789]), 0); + +// memory_copy.wast:3091 +assert_return(() => call($16, "load8_u", [41_988]), 0); + +// memory_copy.wast:3092 +assert_return(() => call($16, "load8_u", [42_187]), 0); + +// memory_copy.wast:3093 +assert_return(() => call($16, "load8_u", [42_386]), 0); + +// memory_copy.wast:3094 +assert_return(() => call($16, "load8_u", [42_585]), 0); + +// memory_copy.wast:3095 +assert_return(() => call($16, "load8_u", [42_784]), 0); + +// memory_copy.wast:3096 +assert_return(() => call($16, "load8_u", [42_983]), 0); + +// memory_copy.wast:3097 +assert_return(() => call($16, "load8_u", [43_182]), 0); + +// memory_copy.wast:3098 +assert_return(() => call($16, "load8_u", [43_381]), 0); + +// memory_copy.wast:3099 +assert_return(() => call($16, "load8_u", [43_580]), 0); + +// memory_copy.wast:3100 +assert_return(() => call($16, "load8_u", [43_779]), 0); + +// memory_copy.wast:3101 +assert_return(() => call($16, "load8_u", [43_978]), 0); + +// memory_copy.wast:3102 +assert_return(() => call($16, "load8_u", [44_177]), 0); + +// memory_copy.wast:3103 +assert_return(() => call($16, "load8_u", [44_376]), 0); + +// memory_copy.wast:3104 +assert_return(() => call($16, "load8_u", [44_575]), 0); + +// memory_copy.wast:3105 +assert_return(() => call($16, "load8_u", [44_774]), 0); + +// memory_copy.wast:3106 +assert_return(() => call($16, "load8_u", [44_973]), 0); + +// memory_copy.wast:3107 +assert_return(() => call($16, "load8_u", [45_172]), 0); + +// memory_copy.wast:3108 +assert_return(() => call($16, "load8_u", [45_371]), 0); + +// memory_copy.wast:3109 +assert_return(() => call($16, "load8_u", [45_570]), 0); + +// memory_copy.wast:3110 +assert_return(() => call($16, "load8_u", [45_769]), 0); + +// memory_copy.wast:3111 +assert_return(() => call($16, "load8_u", [45_968]), 0); + +// memory_copy.wast:3112 +assert_return(() => call($16, "load8_u", [46_167]), 0); + +// memory_copy.wast:3113 +assert_return(() => call($16, "load8_u", [46_366]), 0); + +// memory_copy.wast:3114 +assert_return(() => call($16, "load8_u", [46_565]), 0); + +// memory_copy.wast:3115 +assert_return(() => call($16, "load8_u", [46_764]), 0); + +// memory_copy.wast:3116 +assert_return(() => call($16, "load8_u", [46_963]), 0); + +// memory_copy.wast:3117 +assert_return(() => call($16, "load8_u", [47_162]), 0); + +// memory_copy.wast:3118 +assert_return(() => call($16, "load8_u", [47_361]), 0); + +// memory_copy.wast:3119 +assert_return(() => call($16, "load8_u", [47_560]), 0); + +// memory_copy.wast:3120 +assert_return(() => call($16, "load8_u", [47_759]), 0); + +// memory_copy.wast:3121 +assert_return(() => call($16, "load8_u", [47_958]), 0); + +// memory_copy.wast:3122 +assert_return(() => call($16, "load8_u", [48_157]), 0); + +// memory_copy.wast:3123 +assert_return(() => call($16, "load8_u", [48_356]), 0); + +// memory_copy.wast:3124 +assert_return(() => call($16, "load8_u", [48_555]), 0); + +// memory_copy.wast:3125 +assert_return(() => call($16, "load8_u", [48_754]), 0); + +// memory_copy.wast:3126 +assert_return(() => call($16, "load8_u", [48_953]), 0); + +// memory_copy.wast:3127 +assert_return(() => call($16, "load8_u", [49_152]), 0); + +// memory_copy.wast:3128 +assert_return(() => call($16, "load8_u", [49_351]), 0); + +// memory_copy.wast:3129 +assert_return(() => call($16, "load8_u", [49_550]), 0); + +// memory_copy.wast:3130 +assert_return(() => call($16, "load8_u", [49_749]), 0); + +// memory_copy.wast:3131 +assert_return(() => call($16, "load8_u", [49_948]), 0); + +// memory_copy.wast:3132 +assert_return(() => call($16, "load8_u", [50_147]), 0); + +// memory_copy.wast:3133 +assert_return(() => call($16, "load8_u", [50_346]), 0); + +// memory_copy.wast:3134 +assert_return(() => call($16, "load8_u", [50_545]), 0); + +// memory_copy.wast:3135 +assert_return(() => call($16, "load8_u", [50_744]), 0); + +// memory_copy.wast:3136 +assert_return(() => call($16, "load8_u", [50_943]), 0); + +// memory_copy.wast:3137 +assert_return(() => call($16, "load8_u", [51_142]), 0); + +// memory_copy.wast:3138 +assert_return(() => call($16, "load8_u", [51_341]), 0); + +// memory_copy.wast:3139 +assert_return(() => call($16, "load8_u", [51_540]), 0); + +// memory_copy.wast:3140 +assert_return(() => call($16, "load8_u", [51_739]), 0); + +// memory_copy.wast:3141 +assert_return(() => call($16, "load8_u", [51_938]), 0); + +// memory_copy.wast:3142 +assert_return(() => call($16, "load8_u", [52_137]), 0); + +// memory_copy.wast:3143 +assert_return(() => call($16, "load8_u", [52_336]), 0); + +// memory_copy.wast:3144 +assert_return(() => call($16, "load8_u", [52_535]), 0); + +// memory_copy.wast:3145 +assert_return(() => call($16, "load8_u", [52_734]), 0); + +// memory_copy.wast:3146 +assert_return(() => call($16, "load8_u", [52_933]), 0); + +// memory_copy.wast:3147 +assert_return(() => call($16, "load8_u", [53_132]), 0); + +// memory_copy.wast:3148 +assert_return(() => call($16, "load8_u", [53_331]), 0); + +// memory_copy.wast:3149 +assert_return(() => call($16, "load8_u", [53_530]), 0); + +// memory_copy.wast:3150 +assert_return(() => call($16, "load8_u", [53_729]), 0); + +// memory_copy.wast:3151 +assert_return(() => call($16, "load8_u", [53_928]), 0); + +// memory_copy.wast:3152 +assert_return(() => call($16, "load8_u", [54_127]), 0); + +// memory_copy.wast:3153 +assert_return(() => call($16, "load8_u", [54_326]), 0); + +// memory_copy.wast:3154 +assert_return(() => call($16, "load8_u", [54_525]), 0); + +// memory_copy.wast:3155 +assert_return(() => call($16, "load8_u", [54_724]), 0); + +// memory_copy.wast:3156 +assert_return(() => call($16, "load8_u", [54_923]), 0); + +// memory_copy.wast:3157 +assert_return(() => call($16, "load8_u", [55_122]), 0); + +// memory_copy.wast:3158 +assert_return(() => call($16, "load8_u", [55_321]), 0); + +// memory_copy.wast:3159 +assert_return(() => call($16, "load8_u", [55_520]), 0); + +// memory_copy.wast:3160 +assert_return(() => call($16, "load8_u", [55_719]), 0); + +// memory_copy.wast:3161 +assert_return(() => call($16, "load8_u", [55_918]), 0); + +// memory_copy.wast:3162 +assert_return(() => call($16, "load8_u", [56_117]), 0); + +// memory_copy.wast:3163 +assert_return(() => call($16, "load8_u", [56_316]), 0); + +// memory_copy.wast:3164 +assert_return(() => call($16, "load8_u", [56_515]), 0); + +// memory_copy.wast:3165 +assert_return(() => call($16, "load8_u", [56_714]), 0); + +// memory_copy.wast:3166 +assert_return(() => call($16, "load8_u", [56_913]), 0); + +// memory_copy.wast:3167 +assert_return(() => call($16, "load8_u", [57_112]), 0); + +// memory_copy.wast:3168 +assert_return(() => call($16, "load8_u", [57_311]), 0); + +// memory_copy.wast:3169 +assert_return(() => call($16, "load8_u", [57_510]), 0); + +// memory_copy.wast:3170 +assert_return(() => call($16, "load8_u", [57_709]), 0); + +// memory_copy.wast:3171 +assert_return(() => call($16, "load8_u", [57_908]), 0); + +// memory_copy.wast:3172 +assert_return(() => call($16, "load8_u", [58_107]), 0); + +// memory_copy.wast:3173 +assert_return(() => call($16, "load8_u", [58_306]), 0); + +// memory_copy.wast:3174 +assert_return(() => call($16, "load8_u", [58_505]), 0); + +// memory_copy.wast:3175 +assert_return(() => call($16, "load8_u", [58_704]), 0); + +// memory_copy.wast:3176 +assert_return(() => call($16, "load8_u", [58_903]), 0); + +// memory_copy.wast:3177 +assert_return(() => call($16, "load8_u", [59_102]), 0); + +// memory_copy.wast:3178 +assert_return(() => call($16, "load8_u", [59_301]), 0); + +// memory_copy.wast:3179 +assert_return(() => call($16, "load8_u", [59_500]), 0); + +// memory_copy.wast:3180 +assert_return(() => call($16, "load8_u", [59_699]), 0); + +// memory_copy.wast:3181 +assert_return(() => call($16, "load8_u", [59_898]), 0); + +// memory_copy.wast:3182 +assert_return(() => call($16, "load8_u", [60_097]), 0); + +// memory_copy.wast:3183 +assert_return(() => call($16, "load8_u", [60_296]), 0); + +// memory_copy.wast:3184 +assert_return(() => call($16, "load8_u", [60_495]), 0); + +// memory_copy.wast:3185 +assert_return(() => call($16, "load8_u", [60_694]), 0); + +// memory_copy.wast:3186 +assert_return(() => call($16, "load8_u", [60_893]), 0); + +// memory_copy.wast:3187 +assert_return(() => call($16, "load8_u", [61_092]), 0); + +// memory_copy.wast:3188 +assert_return(() => call($16, "load8_u", [61_291]), 0); + +// memory_copy.wast:3189 +assert_return(() => call($16, "load8_u", [61_490]), 0); + +// memory_copy.wast:3190 +assert_return(() => call($16, "load8_u", [61_689]), 0); + +// memory_copy.wast:3191 +assert_return(() => call($16, "load8_u", [61_888]), 0); + +// memory_copy.wast:3192 +assert_return(() => call($16, "load8_u", [62_087]), 0); + +// memory_copy.wast:3193 +assert_return(() => call($16, "load8_u", [62_286]), 0); + +// memory_copy.wast:3194 +assert_return(() => call($16, "load8_u", [62_485]), 0); + +// memory_copy.wast:3195 +assert_return(() => call($16, "load8_u", [62_684]), 0); + +// memory_copy.wast:3196 +assert_return(() => call($16, "load8_u", [62_883]), 0); + +// memory_copy.wast:3197 +assert_return(() => call($16, "load8_u", [63_082]), 0); + +// memory_copy.wast:3198 +assert_return(() => call($16, "load8_u", [63_281]), 0); + +// memory_copy.wast:3199 +assert_return(() => call($16, "load8_u", [63_480]), 0); + +// memory_copy.wast:3200 +assert_return(() => call($16, "load8_u", [63_679]), 0); + +// memory_copy.wast:3201 +assert_return(() => call($16, "load8_u", [63_878]), 0); + +// memory_copy.wast:3202 +assert_return(() => call($16, "load8_u", [64_077]), 0); + +// memory_copy.wast:3203 +assert_return(() => call($16, "load8_u", [64_276]), 0); + +// memory_copy.wast:3204 +assert_return(() => call($16, "load8_u", [64_475]), 0); + +// memory_copy.wast:3205 +assert_return(() => call($16, "load8_u", [64_674]), 0); + +// memory_copy.wast:3206 +assert_return(() => call($16, "load8_u", [64_873]), 0); + +// memory_copy.wast:3207 +assert_return(() => call($16, "load8_u", [65_072]), 0); + +// memory_copy.wast:3208 +assert_return(() => call($16, "load8_u", [65_271]), 0); + +// memory_copy.wast:3209 +assert_return(() => call($16, "load8_u", [65_470]), 0); + +// memory_copy.wast:3210 +assert_return(() => call($16, "load8_u", [65_516]), 0); + +// memory_copy.wast:3211 +assert_return(() => call($16, "load8_u", [65_517]), 1); + +// memory_copy.wast:3212 +assert_return(() => call($16, "load8_u", [65_518]), 2); + +// memory_copy.wast:3213 +assert_return(() => call($16, "load8_u", [65_519]), 3); + +// memory_copy.wast:3214 +assert_return(() => call($16, "load8_u", [65_520]), 4); + +// memory_copy.wast:3215 +assert_return(() => call($16, "load8_u", [65_521]), 5); + +// memory_copy.wast:3216 +assert_return(() => call($16, "load8_u", [65_522]), 6); + +// memory_copy.wast:3217 +assert_return(() => call($16, "load8_u", [65_523]), 7); + +// memory_copy.wast:3218 +assert_return(() => call($16, "load8_u", [65_524]), 8); + +// memory_copy.wast:3219 +assert_return(() => call($16, "load8_u", [65_525]), 9); + +// memory_copy.wast:3220 +assert_return(() => call($16, "load8_u", [65_526]), 10); + +// memory_copy.wast:3221 +assert_return(() => call($16, "load8_u", [65_527]), 11); + +// memory_copy.wast:3222 +assert_return(() => call($16, "load8_u", [65_528]), 12); + +// memory_copy.wast:3223 +assert_return(() => call($16, "load8_u", [65_529]), 13); + +// memory_copy.wast:3224 +assert_return(() => call($16, "load8_u", [65_530]), 14); + +// memory_copy.wast:3225 +assert_return(() => call($16, "load8_u", [65_531]), 15); + +// memory_copy.wast:3226 +assert_return(() => call($16, "load8_u", [65_532]), 16); + +// memory_copy.wast:3227 +assert_return(() => call($16, "load8_u", [65_533]), 17); + +// memory_copy.wast:3228 +assert_return(() => call($16, "load8_u", [65_534]), 18); + +// memory_copy.wast:3229 +assert_return(() => call($16, "load8_u", [65_535]), 19); + +// memory_copy.wast:3231 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3239 +assert_trap(() => call($17, "run", [65_516, 65_516, 40])); + +// memory_copy.wast:3242 +assert_return(() => call($17, "load8_u", [198]), 0); + +// memory_copy.wast:3243 +assert_return(() => call($17, "load8_u", [397]), 0); + +// memory_copy.wast:3244 +assert_return(() => call($17, "load8_u", [596]), 0); + +// memory_copy.wast:3245 +assert_return(() => call($17, "load8_u", [795]), 0); + +// memory_copy.wast:3246 +assert_return(() => call($17, "load8_u", [994]), 0); + +// memory_copy.wast:3247 +assert_return(() => call($17, "load8_u", [1_193]), 0); + +// memory_copy.wast:3248 +assert_return(() => call($17, "load8_u", [1_392]), 0); + +// memory_copy.wast:3249 +assert_return(() => call($17, "load8_u", [1_591]), 0); + +// memory_copy.wast:3250 +assert_return(() => call($17, "load8_u", [1_790]), 0); + +// memory_copy.wast:3251 +assert_return(() => call($17, "load8_u", [1_989]), 0); + +// memory_copy.wast:3252 +assert_return(() => call($17, "load8_u", [2_188]), 0); + +// memory_copy.wast:3253 +assert_return(() => call($17, "load8_u", [2_387]), 0); + +// memory_copy.wast:3254 +assert_return(() => call($17, "load8_u", [2_586]), 0); + +// memory_copy.wast:3255 +assert_return(() => call($17, "load8_u", [2_785]), 0); + +// memory_copy.wast:3256 +assert_return(() => call($17, "load8_u", [2_984]), 0); + +// memory_copy.wast:3257 +assert_return(() => call($17, "load8_u", [3_183]), 0); + +// memory_copy.wast:3258 +assert_return(() => call($17, "load8_u", [3_382]), 0); + +// memory_copy.wast:3259 +assert_return(() => call($17, "load8_u", [3_581]), 0); + +// memory_copy.wast:3260 +assert_return(() => call($17, "load8_u", [3_780]), 0); + +// memory_copy.wast:3261 +assert_return(() => call($17, "load8_u", [3_979]), 0); + +// memory_copy.wast:3262 +assert_return(() => call($17, "load8_u", [4_178]), 0); + +// memory_copy.wast:3263 +assert_return(() => call($17, "load8_u", [4_377]), 0); + +// memory_copy.wast:3264 +assert_return(() => call($17, "load8_u", [4_576]), 0); + +// memory_copy.wast:3265 +assert_return(() => call($17, "load8_u", [4_775]), 0); + +// memory_copy.wast:3266 +assert_return(() => call($17, "load8_u", [4_974]), 0); + +// memory_copy.wast:3267 +assert_return(() => call($17, "load8_u", [5_173]), 0); + +// memory_copy.wast:3268 +assert_return(() => call($17, "load8_u", [5_372]), 0); + +// memory_copy.wast:3269 +assert_return(() => call($17, "load8_u", [5_571]), 0); + +// memory_copy.wast:3270 +assert_return(() => call($17, "load8_u", [5_770]), 0); + +// memory_copy.wast:3271 +assert_return(() => call($17, "load8_u", [5_969]), 0); + +// memory_copy.wast:3272 +assert_return(() => call($17, "load8_u", [6_168]), 0); + +// memory_copy.wast:3273 +assert_return(() => call($17, "load8_u", [6_367]), 0); + +// memory_copy.wast:3274 +assert_return(() => call($17, "load8_u", [6_566]), 0); + +// memory_copy.wast:3275 +assert_return(() => call($17, "load8_u", [6_765]), 0); + +// memory_copy.wast:3276 +assert_return(() => call($17, "load8_u", [6_964]), 0); + +// memory_copy.wast:3277 +assert_return(() => call($17, "load8_u", [7_163]), 0); + +// memory_copy.wast:3278 +assert_return(() => call($17, "load8_u", [7_362]), 0); + +// memory_copy.wast:3279 +assert_return(() => call($17, "load8_u", [7_561]), 0); + +// memory_copy.wast:3280 +assert_return(() => call($17, "load8_u", [7_760]), 0); + +// memory_copy.wast:3281 +assert_return(() => call($17, "load8_u", [7_959]), 0); + +// memory_copy.wast:3282 +assert_return(() => call($17, "load8_u", [8_158]), 0); + +// memory_copy.wast:3283 +assert_return(() => call($17, "load8_u", [8_357]), 0); + +// memory_copy.wast:3284 +assert_return(() => call($17, "load8_u", [8_556]), 0); + +// memory_copy.wast:3285 +assert_return(() => call($17, "load8_u", [8_755]), 0); + +// memory_copy.wast:3286 +assert_return(() => call($17, "load8_u", [8_954]), 0); + +// memory_copy.wast:3287 +assert_return(() => call($17, "load8_u", [9_153]), 0); + +// memory_copy.wast:3288 +assert_return(() => call($17, "load8_u", [9_352]), 0); + +// memory_copy.wast:3289 +assert_return(() => call($17, "load8_u", [9_551]), 0); + +// memory_copy.wast:3290 +assert_return(() => call($17, "load8_u", [9_750]), 0); + +// memory_copy.wast:3291 +assert_return(() => call($17, "load8_u", [9_949]), 0); + +// memory_copy.wast:3292 +assert_return(() => call($17, "load8_u", [10_148]), 0); + +// memory_copy.wast:3293 +assert_return(() => call($17, "load8_u", [10_347]), 0); + +// memory_copy.wast:3294 +assert_return(() => call($17, "load8_u", [10_546]), 0); + +// memory_copy.wast:3295 +assert_return(() => call($17, "load8_u", [10_745]), 0); + +// memory_copy.wast:3296 +assert_return(() => call($17, "load8_u", [10_944]), 0); + +// memory_copy.wast:3297 +assert_return(() => call($17, "load8_u", [11_143]), 0); + +// memory_copy.wast:3298 +assert_return(() => call($17, "load8_u", [11_342]), 0); + +// memory_copy.wast:3299 +assert_return(() => call($17, "load8_u", [11_541]), 0); + +// memory_copy.wast:3300 +assert_return(() => call($17, "load8_u", [11_740]), 0); + +// memory_copy.wast:3301 +assert_return(() => call($17, "load8_u", [11_939]), 0); + +// memory_copy.wast:3302 +assert_return(() => call($17, "load8_u", [12_138]), 0); + +// memory_copy.wast:3303 +assert_return(() => call($17, "load8_u", [12_337]), 0); + +// memory_copy.wast:3304 +assert_return(() => call($17, "load8_u", [12_536]), 0); + +// memory_copy.wast:3305 +assert_return(() => call($17, "load8_u", [12_735]), 0); + +// memory_copy.wast:3306 +assert_return(() => call($17, "load8_u", [12_934]), 0); + +// memory_copy.wast:3307 +assert_return(() => call($17, "load8_u", [13_133]), 0); + +// memory_copy.wast:3308 +assert_return(() => call($17, "load8_u", [13_332]), 0); + +// memory_copy.wast:3309 +assert_return(() => call($17, "load8_u", [13_531]), 0); + +// memory_copy.wast:3310 +assert_return(() => call($17, "load8_u", [13_730]), 0); + +// memory_copy.wast:3311 +assert_return(() => call($17, "load8_u", [13_929]), 0); + +// memory_copy.wast:3312 +assert_return(() => call($17, "load8_u", [14_128]), 0); + +// memory_copy.wast:3313 +assert_return(() => call($17, "load8_u", [14_327]), 0); + +// memory_copy.wast:3314 +assert_return(() => call($17, "load8_u", [14_526]), 0); + +// memory_copy.wast:3315 +assert_return(() => call($17, "load8_u", [14_725]), 0); + +// memory_copy.wast:3316 +assert_return(() => call($17, "load8_u", [14_924]), 0); + +// memory_copy.wast:3317 +assert_return(() => call($17, "load8_u", [15_123]), 0); + +// memory_copy.wast:3318 +assert_return(() => call($17, "load8_u", [15_322]), 0); + +// memory_copy.wast:3319 +assert_return(() => call($17, "load8_u", [15_521]), 0); + +// memory_copy.wast:3320 +assert_return(() => call($17, "load8_u", [15_720]), 0); + +// memory_copy.wast:3321 +assert_return(() => call($17, "load8_u", [15_919]), 0); + +// memory_copy.wast:3322 +assert_return(() => call($17, "load8_u", [16_118]), 0); + +// memory_copy.wast:3323 +assert_return(() => call($17, "load8_u", [16_317]), 0); + +// memory_copy.wast:3324 +assert_return(() => call($17, "load8_u", [16_516]), 0); + +// memory_copy.wast:3325 +assert_return(() => call($17, "load8_u", [16_715]), 0); + +// memory_copy.wast:3326 +assert_return(() => call($17, "load8_u", [16_914]), 0); + +// memory_copy.wast:3327 +assert_return(() => call($17, "load8_u", [17_113]), 0); + +// memory_copy.wast:3328 +assert_return(() => call($17, "load8_u", [17_312]), 0); + +// memory_copy.wast:3329 +assert_return(() => call($17, "load8_u", [17_511]), 0); + +// memory_copy.wast:3330 +assert_return(() => call($17, "load8_u", [17_710]), 0); + +// memory_copy.wast:3331 +assert_return(() => call($17, "load8_u", [17_909]), 0); + +// memory_copy.wast:3332 +assert_return(() => call($17, "load8_u", [18_108]), 0); + +// memory_copy.wast:3333 +assert_return(() => call($17, "load8_u", [18_307]), 0); + +// memory_copy.wast:3334 +assert_return(() => call($17, "load8_u", [18_506]), 0); + +// memory_copy.wast:3335 +assert_return(() => call($17, "load8_u", [18_705]), 0); + +// memory_copy.wast:3336 +assert_return(() => call($17, "load8_u", [18_904]), 0); + +// memory_copy.wast:3337 +assert_return(() => call($17, "load8_u", [19_103]), 0); + +// memory_copy.wast:3338 +assert_return(() => call($17, "load8_u", [19_302]), 0); + +// memory_copy.wast:3339 +assert_return(() => call($17, "load8_u", [19_501]), 0); + +// memory_copy.wast:3340 +assert_return(() => call($17, "load8_u", [19_700]), 0); + +// memory_copy.wast:3341 +assert_return(() => call($17, "load8_u", [19_899]), 0); + +// memory_copy.wast:3342 +assert_return(() => call($17, "load8_u", [20_098]), 0); + +// memory_copy.wast:3343 +assert_return(() => call($17, "load8_u", [20_297]), 0); + +// memory_copy.wast:3344 +assert_return(() => call($17, "load8_u", [20_496]), 0); + +// memory_copy.wast:3345 +assert_return(() => call($17, "load8_u", [20_695]), 0); + +// memory_copy.wast:3346 +assert_return(() => call($17, "load8_u", [20_894]), 0); + +// memory_copy.wast:3347 +assert_return(() => call($17, "load8_u", [21_093]), 0); + +// memory_copy.wast:3348 +assert_return(() => call($17, "load8_u", [21_292]), 0); + +// memory_copy.wast:3349 +assert_return(() => call($17, "load8_u", [21_491]), 0); + +// memory_copy.wast:3350 +assert_return(() => call($17, "load8_u", [21_690]), 0); + +// memory_copy.wast:3351 +assert_return(() => call($17, "load8_u", [21_889]), 0); + +// memory_copy.wast:3352 +assert_return(() => call($17, "load8_u", [22_088]), 0); + +// memory_copy.wast:3353 +assert_return(() => call($17, "load8_u", [22_287]), 0); + +// memory_copy.wast:3354 +assert_return(() => call($17, "load8_u", [22_486]), 0); + +// memory_copy.wast:3355 +assert_return(() => call($17, "load8_u", [22_685]), 0); + +// memory_copy.wast:3356 +assert_return(() => call($17, "load8_u", [22_884]), 0); + +// memory_copy.wast:3357 +assert_return(() => call($17, "load8_u", [23_083]), 0); + +// memory_copy.wast:3358 +assert_return(() => call($17, "load8_u", [23_282]), 0); + +// memory_copy.wast:3359 +assert_return(() => call($17, "load8_u", [23_481]), 0); + +// memory_copy.wast:3360 +assert_return(() => call($17, "load8_u", [23_680]), 0); + +// memory_copy.wast:3361 +assert_return(() => call($17, "load8_u", [23_879]), 0); + +// memory_copy.wast:3362 +assert_return(() => call($17, "load8_u", [24_078]), 0); + +// memory_copy.wast:3363 +assert_return(() => call($17, "load8_u", [24_277]), 0); + +// memory_copy.wast:3364 +assert_return(() => call($17, "load8_u", [24_476]), 0); + +// memory_copy.wast:3365 +assert_return(() => call($17, "load8_u", [24_675]), 0); + +// memory_copy.wast:3366 +assert_return(() => call($17, "load8_u", [24_874]), 0); + +// memory_copy.wast:3367 +assert_return(() => call($17, "load8_u", [25_073]), 0); + +// memory_copy.wast:3368 +assert_return(() => call($17, "load8_u", [25_272]), 0); + +// memory_copy.wast:3369 +assert_return(() => call($17, "load8_u", [25_471]), 0); + +// memory_copy.wast:3370 +assert_return(() => call($17, "load8_u", [25_670]), 0); + +// memory_copy.wast:3371 +assert_return(() => call($17, "load8_u", [25_869]), 0); + +// memory_copy.wast:3372 +assert_return(() => call($17, "load8_u", [26_068]), 0); + +// memory_copy.wast:3373 +assert_return(() => call($17, "load8_u", [26_267]), 0); + +// memory_copy.wast:3374 +assert_return(() => call($17, "load8_u", [26_466]), 0); + +// memory_copy.wast:3375 +assert_return(() => call($17, "load8_u", [26_665]), 0); + +// memory_copy.wast:3376 +assert_return(() => call($17, "load8_u", [26_864]), 0); + +// memory_copy.wast:3377 +assert_return(() => call($17, "load8_u", [27_063]), 0); + +// memory_copy.wast:3378 +assert_return(() => call($17, "load8_u", [27_262]), 0); + +// memory_copy.wast:3379 +assert_return(() => call($17, "load8_u", [27_461]), 0); + +// memory_copy.wast:3380 +assert_return(() => call($17, "load8_u", [27_660]), 0); + +// memory_copy.wast:3381 +assert_return(() => call($17, "load8_u", [27_859]), 0); + +// memory_copy.wast:3382 +assert_return(() => call($17, "load8_u", [28_058]), 0); + +// memory_copy.wast:3383 +assert_return(() => call($17, "load8_u", [28_257]), 0); + +// memory_copy.wast:3384 +assert_return(() => call($17, "load8_u", [28_456]), 0); + +// memory_copy.wast:3385 +assert_return(() => call($17, "load8_u", [28_655]), 0); + +// memory_copy.wast:3386 +assert_return(() => call($17, "load8_u", [28_854]), 0); + +// memory_copy.wast:3387 +assert_return(() => call($17, "load8_u", [29_053]), 0); + +// memory_copy.wast:3388 +assert_return(() => call($17, "load8_u", [29_252]), 0); + +// memory_copy.wast:3389 +assert_return(() => call($17, "load8_u", [29_451]), 0); + +// memory_copy.wast:3390 +assert_return(() => call($17, "load8_u", [29_650]), 0); + +// memory_copy.wast:3391 +assert_return(() => call($17, "load8_u", [29_849]), 0); + +// memory_copy.wast:3392 +assert_return(() => call($17, "load8_u", [30_048]), 0); + +// memory_copy.wast:3393 +assert_return(() => call($17, "load8_u", [30_247]), 0); + +// memory_copy.wast:3394 +assert_return(() => call($17, "load8_u", [30_446]), 0); + +// memory_copy.wast:3395 +assert_return(() => call($17, "load8_u", [30_645]), 0); + +// memory_copy.wast:3396 +assert_return(() => call($17, "load8_u", [30_844]), 0); + +// memory_copy.wast:3397 +assert_return(() => call($17, "load8_u", [31_043]), 0); + +// memory_copy.wast:3398 +assert_return(() => call($17, "load8_u", [31_242]), 0); + +// memory_copy.wast:3399 +assert_return(() => call($17, "load8_u", [31_441]), 0); + +// memory_copy.wast:3400 +assert_return(() => call($17, "load8_u", [31_640]), 0); + +// memory_copy.wast:3401 +assert_return(() => call($17, "load8_u", [31_839]), 0); + +// memory_copy.wast:3402 +assert_return(() => call($17, "load8_u", [32_038]), 0); + +// memory_copy.wast:3403 +assert_return(() => call($17, "load8_u", [32_237]), 0); + +// memory_copy.wast:3404 +assert_return(() => call($17, "load8_u", [32_436]), 0); + +// memory_copy.wast:3405 +assert_return(() => call($17, "load8_u", [32_635]), 0); + +// memory_copy.wast:3406 +assert_return(() => call($17, "load8_u", [32_834]), 0); + +// memory_copy.wast:3407 +assert_return(() => call($17, "load8_u", [33_033]), 0); + +// memory_copy.wast:3408 +assert_return(() => call($17, "load8_u", [33_232]), 0); + +// memory_copy.wast:3409 +assert_return(() => call($17, "load8_u", [33_431]), 0); + +// memory_copy.wast:3410 +assert_return(() => call($17, "load8_u", [33_630]), 0); + +// memory_copy.wast:3411 +assert_return(() => call($17, "load8_u", [33_829]), 0); + +// memory_copy.wast:3412 +assert_return(() => call($17, "load8_u", [34_028]), 0); + +// memory_copy.wast:3413 +assert_return(() => call($17, "load8_u", [34_227]), 0); + +// memory_copy.wast:3414 +assert_return(() => call($17, "load8_u", [34_426]), 0); + +// memory_copy.wast:3415 +assert_return(() => call($17, "load8_u", [34_625]), 0); + +// memory_copy.wast:3416 +assert_return(() => call($17, "load8_u", [34_824]), 0); + +// memory_copy.wast:3417 +assert_return(() => call($17, "load8_u", [35_023]), 0); + +// memory_copy.wast:3418 +assert_return(() => call($17, "load8_u", [35_222]), 0); + +// memory_copy.wast:3419 +assert_return(() => call($17, "load8_u", [35_421]), 0); + +// memory_copy.wast:3420 +assert_return(() => call($17, "load8_u", [35_620]), 0); + +// memory_copy.wast:3421 +assert_return(() => call($17, "load8_u", [35_819]), 0); + +// memory_copy.wast:3422 +assert_return(() => call($17, "load8_u", [36_018]), 0); + +// memory_copy.wast:3423 +assert_return(() => call($17, "load8_u", [36_217]), 0); + +// memory_copy.wast:3424 +assert_return(() => call($17, "load8_u", [36_416]), 0); + +// memory_copy.wast:3425 +assert_return(() => call($17, "load8_u", [36_615]), 0); + +// memory_copy.wast:3426 +assert_return(() => call($17, "load8_u", [36_814]), 0); + +// memory_copy.wast:3427 +assert_return(() => call($17, "load8_u", [37_013]), 0); + +// memory_copy.wast:3428 +assert_return(() => call($17, "load8_u", [37_212]), 0); + +// memory_copy.wast:3429 +assert_return(() => call($17, "load8_u", [37_411]), 0); + +// memory_copy.wast:3430 +assert_return(() => call($17, "load8_u", [37_610]), 0); + +// memory_copy.wast:3431 +assert_return(() => call($17, "load8_u", [37_809]), 0); + +// memory_copy.wast:3432 +assert_return(() => call($17, "load8_u", [38_008]), 0); + +// memory_copy.wast:3433 +assert_return(() => call($17, "load8_u", [38_207]), 0); + +// memory_copy.wast:3434 +assert_return(() => call($17, "load8_u", [38_406]), 0); + +// memory_copy.wast:3435 +assert_return(() => call($17, "load8_u", [38_605]), 0); + +// memory_copy.wast:3436 +assert_return(() => call($17, "load8_u", [38_804]), 0); + +// memory_copy.wast:3437 +assert_return(() => call($17, "load8_u", [39_003]), 0); + +// memory_copy.wast:3438 +assert_return(() => call($17, "load8_u", [39_202]), 0); + +// memory_copy.wast:3439 +assert_return(() => call($17, "load8_u", [39_401]), 0); + +// memory_copy.wast:3440 +assert_return(() => call($17, "load8_u", [39_600]), 0); + +// memory_copy.wast:3441 +assert_return(() => call($17, "load8_u", [39_799]), 0); + +// memory_copy.wast:3442 +assert_return(() => call($17, "load8_u", [39_998]), 0); + +// memory_copy.wast:3443 +assert_return(() => call($17, "load8_u", [40_197]), 0); + +// memory_copy.wast:3444 +assert_return(() => call($17, "load8_u", [40_396]), 0); + +// memory_copy.wast:3445 +assert_return(() => call($17, "load8_u", [40_595]), 0); + +// memory_copy.wast:3446 +assert_return(() => call($17, "load8_u", [40_794]), 0); + +// memory_copy.wast:3447 +assert_return(() => call($17, "load8_u", [40_993]), 0); + +// memory_copy.wast:3448 +assert_return(() => call($17, "load8_u", [41_192]), 0); + +// memory_copy.wast:3449 +assert_return(() => call($17, "load8_u", [41_391]), 0); + +// memory_copy.wast:3450 +assert_return(() => call($17, "load8_u", [41_590]), 0); + +// memory_copy.wast:3451 +assert_return(() => call($17, "load8_u", [41_789]), 0); + +// memory_copy.wast:3452 +assert_return(() => call($17, "load8_u", [41_988]), 0); + +// memory_copy.wast:3453 +assert_return(() => call($17, "load8_u", [42_187]), 0); + +// memory_copy.wast:3454 +assert_return(() => call($17, "load8_u", [42_386]), 0); + +// memory_copy.wast:3455 +assert_return(() => call($17, "load8_u", [42_585]), 0); + +// memory_copy.wast:3456 +assert_return(() => call($17, "load8_u", [42_784]), 0); + +// memory_copy.wast:3457 +assert_return(() => call($17, "load8_u", [42_983]), 0); + +// memory_copy.wast:3458 +assert_return(() => call($17, "load8_u", [43_182]), 0); + +// memory_copy.wast:3459 +assert_return(() => call($17, "load8_u", [43_381]), 0); + +// memory_copy.wast:3460 +assert_return(() => call($17, "load8_u", [43_580]), 0); + +// memory_copy.wast:3461 +assert_return(() => call($17, "load8_u", [43_779]), 0); + +// memory_copy.wast:3462 +assert_return(() => call($17, "load8_u", [43_978]), 0); + +// memory_copy.wast:3463 +assert_return(() => call($17, "load8_u", [44_177]), 0); + +// memory_copy.wast:3464 +assert_return(() => call($17, "load8_u", [44_376]), 0); + +// memory_copy.wast:3465 +assert_return(() => call($17, "load8_u", [44_575]), 0); + +// memory_copy.wast:3466 +assert_return(() => call($17, "load8_u", [44_774]), 0); + +// memory_copy.wast:3467 +assert_return(() => call($17, "load8_u", [44_973]), 0); + +// memory_copy.wast:3468 +assert_return(() => call($17, "load8_u", [45_172]), 0); + +// memory_copy.wast:3469 +assert_return(() => call($17, "load8_u", [45_371]), 0); + +// memory_copy.wast:3470 +assert_return(() => call($17, "load8_u", [45_570]), 0); + +// memory_copy.wast:3471 +assert_return(() => call($17, "load8_u", [45_769]), 0); + +// memory_copy.wast:3472 +assert_return(() => call($17, "load8_u", [45_968]), 0); + +// memory_copy.wast:3473 +assert_return(() => call($17, "load8_u", [46_167]), 0); + +// memory_copy.wast:3474 +assert_return(() => call($17, "load8_u", [46_366]), 0); + +// memory_copy.wast:3475 +assert_return(() => call($17, "load8_u", [46_565]), 0); + +// memory_copy.wast:3476 +assert_return(() => call($17, "load8_u", [46_764]), 0); + +// memory_copy.wast:3477 +assert_return(() => call($17, "load8_u", [46_963]), 0); + +// memory_copy.wast:3478 +assert_return(() => call($17, "load8_u", [47_162]), 0); + +// memory_copy.wast:3479 +assert_return(() => call($17, "load8_u", [47_361]), 0); + +// memory_copy.wast:3480 +assert_return(() => call($17, "load8_u", [47_560]), 0); + +// memory_copy.wast:3481 +assert_return(() => call($17, "load8_u", [47_759]), 0); + +// memory_copy.wast:3482 +assert_return(() => call($17, "load8_u", [47_958]), 0); + +// memory_copy.wast:3483 +assert_return(() => call($17, "load8_u", [48_157]), 0); + +// memory_copy.wast:3484 +assert_return(() => call($17, "load8_u", [48_356]), 0); + +// memory_copy.wast:3485 +assert_return(() => call($17, "load8_u", [48_555]), 0); + +// memory_copy.wast:3486 +assert_return(() => call($17, "load8_u", [48_754]), 0); + +// memory_copy.wast:3487 +assert_return(() => call($17, "load8_u", [48_953]), 0); + +// memory_copy.wast:3488 +assert_return(() => call($17, "load8_u", [49_152]), 0); + +// memory_copy.wast:3489 +assert_return(() => call($17, "load8_u", [49_351]), 0); + +// memory_copy.wast:3490 +assert_return(() => call($17, "load8_u", [49_550]), 0); + +// memory_copy.wast:3491 +assert_return(() => call($17, "load8_u", [49_749]), 0); + +// memory_copy.wast:3492 +assert_return(() => call($17, "load8_u", [49_948]), 0); + +// memory_copy.wast:3493 +assert_return(() => call($17, "load8_u", [50_147]), 0); + +// memory_copy.wast:3494 +assert_return(() => call($17, "load8_u", [50_346]), 0); + +// memory_copy.wast:3495 +assert_return(() => call($17, "load8_u", [50_545]), 0); + +// memory_copy.wast:3496 +assert_return(() => call($17, "load8_u", [50_744]), 0); + +// memory_copy.wast:3497 +assert_return(() => call($17, "load8_u", [50_943]), 0); + +// memory_copy.wast:3498 +assert_return(() => call($17, "load8_u", [51_142]), 0); + +// memory_copy.wast:3499 +assert_return(() => call($17, "load8_u", [51_341]), 0); + +// memory_copy.wast:3500 +assert_return(() => call($17, "load8_u", [51_540]), 0); + +// memory_copy.wast:3501 +assert_return(() => call($17, "load8_u", [51_739]), 0); + +// memory_copy.wast:3502 +assert_return(() => call($17, "load8_u", [51_938]), 0); + +// memory_copy.wast:3503 +assert_return(() => call($17, "load8_u", [52_137]), 0); + +// memory_copy.wast:3504 +assert_return(() => call($17, "load8_u", [52_336]), 0); + +// memory_copy.wast:3505 +assert_return(() => call($17, "load8_u", [52_535]), 0); + +// memory_copy.wast:3506 +assert_return(() => call($17, "load8_u", [52_734]), 0); + +// memory_copy.wast:3507 +assert_return(() => call($17, "load8_u", [52_933]), 0); + +// memory_copy.wast:3508 +assert_return(() => call($17, "load8_u", [53_132]), 0); + +// memory_copy.wast:3509 +assert_return(() => call($17, "load8_u", [53_331]), 0); + +// memory_copy.wast:3510 +assert_return(() => call($17, "load8_u", [53_530]), 0); + +// memory_copy.wast:3511 +assert_return(() => call($17, "load8_u", [53_729]), 0); + +// memory_copy.wast:3512 +assert_return(() => call($17, "load8_u", [53_928]), 0); + +// memory_copy.wast:3513 +assert_return(() => call($17, "load8_u", [54_127]), 0); + +// memory_copy.wast:3514 +assert_return(() => call($17, "load8_u", [54_326]), 0); + +// memory_copy.wast:3515 +assert_return(() => call($17, "load8_u", [54_525]), 0); + +// memory_copy.wast:3516 +assert_return(() => call($17, "load8_u", [54_724]), 0); + +// memory_copy.wast:3517 +assert_return(() => call($17, "load8_u", [54_923]), 0); + +// memory_copy.wast:3518 +assert_return(() => call($17, "load8_u", [55_122]), 0); + +// memory_copy.wast:3519 +assert_return(() => call($17, "load8_u", [55_321]), 0); + +// memory_copy.wast:3520 +assert_return(() => call($17, "load8_u", [55_520]), 0); + +// memory_copy.wast:3521 +assert_return(() => call($17, "load8_u", [55_719]), 0); + +// memory_copy.wast:3522 +assert_return(() => call($17, "load8_u", [55_918]), 0); + +// memory_copy.wast:3523 +assert_return(() => call($17, "load8_u", [56_117]), 0); + +// memory_copy.wast:3524 +assert_return(() => call($17, "load8_u", [56_316]), 0); + +// memory_copy.wast:3525 +assert_return(() => call($17, "load8_u", [56_515]), 0); + +// memory_copy.wast:3526 +assert_return(() => call($17, "load8_u", [56_714]), 0); + +// memory_copy.wast:3527 +assert_return(() => call($17, "load8_u", [56_913]), 0); + +// memory_copy.wast:3528 +assert_return(() => call($17, "load8_u", [57_112]), 0); + +// memory_copy.wast:3529 +assert_return(() => call($17, "load8_u", [57_311]), 0); + +// memory_copy.wast:3530 +assert_return(() => call($17, "load8_u", [57_510]), 0); + +// memory_copy.wast:3531 +assert_return(() => call($17, "load8_u", [57_709]), 0); + +// memory_copy.wast:3532 +assert_return(() => call($17, "load8_u", [57_908]), 0); + +// memory_copy.wast:3533 +assert_return(() => call($17, "load8_u", [58_107]), 0); + +// memory_copy.wast:3534 +assert_return(() => call($17, "load8_u", [58_306]), 0); + +// memory_copy.wast:3535 +assert_return(() => call($17, "load8_u", [58_505]), 0); + +// memory_copy.wast:3536 +assert_return(() => call($17, "load8_u", [58_704]), 0); + +// memory_copy.wast:3537 +assert_return(() => call($17, "load8_u", [58_903]), 0); + +// memory_copy.wast:3538 +assert_return(() => call($17, "load8_u", [59_102]), 0); + +// memory_copy.wast:3539 +assert_return(() => call($17, "load8_u", [59_301]), 0); + +// memory_copy.wast:3540 +assert_return(() => call($17, "load8_u", [59_500]), 0); + +// memory_copy.wast:3541 +assert_return(() => call($17, "load8_u", [59_699]), 0); + +// memory_copy.wast:3542 +assert_return(() => call($17, "load8_u", [59_898]), 0); + +// memory_copy.wast:3543 +assert_return(() => call($17, "load8_u", [60_097]), 0); + +// memory_copy.wast:3544 +assert_return(() => call($17, "load8_u", [60_296]), 0); + +// memory_copy.wast:3545 +assert_return(() => call($17, "load8_u", [60_495]), 0); + +// memory_copy.wast:3546 +assert_return(() => call($17, "load8_u", [60_694]), 0); + +// memory_copy.wast:3547 +assert_return(() => call($17, "load8_u", [60_893]), 0); + +// memory_copy.wast:3548 +assert_return(() => call($17, "load8_u", [61_092]), 0); + +// memory_copy.wast:3549 +assert_return(() => call($17, "load8_u", [61_291]), 0); + +// memory_copy.wast:3550 +assert_return(() => call($17, "load8_u", [61_490]), 0); + +// memory_copy.wast:3551 +assert_return(() => call($17, "load8_u", [61_689]), 0); + +// memory_copy.wast:3552 +assert_return(() => call($17, "load8_u", [61_888]), 0); + +// memory_copy.wast:3553 +assert_return(() => call($17, "load8_u", [62_087]), 0); + +// memory_copy.wast:3554 +assert_return(() => call($17, "load8_u", [62_286]), 0); + +// memory_copy.wast:3555 +assert_return(() => call($17, "load8_u", [62_485]), 0); + +// memory_copy.wast:3556 +assert_return(() => call($17, "load8_u", [62_684]), 0); + +// memory_copy.wast:3557 +assert_return(() => call($17, "load8_u", [62_883]), 0); + +// memory_copy.wast:3558 +assert_return(() => call($17, "load8_u", [63_082]), 0); + +// memory_copy.wast:3559 +assert_return(() => call($17, "load8_u", [63_281]), 0); + +// memory_copy.wast:3560 +assert_return(() => call($17, "load8_u", [63_480]), 0); + +// memory_copy.wast:3561 +assert_return(() => call($17, "load8_u", [63_679]), 0); + +// memory_copy.wast:3562 +assert_return(() => call($17, "load8_u", [63_878]), 0); + +// memory_copy.wast:3563 +assert_return(() => call($17, "load8_u", [64_077]), 0); + +// memory_copy.wast:3564 +assert_return(() => call($17, "load8_u", [64_276]), 0); + +// memory_copy.wast:3565 +assert_return(() => call($17, "load8_u", [64_475]), 0); + +// memory_copy.wast:3566 +assert_return(() => call($17, "load8_u", [64_674]), 0); + +// memory_copy.wast:3567 +assert_return(() => call($17, "load8_u", [64_873]), 0); + +// memory_copy.wast:3568 +assert_return(() => call($17, "load8_u", [65_072]), 0); + +// memory_copy.wast:3569 +assert_return(() => call($17, "load8_u", [65_271]), 0); + +// memory_copy.wast:3570 +assert_return(() => call($17, "load8_u", [65_470]), 0); + +// memory_copy.wast:3571 +assert_return(() => call($17, "load8_u", [65_516]), 0); + +// memory_copy.wast:3572 +assert_return(() => call($17, "load8_u", [65_517]), 1); + +// memory_copy.wast:3573 +assert_return(() => call($17, "load8_u", [65_518]), 2); + +// memory_copy.wast:3574 +assert_return(() => call($17, "load8_u", [65_519]), 3); + +// memory_copy.wast:3575 +assert_return(() => call($17, "load8_u", [65_520]), 4); + +// memory_copy.wast:3576 +assert_return(() => call($17, "load8_u", [65_521]), 5); + +// memory_copy.wast:3577 +assert_return(() => call($17, "load8_u", [65_522]), 6); + +// memory_copy.wast:3578 +assert_return(() => call($17, "load8_u", [65_523]), 7); + +// memory_copy.wast:3579 +assert_return(() => call($17, "load8_u", [65_524]), 8); + +// memory_copy.wast:3580 +assert_return(() => call($17, "load8_u", [65_525]), 9); + +// memory_copy.wast:3581 +assert_return(() => call($17, "load8_u", [65_526]), 10); + +// memory_copy.wast:3582 +assert_return(() => call($17, "load8_u", [65_527]), 11); + +// memory_copy.wast:3583 +assert_return(() => call($17, "load8_u", [65_528]), 12); + +// memory_copy.wast:3584 +assert_return(() => call($17, "load8_u", [65_529]), 13); + +// memory_copy.wast:3585 +assert_return(() => call($17, "load8_u", [65_530]), 14); + +// memory_copy.wast:3586 +assert_return(() => call($17, "load8_u", [65_531]), 15); + +// memory_copy.wast:3587 +assert_return(() => call($17, "load8_u", [65_532]), 16); + +// memory_copy.wast:3588 +assert_return(() => call($17, "load8_u", [65_533]), 17); + +// memory_copy.wast:3589 +assert_return(() => call($17, "load8_u", [65_534]), 18); + +// memory_copy.wast:3590 +assert_return(() => call($17, "load8_u", [65_535]), 19); + +// memory_copy.wast:3592 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3600 +assert_trap(() => call($18, "run", [0, 65_516, -4_096])); + +// memory_copy.wast:3603 +assert_return(() => call($18, "load8_u", [198]), 0); + +// memory_copy.wast:3604 +assert_return(() => call($18, "load8_u", [397]), 0); + +// memory_copy.wast:3605 +assert_return(() => call($18, "load8_u", [596]), 0); + +// memory_copy.wast:3606 +assert_return(() => call($18, "load8_u", [795]), 0); + +// memory_copy.wast:3607 +assert_return(() => call($18, "load8_u", [994]), 0); + +// memory_copy.wast:3608 +assert_return(() => call($18, "load8_u", [1_193]), 0); + +// memory_copy.wast:3609 +assert_return(() => call($18, "load8_u", [1_392]), 0); + +// memory_copy.wast:3610 +assert_return(() => call($18, "load8_u", [1_591]), 0); + +// memory_copy.wast:3611 +assert_return(() => call($18, "load8_u", [1_790]), 0); + +// memory_copy.wast:3612 +assert_return(() => call($18, "load8_u", [1_989]), 0); + +// memory_copy.wast:3613 +assert_return(() => call($18, "load8_u", [2_188]), 0); + +// memory_copy.wast:3614 +assert_return(() => call($18, "load8_u", [2_387]), 0); + +// memory_copy.wast:3615 +assert_return(() => call($18, "load8_u", [2_586]), 0); + +// memory_copy.wast:3616 +assert_return(() => call($18, "load8_u", [2_785]), 0); + +// memory_copy.wast:3617 +assert_return(() => call($18, "load8_u", [2_984]), 0); + +// memory_copy.wast:3618 +assert_return(() => call($18, "load8_u", [3_183]), 0); + +// memory_copy.wast:3619 +assert_return(() => call($18, "load8_u", [3_382]), 0); + +// memory_copy.wast:3620 +assert_return(() => call($18, "load8_u", [3_581]), 0); + +// memory_copy.wast:3621 +assert_return(() => call($18, "load8_u", [3_780]), 0); + +// memory_copy.wast:3622 +assert_return(() => call($18, "load8_u", [3_979]), 0); + +// memory_copy.wast:3623 +assert_return(() => call($18, "load8_u", [4_178]), 0); + +// memory_copy.wast:3624 +assert_return(() => call($18, "load8_u", [4_377]), 0); + +// memory_copy.wast:3625 +assert_return(() => call($18, "load8_u", [4_576]), 0); + +// memory_copy.wast:3626 +assert_return(() => call($18, "load8_u", [4_775]), 0); + +// memory_copy.wast:3627 +assert_return(() => call($18, "load8_u", [4_974]), 0); + +// memory_copy.wast:3628 +assert_return(() => call($18, "load8_u", [5_173]), 0); + +// memory_copy.wast:3629 +assert_return(() => call($18, "load8_u", [5_372]), 0); + +// memory_copy.wast:3630 +assert_return(() => call($18, "load8_u", [5_571]), 0); + +// memory_copy.wast:3631 +assert_return(() => call($18, "load8_u", [5_770]), 0); + +// memory_copy.wast:3632 +assert_return(() => call($18, "load8_u", [5_969]), 0); + +// memory_copy.wast:3633 +assert_return(() => call($18, "load8_u", [6_168]), 0); + +// memory_copy.wast:3634 +assert_return(() => call($18, "load8_u", [6_367]), 0); + +// memory_copy.wast:3635 +assert_return(() => call($18, "load8_u", [6_566]), 0); + +// memory_copy.wast:3636 +assert_return(() => call($18, "load8_u", [6_765]), 0); + +// memory_copy.wast:3637 +assert_return(() => call($18, "load8_u", [6_964]), 0); + +// memory_copy.wast:3638 +assert_return(() => call($18, "load8_u", [7_163]), 0); + +// memory_copy.wast:3639 +assert_return(() => call($18, "load8_u", [7_362]), 0); + +// memory_copy.wast:3640 +assert_return(() => call($18, "load8_u", [7_561]), 0); + +// memory_copy.wast:3641 +assert_return(() => call($18, "load8_u", [7_760]), 0); + +// memory_copy.wast:3642 +assert_return(() => call($18, "load8_u", [7_959]), 0); + +// memory_copy.wast:3643 +assert_return(() => call($18, "load8_u", [8_158]), 0); + +// memory_copy.wast:3644 +assert_return(() => call($18, "load8_u", [8_357]), 0); + +// memory_copy.wast:3645 +assert_return(() => call($18, "load8_u", [8_556]), 0); + +// memory_copy.wast:3646 +assert_return(() => call($18, "load8_u", [8_755]), 0); + +// memory_copy.wast:3647 +assert_return(() => call($18, "load8_u", [8_954]), 0); + +// memory_copy.wast:3648 +assert_return(() => call($18, "load8_u", [9_153]), 0); + +// memory_copy.wast:3649 +assert_return(() => call($18, "load8_u", [9_352]), 0); + +// memory_copy.wast:3650 +assert_return(() => call($18, "load8_u", [9_551]), 0); + +// memory_copy.wast:3651 +assert_return(() => call($18, "load8_u", [9_750]), 0); + +// memory_copy.wast:3652 +assert_return(() => call($18, "load8_u", [9_949]), 0); + +// memory_copy.wast:3653 +assert_return(() => call($18, "load8_u", [10_148]), 0); + +// memory_copy.wast:3654 +assert_return(() => call($18, "load8_u", [10_347]), 0); + +// memory_copy.wast:3655 +assert_return(() => call($18, "load8_u", [10_546]), 0); + +// memory_copy.wast:3656 +assert_return(() => call($18, "load8_u", [10_745]), 0); + +// memory_copy.wast:3657 +assert_return(() => call($18, "load8_u", [10_944]), 0); + +// memory_copy.wast:3658 +assert_return(() => call($18, "load8_u", [11_143]), 0); + +// memory_copy.wast:3659 +assert_return(() => call($18, "load8_u", [11_342]), 0); + +// memory_copy.wast:3660 +assert_return(() => call($18, "load8_u", [11_541]), 0); + +// memory_copy.wast:3661 +assert_return(() => call($18, "load8_u", [11_740]), 0); + +// memory_copy.wast:3662 +assert_return(() => call($18, "load8_u", [11_939]), 0); + +// memory_copy.wast:3663 +assert_return(() => call($18, "load8_u", [12_138]), 0); + +// memory_copy.wast:3664 +assert_return(() => call($18, "load8_u", [12_337]), 0); + +// memory_copy.wast:3665 +assert_return(() => call($18, "load8_u", [12_536]), 0); + +// memory_copy.wast:3666 +assert_return(() => call($18, "load8_u", [12_735]), 0); + +// memory_copy.wast:3667 +assert_return(() => call($18, "load8_u", [12_934]), 0); + +// memory_copy.wast:3668 +assert_return(() => call($18, "load8_u", [13_133]), 0); + +// memory_copy.wast:3669 +assert_return(() => call($18, "load8_u", [13_332]), 0); + +// memory_copy.wast:3670 +assert_return(() => call($18, "load8_u", [13_531]), 0); + +// memory_copy.wast:3671 +assert_return(() => call($18, "load8_u", [13_730]), 0); + +// memory_copy.wast:3672 +assert_return(() => call($18, "load8_u", [13_929]), 0); + +// memory_copy.wast:3673 +assert_return(() => call($18, "load8_u", [14_128]), 0); + +// memory_copy.wast:3674 +assert_return(() => call($18, "load8_u", [14_327]), 0); + +// memory_copy.wast:3675 +assert_return(() => call($18, "load8_u", [14_526]), 0); + +// memory_copy.wast:3676 +assert_return(() => call($18, "load8_u", [14_725]), 0); + +// memory_copy.wast:3677 +assert_return(() => call($18, "load8_u", [14_924]), 0); + +// memory_copy.wast:3678 +assert_return(() => call($18, "load8_u", [15_123]), 0); + +// memory_copy.wast:3679 +assert_return(() => call($18, "load8_u", [15_322]), 0); + +// memory_copy.wast:3680 +assert_return(() => call($18, "load8_u", [15_521]), 0); + +// memory_copy.wast:3681 +assert_return(() => call($18, "load8_u", [15_720]), 0); + +// memory_copy.wast:3682 +assert_return(() => call($18, "load8_u", [15_919]), 0); + +// memory_copy.wast:3683 +assert_return(() => call($18, "load8_u", [16_118]), 0); + +// memory_copy.wast:3684 +assert_return(() => call($18, "load8_u", [16_317]), 0); + +// memory_copy.wast:3685 +assert_return(() => call($18, "load8_u", [16_516]), 0); + +// memory_copy.wast:3686 +assert_return(() => call($18, "load8_u", [16_715]), 0); + +// memory_copy.wast:3687 +assert_return(() => call($18, "load8_u", [16_914]), 0); + +// memory_copy.wast:3688 +assert_return(() => call($18, "load8_u", [17_113]), 0); + +// memory_copy.wast:3689 +assert_return(() => call($18, "load8_u", [17_312]), 0); + +// memory_copy.wast:3690 +assert_return(() => call($18, "load8_u", [17_511]), 0); + +// memory_copy.wast:3691 +assert_return(() => call($18, "load8_u", [17_710]), 0); + +// memory_copy.wast:3692 +assert_return(() => call($18, "load8_u", [17_909]), 0); + +// memory_copy.wast:3693 +assert_return(() => call($18, "load8_u", [18_108]), 0); + +// memory_copy.wast:3694 +assert_return(() => call($18, "load8_u", [18_307]), 0); + +// memory_copy.wast:3695 +assert_return(() => call($18, "load8_u", [18_506]), 0); + +// memory_copy.wast:3696 +assert_return(() => call($18, "load8_u", [18_705]), 0); + +// memory_copy.wast:3697 +assert_return(() => call($18, "load8_u", [18_904]), 0); + +// memory_copy.wast:3698 +assert_return(() => call($18, "load8_u", [19_103]), 0); + +// memory_copy.wast:3699 +assert_return(() => call($18, "load8_u", [19_302]), 0); + +// memory_copy.wast:3700 +assert_return(() => call($18, "load8_u", [19_501]), 0); + +// memory_copy.wast:3701 +assert_return(() => call($18, "load8_u", [19_700]), 0); + +// memory_copy.wast:3702 +assert_return(() => call($18, "load8_u", [19_899]), 0); + +// memory_copy.wast:3703 +assert_return(() => call($18, "load8_u", [20_098]), 0); + +// memory_copy.wast:3704 +assert_return(() => call($18, "load8_u", [20_297]), 0); + +// memory_copy.wast:3705 +assert_return(() => call($18, "load8_u", [20_496]), 0); + +// memory_copy.wast:3706 +assert_return(() => call($18, "load8_u", [20_695]), 0); + +// memory_copy.wast:3707 +assert_return(() => call($18, "load8_u", [20_894]), 0); + +// memory_copy.wast:3708 +assert_return(() => call($18, "load8_u", [21_093]), 0); + +// memory_copy.wast:3709 +assert_return(() => call($18, "load8_u", [21_292]), 0); + +// memory_copy.wast:3710 +assert_return(() => call($18, "load8_u", [21_491]), 0); + +// memory_copy.wast:3711 +assert_return(() => call($18, "load8_u", [21_690]), 0); + +// memory_copy.wast:3712 +assert_return(() => call($18, "load8_u", [21_889]), 0); + +// memory_copy.wast:3713 +assert_return(() => call($18, "load8_u", [22_088]), 0); + +// memory_copy.wast:3714 +assert_return(() => call($18, "load8_u", [22_287]), 0); + +// memory_copy.wast:3715 +assert_return(() => call($18, "load8_u", [22_486]), 0); + +// memory_copy.wast:3716 +assert_return(() => call($18, "load8_u", [22_685]), 0); + +// memory_copy.wast:3717 +assert_return(() => call($18, "load8_u", [22_884]), 0); + +// memory_copy.wast:3718 +assert_return(() => call($18, "load8_u", [23_083]), 0); + +// memory_copy.wast:3719 +assert_return(() => call($18, "load8_u", [23_282]), 0); + +// memory_copy.wast:3720 +assert_return(() => call($18, "load8_u", [23_481]), 0); + +// memory_copy.wast:3721 +assert_return(() => call($18, "load8_u", [23_680]), 0); + +// memory_copy.wast:3722 +assert_return(() => call($18, "load8_u", [23_879]), 0); + +// memory_copy.wast:3723 +assert_return(() => call($18, "load8_u", [24_078]), 0); + +// memory_copy.wast:3724 +assert_return(() => call($18, "load8_u", [24_277]), 0); + +// memory_copy.wast:3725 +assert_return(() => call($18, "load8_u", [24_476]), 0); + +// memory_copy.wast:3726 +assert_return(() => call($18, "load8_u", [24_675]), 0); + +// memory_copy.wast:3727 +assert_return(() => call($18, "load8_u", [24_874]), 0); + +// memory_copy.wast:3728 +assert_return(() => call($18, "load8_u", [25_073]), 0); + +// memory_copy.wast:3729 +assert_return(() => call($18, "load8_u", [25_272]), 0); + +// memory_copy.wast:3730 +assert_return(() => call($18, "load8_u", [25_471]), 0); + +// memory_copy.wast:3731 +assert_return(() => call($18, "load8_u", [25_670]), 0); + +// memory_copy.wast:3732 +assert_return(() => call($18, "load8_u", [25_869]), 0); + +// memory_copy.wast:3733 +assert_return(() => call($18, "load8_u", [26_068]), 0); + +// memory_copy.wast:3734 +assert_return(() => call($18, "load8_u", [26_267]), 0); + +// memory_copy.wast:3735 +assert_return(() => call($18, "load8_u", [26_466]), 0); + +// memory_copy.wast:3736 +assert_return(() => call($18, "load8_u", [26_665]), 0); + +// memory_copy.wast:3737 +assert_return(() => call($18, "load8_u", [26_864]), 0); + +// memory_copy.wast:3738 +assert_return(() => call($18, "load8_u", [27_063]), 0); + +// memory_copy.wast:3739 +assert_return(() => call($18, "load8_u", [27_262]), 0); + +// memory_copy.wast:3740 +assert_return(() => call($18, "load8_u", [27_461]), 0); + +// memory_copy.wast:3741 +assert_return(() => call($18, "load8_u", [27_660]), 0); + +// memory_copy.wast:3742 +assert_return(() => call($18, "load8_u", [27_859]), 0); + +// memory_copy.wast:3743 +assert_return(() => call($18, "load8_u", [28_058]), 0); + +// memory_copy.wast:3744 +assert_return(() => call($18, "load8_u", [28_257]), 0); + +// memory_copy.wast:3745 +assert_return(() => call($18, "load8_u", [28_456]), 0); + +// memory_copy.wast:3746 +assert_return(() => call($18, "load8_u", [28_655]), 0); + +// memory_copy.wast:3747 +assert_return(() => call($18, "load8_u", [28_854]), 0); + +// memory_copy.wast:3748 +assert_return(() => call($18, "load8_u", [29_053]), 0); + +// memory_copy.wast:3749 +assert_return(() => call($18, "load8_u", [29_252]), 0); + +// memory_copy.wast:3750 +assert_return(() => call($18, "load8_u", [29_451]), 0); + +// memory_copy.wast:3751 +assert_return(() => call($18, "load8_u", [29_650]), 0); + +// memory_copy.wast:3752 +assert_return(() => call($18, "load8_u", [29_849]), 0); + +// memory_copy.wast:3753 +assert_return(() => call($18, "load8_u", [30_048]), 0); + +// memory_copy.wast:3754 +assert_return(() => call($18, "load8_u", [30_247]), 0); + +// memory_copy.wast:3755 +assert_return(() => call($18, "load8_u", [30_446]), 0); + +// memory_copy.wast:3756 +assert_return(() => call($18, "load8_u", [30_645]), 0); + +// memory_copy.wast:3757 +assert_return(() => call($18, "load8_u", [30_844]), 0); + +// memory_copy.wast:3758 +assert_return(() => call($18, "load8_u", [31_043]), 0); + +// memory_copy.wast:3759 +assert_return(() => call($18, "load8_u", [31_242]), 0); + +// memory_copy.wast:3760 +assert_return(() => call($18, "load8_u", [31_441]), 0); + +// memory_copy.wast:3761 +assert_return(() => call($18, "load8_u", [31_640]), 0); + +// memory_copy.wast:3762 +assert_return(() => call($18, "load8_u", [31_839]), 0); + +// memory_copy.wast:3763 +assert_return(() => call($18, "load8_u", [32_038]), 0); + +// memory_copy.wast:3764 +assert_return(() => call($18, "load8_u", [32_237]), 0); + +// memory_copy.wast:3765 +assert_return(() => call($18, "load8_u", [32_436]), 0); + +// memory_copy.wast:3766 +assert_return(() => call($18, "load8_u", [32_635]), 0); + +// memory_copy.wast:3767 +assert_return(() => call($18, "load8_u", [32_834]), 0); + +// memory_copy.wast:3768 +assert_return(() => call($18, "load8_u", [33_033]), 0); + +// memory_copy.wast:3769 +assert_return(() => call($18, "load8_u", [33_232]), 0); + +// memory_copy.wast:3770 +assert_return(() => call($18, "load8_u", [33_431]), 0); + +// memory_copy.wast:3771 +assert_return(() => call($18, "load8_u", [33_630]), 0); + +// memory_copy.wast:3772 +assert_return(() => call($18, "load8_u", [33_829]), 0); + +// memory_copy.wast:3773 +assert_return(() => call($18, "load8_u", [34_028]), 0); + +// memory_copy.wast:3774 +assert_return(() => call($18, "load8_u", [34_227]), 0); + +// memory_copy.wast:3775 +assert_return(() => call($18, "load8_u", [34_426]), 0); + +// memory_copy.wast:3776 +assert_return(() => call($18, "load8_u", [34_625]), 0); + +// memory_copy.wast:3777 +assert_return(() => call($18, "load8_u", [34_824]), 0); + +// memory_copy.wast:3778 +assert_return(() => call($18, "load8_u", [35_023]), 0); + +// memory_copy.wast:3779 +assert_return(() => call($18, "load8_u", [35_222]), 0); + +// memory_copy.wast:3780 +assert_return(() => call($18, "load8_u", [35_421]), 0); + +// memory_copy.wast:3781 +assert_return(() => call($18, "load8_u", [35_620]), 0); + +// memory_copy.wast:3782 +assert_return(() => call($18, "load8_u", [35_819]), 0); + +// memory_copy.wast:3783 +assert_return(() => call($18, "load8_u", [36_018]), 0); + +// memory_copy.wast:3784 +assert_return(() => call($18, "load8_u", [36_217]), 0); + +// memory_copy.wast:3785 +assert_return(() => call($18, "load8_u", [36_416]), 0); + +// memory_copy.wast:3786 +assert_return(() => call($18, "load8_u", [36_615]), 0); + +// memory_copy.wast:3787 +assert_return(() => call($18, "load8_u", [36_814]), 0); + +// memory_copy.wast:3788 +assert_return(() => call($18, "load8_u", [37_013]), 0); + +// memory_copy.wast:3789 +assert_return(() => call($18, "load8_u", [37_212]), 0); + +// memory_copy.wast:3790 +assert_return(() => call($18, "load8_u", [37_411]), 0); + +// memory_copy.wast:3791 +assert_return(() => call($18, "load8_u", [37_610]), 0); + +// memory_copy.wast:3792 +assert_return(() => call($18, "load8_u", [37_809]), 0); + +// memory_copy.wast:3793 +assert_return(() => call($18, "load8_u", [38_008]), 0); + +// memory_copy.wast:3794 +assert_return(() => call($18, "load8_u", [38_207]), 0); + +// memory_copy.wast:3795 +assert_return(() => call($18, "load8_u", [38_406]), 0); + +// memory_copy.wast:3796 +assert_return(() => call($18, "load8_u", [38_605]), 0); + +// memory_copy.wast:3797 +assert_return(() => call($18, "load8_u", [38_804]), 0); + +// memory_copy.wast:3798 +assert_return(() => call($18, "load8_u", [39_003]), 0); + +// memory_copy.wast:3799 +assert_return(() => call($18, "load8_u", [39_202]), 0); + +// memory_copy.wast:3800 +assert_return(() => call($18, "load8_u", [39_401]), 0); + +// memory_copy.wast:3801 +assert_return(() => call($18, "load8_u", [39_600]), 0); + +// memory_copy.wast:3802 +assert_return(() => call($18, "load8_u", [39_799]), 0); + +// memory_copy.wast:3803 +assert_return(() => call($18, "load8_u", [39_998]), 0); + +// memory_copy.wast:3804 +assert_return(() => call($18, "load8_u", [40_197]), 0); + +// memory_copy.wast:3805 +assert_return(() => call($18, "load8_u", [40_396]), 0); + +// memory_copy.wast:3806 +assert_return(() => call($18, "load8_u", [40_595]), 0); + +// memory_copy.wast:3807 +assert_return(() => call($18, "load8_u", [40_794]), 0); + +// memory_copy.wast:3808 +assert_return(() => call($18, "load8_u", [40_993]), 0); + +// memory_copy.wast:3809 +assert_return(() => call($18, "load8_u", [41_192]), 0); + +// memory_copy.wast:3810 +assert_return(() => call($18, "load8_u", [41_391]), 0); + +// memory_copy.wast:3811 +assert_return(() => call($18, "load8_u", [41_590]), 0); + +// memory_copy.wast:3812 +assert_return(() => call($18, "load8_u", [41_789]), 0); + +// memory_copy.wast:3813 +assert_return(() => call($18, "load8_u", [41_988]), 0); + +// memory_copy.wast:3814 +assert_return(() => call($18, "load8_u", [42_187]), 0); + +// memory_copy.wast:3815 +assert_return(() => call($18, "load8_u", [42_386]), 0); + +// memory_copy.wast:3816 +assert_return(() => call($18, "load8_u", [42_585]), 0); + +// memory_copy.wast:3817 +assert_return(() => call($18, "load8_u", [42_784]), 0); + +// memory_copy.wast:3818 +assert_return(() => call($18, "load8_u", [42_983]), 0); + +// memory_copy.wast:3819 +assert_return(() => call($18, "load8_u", [43_182]), 0); + +// memory_copy.wast:3820 +assert_return(() => call($18, "load8_u", [43_381]), 0); + +// memory_copy.wast:3821 +assert_return(() => call($18, "load8_u", [43_580]), 0); + +// memory_copy.wast:3822 +assert_return(() => call($18, "load8_u", [43_779]), 0); + +// memory_copy.wast:3823 +assert_return(() => call($18, "load8_u", [43_978]), 0); + +// memory_copy.wast:3824 +assert_return(() => call($18, "load8_u", [44_177]), 0); + +// memory_copy.wast:3825 +assert_return(() => call($18, "load8_u", [44_376]), 0); + +// memory_copy.wast:3826 +assert_return(() => call($18, "load8_u", [44_575]), 0); + +// memory_copy.wast:3827 +assert_return(() => call($18, "load8_u", [44_774]), 0); + +// memory_copy.wast:3828 +assert_return(() => call($18, "load8_u", [44_973]), 0); + +// memory_copy.wast:3829 +assert_return(() => call($18, "load8_u", [45_172]), 0); + +// memory_copy.wast:3830 +assert_return(() => call($18, "load8_u", [45_371]), 0); + +// memory_copy.wast:3831 +assert_return(() => call($18, "load8_u", [45_570]), 0); + +// memory_copy.wast:3832 +assert_return(() => call($18, "load8_u", [45_769]), 0); + +// memory_copy.wast:3833 +assert_return(() => call($18, "load8_u", [45_968]), 0); + +// memory_copy.wast:3834 +assert_return(() => call($18, "load8_u", [46_167]), 0); + +// memory_copy.wast:3835 +assert_return(() => call($18, "load8_u", [46_366]), 0); + +// memory_copy.wast:3836 +assert_return(() => call($18, "load8_u", [46_565]), 0); + +// memory_copy.wast:3837 +assert_return(() => call($18, "load8_u", [46_764]), 0); + +// memory_copy.wast:3838 +assert_return(() => call($18, "load8_u", [46_963]), 0); + +// memory_copy.wast:3839 +assert_return(() => call($18, "load8_u", [47_162]), 0); + +// memory_copy.wast:3840 +assert_return(() => call($18, "load8_u", [47_361]), 0); + +// memory_copy.wast:3841 +assert_return(() => call($18, "load8_u", [47_560]), 0); + +// memory_copy.wast:3842 +assert_return(() => call($18, "load8_u", [47_759]), 0); + +// memory_copy.wast:3843 +assert_return(() => call($18, "load8_u", [47_958]), 0); + +// memory_copy.wast:3844 +assert_return(() => call($18, "load8_u", [48_157]), 0); + +// memory_copy.wast:3845 +assert_return(() => call($18, "load8_u", [48_356]), 0); + +// memory_copy.wast:3846 +assert_return(() => call($18, "load8_u", [48_555]), 0); + +// memory_copy.wast:3847 +assert_return(() => call($18, "load8_u", [48_754]), 0); + +// memory_copy.wast:3848 +assert_return(() => call($18, "load8_u", [48_953]), 0); + +// memory_copy.wast:3849 +assert_return(() => call($18, "load8_u", [49_152]), 0); + +// memory_copy.wast:3850 +assert_return(() => call($18, "load8_u", [49_351]), 0); + +// memory_copy.wast:3851 +assert_return(() => call($18, "load8_u", [49_550]), 0); + +// memory_copy.wast:3852 +assert_return(() => call($18, "load8_u", [49_749]), 0); + +// memory_copy.wast:3853 +assert_return(() => call($18, "load8_u", [49_948]), 0); + +// memory_copy.wast:3854 +assert_return(() => call($18, "load8_u", [50_147]), 0); + +// memory_copy.wast:3855 +assert_return(() => call($18, "load8_u", [50_346]), 0); + +// memory_copy.wast:3856 +assert_return(() => call($18, "load8_u", [50_545]), 0); + +// memory_copy.wast:3857 +assert_return(() => call($18, "load8_u", [50_744]), 0); + +// memory_copy.wast:3858 +assert_return(() => call($18, "load8_u", [50_943]), 0); + +// memory_copy.wast:3859 +assert_return(() => call($18, "load8_u", [51_142]), 0); + +// memory_copy.wast:3860 +assert_return(() => call($18, "load8_u", [51_341]), 0); + +// memory_copy.wast:3861 +assert_return(() => call($18, "load8_u", [51_540]), 0); + +// memory_copy.wast:3862 +assert_return(() => call($18, "load8_u", [51_739]), 0); + +// memory_copy.wast:3863 +assert_return(() => call($18, "load8_u", [51_938]), 0); + +// memory_copy.wast:3864 +assert_return(() => call($18, "load8_u", [52_137]), 0); + +// memory_copy.wast:3865 +assert_return(() => call($18, "load8_u", [52_336]), 0); + +// memory_copy.wast:3866 +assert_return(() => call($18, "load8_u", [52_535]), 0); + +// memory_copy.wast:3867 +assert_return(() => call($18, "load8_u", [52_734]), 0); + +// memory_copy.wast:3868 +assert_return(() => call($18, "load8_u", [52_933]), 0); + +// memory_copy.wast:3869 +assert_return(() => call($18, "load8_u", [53_132]), 0); + +// memory_copy.wast:3870 +assert_return(() => call($18, "load8_u", [53_331]), 0); + +// memory_copy.wast:3871 +assert_return(() => call($18, "load8_u", [53_530]), 0); + +// memory_copy.wast:3872 +assert_return(() => call($18, "load8_u", [53_729]), 0); + +// memory_copy.wast:3873 +assert_return(() => call($18, "load8_u", [53_928]), 0); + +// memory_copy.wast:3874 +assert_return(() => call($18, "load8_u", [54_127]), 0); + +// memory_copy.wast:3875 +assert_return(() => call($18, "load8_u", [54_326]), 0); + +// memory_copy.wast:3876 +assert_return(() => call($18, "load8_u", [54_525]), 0); + +// memory_copy.wast:3877 +assert_return(() => call($18, "load8_u", [54_724]), 0); + +// memory_copy.wast:3878 +assert_return(() => call($18, "load8_u", [54_923]), 0); + +// memory_copy.wast:3879 +assert_return(() => call($18, "load8_u", [55_122]), 0); + +// memory_copy.wast:3880 +assert_return(() => call($18, "load8_u", [55_321]), 0); + +// memory_copy.wast:3881 +assert_return(() => call($18, "load8_u", [55_520]), 0); + +// memory_copy.wast:3882 +assert_return(() => call($18, "load8_u", [55_719]), 0); + +// memory_copy.wast:3883 +assert_return(() => call($18, "load8_u", [55_918]), 0); + +// memory_copy.wast:3884 +assert_return(() => call($18, "load8_u", [56_117]), 0); + +// memory_copy.wast:3885 +assert_return(() => call($18, "load8_u", [56_316]), 0); + +// memory_copy.wast:3886 +assert_return(() => call($18, "load8_u", [56_515]), 0); + +// memory_copy.wast:3887 +assert_return(() => call($18, "load8_u", [56_714]), 0); + +// memory_copy.wast:3888 +assert_return(() => call($18, "load8_u", [56_913]), 0); + +// memory_copy.wast:3889 +assert_return(() => call($18, "load8_u", [57_112]), 0); + +// memory_copy.wast:3890 +assert_return(() => call($18, "load8_u", [57_311]), 0); + +// memory_copy.wast:3891 +assert_return(() => call($18, "load8_u", [57_510]), 0); + +// memory_copy.wast:3892 +assert_return(() => call($18, "load8_u", [57_709]), 0); + +// memory_copy.wast:3893 +assert_return(() => call($18, "load8_u", [57_908]), 0); + +// memory_copy.wast:3894 +assert_return(() => call($18, "load8_u", [58_107]), 0); + +// memory_copy.wast:3895 +assert_return(() => call($18, "load8_u", [58_306]), 0); + +// memory_copy.wast:3896 +assert_return(() => call($18, "load8_u", [58_505]), 0); + +// memory_copy.wast:3897 +assert_return(() => call($18, "load8_u", [58_704]), 0); + +// memory_copy.wast:3898 +assert_return(() => call($18, "load8_u", [58_903]), 0); + +// memory_copy.wast:3899 +assert_return(() => call($18, "load8_u", [59_102]), 0); + +// memory_copy.wast:3900 +assert_return(() => call($18, "load8_u", [59_301]), 0); + +// memory_copy.wast:3901 +assert_return(() => call($18, "load8_u", [59_500]), 0); + +// memory_copy.wast:3902 +assert_return(() => call($18, "load8_u", [59_699]), 0); + +// memory_copy.wast:3903 +assert_return(() => call($18, "load8_u", [59_898]), 0); + +// memory_copy.wast:3904 +assert_return(() => call($18, "load8_u", [60_097]), 0); + +// memory_copy.wast:3905 +assert_return(() => call($18, "load8_u", [60_296]), 0); + +// memory_copy.wast:3906 +assert_return(() => call($18, "load8_u", [60_495]), 0); + +// memory_copy.wast:3907 +assert_return(() => call($18, "load8_u", [60_694]), 0); + +// memory_copy.wast:3908 +assert_return(() => call($18, "load8_u", [60_893]), 0); + +// memory_copy.wast:3909 +assert_return(() => call($18, "load8_u", [61_092]), 0); + +// memory_copy.wast:3910 +assert_return(() => call($18, "load8_u", [61_291]), 0); + +// memory_copy.wast:3911 +assert_return(() => call($18, "load8_u", [61_490]), 0); + +// memory_copy.wast:3912 +assert_return(() => call($18, "load8_u", [61_689]), 0); + +// memory_copy.wast:3913 +assert_return(() => call($18, "load8_u", [61_888]), 0); + +// memory_copy.wast:3914 +assert_return(() => call($18, "load8_u", [62_087]), 0); + +// memory_copy.wast:3915 +assert_return(() => call($18, "load8_u", [62_286]), 0); + +// memory_copy.wast:3916 +assert_return(() => call($18, "load8_u", [62_485]), 0); + +// memory_copy.wast:3917 +assert_return(() => call($18, "load8_u", [62_684]), 0); + +// memory_copy.wast:3918 +assert_return(() => call($18, "load8_u", [62_883]), 0); + +// memory_copy.wast:3919 +assert_return(() => call($18, "load8_u", [63_082]), 0); + +// memory_copy.wast:3920 +assert_return(() => call($18, "load8_u", [63_281]), 0); + +// memory_copy.wast:3921 +assert_return(() => call($18, "load8_u", [63_480]), 0); + +// memory_copy.wast:3922 +assert_return(() => call($18, "load8_u", [63_679]), 0); + +// memory_copy.wast:3923 +assert_return(() => call($18, "load8_u", [63_878]), 0); + +// memory_copy.wast:3924 +assert_return(() => call($18, "load8_u", [64_077]), 0); + +// memory_copy.wast:3925 +assert_return(() => call($18, "load8_u", [64_276]), 0); + +// memory_copy.wast:3926 +assert_return(() => call($18, "load8_u", [64_475]), 0); + +// memory_copy.wast:3927 +assert_return(() => call($18, "load8_u", [64_674]), 0); + +// memory_copy.wast:3928 +assert_return(() => call($18, "load8_u", [64_873]), 0); + +// memory_copy.wast:3929 +assert_return(() => call($18, "load8_u", [65_072]), 0); + +// memory_copy.wast:3930 +assert_return(() => call($18, "load8_u", [65_271]), 0); + +// memory_copy.wast:3931 +assert_return(() => call($18, "load8_u", [65_470]), 0); + +// memory_copy.wast:3932 +assert_return(() => call($18, "load8_u", [65_516]), 0); + +// memory_copy.wast:3933 +assert_return(() => call($18, "load8_u", [65_517]), 1); + +// memory_copy.wast:3934 +assert_return(() => call($18, "load8_u", [65_518]), 2); + +// memory_copy.wast:3935 +assert_return(() => call($18, "load8_u", [65_519]), 3); + +// memory_copy.wast:3936 +assert_return(() => call($18, "load8_u", [65_520]), 4); + +// memory_copy.wast:3937 +assert_return(() => call($18, "load8_u", [65_521]), 5); + +// memory_copy.wast:3938 +assert_return(() => call($18, "load8_u", [65_522]), 6); + +// memory_copy.wast:3939 +assert_return(() => call($18, "load8_u", [65_523]), 7); + +// memory_copy.wast:3940 +assert_return(() => call($18, "load8_u", [65_524]), 8); + +// memory_copy.wast:3941 +assert_return(() => call($18, "load8_u", [65_525]), 9); + +// memory_copy.wast:3942 +assert_return(() => call($18, "load8_u", [65_526]), 10); + +// memory_copy.wast:3943 +assert_return(() => call($18, "load8_u", [65_527]), 11); + +// memory_copy.wast:3944 +assert_return(() => call($18, "load8_u", [65_528]), 12); + +// memory_copy.wast:3945 +assert_return(() => call($18, "load8_u", [65_529]), 13); + +// memory_copy.wast:3946 +assert_return(() => call($18, "load8_u", [65_530]), 14); + +// memory_copy.wast:3947 +assert_return(() => call($18, "load8_u", [65_531]), 15); + +// memory_copy.wast:3948 +assert_return(() => call($18, "load8_u", [65_532]), 16); + +// memory_copy.wast:3949 +assert_return(() => call($18, "load8_u", [65_533]), 17); + +// memory_copy.wast:3950 +assert_return(() => call($18, "load8_u", [65_534]), 18); + +// memory_copy.wast:3951 +assert_return(() => call($18, "load8_u", [65_535]), 19); + +// memory_copy.wast:3953 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\x80\xe0\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3961 +assert_trap(() => call($19, "run", [65_516, 61_440, -256])); + +// memory_copy.wast:3964 +assert_return(() => call($19, "load8_u", [198]), 0); + +// memory_copy.wast:3965 +assert_return(() => call($19, "load8_u", [397]), 0); + +// memory_copy.wast:3966 +assert_return(() => call($19, "load8_u", [596]), 0); + +// memory_copy.wast:3967 +assert_return(() => call($19, "load8_u", [795]), 0); + +// memory_copy.wast:3968 +assert_return(() => call($19, "load8_u", [994]), 0); + +// memory_copy.wast:3969 +assert_return(() => call($19, "load8_u", [1_193]), 0); + +// memory_copy.wast:3970 +assert_return(() => call($19, "load8_u", [1_392]), 0); + +// memory_copy.wast:3971 +assert_return(() => call($19, "load8_u", [1_591]), 0); + +// memory_copy.wast:3972 +assert_return(() => call($19, "load8_u", [1_790]), 0); + +// memory_copy.wast:3973 +assert_return(() => call($19, "load8_u", [1_989]), 0); + +// memory_copy.wast:3974 +assert_return(() => call($19, "load8_u", [2_188]), 0); + +// memory_copy.wast:3975 +assert_return(() => call($19, "load8_u", [2_387]), 0); + +// memory_copy.wast:3976 +assert_return(() => call($19, "load8_u", [2_586]), 0); + +// memory_copy.wast:3977 +assert_return(() => call($19, "load8_u", [2_785]), 0); + +// memory_copy.wast:3978 +assert_return(() => call($19, "load8_u", [2_984]), 0); + +// memory_copy.wast:3979 +assert_return(() => call($19, "load8_u", [3_183]), 0); + +// memory_copy.wast:3980 +assert_return(() => call($19, "load8_u", [3_382]), 0); + +// memory_copy.wast:3981 +assert_return(() => call($19, "load8_u", [3_581]), 0); + +// memory_copy.wast:3982 +assert_return(() => call($19, "load8_u", [3_780]), 0); + +// memory_copy.wast:3983 +assert_return(() => call($19, "load8_u", [3_979]), 0); + +// memory_copy.wast:3984 +assert_return(() => call($19, "load8_u", [4_178]), 0); + +// memory_copy.wast:3985 +assert_return(() => call($19, "load8_u", [4_377]), 0); + +// memory_copy.wast:3986 +assert_return(() => call($19, "load8_u", [4_576]), 0); + +// memory_copy.wast:3987 +assert_return(() => call($19, "load8_u", [4_775]), 0); + +// memory_copy.wast:3988 +assert_return(() => call($19, "load8_u", [4_974]), 0); + +// memory_copy.wast:3989 +assert_return(() => call($19, "load8_u", [5_173]), 0); + +// memory_copy.wast:3990 +assert_return(() => call($19, "load8_u", [5_372]), 0); + +// memory_copy.wast:3991 +assert_return(() => call($19, "load8_u", [5_571]), 0); + +// memory_copy.wast:3992 +assert_return(() => call($19, "load8_u", [5_770]), 0); + +// memory_copy.wast:3993 +assert_return(() => call($19, "load8_u", [5_969]), 0); + +// memory_copy.wast:3994 +assert_return(() => call($19, "load8_u", [6_168]), 0); + +// memory_copy.wast:3995 +assert_return(() => call($19, "load8_u", [6_367]), 0); + +// memory_copy.wast:3996 +assert_return(() => call($19, "load8_u", [6_566]), 0); + +// memory_copy.wast:3997 +assert_return(() => call($19, "load8_u", [6_765]), 0); + +// memory_copy.wast:3998 +assert_return(() => call($19, "load8_u", [6_964]), 0); + +// memory_copy.wast:3999 +assert_return(() => call($19, "load8_u", [7_163]), 0); + +// memory_copy.wast:4000 +assert_return(() => call($19, "load8_u", [7_362]), 0); + +// memory_copy.wast:4001 +assert_return(() => call($19, "load8_u", [7_561]), 0); + +// memory_copy.wast:4002 +assert_return(() => call($19, "load8_u", [7_760]), 0); + +// memory_copy.wast:4003 +assert_return(() => call($19, "load8_u", [7_959]), 0); + +// memory_copy.wast:4004 +assert_return(() => call($19, "load8_u", [8_158]), 0); + +// memory_copy.wast:4005 +assert_return(() => call($19, "load8_u", [8_357]), 0); + +// memory_copy.wast:4006 +assert_return(() => call($19, "load8_u", [8_556]), 0); + +// memory_copy.wast:4007 +assert_return(() => call($19, "load8_u", [8_755]), 0); + +// memory_copy.wast:4008 +assert_return(() => call($19, "load8_u", [8_954]), 0); + +// memory_copy.wast:4009 +assert_return(() => call($19, "load8_u", [9_153]), 0); + +// memory_copy.wast:4010 +assert_return(() => call($19, "load8_u", [9_352]), 0); + +// memory_copy.wast:4011 +assert_return(() => call($19, "load8_u", [9_551]), 0); + +// memory_copy.wast:4012 +assert_return(() => call($19, "load8_u", [9_750]), 0); + +// memory_copy.wast:4013 +assert_return(() => call($19, "load8_u", [9_949]), 0); + +// memory_copy.wast:4014 +assert_return(() => call($19, "load8_u", [10_148]), 0); + +// memory_copy.wast:4015 +assert_return(() => call($19, "load8_u", [10_347]), 0); + +// memory_copy.wast:4016 +assert_return(() => call($19, "load8_u", [10_546]), 0); + +// memory_copy.wast:4017 +assert_return(() => call($19, "load8_u", [10_745]), 0); + +// memory_copy.wast:4018 +assert_return(() => call($19, "load8_u", [10_944]), 0); + +// memory_copy.wast:4019 +assert_return(() => call($19, "load8_u", [11_143]), 0); + +// memory_copy.wast:4020 +assert_return(() => call($19, "load8_u", [11_342]), 0); + +// memory_copy.wast:4021 +assert_return(() => call($19, "load8_u", [11_541]), 0); + +// memory_copy.wast:4022 +assert_return(() => call($19, "load8_u", [11_740]), 0); + +// memory_copy.wast:4023 +assert_return(() => call($19, "load8_u", [11_939]), 0); + +// memory_copy.wast:4024 +assert_return(() => call($19, "load8_u", [12_138]), 0); + +// memory_copy.wast:4025 +assert_return(() => call($19, "load8_u", [12_337]), 0); + +// memory_copy.wast:4026 +assert_return(() => call($19, "load8_u", [12_536]), 0); + +// memory_copy.wast:4027 +assert_return(() => call($19, "load8_u", [12_735]), 0); + +// memory_copy.wast:4028 +assert_return(() => call($19, "load8_u", [12_934]), 0); + +// memory_copy.wast:4029 +assert_return(() => call($19, "load8_u", [13_133]), 0); + +// memory_copy.wast:4030 +assert_return(() => call($19, "load8_u", [13_332]), 0); + +// memory_copy.wast:4031 +assert_return(() => call($19, "load8_u", [13_531]), 0); + +// memory_copy.wast:4032 +assert_return(() => call($19, "load8_u", [13_730]), 0); + +// memory_copy.wast:4033 +assert_return(() => call($19, "load8_u", [13_929]), 0); + +// memory_copy.wast:4034 +assert_return(() => call($19, "load8_u", [14_128]), 0); + +// memory_copy.wast:4035 +assert_return(() => call($19, "load8_u", [14_327]), 0); + +// memory_copy.wast:4036 +assert_return(() => call($19, "load8_u", [14_526]), 0); + +// memory_copy.wast:4037 +assert_return(() => call($19, "load8_u", [14_725]), 0); + +// memory_copy.wast:4038 +assert_return(() => call($19, "load8_u", [14_924]), 0); + +// memory_copy.wast:4039 +assert_return(() => call($19, "load8_u", [15_123]), 0); + +// memory_copy.wast:4040 +assert_return(() => call($19, "load8_u", [15_322]), 0); + +// memory_copy.wast:4041 +assert_return(() => call($19, "load8_u", [15_521]), 0); + +// memory_copy.wast:4042 +assert_return(() => call($19, "load8_u", [15_720]), 0); + +// memory_copy.wast:4043 +assert_return(() => call($19, "load8_u", [15_919]), 0); + +// memory_copy.wast:4044 +assert_return(() => call($19, "load8_u", [16_118]), 0); + +// memory_copy.wast:4045 +assert_return(() => call($19, "load8_u", [16_317]), 0); + +// memory_copy.wast:4046 +assert_return(() => call($19, "load8_u", [16_516]), 0); + +// memory_copy.wast:4047 +assert_return(() => call($19, "load8_u", [16_715]), 0); + +// memory_copy.wast:4048 +assert_return(() => call($19, "load8_u", [16_914]), 0); + +// memory_copy.wast:4049 +assert_return(() => call($19, "load8_u", [17_113]), 0); + +// memory_copy.wast:4050 +assert_return(() => call($19, "load8_u", [17_312]), 0); + +// memory_copy.wast:4051 +assert_return(() => call($19, "load8_u", [17_511]), 0); + +// memory_copy.wast:4052 +assert_return(() => call($19, "load8_u", [17_710]), 0); + +// memory_copy.wast:4053 +assert_return(() => call($19, "load8_u", [17_909]), 0); + +// memory_copy.wast:4054 +assert_return(() => call($19, "load8_u", [18_108]), 0); + +// memory_copy.wast:4055 +assert_return(() => call($19, "load8_u", [18_307]), 0); + +// memory_copy.wast:4056 +assert_return(() => call($19, "load8_u", [18_506]), 0); + +// memory_copy.wast:4057 +assert_return(() => call($19, "load8_u", [18_705]), 0); + +// memory_copy.wast:4058 +assert_return(() => call($19, "load8_u", [18_904]), 0); + +// memory_copy.wast:4059 +assert_return(() => call($19, "load8_u", [19_103]), 0); + +// memory_copy.wast:4060 +assert_return(() => call($19, "load8_u", [19_302]), 0); + +// memory_copy.wast:4061 +assert_return(() => call($19, "load8_u", [19_501]), 0); + +// memory_copy.wast:4062 +assert_return(() => call($19, "load8_u", [19_700]), 0); + +// memory_copy.wast:4063 +assert_return(() => call($19, "load8_u", [19_899]), 0); + +// memory_copy.wast:4064 +assert_return(() => call($19, "load8_u", [20_098]), 0); + +// memory_copy.wast:4065 +assert_return(() => call($19, "load8_u", [20_297]), 0); + +// memory_copy.wast:4066 +assert_return(() => call($19, "load8_u", [20_496]), 0); + +// memory_copy.wast:4067 +assert_return(() => call($19, "load8_u", [20_695]), 0); + +// memory_copy.wast:4068 +assert_return(() => call($19, "load8_u", [20_894]), 0); + +// memory_copy.wast:4069 +assert_return(() => call($19, "load8_u", [21_093]), 0); + +// memory_copy.wast:4070 +assert_return(() => call($19, "load8_u", [21_292]), 0); + +// memory_copy.wast:4071 +assert_return(() => call($19, "load8_u", [21_491]), 0); + +// memory_copy.wast:4072 +assert_return(() => call($19, "load8_u", [21_690]), 0); + +// memory_copy.wast:4073 +assert_return(() => call($19, "load8_u", [21_889]), 0); + +// memory_copy.wast:4074 +assert_return(() => call($19, "load8_u", [22_088]), 0); + +// memory_copy.wast:4075 +assert_return(() => call($19, "load8_u", [22_287]), 0); + +// memory_copy.wast:4076 +assert_return(() => call($19, "load8_u", [22_486]), 0); + +// memory_copy.wast:4077 +assert_return(() => call($19, "load8_u", [22_685]), 0); + +// memory_copy.wast:4078 +assert_return(() => call($19, "load8_u", [22_884]), 0); + +// memory_copy.wast:4079 +assert_return(() => call($19, "load8_u", [23_083]), 0); + +// memory_copy.wast:4080 +assert_return(() => call($19, "load8_u", [23_282]), 0); + +// memory_copy.wast:4081 +assert_return(() => call($19, "load8_u", [23_481]), 0); + +// memory_copy.wast:4082 +assert_return(() => call($19, "load8_u", [23_680]), 0); + +// memory_copy.wast:4083 +assert_return(() => call($19, "load8_u", [23_879]), 0); + +// memory_copy.wast:4084 +assert_return(() => call($19, "load8_u", [24_078]), 0); + +// memory_copy.wast:4085 +assert_return(() => call($19, "load8_u", [24_277]), 0); + +// memory_copy.wast:4086 +assert_return(() => call($19, "load8_u", [24_476]), 0); + +// memory_copy.wast:4087 +assert_return(() => call($19, "load8_u", [24_675]), 0); + +// memory_copy.wast:4088 +assert_return(() => call($19, "load8_u", [24_874]), 0); + +// memory_copy.wast:4089 +assert_return(() => call($19, "load8_u", [25_073]), 0); + +// memory_copy.wast:4090 +assert_return(() => call($19, "load8_u", [25_272]), 0); + +// memory_copy.wast:4091 +assert_return(() => call($19, "load8_u", [25_471]), 0); + +// memory_copy.wast:4092 +assert_return(() => call($19, "load8_u", [25_670]), 0); + +// memory_copy.wast:4093 +assert_return(() => call($19, "load8_u", [25_869]), 0); + +// memory_copy.wast:4094 +assert_return(() => call($19, "load8_u", [26_068]), 0); + +// memory_copy.wast:4095 +assert_return(() => call($19, "load8_u", [26_267]), 0); + +// memory_copy.wast:4096 +assert_return(() => call($19, "load8_u", [26_466]), 0); + +// memory_copy.wast:4097 +assert_return(() => call($19, "load8_u", [26_665]), 0); + +// memory_copy.wast:4098 +assert_return(() => call($19, "load8_u", [26_864]), 0); + +// memory_copy.wast:4099 +assert_return(() => call($19, "load8_u", [27_063]), 0); + +// memory_copy.wast:4100 +assert_return(() => call($19, "load8_u", [27_262]), 0); + +// memory_copy.wast:4101 +assert_return(() => call($19, "load8_u", [27_461]), 0); + +// memory_copy.wast:4102 +assert_return(() => call($19, "load8_u", [27_660]), 0); + +// memory_copy.wast:4103 +assert_return(() => call($19, "load8_u", [27_859]), 0); + +// memory_copy.wast:4104 +assert_return(() => call($19, "load8_u", [28_058]), 0); + +// memory_copy.wast:4105 +assert_return(() => call($19, "load8_u", [28_257]), 0); + +// memory_copy.wast:4106 +assert_return(() => call($19, "load8_u", [28_456]), 0); + +// memory_copy.wast:4107 +assert_return(() => call($19, "load8_u", [28_655]), 0); + +// memory_copy.wast:4108 +assert_return(() => call($19, "load8_u", [28_854]), 0); + +// memory_copy.wast:4109 +assert_return(() => call($19, "load8_u", [29_053]), 0); + +// memory_copy.wast:4110 +assert_return(() => call($19, "load8_u", [29_252]), 0); + +// memory_copy.wast:4111 +assert_return(() => call($19, "load8_u", [29_451]), 0); + +// memory_copy.wast:4112 +assert_return(() => call($19, "load8_u", [29_650]), 0); + +// memory_copy.wast:4113 +assert_return(() => call($19, "load8_u", [29_849]), 0); + +// memory_copy.wast:4114 +assert_return(() => call($19, "load8_u", [30_048]), 0); + +// memory_copy.wast:4115 +assert_return(() => call($19, "load8_u", [30_247]), 0); + +// memory_copy.wast:4116 +assert_return(() => call($19, "load8_u", [30_446]), 0); + +// memory_copy.wast:4117 +assert_return(() => call($19, "load8_u", [30_645]), 0); + +// memory_copy.wast:4118 +assert_return(() => call($19, "load8_u", [30_844]), 0); + +// memory_copy.wast:4119 +assert_return(() => call($19, "load8_u", [31_043]), 0); + +// memory_copy.wast:4120 +assert_return(() => call($19, "load8_u", [31_242]), 0); + +// memory_copy.wast:4121 +assert_return(() => call($19, "load8_u", [31_441]), 0); + +// memory_copy.wast:4122 +assert_return(() => call($19, "load8_u", [31_640]), 0); + +// memory_copy.wast:4123 +assert_return(() => call($19, "load8_u", [31_839]), 0); + +// memory_copy.wast:4124 +assert_return(() => call($19, "load8_u", [32_038]), 0); + +// memory_copy.wast:4125 +assert_return(() => call($19, "load8_u", [32_237]), 0); + +// memory_copy.wast:4126 +assert_return(() => call($19, "load8_u", [32_436]), 0); + +// memory_copy.wast:4127 +assert_return(() => call($19, "load8_u", [32_635]), 0); + +// memory_copy.wast:4128 +assert_return(() => call($19, "load8_u", [32_834]), 0); + +// memory_copy.wast:4129 +assert_return(() => call($19, "load8_u", [33_033]), 0); + +// memory_copy.wast:4130 +assert_return(() => call($19, "load8_u", [33_232]), 0); + +// memory_copy.wast:4131 +assert_return(() => call($19, "load8_u", [33_431]), 0); + +// memory_copy.wast:4132 +assert_return(() => call($19, "load8_u", [33_630]), 0); + +// memory_copy.wast:4133 +assert_return(() => call($19, "load8_u", [33_829]), 0); + +// memory_copy.wast:4134 +assert_return(() => call($19, "load8_u", [34_028]), 0); + +// memory_copy.wast:4135 +assert_return(() => call($19, "load8_u", [34_227]), 0); + +// memory_copy.wast:4136 +assert_return(() => call($19, "load8_u", [34_426]), 0); + +// memory_copy.wast:4137 +assert_return(() => call($19, "load8_u", [34_625]), 0); + +// memory_copy.wast:4138 +assert_return(() => call($19, "load8_u", [34_824]), 0); + +// memory_copy.wast:4139 +assert_return(() => call($19, "load8_u", [35_023]), 0); + +// memory_copy.wast:4140 +assert_return(() => call($19, "load8_u", [35_222]), 0); + +// memory_copy.wast:4141 +assert_return(() => call($19, "load8_u", [35_421]), 0); + +// memory_copy.wast:4142 +assert_return(() => call($19, "load8_u", [35_620]), 0); + +// memory_copy.wast:4143 +assert_return(() => call($19, "load8_u", [35_819]), 0); + +// memory_copy.wast:4144 +assert_return(() => call($19, "load8_u", [36_018]), 0); + +// memory_copy.wast:4145 +assert_return(() => call($19, "load8_u", [36_217]), 0); + +// memory_copy.wast:4146 +assert_return(() => call($19, "load8_u", [36_416]), 0); + +// memory_copy.wast:4147 +assert_return(() => call($19, "load8_u", [36_615]), 0); + +// memory_copy.wast:4148 +assert_return(() => call($19, "load8_u", [36_814]), 0); + +// memory_copy.wast:4149 +assert_return(() => call($19, "load8_u", [37_013]), 0); + +// memory_copy.wast:4150 +assert_return(() => call($19, "load8_u", [37_212]), 0); + +// memory_copy.wast:4151 +assert_return(() => call($19, "load8_u", [37_411]), 0); + +// memory_copy.wast:4152 +assert_return(() => call($19, "load8_u", [37_610]), 0); + +// memory_copy.wast:4153 +assert_return(() => call($19, "load8_u", [37_809]), 0); + +// memory_copy.wast:4154 +assert_return(() => call($19, "load8_u", [38_008]), 0); + +// memory_copy.wast:4155 +assert_return(() => call($19, "load8_u", [38_207]), 0); + +// memory_copy.wast:4156 +assert_return(() => call($19, "load8_u", [38_406]), 0); + +// memory_copy.wast:4157 +assert_return(() => call($19, "load8_u", [38_605]), 0); + +// memory_copy.wast:4158 +assert_return(() => call($19, "load8_u", [38_804]), 0); + +// memory_copy.wast:4159 +assert_return(() => call($19, "load8_u", [39_003]), 0); + +// memory_copy.wast:4160 +assert_return(() => call($19, "load8_u", [39_202]), 0); + +// memory_copy.wast:4161 +assert_return(() => call($19, "load8_u", [39_401]), 0); + +// memory_copy.wast:4162 +assert_return(() => call($19, "load8_u", [39_600]), 0); + +// memory_copy.wast:4163 +assert_return(() => call($19, "load8_u", [39_799]), 0); + +// memory_copy.wast:4164 +assert_return(() => call($19, "load8_u", [39_998]), 0); + +// memory_copy.wast:4165 +assert_return(() => call($19, "load8_u", [40_197]), 0); + +// memory_copy.wast:4166 +assert_return(() => call($19, "load8_u", [40_396]), 0); + +// memory_copy.wast:4167 +assert_return(() => call($19, "load8_u", [40_595]), 0); + +// memory_copy.wast:4168 +assert_return(() => call($19, "load8_u", [40_794]), 0); + +// memory_copy.wast:4169 +assert_return(() => call($19, "load8_u", [40_993]), 0); + +// memory_copy.wast:4170 +assert_return(() => call($19, "load8_u", [41_192]), 0); + +// memory_copy.wast:4171 +assert_return(() => call($19, "load8_u", [41_391]), 0); + +// memory_copy.wast:4172 +assert_return(() => call($19, "load8_u", [41_590]), 0); + +// memory_copy.wast:4173 +assert_return(() => call($19, "load8_u", [41_789]), 0); + +// memory_copy.wast:4174 +assert_return(() => call($19, "load8_u", [41_988]), 0); + +// memory_copy.wast:4175 +assert_return(() => call($19, "load8_u", [42_187]), 0); + +// memory_copy.wast:4176 +assert_return(() => call($19, "load8_u", [42_386]), 0); + +// memory_copy.wast:4177 +assert_return(() => call($19, "load8_u", [42_585]), 0); + +// memory_copy.wast:4178 +assert_return(() => call($19, "load8_u", [42_784]), 0); + +// memory_copy.wast:4179 +assert_return(() => call($19, "load8_u", [42_983]), 0); + +// memory_copy.wast:4180 +assert_return(() => call($19, "load8_u", [43_182]), 0); + +// memory_copy.wast:4181 +assert_return(() => call($19, "load8_u", [43_381]), 0); + +// memory_copy.wast:4182 +assert_return(() => call($19, "load8_u", [43_580]), 0); + +// memory_copy.wast:4183 +assert_return(() => call($19, "load8_u", [43_779]), 0); + +// memory_copy.wast:4184 +assert_return(() => call($19, "load8_u", [43_978]), 0); + +// memory_copy.wast:4185 +assert_return(() => call($19, "load8_u", [44_177]), 0); + +// memory_copy.wast:4186 +assert_return(() => call($19, "load8_u", [44_376]), 0); + +// memory_copy.wast:4187 +assert_return(() => call($19, "load8_u", [44_575]), 0); + +// memory_copy.wast:4188 +assert_return(() => call($19, "load8_u", [44_774]), 0); + +// memory_copy.wast:4189 +assert_return(() => call($19, "load8_u", [44_973]), 0); + +// memory_copy.wast:4190 +assert_return(() => call($19, "load8_u", [45_172]), 0); + +// memory_copy.wast:4191 +assert_return(() => call($19, "load8_u", [45_371]), 0); + +// memory_copy.wast:4192 +assert_return(() => call($19, "load8_u", [45_570]), 0); + +// memory_copy.wast:4193 +assert_return(() => call($19, "load8_u", [45_769]), 0); + +// memory_copy.wast:4194 +assert_return(() => call($19, "load8_u", [45_968]), 0); + +// memory_copy.wast:4195 +assert_return(() => call($19, "load8_u", [46_167]), 0); + +// memory_copy.wast:4196 +assert_return(() => call($19, "load8_u", [46_366]), 0); + +// memory_copy.wast:4197 +assert_return(() => call($19, "load8_u", [46_565]), 0); + +// memory_copy.wast:4198 +assert_return(() => call($19, "load8_u", [46_764]), 0); + +// memory_copy.wast:4199 +assert_return(() => call($19, "load8_u", [46_963]), 0); + +// memory_copy.wast:4200 +assert_return(() => call($19, "load8_u", [47_162]), 0); + +// memory_copy.wast:4201 +assert_return(() => call($19, "load8_u", [47_361]), 0); + +// memory_copy.wast:4202 +assert_return(() => call($19, "load8_u", [47_560]), 0); + +// memory_copy.wast:4203 +assert_return(() => call($19, "load8_u", [47_759]), 0); + +// memory_copy.wast:4204 +assert_return(() => call($19, "load8_u", [47_958]), 0); + +// memory_copy.wast:4205 +assert_return(() => call($19, "load8_u", [48_157]), 0); + +// memory_copy.wast:4206 +assert_return(() => call($19, "load8_u", [48_356]), 0); + +// memory_copy.wast:4207 +assert_return(() => call($19, "load8_u", [48_555]), 0); + +// memory_copy.wast:4208 +assert_return(() => call($19, "load8_u", [48_754]), 0); + +// memory_copy.wast:4209 +assert_return(() => call($19, "load8_u", [48_953]), 0); + +// memory_copy.wast:4210 +assert_return(() => call($19, "load8_u", [49_152]), 0); + +// memory_copy.wast:4211 +assert_return(() => call($19, "load8_u", [49_351]), 0); + +// memory_copy.wast:4212 +assert_return(() => call($19, "load8_u", [49_550]), 0); + +// memory_copy.wast:4213 +assert_return(() => call($19, "load8_u", [49_749]), 0); + +// memory_copy.wast:4214 +assert_return(() => call($19, "load8_u", [49_948]), 0); + +// memory_copy.wast:4215 +assert_return(() => call($19, "load8_u", [50_147]), 0); + +// memory_copy.wast:4216 +assert_return(() => call($19, "load8_u", [50_346]), 0); + +// memory_copy.wast:4217 +assert_return(() => call($19, "load8_u", [50_545]), 0); + +// memory_copy.wast:4218 +assert_return(() => call($19, "load8_u", [50_744]), 0); + +// memory_copy.wast:4219 +assert_return(() => call($19, "load8_u", [50_943]), 0); + +// memory_copy.wast:4220 +assert_return(() => call($19, "load8_u", [51_142]), 0); + +// memory_copy.wast:4221 +assert_return(() => call($19, "load8_u", [51_341]), 0); + +// memory_copy.wast:4222 +assert_return(() => call($19, "load8_u", [51_540]), 0); + +// memory_copy.wast:4223 +assert_return(() => call($19, "load8_u", [51_739]), 0); + +// memory_copy.wast:4224 +assert_return(() => call($19, "load8_u", [51_938]), 0); + +// memory_copy.wast:4225 +assert_return(() => call($19, "load8_u", [52_137]), 0); + +// memory_copy.wast:4226 +assert_return(() => call($19, "load8_u", [52_336]), 0); + +// memory_copy.wast:4227 +assert_return(() => call($19, "load8_u", [52_535]), 0); + +// memory_copy.wast:4228 +assert_return(() => call($19, "load8_u", [52_734]), 0); + +// memory_copy.wast:4229 +assert_return(() => call($19, "load8_u", [52_933]), 0); + +// memory_copy.wast:4230 +assert_return(() => call($19, "load8_u", [53_132]), 0); + +// memory_copy.wast:4231 +assert_return(() => call($19, "load8_u", [53_331]), 0); + +// memory_copy.wast:4232 +assert_return(() => call($19, "load8_u", [53_530]), 0); + +// memory_copy.wast:4233 +assert_return(() => call($19, "load8_u", [53_729]), 0); + +// memory_copy.wast:4234 +assert_return(() => call($19, "load8_u", [53_928]), 0); + +// memory_copy.wast:4235 +assert_return(() => call($19, "load8_u", [54_127]), 0); + +// memory_copy.wast:4236 +assert_return(() => call($19, "load8_u", [54_326]), 0); + +// memory_copy.wast:4237 +assert_return(() => call($19, "load8_u", [54_525]), 0); + +// memory_copy.wast:4238 +assert_return(() => call($19, "load8_u", [54_724]), 0); + +// memory_copy.wast:4239 +assert_return(() => call($19, "load8_u", [54_923]), 0); + +// memory_copy.wast:4240 +assert_return(() => call($19, "load8_u", [55_122]), 0); + +// memory_copy.wast:4241 +assert_return(() => call($19, "load8_u", [55_321]), 0); + +// memory_copy.wast:4242 +assert_return(() => call($19, "load8_u", [55_520]), 0); + +// memory_copy.wast:4243 +assert_return(() => call($19, "load8_u", [55_719]), 0); + +// memory_copy.wast:4244 +assert_return(() => call($19, "load8_u", [55_918]), 0); + +// memory_copy.wast:4245 +assert_return(() => call($19, "load8_u", [56_117]), 0); + +// memory_copy.wast:4246 +assert_return(() => call($19, "load8_u", [56_316]), 0); + +// memory_copy.wast:4247 +assert_return(() => call($19, "load8_u", [56_515]), 0); + +// memory_copy.wast:4248 +assert_return(() => call($19, "load8_u", [56_714]), 0); + +// memory_copy.wast:4249 +assert_return(() => call($19, "load8_u", [56_913]), 0); + +// memory_copy.wast:4250 +assert_return(() => call($19, "load8_u", [57_112]), 0); + +// memory_copy.wast:4251 +assert_return(() => call($19, "load8_u", [57_311]), 0); + +// memory_copy.wast:4252 +assert_return(() => call($19, "load8_u", [57_510]), 0); + +// memory_copy.wast:4253 +assert_return(() => call($19, "load8_u", [57_709]), 0); + +// memory_copy.wast:4254 +assert_return(() => call($19, "load8_u", [57_908]), 0); + +// memory_copy.wast:4255 +assert_return(() => call($19, "load8_u", [58_107]), 0); + +// memory_copy.wast:4256 +assert_return(() => call($19, "load8_u", [58_306]), 0); + +// memory_copy.wast:4257 +assert_return(() => call($19, "load8_u", [58_505]), 0); + +// memory_copy.wast:4258 +assert_return(() => call($19, "load8_u", [58_704]), 0); + +// memory_copy.wast:4259 +assert_return(() => call($19, "load8_u", [58_903]), 0); + +// memory_copy.wast:4260 +assert_return(() => call($19, "load8_u", [59_102]), 0); + +// memory_copy.wast:4261 +assert_return(() => call($19, "load8_u", [59_301]), 0); + +// memory_copy.wast:4262 +assert_return(() => call($19, "load8_u", [59_500]), 0); + +// memory_copy.wast:4263 +assert_return(() => call($19, "load8_u", [59_699]), 0); + +// memory_copy.wast:4264 +assert_return(() => call($19, "load8_u", [59_898]), 0); + +// memory_copy.wast:4265 +assert_return(() => call($19, "load8_u", [60_097]), 0); + +// memory_copy.wast:4266 +assert_return(() => call($19, "load8_u", [60_296]), 0); + +// memory_copy.wast:4267 +assert_return(() => call($19, "load8_u", [60_495]), 0); + +// memory_copy.wast:4268 +assert_return(() => call($19, "load8_u", [60_694]), 0); + +// memory_copy.wast:4269 +assert_return(() => call($19, "load8_u", [60_893]), 0); + +// memory_copy.wast:4270 +assert_return(() => call($19, "load8_u", [61_092]), 0); + +// memory_copy.wast:4271 +assert_return(() => call($19, "load8_u", [61_291]), 0); + +// memory_copy.wast:4272 +assert_return(() => call($19, "load8_u", [61_440]), 0); + +// memory_copy.wast:4273 +assert_return(() => call($19, "load8_u", [61_441]), 1); + +// memory_copy.wast:4274 +assert_return(() => call($19, "load8_u", [61_442]), 2); + +// memory_copy.wast:4275 +assert_return(() => call($19, "load8_u", [61_443]), 3); + +// memory_copy.wast:4276 +assert_return(() => call($19, "load8_u", [61_444]), 4); + +// memory_copy.wast:4277 +assert_return(() => call($19, "load8_u", [61_445]), 5); + +// memory_copy.wast:4278 +assert_return(() => call($19, "load8_u", [61_446]), 6); + +// memory_copy.wast:4279 +assert_return(() => call($19, "load8_u", [61_447]), 7); + +// memory_copy.wast:4280 +assert_return(() => call($19, "load8_u", [61_448]), 8); + +// memory_copy.wast:4281 +assert_return(() => call($19, "load8_u", [61_449]), 9); + +// memory_copy.wast:4282 +assert_return(() => call($19, "load8_u", [61_450]), 10); + +// memory_copy.wast:4283 +assert_return(() => call($19, "load8_u", [61_451]), 11); + +// memory_copy.wast:4284 +assert_return(() => call($19, "load8_u", [61_452]), 12); + +// memory_copy.wast:4285 +assert_return(() => call($19, "load8_u", [61_453]), 13); + +// memory_copy.wast:4286 +assert_return(() => call($19, "load8_u", [61_454]), 14); + +// memory_copy.wast:4287 +assert_return(() => call($19, "load8_u", [61_455]), 15); + +// memory_copy.wast:4288 +assert_return(() => call($19, "load8_u", [61_456]), 16); + +// memory_copy.wast:4289 +assert_return(() => call($19, "load8_u", [61_457]), 17); + +// memory_copy.wast:4290 +assert_return(() => call($19, "load8_u", [61_458]), 18); + +// memory_copy.wast:4291 +assert_return(() => call($19, "load8_u", [61_459]), 19); + +// memory_copy.wast:4292 +assert_return(() => call($19, "load8_u", [61_510]), 0); + +// memory_copy.wast:4293 +assert_return(() => call($19, "load8_u", [61_709]), 0); + +// memory_copy.wast:4294 +assert_return(() => call($19, "load8_u", [61_908]), 0); + +// memory_copy.wast:4295 +assert_return(() => call($19, "load8_u", [62_107]), 0); + +// memory_copy.wast:4296 +assert_return(() => call($19, "load8_u", [62_306]), 0); + +// memory_copy.wast:4297 +assert_return(() => call($19, "load8_u", [62_505]), 0); + +// memory_copy.wast:4298 +assert_return(() => call($19, "load8_u", [62_704]), 0); + +// memory_copy.wast:4299 +assert_return(() => call($19, "load8_u", [62_903]), 0); + +// memory_copy.wast:4300 +assert_return(() => call($19, "load8_u", [63_102]), 0); + +// memory_copy.wast:4301 +assert_return(() => call($19, "load8_u", [63_301]), 0); + +// memory_copy.wast:4302 +assert_return(() => call($19, "load8_u", [63_500]), 0); + +// memory_copy.wast:4303 +assert_return(() => call($19, "load8_u", [63_699]), 0); + +// memory_copy.wast:4304 +assert_return(() => call($19, "load8_u", [63_898]), 0); + +// memory_copy.wast:4305 +assert_return(() => call($19, "load8_u", [64_097]), 0); + +// memory_copy.wast:4306 +assert_return(() => call($19, "load8_u", [64_296]), 0); + +// memory_copy.wast:4307 +assert_return(() => call($19, "load8_u", [64_495]), 0); + +// memory_copy.wast:4308 +assert_return(() => call($19, "load8_u", [64_694]), 0); + +// memory_copy.wast:4309 +assert_return(() => call($19, "load8_u", [64_893]), 0); + +// memory_copy.wast:4310 +assert_return(() => call($19, "load8_u", [65_092]), 0); + +// memory_copy.wast:4311 +assert_return(() => call($19, "load8_u", [65_291]), 0); + +// memory_copy.wast:4312 +assert_return(() => call($19, "load8_u", [65_490]), 0); + +// memory_copy.wast:4314 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4320 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4327 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4334 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4341 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4348 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4355 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4362 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4369 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4376 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4383 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4390 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4397 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4404 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4411 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4418 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4425 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4432 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4439 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4446 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4453 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4460 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4467 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4474 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4481 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4488 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4495 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4502 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4509 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4516 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4523 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4530 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4537 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4544 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4551 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4558 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4565 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4572 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4579 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4586 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4593 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4600 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4607 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4614 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4621 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4628 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4635 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4642 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4649 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4656 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4663 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4670 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4677 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4684 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4691 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4698 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4705 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4712 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4719 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4726 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4733 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4740 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4747 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4754 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4762 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\x96\x80\x80\x80\x00\x00\x41\x0a\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x09\x41\x0a\x41\x05\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4779 +run(() => call($20, "test", [])); + +// memory_copy.wast:4781 +assert_return(() => call($20, "checkRange", [0, 9, 0]), -1); + +// memory_copy.wast:4783 +assert_return(() => call($20, "checkRange", [9, 20, 85]), -1); + +// memory_copy.wast:4785 +assert_return(() => call($20, "checkRange", [20, 65_536, 0]), -1); + +// memory_copy.wast:4788 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\x96\x80\x80\x80\x00\x00\x41\x0a\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x10\x41\x0f\x41\x05\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4805 +run(() => call($21, "test", [])); + +// memory_copy.wast:4807 +assert_return(() => call($21, "checkRange", [0, 10, 0]), -1); + +// memory_copy.wast:4809 +assert_return(() => call($21, "checkRange", [10, 21, 85]), -1); + +// memory_copy.wast:4811 +assert_return(() => call($21, "checkRange", [21, 65_536, 0]), -1); + +// memory_copy.wast:4814 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\x80\x80\x02\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4818 +assert_trap(() => call($22, "test", [])); + +// memory_copy.wast:4820 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x7e\x41\x80\x80\x01\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4824 +assert_trap(() => call($23, "test", [])); + +// memory_copy.wast:4826 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x80\x80\x02\x41\x80\xfe\x03\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4830 +assert_trap(() => call($24, "test", [])); + +// memory_copy.wast:4832 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x01\x41\x80\x7e\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4836 +assert_trap(() => call($25, "test", [])); + +// memory_copy.wast:4838 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xdc\x80\x80\x80\x00\x02\xaa\x80\x80\x80\x00\x00\x41\x00\x41\xd5\x00\x41\x80\x80\x02\xfc\x0b\x00\x41\x80\x80\x02\x41\xaa\x01\x41\x80\x80\x02\xfc\x0b\x00\x41\x80\xa0\x02\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4856 +run(() => call($26, "test", [])); + +// memory_copy.wast:4858 +assert_return(() => call($26, "checkRange", [0, 32_768, 85]), -1); + +// memory_copy.wast:4860 +assert_return(() => call($26, "checkRange", [32_768, 65_536, 170]), -1); + +// memory_copy.wast:4862 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4866 +run(() => call($27, "test", [])); + +// memory_copy.wast:4868 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4872 +assert_trap(() => call($28, "test", [])); + +// memory_copy.wast:4874 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\xa0\x02\x41\x80\x80\x04\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4878 +run(() => call($29, "test", [])); + +// memory_copy.wast:4880 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\xa0\x02\x41\x80\x80\x08\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4884 +assert_trap(() => call($30, "test", [])); + +// memory_copy.wast:4886 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x80\x80\x04\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4890 +run(() => call($31, "test", [])); + +// memory_copy.wast:4892 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\x80\x80\x08\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4896 +assert_trap(() => call($32, "test", [])); + +// memory_copy.wast:4898 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xbe\x95\x80\x80\x00\x02\x8c\x95\x80\x80\x00\x00\x41\xe7\x8a\x01\x41\x01\x41\xc0\x0a\xfc\x0b\x00\x41\xe9\xb0\x02\x41\x02\x41\x9f\x08\xfc\x0b\x00\x41\xd1\xb8\x03\x41\x03\x41\xdc\x07\xfc\x0b\x00\x41\xca\xa8\x02\x41\x04\x41\xc2\x02\xfc\x0b\x00\x41\xa9\x3e\x41\x05\x41\xca\x0f\xfc\x0b\x00\x41\xba\xb1\x01\x41\x06\x41\xdc\x17\xfc\x0b\x00\x41\xf2\x83\x01\x41\x07\x41\xc4\x12\xfc\x0b\x00\x41\xe3\xd3\x02\x41\x08\x41\xc3\x06\xfc\x0b\x00\x41\xfc\x00\x41\x09\x41\xf1\x0a\xfc\x0b\x00\x41\xd4\x10\x41\x0a\x41\xc6\x15\xfc\x0b\x00\x41\x9b\xc6\x00\x41\x0b\x41\x9a\x18\xfc\x0b\x00\x41\xe7\x9b\x03\x41\x0c\x41\xe5\x05\xfc\x0b\x00\x41\xf6\x1e\x41\x0d\x41\x87\x16\xfc\x0b\x00\x41\xb3\x84\x03\x41\x0e\x41\x80\x0a\xfc\x0b\x00\x41\xc9\x89\x03\x41\x0f\x41\xba\x0b\xfc\x0b\x00\x41\x8d\xa0\x01\x41\x10\x41\xd6\x18\xfc\x0b\x00\x41\xb1\xf4\x02\x41\x11\x41\xa0\x04\xfc\x0b\x00\x41\xa3\xe1\x00\x41\x12\x41\xed\x14\xfc\x0b\x00\x41\xa5\xc2\x01\x41\x13\x41\xdb\x14\xfc\x0b\x00\x41\x85\xe2\x02\x41\x14\x41\xa2\x0c\xfc\x0b\x00\x41\xd8\xd0\x02\x41\x15\x41\x9b\x0d\xfc\x0b\x00\x41\xde\x88\x02\x41\x16\x41\x86\x05\xfc\x0b\x00\x41\xab\xfb\x02\x41\x17\x41\xc2\x0e\xfc\x0b\x00\x41\xcd\xa1\x03\x41\x18\x41\xe1\x14\xfc\x0b\x00\x41\x9b\xed\x01\x41\x19\x41\xd5\x07\xfc\x0b\x00\x41\xd4\xc8\x00\x41\x1a\x41\x8f\x0e\xfc\x0b\x00\x41\x8e\x88\x03\x41\x1b\x41\xe7\x03\xfc\x0b\x00\x41\xa1\xea\x03\x41\x1c\x41\x92\x04\xfc\x0b\x00\x41\xdc\x9b\x02\x41\x1d\x41\xaf\x07\xfc\x0b\x00\x41\xf0\x34\x41\x1e\x41\xfd\x02\xfc\x0b\x00\x41\xbe\x90\x03\x41\x1f\x41\x91\x18\xfc\x0b\x00\x41\xc1\x84\x03\x41\x20\x41\x92\x05\xfc\x0b\x00\x41\xfc\xdb\x02\x41\x21\x41\xa6\x0d\xfc\x0b\x00\x41\xbe\x84\x02\x41\x22\x41\xc4\x08\xfc\x0b\x00\x41\xfe\x8c\x03\x41\x23\x41\x82\x0b\xfc\x0b\x00\x41\xea\xf3\x02\x41\x24\x41\x9c\x11\xfc\x0b\x00\x41\xeb\xa6\x03\x41\x25\x41\xda\x12\xfc\x0b\x00\x41\x8f\xaf\x03\x41\x26\x41\xfa\x01\xfc\x0b\x00\x41\xdc\xb0\x01\x41\x27\x41\xb1\x10\xfc\x0b\x00\x41\xec\x85\x01\x41\x28\x41\xc0\x19\xfc\x0b\x00\x41\xbb\xa8\x03\x41\x29\x41\xe3\x19\xfc\x0b\x00\x41\xb2\xb4\x02\x41\x2a\x41\xec\x15\xfc\x0b\x00\x41\xbc\x9a\x02\x41\x2b\x41\x96\x10\xfc\x0b\x00\x41\xec\x93\x02\x41\x2c\x41\xcb\x15\xfc\x0b\x00\x41\xdb\xff\x01\x41\x2d\x41\xb8\x02\xfc\x0b\x00\x41\x82\xf2\x03\x41\x2e\x41\xc0\x01\xfc\x0b\x00\x41\xfe\xf1\x01\x41\x2f\x41\xd4\x04\xfc\x0b\x00\x41\xfb\x81\x01\x41\x30\x41\xf5\x03\xfc\x0b\x00\x41\xaa\xbd\x03\x41\x31\x41\xae\x05\xfc\x0b\x00\x41\xfb\x8b\x02\x41\x32\x41\x81\x03\xfc\x0b\x00\x41\xd1\xdb\x03\x41\x33\x41\x87\x07\xfc\x0b\x00\x41\x85\xe0\x03\x41\x34\x41\xd6\x12\xfc\x0b\x00\x41\xfc\xee\x02\x41\x35\x41\xa1\x0b\xfc\x0b\x00\x41\xf5\xca\x01\x41\x36\x41\xda\x18\xfc\x0b\x00\x41\xbe\x2b\x41\x37\x41\xd7\x10\xfc\x0b\x00\x41\x89\x99\x02\x41\x38\x41\x87\x04\xfc\x0b\x00\x41\xdc\xde\x02\x41\x39\x41\xd0\x19\xfc\x0b\x00\x41\xa8\xed\x02\x41\x3a\x41\x8e\x0d\xfc\x0b\x00\x41\x8f\xec\x02\x41\x3b\x41\xe0\x18\xfc\x0b\x00\x41\xb1\xaf\x01\x41\x3c\x41\xa1\x0b\xfc\x0b\x00\x41\xf1\xc9\x03\x41\x3d\x41\x97\x05\xfc\x0b\x00\x41\x85\xfc\x01\x41\x3e\x41\x87\x0d\xfc\x0b\x00\x41\xf7\x17\x41\x3f\x41\xd1\x05\xfc\x0b\x00\x41\xe9\x89\x02\x41\xc0\x00\x41\xd4\x00\xfc\x0b\x00\x41\xba\x84\x02\x41\xc1\x00\x41\xed\x0f\xfc\x0b\x00\x41\xca\x9f\x02\x41\xc2\x00\x41\x1d\xfc\x0b\x00\x41\xcb\x95\x01\x41\xc3\x00\x41\xda\x17\xfc\x0b\x00\x41\xc8\xe2\x00\x41\xc4\x00\x41\x93\x08\xfc\x0b\x00\x41\xe4\x8e\x01\x41\xc5\x00\x41\xfc\x19\xfc\x0b\x00\x41\x9f\x24\x41\xc6\x00\x41\xc3\x08\xfc\x0b\x00\x41\x9e\xfe\x00\x41\xc7\x00\x41\xcd\x0f\xfc\x0b\x00\x41\x9c\x8e\x01\x41\xc8\x00\x41\xd3\x11\xfc\x0b\x00\x41\xe4\x8a\x03\x41\xc9\x00\x41\xf5\x18\xfc\x0b\x00\x41\x94\xd6\x00\x41\xca\x00\x41\xb0\x0f\xfc\x0b\x00\x41\xda\xfc\x00\x41\xcb\x00\x41\xaf\x0b\xfc\x0b\x00\x41\xde\xe2\x02\x41\xcc\x00\x41\x99\x09\xfc\x0b\x00\x41\xf9\xa6\x03\x41\xcd\x00\x41\xa0\x0c\xfc\x0b\x00\x41\xbb\x82\x02\x41\xce\x00\x41\xea\x0c\xfc\x0b\x00\x41\xe4\xdc\x03\x41\xcf\x00\x41\xd4\x19\xfc\x0b\x00\x41\x91\x94\x03\x41\xd0\x00\x41\xdf\x01\xfc\x0b\x00\x41\x89\x22\x41\xd1\x00\x41\xfb\x10\xfc\x0b\x00\x41\xaa\xc1\x03\x41\xd2\x00\x41\xaa\x0a\xfc\x0b\x00\x41\xac\xb3\x03\x41\xd3\x00\x41\xd8\x14\xfc\x0b\x00\x41\x9b\xbc\x01\x41\xd4\x00\x41\x95\x08\xfc\x0b\x00\x41\xaf\xd1\x02\x41\xd5\x00\x41\x99\x18\xfc\x0b\x00\x41\xb3\xfc\x01\x41\xd6\x00\x41\xec\x15\xfc\x0b\x00\x41\xe3\x1d\x41\xd7\x00\x41\xda\x0f\xfc\x0b\x00\x41\xc8\xac\x03\x41\xd8\x00\x41\x00\xfc\x0b\x00\x41\x95\x86\x03\x41\xd9\x00\x41\x95\x10\xfc\x0b\x00\x41\xbb\x9f\x01\x41\xda\x00\x41\xd0\x16\xfc\x0b\x00\x41\xa2\x88\x02\x41\xdb\x00\x41\xc0\x01\xfc\x0b\x00\x41\xba\xc9\x00\x41\xdc\x00\x41\x93\x11\xfc\x0b\x00\x41\xfd\xe0\x00\x41\xdd\x00\x41\x18\xfc\x0b\x00\x41\x8b\xee\x00\x41\xde\x00\x41\xc1\x04\xfc\x0b\x00\x41\x9a\xd8\x02\x41\xdf\x00\x41\xa9\x10\xfc\x0b\x00\x41\xff\x9e\x02\x41\xe0\x00\x41\xec\x1a\xfc\x0b\x00\x41\xf8\xb5\x01\x41\xe1\x00\x41\xcd\x15\xfc\x0b\x00\x41\xf8\x31\x41\xe2\x00\x41\xbe\x06\xfc\x0b\x00\x41\x9b\x84\x02\x41\xe3\x00\x41\x92\x0f\xfc\x0b\x00\x41\xb5\xab\x01\x41\xe4\x00\x41\xbe\x15\xfc\x0b\x00\x41\xce\xce\x03\x41\xe8\xa7\x03\x41\xb2\x10\xfc\x0a\x00\x00\x41\xb2\xec\x03\x41\xb8\xb2\x02\x41\xe6\x01\xfc\x0a\x00\x00\x41\xf9\x94\x03\x41\xcd\xb8\x01\x41\xfc\x11\xfc\x0a\x00\x00\x41\xb4\x34\x41\xbc\xbb\x01\x41\xff\x04\xfc\x0a\x00\x00\x41\xce\x36\x41\xf7\x84\x02\x41\xc9\x08\xfc\x0a\x00\x00\x41\xcb\x97\x01\x41\xec\xd0\x00\x41\xfd\x18\xfc\x0a\x00\x00\x41\xac\xd5\x01\x41\x86\xa9\x03\x41\xe4\x00\xfc\x0a\x00\x00\x41\xd5\xd4\x01\x41\xa2\xd5\x02\x41\xb5\x0d\xfc\x0a\x00\x00\x41\xf0\xd8\x03\x41\xb5\xc3\x00\x41\xf7\x00\xfc\x0a\x00\x00\x41\xbb\x2e\x41\x84\x12\x41\x92\x05\xfc\x0a\x00\x00\x41\xb3\x25\x41\xaf\x93\x03\x41\xdd\x11\xfc\x0a\x00\x00\x41\xc9\xe2\x00\x41\xfd\x95\x01\x41\xc1\x06\xfc\x0a\x00\x00\x41\xce\xdc\x00\x41\xa9\xeb\x02\x41\xe4\x19\xfc\x0a\x00\x00\x41\xf0\xd8\x00\x41\xd4\xdf\x02\x41\xe9\x11\xfc\x0a\x00\x00\x41\x8a\x8b\x02\x41\xa9\x34\x41\x8c\x14\xfc\x0a\x00\x00\x41\xc8\x26\x41\x9a\x0d\x41\xb0\x0a\xfc\x0a\x00\x00\x41\xbc\xed\x03\x41\xd5\x3b\x41\x86\x0d\xfc\x0a\x00\x00\x41\x98\xdc\x02\x41\xa8\x8f\x01\x41\x21\xfc\x0a\x00\x00\x41\x8e\xd7\x02\x41\xcc\xae\x01\x41\x93\x0b\xfc\x0a\x00\x00\x41\xad\xec\x02\x41\x9b\x85\x03\x41\x9a\x0b\xfc\x0a\x00\x00\x41\xc4\xf1\x03\x41\xb3\xc4\x00\x41\xc2\x06\xfc\x0a\x00\x00\x41\xcd\x85\x02\x41\xa3\x9d\x01\x41\xf5\x19\xfc\x0a\x00\x00\x41\xff\xbc\x02\x41\xad\xa8\x03\x41\x81\x19\xfc\x0a\x00\x00\x41\xd4\xc9\x01\x41\xf6\xce\x03\x41\x94\x13\xfc\x0a\x00\x00\x41\xde\x99\x01\x41\xb2\xbc\x03\x41\xda\x02\xfc\x0a\x00\x00\x41\xec\xfb\x00\x41\xca\x98\x02\x41\xfe\x12\xfc\x0a\x00\x00\x41\xb0\xdc\x00\x41\xf6\x95\x02\x41\xac\x02\xfc\x0a\x00\x00\x41\xa3\xd0\x03\x41\x85\xed\x00\x41\xd1\x18\xfc\x0a\x00\x00\x41\xfb\x8b\x02\x41\xb2\xd9\x03\x41\x81\x0a\xfc\x0a\x00\x00\x41\x84\xc6\x00\x41\xf4\xdf\x00\x41\xaf\x07\xfc\x0a\x00\x00\x41\x8b\x16\x41\xb9\xd1\x00\x41\xdf\x0e\xfc\x0a\x00\x00\x41\xba\xd1\x02\x41\x86\xd7\x02\x41\xe2\x05\xfc\x0a\x00\x00\x41\xbe\xec\x03\x41\x85\x94\x01\x41\xfa\x00\xfc\x0a\x00\x00\x41\xec\xbb\x01\x41\xd9\xdd\x02\x41\xdb\x0d\xfc\x0a\x00\x00\x41\xd0\xb0\x01\x41\xa3\xf3\x00\x41\xbe\x05\xfc\x0a\x00\x00\x41\x94\xd8\x00\x41\xd3\xcf\x01\x41\xa6\x0e\xfc\x0a\x00\x00\x41\xb4\xb4\x01\x41\xf7\x9f\x01\x41\xa8\x08\xfc\x0a\x00\x00\x41\xa0\xbf\x03\x41\xf2\xab\x03\x41\xc7\x14\xfc\x0a\x00\x00\x41\x94\xc7\x01\x41\x81\x08\x41\xa9\x18\xfc\x0a\x00\x00\x41\xb4\x83\x03\x41\xbc\xd9\x02\x41\xcf\x07\xfc\x0a\x00\x00\x41\xf8\xdc\x01\x41\xfa\xc5\x02\x41\xa0\x12\xfc\x0a\x00\x00\x41\xe9\xde\x03\x41\xe6\x01\x41\xb8\x16\xfc\x0a\x00\x00\x41\xd0\xaf\x01\x41\x9a\x9a\x03\x41\x95\x11\xfc\x0a\x00\x00\x41\xe9\xbc\x02\x41\xea\xca\x00\x41\xa6\x0f\xfc\x0a\x00\x00\x41\xcc\xe2\x01\x41\xfe\xa2\x01\x41\x8a\x11\xfc\x0a\x00\x00\x41\xa5\x9e\x03\x41\xb3\xd7\x02\x41\x8d\x08\xfc\x0a\x00\x00\x41\x84\xc7\x01\x41\xd3\x96\x02\x41\xf2\x0c\xfc\x0a\x00\x00\x41\x94\xc9\x03\x41\xfb\xe5\x02\x41\xc2\x0f\xfc\x0a\x00\x00\x41\x99\xab\x02\x41\x90\x2d\x41\xa3\x0f\xfc\x0a\x00\x00\x41\xd7\xde\x01\x41\xc4\xb0\x03\x41\xc0\x12\xfc\x0a\x00\x00\x41\x9b\xe9\x03\x41\xbc\x8d\x01\x41\xcc\x0a\xfc\x0a\x00\x00\x41\xe5\x87\x03\x41\xa5\xec\x00\x41\xfe\x02\xfc\x0a\x00\x00\x41\x88\x84\x01\x41\xf5\x9b\x02\x41\xec\x0e\xfc\x0a\x00\x00\x41\xe2\xf7\x02\x41\xde\xd8\x00\x41\xf7\x15\xfc\x0a\x00\x00\x41\xe0\xde\x01\x41\xaa\xbb\x02\x41\xc3\x02\xfc\x0a\x00\x00\x41\xb2\x95\x02\x41\xd0\xd9\x01\x41\x86\x0d\xfc\x0a\x00\x00\x41\xfa\xeb\x03\x41\xd4\xa0\x03\x41\xbd\x0a\xfc\x0a\x00\x00\x41\xb5\xee\x00\x41\xe8\xe9\x02\x41\x84\x05\xfc\x0a\x00\x00\x41\xe6\xe2\x01\x41\x82\x95\x01\x41\xf0\x03\xfc\x0a\x00\x00\x41\x98\xdf\x02\x41\xd9\xf3\x02\x41\xe0\x15\xfc\x0a\x00\x00\x41\x87\xb5\x02\x41\xf5\xdc\x02\x41\xc6\x0a\xfc\x0a\x00\x00\x41\xf0\xd0\x00\x41\xda\xe4\x01\x41\xc3\x0b\xfc\x0a\x00\x00\x41\xbf\xee\x02\x41\xe2\xe8\x02\x41\xbb\x0b\xfc\x0a\x00\x00\x41\xa9\x26\x41\xc4\xe0\x01\x41\xe7\x0e\xfc\x0a\x00\x00\x41\xfc\xa8\x02\x41\xa5\xbf\x03\x41\xd7\x0d\xfc\x0a\x00\x00\x41\xce\xce\x01\x41\xd7\xd4\x01\x41\xe7\x08\xfc\x0a\x00\x00\x41\xd3\xcb\x03\x41\xd1\xc0\x01\x41\xa7\x08\xfc\x0a\x00\x00\x41\xac\xdf\x03\x41\x86\xaf\x02\x41\xfe\x05\xfc\x0a\x00\x00\x41\x80\xd9\x02\x41\xec\x11\x41\xf0\x0b\xfc\x0a\x00\x00\x41\xe4\xff\x01\x41\x85\xf1\x02\x41\xc6\x17\xfc\x0a\x00\x00\x41\x8c\xd7\x00\x41\x8c\xa6\x01\x41\xf3\x07\xfc\x0a\x00\x00\x41\xf1\x3b\x41\xfc\xf6\x01\x41\xda\x17\xfc\x0a\x00\x00\x41\xfc\x8c\x01\x41\xbb\xe5\x00\x41\xf8\x19\xfc\x0a\x00\x00\x41\xda\xbf\x03\x41\xe1\xb4\x03\x41\xb4\x02\xfc\x0a\x00\x00\x41\xe3\xc0\x01\x41\xaf\x83\x01\x41\x83\x09\xfc\x0a\x00\x00\x41\xbc\x9b\x01\x41\x83\xcf\x00\x41\xd2\x05\xfc\x0a\x00\x00\x41\xe9\x16\x41\xaf\x2e\x41\xc2\x12\xfc\x0a\x00\x00\x41\xff\xfb\x01\x41\xaf\x87\x03\x41\xee\x16\xfc\x0a\x00\x00\x41\x96\xf6\x00\x41\x93\x87\x01\x41\xaf\x14\xfc\x0a\x00\x00\x41\x87\xe4\x02\x41\x9f\xde\x01\x41\xfd\x0f\xfc\x0a\x00\x00\x41\xed\xae\x03\x41\x91\x9a\x02\x41\xa4\x14\xfc\x0a\x00\x00\x41\xad\xde\x01\x41\x8d\xa7\x03\x41\x90\x09\xfc\x0a\x00\x00\x41\xcf\xf6\x02\x41\x89\xa1\x03\x41\xc1\x18\xfc\x0a\x00\x00\x41\xb6\xef\x01\x41\xe3\xe0\x02\x41\xd9\x14\xfc\x0a\x00\x00\x41\xc1\x27\x41\xc7\x21\x41\x34\xfc\x0a\x00\x00\x41\xa4\x34\x41\x83\xbd\x01\x41\xb9\x03\xfc\x0a\x00\x00\x41\xd8\x81\x02\x41\xed\xd3\x01\x41\xf5\x1a\xfc\x0a\x00\x00\x41\x92\xfe\x01\x41\xec\xcf\x03\x41\xe1\x15\xfc\x0a\x00\x00\x41\xb9\x8c\x02\x41\x82\xc6\x00\x41\xe6\x12\xfc\x0a\x00\x00\x41\xe5\x8b\x01\x41\x8a\xaa\x03\x41\xb5\x1a\xfc\x0a\x00\x00\x41\x9d\xb1\x01\x41\xf7\xd8\x02\x41\x88\x01\xfc\x0a\x00\x00\x41\xd1\xcd\x03\x41\xa5\x37\x41\x95\x08\xfc\x0a\x00\x00\x41\xc1\xcf\x02\x41\xf4\xad\x03\x41\xd5\x12\xfc\x0a\x00\x00\x41\x95\xdd\x02\x41\xaa\x9d\x01\x41\xed\x06\xfc\x0a\x00\x00\x41\xca\x9f\x02\x41\xec\xc4\x01\x41\xf7\x1a\xfc\x0a\x00\x00\x41\xae\xe5\x02\x41\x90\xf9\x01\x41\xd6\x06\xfc\x0a\x00\x00\x41\xac\xbd\x01\x41\xfa\xf8\x01\x41\xe1\x0a\xfc\x0a\x00\x00\x41\xf2\x87\x02\x41\xb4\x05\x41\xba\x0c\xfc\x0a\x00\x00\x41\xca\xd9\x03\x41\x99\x91\x01\x41\xab\x17\xfc\x0a\x00\x00\x41\xc2\x89\x03\x41\xb7\xc2\x02\x41\xfe\x0a\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:5114 +run(() => call($33, "test", [])); + +// memory_copy.wast:5116 +assert_return(() => call($33, "checkRange", [0, 124, 0]), -1); + +// memory_copy.wast:5118 +assert_return(() => call($33, "checkRange", [124, 1_517, 9]), -1); + +// memory_copy.wast:5120 +assert_return(() => call($33, "checkRange", [1_517, 2_132, 0]), -1); + +// memory_copy.wast:5122 +assert_return(() => call($33, "checkRange", [2_132, 2_827, 10]), -1); + +// memory_copy.wast:5124 +assert_return(() => call($33, "checkRange", [2_827, 2_921, 92]), -1); + +// memory_copy.wast:5126 +assert_return(() => call($33, "checkRange", [2_921, 3_538, 83]), -1); + +// memory_copy.wast:5128 +assert_return(() => call($33, "checkRange", [3_538, 3_786, 77]), -1); + +// memory_copy.wast:5130 +assert_return(() => call($33, "checkRange", [3_786, 4_042, 97]), -1); + +// memory_copy.wast:5132 +assert_return(() => call($33, "checkRange", [4_042, 4_651, 99]), -1); + +// memory_copy.wast:5134 +assert_return(() => call($33, "checkRange", [4_651, 5_057, 0]), -1); + +// memory_copy.wast:5136 +assert_return(() => call($33, "checkRange", [5_057, 5_109, 99]), -1); + +// memory_copy.wast:5138 +assert_return(() => call($33, "checkRange", [5_109, 5_291, 0]), -1); + +// memory_copy.wast:5140 +assert_return(() => call($33, "checkRange", [5_291, 5_524, 72]), -1); + +// memory_copy.wast:5142 +assert_return(() => call($33, "checkRange", [5_524, 5_691, 92]), -1); + +// memory_copy.wast:5144 +assert_return(() => call($33, "checkRange", [5_691, 6_552, 83]), -1); + +// memory_copy.wast:5146 +assert_return(() => call($33, "checkRange", [6_552, 7_133, 77]), -1); + +// memory_copy.wast:5148 +assert_return(() => call($33, "checkRange", [7_133, 7_665, 99]), -1); + +// memory_copy.wast:5150 +assert_return(() => call($33, "checkRange", [7_665, 8_314, 0]), -1); + +// memory_copy.wast:5152 +assert_return(() => call($33, "checkRange", [8_314, 8_360, 62]), -1); + +// memory_copy.wast:5154 +assert_return(() => call($33, "checkRange", [8_360, 8_793, 86]), -1); + +// memory_copy.wast:5156 +assert_return(() => call($33, "checkRange", [8_793, 8_979, 83]), -1); + +// memory_copy.wast:5158 +assert_return(() => call($33, "checkRange", [8_979, 9_373, 79]), -1); + +// memory_copy.wast:5160 +assert_return(() => call($33, "checkRange", [9_373, 9_518, 95]), -1); + +// memory_copy.wast:5162 +assert_return(() => call($33, "checkRange", [9_518, 9_934, 59]), -1); + +// memory_copy.wast:5164 +assert_return(() => call($33, "checkRange", [9_934, 10_087, 77]), -1); + +// memory_copy.wast:5166 +assert_return(() => call($33, "checkRange", [10_087, 10_206, 5]), -1); + +// memory_copy.wast:5168 +assert_return(() => call($33, "checkRange", [10_206, 10_230, 77]), -1); + +// memory_copy.wast:5170 +assert_return(() => call($33, "checkRange", [10_230, 10_249, 41]), -1); + +// memory_copy.wast:5172 +assert_return(() => call($33, "checkRange", [10_249, 11_148, 83]), -1); + +// memory_copy.wast:5174 +assert_return(() => call($33, "checkRange", [11_148, 11_356, 74]), -1); + +// memory_copy.wast:5176 +assert_return(() => call($33, "checkRange", [11_356, 11_380, 93]), -1); + +// memory_copy.wast:5178 +assert_return(() => call($33, "checkRange", [11_380, 11_939, 74]), -1); + +// memory_copy.wast:5180 +assert_return(() => call($33, "checkRange", [11_939, 12_159, 68]), -1); + +// memory_copy.wast:5182 +assert_return(() => call($33, "checkRange", [12_159, 12_575, 83]), -1); + +// memory_copy.wast:5184 +assert_return(() => call($33, "checkRange", [12_575, 12_969, 79]), -1); + +// memory_copy.wast:5186 +assert_return(() => call($33, "checkRange", [12_969, 13_114, 95]), -1); + +// memory_copy.wast:5188 +assert_return(() => call($33, "checkRange", [13_114, 14_133, 59]), -1); + +// memory_copy.wast:5190 +assert_return(() => call($33, "checkRange", [14_133, 14_404, 76]), -1); + +// memory_copy.wast:5192 +assert_return(() => call($33, "checkRange", [14_404, 14_428, 57]), -1); + +// memory_copy.wast:5194 +assert_return(() => call($33, "checkRange", [14_428, 14_458, 59]), -1); + +// memory_copy.wast:5196 +assert_return(() => call($33, "checkRange", [14_458, 14_580, 32]), -1); + +// memory_copy.wast:5198 +assert_return(() => call($33, "checkRange", [14_580, 14_777, 89]), -1); + +// memory_copy.wast:5200 +assert_return(() => call($33, "checkRange", [14_777, 15_124, 59]), -1); + +// memory_copy.wast:5202 +assert_return(() => call($33, "checkRange", [15_124, 15_126, 36]), -1); + +// memory_copy.wast:5204 +assert_return(() => call($33, "checkRange", [15_126, 15_192, 100]), -1); + +// memory_copy.wast:5206 +assert_return(() => call($33, "checkRange", [15_192, 15_871, 96]), -1); + +// memory_copy.wast:5208 +assert_return(() => call($33, "checkRange", [15_871, 15_998, 95]), -1); + +// memory_copy.wast:5210 +assert_return(() => call($33, "checkRange", [15_998, 17_017, 59]), -1); + +// memory_copy.wast:5212 +assert_return(() => call($33, "checkRange", [17_017, 17_288, 76]), -1); + +// memory_copy.wast:5214 +assert_return(() => call($33, "checkRange", [17_288, 17_312, 57]), -1); + +// memory_copy.wast:5216 +assert_return(() => call($33, "checkRange", [17_312, 17_342, 59]), -1); + +// memory_copy.wast:5218 +assert_return(() => call($33, "checkRange", [17_342, 17_464, 32]), -1); + +// memory_copy.wast:5220 +assert_return(() => call($33, "checkRange", [17_464, 17_661, 89]), -1); + +// memory_copy.wast:5222 +assert_return(() => call($33, "checkRange", [17_661, 17_727, 59]), -1); + +// memory_copy.wast:5224 +assert_return(() => call($33, "checkRange", [17_727, 17_733, 5]), -1); + +// memory_copy.wast:5226 +assert_return(() => call($33, "checkRange", [17_733, 17_893, 96]), -1); + +// memory_copy.wast:5228 +assert_return(() => call($33, "checkRange", [17_893, 18_553, 77]), -1); + +// memory_copy.wast:5230 +assert_return(() => call($33, "checkRange", [18_553, 18_744, 42]), -1); + +// memory_copy.wast:5232 +assert_return(() => call($33, "checkRange", [18_744, 18_801, 76]), -1); + +// memory_copy.wast:5234 +assert_return(() => call($33, "checkRange", [18_801, 18_825, 57]), -1); + +// memory_copy.wast:5236 +assert_return(() => call($33, "checkRange", [18_825, 18_876, 59]), -1); + +// memory_copy.wast:5238 +assert_return(() => call($33, "checkRange", [18_876, 18_885, 77]), -1); + +// memory_copy.wast:5240 +assert_return(() => call($33, "checkRange", [18_885, 18_904, 41]), -1); + +// memory_copy.wast:5242 +assert_return(() => call($33, "checkRange", [18_904, 19_567, 83]), -1); + +// memory_copy.wast:5244 +assert_return(() => call($33, "checkRange", [19_567, 20_403, 96]), -1); + +// memory_copy.wast:5246 +assert_return(() => call($33, "checkRange", [20_403, 21_274, 77]), -1); + +// memory_copy.wast:5248 +assert_return(() => call($33, "checkRange", [21_274, 21_364, 100]), -1); + +// memory_copy.wast:5250 +assert_return(() => call($33, "checkRange", [21_364, 21_468, 74]), -1); + +// memory_copy.wast:5252 +assert_return(() => call($33, "checkRange", [21_468, 21_492, 93]), -1); + +// memory_copy.wast:5254 +assert_return(() => call($33, "checkRange", [21_492, 22_051, 74]), -1); + +// memory_copy.wast:5256 +assert_return(() => call($33, "checkRange", [22_051, 22_480, 68]), -1); + +// memory_copy.wast:5258 +assert_return(() => call($33, "checkRange", [22_480, 22_685, 100]), -1); + +// memory_copy.wast:5260 +assert_return(() => call($33, "checkRange", [22_685, 22_694, 68]), -1); + +// memory_copy.wast:5262 +assert_return(() => call($33, "checkRange", [22_694, 22_821, 10]), -1); + +// memory_copy.wast:5264 +assert_return(() => call($33, "checkRange", [22_821, 22_869, 100]), -1); + +// memory_copy.wast:5266 +assert_return(() => call($33, "checkRange", [22_869, 24_107, 97]), -1); + +// memory_copy.wast:5268 +assert_return(() => call($33, "checkRange", [24_107, 24_111, 37]), -1); + +// memory_copy.wast:5270 +assert_return(() => call($33, "checkRange", [24_111, 24_236, 77]), -1); + +// memory_copy.wast:5272 +assert_return(() => call($33, "checkRange", [24_236, 24_348, 72]), -1); + +// memory_copy.wast:5274 +assert_return(() => call($33, "checkRange", [24_348, 24_515, 92]), -1); + +// memory_copy.wast:5276 +assert_return(() => call($33, "checkRange", [24_515, 24_900, 83]), -1); + +// memory_copy.wast:5278 +assert_return(() => call($33, "checkRange", [24_900, 25_136, 95]), -1); + +// memory_copy.wast:5280 +assert_return(() => call($33, "checkRange", [25_136, 25_182, 85]), -1); + +// memory_copy.wast:5282 +assert_return(() => call($33, "checkRange", [25_182, 25_426, 68]), -1); + +// memory_copy.wast:5284 +assert_return(() => call($33, "checkRange", [25_426, 25_613, 89]), -1); + +// memory_copy.wast:5286 +assert_return(() => call($33, "checkRange", [25_613, 25_830, 96]), -1); + +// memory_copy.wast:5288 +assert_return(() => call($33, "checkRange", [25_830, 26_446, 100]), -1); + +// memory_copy.wast:5290 +assert_return(() => call($33, "checkRange", [26_446, 26_517, 10]), -1); + +// memory_copy.wast:5292 +assert_return(() => call($33, "checkRange", [26_517, 27_468, 92]), -1); + +// memory_copy.wast:5294 +assert_return(() => call($33, "checkRange", [27_468, 27_503, 95]), -1); + +// memory_copy.wast:5296 +assert_return(() => call($33, "checkRange", [27_503, 27_573, 77]), -1); + +// memory_copy.wast:5298 +assert_return(() => call($33, "checkRange", [27_573, 28_245, 92]), -1); + +// memory_copy.wast:5300 +assert_return(() => call($33, "checkRange", [28_245, 28_280, 95]), -1); + +// memory_copy.wast:5302 +assert_return(() => call($33, "checkRange", [28_280, 29_502, 77]), -1); + +// memory_copy.wast:5304 +assert_return(() => call($33, "checkRange", [29_502, 29_629, 42]), -1); + +// memory_copy.wast:5306 +assert_return(() => call($33, "checkRange", [29_629, 30_387, 83]), -1); + +// memory_copy.wast:5308 +assert_return(() => call($33, "checkRange", [30_387, 30_646, 77]), -1); + +// memory_copy.wast:5310 +assert_return(() => call($33, "checkRange", [30_646, 31_066, 92]), -1); + +// memory_copy.wast:5312 +assert_return(() => call($33, "checkRange", [31_066, 31_131, 77]), -1); + +// memory_copy.wast:5314 +assert_return(() => call($33, "checkRange", [31_131, 31_322, 42]), -1); + +// memory_copy.wast:5316 +assert_return(() => call($33, "checkRange", [31_322, 31_379, 76]), -1); + +// memory_copy.wast:5318 +assert_return(() => call($33, "checkRange", [31_379, 31_403, 57]), -1); + +// memory_copy.wast:5320 +assert_return(() => call($33, "checkRange", [31_403, 31_454, 59]), -1); + +// memory_copy.wast:5322 +assert_return(() => call($33, "checkRange", [31_454, 31_463, 77]), -1); + +// memory_copy.wast:5324 +assert_return(() => call($33, "checkRange", [31_463, 31_482, 41]), -1); + +// memory_copy.wast:5326 +assert_return(() => call($33, "checkRange", [31_482, 31_649, 83]), -1); + +// memory_copy.wast:5328 +assert_return(() => call($33, "checkRange", [31_649, 31_978, 72]), -1); + +// memory_copy.wast:5330 +assert_return(() => call($33, "checkRange", [31_978, 32_145, 92]), -1); + +// memory_copy.wast:5332 +assert_return(() => call($33, "checkRange", [32_145, 32_530, 83]), -1); + +// memory_copy.wast:5334 +assert_return(() => call($33, "checkRange", [32_530, 32_766, 95]), -1); + +// memory_copy.wast:5336 +assert_return(() => call($33, "checkRange", [32_766, 32_812, 85]), -1); + +// memory_copy.wast:5338 +assert_return(() => call($33, "checkRange", [32_812, 33_056, 68]), -1); + +// memory_copy.wast:5340 +assert_return(() => call($33, "checkRange", [33_056, 33_660, 89]), -1); + +// memory_copy.wast:5342 +assert_return(() => call($33, "checkRange", [33_660, 33_752, 59]), -1); + +// memory_copy.wast:5344 +assert_return(() => call($33, "checkRange", [33_752, 33_775, 36]), -1); + +// memory_copy.wast:5346 +assert_return(() => call($33, "checkRange", [33_775, 33_778, 32]), -1); + +// memory_copy.wast:5348 +assert_return(() => call($33, "checkRange", [33_778, 34_603, 9]), -1); + +// memory_copy.wast:5350 +assert_return(() => call($33, "checkRange", [34_603, 35_218, 0]), -1); + +// memory_copy.wast:5352 +assert_return(() => call($33, "checkRange", [35_218, 35_372, 10]), -1); + +// memory_copy.wast:5354 +assert_return(() => call($33, "checkRange", [35_372, 35_486, 77]), -1); + +// memory_copy.wast:5356 +assert_return(() => call($33, "checkRange", [35_486, 35_605, 5]), -1); + +// memory_copy.wast:5358 +assert_return(() => call($33, "checkRange", [35_605, 35_629, 77]), -1); + +// memory_copy.wast:5360 +assert_return(() => call($33, "checkRange", [35_629, 35_648, 41]), -1); + +// memory_copy.wast:5362 +assert_return(() => call($33, "checkRange", [35_648, 36_547, 83]), -1); + +// memory_copy.wast:5364 +assert_return(() => call($33, "checkRange", [36_547, 36_755, 74]), -1); + +// memory_copy.wast:5366 +assert_return(() => call($33, "checkRange", [36_755, 36_767, 93]), -1); + +// memory_copy.wast:5368 +assert_return(() => call($33, "checkRange", [36_767, 36_810, 83]), -1); + +// memory_copy.wast:5370 +assert_return(() => call($33, "checkRange", [36_810, 36_839, 100]), -1); + +// memory_copy.wast:5372 +assert_return(() => call($33, "checkRange", [36_839, 37_444, 96]), -1); + +// memory_copy.wast:5374 +assert_return(() => call($33, "checkRange", [37_444, 38_060, 100]), -1); + +// memory_copy.wast:5376 +assert_return(() => call($33, "checkRange", [38_060, 38_131, 10]), -1); + +// memory_copy.wast:5378 +assert_return(() => call($33, "checkRange", [38_131, 39_082, 92]), -1); + +// memory_copy.wast:5380 +assert_return(() => call($33, "checkRange", [39_082, 39_117, 95]), -1); + +// memory_copy.wast:5382 +assert_return(() => call($33, "checkRange", [39_117, 39_187, 77]), -1); + +// memory_copy.wast:5384 +assert_return(() => call($33, "checkRange", [39_187, 39_859, 92]), -1); + +// memory_copy.wast:5386 +assert_return(() => call($33, "checkRange", [39_859, 39_894, 95]), -1); + +// memory_copy.wast:5388 +assert_return(() => call($33, "checkRange", [39_894, 40_257, 77]), -1); + +// memory_copy.wast:5390 +assert_return(() => call($33, "checkRange", [40_257, 40_344, 89]), -1); + +// memory_copy.wast:5392 +assert_return(() => call($33, "checkRange", [40_344, 40_371, 59]), -1); + +// memory_copy.wast:5394 +assert_return(() => call($33, "checkRange", [40_371, 40_804, 77]), -1); + +// memory_copy.wast:5396 +assert_return(() => call($33, "checkRange", [40_804, 40_909, 5]), -1); + +// memory_copy.wast:5398 +assert_return(() => call($33, "checkRange", [40_909, 42_259, 92]), -1); + +// memory_copy.wast:5400 +assert_return(() => call($33, "checkRange", [42_259, 42_511, 77]), -1); + +// memory_copy.wast:5402 +assert_return(() => call($33, "checkRange", [42_511, 42_945, 83]), -1); + +// memory_copy.wast:5404 +assert_return(() => call($33, "checkRange", [42_945, 43_115, 77]), -1); + +// memory_copy.wast:5406 +assert_return(() => call($33, "checkRange", [43_115, 43_306, 42]), -1); + +// memory_copy.wast:5408 +assert_return(() => call($33, "checkRange", [43_306, 43_363, 76]), -1); + +// memory_copy.wast:5410 +assert_return(() => call($33, "checkRange", [43_363, 43_387, 57]), -1); + +// memory_copy.wast:5412 +assert_return(() => call($33, "checkRange", [43_387, 43_438, 59]), -1); + +// memory_copy.wast:5414 +assert_return(() => call($33, "checkRange", [43_438, 43_447, 77]), -1); + +// memory_copy.wast:5416 +assert_return(() => call($33, "checkRange", [43_447, 43_466, 41]), -1); + +// memory_copy.wast:5418 +assert_return(() => call($33, "checkRange", [43_466, 44_129, 83]), -1); + +// memory_copy.wast:5420 +assert_return(() => call($33, "checkRange", [44_129, 44_958, 96]), -1); + +// memory_copy.wast:5422 +assert_return(() => call($33, "checkRange", [44_958, 45_570, 77]), -1); + +// memory_copy.wast:5424 +assert_return(() => call($33, "checkRange", [45_570, 45_575, 92]), -1); + +// memory_copy.wast:5426 +assert_return(() => call($33, "checkRange", [45_575, 45_640, 77]), -1); + +// memory_copy.wast:5428 +assert_return(() => call($33, "checkRange", [45_640, 45_742, 42]), -1); + +// memory_copy.wast:5430 +assert_return(() => call($33, "checkRange", [45_742, 45_832, 72]), -1); + +// memory_copy.wast:5432 +assert_return(() => call($33, "checkRange", [45_832, 45_999, 92]), -1); + +// memory_copy.wast:5434 +assert_return(() => call($33, "checkRange", [45_999, 46_384, 83]), -1); + +// memory_copy.wast:5436 +assert_return(() => call($33, "checkRange", [46_384, 46_596, 95]), -1); + +// memory_copy.wast:5438 +assert_return(() => call($33, "checkRange", [46_596, 46_654, 92]), -1); + +// memory_copy.wast:5440 +assert_return(() => call($33, "checkRange", [46_654, 47_515, 83]), -1); + +// memory_copy.wast:5442 +assert_return(() => call($33, "checkRange", [47_515, 47_620, 77]), -1); + +// memory_copy.wast:5444 +assert_return(() => call($33, "checkRange", [47_620, 47_817, 79]), -1); + +// memory_copy.wast:5446 +assert_return(() => call($33, "checkRange", [47_817, 47_951, 95]), -1); + +// memory_copy.wast:5448 +assert_return(() => call($33, "checkRange", [47_951, 48_632, 100]), -1); + +// memory_copy.wast:5450 +assert_return(() => call($33, "checkRange", [48_632, 48_699, 97]), -1); + +// memory_copy.wast:5452 +assert_return(() => call($33, "checkRange", [48_699, 48_703, 37]), -1); + +// memory_copy.wast:5454 +assert_return(() => call($33, "checkRange", [48_703, 49_764, 77]), -1); + +// memory_copy.wast:5456 +assert_return(() => call($33, "checkRange", [49_764, 49_955, 42]), -1); + +// memory_copy.wast:5458 +assert_return(() => call($33, "checkRange", [49_955, 50_012, 76]), -1); + +// memory_copy.wast:5460 +assert_return(() => call($33, "checkRange", [50_012, 50_036, 57]), -1); + +// memory_copy.wast:5462 +assert_return(() => call($33, "checkRange", [50_036, 50_087, 59]), -1); + +// memory_copy.wast:5464 +assert_return(() => call($33, "checkRange", [50_087, 50_096, 77]), -1); + +// memory_copy.wast:5466 +assert_return(() => call($33, "checkRange", [50_096, 50_115, 41]), -1); + +// memory_copy.wast:5468 +assert_return(() => call($33, "checkRange", [50_115, 50_370, 83]), -1); + +// memory_copy.wast:5470 +assert_return(() => call($33, "checkRange", [50_370, 51_358, 92]), -1); + +// memory_copy.wast:5472 +assert_return(() => call($33, "checkRange", [51_358, 51_610, 77]), -1); + +// memory_copy.wast:5474 +assert_return(() => call($33, "checkRange", [51_610, 51_776, 83]), -1); + +// memory_copy.wast:5476 +assert_return(() => call($33, "checkRange", [51_776, 51_833, 89]), -1); + +// memory_copy.wast:5478 +assert_return(() => call($33, "checkRange", [51_833, 52_895, 100]), -1); + +// memory_copy.wast:5480 +assert_return(() => call($33, "checkRange", [52_895, 53_029, 97]), -1); + +// memory_copy.wast:5482 +assert_return(() => call($33, "checkRange", [53_029, 53_244, 68]), -1); + +// memory_copy.wast:5484 +assert_return(() => call($33, "checkRange", [53_244, 54_066, 100]), -1); + +// memory_copy.wast:5486 +assert_return(() => call($33, "checkRange", [54_066, 54_133, 97]), -1); + +// memory_copy.wast:5488 +assert_return(() => call($33, "checkRange", [54_133, 54_137, 37]), -1); + +// memory_copy.wast:5490 +assert_return(() => call($33, "checkRange", [54_137, 55_198, 77]), -1); + +// memory_copy.wast:5492 +assert_return(() => call($33, "checkRange", [55_198, 55_389, 42]), -1); + +// memory_copy.wast:5494 +assert_return(() => call($33, "checkRange", [55_389, 55_446, 76]), -1); + +// memory_copy.wast:5496 +assert_return(() => call($33, "checkRange", [55_446, 55_470, 57]), -1); + +// memory_copy.wast:5498 +assert_return(() => call($33, "checkRange", [55_470, 55_521, 59]), -1); + +// memory_copy.wast:5500 +assert_return(() => call($33, "checkRange", [55_521, 55_530, 77]), -1); + +// memory_copy.wast:5502 +assert_return(() => call($33, "checkRange", [55_530, 55_549, 41]), -1); + +// memory_copy.wast:5504 +assert_return(() => call($33, "checkRange", [55_549, 56_212, 83]), -1); + +// memory_copy.wast:5506 +assert_return(() => call($33, "checkRange", [56_212, 57_048, 96]), -1); + +// memory_copy.wast:5508 +assert_return(() => call($33, "checkRange", [57_048, 58_183, 77]), -1); + +// memory_copy.wast:5510 +assert_return(() => call($33, "checkRange", [58_183, 58_202, 41]), -1); + +// memory_copy.wast:5512 +assert_return(() => call($33, "checkRange", [58_202, 58_516, 83]), -1); + +// memory_copy.wast:5514 +assert_return(() => call($33, "checkRange", [58_516, 58_835, 95]), -1); + +// memory_copy.wast:5516 +assert_return(() => call($33, "checkRange", [58_835, 58_855, 77]), -1); + +// memory_copy.wast:5518 +assert_return(() => call($33, "checkRange", [58_855, 59_089, 95]), -1); + +// memory_copy.wast:5520 +assert_return(() => call($33, "checkRange", [59_089, 59_145, 77]), -1); + +// memory_copy.wast:5522 +assert_return(() => call($33, "checkRange", [59_145, 59_677, 99]), -1); + +// memory_copy.wast:5524 +assert_return(() => call($33, "checkRange", [59_677, 60_134, 0]), -1); + +// memory_copy.wast:5526 +assert_return(() => call($33, "checkRange", [60_134, 60_502, 89]), -1); + +// memory_copy.wast:5528 +assert_return(() => call($33, "checkRange", [60_502, 60_594, 59]), -1); + +// memory_copy.wast:5530 +assert_return(() => call($33, "checkRange", [60_594, 60_617, 36]), -1); + +// memory_copy.wast:5532 +assert_return(() => call($33, "checkRange", [60_617, 60_618, 32]), -1); + +// memory_copy.wast:5534 +assert_return(() => call($33, "checkRange", [60_618, 60_777, 42]), -1); + +// memory_copy.wast:5536 +assert_return(() => call($33, "checkRange", [60_777, 60_834, 76]), -1); + +// memory_copy.wast:5538 +assert_return(() => call($33, "checkRange", [60_834, 60_858, 57]), -1); + +// memory_copy.wast:5540 +assert_return(() => call($33, "checkRange", [60_858, 60_909, 59]), -1); + +// memory_copy.wast:5542 +assert_return(() => call($33, "checkRange", [60_909, 60_918, 77]), -1); + +// memory_copy.wast:5544 +assert_return(() => call($33, "checkRange", [60_918, 60_937, 41]), -1); + +// memory_copy.wast:5546 +assert_return(() => call($33, "checkRange", [60_937, 61_600, 83]), -1); + +// memory_copy.wast:5548 +assert_return(() => call($33, "checkRange", [61_600, 62_436, 96]), -1); + +// memory_copy.wast:5550 +assert_return(() => call($33, "checkRange", [62_436, 63_307, 77]), -1); + +// memory_copy.wast:5552 +assert_return(() => call($33, "checkRange", [63_307, 63_397, 100]), -1); + +// memory_copy.wast:5554 +assert_return(() => call($33, "checkRange", [63_397, 63_501, 74]), -1); + +// memory_copy.wast:5556 +assert_return(() => call($33, "checkRange", [63_501, 63_525, 93]), -1); + +// memory_copy.wast:5558 +assert_return(() => call($33, "checkRange", [63_525, 63_605, 74]), -1); + +// memory_copy.wast:5560 +assert_return(() => call($33, "checkRange", [63_605, 63_704, 100]), -1); + +// memory_copy.wast:5562 +assert_return(() => call($33, "checkRange", [63_704, 63_771, 97]), -1); + +// memory_copy.wast:5564 +assert_return(() => call($33, "checkRange", [63_771, 63_775, 37]), -1); + +// memory_copy.wast:5566 +assert_return(() => call($33, "checkRange", [63_775, 64_311, 77]), -1); + +// memory_copy.wast:5568 +assert_return(() => call($33, "checkRange", [64_311, 64_331, 26]), -1); + +// memory_copy.wast:5570 +assert_return(() => call($33, "checkRange", [64_331, 64_518, 92]), -1); + +// memory_copy.wast:5572 +assert_return(() => call($33, "checkRange", [64_518, 64_827, 11]), -1); + +// memory_copy.wast:5574 +assert_return(() => call($33, "checkRange", [64_827, 64_834, 26]), -1); + +// memory_copy.wast:5576 +assert_return(() => call($33, "checkRange", [64_834, 65_536, 0]), -1); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_fill.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_fill.wast.js new file mode 100644 index 0000000000..fadf36c2bc --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_fill.wast.js @@ -0,0 +1,300 @@ + +// memory_fill.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc1\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8f\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\xd5\x00\x41\x80\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:21 +run(() => call($1, "test", [])); + +// memory_fill.wast:23 +assert_return(() => call($1, "checkRange", [0, 65_280, 0]), -1); + +// memory_fill.wast:25 +assert_return(() => call($1, "checkRange", [65_280, 65_536, 85]), -1); + +// memory_fill.wast:27 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc1\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8f\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\xd5\x00\x41\x81\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:43 +assert_trap(() => call($2, "test", [])); + +// memory_fill.wast:45 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x7e\x41\xd5\x00\x41\x81\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:61 +assert_trap(() => call($3, "test", [])); + +// memory_fill.wast:63 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x41\x12\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:79 +run(() => call($4, "test", [])); + +// memory_fill.wast:81 +assert_return(() => call($4, "checkRange", [0, 65_536, 0]), -1); + +// memory_fill.wast:83 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:99 +run(() => call($5, "test", [])); + +// memory_fill.wast:101 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:117 +assert_trap(() => call($6, "test", [])); + +// memory_fill.wast:119 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\x41\xaa\x01\x41\xfe\xff\x03\xfc\x0b\x00\x0b"); + +// memory_fill.wast:135 +run(() => call($7, "test", [])); + +// memory_fill.wast:137 +assert_return(() => call($7, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:139 +assert_return(() => call($7, "checkRange", [1, 65_535, 170]), -1); + +// memory_fill.wast:141 +assert_return(() => call($7, "checkRange", [65_535, 65_536, 0]), -1); + +// memory_fill.wast:144 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x96\x80\x80\x80\x00\x00\x41\x12\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x15\x41\xaa\x01\x41\x04\xfc\x0b\x00\x0b"); + +// memory_fill.wast:161 +run(() => call($8, "test", [])); + +// memory_fill.wast:163 +assert_return(() => call($8, "checkRange", [0, 18, 0]), -1); + +// memory_fill.wast:165 +assert_return(() => call($8, "checkRange", [18, 21, 85]), -1); + +// memory_fill.wast:167 +assert_return(() => call($8, "checkRange", [21, 25, 170]), -1); + +// memory_fill.wast:169 +assert_return(() => call($8, "checkRange", [25, 28, 85]), -1); + +// memory_fill.wast:171 +assert_return(() => call($8, "checkRange", [28, 65_536, 0]), -1); + +// memory_fill.wast:173 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:179 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:186 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:193 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:200 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:207 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:214 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:221 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:228 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:235 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:242 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:249 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:256 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:263 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:270 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:277 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:284 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:291 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:298 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:305 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:312 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:319 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:326 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:333 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:340 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:347 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:354 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:361 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:368 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:375 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:382 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:389 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:396 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:403 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:410 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:417 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:424 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:431 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:438 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:445 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:452 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:459 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:466 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:473 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:480 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:487 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:494 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:501 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:508 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:515 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:522 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:529 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:536 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:543 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:550 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:557 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:564 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:571 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:578 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:585 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:592 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:599 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:606 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:613 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:620 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:637 +assert_trap(() => call($9, "run", [65_280, 37, 512])); + +// memory_fill.wast:640 +assert_return(() => call($9, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:642 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:659 +assert_trap(() => call($10, "run", [65_279, 37, 514])); + +// memory_fill.wast:662 +assert_return(() => call($10, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:664 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:681 +assert_trap(() => call($11, "run", [65_279, 37, -1])); + +// memory_fill.wast:684 +assert_return(() => call($11, "checkRange", [0, 1, 0]), -1); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_init.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_init.wast.js new file mode 100644 index 0000000000..1e49ac3f3c --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/memory_init.wast.js @@ -0,0 +1,720 @@ + +// memory_init.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:16 +run(() => call($1, "test", [])); + +// memory_init.wast:18 +assert_return(() => call($1, "load8_u", [0]), 0); + +// memory_init.wast:19 +assert_return(() => call($1, "load8_u", [1]), 0); + +// memory_init.wast:20 +assert_return(() => call($1, "load8_u", [2]), 3); + +// memory_init.wast:21 +assert_return(() => call($1, "load8_u", [3]), 1); + +// memory_init.wast:22 +assert_return(() => call($1, "load8_u", [4]), 4); + +// memory_init.wast:23 +assert_return(() => call($1, "load8_u", [5]), 1); + +// memory_init.wast:24 +assert_return(() => call($1, "load8_u", [6]), 0); + +// memory_init.wast:25 +assert_return(() => call($1, "load8_u", [7]), 0); + +// memory_init.wast:26 +assert_return(() => call($1, "load8_u", [8]), 0); + +// memory_init.wast:27 +assert_return(() => call($1, "load8_u", [9]), 0); + +// memory_init.wast:28 +assert_return(() => call($1, "load8_u", [10]), 0); + +// memory_init.wast:29 +assert_return(() => call($1, "load8_u", [11]), 0); + +// memory_init.wast:30 +assert_return(() => call($1, "load8_u", [12]), 7); + +// memory_init.wast:31 +assert_return(() => call($1, "load8_u", [13]), 5); + +// memory_init.wast:32 +assert_return(() => call($1, "load8_u", [14]), 2); + +// memory_init.wast:33 +assert_return(() => call($1, "load8_u", [15]), 3); + +// memory_init.wast:34 +assert_return(() => call($1, "load8_u", [16]), 6); + +// memory_init.wast:35 +assert_return(() => call($1, "load8_u", [17]), 0); + +// memory_init.wast:36 +assert_return(() => call($1, "load8_u", [18]), 0); + +// memory_init.wast:37 +assert_return(() => call($1, "load8_u", [19]), 0); + +// memory_init.wast:38 +assert_return(() => call($1, "load8_u", [20]), 0); + +// memory_init.wast:39 +assert_return(() => call($1, "load8_u", [21]), 0); + +// memory_init.wast:40 +assert_return(() => call($1, "load8_u", [22]), 0); + +// memory_init.wast:41 +assert_return(() => call($1, "load8_u", [23]), 0); + +// memory_init.wast:42 +assert_return(() => call($1, "load8_u", [24]), 0); + +// memory_init.wast:43 +assert_return(() => call($1, "load8_u", [25]), 0); + +// memory_init.wast:44 +assert_return(() => call($1, "load8_u", [26]), 0); + +// memory_init.wast:45 +assert_return(() => call($1, "load8_u", [27]), 0); + +// memory_init.wast:46 +assert_return(() => call($1, "load8_u", [28]), 0); + +// memory_init.wast:47 +assert_return(() => call($1, "load8_u", [29]), 0); + +// memory_init.wast:49 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x08\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:60 +run(() => call($2, "test", [])); + +// memory_init.wast:62 +assert_return(() => call($2, "load8_u", [0]), 0); + +// memory_init.wast:63 +assert_return(() => call($2, "load8_u", [1]), 0); + +// memory_init.wast:64 +assert_return(() => call($2, "load8_u", [2]), 3); + +// memory_init.wast:65 +assert_return(() => call($2, "load8_u", [3]), 1); + +// memory_init.wast:66 +assert_return(() => call($2, "load8_u", [4]), 4); + +// memory_init.wast:67 +assert_return(() => call($2, "load8_u", [5]), 1); + +// memory_init.wast:68 +assert_return(() => call($2, "load8_u", [6]), 0); + +// memory_init.wast:69 +assert_return(() => call($2, "load8_u", [7]), 2); + +// memory_init.wast:70 +assert_return(() => call($2, "load8_u", [8]), 7); + +// memory_init.wast:71 +assert_return(() => call($2, "load8_u", [9]), 1); + +// memory_init.wast:72 +assert_return(() => call($2, "load8_u", [10]), 8); + +// memory_init.wast:73 +assert_return(() => call($2, "load8_u", [11]), 0); + +// memory_init.wast:74 +assert_return(() => call($2, "load8_u", [12]), 7); + +// memory_init.wast:75 +assert_return(() => call($2, "load8_u", [13]), 5); + +// memory_init.wast:76 +assert_return(() => call($2, "load8_u", [14]), 2); + +// memory_init.wast:77 +assert_return(() => call($2, "load8_u", [15]), 3); + +// memory_init.wast:78 +assert_return(() => call($2, "load8_u", [16]), 6); + +// memory_init.wast:79 +assert_return(() => call($2, "load8_u", [17]), 0); + +// memory_init.wast:80 +assert_return(() => call($2, "load8_u", [18]), 0); + +// memory_init.wast:81 +assert_return(() => call($2, "load8_u", [19]), 0); + +// memory_init.wast:82 +assert_return(() => call($2, "load8_u", [20]), 0); + +// memory_init.wast:83 +assert_return(() => call($2, "load8_u", [21]), 0); + +// memory_init.wast:84 +assert_return(() => call($2, "load8_u", [22]), 0); + +// memory_init.wast:85 +assert_return(() => call($2, "load8_u", [23]), 0); + +// memory_init.wast:86 +assert_return(() => call($2, "load8_u", [24]), 0); + +// memory_init.wast:87 +assert_return(() => call($2, "load8_u", [25]), 0); + +// memory_init.wast:88 +assert_return(() => call($2, "load8_u", [26]), 0); + +// memory_init.wast:89 +assert_return(() => call($2, "load8_u", [27]), 0); + +// memory_init.wast:90 +assert_return(() => call($2, "load8_u", [28]), 0); + +// memory_init.wast:91 +assert_return(() => call($2, "load8_u", [29]), 0); + +// memory_init.wast:93 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x01\x41\x03\xfc\x08\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:104 +run(() => call($3, "test", [])); + +// memory_init.wast:106 +assert_return(() => call($3, "load8_u", [0]), 0); + +// memory_init.wast:107 +assert_return(() => call($3, "load8_u", [1]), 0); + +// memory_init.wast:108 +assert_return(() => call($3, "load8_u", [2]), 3); + +// memory_init.wast:109 +assert_return(() => call($3, "load8_u", [3]), 1); + +// memory_init.wast:110 +assert_return(() => call($3, "load8_u", [4]), 4); + +// memory_init.wast:111 +assert_return(() => call($3, "load8_u", [5]), 1); + +// memory_init.wast:112 +assert_return(() => call($3, "load8_u", [6]), 0); + +// memory_init.wast:113 +assert_return(() => call($3, "load8_u", [7]), 0); + +// memory_init.wast:114 +assert_return(() => call($3, "load8_u", [8]), 0); + +// memory_init.wast:115 +assert_return(() => call($3, "load8_u", [9]), 0); + +// memory_init.wast:116 +assert_return(() => call($3, "load8_u", [10]), 0); + +// memory_init.wast:117 +assert_return(() => call($3, "load8_u", [11]), 0); + +// memory_init.wast:118 +assert_return(() => call($3, "load8_u", [12]), 7); + +// memory_init.wast:119 +assert_return(() => call($3, "load8_u", [13]), 5); + +// memory_init.wast:120 +assert_return(() => call($3, "load8_u", [14]), 2); + +// memory_init.wast:121 +assert_return(() => call($3, "load8_u", [15]), 9); + +// memory_init.wast:122 +assert_return(() => call($3, "load8_u", [16]), 2); + +// memory_init.wast:123 +assert_return(() => call($3, "load8_u", [17]), 7); + +// memory_init.wast:124 +assert_return(() => call($3, "load8_u", [18]), 0); + +// memory_init.wast:125 +assert_return(() => call($3, "load8_u", [19]), 0); + +// memory_init.wast:126 +assert_return(() => call($3, "load8_u", [20]), 0); + +// memory_init.wast:127 +assert_return(() => call($3, "load8_u", [21]), 0); + +// memory_init.wast:128 +assert_return(() => call($3, "load8_u", [22]), 0); + +// memory_init.wast:129 +assert_return(() => call($3, "load8_u", [23]), 0); + +// memory_init.wast:130 +assert_return(() => call($3, "load8_u", [24]), 0); + +// memory_init.wast:131 +assert_return(() => call($3, "load8_u", [25]), 0); + +// memory_init.wast:132 +assert_return(() => call($3, "load8_u", [26]), 0); + +// memory_init.wast:133 +assert_return(() => call($3, "load8_u", [27]), 0); + +// memory_init.wast:134 +assert_return(() => call($3, "load8_u", [28]), 0); + +// memory_init.wast:135 +assert_return(() => call($3, "load8_u", [29]), 0); + +// memory_init.wast:137 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\xe0\x80\x80\x80\x00\x02\xce\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x08\x01\x00\xfc\x09\x01\x41\x0f\x41\x01\x41\x03\xfc\x08\x03\x00\xfc\x09\x03\x41\x14\x41\x0f\x41\x05\xfc\x0a\x00\x00\x41\x15\x41\x1d\x41\x01\xfc\x0a\x00\x00\x41\x18\x41\x0a\x41\x01\xfc\x0a\x00\x00\x41\x0d\x41\x0b\x41\x04\xfc\x0a\x00\x00\x41\x13\x41\x14\x41\x05\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:156 +run(() => call($4, "test", [])); + +// memory_init.wast:158 +assert_return(() => call($4, "load8_u", [0]), 0); + +// memory_init.wast:159 +assert_return(() => call($4, "load8_u", [1]), 0); + +// memory_init.wast:160 +assert_return(() => call($4, "load8_u", [2]), 3); + +// memory_init.wast:161 +assert_return(() => call($4, "load8_u", [3]), 1); + +// memory_init.wast:162 +assert_return(() => call($4, "load8_u", [4]), 4); + +// memory_init.wast:163 +assert_return(() => call($4, "load8_u", [5]), 1); + +// memory_init.wast:164 +assert_return(() => call($4, "load8_u", [6]), 0); + +// memory_init.wast:165 +assert_return(() => call($4, "load8_u", [7]), 2); + +// memory_init.wast:166 +assert_return(() => call($4, "load8_u", [8]), 7); + +// memory_init.wast:167 +assert_return(() => call($4, "load8_u", [9]), 1); + +// memory_init.wast:168 +assert_return(() => call($4, "load8_u", [10]), 8); + +// memory_init.wast:169 +assert_return(() => call($4, "load8_u", [11]), 0); + +// memory_init.wast:170 +assert_return(() => call($4, "load8_u", [12]), 7); + +// memory_init.wast:171 +assert_return(() => call($4, "load8_u", [13]), 0); + +// memory_init.wast:172 +assert_return(() => call($4, "load8_u", [14]), 7); + +// memory_init.wast:173 +assert_return(() => call($4, "load8_u", [15]), 5); + +// memory_init.wast:174 +assert_return(() => call($4, "load8_u", [16]), 2); + +// memory_init.wast:175 +assert_return(() => call($4, "load8_u", [17]), 7); + +// memory_init.wast:176 +assert_return(() => call($4, "load8_u", [18]), 0); + +// memory_init.wast:177 +assert_return(() => call($4, "load8_u", [19]), 9); + +// memory_init.wast:178 +assert_return(() => call($4, "load8_u", [20]), 0); + +// memory_init.wast:179 +assert_return(() => call($4, "load8_u", [21]), 7); + +// memory_init.wast:180 +assert_return(() => call($4, "load8_u", [22]), 0); + +// memory_init.wast:181 +assert_return(() => call($4, "load8_u", [23]), 8); + +// memory_init.wast:182 +assert_return(() => call($4, "load8_u", [24]), 8); + +// memory_init.wast:183 +assert_return(() => call($4, "load8_u", [25]), 0); + +// memory_init.wast:184 +assert_return(() => call($4, "load8_u", [26]), 0); + +// memory_init.wast:185 +assert_return(() => call($4, "load8_u", [27]), 0); + +// memory_init.wast:186 +assert_return(() => call($4, "load8_u", [28]), 0); + +// memory_init.wast:187 +assert_return(() => call($4, "load8_u", [29]), 0); + +// memory_init.wast:188 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b"); + +// memory_init.wast:194 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x04\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:202 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\xfc\x09\x00\xfc\x09\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:208 +run(() => call($5, "test", [])); + +// memory_init.wast:210 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\xfc\x09\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:216 +assert_trap(() => call($6, "test", [])); + +// memory_init.wast:218 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x37"); + +// memory_init.wast:223 +assert_trap(() => call($7, "test", [])); + +// memory_init.wast:225 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x01\x00\x0b"); + +// memory_init.wast:231 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x01\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:239 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x41\x00\x41\x01\xfc\x08\x00\x00\x41\x01\x41\x00\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:245 +run(() => call($8, "test", [])); + +// memory_init.wast:247 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x00\x41\x05\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:252 +assert_trap(() => call($9, "test", [])); + +// memory_init.wast:254 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x02\x41\x03\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:259 +assert_trap(() => call($10, "test", [])); + +// memory_init.wast:261 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\xfe\xff\x03\x41\x01\x41\x03\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:266 +assert_trap(() => call($11, "test", [])); + +// memory_init.wast:268 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x04\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:273 +assert_trap(() => call($12, "test", [])); + +// memory_init.wast:275 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:280 +run(() => call($13, "test", [])); + +// memory_init.wast:282 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x81\x80\x04\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:287 +assert_trap(() => call($14, "test", [])); + +// memory_init.wast:289 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:294 +run(() => call($15, "test", [])); + +// memory_init.wast:296 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x01\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:301 +run(() => call($16, "test", [])); + +// memory_init.wast:303 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x81\x80\x04\x41\x04\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:308 +assert_trap(() => call($17, "test", [])); + +// memory_init.wast:310 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:318 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:326 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:334 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:342 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:350 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:358 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:366 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:374 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:382 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:390 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:398 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:406 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:414 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:422 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:430 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:438 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:446 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:454 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:462 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:470 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:478 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:486 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:494 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:502 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:510 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:518 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:526 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:534 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:542 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:550 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:558 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:566 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:574 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:582 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:590 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:598 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:606 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:614 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:622 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:630 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:638 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:646 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:654 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:662 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:670 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:678 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:686 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:694 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:702 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:710 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:718 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:726 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:734 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:742 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:750 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:758 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:766 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:774 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:782 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:790 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:798 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:806 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:814 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:832 +assert_trap(() => call($18, "run", [65_528, 16])); + +// memory_init.wast:835 +assert_return(() => call($18, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:837 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:855 +assert_trap(() => call($19, "run", [65_527, 16])); + +// memory_init.wast:858 +assert_return(() => call($19, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:860 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:878 +assert_trap(() => call($20, "run", [65_472, 30])); + +// memory_init.wast:881 +assert_return(() => call($20, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:883 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:901 +assert_trap(() => call($21, "run", [65_473, 31])); + +// memory_init.wast:904 +assert_return(() => call($21, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:906 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:924 +assert_trap(() => call($22, "run", [65_528, -256])); + +// memory_init.wast:927 +assert_return(() => call($22, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:929 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:947 +assert_trap(() => call($23, "run", [0, -4])); + +// memory_init.wast:950 +assert_return(() => call($23, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:953 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0c\x81\x80\x80\x80\x00\x41\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\xfc\x08\x40\x00\x0b\x0b\x83\x81\x80\x80\x00\x41\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_copy.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_copy.wast.js new file mode 100644 index 0000000000..362b2dbc6c --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_copy.wast.js @@ -0,0 +1,2538 @@ + +// table_copy.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x00\x00\x07\x9f\x80\x80\x80\x00\x05\x03\x65\x66\x30\x00\x00\x03\x65\x66\x31\x00\x01\x03\x65\x66\x32\x00\x02\x03\x65\x66\x33\x00\x03\x03\x65\x66\x34\x00\x04\x0a\xae\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b"); + +// table_copy.wast:12 +register("a", $1) + +// table_copy.wast:14 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xc2\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:39 +run(() => call($2, "test", [])); + +// table_copy.wast:40 +assert_trap(() => call($2, "check", [0])); + +// table_copy.wast:41 +assert_trap(() => call($2, "check", [1])); + +// table_copy.wast:42 +assert_return(() => call($2, "check", [2]), 3); + +// table_copy.wast:43 +assert_return(() => call($2, "check", [3]), 1); + +// table_copy.wast:44 +assert_return(() => call($2, "check", [4]), 4); + +// table_copy.wast:45 +assert_return(() => call($2, "check", [5]), 1); + +// table_copy.wast:46 +assert_trap(() => call($2, "check", [6])); + +// table_copy.wast:47 +assert_trap(() => call($2, "check", [7])); + +// table_copy.wast:48 +assert_trap(() => call($2, "check", [8])); + +// table_copy.wast:49 +assert_trap(() => call($2, "check", [9])); + +// table_copy.wast:50 +assert_trap(() => call($2, "check", [10])); + +// table_copy.wast:51 +assert_trap(() => call($2, "check", [11])); + +// table_copy.wast:52 +assert_return(() => call($2, "check", [12]), 7); + +// table_copy.wast:53 +assert_return(() => call($2, "check", [13]), 5); + +// table_copy.wast:54 +assert_return(() => call($2, "check", [14]), 2); + +// table_copy.wast:55 +assert_return(() => call($2, "check", [15]), 3); + +// table_copy.wast:56 +assert_return(() => call($2, "check", [16]), 6); + +// table_copy.wast:57 +assert_trap(() => call($2, "check", [17])); + +// table_copy.wast:58 +assert_trap(() => call($2, "check", [18])); + +// table_copy.wast:59 +assert_trap(() => call($2, "check", [19])); + +// table_copy.wast:60 +assert_trap(() => call($2, "check", [20])); + +// table_copy.wast:61 +assert_trap(() => call($2, "check", [21])); + +// table_copy.wast:62 +assert_trap(() => call($2, "check", [22])); + +// table_copy.wast:63 +assert_trap(() => call($2, "check", [23])); + +// table_copy.wast:64 +assert_trap(() => call($2, "check", [24])); + +// table_copy.wast:65 +assert_trap(() => call($2, "check", [25])); + +// table_copy.wast:66 +assert_trap(() => call($2, "check", [26])); + +// table_copy.wast:67 +assert_trap(() => call($2, "check", [27])); + +// table_copy.wast:68 +assert_trap(() => call($2, "check", [28])); + +// table_copy.wast:69 +assert_trap(() => call($2, "check", [29])); + +// table_copy.wast:71 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x02\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:96 +run(() => call($3, "test", [])); + +// table_copy.wast:97 +assert_trap(() => call($3, "check", [0])); + +// table_copy.wast:98 +assert_trap(() => call($3, "check", [1])); + +// table_copy.wast:99 +assert_return(() => call($3, "check", [2]), 3); + +// table_copy.wast:100 +assert_return(() => call($3, "check", [3]), 1); + +// table_copy.wast:101 +assert_return(() => call($3, "check", [4]), 4); + +// table_copy.wast:102 +assert_return(() => call($3, "check", [5]), 1); + +// table_copy.wast:103 +assert_trap(() => call($3, "check", [6])); + +// table_copy.wast:104 +assert_trap(() => call($3, "check", [7])); + +// table_copy.wast:105 +assert_trap(() => call($3, "check", [8])); + +// table_copy.wast:106 +assert_trap(() => call($3, "check", [9])); + +// table_copy.wast:107 +assert_trap(() => call($3, "check", [10])); + +// table_copy.wast:108 +assert_trap(() => call($3, "check", [11])); + +// table_copy.wast:109 +assert_return(() => call($3, "check", [12]), 7); + +// table_copy.wast:110 +assert_return(() => call($3, "check", [13]), 3); + +// table_copy.wast:111 +assert_return(() => call($3, "check", [14]), 1); + +// table_copy.wast:112 +assert_return(() => call($3, "check", [15]), 4); + +// table_copy.wast:113 +assert_return(() => call($3, "check", [16]), 6); + +// table_copy.wast:114 +assert_trap(() => call($3, "check", [17])); + +// table_copy.wast:115 +assert_trap(() => call($3, "check", [18])); + +// table_copy.wast:116 +assert_trap(() => call($3, "check", [19])); + +// table_copy.wast:117 +assert_trap(() => call($3, "check", [20])); + +// table_copy.wast:118 +assert_trap(() => call($3, "check", [21])); + +// table_copy.wast:119 +assert_trap(() => call($3, "check", [22])); + +// table_copy.wast:120 +assert_trap(() => call($3, "check", [23])); + +// table_copy.wast:121 +assert_trap(() => call($3, "check", [24])); + +// table_copy.wast:122 +assert_trap(() => call($3, "check", [25])); + +// table_copy.wast:123 +assert_trap(() => call($3, "check", [26])); + +// table_copy.wast:124 +assert_trap(() => call($3, "check", [27])); + +// table_copy.wast:125 +assert_trap(() => call($3, "check", [28])); + +// table_copy.wast:126 +assert_trap(() => call($3, "check", [29])); + +// table_copy.wast:128 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x0f\x41\x02\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:153 +run(() => call($4, "test", [])); + +// table_copy.wast:154 +assert_trap(() => call($4, "check", [0])); + +// table_copy.wast:155 +assert_trap(() => call($4, "check", [1])); + +// table_copy.wast:156 +assert_return(() => call($4, "check", [2]), 3); + +// table_copy.wast:157 +assert_return(() => call($4, "check", [3]), 1); + +// table_copy.wast:158 +assert_return(() => call($4, "check", [4]), 4); + +// table_copy.wast:159 +assert_return(() => call($4, "check", [5]), 1); + +// table_copy.wast:160 +assert_trap(() => call($4, "check", [6])); + +// table_copy.wast:161 +assert_trap(() => call($4, "check", [7])); + +// table_copy.wast:162 +assert_trap(() => call($4, "check", [8])); + +// table_copy.wast:163 +assert_trap(() => call($4, "check", [9])); + +// table_copy.wast:164 +assert_trap(() => call($4, "check", [10])); + +// table_copy.wast:165 +assert_trap(() => call($4, "check", [11])); + +// table_copy.wast:166 +assert_return(() => call($4, "check", [12]), 7); + +// table_copy.wast:167 +assert_return(() => call($4, "check", [13]), 5); + +// table_copy.wast:168 +assert_return(() => call($4, "check", [14]), 2); + +// table_copy.wast:169 +assert_return(() => call($4, "check", [15]), 3); + +// table_copy.wast:170 +assert_return(() => call($4, "check", [16]), 6); + +// table_copy.wast:171 +assert_trap(() => call($4, "check", [17])); + +// table_copy.wast:172 +assert_trap(() => call($4, "check", [18])); + +// table_copy.wast:173 +assert_trap(() => call($4, "check", [19])); + +// table_copy.wast:174 +assert_trap(() => call($4, "check", [20])); + +// table_copy.wast:175 +assert_trap(() => call($4, "check", [21])); + +// table_copy.wast:176 +assert_trap(() => call($4, "check", [22])); + +// table_copy.wast:177 +assert_trap(() => call($4, "check", [23])); + +// table_copy.wast:178 +assert_trap(() => call($4, "check", [24])); + +// table_copy.wast:179 +assert_return(() => call($4, "check", [25]), 3); + +// table_copy.wast:180 +assert_return(() => call($4, "check", [26]), 6); + +// table_copy.wast:181 +assert_trap(() => call($4, "check", [27])); + +// table_copy.wast:182 +assert_trap(() => call($4, "check", [28])); + +// table_copy.wast:183 +assert_trap(() => call($4, "check", [29])); + +// table_copy.wast:185 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x19\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:210 +run(() => call($5, "test", [])); + +// table_copy.wast:211 +assert_trap(() => call($5, "check", [0])); + +// table_copy.wast:212 +assert_trap(() => call($5, "check", [1])); + +// table_copy.wast:213 +assert_return(() => call($5, "check", [2]), 3); + +// table_copy.wast:214 +assert_return(() => call($5, "check", [3]), 1); + +// table_copy.wast:215 +assert_return(() => call($5, "check", [4]), 4); + +// table_copy.wast:216 +assert_return(() => call($5, "check", [5]), 1); + +// table_copy.wast:217 +assert_trap(() => call($5, "check", [6])); + +// table_copy.wast:218 +assert_trap(() => call($5, "check", [7])); + +// table_copy.wast:219 +assert_trap(() => call($5, "check", [8])); + +// table_copy.wast:220 +assert_trap(() => call($5, "check", [9])); + +// table_copy.wast:221 +assert_trap(() => call($5, "check", [10])); + +// table_copy.wast:222 +assert_trap(() => call($5, "check", [11])); + +// table_copy.wast:223 +assert_return(() => call($5, "check", [12]), 7); + +// table_copy.wast:224 +assert_trap(() => call($5, "check", [13])); + +// table_copy.wast:225 +assert_trap(() => call($5, "check", [14])); + +// table_copy.wast:226 +assert_trap(() => call($5, "check", [15])); + +// table_copy.wast:227 +assert_return(() => call($5, "check", [16]), 6); + +// table_copy.wast:228 +assert_trap(() => call($5, "check", [17])); + +// table_copy.wast:229 +assert_trap(() => call($5, "check", [18])); + +// table_copy.wast:230 +assert_trap(() => call($5, "check", [19])); + +// table_copy.wast:231 +assert_trap(() => call($5, "check", [20])); + +// table_copy.wast:232 +assert_trap(() => call($5, "check", [21])); + +// table_copy.wast:233 +assert_trap(() => call($5, "check", [22])); + +// table_copy.wast:234 +assert_trap(() => call($5, "check", [23])); + +// table_copy.wast:235 +assert_trap(() => call($5, "check", [24])); + +// table_copy.wast:236 +assert_trap(() => call($5, "check", [25])); + +// table_copy.wast:237 +assert_trap(() => call($5, "check", [26])); + +// table_copy.wast:238 +assert_trap(() => call($5, "check", [27])); + +// table_copy.wast:239 +assert_trap(() => call($5, "check", [28])); + +// table_copy.wast:240 +assert_trap(() => call($5, "check", [29])); + +// table_copy.wast:242 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x14\x41\x16\x41\x04\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:267 +run(() => call($6, "test", [])); + +// table_copy.wast:268 +assert_trap(() => call($6, "check", [0])); + +// table_copy.wast:269 +assert_trap(() => call($6, "check", [1])); + +// table_copy.wast:270 +assert_return(() => call($6, "check", [2]), 3); + +// table_copy.wast:271 +assert_return(() => call($6, "check", [3]), 1); + +// table_copy.wast:272 +assert_return(() => call($6, "check", [4]), 4); + +// table_copy.wast:273 +assert_return(() => call($6, "check", [5]), 1); + +// table_copy.wast:274 +assert_trap(() => call($6, "check", [6])); + +// table_copy.wast:275 +assert_trap(() => call($6, "check", [7])); + +// table_copy.wast:276 +assert_trap(() => call($6, "check", [8])); + +// table_copy.wast:277 +assert_trap(() => call($6, "check", [9])); + +// table_copy.wast:278 +assert_trap(() => call($6, "check", [10])); + +// table_copy.wast:279 +assert_trap(() => call($6, "check", [11])); + +// table_copy.wast:280 +assert_return(() => call($6, "check", [12]), 7); + +// table_copy.wast:281 +assert_return(() => call($6, "check", [13]), 5); + +// table_copy.wast:282 +assert_return(() => call($6, "check", [14]), 2); + +// table_copy.wast:283 +assert_return(() => call($6, "check", [15]), 3); + +// table_copy.wast:284 +assert_return(() => call($6, "check", [16]), 6); + +// table_copy.wast:285 +assert_trap(() => call($6, "check", [17])); + +// table_copy.wast:286 +assert_trap(() => call($6, "check", [18])); + +// table_copy.wast:287 +assert_trap(() => call($6, "check", [19])); + +// table_copy.wast:288 +assert_trap(() => call($6, "check", [20])); + +// table_copy.wast:289 +assert_trap(() => call($6, "check", [21])); + +// table_copy.wast:290 +assert_trap(() => call($6, "check", [22])); + +// table_copy.wast:291 +assert_trap(() => call($6, "check", [23])); + +// table_copy.wast:292 +assert_trap(() => call($6, "check", [24])); + +// table_copy.wast:293 +assert_trap(() => call($6, "check", [25])); + +// table_copy.wast:294 +assert_trap(() => call($6, "check", [26])); + +// table_copy.wast:295 +assert_trap(() => call($6, "check", [27])); + +// table_copy.wast:296 +assert_trap(() => call($6, "check", [28])); + +// table_copy.wast:297 +assert_trap(() => call($6, "check", [29])); + +// table_copy.wast:299 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x01\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:324 +run(() => call($7, "test", [])); + +// table_copy.wast:325 +assert_trap(() => call($7, "check", [0])); + +// table_copy.wast:326 +assert_trap(() => call($7, "check", [1])); + +// table_copy.wast:327 +assert_return(() => call($7, "check", [2]), 3); + +// table_copy.wast:328 +assert_return(() => call($7, "check", [3]), 1); + +// table_copy.wast:329 +assert_return(() => call($7, "check", [4]), 4); + +// table_copy.wast:330 +assert_return(() => call($7, "check", [5]), 1); + +// table_copy.wast:331 +assert_trap(() => call($7, "check", [6])); + +// table_copy.wast:332 +assert_trap(() => call($7, "check", [7])); + +// table_copy.wast:333 +assert_trap(() => call($7, "check", [8])); + +// table_copy.wast:334 +assert_trap(() => call($7, "check", [9])); + +// table_copy.wast:335 +assert_trap(() => call($7, "check", [10])); + +// table_copy.wast:336 +assert_trap(() => call($7, "check", [11])); + +// table_copy.wast:337 +assert_return(() => call($7, "check", [12]), 7); + +// table_copy.wast:338 +assert_return(() => call($7, "check", [13]), 5); + +// table_copy.wast:339 +assert_return(() => call($7, "check", [14]), 2); + +// table_copy.wast:340 +assert_return(() => call($7, "check", [15]), 3); + +// table_copy.wast:341 +assert_return(() => call($7, "check", [16]), 6); + +// table_copy.wast:342 +assert_trap(() => call($7, "check", [17])); + +// table_copy.wast:343 +assert_trap(() => call($7, "check", [18])); + +// table_copy.wast:344 +assert_trap(() => call($7, "check", [19])); + +// table_copy.wast:345 +assert_trap(() => call($7, "check", [20])); + +// table_copy.wast:346 +assert_trap(() => call($7, "check", [21])); + +// table_copy.wast:347 +assert_trap(() => call($7, "check", [22])); + +// table_copy.wast:348 +assert_trap(() => call($7, "check", [23])); + +// table_copy.wast:349 +assert_trap(() => call($7, "check", [24])); + +// table_copy.wast:350 +assert_trap(() => call($7, "check", [25])); + +// table_copy.wast:351 +assert_return(() => call($7, "check", [26]), 3); + +// table_copy.wast:352 +assert_return(() => call($7, "check", [27]), 1); + +// table_copy.wast:353 +assert_trap(() => call($7, "check", [28])); + +// table_copy.wast:354 +assert_trap(() => call($7, "check", [29])); + +// table_copy.wast:356 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x0c\x41\x07\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:381 +run(() => call($8, "test", [])); + +// table_copy.wast:382 +assert_trap(() => call($8, "check", [0])); + +// table_copy.wast:383 +assert_trap(() => call($8, "check", [1])); + +// table_copy.wast:384 +assert_return(() => call($8, "check", [2]), 3); + +// table_copy.wast:385 +assert_return(() => call($8, "check", [3]), 1); + +// table_copy.wast:386 +assert_return(() => call($8, "check", [4]), 4); + +// table_copy.wast:387 +assert_return(() => call($8, "check", [5]), 1); + +// table_copy.wast:388 +assert_trap(() => call($8, "check", [6])); + +// table_copy.wast:389 +assert_trap(() => call($8, "check", [7])); + +// table_copy.wast:390 +assert_trap(() => call($8, "check", [8])); + +// table_copy.wast:391 +assert_trap(() => call($8, "check", [9])); + +// table_copy.wast:392 +assert_return(() => call($8, "check", [10]), 7); + +// table_copy.wast:393 +assert_return(() => call($8, "check", [11]), 5); + +// table_copy.wast:394 +assert_return(() => call($8, "check", [12]), 2); + +// table_copy.wast:395 +assert_return(() => call($8, "check", [13]), 3); + +// table_copy.wast:396 +assert_return(() => call($8, "check", [14]), 6); + +// table_copy.wast:397 +assert_trap(() => call($8, "check", [15])); + +// table_copy.wast:398 +assert_trap(() => call($8, "check", [16])); + +// table_copy.wast:399 +assert_trap(() => call($8, "check", [17])); + +// table_copy.wast:400 +assert_trap(() => call($8, "check", [18])); + +// table_copy.wast:401 +assert_trap(() => call($8, "check", [19])); + +// table_copy.wast:402 +assert_trap(() => call($8, "check", [20])); + +// table_copy.wast:403 +assert_trap(() => call($8, "check", [21])); + +// table_copy.wast:404 +assert_trap(() => call($8, "check", [22])); + +// table_copy.wast:405 +assert_trap(() => call($8, "check", [23])); + +// table_copy.wast:406 +assert_trap(() => call($8, "check", [24])); + +// table_copy.wast:407 +assert_trap(() => call($8, "check", [25])); + +// table_copy.wast:408 +assert_trap(() => call($8, "check", [26])); + +// table_copy.wast:409 +assert_trap(() => call($8, "check", [27])); + +// table_copy.wast:410 +assert_trap(() => call($8, "check", [28])); + +// table_copy.wast:411 +assert_trap(() => call($8, "check", [29])); + +// table_copy.wast:413 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x0a\x41\x07\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:438 +run(() => call($9, "test", [])); + +// table_copy.wast:439 +assert_trap(() => call($9, "check", [0])); + +// table_copy.wast:440 +assert_trap(() => call($9, "check", [1])); + +// table_copy.wast:441 +assert_return(() => call($9, "check", [2]), 3); + +// table_copy.wast:442 +assert_return(() => call($9, "check", [3]), 1); + +// table_copy.wast:443 +assert_return(() => call($9, "check", [4]), 4); + +// table_copy.wast:444 +assert_return(() => call($9, "check", [5]), 1); + +// table_copy.wast:445 +assert_trap(() => call($9, "check", [6])); + +// table_copy.wast:446 +assert_trap(() => call($9, "check", [7])); + +// table_copy.wast:447 +assert_trap(() => call($9, "check", [8])); + +// table_copy.wast:448 +assert_trap(() => call($9, "check", [9])); + +// table_copy.wast:449 +assert_trap(() => call($9, "check", [10])); + +// table_copy.wast:450 +assert_trap(() => call($9, "check", [11])); + +// table_copy.wast:451 +assert_trap(() => call($9, "check", [12])); + +// table_copy.wast:452 +assert_trap(() => call($9, "check", [13])); + +// table_copy.wast:453 +assert_return(() => call($9, "check", [14]), 7); + +// table_copy.wast:454 +assert_return(() => call($9, "check", [15]), 5); + +// table_copy.wast:455 +assert_return(() => call($9, "check", [16]), 2); + +// table_copy.wast:456 +assert_return(() => call($9, "check", [17]), 3); + +// table_copy.wast:457 +assert_return(() => call($9, "check", [18]), 6); + +// table_copy.wast:458 +assert_trap(() => call($9, "check", [19])); + +// table_copy.wast:459 +assert_trap(() => call($9, "check", [20])); + +// table_copy.wast:460 +assert_trap(() => call($9, "check", [21])); + +// table_copy.wast:461 +assert_trap(() => call($9, "check", [22])); + +// table_copy.wast:462 +assert_trap(() => call($9, "check", [23])); + +// table_copy.wast:463 +assert_trap(() => call($9, "check", [24])); + +// table_copy.wast:464 +assert_trap(() => call($9, "check", [25])); + +// table_copy.wast:465 +assert_trap(() => call($9, "check", [26])); + +// table_copy.wast:466 +assert_trap(() => call($9, "check", [27])); + +// table_copy.wast:467 +assert_trap(() => call($9, "check", [28])); + +// table_copy.wast:468 +assert_trap(() => call($9, "check", [29])); + +// table_copy.wast:470 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x01\x41\x03\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:492 +assert_trap(() => call($10, "test", [])); + +// table_copy.wast:494 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x7e\x41\x01\x41\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:516 +assert_trap(() => call($11, "test", [])); + +// table_copy.wast:518 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x06\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:540 +assert_trap(() => call($12, "test", [])); + +// table_copy.wast:542 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x7e\x41\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:564 +assert_trap(() => call($13, "test", [])); + +// table_copy.wast:566 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:588 +run(() => call($14, "test", [])); + +// table_copy.wast:590 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x0f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:612 +run(() => call($15, "test", [])); + +// table_copy.wast:614 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x0f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:636 +assert_trap(() => call($16, "test", [])); + +// table_copy.wast:638 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1e\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:660 +run(() => call($17, "test", [])); + +// table_copy.wast:662 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:684 +assert_trap(() => call($18, "test", [])); + +// table_copy.wast:686 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x1e\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:708 +run(() => call($19, "test", [])); + +// table_copy.wast:710 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x1f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:732 +assert_trap(() => call($20, "test", [])); + +// table_copy.wast:734 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:760 +assert_trap(() => call($21, "run", [24, 0, 16])); + +// table_copy.wast:762 +assert_return(() => call($21, "test", [0]), 0); + +// table_copy.wast:763 +assert_return(() => call($21, "test", [1]), 1); + +// table_copy.wast:764 +assert_return(() => call($21, "test", [2]), 2); + +// table_copy.wast:765 +assert_return(() => call($21, "test", [3]), 3); + +// table_copy.wast:766 +assert_return(() => call($21, "test", [4]), 4); + +// table_copy.wast:767 +assert_return(() => call($21, "test", [5]), 5); + +// table_copy.wast:768 +assert_return(() => call($21, "test", [6]), 6); + +// table_copy.wast:769 +assert_return(() => call($21, "test", [7]), 7); + +// table_copy.wast:770 +assert_trap(() => call($21, "test", [8])); + +// table_copy.wast:771 +assert_trap(() => call($21, "test", [9])); + +// table_copy.wast:772 +assert_trap(() => call($21, "test", [10])); + +// table_copy.wast:773 +assert_trap(() => call($21, "test", [11])); + +// table_copy.wast:774 +assert_trap(() => call($21, "test", [12])); + +// table_copy.wast:775 +assert_trap(() => call($21, "test", [13])); + +// table_copy.wast:776 +assert_trap(() => call($21, "test", [14])); + +// table_copy.wast:777 +assert_trap(() => call($21, "test", [15])); + +// table_copy.wast:778 +assert_trap(() => call($21, "test", [16])); + +// table_copy.wast:779 +assert_trap(() => call($21, "test", [17])); + +// table_copy.wast:780 +assert_trap(() => call($21, "test", [18])); + +// table_copy.wast:781 +assert_trap(() => call($21, "test", [19])); + +// table_copy.wast:782 +assert_trap(() => call($21, "test", [20])); + +// table_copy.wast:783 +assert_trap(() => call($21, "test", [21])); + +// table_copy.wast:784 +assert_trap(() => call($21, "test", [22])); + +// table_copy.wast:785 +assert_trap(() => call($21, "test", [23])); + +// table_copy.wast:786 +assert_trap(() => call($21, "test", [24])); + +// table_copy.wast:787 +assert_trap(() => call($21, "test", [25])); + +// table_copy.wast:788 +assert_trap(() => call($21, "test", [26])); + +// table_copy.wast:789 +assert_trap(() => call($21, "test", [27])); + +// table_copy.wast:790 +assert_trap(() => call($21, "test", [28])); + +// table_copy.wast:791 +assert_trap(() => call($21, "test", [29])); + +// table_copy.wast:792 +assert_trap(() => call($21, "test", [30])); + +// table_copy.wast:793 +assert_trap(() => call($21, "test", [31])); + +// table_copy.wast:795 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8f\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x09\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:821 +assert_trap(() => call($22, "run", [23, 0, 15])); + +// table_copy.wast:823 +assert_return(() => call($22, "test", [0]), 0); + +// table_copy.wast:824 +assert_return(() => call($22, "test", [1]), 1); + +// table_copy.wast:825 +assert_return(() => call($22, "test", [2]), 2); + +// table_copy.wast:826 +assert_return(() => call($22, "test", [3]), 3); + +// table_copy.wast:827 +assert_return(() => call($22, "test", [4]), 4); + +// table_copy.wast:828 +assert_return(() => call($22, "test", [5]), 5); + +// table_copy.wast:829 +assert_return(() => call($22, "test", [6]), 6); + +// table_copy.wast:830 +assert_return(() => call($22, "test", [7]), 7); + +// table_copy.wast:831 +assert_return(() => call($22, "test", [8]), 8); + +// table_copy.wast:832 +assert_trap(() => call($22, "test", [9])); + +// table_copy.wast:833 +assert_trap(() => call($22, "test", [10])); + +// table_copy.wast:834 +assert_trap(() => call($22, "test", [11])); + +// table_copy.wast:835 +assert_trap(() => call($22, "test", [12])); + +// table_copy.wast:836 +assert_trap(() => call($22, "test", [13])); + +// table_copy.wast:837 +assert_trap(() => call($22, "test", [14])); + +// table_copy.wast:838 +assert_trap(() => call($22, "test", [15])); + +// table_copy.wast:839 +assert_trap(() => call($22, "test", [16])); + +// table_copy.wast:840 +assert_trap(() => call($22, "test", [17])); + +// table_copy.wast:841 +assert_trap(() => call($22, "test", [18])); + +// table_copy.wast:842 +assert_trap(() => call($22, "test", [19])); + +// table_copy.wast:843 +assert_trap(() => call($22, "test", [20])); + +// table_copy.wast:844 +assert_trap(() => call($22, "test", [21])); + +// table_copy.wast:845 +assert_trap(() => call($22, "test", [22])); + +// table_copy.wast:846 +assert_trap(() => call($22, "test", [23])); + +// table_copy.wast:847 +assert_trap(() => call($22, "test", [24])); + +// table_copy.wast:848 +assert_trap(() => call($22, "test", [25])); + +// table_copy.wast:849 +assert_trap(() => call($22, "test", [26])); + +// table_copy.wast:850 +assert_trap(() => call($22, "test", [27])); + +// table_copy.wast:851 +assert_trap(() => call($22, "test", [28])); + +// table_copy.wast:852 +assert_trap(() => call($22, "test", [29])); + +// table_copy.wast:853 +assert_trap(() => call($22, "test", [30])); + +// table_copy.wast:854 +assert_trap(() => call($22, "test", [31])); + +// table_copy.wast:856 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:882 +assert_trap(() => call($23, "run", [0, 24, 16])); + +// table_copy.wast:884 +assert_trap(() => call($23, "test", [0])); + +// table_copy.wast:885 +assert_trap(() => call($23, "test", [1])); + +// table_copy.wast:886 +assert_trap(() => call($23, "test", [2])); + +// table_copy.wast:887 +assert_trap(() => call($23, "test", [3])); + +// table_copy.wast:888 +assert_trap(() => call($23, "test", [4])); + +// table_copy.wast:889 +assert_trap(() => call($23, "test", [5])); + +// table_copy.wast:890 +assert_trap(() => call($23, "test", [6])); + +// table_copy.wast:891 +assert_trap(() => call($23, "test", [7])); + +// table_copy.wast:892 +assert_trap(() => call($23, "test", [8])); + +// table_copy.wast:893 +assert_trap(() => call($23, "test", [9])); + +// table_copy.wast:894 +assert_trap(() => call($23, "test", [10])); + +// table_copy.wast:895 +assert_trap(() => call($23, "test", [11])); + +// table_copy.wast:896 +assert_trap(() => call($23, "test", [12])); + +// table_copy.wast:897 +assert_trap(() => call($23, "test", [13])); + +// table_copy.wast:898 +assert_trap(() => call($23, "test", [14])); + +// table_copy.wast:899 +assert_trap(() => call($23, "test", [15])); + +// table_copy.wast:900 +assert_trap(() => call($23, "test", [16])); + +// table_copy.wast:901 +assert_trap(() => call($23, "test", [17])); + +// table_copy.wast:902 +assert_trap(() => call($23, "test", [18])); + +// table_copy.wast:903 +assert_trap(() => call($23, "test", [19])); + +// table_copy.wast:904 +assert_trap(() => call($23, "test", [20])); + +// table_copy.wast:905 +assert_trap(() => call($23, "test", [21])); + +// table_copy.wast:906 +assert_trap(() => call($23, "test", [22])); + +// table_copy.wast:907 +assert_trap(() => call($23, "test", [23])); + +// table_copy.wast:908 +assert_return(() => call($23, "test", [24]), 0); + +// table_copy.wast:909 +assert_return(() => call($23, "test", [25]), 1); + +// table_copy.wast:910 +assert_return(() => call($23, "test", [26]), 2); + +// table_copy.wast:911 +assert_return(() => call($23, "test", [27]), 3); + +// table_copy.wast:912 +assert_return(() => call($23, "test", [28]), 4); + +// table_copy.wast:913 +assert_return(() => call($23, "test", [29]), 5); + +// table_copy.wast:914 +assert_return(() => call($23, "test", [30]), 6); + +// table_copy.wast:915 +assert_return(() => call($23, "test", [31]), 7); + +// table_copy.wast:917 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8f\x80\x80\x80\x00\x01\x00\x41\x17\x0b\x09\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:943 +assert_trap(() => call($24, "run", [0, 23, 15])); + +// table_copy.wast:945 +assert_trap(() => call($24, "test", [0])); + +// table_copy.wast:946 +assert_trap(() => call($24, "test", [1])); + +// table_copy.wast:947 +assert_trap(() => call($24, "test", [2])); + +// table_copy.wast:948 +assert_trap(() => call($24, "test", [3])); + +// table_copy.wast:949 +assert_trap(() => call($24, "test", [4])); + +// table_copy.wast:950 +assert_trap(() => call($24, "test", [5])); + +// table_copy.wast:951 +assert_trap(() => call($24, "test", [6])); + +// table_copy.wast:952 +assert_trap(() => call($24, "test", [7])); + +// table_copy.wast:953 +assert_trap(() => call($24, "test", [8])); + +// table_copy.wast:954 +assert_trap(() => call($24, "test", [9])); + +// table_copy.wast:955 +assert_trap(() => call($24, "test", [10])); + +// table_copy.wast:956 +assert_trap(() => call($24, "test", [11])); + +// table_copy.wast:957 +assert_trap(() => call($24, "test", [12])); + +// table_copy.wast:958 +assert_trap(() => call($24, "test", [13])); + +// table_copy.wast:959 +assert_trap(() => call($24, "test", [14])); + +// table_copy.wast:960 +assert_trap(() => call($24, "test", [15])); + +// table_copy.wast:961 +assert_trap(() => call($24, "test", [16])); + +// table_copy.wast:962 +assert_trap(() => call($24, "test", [17])); + +// table_copy.wast:963 +assert_trap(() => call($24, "test", [18])); + +// table_copy.wast:964 +assert_trap(() => call($24, "test", [19])); + +// table_copy.wast:965 +assert_trap(() => call($24, "test", [20])); + +// table_copy.wast:966 +assert_trap(() => call($24, "test", [21])); + +// table_copy.wast:967 +assert_trap(() => call($24, "test", [22])); + +// table_copy.wast:968 +assert_return(() => call($24, "test", [23]), 0); + +// table_copy.wast:969 +assert_return(() => call($24, "test", [24]), 1); + +// table_copy.wast:970 +assert_return(() => call($24, "test", [25]), 2); + +// table_copy.wast:971 +assert_return(() => call($24, "test", [26]), 3); + +// table_copy.wast:972 +assert_return(() => call($24, "test", [27]), 4); + +// table_copy.wast:973 +assert_return(() => call($24, "test", [28]), 5); + +// table_copy.wast:974 +assert_return(() => call($24, "test", [29]), 6); + +// table_copy.wast:975 +assert_return(() => call($24, "test", [30]), 7); + +// table_copy.wast:976 +assert_return(() => call($24, "test", [31]), 8); + +// table_copy.wast:978 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x0b\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1004 +assert_trap(() => call($25, "run", [24, 11, 16])); + +// table_copy.wast:1006 +assert_trap(() => call($25, "test", [0])); + +// table_copy.wast:1007 +assert_trap(() => call($25, "test", [1])); + +// table_copy.wast:1008 +assert_trap(() => call($25, "test", [2])); + +// table_copy.wast:1009 +assert_trap(() => call($25, "test", [3])); + +// table_copy.wast:1010 +assert_trap(() => call($25, "test", [4])); + +// table_copy.wast:1011 +assert_trap(() => call($25, "test", [5])); + +// table_copy.wast:1012 +assert_trap(() => call($25, "test", [6])); + +// table_copy.wast:1013 +assert_trap(() => call($25, "test", [7])); + +// table_copy.wast:1014 +assert_trap(() => call($25, "test", [8])); + +// table_copy.wast:1015 +assert_trap(() => call($25, "test", [9])); + +// table_copy.wast:1016 +assert_trap(() => call($25, "test", [10])); + +// table_copy.wast:1017 +assert_return(() => call($25, "test", [11]), 0); + +// table_copy.wast:1018 +assert_return(() => call($25, "test", [12]), 1); + +// table_copy.wast:1019 +assert_return(() => call($25, "test", [13]), 2); + +// table_copy.wast:1020 +assert_return(() => call($25, "test", [14]), 3); + +// table_copy.wast:1021 +assert_return(() => call($25, "test", [15]), 4); + +// table_copy.wast:1022 +assert_return(() => call($25, "test", [16]), 5); + +// table_copy.wast:1023 +assert_return(() => call($25, "test", [17]), 6); + +// table_copy.wast:1024 +assert_return(() => call($25, "test", [18]), 7); + +// table_copy.wast:1025 +assert_trap(() => call($25, "test", [19])); + +// table_copy.wast:1026 +assert_trap(() => call($25, "test", [20])); + +// table_copy.wast:1027 +assert_trap(() => call($25, "test", [21])); + +// table_copy.wast:1028 +assert_trap(() => call($25, "test", [22])); + +// table_copy.wast:1029 +assert_trap(() => call($25, "test", [23])); + +// table_copy.wast:1030 +assert_trap(() => call($25, "test", [24])); + +// table_copy.wast:1031 +assert_trap(() => call($25, "test", [25])); + +// table_copy.wast:1032 +assert_trap(() => call($25, "test", [26])); + +// table_copy.wast:1033 +assert_trap(() => call($25, "test", [27])); + +// table_copy.wast:1034 +assert_trap(() => call($25, "test", [28])); + +// table_copy.wast:1035 +assert_trap(() => call($25, "test", [29])); + +// table_copy.wast:1036 +assert_trap(() => call($25, "test", [30])); + +// table_copy.wast:1037 +assert_trap(() => call($25, "test", [31])); + +// table_copy.wast:1039 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1065 +assert_trap(() => call($26, "run", [11, 24, 16])); + +// table_copy.wast:1067 +assert_trap(() => call($26, "test", [0])); + +// table_copy.wast:1068 +assert_trap(() => call($26, "test", [1])); + +// table_copy.wast:1069 +assert_trap(() => call($26, "test", [2])); + +// table_copy.wast:1070 +assert_trap(() => call($26, "test", [3])); + +// table_copy.wast:1071 +assert_trap(() => call($26, "test", [4])); + +// table_copy.wast:1072 +assert_trap(() => call($26, "test", [5])); + +// table_copy.wast:1073 +assert_trap(() => call($26, "test", [6])); + +// table_copy.wast:1074 +assert_trap(() => call($26, "test", [7])); + +// table_copy.wast:1075 +assert_trap(() => call($26, "test", [8])); + +// table_copy.wast:1076 +assert_trap(() => call($26, "test", [9])); + +// table_copy.wast:1077 +assert_trap(() => call($26, "test", [10])); + +// table_copy.wast:1078 +assert_trap(() => call($26, "test", [11])); + +// table_copy.wast:1079 +assert_trap(() => call($26, "test", [12])); + +// table_copy.wast:1080 +assert_trap(() => call($26, "test", [13])); + +// table_copy.wast:1081 +assert_trap(() => call($26, "test", [14])); + +// table_copy.wast:1082 +assert_trap(() => call($26, "test", [15])); + +// table_copy.wast:1083 +assert_trap(() => call($26, "test", [16])); + +// table_copy.wast:1084 +assert_trap(() => call($26, "test", [17])); + +// table_copy.wast:1085 +assert_trap(() => call($26, "test", [18])); + +// table_copy.wast:1086 +assert_trap(() => call($26, "test", [19])); + +// table_copy.wast:1087 +assert_trap(() => call($26, "test", [20])); + +// table_copy.wast:1088 +assert_trap(() => call($26, "test", [21])); + +// table_copy.wast:1089 +assert_trap(() => call($26, "test", [22])); + +// table_copy.wast:1090 +assert_trap(() => call($26, "test", [23])); + +// table_copy.wast:1091 +assert_return(() => call($26, "test", [24]), 0); + +// table_copy.wast:1092 +assert_return(() => call($26, "test", [25]), 1); + +// table_copy.wast:1093 +assert_return(() => call($26, "test", [26]), 2); + +// table_copy.wast:1094 +assert_return(() => call($26, "test", [27]), 3); + +// table_copy.wast:1095 +assert_return(() => call($26, "test", [28]), 4); + +// table_copy.wast:1096 +assert_return(() => call($26, "test", [29]), 5); + +// table_copy.wast:1097 +assert_return(() => call($26, "test", [30]), 6); + +// table_copy.wast:1098 +assert_return(() => call($26, "test", [31]), 7); + +// table_copy.wast:1100 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x15\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1126 +assert_trap(() => call($27, "run", [24, 21, 16])); + +// table_copy.wast:1128 +assert_trap(() => call($27, "test", [0])); + +// table_copy.wast:1129 +assert_trap(() => call($27, "test", [1])); + +// table_copy.wast:1130 +assert_trap(() => call($27, "test", [2])); + +// table_copy.wast:1131 +assert_trap(() => call($27, "test", [3])); + +// table_copy.wast:1132 +assert_trap(() => call($27, "test", [4])); + +// table_copy.wast:1133 +assert_trap(() => call($27, "test", [5])); + +// table_copy.wast:1134 +assert_trap(() => call($27, "test", [6])); + +// table_copy.wast:1135 +assert_trap(() => call($27, "test", [7])); + +// table_copy.wast:1136 +assert_trap(() => call($27, "test", [8])); + +// table_copy.wast:1137 +assert_trap(() => call($27, "test", [9])); + +// table_copy.wast:1138 +assert_trap(() => call($27, "test", [10])); + +// table_copy.wast:1139 +assert_trap(() => call($27, "test", [11])); + +// table_copy.wast:1140 +assert_trap(() => call($27, "test", [12])); + +// table_copy.wast:1141 +assert_trap(() => call($27, "test", [13])); + +// table_copy.wast:1142 +assert_trap(() => call($27, "test", [14])); + +// table_copy.wast:1143 +assert_trap(() => call($27, "test", [15])); + +// table_copy.wast:1144 +assert_trap(() => call($27, "test", [16])); + +// table_copy.wast:1145 +assert_trap(() => call($27, "test", [17])); + +// table_copy.wast:1146 +assert_trap(() => call($27, "test", [18])); + +// table_copy.wast:1147 +assert_trap(() => call($27, "test", [19])); + +// table_copy.wast:1148 +assert_trap(() => call($27, "test", [20])); + +// table_copy.wast:1149 +assert_return(() => call($27, "test", [21]), 0); + +// table_copy.wast:1150 +assert_return(() => call($27, "test", [22]), 1); + +// table_copy.wast:1151 +assert_return(() => call($27, "test", [23]), 2); + +// table_copy.wast:1152 +assert_return(() => call($27, "test", [24]), 3); + +// table_copy.wast:1153 +assert_return(() => call($27, "test", [25]), 4); + +// table_copy.wast:1154 +assert_return(() => call($27, "test", [26]), 5); + +// table_copy.wast:1155 +assert_return(() => call($27, "test", [27]), 6); + +// table_copy.wast:1156 +assert_return(() => call($27, "test", [28]), 7); + +// table_copy.wast:1157 +assert_trap(() => call($27, "test", [29])); + +// table_copy.wast:1158 +assert_trap(() => call($27, "test", [30])); + +// table_copy.wast:1159 +assert_trap(() => call($27, "test", [31])); + +// table_copy.wast:1161 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1187 +assert_trap(() => call($28, "run", [21, 24, 16])); + +// table_copy.wast:1189 +assert_trap(() => call($28, "test", [0])); + +// table_copy.wast:1190 +assert_trap(() => call($28, "test", [1])); + +// table_copy.wast:1191 +assert_trap(() => call($28, "test", [2])); + +// table_copy.wast:1192 +assert_trap(() => call($28, "test", [3])); + +// table_copy.wast:1193 +assert_trap(() => call($28, "test", [4])); + +// table_copy.wast:1194 +assert_trap(() => call($28, "test", [5])); + +// table_copy.wast:1195 +assert_trap(() => call($28, "test", [6])); + +// table_copy.wast:1196 +assert_trap(() => call($28, "test", [7])); + +// table_copy.wast:1197 +assert_trap(() => call($28, "test", [8])); + +// table_copy.wast:1198 +assert_trap(() => call($28, "test", [9])); + +// table_copy.wast:1199 +assert_trap(() => call($28, "test", [10])); + +// table_copy.wast:1200 +assert_trap(() => call($28, "test", [11])); + +// table_copy.wast:1201 +assert_trap(() => call($28, "test", [12])); + +// table_copy.wast:1202 +assert_trap(() => call($28, "test", [13])); + +// table_copy.wast:1203 +assert_trap(() => call($28, "test", [14])); + +// table_copy.wast:1204 +assert_trap(() => call($28, "test", [15])); + +// table_copy.wast:1205 +assert_trap(() => call($28, "test", [16])); + +// table_copy.wast:1206 +assert_trap(() => call($28, "test", [17])); + +// table_copy.wast:1207 +assert_trap(() => call($28, "test", [18])); + +// table_copy.wast:1208 +assert_trap(() => call($28, "test", [19])); + +// table_copy.wast:1209 +assert_trap(() => call($28, "test", [20])); + +// table_copy.wast:1210 +assert_trap(() => call($28, "test", [21])); + +// table_copy.wast:1211 +assert_trap(() => call($28, "test", [22])); + +// table_copy.wast:1212 +assert_trap(() => call($28, "test", [23])); + +// table_copy.wast:1213 +assert_return(() => call($28, "test", [24]), 0); + +// table_copy.wast:1214 +assert_return(() => call($28, "test", [25]), 1); + +// table_copy.wast:1215 +assert_return(() => call($28, "test", [26]), 2); + +// table_copy.wast:1216 +assert_return(() => call($28, "test", [27]), 3); + +// table_copy.wast:1217 +assert_return(() => call($28, "test", [28]), 4); + +// table_copy.wast:1218 +assert_return(() => call($28, "test", [29]), 5); + +// table_copy.wast:1219 +assert_return(() => call($28, "test", [30]), 6); + +// table_copy.wast:1220 +assert_return(() => call($28, "test", [31]), 7); + +// table_copy.wast:1222 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x91\x80\x80\x80\x00\x01\x00\x41\x15\x0b\x0b\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1248 +assert_trap(() => call($29, "run", [21, 21, 16])); + +// table_copy.wast:1250 +assert_trap(() => call($29, "test", [0])); + +// table_copy.wast:1251 +assert_trap(() => call($29, "test", [1])); + +// table_copy.wast:1252 +assert_trap(() => call($29, "test", [2])); + +// table_copy.wast:1253 +assert_trap(() => call($29, "test", [3])); + +// table_copy.wast:1254 +assert_trap(() => call($29, "test", [4])); + +// table_copy.wast:1255 +assert_trap(() => call($29, "test", [5])); + +// table_copy.wast:1256 +assert_trap(() => call($29, "test", [6])); + +// table_copy.wast:1257 +assert_trap(() => call($29, "test", [7])); + +// table_copy.wast:1258 +assert_trap(() => call($29, "test", [8])); + +// table_copy.wast:1259 +assert_trap(() => call($29, "test", [9])); + +// table_copy.wast:1260 +assert_trap(() => call($29, "test", [10])); + +// table_copy.wast:1261 +assert_trap(() => call($29, "test", [11])); + +// table_copy.wast:1262 +assert_trap(() => call($29, "test", [12])); + +// table_copy.wast:1263 +assert_trap(() => call($29, "test", [13])); + +// table_copy.wast:1264 +assert_trap(() => call($29, "test", [14])); + +// table_copy.wast:1265 +assert_trap(() => call($29, "test", [15])); + +// table_copy.wast:1266 +assert_trap(() => call($29, "test", [16])); + +// table_copy.wast:1267 +assert_trap(() => call($29, "test", [17])); + +// table_copy.wast:1268 +assert_trap(() => call($29, "test", [18])); + +// table_copy.wast:1269 +assert_trap(() => call($29, "test", [19])); + +// table_copy.wast:1270 +assert_trap(() => call($29, "test", [20])); + +// table_copy.wast:1271 +assert_return(() => call($29, "test", [21]), 0); + +// table_copy.wast:1272 +assert_return(() => call($29, "test", [22]), 1); + +// table_copy.wast:1273 +assert_return(() => call($29, "test", [23]), 2); + +// table_copy.wast:1274 +assert_return(() => call($29, "test", [24]), 3); + +// table_copy.wast:1275 +assert_return(() => call($29, "test", [25]), 4); + +// table_copy.wast:1276 +assert_return(() => call($29, "test", [26]), 5); + +// table_copy.wast:1277 +assert_return(() => call($29, "test", [27]), 6); + +// table_copy.wast:1278 +assert_return(() => call($29, "test", [28]), 7); + +// table_copy.wast:1279 +assert_return(() => call($29, "test", [29]), 8); + +// table_copy.wast:1280 +assert_return(() => call($29, "test", [30]), 9); + +// table_copy.wast:1281 +assert_return(() => call($29, "test", [31]), 10); + +// table_copy.wast:1283 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\x80\x01\x80\x01\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x97\x80\x80\x80\x00\x01\x00\x41\xf0\x00\x0b\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1309 +assert_trap(() => call($30, "run", [0, 112, -32])); + +// table_copy.wast:1311 +assert_trap(() => call($30, "test", [0])); + +// table_copy.wast:1312 +assert_trap(() => call($30, "test", [1])); + +// table_copy.wast:1313 +assert_trap(() => call($30, "test", [2])); + +// table_copy.wast:1314 +assert_trap(() => call($30, "test", [3])); + +// table_copy.wast:1315 +assert_trap(() => call($30, "test", [4])); + +// table_copy.wast:1316 +assert_trap(() => call($30, "test", [5])); + +// table_copy.wast:1317 +assert_trap(() => call($30, "test", [6])); + +// table_copy.wast:1318 +assert_trap(() => call($30, "test", [7])); + +// table_copy.wast:1319 +assert_trap(() => call($30, "test", [8])); + +// table_copy.wast:1320 +assert_trap(() => call($30, "test", [9])); + +// table_copy.wast:1321 +assert_trap(() => call($30, "test", [10])); + +// table_copy.wast:1322 +assert_trap(() => call($30, "test", [11])); + +// table_copy.wast:1323 +assert_trap(() => call($30, "test", [12])); + +// table_copy.wast:1324 +assert_trap(() => call($30, "test", [13])); + +// table_copy.wast:1325 +assert_trap(() => call($30, "test", [14])); + +// table_copy.wast:1326 +assert_trap(() => call($30, "test", [15])); + +// table_copy.wast:1327 +assert_trap(() => call($30, "test", [16])); + +// table_copy.wast:1328 +assert_trap(() => call($30, "test", [17])); + +// table_copy.wast:1329 +assert_trap(() => call($30, "test", [18])); + +// table_copy.wast:1330 +assert_trap(() => call($30, "test", [19])); + +// table_copy.wast:1331 +assert_trap(() => call($30, "test", [20])); + +// table_copy.wast:1332 +assert_trap(() => call($30, "test", [21])); + +// table_copy.wast:1333 +assert_trap(() => call($30, "test", [22])); + +// table_copy.wast:1334 +assert_trap(() => call($30, "test", [23])); + +// table_copy.wast:1335 +assert_trap(() => call($30, "test", [24])); + +// table_copy.wast:1336 +assert_trap(() => call($30, "test", [25])); + +// table_copy.wast:1337 +assert_trap(() => call($30, "test", [26])); + +// table_copy.wast:1338 +assert_trap(() => call($30, "test", [27])); + +// table_copy.wast:1339 +assert_trap(() => call($30, "test", [28])); + +// table_copy.wast:1340 +assert_trap(() => call($30, "test", [29])); + +// table_copy.wast:1341 +assert_trap(() => call($30, "test", [30])); + +// table_copy.wast:1342 +assert_trap(() => call($30, "test", [31])); + +// table_copy.wast:1343 +assert_trap(() => call($30, "test", [32])); + +// table_copy.wast:1344 +assert_trap(() => call($30, "test", [33])); + +// table_copy.wast:1345 +assert_trap(() => call($30, "test", [34])); + +// table_copy.wast:1346 +assert_trap(() => call($30, "test", [35])); + +// table_copy.wast:1347 +assert_trap(() => call($30, "test", [36])); + +// table_copy.wast:1348 +assert_trap(() => call($30, "test", [37])); + +// table_copy.wast:1349 +assert_trap(() => call($30, "test", [38])); + +// table_copy.wast:1350 +assert_trap(() => call($30, "test", [39])); + +// table_copy.wast:1351 +assert_trap(() => call($30, "test", [40])); + +// table_copy.wast:1352 +assert_trap(() => call($30, "test", [41])); + +// table_copy.wast:1353 +assert_trap(() => call($30, "test", [42])); + +// table_copy.wast:1354 +assert_trap(() => call($30, "test", [43])); + +// table_copy.wast:1355 +assert_trap(() => call($30, "test", [44])); + +// table_copy.wast:1356 +assert_trap(() => call($30, "test", [45])); + +// table_copy.wast:1357 +assert_trap(() => call($30, "test", [46])); + +// table_copy.wast:1358 +assert_trap(() => call($30, "test", [47])); + +// table_copy.wast:1359 +assert_trap(() => call($30, "test", [48])); + +// table_copy.wast:1360 +assert_trap(() => call($30, "test", [49])); + +// table_copy.wast:1361 +assert_trap(() => call($30, "test", [50])); + +// table_copy.wast:1362 +assert_trap(() => call($30, "test", [51])); + +// table_copy.wast:1363 +assert_trap(() => call($30, "test", [52])); + +// table_copy.wast:1364 +assert_trap(() => call($30, "test", [53])); + +// table_copy.wast:1365 +assert_trap(() => call($30, "test", [54])); + +// table_copy.wast:1366 +assert_trap(() => call($30, "test", [55])); + +// table_copy.wast:1367 +assert_trap(() => call($30, "test", [56])); + +// table_copy.wast:1368 +assert_trap(() => call($30, "test", [57])); + +// table_copy.wast:1369 +assert_trap(() => call($30, "test", [58])); + +// table_copy.wast:1370 +assert_trap(() => call($30, "test", [59])); + +// table_copy.wast:1371 +assert_trap(() => call($30, "test", [60])); + +// table_copy.wast:1372 +assert_trap(() => call($30, "test", [61])); + +// table_copy.wast:1373 +assert_trap(() => call($30, "test", [62])); + +// table_copy.wast:1374 +assert_trap(() => call($30, "test", [63])); + +// table_copy.wast:1375 +assert_trap(() => call($30, "test", [64])); + +// table_copy.wast:1376 +assert_trap(() => call($30, "test", [65])); + +// table_copy.wast:1377 +assert_trap(() => call($30, "test", [66])); + +// table_copy.wast:1378 +assert_trap(() => call($30, "test", [67])); + +// table_copy.wast:1379 +assert_trap(() => call($30, "test", [68])); + +// table_copy.wast:1380 +assert_trap(() => call($30, "test", [69])); + +// table_copy.wast:1381 +assert_trap(() => call($30, "test", [70])); + +// table_copy.wast:1382 +assert_trap(() => call($30, "test", [71])); + +// table_copy.wast:1383 +assert_trap(() => call($30, "test", [72])); + +// table_copy.wast:1384 +assert_trap(() => call($30, "test", [73])); + +// table_copy.wast:1385 +assert_trap(() => call($30, "test", [74])); + +// table_copy.wast:1386 +assert_trap(() => call($30, "test", [75])); + +// table_copy.wast:1387 +assert_trap(() => call($30, "test", [76])); + +// table_copy.wast:1388 +assert_trap(() => call($30, "test", [77])); + +// table_copy.wast:1389 +assert_trap(() => call($30, "test", [78])); + +// table_copy.wast:1390 +assert_trap(() => call($30, "test", [79])); + +// table_copy.wast:1391 +assert_trap(() => call($30, "test", [80])); + +// table_copy.wast:1392 +assert_trap(() => call($30, "test", [81])); + +// table_copy.wast:1393 +assert_trap(() => call($30, "test", [82])); + +// table_copy.wast:1394 +assert_trap(() => call($30, "test", [83])); + +// table_copy.wast:1395 +assert_trap(() => call($30, "test", [84])); + +// table_copy.wast:1396 +assert_trap(() => call($30, "test", [85])); + +// table_copy.wast:1397 +assert_trap(() => call($30, "test", [86])); + +// table_copy.wast:1398 +assert_trap(() => call($30, "test", [87])); + +// table_copy.wast:1399 +assert_trap(() => call($30, "test", [88])); + +// table_copy.wast:1400 +assert_trap(() => call($30, "test", [89])); + +// table_copy.wast:1401 +assert_trap(() => call($30, "test", [90])); + +// table_copy.wast:1402 +assert_trap(() => call($30, "test", [91])); + +// table_copy.wast:1403 +assert_trap(() => call($30, "test", [92])); + +// table_copy.wast:1404 +assert_trap(() => call($30, "test", [93])); + +// table_copy.wast:1405 +assert_trap(() => call($30, "test", [94])); + +// table_copy.wast:1406 +assert_trap(() => call($30, "test", [95])); + +// table_copy.wast:1407 +assert_trap(() => call($30, "test", [96])); + +// table_copy.wast:1408 +assert_trap(() => call($30, "test", [97])); + +// table_copy.wast:1409 +assert_trap(() => call($30, "test", [98])); + +// table_copy.wast:1410 +assert_trap(() => call($30, "test", [99])); + +// table_copy.wast:1411 +assert_trap(() => call($30, "test", [100])); + +// table_copy.wast:1412 +assert_trap(() => call($30, "test", [101])); + +// table_copy.wast:1413 +assert_trap(() => call($30, "test", [102])); + +// table_copy.wast:1414 +assert_trap(() => call($30, "test", [103])); + +// table_copy.wast:1415 +assert_trap(() => call($30, "test", [104])); + +// table_copy.wast:1416 +assert_trap(() => call($30, "test", [105])); + +// table_copy.wast:1417 +assert_trap(() => call($30, "test", [106])); + +// table_copy.wast:1418 +assert_trap(() => call($30, "test", [107])); + +// table_copy.wast:1419 +assert_trap(() => call($30, "test", [108])); + +// table_copy.wast:1420 +assert_trap(() => call($30, "test", [109])); + +// table_copy.wast:1421 +assert_trap(() => call($30, "test", [110])); + +// table_copy.wast:1422 +assert_trap(() => call($30, "test", [111])); + +// table_copy.wast:1423 +assert_return(() => call($30, "test", [112]), 0); + +// table_copy.wast:1424 +assert_return(() => call($30, "test", [113]), 1); + +// table_copy.wast:1425 +assert_return(() => call($30, "test", [114]), 2); + +// table_copy.wast:1426 +assert_return(() => call($30, "test", [115]), 3); + +// table_copy.wast:1427 +assert_return(() => call($30, "test", [116]), 4); + +// table_copy.wast:1428 +assert_return(() => call($30, "test", [117]), 5); + +// table_copy.wast:1429 +assert_return(() => call($30, "test", [118]), 6); + +// table_copy.wast:1430 +assert_return(() => call($30, "test", [119]), 7); + +// table_copy.wast:1431 +assert_return(() => call($30, "test", [120]), 8); + +// table_copy.wast:1432 +assert_return(() => call($30, "test", [121]), 9); + +// table_copy.wast:1433 +assert_return(() => call($30, "test", [122]), 10); + +// table_copy.wast:1434 +assert_return(() => call($30, "test", [123]), 11); + +// table_copy.wast:1435 +assert_return(() => call($30, "test", [124]), 12); + +// table_copy.wast:1436 +assert_return(() => call($30, "test", [125]), 13); + +// table_copy.wast:1437 +assert_return(() => call($30, "test", [126]), 14); + +// table_copy.wast:1438 +assert_return(() => call($30, "test", [127]), 15); + +// table_copy.wast:1440 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\x80\x01\x80\x01\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x96\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1466 +assert_trap(() => call($31, "run", [112, 0, -32])); + +// table_copy.wast:1468 +assert_return(() => call($31, "test", [0]), 0); + +// table_copy.wast:1469 +assert_return(() => call($31, "test", [1]), 1); + +// table_copy.wast:1470 +assert_return(() => call($31, "test", [2]), 2); + +// table_copy.wast:1471 +assert_return(() => call($31, "test", [3]), 3); + +// table_copy.wast:1472 +assert_return(() => call($31, "test", [4]), 4); + +// table_copy.wast:1473 +assert_return(() => call($31, "test", [5]), 5); + +// table_copy.wast:1474 +assert_return(() => call($31, "test", [6]), 6); + +// table_copy.wast:1475 +assert_return(() => call($31, "test", [7]), 7); + +// table_copy.wast:1476 +assert_return(() => call($31, "test", [8]), 8); + +// table_copy.wast:1477 +assert_return(() => call($31, "test", [9]), 9); + +// table_copy.wast:1478 +assert_return(() => call($31, "test", [10]), 10); + +// table_copy.wast:1479 +assert_return(() => call($31, "test", [11]), 11); + +// table_copy.wast:1480 +assert_return(() => call($31, "test", [12]), 12); + +// table_copy.wast:1481 +assert_return(() => call($31, "test", [13]), 13); + +// table_copy.wast:1482 +assert_return(() => call($31, "test", [14]), 14); + +// table_copy.wast:1483 +assert_return(() => call($31, "test", [15]), 15); + +// table_copy.wast:1484 +assert_trap(() => call($31, "test", [16])); + +// table_copy.wast:1485 +assert_trap(() => call($31, "test", [17])); + +// table_copy.wast:1486 +assert_trap(() => call($31, "test", [18])); + +// table_copy.wast:1487 +assert_trap(() => call($31, "test", [19])); + +// table_copy.wast:1488 +assert_trap(() => call($31, "test", [20])); + +// table_copy.wast:1489 +assert_trap(() => call($31, "test", [21])); + +// table_copy.wast:1490 +assert_trap(() => call($31, "test", [22])); + +// table_copy.wast:1491 +assert_trap(() => call($31, "test", [23])); + +// table_copy.wast:1492 +assert_trap(() => call($31, "test", [24])); + +// table_copy.wast:1493 +assert_trap(() => call($31, "test", [25])); + +// table_copy.wast:1494 +assert_trap(() => call($31, "test", [26])); + +// table_copy.wast:1495 +assert_trap(() => call($31, "test", [27])); + +// table_copy.wast:1496 +assert_trap(() => call($31, "test", [28])); + +// table_copy.wast:1497 +assert_trap(() => call($31, "test", [29])); + +// table_copy.wast:1498 +assert_trap(() => call($31, "test", [30])); + +// table_copy.wast:1499 +assert_trap(() => call($31, "test", [31])); + +// table_copy.wast:1500 +assert_trap(() => call($31, "test", [32])); + +// table_copy.wast:1501 +assert_trap(() => call($31, "test", [33])); + +// table_copy.wast:1502 +assert_trap(() => call($31, "test", [34])); + +// table_copy.wast:1503 +assert_trap(() => call($31, "test", [35])); + +// table_copy.wast:1504 +assert_trap(() => call($31, "test", [36])); + +// table_copy.wast:1505 +assert_trap(() => call($31, "test", [37])); + +// table_copy.wast:1506 +assert_trap(() => call($31, "test", [38])); + +// table_copy.wast:1507 +assert_trap(() => call($31, "test", [39])); + +// table_copy.wast:1508 +assert_trap(() => call($31, "test", [40])); + +// table_copy.wast:1509 +assert_trap(() => call($31, "test", [41])); + +// table_copy.wast:1510 +assert_trap(() => call($31, "test", [42])); + +// table_copy.wast:1511 +assert_trap(() => call($31, "test", [43])); + +// table_copy.wast:1512 +assert_trap(() => call($31, "test", [44])); + +// table_copy.wast:1513 +assert_trap(() => call($31, "test", [45])); + +// table_copy.wast:1514 +assert_trap(() => call($31, "test", [46])); + +// table_copy.wast:1515 +assert_trap(() => call($31, "test", [47])); + +// table_copy.wast:1516 +assert_trap(() => call($31, "test", [48])); + +// table_copy.wast:1517 +assert_trap(() => call($31, "test", [49])); + +// table_copy.wast:1518 +assert_trap(() => call($31, "test", [50])); + +// table_copy.wast:1519 +assert_trap(() => call($31, "test", [51])); + +// table_copy.wast:1520 +assert_trap(() => call($31, "test", [52])); + +// table_copy.wast:1521 +assert_trap(() => call($31, "test", [53])); + +// table_copy.wast:1522 +assert_trap(() => call($31, "test", [54])); + +// table_copy.wast:1523 +assert_trap(() => call($31, "test", [55])); + +// table_copy.wast:1524 +assert_trap(() => call($31, "test", [56])); + +// table_copy.wast:1525 +assert_trap(() => call($31, "test", [57])); + +// table_copy.wast:1526 +assert_trap(() => call($31, "test", [58])); + +// table_copy.wast:1527 +assert_trap(() => call($31, "test", [59])); + +// table_copy.wast:1528 +assert_trap(() => call($31, "test", [60])); + +// table_copy.wast:1529 +assert_trap(() => call($31, "test", [61])); + +// table_copy.wast:1530 +assert_trap(() => call($31, "test", [62])); + +// table_copy.wast:1531 +assert_trap(() => call($31, "test", [63])); + +// table_copy.wast:1532 +assert_trap(() => call($31, "test", [64])); + +// table_copy.wast:1533 +assert_trap(() => call($31, "test", [65])); + +// table_copy.wast:1534 +assert_trap(() => call($31, "test", [66])); + +// table_copy.wast:1535 +assert_trap(() => call($31, "test", [67])); + +// table_copy.wast:1536 +assert_trap(() => call($31, "test", [68])); + +// table_copy.wast:1537 +assert_trap(() => call($31, "test", [69])); + +// table_copy.wast:1538 +assert_trap(() => call($31, "test", [70])); + +// table_copy.wast:1539 +assert_trap(() => call($31, "test", [71])); + +// table_copy.wast:1540 +assert_trap(() => call($31, "test", [72])); + +// table_copy.wast:1541 +assert_trap(() => call($31, "test", [73])); + +// table_copy.wast:1542 +assert_trap(() => call($31, "test", [74])); + +// table_copy.wast:1543 +assert_trap(() => call($31, "test", [75])); + +// table_copy.wast:1544 +assert_trap(() => call($31, "test", [76])); + +// table_copy.wast:1545 +assert_trap(() => call($31, "test", [77])); + +// table_copy.wast:1546 +assert_trap(() => call($31, "test", [78])); + +// table_copy.wast:1547 +assert_trap(() => call($31, "test", [79])); + +// table_copy.wast:1548 +assert_trap(() => call($31, "test", [80])); + +// table_copy.wast:1549 +assert_trap(() => call($31, "test", [81])); + +// table_copy.wast:1550 +assert_trap(() => call($31, "test", [82])); + +// table_copy.wast:1551 +assert_trap(() => call($31, "test", [83])); + +// table_copy.wast:1552 +assert_trap(() => call($31, "test", [84])); + +// table_copy.wast:1553 +assert_trap(() => call($31, "test", [85])); + +// table_copy.wast:1554 +assert_trap(() => call($31, "test", [86])); + +// table_copy.wast:1555 +assert_trap(() => call($31, "test", [87])); + +// table_copy.wast:1556 +assert_trap(() => call($31, "test", [88])); + +// table_copy.wast:1557 +assert_trap(() => call($31, "test", [89])); + +// table_copy.wast:1558 +assert_trap(() => call($31, "test", [90])); + +// table_copy.wast:1559 +assert_trap(() => call($31, "test", [91])); + +// table_copy.wast:1560 +assert_trap(() => call($31, "test", [92])); + +// table_copy.wast:1561 +assert_trap(() => call($31, "test", [93])); + +// table_copy.wast:1562 +assert_trap(() => call($31, "test", [94])); + +// table_copy.wast:1563 +assert_trap(() => call($31, "test", [95])); + +// table_copy.wast:1564 +assert_trap(() => call($31, "test", [96])); + +// table_copy.wast:1565 +assert_trap(() => call($31, "test", [97])); + +// table_copy.wast:1566 +assert_trap(() => call($31, "test", [98])); + +// table_copy.wast:1567 +assert_trap(() => call($31, "test", [99])); + +// table_copy.wast:1568 +assert_trap(() => call($31, "test", [100])); + +// table_copy.wast:1569 +assert_trap(() => call($31, "test", [101])); + +// table_copy.wast:1570 +assert_trap(() => call($31, "test", [102])); + +// table_copy.wast:1571 +assert_trap(() => call($31, "test", [103])); + +// table_copy.wast:1572 +assert_trap(() => call($31, "test", [104])); + +// table_copy.wast:1573 +assert_trap(() => call($31, "test", [105])); + +// table_copy.wast:1574 +assert_trap(() => call($31, "test", [106])); + +// table_copy.wast:1575 +assert_trap(() => call($31, "test", [107])); + +// table_copy.wast:1576 +assert_trap(() => call($31, "test", [108])); + +// table_copy.wast:1577 +assert_trap(() => call($31, "test", [109])); + +// table_copy.wast:1578 +assert_trap(() => call($31, "test", [110])); + +// table_copy.wast:1579 +assert_trap(() => call($31, "test", [111])); + +// table_copy.wast:1580 +assert_trap(() => call($31, "test", [112])); + +// table_copy.wast:1581 +assert_trap(() => call($31, "test", [113])); + +// table_copy.wast:1582 +assert_trap(() => call($31, "test", [114])); + +// table_copy.wast:1583 +assert_trap(() => call($31, "test", [115])); + +// table_copy.wast:1584 +assert_trap(() => call($31, "test", [116])); + +// table_copy.wast:1585 +assert_trap(() => call($31, "test", [117])); + +// table_copy.wast:1586 +assert_trap(() => call($31, "test", [118])); + +// table_copy.wast:1587 +assert_trap(() => call($31, "test", [119])); + +// table_copy.wast:1588 +assert_trap(() => call($31, "test", [120])); + +// table_copy.wast:1589 +assert_trap(() => call($31, "test", [121])); + +// table_copy.wast:1590 +assert_trap(() => call($31, "test", [122])); + +// table_copy.wast:1591 +assert_trap(() => call($31, "test", [123])); + +// table_copy.wast:1592 +assert_trap(() => call($31, "test", [124])); + +// table_copy.wast:1593 +assert_trap(() => call($31, "test", [125])); + +// table_copy.wast:1594 +assert_trap(() => call($31, "test", [126])); + +// table_copy.wast:1595 +assert_trap(() => call($31, "test", [127])); diff --git a/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_init.wast.js b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_init.wast.js new file mode 100644 index 0000000000..04070373bf --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/bulk-memory-operations/table_init.wast.js @@ -0,0 +1,2010 @@ + +// table_init.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x00\x00\x07\x9f\x80\x80\x80\x00\x05\x03\x65\x66\x30\x00\x00\x03\x65\x66\x31\x00\x01\x03\x65\x66\x32\x00\x02\x03\x65\x66\x33\x00\x03\x03\x65\x66\x34\x00\x04\x0a\xae\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b"); + +// table_init.wast:12 +register("a", $1) + +// table_init.wast:14 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:39 +run(() => call($2, "test", [])); + +// table_init.wast:40 +assert_trap(() => call($2, "check", [0])); + +// table_init.wast:41 +assert_trap(() => call($2, "check", [1])); + +// table_init.wast:42 +assert_return(() => call($2, "check", [2]), 3); + +// table_init.wast:43 +assert_return(() => call($2, "check", [3]), 1); + +// table_init.wast:44 +assert_return(() => call($2, "check", [4]), 4); + +// table_init.wast:45 +assert_return(() => call($2, "check", [5]), 1); + +// table_init.wast:46 +assert_trap(() => call($2, "check", [6])); + +// table_init.wast:47 +assert_return(() => call($2, "check", [7]), 2); + +// table_init.wast:48 +assert_return(() => call($2, "check", [8]), 7); + +// table_init.wast:49 +assert_return(() => call($2, "check", [9]), 1); + +// table_init.wast:50 +assert_return(() => call($2, "check", [10]), 8); + +// table_init.wast:51 +assert_trap(() => call($2, "check", [11])); + +// table_init.wast:52 +assert_return(() => call($2, "check", [12]), 7); + +// table_init.wast:53 +assert_return(() => call($2, "check", [13]), 5); + +// table_init.wast:54 +assert_return(() => call($2, "check", [14]), 2); + +// table_init.wast:55 +assert_return(() => call($2, "check", [15]), 3); + +// table_init.wast:56 +assert_return(() => call($2, "check", [16]), 6); + +// table_init.wast:57 +assert_trap(() => call($2, "check", [17])); + +// table_init.wast:58 +assert_trap(() => call($2, "check", [18])); + +// table_init.wast:59 +assert_trap(() => call($2, "check", [19])); + +// table_init.wast:60 +assert_trap(() => call($2, "check", [20])); + +// table_init.wast:61 +assert_trap(() => call($2, "check", [21])); + +// table_init.wast:62 +assert_trap(() => call($2, "check", [22])); + +// table_init.wast:63 +assert_trap(() => call($2, "check", [23])); + +// table_init.wast:64 +assert_trap(() => call($2, "check", [24])); + +// table_init.wast:65 +assert_trap(() => call($2, "check", [25])); + +// table_init.wast:66 +assert_trap(() => call($2, "check", [26])); + +// table_init.wast:67 +assert_trap(() => call($2, "check", [27])); + +// table_init.wast:68 +assert_trap(() => call($2, "check", [28])); + +// table_init.wast:69 +assert_trap(() => call($2, "check", [29])); + +// table_init.wast:71 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:96 +run(() => call($3, "test", [])); + +// table_init.wast:97 +assert_trap(() => call($3, "check", [0])); + +// table_init.wast:98 +assert_trap(() => call($3, "check", [1])); + +// table_init.wast:99 +assert_return(() => call($3, "check", [2]), 3); + +// table_init.wast:100 +assert_return(() => call($3, "check", [3]), 1); + +// table_init.wast:101 +assert_return(() => call($3, "check", [4]), 4); + +// table_init.wast:102 +assert_return(() => call($3, "check", [5]), 1); + +// table_init.wast:103 +assert_trap(() => call($3, "check", [6])); + +// table_init.wast:104 +assert_trap(() => call($3, "check", [7])); + +// table_init.wast:105 +assert_trap(() => call($3, "check", [8])); + +// table_init.wast:106 +assert_trap(() => call($3, "check", [9])); + +// table_init.wast:107 +assert_trap(() => call($3, "check", [10])); + +// table_init.wast:108 +assert_trap(() => call($3, "check", [11])); + +// table_init.wast:109 +assert_return(() => call($3, "check", [12]), 7); + +// table_init.wast:110 +assert_return(() => call($3, "check", [13]), 5); + +// table_init.wast:111 +assert_return(() => call($3, "check", [14]), 2); + +// table_init.wast:112 +assert_return(() => call($3, "check", [15]), 9); + +// table_init.wast:113 +assert_return(() => call($3, "check", [16]), 2); + +// table_init.wast:114 +assert_return(() => call($3, "check", [17]), 7); + +// table_init.wast:115 +assert_trap(() => call($3, "check", [18])); + +// table_init.wast:116 +assert_trap(() => call($3, "check", [19])); + +// table_init.wast:117 +assert_trap(() => call($3, "check", [20])); + +// table_init.wast:118 +assert_trap(() => call($3, "check", [21])); + +// table_init.wast:119 +assert_trap(() => call($3, "check", [22])); + +// table_init.wast:120 +assert_trap(() => call($3, "check", [23])); + +// table_init.wast:121 +assert_trap(() => call($3, "check", [24])); + +// table_init.wast:122 +assert_trap(() => call($3, "check", [25])); + +// table_init.wast:123 +assert_trap(() => call($3, "check", [26])); + +// table_init.wast:124 +assert_trap(() => call($3, "check", [27])); + +// table_init.wast:125 +assert_trap(() => call($3, "check", [28])); + +// table_init.wast:126 +assert_trap(() => call($3, "check", [29])); + +// table_init.wast:128 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\x8d\x81\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\xce\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x00\xfc\x0d\x01\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x00\xfc\x0d\x03\x41\x14\x41\x0f\x41\x05\xfc\x0e\x00\x00\x41\x15\x41\x1d\x41\x01\xfc\x0e\x00\x00\x41\x18\x41\x0a\x41\x01\xfc\x0e\x00\x00\x41\x0d\x41\x0b\x41\x04\xfc\x0e\x00\x00\x41\x13\x41\x14\x41\x05\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:161 +run(() => call($4, "test", [])); + +// table_init.wast:162 +assert_trap(() => call($4, "check", [0])); + +// table_init.wast:163 +assert_trap(() => call($4, "check", [1])); + +// table_init.wast:164 +assert_return(() => call($4, "check", [2]), 3); + +// table_init.wast:165 +assert_return(() => call($4, "check", [3]), 1); + +// table_init.wast:166 +assert_return(() => call($4, "check", [4]), 4); + +// table_init.wast:167 +assert_return(() => call($4, "check", [5]), 1); + +// table_init.wast:168 +assert_trap(() => call($4, "check", [6])); + +// table_init.wast:169 +assert_return(() => call($4, "check", [7]), 2); + +// table_init.wast:170 +assert_return(() => call($4, "check", [8]), 7); + +// table_init.wast:171 +assert_return(() => call($4, "check", [9]), 1); + +// table_init.wast:172 +assert_return(() => call($4, "check", [10]), 8); + +// table_init.wast:173 +assert_trap(() => call($4, "check", [11])); + +// table_init.wast:174 +assert_return(() => call($4, "check", [12]), 7); + +// table_init.wast:175 +assert_trap(() => call($4, "check", [13])); + +// table_init.wast:176 +assert_return(() => call($4, "check", [14]), 7); + +// table_init.wast:177 +assert_return(() => call($4, "check", [15]), 5); + +// table_init.wast:178 +assert_return(() => call($4, "check", [16]), 2); + +// table_init.wast:179 +assert_return(() => call($4, "check", [17]), 7); + +// table_init.wast:180 +assert_trap(() => call($4, "check", [18])); + +// table_init.wast:181 +assert_return(() => call($4, "check", [19]), 9); + +// table_init.wast:182 +assert_trap(() => call($4, "check", [20])); + +// table_init.wast:183 +assert_return(() => call($4, "check", [21]), 7); + +// table_init.wast:184 +assert_trap(() => call($4, "check", [22])); + +// table_init.wast:185 +assert_return(() => call($4, "check", [23]), 8); + +// table_init.wast:186 +assert_return(() => call($4, "check", [24]), 8); + +// table_init.wast:187 +assert_trap(() => call($4, "check", [25])); + +// table_init.wast:188 +assert_trap(() => call($4, "check", [26])); + +// table_init.wast:189 +assert_trap(() => call($4, "check", [27])); + +// table_init.wast:190 +assert_trap(() => call($4, "check", [28])); + +// table_init.wast:191 +assert_trap(() => call($4, "check", [29])); + +// table_init.wast:192 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b"); + +// table_init.wast:198 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:204 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x04\x0b"); + +// table_init.wast:212 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x04\x00\x0b"); + +// table_init.wast:221 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xe5\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x02\x0b"); + +// table_init.wast:242 +run(() => call($5, "test", [])); + +// table_init.wast:244 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x02\x00\x0b"); + +// table_init.wast:265 +assert_trap(() => call($6, "test", [])); + +// table_init.wast:267 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xf6\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x96\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x01\x00\x41\x15\x41\x01\x41\x01\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:288 +run(() => call($7, "test", [])); + +// table_init.wast:290 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xe8\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x88\x80\x80\x80\x00\x00\xfc\x0d\x01\xfc\x0d\x01\x0b"); + +// table_init.wast:311 +run(() => call($8, "test", [])); + +// table_init.wast:313 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xef\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8f\x80\x80\x80\x00\x00\xfc\x0d\x01\x41\x0c\x41\x01\x41\x01\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:334 +assert_trap(() => call($9, "test", [])); + +// table_init.wast:336 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x00\x41\x05\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:357 +assert_trap(() => call($10, "test", [])); + +// table_init.wast:359 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x02\x41\x03\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:380 +assert_trap(() => call($11, "test", [])); + +// table_init.wast:382 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x01\x41\x03\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:403 +assert_trap(() => call($12, "test", [])); + +// table_init.wast:405 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x04\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:426 +run(() => call($13, "test", [])); + +// table_init.wast:428 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x05\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:449 +assert_trap(() => call($14, "test", [])); + +// table_init.wast:451 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x02\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:472 +run(() => call($15, "test", [])); + +// table_init.wast:474 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x02\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:495 +assert_trap(() => call($16, "test", [])); + +// table_init.wast:497 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x04\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:518 +run(() => call($17, "test", [])); + +// table_init.wast:520 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x05\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:541 +assert_trap(() => call($18, "test", [])); + +// table_init.wast:543 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:552 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:561 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:570 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:579 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:588 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:597 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:606 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:615 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:624 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:633 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:642 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:651 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:660 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:669 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:678 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:687 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:696 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:705 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:714 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:723 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa2\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x95\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:732 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:741 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:750 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:759 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:768 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:777 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:786 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:795 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:804 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:813 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:822 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:831 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:840 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:849 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:858 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:867 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:876 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:885 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:894 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:903 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:912 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:921 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:930 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:939 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:948 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:957 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:966 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:975 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:984 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:993 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1002 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1011 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1020 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1029 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1038 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1047 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1056 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1065 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1074 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1083 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1092 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1101 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xae\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1110 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1138 +assert_trap(() => call($19, "run", [24, 16])); + +// table_init.wast:1139 +assert_trap(() => call($19, "test", [0])); + +// table_init.wast:1140 +assert_trap(() => call($19, "test", [1])); + +// table_init.wast:1141 +assert_trap(() => call($19, "test", [2])); + +// table_init.wast:1142 +assert_trap(() => call($19, "test", [3])); + +// table_init.wast:1143 +assert_trap(() => call($19, "test", [4])); + +// table_init.wast:1144 +assert_trap(() => call($19, "test", [5])); + +// table_init.wast:1145 +assert_trap(() => call($19, "test", [6])); + +// table_init.wast:1146 +assert_trap(() => call($19, "test", [7])); + +// table_init.wast:1147 +assert_trap(() => call($19, "test", [8])); + +// table_init.wast:1148 +assert_trap(() => call($19, "test", [9])); + +// table_init.wast:1149 +assert_trap(() => call($19, "test", [10])); + +// table_init.wast:1150 +assert_trap(() => call($19, "test", [11])); + +// table_init.wast:1151 +assert_trap(() => call($19, "test", [12])); + +// table_init.wast:1152 +assert_trap(() => call($19, "test", [13])); + +// table_init.wast:1153 +assert_trap(() => call($19, "test", [14])); + +// table_init.wast:1154 +assert_trap(() => call($19, "test", [15])); + +// table_init.wast:1155 +assert_trap(() => call($19, "test", [16])); + +// table_init.wast:1156 +assert_trap(() => call($19, "test", [17])); + +// table_init.wast:1157 +assert_trap(() => call($19, "test", [18])); + +// table_init.wast:1158 +assert_trap(() => call($19, "test", [19])); + +// table_init.wast:1159 +assert_trap(() => call($19, "test", [20])); + +// table_init.wast:1160 +assert_trap(() => call($19, "test", [21])); + +// table_init.wast:1161 +assert_trap(() => call($19, "test", [22])); + +// table_init.wast:1162 +assert_trap(() => call($19, "test", [23])); + +// table_init.wast:1163 +assert_trap(() => call($19, "test", [24])); + +// table_init.wast:1164 +assert_trap(() => call($19, "test", [25])); + +// table_init.wast:1165 +assert_trap(() => call($19, "test", [26])); + +// table_init.wast:1166 +assert_trap(() => call($19, "test", [27])); + +// table_init.wast:1167 +assert_trap(() => call($19, "test", [28])); + +// table_init.wast:1168 +assert_trap(() => call($19, "test", [29])); + +// table_init.wast:1169 +assert_trap(() => call($19, "test", [30])); + +// table_init.wast:1170 +assert_trap(() => call($19, "test", [31])); + +// table_init.wast:1172 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1200 +assert_trap(() => call($20, "run", [25, 16])); + +// table_init.wast:1201 +assert_trap(() => call($20, "test", [0])); + +// table_init.wast:1202 +assert_trap(() => call($20, "test", [1])); + +// table_init.wast:1203 +assert_trap(() => call($20, "test", [2])); + +// table_init.wast:1204 +assert_trap(() => call($20, "test", [3])); + +// table_init.wast:1205 +assert_trap(() => call($20, "test", [4])); + +// table_init.wast:1206 +assert_trap(() => call($20, "test", [5])); + +// table_init.wast:1207 +assert_trap(() => call($20, "test", [6])); + +// table_init.wast:1208 +assert_trap(() => call($20, "test", [7])); + +// table_init.wast:1209 +assert_trap(() => call($20, "test", [8])); + +// table_init.wast:1210 +assert_trap(() => call($20, "test", [9])); + +// table_init.wast:1211 +assert_trap(() => call($20, "test", [10])); + +// table_init.wast:1212 +assert_trap(() => call($20, "test", [11])); + +// table_init.wast:1213 +assert_trap(() => call($20, "test", [12])); + +// table_init.wast:1214 +assert_trap(() => call($20, "test", [13])); + +// table_init.wast:1215 +assert_trap(() => call($20, "test", [14])); + +// table_init.wast:1216 +assert_trap(() => call($20, "test", [15])); + +// table_init.wast:1217 +assert_trap(() => call($20, "test", [16])); + +// table_init.wast:1218 +assert_trap(() => call($20, "test", [17])); + +// table_init.wast:1219 +assert_trap(() => call($20, "test", [18])); + +// table_init.wast:1220 +assert_trap(() => call($20, "test", [19])); + +// table_init.wast:1221 +assert_trap(() => call($20, "test", [20])); + +// table_init.wast:1222 +assert_trap(() => call($20, "test", [21])); + +// table_init.wast:1223 +assert_trap(() => call($20, "test", [22])); + +// table_init.wast:1224 +assert_trap(() => call($20, "test", [23])); + +// table_init.wast:1225 +assert_trap(() => call($20, "test", [24])); + +// table_init.wast:1226 +assert_trap(() => call($20, "test", [25])); + +// table_init.wast:1227 +assert_trap(() => call($20, "test", [26])); + +// table_init.wast:1228 +assert_trap(() => call($20, "test", [27])); + +// table_init.wast:1229 +assert_trap(() => call($20, "test", [28])); + +// table_init.wast:1230 +assert_trap(() => call($20, "test", [29])); + +// table_init.wast:1231 +assert_trap(() => call($20, "test", [30])); + +// table_init.wast:1232 +assert_trap(() => call($20, "test", [31])); + +// table_init.wast:1234 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\xa0\x01\xc0\x02\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1262 +assert_trap(() => call($21, "run", [96, 32])); + +// table_init.wast:1263 +assert_trap(() => call($21, "test", [0])); + +// table_init.wast:1264 +assert_trap(() => call($21, "test", [1])); + +// table_init.wast:1265 +assert_trap(() => call($21, "test", [2])); + +// table_init.wast:1266 +assert_trap(() => call($21, "test", [3])); + +// table_init.wast:1267 +assert_trap(() => call($21, "test", [4])); + +// table_init.wast:1268 +assert_trap(() => call($21, "test", [5])); + +// table_init.wast:1269 +assert_trap(() => call($21, "test", [6])); + +// table_init.wast:1270 +assert_trap(() => call($21, "test", [7])); + +// table_init.wast:1271 +assert_trap(() => call($21, "test", [8])); + +// table_init.wast:1272 +assert_trap(() => call($21, "test", [9])); + +// table_init.wast:1273 +assert_trap(() => call($21, "test", [10])); + +// table_init.wast:1274 +assert_trap(() => call($21, "test", [11])); + +// table_init.wast:1275 +assert_trap(() => call($21, "test", [12])); + +// table_init.wast:1276 +assert_trap(() => call($21, "test", [13])); + +// table_init.wast:1277 +assert_trap(() => call($21, "test", [14])); + +// table_init.wast:1278 +assert_trap(() => call($21, "test", [15])); + +// table_init.wast:1279 +assert_trap(() => call($21, "test", [16])); + +// table_init.wast:1280 +assert_trap(() => call($21, "test", [17])); + +// table_init.wast:1281 +assert_trap(() => call($21, "test", [18])); + +// table_init.wast:1282 +assert_trap(() => call($21, "test", [19])); + +// table_init.wast:1283 +assert_trap(() => call($21, "test", [20])); + +// table_init.wast:1284 +assert_trap(() => call($21, "test", [21])); + +// table_init.wast:1285 +assert_trap(() => call($21, "test", [22])); + +// table_init.wast:1286 +assert_trap(() => call($21, "test", [23])); + +// table_init.wast:1287 +assert_trap(() => call($21, "test", [24])); + +// table_init.wast:1288 +assert_trap(() => call($21, "test", [25])); + +// table_init.wast:1289 +assert_trap(() => call($21, "test", [26])); + +// table_init.wast:1290 +assert_trap(() => call($21, "test", [27])); + +// table_init.wast:1291 +assert_trap(() => call($21, "test", [28])); + +// table_init.wast:1292 +assert_trap(() => call($21, "test", [29])); + +// table_init.wast:1293 +assert_trap(() => call($21, "test", [30])); + +// table_init.wast:1294 +assert_trap(() => call($21, "test", [31])); + +// table_init.wast:1295 +assert_trap(() => call($21, "test", [32])); + +// table_init.wast:1296 +assert_trap(() => call($21, "test", [33])); + +// table_init.wast:1297 +assert_trap(() => call($21, "test", [34])); + +// table_init.wast:1298 +assert_trap(() => call($21, "test", [35])); + +// table_init.wast:1299 +assert_trap(() => call($21, "test", [36])); + +// table_init.wast:1300 +assert_trap(() => call($21, "test", [37])); + +// table_init.wast:1301 +assert_trap(() => call($21, "test", [38])); + +// table_init.wast:1302 +assert_trap(() => call($21, "test", [39])); + +// table_init.wast:1303 +assert_trap(() => call($21, "test", [40])); + +// table_init.wast:1304 +assert_trap(() => call($21, "test", [41])); + +// table_init.wast:1305 +assert_trap(() => call($21, "test", [42])); + +// table_init.wast:1306 +assert_trap(() => call($21, "test", [43])); + +// table_init.wast:1307 +assert_trap(() => call($21, "test", [44])); + +// table_init.wast:1308 +assert_trap(() => call($21, "test", [45])); + +// table_init.wast:1309 +assert_trap(() => call($21, "test", [46])); + +// table_init.wast:1310 +assert_trap(() => call($21, "test", [47])); + +// table_init.wast:1311 +assert_trap(() => call($21, "test", [48])); + +// table_init.wast:1312 +assert_trap(() => call($21, "test", [49])); + +// table_init.wast:1313 +assert_trap(() => call($21, "test", [50])); + +// table_init.wast:1314 +assert_trap(() => call($21, "test", [51])); + +// table_init.wast:1315 +assert_trap(() => call($21, "test", [52])); + +// table_init.wast:1316 +assert_trap(() => call($21, "test", [53])); + +// table_init.wast:1317 +assert_trap(() => call($21, "test", [54])); + +// table_init.wast:1318 +assert_trap(() => call($21, "test", [55])); + +// table_init.wast:1319 +assert_trap(() => call($21, "test", [56])); + +// table_init.wast:1320 +assert_trap(() => call($21, "test", [57])); + +// table_init.wast:1321 +assert_trap(() => call($21, "test", [58])); + +// table_init.wast:1322 +assert_trap(() => call($21, "test", [59])); + +// table_init.wast:1323 +assert_trap(() => call($21, "test", [60])); + +// table_init.wast:1324 +assert_trap(() => call($21, "test", [61])); + +// table_init.wast:1325 +assert_trap(() => call($21, "test", [62])); + +// table_init.wast:1326 +assert_trap(() => call($21, "test", [63])); + +// table_init.wast:1327 +assert_trap(() => call($21, "test", [64])); + +// table_init.wast:1328 +assert_trap(() => call($21, "test", [65])); + +// table_init.wast:1329 +assert_trap(() => call($21, "test", [66])); + +// table_init.wast:1330 +assert_trap(() => call($21, "test", [67])); + +// table_init.wast:1331 +assert_trap(() => call($21, "test", [68])); + +// table_init.wast:1332 +assert_trap(() => call($21, "test", [69])); + +// table_init.wast:1333 +assert_trap(() => call($21, "test", [70])); + +// table_init.wast:1334 +assert_trap(() => call($21, "test", [71])); + +// table_init.wast:1335 +assert_trap(() => call($21, "test", [72])); + +// table_init.wast:1336 +assert_trap(() => call($21, "test", [73])); + +// table_init.wast:1337 +assert_trap(() => call($21, "test", [74])); + +// table_init.wast:1338 +assert_trap(() => call($21, "test", [75])); + +// table_init.wast:1339 +assert_trap(() => call($21, "test", [76])); + +// table_init.wast:1340 +assert_trap(() => call($21, "test", [77])); + +// table_init.wast:1341 +assert_trap(() => call($21, "test", [78])); + +// table_init.wast:1342 +assert_trap(() => call($21, "test", [79])); + +// table_init.wast:1343 +assert_trap(() => call($21, "test", [80])); + +// table_init.wast:1344 +assert_trap(() => call($21, "test", [81])); + +// table_init.wast:1345 +assert_trap(() => call($21, "test", [82])); + +// table_init.wast:1346 +assert_trap(() => call($21, "test", [83])); + +// table_init.wast:1347 +assert_trap(() => call($21, "test", [84])); + +// table_init.wast:1348 +assert_trap(() => call($21, "test", [85])); + +// table_init.wast:1349 +assert_trap(() => call($21, "test", [86])); + +// table_init.wast:1350 +assert_trap(() => call($21, "test", [87])); + +// table_init.wast:1351 +assert_trap(() => call($21, "test", [88])); + +// table_init.wast:1352 +assert_trap(() => call($21, "test", [89])); + +// table_init.wast:1353 +assert_trap(() => call($21, "test", [90])); + +// table_init.wast:1354 +assert_trap(() => call($21, "test", [91])); + +// table_init.wast:1355 +assert_trap(() => call($21, "test", [92])); + +// table_init.wast:1356 +assert_trap(() => call($21, "test", [93])); + +// table_init.wast:1357 +assert_trap(() => call($21, "test", [94])); + +// table_init.wast:1358 +assert_trap(() => call($21, "test", [95])); + +// table_init.wast:1359 +assert_trap(() => call($21, "test", [96])); + +// table_init.wast:1360 +assert_trap(() => call($21, "test", [97])); + +// table_init.wast:1361 +assert_trap(() => call($21, "test", [98])); + +// table_init.wast:1362 +assert_trap(() => call($21, "test", [99])); + +// table_init.wast:1363 +assert_trap(() => call($21, "test", [100])); + +// table_init.wast:1364 +assert_trap(() => call($21, "test", [101])); + +// table_init.wast:1365 +assert_trap(() => call($21, "test", [102])); + +// table_init.wast:1366 +assert_trap(() => call($21, "test", [103])); + +// table_init.wast:1367 +assert_trap(() => call($21, "test", [104])); + +// table_init.wast:1368 +assert_trap(() => call($21, "test", [105])); + +// table_init.wast:1369 +assert_trap(() => call($21, "test", [106])); + +// table_init.wast:1370 +assert_trap(() => call($21, "test", [107])); + +// table_init.wast:1371 +assert_trap(() => call($21, "test", [108])); + +// table_init.wast:1372 +assert_trap(() => call($21, "test", [109])); + +// table_init.wast:1373 +assert_trap(() => call($21, "test", [110])); + +// table_init.wast:1374 +assert_trap(() => call($21, "test", [111])); + +// table_init.wast:1375 +assert_trap(() => call($21, "test", [112])); + +// table_init.wast:1376 +assert_trap(() => call($21, "test", [113])); + +// table_init.wast:1377 +assert_trap(() => call($21, "test", [114])); + +// table_init.wast:1378 +assert_trap(() => call($21, "test", [115])); + +// table_init.wast:1379 +assert_trap(() => call($21, "test", [116])); + +// table_init.wast:1380 +assert_trap(() => call($21, "test", [117])); + +// table_init.wast:1381 +assert_trap(() => call($21, "test", [118])); + +// table_init.wast:1382 +assert_trap(() => call($21, "test", [119])); + +// table_init.wast:1383 +assert_trap(() => call($21, "test", [120])); + +// table_init.wast:1384 +assert_trap(() => call($21, "test", [121])); + +// table_init.wast:1385 +assert_trap(() => call($21, "test", [122])); + +// table_init.wast:1386 +assert_trap(() => call($21, "test", [123])); + +// table_init.wast:1387 +assert_trap(() => call($21, "test", [124])); + +// table_init.wast:1388 +assert_trap(() => call($21, "test", [125])); + +// table_init.wast:1389 +assert_trap(() => call($21, "test", [126])); + +// table_init.wast:1390 +assert_trap(() => call($21, "test", [127])); + +// table_init.wast:1391 +assert_trap(() => call($21, "test", [128])); + +// table_init.wast:1392 +assert_trap(() => call($21, "test", [129])); + +// table_init.wast:1393 +assert_trap(() => call($21, "test", [130])); + +// table_init.wast:1394 +assert_trap(() => call($21, "test", [131])); + +// table_init.wast:1395 +assert_trap(() => call($21, "test", [132])); + +// table_init.wast:1396 +assert_trap(() => call($21, "test", [133])); + +// table_init.wast:1397 +assert_trap(() => call($21, "test", [134])); + +// table_init.wast:1398 +assert_trap(() => call($21, "test", [135])); + +// table_init.wast:1399 +assert_trap(() => call($21, "test", [136])); + +// table_init.wast:1400 +assert_trap(() => call($21, "test", [137])); + +// table_init.wast:1401 +assert_trap(() => call($21, "test", [138])); + +// table_init.wast:1402 +assert_trap(() => call($21, "test", [139])); + +// table_init.wast:1403 +assert_trap(() => call($21, "test", [140])); + +// table_init.wast:1404 +assert_trap(() => call($21, "test", [141])); + +// table_init.wast:1405 +assert_trap(() => call($21, "test", [142])); + +// table_init.wast:1406 +assert_trap(() => call($21, "test", [143])); + +// table_init.wast:1407 +assert_trap(() => call($21, "test", [144])); + +// table_init.wast:1408 +assert_trap(() => call($21, "test", [145])); + +// table_init.wast:1409 +assert_trap(() => call($21, "test", [146])); + +// table_init.wast:1410 +assert_trap(() => call($21, "test", [147])); + +// table_init.wast:1411 +assert_trap(() => call($21, "test", [148])); + +// table_init.wast:1412 +assert_trap(() => call($21, "test", [149])); + +// table_init.wast:1413 +assert_trap(() => call($21, "test", [150])); + +// table_init.wast:1414 +assert_trap(() => call($21, "test", [151])); + +// table_init.wast:1415 +assert_trap(() => call($21, "test", [152])); + +// table_init.wast:1416 +assert_trap(() => call($21, "test", [153])); + +// table_init.wast:1417 +assert_trap(() => call($21, "test", [154])); + +// table_init.wast:1418 +assert_trap(() => call($21, "test", [155])); + +// table_init.wast:1419 +assert_trap(() => call($21, "test", [156])); + +// table_init.wast:1420 +assert_trap(() => call($21, "test", [157])); + +// table_init.wast:1421 +assert_trap(() => call($21, "test", [158])); + +// table_init.wast:1422 +assert_trap(() => call($21, "test", [159])); + +// table_init.wast:1424 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\xa0\x01\xc0\x02\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1452 +assert_trap(() => call($22, "run", [97, 31])); + +// table_init.wast:1453 +assert_trap(() => call($22, "test", [0])); + +// table_init.wast:1454 +assert_trap(() => call($22, "test", [1])); + +// table_init.wast:1455 +assert_trap(() => call($22, "test", [2])); + +// table_init.wast:1456 +assert_trap(() => call($22, "test", [3])); + +// table_init.wast:1457 +assert_trap(() => call($22, "test", [4])); + +// table_init.wast:1458 +assert_trap(() => call($22, "test", [5])); + +// table_init.wast:1459 +assert_trap(() => call($22, "test", [6])); + +// table_init.wast:1460 +assert_trap(() => call($22, "test", [7])); + +// table_init.wast:1461 +assert_trap(() => call($22, "test", [8])); + +// table_init.wast:1462 +assert_trap(() => call($22, "test", [9])); + +// table_init.wast:1463 +assert_trap(() => call($22, "test", [10])); + +// table_init.wast:1464 +assert_trap(() => call($22, "test", [11])); + +// table_init.wast:1465 +assert_trap(() => call($22, "test", [12])); + +// table_init.wast:1466 +assert_trap(() => call($22, "test", [13])); + +// table_init.wast:1467 +assert_trap(() => call($22, "test", [14])); + +// table_init.wast:1468 +assert_trap(() => call($22, "test", [15])); + +// table_init.wast:1469 +assert_trap(() => call($22, "test", [16])); + +// table_init.wast:1470 +assert_trap(() => call($22, "test", [17])); + +// table_init.wast:1471 +assert_trap(() => call($22, "test", [18])); + +// table_init.wast:1472 +assert_trap(() => call($22, "test", [19])); + +// table_init.wast:1473 +assert_trap(() => call($22, "test", [20])); + +// table_init.wast:1474 +assert_trap(() => call($22, "test", [21])); + +// table_init.wast:1475 +assert_trap(() => call($22, "test", [22])); + +// table_init.wast:1476 +assert_trap(() => call($22, "test", [23])); + +// table_init.wast:1477 +assert_trap(() => call($22, "test", [24])); + +// table_init.wast:1478 +assert_trap(() => call($22, "test", [25])); + +// table_init.wast:1479 +assert_trap(() => call($22, "test", [26])); + +// table_init.wast:1480 +assert_trap(() => call($22, "test", [27])); + +// table_init.wast:1481 +assert_trap(() => call($22, "test", [28])); + +// table_init.wast:1482 +assert_trap(() => call($22, "test", [29])); + +// table_init.wast:1483 +assert_trap(() => call($22, "test", [30])); + +// table_init.wast:1484 +assert_trap(() => call($22, "test", [31])); + +// table_init.wast:1485 +assert_trap(() => call($22, "test", [32])); + +// table_init.wast:1486 +assert_trap(() => call($22, "test", [33])); + +// table_init.wast:1487 +assert_trap(() => call($22, "test", [34])); + +// table_init.wast:1488 +assert_trap(() => call($22, "test", [35])); + +// table_init.wast:1489 +assert_trap(() => call($22, "test", [36])); + +// table_init.wast:1490 +assert_trap(() => call($22, "test", [37])); + +// table_init.wast:1491 +assert_trap(() => call($22, "test", [38])); + +// table_init.wast:1492 +assert_trap(() => call($22, "test", [39])); + +// table_init.wast:1493 +assert_trap(() => call($22, "test", [40])); + +// table_init.wast:1494 +assert_trap(() => call($22, "test", [41])); + +// table_init.wast:1495 +assert_trap(() => call($22, "test", [42])); + +// table_init.wast:1496 +assert_trap(() => call($22, "test", [43])); + +// table_init.wast:1497 +assert_trap(() => call($22, "test", [44])); + +// table_init.wast:1498 +assert_trap(() => call($22, "test", [45])); + +// table_init.wast:1499 +assert_trap(() => call($22, "test", [46])); + +// table_init.wast:1500 +assert_trap(() => call($22, "test", [47])); + +// table_init.wast:1501 +assert_trap(() => call($22, "test", [48])); + +// table_init.wast:1502 +assert_trap(() => call($22, "test", [49])); + +// table_init.wast:1503 +assert_trap(() => call($22, "test", [50])); + +// table_init.wast:1504 +assert_trap(() => call($22, "test", [51])); + +// table_init.wast:1505 +assert_trap(() => call($22, "test", [52])); + +// table_init.wast:1506 +assert_trap(() => call($22, "test", [53])); + +// table_init.wast:1507 +assert_trap(() => call($22, "test", [54])); + +// table_init.wast:1508 +assert_trap(() => call($22, "test", [55])); + +// table_init.wast:1509 +assert_trap(() => call($22, "test", [56])); + +// table_init.wast:1510 +assert_trap(() => call($22, "test", [57])); + +// table_init.wast:1511 +assert_trap(() => call($22, "test", [58])); + +// table_init.wast:1512 +assert_trap(() => call($22, "test", [59])); + +// table_init.wast:1513 +assert_trap(() => call($22, "test", [60])); + +// table_init.wast:1514 +assert_trap(() => call($22, "test", [61])); + +// table_init.wast:1515 +assert_trap(() => call($22, "test", [62])); + +// table_init.wast:1516 +assert_trap(() => call($22, "test", [63])); + +// table_init.wast:1517 +assert_trap(() => call($22, "test", [64])); + +// table_init.wast:1518 +assert_trap(() => call($22, "test", [65])); + +// table_init.wast:1519 +assert_trap(() => call($22, "test", [66])); + +// table_init.wast:1520 +assert_trap(() => call($22, "test", [67])); + +// table_init.wast:1521 +assert_trap(() => call($22, "test", [68])); + +// table_init.wast:1522 +assert_trap(() => call($22, "test", [69])); + +// table_init.wast:1523 +assert_trap(() => call($22, "test", [70])); + +// table_init.wast:1524 +assert_trap(() => call($22, "test", [71])); + +// table_init.wast:1525 +assert_trap(() => call($22, "test", [72])); + +// table_init.wast:1526 +assert_trap(() => call($22, "test", [73])); + +// table_init.wast:1527 +assert_trap(() => call($22, "test", [74])); + +// table_init.wast:1528 +assert_trap(() => call($22, "test", [75])); + +// table_init.wast:1529 +assert_trap(() => call($22, "test", [76])); + +// table_init.wast:1530 +assert_trap(() => call($22, "test", [77])); + +// table_init.wast:1531 +assert_trap(() => call($22, "test", [78])); + +// table_init.wast:1532 +assert_trap(() => call($22, "test", [79])); + +// table_init.wast:1533 +assert_trap(() => call($22, "test", [80])); + +// table_init.wast:1534 +assert_trap(() => call($22, "test", [81])); + +// table_init.wast:1535 +assert_trap(() => call($22, "test", [82])); + +// table_init.wast:1536 +assert_trap(() => call($22, "test", [83])); + +// table_init.wast:1537 +assert_trap(() => call($22, "test", [84])); + +// table_init.wast:1538 +assert_trap(() => call($22, "test", [85])); + +// table_init.wast:1539 +assert_trap(() => call($22, "test", [86])); + +// table_init.wast:1540 +assert_trap(() => call($22, "test", [87])); + +// table_init.wast:1541 +assert_trap(() => call($22, "test", [88])); + +// table_init.wast:1542 +assert_trap(() => call($22, "test", [89])); + +// table_init.wast:1543 +assert_trap(() => call($22, "test", [90])); + +// table_init.wast:1544 +assert_trap(() => call($22, "test", [91])); + +// table_init.wast:1545 +assert_trap(() => call($22, "test", [92])); + +// table_init.wast:1546 +assert_trap(() => call($22, "test", [93])); + +// table_init.wast:1547 +assert_trap(() => call($22, "test", [94])); + +// table_init.wast:1548 +assert_trap(() => call($22, "test", [95])); + +// table_init.wast:1549 +assert_trap(() => call($22, "test", [96])); + +// table_init.wast:1550 +assert_trap(() => call($22, "test", [97])); + +// table_init.wast:1551 +assert_trap(() => call($22, "test", [98])); + +// table_init.wast:1552 +assert_trap(() => call($22, "test", [99])); + +// table_init.wast:1553 +assert_trap(() => call($22, "test", [100])); + +// table_init.wast:1554 +assert_trap(() => call($22, "test", [101])); + +// table_init.wast:1555 +assert_trap(() => call($22, "test", [102])); + +// table_init.wast:1556 +assert_trap(() => call($22, "test", [103])); + +// table_init.wast:1557 +assert_trap(() => call($22, "test", [104])); + +// table_init.wast:1558 +assert_trap(() => call($22, "test", [105])); + +// table_init.wast:1559 +assert_trap(() => call($22, "test", [106])); + +// table_init.wast:1560 +assert_trap(() => call($22, "test", [107])); + +// table_init.wast:1561 +assert_trap(() => call($22, "test", [108])); + +// table_init.wast:1562 +assert_trap(() => call($22, "test", [109])); + +// table_init.wast:1563 +assert_trap(() => call($22, "test", [110])); + +// table_init.wast:1564 +assert_trap(() => call($22, "test", [111])); + +// table_init.wast:1565 +assert_trap(() => call($22, "test", [112])); + +// table_init.wast:1566 +assert_trap(() => call($22, "test", [113])); + +// table_init.wast:1567 +assert_trap(() => call($22, "test", [114])); + +// table_init.wast:1568 +assert_trap(() => call($22, "test", [115])); + +// table_init.wast:1569 +assert_trap(() => call($22, "test", [116])); + +// table_init.wast:1570 +assert_trap(() => call($22, "test", [117])); + +// table_init.wast:1571 +assert_trap(() => call($22, "test", [118])); + +// table_init.wast:1572 +assert_trap(() => call($22, "test", [119])); + +// table_init.wast:1573 +assert_trap(() => call($22, "test", [120])); + +// table_init.wast:1574 +assert_trap(() => call($22, "test", [121])); + +// table_init.wast:1575 +assert_trap(() => call($22, "test", [122])); + +// table_init.wast:1576 +assert_trap(() => call($22, "test", [123])); + +// table_init.wast:1577 +assert_trap(() => call($22, "test", [124])); + +// table_init.wast:1578 +assert_trap(() => call($22, "test", [125])); + +// table_init.wast:1579 +assert_trap(() => call($22, "test", [126])); + +// table_init.wast:1580 +assert_trap(() => call($22, "test", [127])); + +// table_init.wast:1581 +assert_trap(() => call($22, "test", [128])); + +// table_init.wast:1582 +assert_trap(() => call($22, "test", [129])); + +// table_init.wast:1583 +assert_trap(() => call($22, "test", [130])); + +// table_init.wast:1584 +assert_trap(() => call($22, "test", [131])); + +// table_init.wast:1585 +assert_trap(() => call($22, "test", [132])); + +// table_init.wast:1586 +assert_trap(() => call($22, "test", [133])); + +// table_init.wast:1587 +assert_trap(() => call($22, "test", [134])); + +// table_init.wast:1588 +assert_trap(() => call($22, "test", [135])); + +// table_init.wast:1589 +assert_trap(() => call($22, "test", [136])); + +// table_init.wast:1590 +assert_trap(() => call($22, "test", [137])); + +// table_init.wast:1591 +assert_trap(() => call($22, "test", [138])); + +// table_init.wast:1592 +assert_trap(() => call($22, "test", [139])); + +// table_init.wast:1593 +assert_trap(() => call($22, "test", [140])); + +// table_init.wast:1594 +assert_trap(() => call($22, "test", [141])); + +// table_init.wast:1595 +assert_trap(() => call($22, "test", [142])); + +// table_init.wast:1596 +assert_trap(() => call($22, "test", [143])); + +// table_init.wast:1597 +assert_trap(() => call($22, "test", [144])); + +// table_init.wast:1598 +assert_trap(() => call($22, "test", [145])); + +// table_init.wast:1599 +assert_trap(() => call($22, "test", [146])); + +// table_init.wast:1600 +assert_trap(() => call($22, "test", [147])); + +// table_init.wast:1601 +assert_trap(() => call($22, "test", [148])); + +// table_init.wast:1602 +assert_trap(() => call($22, "test", [149])); + +// table_init.wast:1603 +assert_trap(() => call($22, "test", [150])); + +// table_init.wast:1604 +assert_trap(() => call($22, "test", [151])); + +// table_init.wast:1605 +assert_trap(() => call($22, "test", [152])); + +// table_init.wast:1606 +assert_trap(() => call($22, "test", [153])); + +// table_init.wast:1607 +assert_trap(() => call($22, "test", [154])); + +// table_init.wast:1608 +assert_trap(() => call($22, "test", [155])); + +// table_init.wast:1609 +assert_trap(() => call($22, "test", [156])); + +// table_init.wast:1610 +assert_trap(() => call($22, "test", [157])); + +// table_init.wast:1611 +assert_trap(() => call($22, "test", [158])); + +// table_init.wast:1612 +assert_trap(() => call($22, "test", [159])); + +// table_init.wast:1614 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x40\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1642 +assert_trap(() => call($23, "run", [48, -16])); + +// table_init.wast:1643 +assert_trap(() => call($23, "test", [0])); + +// table_init.wast:1644 +assert_trap(() => call($23, "test", [1])); + +// table_init.wast:1645 +assert_trap(() => call($23, "test", [2])); + +// table_init.wast:1646 +assert_trap(() => call($23, "test", [3])); + +// table_init.wast:1647 +assert_trap(() => call($23, "test", [4])); + +// table_init.wast:1648 +assert_trap(() => call($23, "test", [5])); + +// table_init.wast:1649 +assert_trap(() => call($23, "test", [6])); + +// table_init.wast:1650 +assert_trap(() => call($23, "test", [7])); + +// table_init.wast:1651 +assert_trap(() => call($23, "test", [8])); + +// table_init.wast:1652 +assert_trap(() => call($23, "test", [9])); + +// table_init.wast:1653 +assert_trap(() => call($23, "test", [10])); + +// table_init.wast:1654 +assert_trap(() => call($23, "test", [11])); + +// table_init.wast:1655 +assert_trap(() => call($23, "test", [12])); + +// table_init.wast:1656 +assert_trap(() => call($23, "test", [13])); + +// table_init.wast:1657 +assert_trap(() => call($23, "test", [14])); + +// table_init.wast:1658 +assert_trap(() => call($23, "test", [15])); + +// table_init.wast:1659 +assert_trap(() => call($23, "test", [16])); + +// table_init.wast:1660 +assert_trap(() => call($23, "test", [17])); + +// table_init.wast:1661 +assert_trap(() => call($23, "test", [18])); + +// table_init.wast:1662 +assert_trap(() => call($23, "test", [19])); + +// table_init.wast:1663 +assert_trap(() => call($23, "test", [20])); + +// table_init.wast:1664 +assert_trap(() => call($23, "test", [21])); + +// table_init.wast:1665 +assert_trap(() => call($23, "test", [22])); + +// table_init.wast:1666 +assert_trap(() => call($23, "test", [23])); + +// table_init.wast:1667 +assert_trap(() => call($23, "test", [24])); + +// table_init.wast:1668 +assert_trap(() => call($23, "test", [25])); + +// table_init.wast:1669 +assert_trap(() => call($23, "test", [26])); + +// table_init.wast:1670 +assert_trap(() => call($23, "test", [27])); + +// table_init.wast:1671 +assert_trap(() => call($23, "test", [28])); + +// table_init.wast:1672 +assert_trap(() => call($23, "test", [29])); + +// table_init.wast:1673 +assert_trap(() => call($23, "test", [30])); + +// table_init.wast:1674 +assert_trap(() => call($23, "test", [31])); + +// table_init.wast:1675 +assert_trap(() => call($23, "test", [32])); + +// table_init.wast:1676 +assert_trap(() => call($23, "test", [33])); + +// table_init.wast:1677 +assert_trap(() => call($23, "test", [34])); + +// table_init.wast:1678 +assert_trap(() => call($23, "test", [35])); + +// table_init.wast:1679 +assert_trap(() => call($23, "test", [36])); + +// table_init.wast:1680 +assert_trap(() => call($23, "test", [37])); + +// table_init.wast:1681 +assert_trap(() => call($23, "test", [38])); + +// table_init.wast:1682 +assert_trap(() => call($23, "test", [39])); + +// table_init.wast:1683 +assert_trap(() => call($23, "test", [40])); + +// table_init.wast:1684 +assert_trap(() => call($23, "test", [41])); + +// table_init.wast:1685 +assert_trap(() => call($23, "test", [42])); + +// table_init.wast:1686 +assert_trap(() => call($23, "test", [43])); + +// table_init.wast:1687 +assert_trap(() => call($23, "test", [44])); + +// table_init.wast:1688 +assert_trap(() => call($23, "test", [45])); + +// table_init.wast:1689 +assert_trap(() => call($23, "test", [46])); + +// table_init.wast:1690 +assert_trap(() => call($23, "test", [47])); + +// table_init.wast:1691 +assert_trap(() => call($23, "test", [48])); + +// table_init.wast:1692 +assert_trap(() => call($23, "test", [49])); + +// table_init.wast:1693 +assert_trap(() => call($23, "test", [50])); + +// table_init.wast:1694 +assert_trap(() => call($23, "test", [51])); + +// table_init.wast:1695 +assert_trap(() => call($23, "test", [52])); + +// table_init.wast:1696 +assert_trap(() => call($23, "test", [53])); + +// table_init.wast:1697 +assert_trap(() => call($23, "test", [54])); + +// table_init.wast:1698 +assert_trap(() => call($23, "test", [55])); + +// table_init.wast:1699 +assert_trap(() => call($23, "test", [56])); + +// table_init.wast:1700 +assert_trap(() => call($23, "test", [57])); + +// table_init.wast:1701 +assert_trap(() => call($23, "test", [58])); + +// table_init.wast:1702 +assert_trap(() => call($23, "test", [59])); + +// table_init.wast:1703 +assert_trap(() => call($23, "test", [60])); + +// table_init.wast:1704 +assert_trap(() => call($23, "test", [61])); + +// table_init.wast:1705 +assert_trap(() => call($23, "test", [62])); + +// table_init.wast:1706 +assert_trap(() => call($23, "test", [63])); + +// table_init.wast:1708 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x10\x10\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x08\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1736 +assert_trap(() => call($24, "run", [0, -4])); + +// table_init.wast:1737 +assert_trap(() => call($24, "test", [0])); + +// table_init.wast:1738 +assert_trap(() => call($24, "test", [1])); + +// table_init.wast:1739 +assert_trap(() => call($24, "test", [2])); + +// table_init.wast:1740 +assert_trap(() => call($24, "test", [3])); + +// table_init.wast:1741 +assert_trap(() => call($24, "test", [4])); + +// table_init.wast:1742 +assert_trap(() => call($24, "test", [5])); + +// table_init.wast:1743 +assert_trap(() => call($24, "test", [6])); + +// table_init.wast:1744 +assert_trap(() => call($24, "test", [7])); + +// table_init.wast:1745 +assert_trap(() => call($24, "test", [8])); + +// table_init.wast:1746 +assert_trap(() => call($24, "test", [9])); + +// table_init.wast:1747 +assert_trap(() => call($24, "test", [10])); + +// table_init.wast:1748 +assert_trap(() => call($24, "test", [11])); + +// table_init.wast:1749 +assert_trap(() => call($24, "test", [12])); + +// table_init.wast:1750 +assert_trap(() => call($24, "test", [13])); + +// table_init.wast:1751 +assert_trap(() => call($24, "test", [14])); + +// table_init.wast:1752 +assert_trap(() => call($24, "test", [15])); + +// table_init.wast:1754 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\xc4\x81\x80\x80\x00\x41\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\xfc\x0c\x40\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/data.wast.js b/js/src/jit-test/tests/wasm/spec/data.wast.js deleted file mode 100644 index 53944d21a4..0000000000 --- a/js/src/jit-test/tests/wasm/spec/data.wast.js +++ /dev/null @@ -1,135 +0,0 @@ - -// data.wast:5 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\xd2\x80\x80\x80\x00\x0c\x00\x41\x00\x0b\x00\x00\x41\x01\x0b\x04\x61\x62\x63\x64\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x03\x61\x62\x63\x00\x41\x00\x0b\x00\x00\x41\x01\x0b\x04\x61\x62\x63\x64\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x03\x61\x62\x63\x00\x41\x00\x0b\x00\x00\x41\x01\x0b\x04\x61\x62\x63\x64\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x03\x61\x62\x63"); - -// data.wast:23 -let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:27 -let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:32 -let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\xa2\x80\x80\x80\x00\x05\x00\x41\x00\x0b\x01\x61\x00\x41\x03\x0b\x01\x62\x00\x41\xe4\x00\x0b\x03\x63\x64\x65\x00\x41\x05\x0b\x01\x78\x00\x41\x03\x0b\x01\x63"); - -// data.wast:40 -let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\xa7\x80\x80\x80\x00\x06\x00\x41\x00\x0b\x01\x61\x00\x41\x01\x0b\x01\x62\x00\x41\x02\x0b\x03\x63\x64\x65\x00\x41\x03\x0b\x01\x66\x00\x41\x02\x0b\x01\x67\x00\x41\x01\x0b\x01\x68"); - -// data.wast:50 -let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:55 -let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\xab\x80\x80\x80\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:61 -let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:66 -let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\xab\x80\x80\x80\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:78 -let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x8f\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x01\x61\x00\x41\xff\xff\x03\x0b\x01\x62"); - -// data.wast:83 -let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x8f\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x01\x61\x00\x41\xff\xff\x03\x0b\x01\x62"); - -// data.wast:89 -let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x02\x0b\x89\x80\x80\x80\x00\x01\x00\x41\xff\xff\x07\x0b\x01\x61"); - -// data.wast:94 -let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:98 -let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:103 -let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:108 -let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x88\x80\x80\x80\x00\x01\x00\x41\x80\x80\x04\x0b\x00"); - -// data.wast:113 -let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:117 -let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:122 -let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:127 -let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:132 -let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x95\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x01\x00\x03\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:137 -let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\xab\x80\x80\x80\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:143 -let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\xac\x80\x80\x80\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x01\x00\x03\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:149 -let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x61"); - -// data.wast:154 -let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x95\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x01\x00\x03\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x61"); - -// data.wast:161 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:169 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:177 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x61"); - -// data.wast:185 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x00"); - -// data.wast:193 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x01\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x00"); - -// data.wast:210 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x61"); - -// data.wast:219 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x02\x0b\x89\x80\x80\x80\x00\x01\x00\x41\x80\x80\x04\x0b\x01\x61"); - -// data.wast:226 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x89\x80\x80\x80\x00\x01\x00\x41\x80\x80\x04\x0b\x01\x61"); - -// data.wast:234 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x02\x0b\x89\x80\x80\x80\x00\x01\x00\x41\x80\x80\x08\x0b\x01\x61"); - -// data.wast:242 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x02\x03\x0b\x89\x80\x80\x80\x00\x01\x00\x41\x80\x80\x08\x0b\x01\x61"); - -// data.wast:250 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x7f\x0b\x01\x61"); - -// data.wast:257 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x7f\x0b\x01\x61"); - -// data.wast:265 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x02\x0b\x88\x80\x80\x80\x00\x01\x00\x41\x9c\x7f\x0b\x01\x61"); - -// data.wast:272 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x01\x0b\x88\x80\x80\x80\x00\x01\x00\x41\x9c\x7f\x0b\x01\x61"); - -// data.wast:282 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// data.wast:291 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x86\x80\x80\x80\x00\x01\x00\x42\x00\x0b\x00"); - -// data.wast:299 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x68\x0b\x00"); - -// data.wast:307 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x85\x80\x80\x80\x00\x01\x00\x01\x0b\x00"); - -// data.wast:315 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x01\x41\x00\x0b\x00"); - -// data.wast:323 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x01\x0b\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/directives.txt b/js/src/jit-test/tests/wasm/spec/directives.txt deleted file mode 100644 index 6b827c2b6b..0000000000 --- a/js/src/jit-test/tests/wasm/spec/directives.txt +++ /dev/null @@ -1 +0,0 @@ -|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; include:wasm-testharness.js diff --git a/js/src/jit-test/tests/wasm/spec/elem.wast.js b/js/src/jit-test/tests/wasm/spec/elem.wast.js deleted file mode 100644 index df3dd2df33..0000000000 --- a/js/src/jit-test/tests/wasm/spec/elem.wast.js +++ /dev/null @@ -1,168 +0,0 @@ - -// elem.wast:4 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\xc9\x80\x80\x80\x00\x0c\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x00\x41\x00\x0b\x00\x00\x41\x00\x0b\x02\x00\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:23 -let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:28 -let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:34 -let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x9f\x80\x80\x80\x00\x05\x00\x41\x00\x0b\x01\x00\x00\x41\x03\x0b\x01\x00\x00\x41\x07\x0b\x01\x00\x00\x41\x05\x0b\x01\x00\x00\x41\x03\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:43 -let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x9f\x80\x80\x80\x00\x05\x00\x41\x09\x0b\x01\x00\x00\x41\x03\x0b\x01\x00\x00\x41\x07\x0b\x01\x00\x00\x41\x03\x0b\x01\x00\x00\x41\x05\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:53 -let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x70\x00\xe8\x07\x09\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:60 -let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x70\x00\xe8\x07\x09\x87\x80\x80\x80\x00\x01\x00\x23\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:67 -let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x85\x80\x80\x80\x00\x04\x00\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x93\x80\x80\x80\x00\x02\x06\x63\x61\x6c\x6c\x2d\x37\x00\x02\x06\x63\x61\x6c\x6c\x2d\x39\x00\x03\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x07\x0b\x01\x00\x00\x41\x09\x0b\x01\x01\x0a\xad\x80\x80\x80\x00\x04\x85\x80\x80\x80\x00\x00\x41\xc1\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc2\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x07\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x09\x11\x00\x00\x0b"); - -// elem.wast:81 -assert_return(() => call($8, "call-7", []), 65); - -// elem.wast:82 -assert_return(() => call($8, "call-9", []), 66); - -// elem.wast:86 -let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x87\x80\x80\x80\x00\x01\x00\x41\x09\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:91 -let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x09\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:97 -let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x09\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// elem.wast:101 -let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x00\x09\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// elem.wast:106 -let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x00\x00\x09\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// elem.wast:111 -let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x14\x09\x86\x80\x80\x80\x00\x01\x00\x41\x14\x0b\x00"); - -// elem.wast:116 -let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:122 -let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x95\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x01\x00\x64\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:128 -let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:134 -let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x95\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x01\x00\x1e\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:142 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:151 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x00\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:160 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x00\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:169 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x09\x86\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x00"); - -// elem.wast:177 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x87\x80\x80\x80\x00\x01\x00\x41\x0a\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:185 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x0a\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:194 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x0a\x14\x09\x87\x80\x80\x80\x00\x01\x00\x41\x0a\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:202 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x0a\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:211 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x87\x80\x80\x80\x00\x01\x00\x41\x7f\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:219 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x7f\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:228 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x87\x80\x80\x80\x00\x01\x00\x41\x76\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:236 -assert_uninstantiable("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x76\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:247 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); - -// elem.wast:257 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\x86\x80\x80\x80\x00\x01\x00\x42\x00\x0b\x00"); - -// elem.wast:265 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x68\x0b\x00"); - -// elem.wast:273 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\x85\x80\x80\x80\x00\x01\x00\x01\x0b\x00"); - -// elem.wast:281 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\x87\x80\x80\x80\x00\x01\x00\x01\x41\x00\x0b\x00"); - -// elem.wast:289 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x01\x0b\x00"); - -// elem.wast:305 -let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x84\x80\x80\x80\x00\x03\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x94\x80\x80\x80\x00\x01\x10\x63\x61\x6c\x6c\x2d\x6f\x76\x65\x72\x77\x72\x69\x74\x74\x65\x6e\x00\x02\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x09\x0b\x01\x00\x00\x41\x09\x0b\x01\x01\x0a\xa1\x80\x80\x80\x00\x03\x85\x80\x80\x80\x00\x00\x41\xc1\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc2\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x09\x11\x00\x00\x0b"); - -// elem.wast:316 -assert_return(() => call($19, "call-overwritten", []), 66); - -// elem.wast:318 -let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x84\x80\x80\x80\x00\x03\x00\x00\x00\x07\x9c\x80\x80\x80\x00\x01\x18\x63\x61\x6c\x6c\x2d\x6f\x76\x65\x72\x77\x72\x69\x74\x74\x65\x6e\x2d\x65\x6c\x65\x6d\x65\x6e\x74\x00\x02\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x09\x0b\x01\x00\x00\x41\x09\x0b\x01\x01\x0a\xa1\x80\x80\x80\x00\x03\x85\x80\x80\x80\x00\x00\x41\xc1\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc2\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x09\x11\x00\x00\x0b"); - -// elem.wast:329 -assert_return(() => call($20, "call-overwritten-element", []), 66); - -// elem.wast:333 -let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\xab\x80\x80\x80\x00\x04\x0c\x73\x68\x61\x72\x65\x64\x2d\x74\x61\x62\x6c\x65\x01\x00\x06\x63\x61\x6c\x6c\x2d\x37\x00\x02\x06\x63\x61\x6c\x6c\x2d\x38\x00\x03\x06\x63\x61\x6c\x6c\x2d\x39\x00\x04\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x08\x0b\x01\x00\x00\x41\x09\x0b\x01\x01\x0a\xb9\x80\x80\x80\x00\x05\x85\x80\x80\x80\x00\x00\x41\xc1\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc2\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x07\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x08\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x09\x11\x00\x00\x0b"); -let $module1 = $21; - -// elem.wast:351 -register("module1", $module1) - -// elem.wast:353 -assert_trap(() => call($module1, "call-7", [])); - -// elem.wast:354 -assert_return(() => call($module1, "call-8", []), 65); - -// elem.wast:355 -assert_return(() => call($module1, "call-9", []), 66); - -// elem.wast:357 -let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x07\x6d\x6f\x64\x75\x6c\x65\x31\x0c\x73\x68\x61\x72\x65\x64\x2d\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x83\x80\x80\x80\x00\x02\x00\x00\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x07\x0b\x01\x00\x00\x41\x08\x0b\x01\x01\x0a\x95\x80\x80\x80\x00\x02\x85\x80\x80\x80\x00\x00\x41\xc3\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc4\x00\x0b"); -let $module2 = $22; - -// elem.wast:366 -assert_return(() => call($module1, "call-7", []), 67); - -// elem.wast:367 -assert_return(() => call($module1, "call-8", []), 68); - -// elem.wast:368 -assert_return(() => call($module1, "call-9", []), 66); - -// elem.wast:370 -let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x07\x6d\x6f\x64\x75\x6c\x65\x31\x0c\x73\x68\x61\x72\x65\x64\x2d\x74\x61\x62\x6c\x65\x01\x70\x00\x0a\x03\x83\x80\x80\x80\x00\x02\x00\x00\x09\x8d\x80\x80\x80\x00\x02\x00\x41\x08\x0b\x01\x00\x00\x41\x09\x0b\x01\x01\x0a\x95\x80\x80\x80\x00\x02\x85\x80\x80\x80\x00\x00\x41\xc5\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xc6\x00\x0b"); -let $module3 = $23; - -// elem.wast:379 -assert_return(() => call($module1, "call-7", []), 67); - -// elem.wast:380 -assert_return(() => call($module1, "call-8", []), 69); - -// elem.wast:381 -assert_return(() => call($module1, "call-9", []), 70); diff --git a/js/src/jit-test/tests/wasm/spec/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/harness/directives.txt deleted file mode 100644 index 54014b78be..0000000000 --- a/js/src/jit-test/tests/wasm/spec/harness/directives.txt +++ /dev/null @@ -1 +0,0 @@ -|jit-test| skip-if:true diff --git a/js/src/jit-test/tests/wasm/spec/memory.wast.js b/js/src/jit-test/tests/wasm/spec/memory.wast.js deleted file mode 100644 index 3b26e45a80..0000000000 --- a/js/src/jit-test/tests/wasm/spec/memory.wast.js +++ /dev/null @@ -1,213 +0,0 @@ - -// memory.wast:3 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00"); - -// memory.wast:4 -let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x01"); - -// memory.wast:5 -let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x01\x01\x80\x02"); - -// memory.wast:6 -let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x80\x80\x04"); - -// memory.wast:8 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x02\x00\x00\x00\x00"); - -// memory.wast:9 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00"); - -// memory.wast:11 -let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// memory.wast:12 -assert_return(() => call($5, "memsize", []), 0); - -// memory.wast:13 -let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// memory.wast:14 -assert_return(() => call($6, "memsize", []), 0); - -// memory.wast:15 -let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); - -// memory.wast:16 -assert_return(() => call($7, "memsize", []), 1); - -// memory.wast:18 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// memory.wast:19 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); - -// memory.wast:20 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); - -// memory.wast:22 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2a\x02\x00\x1a\x0b"); - -// memory.wast:26 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x38\x02\x00\x0b"); - -// memory.wast:30 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2c\x00\x00\x1a\x0b"); - -// memory.wast:34 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x41\x00\x3a\x00\x00\x0b"); - -// memory.wast:38 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x3f\x00\x1a\x0b"); - -// memory.wast:42 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x1a\x0b"); - -// memory.wast:48 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x00"); - -// memory.wast:52 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x00\x81\x80\x04"); - -// memory.wast:56 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\x80\x80\x80\x80\x08"); - -// memory.wast:60 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\xff\xff\xff\xff\x0f"); - -// memory.wast:64 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x81\x80\x04"); - -// memory.wast:68 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\x80\x80\x80\x80\x08"); - -// memory.wast:72 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\xff\xff\xff\xff\x0f"); - -// memory.wast:77 -let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x93\x80\x80\x80\x00\x04\x60\x00\x01\x7f\x60\x00\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x03\x8d\x80\x80\x80\x00\x0c\x00\x01\x02\x02\x02\x02\x03\x03\x03\x03\x03\x03\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xa1\x81\x80\x80\x00\x0c\x04\x64\x61\x74\x61\x00\x00\x04\x63\x61\x73\x74\x00\x01\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x02\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x03\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x04\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x05\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x06\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x07\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x08\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x09\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x0a\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x0b\x0a\xcf\x82\x80\x80\x00\x0c\xce\x80\x80\x80\x00\x00\x41\x00\x2d\x00\x00\x41\xc1\x00\x46\x41\x03\x2d\x00\x00\x41\xa7\x01\x46\x71\x41\x06\x2d\x00\x00\x41\x00\x46\x41\x13\x2d\x00\x00\x41\x00\x46\x71\x71\x41\x14\x2d\x00\x00\x41\xd7\x00\x46\x41\x17\x2d\x00\x00\x41\xcd\x00\x46\x71\x41\x18\x2d\x00\x00\x41\x00\x46\x41\xff\x07\x2d\x00\x00\x41\x00\x46\x71\x71\x71\x0b\xb8\x80\x80\x80\x00\x00\x41\x08\x42\xc7\x9f\x7f\x37\x03\x00\x41\x08\x2b\x03\x00\x42\xc7\x9f\x7f\xbf\x61\x04\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0b\x41\x09\x42\x00\x37\x00\x00\x41\x0f\x41\xc5\x80\x01\x3b\x00\x00\x41\x09\x2b\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2c\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2d\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2e\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2f\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x30\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x31\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x32\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x33\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x34\x02\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x35\x02\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x05\x41\x42\x43\xa7\x44\x00\x41\x14\x0b\x04\x57\x41\x53\x4d"); - -// memory.wast:165 -assert_return(() => call($8, "data", []), 1); - -// memory.wast:166 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x38\x04\x63\x61\x73\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x45\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "cast", []), 42.) - -// memory.wast:168 -assert_return(() => call($8, "i32_load8_s", [-1]), -1); - -// memory.wast:169 -assert_return(() => call($8, "i32_load8_u", [-1]), 255); - -// memory.wast:170 -assert_return(() => call($8, "i32_load16_s", [-1]), -1); - -// memory.wast:171 -assert_return(() => call($8, "i32_load16_u", [-1]), 65_535); - -// memory.wast:173 -assert_return(() => call($8, "i32_load8_s", [100]), 100); - -// memory.wast:174 -assert_return(() => call($8, "i32_load8_u", [200]), 200); - -// memory.wast:175 -assert_return(() => call($8, "i32_load16_s", [20_000]), 20_000); - -// memory.wast:176 -assert_return(() => call($8, "i32_load16_u", [40_000]), 40_000); - -// memory.wast:178 -assert_return(() => call($8, "i32_load8_s", [-19_110_589]), 67); - -// memory.wast:179 -assert_return(() => call($8, "i32_load8_s", [878_104_047]), -17); - -// memory.wast:180 -assert_return(() => call($8, "i32_load8_u", [-19_110_589]), 67); - -// memory.wast:181 -assert_return(() => call($8, "i32_load8_u", [878_104_047]), 239); - -// memory.wast:182 -assert_return(() => call($8, "i32_load16_s", [-19_110_589]), 25_923); - -// memory.wast:183 -assert_return(() => call($8, "i32_load16_s", [878_104_047]), -12_817); - -// memory.wast:184 -assert_return(() => call($8, "i32_load16_u", [-19_110_589]), 25_923); - -// memory.wast:185 -assert_return(() => call($8, "i32_load16_u", [878_104_047]), 52_719); - -// memory.wast:187 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_s", [int64("-1")]), int64("-1")) - -// memory.wast:188 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_u", [int64("-1")]), int64("255")) - -// memory.wast:189 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_s", [int64("-1")]), int64("-1")) - -// memory.wast:190 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_u", [int64("-1")]), int64("65_535")) - -// memory.wast:191 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_s", [int64("-1")]), int64("-1")) - -// memory.wast:192 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_u", [int64("-1")]), int64("4_294_967_295")) - -// memory.wast:194 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xe4\x00\x10\x00\x01\x42\xe4\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_s", [int64("100")]), int64("100")) - -// memory.wast:195 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xc8\x01\x10\x00\x01\x42\xc8\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_u", [int64("200")]), int64("200")) - -// memory.wast:196 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_s", [int64("20_000")]), int64("20_000")) - -// memory.wast:197 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_u", [int64("40_000")]), int64("40_000")) - -// memory.wast:198 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_s", [int64("20_000")]), int64("20_000")) - -// memory.wast:199 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_u", [int64("40_000")]), int64("40_000")) - -// memory.wast:201 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_s", [int64("-81_985_529_755_441_853")]), int64("67")) - -// memory.wast:202 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\x6f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_s", [int64("3_771_275_841_602_506_223")]), int64("-17")) - -// memory.wast:203 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_u", [int64("-81_985_529_755_441_853")]), int64("67")) - -// memory.wast:204 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x92\x80\x80\x80\x00\x01\x02\x24\x38\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load8_u", [int64("3_771_275_841_602_506_223")]), int64("239")) - -// memory.wast:205 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_s", [int64("-81_985_529_755_441_853")]), int64("25_923")) - -// memory.wast:206 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_s", [int64("3_771_275_841_602_506_223")]), int64("-12_817")) - -// memory.wast:207 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_u", [int64("-81_985_529_755_441_853")]), int64("25_923")) - -// memory.wast:208 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load16_u", [int64("3_771_275_841_602_506_223")]), int64("52_719")) - -// memory.wast:209 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_s", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) - -// memory.wast:210 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x79\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_s", [int64("3_771_275_841_602_506_223")]), int64("-1_732_588_049")) - -// memory.wast:211 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_u", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) - -// memory.wast:212 -run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x38\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$8", $8)), "run", [])); // assert_return(() => call($8, "i64_load32_u", [int64("3_771_275_841_602_506_223")]), int64("2_562_379_247")) diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/binary.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/binary.wast.js new file mode 100644 index 0000000000..c1de19fa50 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/binary.wast.js @@ -0,0 +1,443 @@ + +// binary.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:2 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:3 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M1 = $3; + +// binary.wast:4 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M2 = $4; + +// binary.wast:6 +assert_malformed(""); + +// binary.wast:7 +assert_malformed("\x01"); + +// binary.wast:8 +assert_malformed("\x00\x61\x73"); + +// binary.wast:9 +assert_malformed("\x61\x73\x6d\x00"); + +// binary.wast:10 +assert_malformed("\x6d\x73\x61\x00"); + +// binary.wast:11 +assert_malformed("\x6d\x73\x61\x00\x01\x00\x00\x00"); + +// binary.wast:12 +assert_malformed("\x6d\x73\x61\x00\x00\x00\x00\x01"); + +// binary.wast:13 +assert_malformed("\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// binary.wast:14 +assert_malformed("\x77\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:15 +assert_malformed("\x7f\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:16 +assert_malformed("\x80\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:17 +assert_malformed("\x82\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:18 +assert_malformed("\xff\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:21 +assert_malformed("\x00\x00\x00\x01\x6d\x73\x61\x00"); + +// binary.wast:24 +assert_malformed("\x61\x00\x6d\x73\x00\x01\x00\x00"); + +// binary.wast:25 +assert_malformed("\x73\x6d\x00\x61\x00\x00\x01\x00"); + +// binary.wast:28 +assert_malformed("\x00\x41\x53\x4d\x01\x00\x00\x00"); + +// binary.wast:31 +assert_malformed("\x00\x81\xa2\x94\x01\x00\x00\x00"); + +// binary.wast:34 +assert_malformed("\xef\xbb\xbf\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:37 +assert_malformed("\x00\x61\x73\x6d"); + +// binary.wast:38 +assert_malformed("\x00\x61\x73\x6d\x01"); + +// binary.wast:39 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00"); + +// binary.wast:40 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x00"); + +// binary.wast:41 +assert_malformed("\x00\x61\x73\x6d\x0d\x00\x00\x00"); + +// binary.wast:42 +assert_malformed("\x00\x61\x73\x6d\x0e\x00\x00\x00"); + +// binary.wast:43 +assert_malformed("\x00\x61\x73\x6d\x00\x01\x00\x00"); + +// binary.wast:44 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x01\x00"); + +// binary.wast:45 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x01"); + +// binary.wast:48 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x04\x01\x00\x82\x00"); + +// binary.wast:53 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x00"); + +// binary.wast:60 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7f\x00\x41\x80\x00\x0b"); + +// binary.wast:67 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7f\x00\x41\xff\x7f\x0b"); + +// binary.wast:74 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:81 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:89 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7e\x00\x42\x80\x00\x0b"); + +// binary.wast:96 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x07\x01\x7e\x00\x42\xff\x7f\x0b"); + +// binary.wast:103 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:110 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:118 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x00\x0b\x06\x01\x00\x41\x00\x0b\x00"); + +// binary.wast:127 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x04\x01\x70\x00\x00\x09\x06\x01\x00\x41\x00\x0b\x00"); + +// binary.wast:137 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x00\x0b\x07\x01\x80\x00\x41\x00\x0b\x00"); + +// binary.wast:147 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x04\x01\x70\x00\x00\x09\x09\x01\x02\x80\x00\x41\x00\x0b\x00\x00"); + +// binary.wast:157 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x08\x01\x00\x82\x80\x80\x80\x80\x00"); + +// binary.wast:167 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:177 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:188 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:198 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:210 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x70"); + +// binary.wast:218 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x40"); + +// binary.wast:228 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x70\x0b"); + +// binary.wast:238 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x0f\x0b"); + +// binary.wast:248 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x1f\x0b"); + +// binary.wast:258 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x4f\x0b"); + +// binary.wast:269 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7e\x0b"); + +// binary.wast:279 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x0b"); + +// binary.wast:289 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02\x0b"); + +// binary.wast:299 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x0b"); + +// binary.wast:311 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7e\x0b"); + +// binary.wast:321 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x0b"); + +// binary.wast:331 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02\x0b"); + +// binary.wast:341 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x0b"); + +// binary.wast:354 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x08\x01\x00\x82\x80\x80\x80\x80\x00"); + +// binary.wast:362 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x28\x02\x82\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:381 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x28\x82\x80\x80\x80\x80\x00\x00\x1a\x0b"); + +// binary.wast:400 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x12\x01\x10\x01\x01\x7f\x41\x00\x41\x03\x36\x82\x80\x80\x80\x80\x00\x03\x0b"); + +// binary.wast:419 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x12\x01\x10\x01\x01\x7f\x41\x00\x41\x03\x36\x02\x82\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:440 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:450 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:461 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:471 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x10\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x0b"); + +// binary.wast:483 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x70"); + +// binary.wast:491 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x07\x01\x00\x82\x80\x80\x80\x40"); + +// binary.wast:499 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x10\x01\x0e\x01\x01\x7f\x41\x00\x28\x02\x82\x80\x80\x80\x10\x1a\x0b"); + +// binary.wast:518 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x10\x01\x0e\x01\x01\x7f\x41\x00\x28\x02\x82\x80\x80\x80\x40\x1a\x0b"); + +// binary.wast:537 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x10\x01\x0e\x01\x01\x7f\x41\x00\x28\x82\x80\x80\x80\x10\x00\x1a\x0b"); + +// binary.wast:555 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x10\x01\x0e\x01\x01\x7f\x41\x00\x28\x82\x80\x80\x80\x40\x00\x1a\x0b"); + +// binary.wast:574 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x41\x03\x36\x82\x80\x80\x80\x10\x03\x0b"); + +// binary.wast:593 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x41\x03\x36\x82\x80\x80\x80\x40\x03\x0b"); + +// binary.wast:612 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x41\x03\x36\x03\x82\x80\x80\x80\x10\x0b"); + +// binary.wast:631 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x01\x0a\x11\x01\x0f\x01\x01\x7f\x41\x00\x41\x03\x36\x02\x82\x80\x80\x80\x40\x0b"); + +// binary.wast:653 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x70\x0b"); + +// binary.wast:663 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x0f\x0b"); + +// binary.wast:673 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\x80\x80\x80\x80\x1f\x0b"); + +// binary.wast:683 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0a\x01\x7f\x00\x41\xff\xff\xff\xff\x4f\x0b"); + +// binary.wast:694 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7e\x0b"); + +// binary.wast:704 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x0b"); + +// binary.wast:714 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x02\x0b"); + +// binary.wast:724 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0f\x01\x7e\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x0b"); + +// binary.wast:736 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x41\x00\x40\x01\x1a\x0b"); + +// binary.wast:756 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x41\x00\x40\x80\x00\x1a\x0b"); + +// binary.wast:776 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x41\x00\x40\x80\x80\x00\x1a\x0b"); + +// binary.wast:795 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0c\x01\x0a\x00\x41\x00\x40\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:814 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0d\x01\x0b\x00\x41\x00\x40\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:834 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x07\x01\x05\x00\x3f\x01\x1a\x0b"); + +// binary.wast:853 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x08\x01\x06\x00\x3f\x80\x00\x1a\x0b"); + +// binary.wast:872 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x3f\x80\x80\x00\x1a\x0b"); + +// binary.wast:890 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x3f\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:908 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x3f\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:927 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0c\x01\x0a\x02\xff\xff\xff\xff\x0f\x7f\x02\x7e\x0b"); + +// binary.wast:944 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0a\x01\x08\x03\x00\x7f\x00\x7e\x02\x7d\x0b"); + +// binary.wast:959 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00"); + +// binary.wast:969 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:978 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:989 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:1000 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x03\x01\x00"); + +// binary.wast:1006 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x01\x00"); + +// binary.wast:1012 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0c\x01\x03\x0b\x05\x02\x01\x00\x01\x00"); + +// binary.wast:1022 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0c\x01\x01\x0b\x05\x02\x01\x00\x01\x00"); + +// binary.wast:1032 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0e\x01\x0c\x00\x41\x00\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x03\x01\x01\x00"); + +// binary.wast:1054 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x07\x01\x05\x00\xfc\x09\x00\x0b\x0b\x03\x01\x01\x00"); + +// binary.wast:1073 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd3\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1099 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x7f\x01\xd2\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1125 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd2\x00\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1149 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x05\x03\x01\x00\x00\x09\x07\x01\x05\x70\x01\xd0\x70\x0b\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1174 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x01\x00"); + +// binary.wast:1180 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x02\x60\x00\x00"); + +// binary.wast:1191 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x00\x00\x60\x00\x00"); + +// binary.wast:1202 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x01\x00"); + +// binary.wast:1210 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x16\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00"); + +// binary.wast:1229 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x09\x02\x60\x01\x7f\x00\x60\x01\x7d\x00\x02\x2b\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x66\x33\x32\x00\x01"); + +// binary.wast:1254 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x00"); + +// binary.wast:1260 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x01"); + +// binary.wast:1270 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x00"); + +// binary.wast:1276 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x01"); + +// binary.wast:1286 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x01\x00"); + +// binary.wast:1292 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x06\x02\x7f\x00\x41\x00\x0b"); + +// binary.wast:1303 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x00\x0b\x7f\x00\x41\x00\x0b"); + +// binary.wast:1314 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:1326 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x06\x02\x02\x66\x31\x00\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:1347 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x0b\x01\x02\x66\x31\x00\x00\x02\x66\x32\x00\x01\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:1368 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1381 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x07\x02\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1399 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x0d\x01\x00\x41\x00\x0b\x01\x00\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1417 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x01\x00"); + +// binary.wast:1425 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x07\x02\x00\x41\x00\x0b\x01\x61"); + +// binary.wast:1438 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0d\x01\x00\x41\x00\x0b\x01\x61\x00\x41\x01\x0b\x01\x62"); + +// binary.wast:1451 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x03\x0b\x07\x61\x62\x63\x64\x65\x66"); + +// binary.wast:1465 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x00\x0b\x05\x61\x62\x63\x64\x65\x66"); + +// binary.wast:1479 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x11\x01\x0f\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x00\x02\x0b\x0b\x0b"); + +// binary.wast:1496 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x10\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x02\x00\x02\x0b\x0b\x0b"); + +// binary.wast:1518 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x11\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x01\x00\x01\x02\x0b\x0b\x0b"); + +// binary.wast:1540 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:1553 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/bulk.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/bulk.wast.js new file mode 100644 index 0000000000..e8046191e5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/bulk.wast.js @@ -0,0 +1,351 @@ + +// bulk.wast:2 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0b\x86\x80\x80\x80\x00\x01\x01\x03\x66\x6f\x6f"); + +// bulk.wast:6 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x03\x09\x8d\x80\x80\x80\x00\x01\x05\x70\x03\xd2\x00\x0b\xd0\x70\x0b\xd2\x01\x0b\x0a\x8f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// bulk.wast:13 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x92\x80\x80\x80\x00\x02\x04\x66\x69\x6c\x6c\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9d\x80\x80\x80\x00\x02\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b"); + +// bulk.wast:27 +run(() => call($3, "fill", [1, 255, 3])); + +// bulk.wast:28 +assert_return(() => call($3, "load8_u", [0]), 0); + +// bulk.wast:29 +assert_return(() => call($3, "load8_u", [1]), 255); + +// bulk.wast:30 +assert_return(() => call($3, "load8_u", [2]), 255); + +// bulk.wast:31 +assert_return(() => call($3, "load8_u", [3]), 255); + +// bulk.wast:32 +assert_return(() => call($3, "load8_u", [4]), 0); + +// bulk.wast:35 +run(() => call($3, "fill", [0, 48_042, 2])); + +// bulk.wast:36 +assert_return(() => call($3, "load8_u", [0]), 170); + +// bulk.wast:37 +assert_return(() => call($3, "load8_u", [1]), 170); + +// bulk.wast:40 +run(() => call($3, "fill", [0, 0, 65_536])); + +// bulk.wast:43 +assert_trap(() => call($3, "fill", [65_280, 1, 257])); + +// bulk.wast:45 +assert_return(() => call($3, "load8_u", [65_280]), 0); + +// bulk.wast:46 +assert_return(() => call($3, "load8_u", [65_535]), 0); + +// bulk.wast:49 +run(() => call($3, "fill", [65_536, 0, 0])); + +// bulk.wast:52 +assert_trap(() => call($3, "fill", [65_537, 0, 0])); + +// bulk.wast:57 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x92\x80\x80\x80\x00\x02\x04\x63\x6f\x70\x79\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x04\xaa\xbb\xcc\xdd"); + +// bulk.wast:71 +run(() => call($4, "copy", [10, 0, 4])); + +// bulk.wast:73 +assert_return(() => call($4, "load8_u", [9]), 0); + +// bulk.wast:74 +assert_return(() => call($4, "load8_u", [10]), 170); + +// bulk.wast:75 +assert_return(() => call($4, "load8_u", [11]), 187); + +// bulk.wast:76 +assert_return(() => call($4, "load8_u", [12]), 204); + +// bulk.wast:77 +assert_return(() => call($4, "load8_u", [13]), 221); + +// bulk.wast:78 +assert_return(() => call($4, "load8_u", [14]), 0); + +// bulk.wast:81 +run(() => call($4, "copy", [8, 10, 4])); + +// bulk.wast:82 +assert_return(() => call($4, "load8_u", [8]), 170); + +// bulk.wast:83 +assert_return(() => call($4, "load8_u", [9]), 187); + +// bulk.wast:84 +assert_return(() => call($4, "load8_u", [10]), 204); + +// bulk.wast:85 +assert_return(() => call($4, "load8_u", [11]), 221); + +// bulk.wast:86 +assert_return(() => call($4, "load8_u", [12]), 204); + +// bulk.wast:87 +assert_return(() => call($4, "load8_u", [13]), 221); + +// bulk.wast:90 +run(() => call($4, "copy", [10, 7, 6])); + +// bulk.wast:91 +assert_return(() => call($4, "load8_u", [10]), 0); + +// bulk.wast:92 +assert_return(() => call($4, "load8_u", [11]), 170); + +// bulk.wast:93 +assert_return(() => call($4, "load8_u", [12]), 187); + +// bulk.wast:94 +assert_return(() => call($4, "load8_u", [13]), 204); + +// bulk.wast:95 +assert_return(() => call($4, "load8_u", [14]), 221); + +// bulk.wast:96 +assert_return(() => call($4, "load8_u", [15]), 204); + +// bulk.wast:97 +assert_return(() => call($4, "load8_u", [16]), 0); + +// bulk.wast:100 +run(() => call($4, "copy", [65_280, 0, 256])); + +// bulk.wast:101 +run(() => call($4, "copy", [65_024, 65_280, 256])); + +// bulk.wast:104 +run(() => call($4, "copy", [65_536, 0, 0])); + +// bulk.wast:105 +run(() => call($4, "copy", [0, 65_536, 0])); + +// bulk.wast:108 +assert_trap(() => call($4, "copy", [65_537, 0, 0])); + +// bulk.wast:110 +assert_trap(() => call($4, "copy", [0, 65_537, 0])); + +// bulk.wast:115 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x92\x80\x80\x80\x00\x02\x04\x69\x6e\x69\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x08\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x01\x04\xaa\xbb\xcc\xdd"); + +// bulk.wast:129 +run(() => call($5, "init", [0, 1, 2])); + +// bulk.wast:130 +assert_return(() => call($5, "load8_u", [0]), 187); + +// bulk.wast:131 +assert_return(() => call($5, "load8_u", [1]), 204); + +// bulk.wast:132 +assert_return(() => call($5, "load8_u", [2]), 0); + +// bulk.wast:135 +run(() => call($5, "init", [65_532, 0, 4])); + +// bulk.wast:138 +assert_trap(() => call($5, "init", [65_534, 0, 3])); + +// bulk.wast:140 +assert_return(() => call($5, "load8_u", [65_534]), 204); + +// bulk.wast:141 +assert_return(() => call($5, "load8_u", [65_535]), 221); + +// bulk.wast:144 +run(() => call($5, "init", [65_536, 0, 0])); + +// bulk.wast:145 +run(() => call($5, "init", [0, 4, 0])); + +// bulk.wast:148 +assert_trap(() => call($5, "init", [65_537, 0, 0])); + +// bulk.wast:150 +assert_trap(() => call($5, "init", [0, 5, 0])); + +// bulk.wast:154 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x85\x80\x80\x80\x00\x04\x00\x01\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xbb\x80\x80\x80\x00\x04\x0c\x64\x72\x6f\x70\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x00\x0c\x69\x6e\x69\x74\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x01\x0b\x64\x72\x6f\x70\x5f\x61\x63\x74\x69\x76\x65\x00\x02\x0b\x69\x6e\x69\x74\x5f\x61\x63\x74\x69\x76\x65\x00\x03\x0c\x81\x80\x80\x80\x00\x02\x0a\xb7\x80\x80\x80\x00\x04\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x08\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x09\x01\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x08\x01\x00\x0b\x0b\x8a\x80\x80\x80\x00\x02\x01\x01\x78\x00\x41\x00\x0b\x01\x78"); + +// bulk.wast:168 +run(() => call($6, "init_passive", [1])); + +// bulk.wast:169 +run(() => call($6, "drop_passive", [])); + +// bulk.wast:170 +run(() => call($6, "drop_passive", [])); + +// bulk.wast:171 +assert_return(() => call($6, "init_passive", [0])); + +// bulk.wast:172 +assert_trap(() => call($6, "init_passive", [1])); + +// bulk.wast:173 +run(() => call($6, "init_passive", [0])); + +// bulk.wast:174 +run(() => call($6, "drop_active", [])); + +// bulk.wast:175 +assert_return(() => call($6, "init_active", [0])); + +// bulk.wast:176 +assert_trap(() => call($6, "init_active", [1])); + +// bulk.wast:177 +run(() => call($6, "init_active", [0])); + +// bulk.wast:181 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0c\x81\x80\x80\x80\x00\x41\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x40\x0b\x0b\x83\x81\x80\x80\x00\x41\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00"); + +// bulk.wast:196 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x01\x07\x67\x6f\x6f\x64\x62\x79\x65"); + +// bulk.wast:199 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x85\x80\x80\x80\x00\x04\x00\x00\x01\x02\x04\x84\x80\x80\x80\x00\x01\x70\x00\x03\x07\x8f\x80\x80\x80\x00\x02\x04\x69\x6e\x69\x74\x00\x02\x04\x63\x61\x6c\x6c\x00\x03\x09\x88\x80\x80\x80\x00\x01\x01\x00\x04\x00\x01\x00\x01\x0a\xb0\x80\x80\x80\x00\x04\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0c\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// bulk.wast:219 +assert_trap(() => call($9, "init", [2, 0, 2])); + +// bulk.wast:221 +assert_trap(() => call($9, "call", [2])); + +// bulk.wast:224 +run(() => call($9, "init", [0, 1, 2])); + +// bulk.wast:225 +assert_return(() => call($9, "call", [0]), 1); + +// bulk.wast:226 +assert_return(() => call($9, "call", [1]), 0); + +// bulk.wast:227 +assert_trap(() => call($9, "call", [2])); + +// bulk.wast:230 +run(() => call($9, "init", [1, 2, 2])); + +// bulk.wast:233 +run(() => call($9, "init", [3, 0, 0])); + +// bulk.wast:234 +run(() => call($9, "init", [0, 4, 0])); + +// bulk.wast:237 +assert_trap(() => call($9, "init", [4, 0, 0])); + +// bulk.wast:239 +assert_trap(() => call($9, "init", [0, 5, 0])); + +// bulk.wast:244 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x86\x80\x80\x80\x00\x05\x00\x00\x01\x00\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x07\xbb\x80\x80\x80\x00\x04\x0c\x64\x72\x6f\x70\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x01\x0c\x69\x6e\x69\x74\x5f\x70\x61\x73\x73\x69\x76\x65\x00\x02\x0b\x64\x72\x6f\x70\x5f\x61\x63\x74\x69\x76\x65\x00\x03\x0b\x69\x6e\x69\x74\x5f\x61\x63\x74\x69\x76\x65\x00\x04\x09\x8b\x80\x80\x80\x00\x02\x01\x00\x01\x00\x00\x41\x00\x0b\x01\x00\x0a\xbe\x80\x80\x80\x00\x05\x82\x80\x80\x80\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x0c\x00\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x01\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x20\x00\xfc\x0c\x01\x00\x0b"); + +// bulk.wast:261 +run(() => call($10, "init_passive", [1])); + +// bulk.wast:262 +run(() => call($10, "drop_passive", [])); + +// bulk.wast:263 +run(() => call($10, "drop_passive", [])); + +// bulk.wast:264 +assert_return(() => call($10, "init_passive", [0])); + +// bulk.wast:265 +assert_trap(() => call($10, "init_passive", [1])); + +// bulk.wast:266 +run(() => call($10, "init_passive", [0])); + +// bulk.wast:267 +run(() => call($10, "drop_active", [])); + +// bulk.wast:268 +assert_return(() => call($10, "init_active", [0])); + +// bulk.wast:269 +assert_trap(() => call($10, "init_active", [1])); + +// bulk.wast:270 +run(() => call($10, "init_active", [0])); + +// bulk.wast:274 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\xc4\x81\x80\x80\x00\x41\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x40\x0b"); + +// bulk.wast:297 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b"); + +// bulk.wast:300 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x01\x02\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x8f\x80\x80\x80\x00\x02\x04\x63\x6f\x70\x79\x00\x03\x04\x63\x61\x6c\x6c\x00\x04\x09\x89\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x03\x00\x01\x02\x0a\xb9\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// bulk.wast:319 +run(() => call($13, "copy", [3, 0, 3])); + +// bulk.wast:321 +assert_return(() => call($13, "call", [3]), 0); + +// bulk.wast:322 +assert_return(() => call($13, "call", [4]), 1); + +// bulk.wast:323 +assert_return(() => call($13, "call", [5]), 2); + +// bulk.wast:326 +run(() => call($13, "copy", [0, 1, 3])); + +// bulk.wast:328 +assert_return(() => call($13, "call", [0]), 1); + +// bulk.wast:329 +assert_return(() => call($13, "call", [1]), 2); + +// bulk.wast:330 +assert_return(() => call($13, "call", [2]), 0); + +// bulk.wast:333 +run(() => call($13, "copy", [2, 0, 3])); + +// bulk.wast:335 +assert_return(() => call($13, "call", [2]), 1); + +// bulk.wast:336 +assert_return(() => call($13, "call", [3]), 2); + +// bulk.wast:337 +assert_return(() => call($13, "call", [4]), 0); + +// bulk.wast:340 +run(() => call($13, "copy", [6, 8, 2])); + +// bulk.wast:341 +run(() => call($13, "copy", [8, 6, 2])); + +// bulk.wast:344 +run(() => call($13, "copy", [10, 0, 0])); + +// bulk.wast:345 +run(() => call($13, "copy", [0, 10, 0])); + +// bulk.wast:348 +assert_trap(() => call($13, "copy", [11, 0, 0])); + +// bulk.wast:350 +assert_trap(() => call($13, "copy", [0, 11, 0])); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/call_indirect.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/call_indirect.wast.js new file mode 100644 index 0000000000..d4cf910c63 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/call_indirect.wast.js @@ -0,0 +1,507 @@ + +// call_indirect.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x98\x81\x80\x80\x00\x1d\x60\x00\x00\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x00\x02\x7c\x7f\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x60\x01\x7d\x01\x7d\x60\x01\x7c\x01\x7c\x60\x02\x7f\x7c\x02\x7f\x7c\x60\x02\x7f\x7e\x02\x7e\x7f\x60\x02\x7d\x7f\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x60\x02\x7c\x7d\x01\x7d\x60\x02\x7e\x7c\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x60\x01\x7d\x01\x7d\x60\x01\x7c\x01\x7c\x60\x04\x7e\x7c\x7f\x7e\x01\x7f\x60\x01\x7e\x01\x7f\x60\x04\x7e\x7c\x7f\x7e\x00\x60\x01\x7e\x00\x60\x00\x02\x7f\x7c\x60\x00\x02\x7e\x7f\x60\x01\x7f\x01\x7e\x60\x01\x7f\x01\x7d\x60\x01\x7f\x01\x7c\x03\xd1\x80\x80\x80\x00\x50\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0d\x0f\x0c\x0e\x10\x11\x12\x13\x00\x01\x02\x03\x04\x05\x02\x01\x02\x03\x04\x01\x02\x03\x04\x05\x18\x19\x0d\x1a\x06\x1b\x1c\x07\x07\x06\x08\x09\x06\x08\x09\x06\x06\x00\x00\x00\x01\x01\x01\x01\x02\x01\x03\x01\x00\x00\x01\x01\x00\x03\x04\x04\x04\x01\x03\x01\x01\x01\x01\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x20\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x8d\x80\x80\x80\x00\x01\x7c\x01\x44\x00\x00\x00\x00\x00\x00\x24\x40\x0b\x07\xc4\x87\x80\x80\x00\x3b\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x14\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x15\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x16\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x17\x0c\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x18\x0a\x74\x79\x70\x65\x2d\x69\x6e\x64\x65\x78\x00\x19\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x1a\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x1b\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x1c\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x1d\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x1e\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x1f\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x20\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x21\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x22\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x23\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x24\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x25\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x26\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x33\x32\x00\x27\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x28\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x29\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x2a\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x2b\x07\x66\x61\x63\x2d\x69\x33\x32\x00\x2c\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x2d\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x2e\x07\x66\x69\x62\x2d\x69\x33\x32\x00\x2f\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x30\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x31\x04\x65\x76\x65\x6e\x00\x32\x03\x6f\x64\x64\x00\x33\x07\x72\x75\x6e\x61\x77\x61\x79\x00\x34\x0e\x6d\x75\x74\x75\x61\x6c\x2d\x72\x75\x6e\x61\x77\x61\x79\x00\x35\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x37\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x38\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x39\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x3a\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x3b\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x3c\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x3d\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x3e\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x3f\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x40\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x41\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x42\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x43\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x44\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x45\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x46\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x47\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x48\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x49\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x4a\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x4b\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x4c\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x4d\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x4e\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x4f\x09\xa6\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x20\x00\x01\x02\x03\x05\x06\x07\x08\x0d\x0b\x0e\x0c\x2a\x2b\x32\x33\x34\x35\x36\x0f\x10\x11\x12\x2c\x2d\x2e\x2f\x30\x31\x04\x09\x0a\x0a\xa1\x8c\x80\x80\x00\x50\x85\x80\x80\x80\x00\x00\x41\xb2\x02\x0b\x85\x80\x80\x80\x00\x00\x42\xe4\x02\x0b\x87\x80\x80\x80\x00\x00\x43\x00\x20\x73\x45\x0b\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\xc8\xae\x40\x0b\x8d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\xc8\xae\x40\x41\x20\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x20\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x01\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\xdd\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x42\x00\x41\x00\x11\x17\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x41\x00\x11\x16\x00\x41\x00\x11\x00\x00\x41\x00\x11\x01\x00\x45\x1a\x41\x00\x11\x01\x00\x45\x1a\x42\x00\x41\x00\x11\x15\x00\x45\x1a\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x41\x00\x11\x14\x00\x45\x1a\x42\x00\x41\x00\x11\x07\x00\x50\x1a\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x01\x11\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x02\x11\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x03\x11\x04\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x1d\x11\x05\x00\x0b\x8a\x80\x80\x80\x00\x00\x42\xe4\x00\x41\x05\x11\x07\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x20\x41\x04\x11\x06\x00\x0b\x8a\x80\x80\x80\x00\x00\x42\xc0\x00\x41\x05\x11\x07\x00\x0b\x8c\x80\x80\x80\x00\x00\x43\xc3\xf5\xa8\x3f\x41\x06\x11\x08\x00\x0b\x90\x80\x80\x80\x00\x00\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\x41\x07\x11\x09\x00\x0b\x8e\x80\x80\x80\x00\x00\x43\x66\x66\x00\x42\x41\x20\x41\x08\x11\x0c\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x20\x42\xc0\x00\x41\x09\x11\x0d\x00\x0b\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x50\x40\x43\x00\x00\x00\x42\x41\x0a\x11\x0e\x00\x0b\x93\x80\x80\x80\x00\x00\x42\xc0\x00\x44\x66\x66\x66\x66\x66\x06\x50\x40\x41\x0b\x11\x0f\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x1d\x11\x05\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x1e\x11\x0a\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x42\x02\x41\x1f\x11\x0b\x00\x0b\x89\x80\x80\x80\x00\x00\x20\x01\x20\x00\x11\x07\x00\x0b\x89\x80\x80\x80\x00\x00\x42\x09\x20\x00\x11\x11\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x09\x20\x00\x11\x10\x00\x0b\x8c\x80\x80\x80\x00\x00\x43\x00\x00\x10\x41\x20\x00\x11\x12\x00\x0b\x90\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x22\x40\x20\x00\x11\x13\x00\x0b\x98\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7e\x42\x01\x05\x20\x00\x20\x00\x42\x01\x7d\x41\x0c\x11\x07\x00\x7e\x0b\x0b\xa2\x80\x80\x80\x00\x00\x20\x00\x42\x01\x58\x04\x7e\x42\x01\x05\x20\x00\x42\x02\x7d\x41\x0d\x11\x07\x00\x20\x00\x42\x01\x7d\x41\x0d\x11\x07\x00\x7c\x0b\x0b\x98\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\x01\x05\x20\x00\x20\x00\x41\x01\x6b\x41\x17\x11\x06\x00\x6c\x0b\x0b\xa3\x80\x80\x80\x00\x00\x20\x00\x43\x00\x00\x00\x00\x5b\x04\x7d\x43\x00\x00\x80\x3f\x05\x20\x00\x20\x00\x43\x00\x00\x80\x3f\x93\x41\x18\x11\x08\x00\x94\x0b\x0b\xaf\x80\x80\x80\x00\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x61\x04\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x05\x20\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xa1\x41\x19\x11\x09\x00\xa2\x0b\x0b\xa2\x80\x80\x80\x00\x00\x20\x00\x41\x01\x4d\x04\x7f\x41\x01\x05\x20\x00\x41\x02\x6b\x41\x1a\x11\x06\x00\x20\x00\x41\x01\x6b\x41\x1a\x11\x06\x00\x6a\x0b\x0b\xae\x80\x80\x80\x00\x00\x20\x00\x43\x00\x00\x80\x3f\x5f\x04\x7d\x43\x00\x00\x80\x3f\x05\x20\x00\x43\x00\x00\x00\x40\x93\x41\x1b\x11\x08\x00\x20\x00\x43\x00\x00\x80\x3f\x93\x41\x1b\x11\x08\x00\x92\x0b\x0b\xbe\x80\x80\x80\x00\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x65\x04\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x05\x20\x00\x44\x00\x00\x00\x00\x00\x00\x00\x40\xa1\x41\x1c\x11\x09\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xa1\x41\x1c\x11\x09\x00\xa0\x0b\x0b\x95\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\x2c\x05\x20\x00\x41\x01\x6b\x41\x0f\x11\x06\x00\x0b\x0b\x96\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\xe3\x00\x05\x20\x00\x41\x01\x6b\x41\x0e\x11\x06\x00\x0b\x0b\x87\x80\x80\x80\x00\x00\x41\x10\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x12\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x11\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x41\x02\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x00\x11\x01\x00\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x03\x41\x00\x11\x01\x00\x1b\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x04\x7f\x41\x01\x05\x41\x02\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x11\x02\x00\x41\x02\x0d\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x11\x01\x00\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7d\x41\x02\x11\x03\x00\x41\x02\x0e\x01\x00\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x11\x01\x00\x0e\x01\x00\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x41\x01\x36\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x03\x11\x04\x00\x39\x03\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x40\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x04\x11\x06\x00\x0f\x0b\x8a\x80\x80\x80\x00\x00\x42\x01\x41\x05\x11\x07\x00\x1a\x0b\x91\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x80\x3f\x41\x06\x11\x08\x00\x0c\x00\x0b\x0b\x96\x80\x80\x80\x00\x01\x01\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x21\x00\x20\x00\x0b\x94\x80\x80\x80\x00\x01\x01\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x22\x00\x0b\x94\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x24\x00\x23\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x28\x02\x00\x0b\x90\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x00\x00\x41\x06\x11\x08\x00\x91\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x41\x0a\x6a\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x04\x11\x06\x00\x6b\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x45\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x41\x0a\x4d\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x04\x11\x06\x00\x47\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x41\x04\x11\x06\x00\xac\x0b\x0b"); + +// call_indirect.wast:471 +assert_return(() => call($1, "type-i32", []), 306); + +// call_indirect.wast:472 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-i64", []), int64("356")) + +// call_indirect.wast:473 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x20\x73\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-f32", []), 3890.) + +// call_indirect.wast:474 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-f64", []), 3940.) + +// call_indirect.wast:475 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x02\x7c\x7f\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x20\x01\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-f64-i32", []), 3940., 32) + +// call_indirect.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x74\x79\x70\x65\x2d\x69\x6e\x64\x65\x78\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-index", []), int64("100")) + +// call_indirect.wast:479 +assert_return(() => call($1, "type-first-i32", []), 32); + +// call_indirect.wast:480 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x8a\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-first-i64", []), int64("64")) + +// call_indirect.wast:481 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x8a\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xc3\xf5\xa8\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-first-f32", []), 1.32000005245) + +// call_indirect.wast:482 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x8a\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-first-f64", []), 1.64) + +// call_indirect.wast:484 +assert_return(() => call($1, "type-second-i32", []), 32); + +// call_indirect.wast:485 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x8b\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-second-i64", []), int64("64")) + +// call_indirect.wast:486 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x8b\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-second-f32", []), 32.) + +// call_indirect.wast:487 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x8b\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x66\x66\x66\x66\x66\x06\x50\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-second-f64", []), 64.1) + +// call_indirect.wast:489 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x02\x7c\x7f\x02\x8c\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x20\x01\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-all-f64-i32", []), 3940., 32) + +// call_indirect.wast:490 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x02\x7f\x7c\x02\x8c\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-all-i32-f64", []), 1, 2.) + +// call_indirect.wast:491 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x02\x7e\x7f\x02\x8c\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "type-all-i32-i64", []), int64("2"), 1) + +// call_indirect.wast:493 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x05\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch", [5, int64("2")]), int64("2")) + +// call_indirect.wast:494 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x05\x42\x05\x10\x00\x01\x42\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch", [5, int64("5")]), int64("5")) + +// call_indirect.wast:495 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x0c\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch", [12, int64("5")]), int64("120")) + +// call_indirect.wast:496 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x0d\x42\x05\x10\x00\x01\x42\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch", [13, int64("5")]), int64("8")) + +// call_indirect.wast:497 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x14\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch", [20, int64("2")]), int64("2")) + +// call_indirect.wast:498 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch", [0, int64("2")])) + +// call_indirect.wast:499 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x0f\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch", [15, int64("2")])) + +// call_indirect.wast:500 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x20\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch", [32, int64("2")])) + +// call_indirect.wast:501 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch", [-1, int64("2")])) + +// call_indirect.wast:502 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa5\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x02\x84\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\xe7\x84\xce\xc2\x04\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch", [1_213_432_423, int64("2")])) + +// call_indirect.wast:504 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x05\x10\x00\x01\x42\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [5]), int64("9")) + +// call_indirect.wast:505 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x0c\x10\x00\x01\x42\x80\x93\x16\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [12]), int64("362_880")) + +// call_indirect.wast:506 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x0d\x10\x00\x01\x42\x37\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [13]), int64("55")) + +// call_indirect.wast:507 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x14\x10\x00\x01\x42\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [20]), int64("9")) + +// call_indirect.wast:508 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x0b\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-i64", [11])) + +// call_indirect.wast:509 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7e\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x16\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-i64", [22])) + +// call_indirect.wast:511 +assert_return(() => call($1, "dispatch-structural-i32", [4]), 9); + +// call_indirect.wast:512 +assert_return(() => call($1, "dispatch-structural-i32", [23]), 362_880); + +// call_indirect.wast:513 +assert_return(() => call($1, "dispatch-structural-i32", [26]), 55); + +// call_indirect.wast:514 +assert_return(() => call($1, "dispatch-structural-i32", [19]), 9); + +// call_indirect.wast:515 +assert_trap(() => call($1, "dispatch-structural-i32", [9])); + +// call_indirect.wast:516 +assert_trap(() => call($1, "dispatch-structural-i32", [21])); + +// call_indirect.wast:518 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x06\x10\x00\xbc\x43\x00\x00\x10\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [6]), 9.) + +// call_indirect.wast:519 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x18\x10\x00\xbc\x43\x00\x30\xb1\x48\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [24]), 362880.) + +// call_indirect.wast:520 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x1b\x10\x00\xbc\x43\x00\x00\x5c\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [27]), 55.) + +// call_indirect.wast:521 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x15\x10\x00\xbc\x43\x00\x00\x10\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [21]), 9.) + +// call_indirect.wast:522 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x08\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f32", [8])) + +// call_indirect.wast:523 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7d\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x13\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f32", [19])) + +// call_indirect.wast:525 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x07\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [7]), 9.) + +// call_indirect.wast:526 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x19\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x26\x16\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [25]), 362880.) + +// call_indirect.wast:527 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x1c\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x80\x4b\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [28]), 55.) + +// call_indirect.wast:528 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x16\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [22]), 9.) + +// call_indirect.wast:529 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x0a\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f64", [10])) + +// call_indirect.wast:530 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7f\x01\x7c\x02\x93\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x12\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f64", [18])) + +// call_indirect.wast:532 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("0")]), int64("1")) + +// call_indirect.wast:533 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("1")]), int64("1")) + +// call_indirect.wast:534 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("5")]), int64("120")) + +// call_indirect.wast:535 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// call_indirect.wast:537 +assert_return(() => call($1, "fac-i32", [0]), 1); + +// call_indirect.wast:538 +assert_return(() => call($1, "fac-i32", [1]), 1); + +// call_indirect.wast:539 +assert_return(() => call($1, "fac-i32", [5]), 120); + +// call_indirect.wast:540 +assert_return(() => call($1, "fac-i32", [10]), 3_628_800); + +// call_indirect.wast:542 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f32", [0.]), 1.) + +// call_indirect.wast:543 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f32", [1.]), 1.) + +// call_indirect.wast:544 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x40\x10\x00\xbc\x43\x00\x00\xf0\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f32", [5.]), 120.) + +// call_indirect.wast:545 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x20\x41\x10\x00\xbc\x43\x00\x7c\x5d\x4a\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f32", [10.]), 3628800.) + +// call_indirect.wast:547 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f64", [0.]), 1.) + +// call_indirect.wast:548 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f64", [1.]), 1.) + +// call_indirect.wast:549 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x14\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x5e\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f64", [5.]), 120.) + +// call_indirect.wast:550 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x24\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x80\xaf\x4b\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fac-f64", [10.]), 3628800.) + +// call_indirect.wast:552 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("0")]), int64("1")) + +// call_indirect.wast:553 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("1")]), int64("1")) + +// call_indirect.wast:554 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("2")]), int64("2")) + +// call_indirect.wast:555 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("5")]), int64("8")) + +// call_indirect.wast:556 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x01\x7e\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x14\x10\x00\x01\x42\xc2\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("20")]), int64("10_946")) + +// call_indirect.wast:558 +assert_return(() => call($1, "fib-i32", [0]), 1); + +// call_indirect.wast:559 +assert_return(() => call($1, "fib-i32", [1]), 1); + +// call_indirect.wast:560 +assert_return(() => call($1, "fib-i32", [2]), 2); + +// call_indirect.wast:561 +assert_return(() => call($1, "fib-i32", [5]), 8); + +// call_indirect.wast:562 +assert_return(() => call($1, "fib-i32", [20]), 10_946); + +// call_indirect.wast:564 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f32", [0.]), 1.) + +// call_indirect.wast:565 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f32", [1.]), 1.) + +// call_indirect.wast:566 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f32", [2.]), 2.) + +// call_indirect.wast:567 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x40\x10\x00\xbc\x43\x00\x00\x00\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f32", [5.]), 8.) + +// call_indirect.wast:568 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x01\x7d\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x41\x10\x00\xbc\x43\x00\x08\x2b\x46\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f32", [20.]), 10946.) + +// call_indirect.wast:570 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f64", [0.]), 1.) + +// call_indirect.wast:571 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f64", [1.]), 1.) + +// call_indirect.wast:572 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f64", [2.]), 2.) + +// call_indirect.wast:573 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x14\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x20\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f64", [5.]), 8.) + +// call_indirect.wast:574 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa4\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x01\x7c\x02\x83\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x61\xc5\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "fib-f64", [20.]), 10946.) + +// call_indirect.wast:576 +assert_return(() => call($1, "even", [0]), 44); + +// call_indirect.wast:577 +assert_return(() => call($1, "even", [1]), 99); + +// call_indirect.wast:578 +assert_return(() => call($1, "even", [100]), 44); + +// call_indirect.wast:579 +assert_return(() => call($1, "even", [77]), 99); + +// call_indirect.wast:580 +assert_return(() => call($1, "odd", [0]), 99); + +// call_indirect.wast:581 +assert_return(() => call($1, "odd", [1]), 44); + +// call_indirect.wast:582 +assert_return(() => call($1, "odd", [200]), 99); + +// call_indirect.wast:583 +assert_return(() => call($1, "odd", [77]), 44); + +// call_indirect.wast:585 +assert_exhaustion(() => call($1, "runaway", [])); + +// call_indirect.wast:586 +assert_exhaustion(() => call($1, "mutual-runaway", [])); + +// call_indirect.wast:588 +assert_return(() => call($1, "as-select-first", []), 306); + +// call_indirect.wast:589 +assert_return(() => call($1, "as-select-mid", []), 2); + +// call_indirect.wast:590 +assert_return(() => call($1, "as-select-last", []), 2); + +// call_indirect.wast:592 +assert_return(() => call($1, "as-if-condition", []), 1); + +// call_indirect.wast:594 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x8a\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-br_if-first", []), int64("356")) + +// call_indirect.wast:595 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// call_indirect.wast:597 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x8d\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x20\x73\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-br_table-first", []), 3890.) + +// call_indirect.wast:598 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// call_indirect.wast:600 +assert_return(() => call($1, "as-store-first", [])); + +// call_indirect.wast:601 +assert_return(() => call($1, "as-store-last", [])); + +// call_indirect.wast:603 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// call_indirect.wast:604 +assert_return(() => call($1, "as-return-value", []), 1); + +// call_indirect.wast:605 +assert_return(() => call($1, "as-drop-operand", [])); + +// call_indirect.wast:606 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x87\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-br-value", []), 1.) + +// call_indirect.wast:607 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x8e\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-local.set-value", []), 1.) + +// call_indirect.wast:608 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x8e\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-local.tee-value", []), 1.) + +// call_indirect.wast:609 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x8f\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-global.set-value", []), 1.) + +// call_indirect.wast:610 +assert_return(() => call($1, "as-load-operand", []), 1); + +// call_indirect.wast:612 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x8c\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 0.) + +// call_indirect.wast:613 +assert_return(() => call($1, "as-binary-left", []), 11); + +// call_indirect.wast:614 +assert_return(() => call($1, "as-binary-right", []), 9); + +// call_indirect.wast:615 +assert_return(() => call($1, "as-test-operand", []), 0); + +// call_indirect.wast:616 +assert_return(() => call($1, "as-compare-left", []), 1); + +// call_indirect.wast:617 +assert_return(() => call($1, "as-compare-right", []), 1); + +// call_indirect.wast:618 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x8e\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "as-convert-operand", []), int64("1")) + +// call_indirect.wast:623 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x91\x80\x80\x80\x00\x03\x60\x02\x7f\x7f\x01\x7f\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x8a\x80\x80\x80\x00\x09\x00\x00\x00\x00\x00\x01\x02\x02\x02\x04\x8c\x80\x80\x80\x00\x03\x70\x01\x02\x02\x70\x01\x03\x03\x70\x00\x04\x07\x9c\x80\x80\x80\x00\x03\x06\x63\x61\x6c\x6c\x2d\x31\x00\x06\x06\x63\x61\x6c\x6c\x2d\x32\x00\x07\x06\x63\x61\x6c\x6c\x2d\x33\x00\x08\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x00\x0b\x02\x00\x01\x02\x01\x41\x00\x0b\x00\x03\x02\x03\x04\x02\x02\x41\x00\x0b\x00\x02\x01\x02\x02\x02\x41\x03\x0b\x00\x01\x05\x0a\xf4\x80\x80\x80\x00\x09\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6a\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6b\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6c\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6e\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x70\x0b\x82\x80\x80\x80\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x11\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x11\x00\x01\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x11\x00\x02\x0b"); + +// call_indirect.wast:650 +assert_return(() => call($2, "call-1", [2, 3, 0]), 5); + +// call_indirect.wast:651 +assert_return(() => call($2, "call-1", [2, 3, 1]), -1); + +// call_indirect.wast:652 +assert_trap(() => call($2, "call-1", [2, 3, 2])); + +// call_indirect.wast:654 +assert_return(() => call($2, "call-2", [2, 3, 0]), 6); + +// call_indirect.wast:655 +assert_return(() => call($2, "call-2", [2, 3, 1]), 0); + +// call_indirect.wast:656 +assert_return(() => call($2, "call-2", [2, 3, 2]), 2); + +// call_indirect.wast:657 +assert_trap(() => call($2, "call-2", [2, 3, 3])); + +// call_indirect.wast:659 +assert_return(() => call($2, "call-3", [2, 3, 0]), -1); + +// call_indirect.wast:660 +assert_return(() => call($2, "call-3", [2, 3, 1]), 6); + +// call_indirect.wast:661 +assert_trap(() => call($2, "call-3", [2, 3, 2])); + +// call_indirect.wast:662 +assert_trap(() => call($2, "call-3", [2, 3, 3])); + +// call_indirect.wast:663 +assert_trap(() => call($2, "call-3", [2, 3, 4])); + +// call_indirect.wast:668 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:680 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:692 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:704 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:716 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:728 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:738 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:745 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:755 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:765 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:775 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:790 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:798 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x45\x0b"); + +// call_indirect.wast:806 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7e\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x45\x0b"); + +// call_indirect.wast:815 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:823 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7c\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:831 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:839 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:850 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x01\x01\x11\x00\x00\x0b"); + +// call_indirect.wast:858 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x42\x01\x11\x00\x00\x0b"); + +// call_indirect.wast:867 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x01\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:877 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:887 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7c\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:897 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7c\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:908 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x97\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:921 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:934 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x97\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8a\x80\x80\x80\x00\x00\x03\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:947 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x03\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:960 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:976 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9d\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:996 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x0b"); + +// call_indirect.wast:1003 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x11\x94\x98\xdb\xe2\x03\x00\x0b"); + +// call_indirect.wast:1014 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x02\x02\x09\x88\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x02\x00\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/custom.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/custom.wast.js new file mode 100644 index 0000000000..2f4c106281 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/custom.wast.js @@ -0,0 +1,33 @@ + +// custom.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x20\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x11\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x00\x10\x00\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x01\x00\x00\x24\x10\x00\x00\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x00\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\xef\xbb\xbf\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\xe2\x8c\xa3\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x1f\x16\x6d\x6f\x64\x75\x6c\x65\x20\x77\x69\x74\x68\x69\x6e\x20\x61\x20\x6d\x6f\x64\x75\x6c\x65\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// custom.wast:14 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x01\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x02\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x03\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x04\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x05\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x06\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x07\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x09\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0a\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0b\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:50 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x1a\x06\x63\x75\x73\x74\x6f\x6d\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x07\x0a\x01\x06\x61\x64\x64\x54\x77\x6f\x00\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:60 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// custom.wast:68 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00"); + +// custom.wast:76 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00\x00\x05\x01\x00\x07\x00\x00"); + +// custom.wast:84 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x26\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:92 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:101 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:114 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// custom.wast:122 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0c\x01\x02\x0b\x06\x01\x00\x41\x00\x0b\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/directives.txt b/js/src/jit-test/tests/wasm/spec/reference-types/directives.txt new file mode 100644 index 0000000000..e03cf225cb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemoryIsSupported(); include:wasm-testharness.js; local-include:harness/sync_index.js; skip-if: !wasmReftypesEnabled() \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/global.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/global.wast.js new file mode 100644 index 0000000000..9d069db1d4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/global.wast.js @@ -0,0 +1,249 @@ + +// global.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xb3\x80\x80\x80\x00\x0c\x60\x02\x7f\x7f\x01\x7f\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x6f\x60\x01\x7f\x00\x60\x01\x7e\x00\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x01\x7d\x00\x60\x01\x7c\x00\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\xaf\x80\x80\x80\x00\x2e\x01\x02\x03\x01\x02\x04\x05\x06\x07\x06\x07\x08\x09\x0a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x0a\x0a\x01\x01\x0b\x01\x01\x0a\x01\x0b\x0b\x01\x01\x01\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\xc7\x80\x80\x80\x00\x0a\x7f\x00\x41\x7e\x0b\x7d\x00\x43\x00\x00\x40\xc0\x0b\x7c\x00\x44\x00\x00\x00\x00\x00\x00\x10\xc0\x0b\x7e\x00\x42\x7b\x0b\x7f\x01\x41\x74\x0b\x7d\x01\x43\x00\x00\x50\xc1\x0b\x7c\x01\x44\x00\x00\x00\x00\x00\x00\x2c\xc0\x0b\x7e\x01\x42\x71\x0b\x6f\x00\xd0\x6f\x0b\x70\x00\xd0\x70\x0b\x07\x8d\x85\x80\x80\x00\x2b\x05\x67\x65\x74\x2d\x61\x00\x00\x05\x67\x65\x74\x2d\x62\x00\x01\x05\x67\x65\x74\x2d\x72\x00\x02\x05\x67\x65\x74\x2d\x78\x00\x03\x05\x67\x65\x74\x2d\x79\x00\x04\x05\x73\x65\x74\x2d\x78\x00\x05\x05\x73\x65\x74\x2d\x79\x00\x06\x05\x67\x65\x74\x2d\x31\x00\x07\x05\x67\x65\x74\x2d\x32\x00\x08\x05\x67\x65\x74\x2d\x35\x00\x09\x05\x67\x65\x74\x2d\x36\x00\x0a\x05\x73\x65\x74\x2d\x35\x00\x0b\x05\x73\x65\x74\x2d\x36\x00\x0c\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x0e\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x0f\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x10\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x11\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x12\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x13\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x14\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x15\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x16\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x17\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x18\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x19\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x1a\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x1c\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x1d\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x1e\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x1f\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x20\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x21\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x22\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x24\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x25\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x26\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x27\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x28\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x29\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x2a\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2b\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2c\x12\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2d\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x1b\x0a\xd2\x84\x80\x80\x00\x2e\x84\x80\x80\x80\x00\x00\x23\x00\x0b\x84\x80\x80\x80\x00\x00\x23\x03\x0b\x84\x80\x80\x80\x00\x00\x23\x08\x0b\x84\x80\x80\x80\x00\x00\x23\x04\x0b\x84\x80\x80\x80\x00\x00\x23\x07\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x04\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x07\x0b\x84\x80\x80\x80\x00\x00\x23\x01\x0b\x84\x80\x80\x80\x00\x00\x23\x02\x0b\x84\x80\x80\x80\x00\x00\x23\x05\x0b\x84\x80\x80\x80\x00\x00\x23\x06\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x05\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x06\x0b\x82\x80\x80\x80\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x23\x04\x41\x02\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x23\x04\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x41\x03\x23\x04\x1b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x23\x04\x10\x0d\x10\x0d\x0b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x10\x0d\x23\x04\x10\x0d\x0b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x10\x0d\x10\x0d\x23\x04\x0b\x0b\x90\x80\x80\x80\x00\x00\x23\x04\x04\x7f\x10\x0d\x41\x02\x05\x10\x0d\x41\x03\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x23\x04\x05\x41\x02\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x41\x02\x05\x23\x04\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x0d\x00\x41\x03\x0f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x0d\x00\x41\x03\x0f\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x0e\x01\x00\x00\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x23\x04\x11\x00\x00\x0b\x0b\x89\x80\x80\x80\x00\x00\x23\x04\x41\x01\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x23\x04\x36\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x23\x04\x28\x02\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x10\x23\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x0f\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x1a\x0b\x89\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x0c\x00\x0b\x0b\x88\x80\x80\x80\x00\x00\x23\x04\x21\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x22\x00\x0b\x88\x80\x80\x80\x00\x00\x23\x04\x24\x04\x23\x04\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x45\x0b\x87\x80\x80\x80\x00\x00\x23\x04\x23\x04\x6c\x0b\x87\x80\x80\x80\x00\x00\x23\x00\x41\x01\x4b\x0b"); + +// global.wast:185 +assert_return(() => call($1, "get-a", []), -2); + +// global.wast:186 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x62\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x7b\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-b", []), int64("-5")) + +// global.wast:187 +assert_return(() => call($1, "get-r", []), null); + +// global.wast:188 +assert_return(() => call($1, "get-x", []), -12); + +// global.wast:189 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x79\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x71\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-y", []), int64("-15")) + +// global.wast:191 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x31\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x40\xc0\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-1", []), -3.) + +// global.wast:192 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\xc0\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-2", []), -4.) + +// global.wast:193 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x35\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x50\xc1\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-5", []), -13.) + +// global.wast:194 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x36\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x2c\xc0\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-6", []), -14.) + +// global.wast:196 +assert_return(() => call($1, "set-x", [6])); + +// global.wast:197 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7e\x00\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x73\x65\x74\x2d\x79\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x42\x07\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "set-y", [int64("7")])) + +// global.wast:198 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7d\x00\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x73\x65\x74\x2d\x35\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x41\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "set-5", [8.])) + +// global.wast:199 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x01\x7c\x00\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x73\x65\x74\x2d\x36\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x22\x40\x10\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "set-6", [9.])) + +// global.wast:201 +assert_return(() => call($1, "get-x", []), 6); + +// global.wast:202 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7e\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x79\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-y", []), int64("7")) + +// global.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7d\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x35\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-5", []), 8.) + +// global.wast:204 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa3\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x00\x01\x7c\x02\x81\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x05\x67\x65\x74\x2d\x36\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "get-6", []), 9.) + +// global.wast:206 +assert_return(() => call($1, "as-select-first", []), 6); + +// global.wast:207 +assert_return(() => call($1, "as-select-mid", []), 2); + +// global.wast:208 +assert_return(() => call($1, "as-select-last", []), 2); + +// global.wast:210 +assert_return(() => call($1, "as-loop-first", []), 6); + +// global.wast:211 +assert_return(() => call($1, "as-loop-mid", []), 6); + +// global.wast:212 +assert_return(() => call($1, "as-loop-last", []), 6); + +// global.wast:214 +assert_return(() => call($1, "as-if-condition", []), 2); + +// global.wast:215 +assert_return(() => call($1, "as-if-then", []), 6); + +// global.wast:216 +assert_return(() => call($1, "as-if-else", []), 6); + +// global.wast:218 +assert_return(() => call($1, "as-br_if-first", []), 6); + +// global.wast:219 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// global.wast:221 +assert_return(() => call($1, "as-br_table-first", []), 6); + +// global.wast:222 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// global.wast:224 +assert_return(() => call($1, "as-call_indirect-first", []), 6); + +// global.wast:225 +assert_return(() => call($1, "as-call_indirect-mid", []), 2); + +// global.wast:226 +assert_trap(() => call($1, "as-call_indirect-last", [])); + +// global.wast:228 +assert_return(() => call($1, "as-store-first", [])); + +// global.wast:229 +assert_return(() => call($1, "as-store-last", [])); + +// global.wast:230 +assert_return(() => call($1, "as-load-operand", []), 1); + +// global.wast:231 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// global.wast:233 +assert_return(() => call($1, "as-call-value", []), 6); + +// global.wast:235 +assert_return(() => call($1, "as-return-value", []), 6); + +// global.wast:236 +assert_return(() => call($1, "as-drop-operand", [])); + +// global.wast:237 +assert_return(() => call($1, "as-br-value", []), 6); + +// global.wast:239 +assert_return(() => call($1, "as-local.set-value", [1]), 6); + +// global.wast:240 +assert_return(() => call($1, "as-local.tee-value", [1]), 6); + +// global.wast:241 +assert_return(() => call($1, "as-global.set-value", []), 6); + +// global.wast:243 +assert_return(() => call($1, "as-unary-operand", []), 0); + +// global.wast:244 +assert_return(() => call($1, "as-binary-operand", []), 36); + +// global.wast:245 +assert_return(() => call($1, "as-compare-operand", []), 1); + +// global.wast:247 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x00\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x24\x00\x0b"); + +// global.wast:253 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x01\x43\x00\x00\x00\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x61\x03\x00"); + +// global.wast:254 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x01\x43\x00\x00\x00\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x61\x03\x00"); + +// global.wast:256 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8a\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x00\x00\x8c\x0b"); + +// global.wast:261 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7d\x00\x20\x00\x0b"); + +// global.wast:266 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8a\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x80\x3f\x8c\x0b"); + +// global.wast:271 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x87\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x01\x0b"); + +// global.wast:276 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x85\x80\x80\x80\x00\x01\x7f\x00\x01\x0b"); + +// global.wast:281 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7f\x00\x43\x00\x00\x00\x00\x0b"); + +// global.wast:286 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x88\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x41\x00\x0b"); + +// global.wast:291 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x84\x80\x80\x80\x00\x01\x7f\x00\x0b"); + +// global.wast:296 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x86\x80\x80\x80\x00\x01\x00\x00\x03\x6f\x00\x06\x86\x80\x80\x80\x00\x01\x70\x00\x23\x00\x0b"); + +// global.wast:301 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x00\x23\x00\x0b"); + +// global.wast:306 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8b\x80\x80\x80\x00\x02\x7f\x00\x23\x01\x0b\x7f\x00\x41\x00\x0b"); + +// global.wast:311 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00"); + +// global.wast:314 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x02"); + +// global.wast:327 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\xff"); + +// global.wast:341 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x0b"); + +// global.wast:344 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x02\x41\x00\x0b"); + +// global.wast:356 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\xff\x41\x00\x0b"); + +// global.wast:370 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x24\x00\x0b"); + +// global.wast:379 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0b\x0b"); + +// global.wast:389 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x03\x40\x24\x00\x0b\x0b"); + +// global.wast:399 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x24\x00\x0b\x0b"); + +// global.wast:409 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x24\x00\x0b\x0b"); + +// global.wast:419 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0c\x00\x0b\x0b"); + +// global.wast:429 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0d\x00\x0b\x0b"); + +// global.wast:439 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0e\x00\x00\x0b\x0b"); + +// global.wast:449 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x24\x00\x0f\x0b"); + +// global.wast:458 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x24\x00\x41\x01\x41\x02\x1b\x0b"); + +// global.wast:467 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x95\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x24\x00\x10\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// global.wast:477 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x24\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// global.wast:496 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// global.wast:500 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// global.wast:504 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/harness/async_index.js b/js/src/jit-test/tests/wasm/spec/reference-types/harness/async_index.js new file mode 100644 index 0000000000..556a39d2ad --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/harness/async_index.js @@ -0,0 +1,416 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +"use strict"; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + }; +})(); + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch (e) { + assert_true( + e instanceof err, + `expected ${err.name}, observed ${e.constructor.name}` + ); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error."); +} + +/****************************************************************************** + ***************************** WAST HARNESS ************************************ + ******************************************************************************/ + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +let externrefs = {}; +let externsym = Symbol("externref"); +function externref(s) { + if (! (s in externrefs)) externrefs[s] = {[externsym]: s}; + return externrefs[s]; +} +function is_externref(x) { + return (x !== null && externsym in x) ? 1 : 0; +} +function is_funcref(x) { + return typeof x === "function" ? 1 : 0; +} +function eq_externref(x, y) { + return x === y ? 1 : 0; +} +function eq_funcref(x, y) { + return x === y ? 1 : 0; +} + +// Default imports. +var registry = {}; + +// All tests run asynchronously and return their results as promises. To ensure +// that all tests execute in the correct order, we chain the promises together +// so that a test is only executed when all previous tests have finished their +// execution. +let chain = Promise.resolve(); + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === "undefined") return; + + chain = chain.then(_ => { + let spectest = { + externref: externref, + is_externref: is_externref, + is_funcref: is_funcref, + eq_externref: eq_externref, + eq_funcref: eq_funcref, + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({ + initial: 10, + maximum: 20, + element: "anyfunc" + }), + memory: new WebAssembly.Memory({ initial: 1, maximum: 2 }) + }; + let handler = { + get(target, prop) { + return prop in target ? target[prop] : {}; + } + }; + registry = new Proxy({ spectest }, handler); + }); + + // This function is called at the end of every generated js test file. By + // adding the chain as a promise_test here we make sure that the WPT harness + // waits for all tests in the chain to finish. + promise_test(_ => chain, testNum() + "Reinitialize the default imports"); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + const test = valid + ? "Test that WebAssembly compilation succeeds" + : "Test that WebAssembly compilation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + let buffer = binary(bytes); + let validated = WebAssembly.validate(buffer); + + uniqueTest(_ => { + assert_equals(valid, validated); + }, test); + + chain = chain.then(_ => WebAssembly.compile(buffer)).then( + module => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return module; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `WebAssembly.compile failed unexpectedly with ${error} at {loc}` + ); + }, test); + } + ); + return chain; +} + +function assert_invalid(bytes) { + module(bytes, EXPECT_INVALID); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports, valid = true) { + const test = valid + ? "Test that WebAssembly instantiation succeeds" + : "Test that WebAssembly instantiation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([imports, chain]) + .then(values => { + let imports = values[0] ? values[0] : registry; + return WebAssembly.instantiate(binary(bytes), imports); + }) + .then( + pair => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return pair.instance; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `unexpected instantiation error, observed ${error} ${loc}` + ); + }, test); + return error; + } + ); + return chain; +} + +function exports(instance) { + return instance.then(inst => { + return { module: inst.exports, spectest: registry.spectest }; + }); +} + +function call(instance, name, args) { + return Promise.all([instance, chain]).then(values => { + return values[0].exports[name](...args); + }); +} + +function run(action) { + const test = "Run a WebAssembly test without special assertions"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + _ => { + uniqueTest(_ => {}, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, "run"); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_trap(action) { + const test = "Test that a WebAssembly code traps"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + result => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof WebAssembly.RuntimeError, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_return(action, expected) { + const test = "Test that a WebAssembly code returns a specific result"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + values => { + uniqueTest(_ => { + let actual = values[0]; + switch (expected) { + case "nan:canonical": + case "nan:arithmetic": + // Note that JS can't reliably distinguish different NaN values, + // so there's no good way to test that it's a canonical NaN. + assert_true(Number.isNaN(actual), `expected NaN, observed ${actual}.`); + return; + case "ref.func": + assert_true(typeof actual === "function", `expected Wasm function, got ${actual}`); + return; + case "ref.any": + assert_true(actual !== null, `expected Wasm reference, got ${actual}`); + return; + default: + assert_equals(actual, expected); + } + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +let StackOverflow; +try { + (function f() { + 1 + f(); + })(); +} catch (e) { + StackOverflow = e.constructor; +} + +function assert_exhaustion(action) { + const test = "Test that a WebAssembly code exhauts the stack space"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof StackOverflow, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_unlinkable(bytes) { + const test = "Test that a WebAssembly module is unlinkable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.LinkError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_uninstantiable(bytes) { + const test = "Test that a WebAssembly module is uninstantiable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.RuntimeError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function register(name, instance) { + const test = + "Test that the exports of a WebAssembly module can be registered"; + const loc = new Error().stack.toString().replace("Error", ""); + let stack = new Error(); + chain = Promise.all([instance, chain]) + .then( + values => { + registry[name] = values[0].exports; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function get(instance, name) { + const test = "Test that an export of a WebAssembly instance can be acquired"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([instance, chain]).then( + values => { + let v = values[0].exports[name]; + return (v instanceof WebAssembly.Global) ? v.value : v; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ); + return chain; +} + diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/reference-types/harness/directives.txt new file mode 100644 index 0000000000..d41243abbb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/harness/directives.txt @@ -0,0 +1 @@ +|jit-test| skip-if: true \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/harness/sync_index.js b/js/src/jit-test/tests/wasm/spec/reference-types/harness/sync_index.js new file mode 100644 index 0000000000..af8957322b --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/harness/sync_index.js @@ -0,0 +1,379 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +'use strict'; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + } +})(); + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch(e) { + assert_true(e instanceof err, `expected ${err.name}, observed ${e.constructor.name}`); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error.") +} + +/****************************************************************************** +***************************** WAST HARNESS ************************************ +******************************************************************************/ + +// For assertions internal to our test harness. +function _assert(x) { + if (!x) { + throw new Error(`Assertion failure: ${x}`); + } +} + +// A simple sum type that can either be a valid Value or an Error. +function Result(type, maybeValue) { + this.value = maybeValue; + this.type = type; +}; + +Result.VALUE = 'VALUE'; +Result.ERROR = 'ERROR'; + +function ValueResult(val) { return new Result(Result.VALUE, val); } +function ErrorResult(err) { return new Result(Result.ERROR, err); } + +Result.prototype.isError = function() { return this.type === Result.ERROR; } + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +let externrefs = {}; +let externsym = Symbol("externref"); +function externref(s) { + if (! (s in externrefs)) externrefs[s] = {[externsym]: s}; + return externrefs[s]; +} +function is_externref(x) { + return (x !== null && externsym in x) ? 1 : 0; +} +function is_funcref(x) { + return typeof x === "function" ? 1 : 0; +} +function eq_externref(x, y) { + return x === y ? 1 : 0; +} +function eq_funcref(x, y) { + return x === y ? 1 : 0; +} + +let $$; + +// Default imports. +var registry = {}; + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === 'undefined') + return; + + let spectest = { + externref: externref, + is_externref: is_externref, + is_funcref: is_funcref, + eq_externref: eq_externref, + eq_funcref: eq_funcref, + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}), + memory: new WebAssembly.Memory({initial: 1, maximum: 2}) + }; + let handler = { + get(target, prop) { + return (prop in target) ? target[prop] : {}; + } + }; + registry = new Proxy({spectest}, handler); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + let buffer = binary(bytes); + let validated; + + try { + validated = WebAssembly.validate(buffer); + } catch (e) { + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + + if (validated !== valid) { + // Try to get a more precise error message from the WebAssembly.CompileError. + try { + new WebAssembly.Module(buffer); + } catch (e) { + if (e instanceof WebAssembly.CompileError) + throw new WebAssembly.CompileError(`WebAssembly.validate error: ${e.toString()}${e.stack}\n`); + else + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + throw new Error(`WebAssembly.validate was expected to fail, but didn't`); + } + + let module; + try { + module = new WebAssembly.Module(buffer); + } catch(e) { + if (valid) + throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}'); + throw e; + } + + return module; +} + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +function assert_invalid(bytes) { + uniqueTest(() => { + try { + module(bytes, /* valid */ false); + throw new Error('did not fail'); + } catch(e) { + assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:"); + } + }, "A wast module that should be invalid or malformed."); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports = registry, valid = true) { + if (imports instanceof Result) { + if (imports.isError()) + return imports; + imports = imports.value; + } + + let err = null; + + let m, i; + try { + let m = module(bytes); + i = new WebAssembly.Instance(m, imports); + } catch(e) { + err = e; + } + + if (valid) { + uniqueTest(() => { + let instantiated = err === null; + assert_true(instantiated, err); + }, "module successfully instantiated"); + } + + return err !== null ? ErrorResult(err) : ValueResult(i); +} + +function register(name, instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return; + + registry[name] = instance.value.exports; +} + +function call(instance, name, args) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let err = null; + let result; + try { + result = instance.value.exports[name](...args); + } catch(e) { + err = e; + } + + return err !== null ? ErrorResult(err) : ValueResult(result); +}; + +function get(instance, name) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let v = instance.value.exports[name]; + return ValueResult((v instanceof WebAssembly.Global) ? v.value : v); +} + +function exports(instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + return ValueResult({ module: instance.value.exports, spectest: registry.spectest }); +} + +function run(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + if (result.isError()) + throw result.value; + }, "A wast test that runs without any special assertion."); +} + +function assert_unlinkable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.LinkError, `expected link error, observed ${e}:`); + } + }, "A wast module that is unlinkable."); +} + +function assert_uninstantiable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that is uninstantiable."); +} + +function assert_trap(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that must trap at runtime."); +} + +let StackOverflow; +try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor } + +function assert_exhaustion(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof StackOverflow, `expected stack overflow error, observed ${e}:`); + } + }, "A wast module that must exhaust the stack space."); +} + +function assert_return(action, expected) { + if (expected instanceof Result) { + if (expected.isError()) + return; + expected = expected.value; + } + + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), `expected success result, got: ${result.value}.`); + let actual = result.value; + switch (expected) { + case "nan:canonical": + case "nan:arithmetic": + // Note that JS can't reliably distinguish different NaN values, + // so there's no good way to test that it's a canonical NaN. + assert_true(Number.isNaN(actual), `expected NaN, observed ${actual}.`); + return; + case "ref.func": + assert_true(typeof actual === "function", `expected Wasm function, got ${actual}`); + return; + case "ref.any": + assert_true(actual !== null, `expected Wasm reference, got ${actual}`); + return; + default: + assert_equals(actual, expected); + } + + }, "A wast module that must return a particular value."); +} + +function assert_return_nan(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), 'expected success result'); + if (!result.isError()) { + assert_true(Number.isNaN(result.value), `expected NaN, observed ${result.value}.`); + }; + }, "A wast module that must return NaN."); +} diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/memory_copy.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/memory_copy.wast.js new file mode 100644 index 0000000000..8866d332e9 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/memory_copy.wast.js @@ -0,0 +1,13350 @@ + +// memory_copy.wast:6 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:15 +run(() => call($1, "test", [])); + +// memory_copy.wast:17 +assert_return(() => call($1, "load8_u", [0]), 0); + +// memory_copy.wast:18 +assert_return(() => call($1, "load8_u", [1]), 0); + +// memory_copy.wast:19 +assert_return(() => call($1, "load8_u", [2]), 3); + +// memory_copy.wast:20 +assert_return(() => call($1, "load8_u", [3]), 1); + +// memory_copy.wast:21 +assert_return(() => call($1, "load8_u", [4]), 4); + +// memory_copy.wast:22 +assert_return(() => call($1, "load8_u", [5]), 1); + +// memory_copy.wast:23 +assert_return(() => call($1, "load8_u", [6]), 0); + +// memory_copy.wast:24 +assert_return(() => call($1, "load8_u", [7]), 0); + +// memory_copy.wast:25 +assert_return(() => call($1, "load8_u", [8]), 0); + +// memory_copy.wast:26 +assert_return(() => call($1, "load8_u", [9]), 0); + +// memory_copy.wast:27 +assert_return(() => call($1, "load8_u", [10]), 0); + +// memory_copy.wast:28 +assert_return(() => call($1, "load8_u", [11]), 0); + +// memory_copy.wast:29 +assert_return(() => call($1, "load8_u", [12]), 7); + +// memory_copy.wast:30 +assert_return(() => call($1, "load8_u", [13]), 5); + +// memory_copy.wast:31 +assert_return(() => call($1, "load8_u", [14]), 2); + +// memory_copy.wast:32 +assert_return(() => call($1, "load8_u", [15]), 3); + +// memory_copy.wast:33 +assert_return(() => call($1, "load8_u", [16]), 6); + +// memory_copy.wast:34 +assert_return(() => call($1, "load8_u", [17]), 0); + +// memory_copy.wast:35 +assert_return(() => call($1, "load8_u", [18]), 0); + +// memory_copy.wast:36 +assert_return(() => call($1, "load8_u", [19]), 0); + +// memory_copy.wast:37 +assert_return(() => call($1, "load8_u", [20]), 0); + +// memory_copy.wast:38 +assert_return(() => call($1, "load8_u", [21]), 0); + +// memory_copy.wast:39 +assert_return(() => call($1, "load8_u", [22]), 0); + +// memory_copy.wast:40 +assert_return(() => call($1, "load8_u", [23]), 0); + +// memory_copy.wast:41 +assert_return(() => call($1, "load8_u", [24]), 0); + +// memory_copy.wast:42 +assert_return(() => call($1, "load8_u", [25]), 0); + +// memory_copy.wast:43 +assert_return(() => call($1, "load8_u", [26]), 0); + +// memory_copy.wast:44 +assert_return(() => call($1, "load8_u", [27]), 0); + +// memory_copy.wast:45 +assert_return(() => call($1, "load8_u", [28]), 0); + +// memory_copy.wast:46 +assert_return(() => call($1, "load8_u", [29]), 0); + +// memory_copy.wast:48 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x02\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:57 +run(() => call($2, "test", [])); + +// memory_copy.wast:59 +assert_return(() => call($2, "load8_u", [0]), 0); + +// memory_copy.wast:60 +assert_return(() => call($2, "load8_u", [1]), 0); + +// memory_copy.wast:61 +assert_return(() => call($2, "load8_u", [2]), 3); + +// memory_copy.wast:62 +assert_return(() => call($2, "load8_u", [3]), 1); + +// memory_copy.wast:63 +assert_return(() => call($2, "load8_u", [4]), 4); + +// memory_copy.wast:64 +assert_return(() => call($2, "load8_u", [5]), 1); + +// memory_copy.wast:65 +assert_return(() => call($2, "load8_u", [6]), 0); + +// memory_copy.wast:66 +assert_return(() => call($2, "load8_u", [7]), 0); + +// memory_copy.wast:67 +assert_return(() => call($2, "load8_u", [8]), 0); + +// memory_copy.wast:68 +assert_return(() => call($2, "load8_u", [9]), 0); + +// memory_copy.wast:69 +assert_return(() => call($2, "load8_u", [10]), 0); + +// memory_copy.wast:70 +assert_return(() => call($2, "load8_u", [11]), 0); + +// memory_copy.wast:71 +assert_return(() => call($2, "load8_u", [12]), 7); + +// memory_copy.wast:72 +assert_return(() => call($2, "load8_u", [13]), 3); + +// memory_copy.wast:73 +assert_return(() => call($2, "load8_u", [14]), 1); + +// memory_copy.wast:74 +assert_return(() => call($2, "load8_u", [15]), 4); + +// memory_copy.wast:75 +assert_return(() => call($2, "load8_u", [16]), 6); + +// memory_copy.wast:76 +assert_return(() => call($2, "load8_u", [17]), 0); + +// memory_copy.wast:77 +assert_return(() => call($2, "load8_u", [18]), 0); + +// memory_copy.wast:78 +assert_return(() => call($2, "load8_u", [19]), 0); + +// memory_copy.wast:79 +assert_return(() => call($2, "load8_u", [20]), 0); + +// memory_copy.wast:80 +assert_return(() => call($2, "load8_u", [21]), 0); + +// memory_copy.wast:81 +assert_return(() => call($2, "load8_u", [22]), 0); + +// memory_copy.wast:82 +assert_return(() => call($2, "load8_u", [23]), 0); + +// memory_copy.wast:83 +assert_return(() => call($2, "load8_u", [24]), 0); + +// memory_copy.wast:84 +assert_return(() => call($2, "load8_u", [25]), 0); + +// memory_copy.wast:85 +assert_return(() => call($2, "load8_u", [26]), 0); + +// memory_copy.wast:86 +assert_return(() => call($2, "load8_u", [27]), 0); + +// memory_copy.wast:87 +assert_return(() => call($2, "load8_u", [28]), 0); + +// memory_copy.wast:88 +assert_return(() => call($2, "load8_u", [29]), 0); + +// memory_copy.wast:90 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x0f\x41\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:99 +run(() => call($3, "test", [])); + +// memory_copy.wast:101 +assert_return(() => call($3, "load8_u", [0]), 0); + +// memory_copy.wast:102 +assert_return(() => call($3, "load8_u", [1]), 0); + +// memory_copy.wast:103 +assert_return(() => call($3, "load8_u", [2]), 3); + +// memory_copy.wast:104 +assert_return(() => call($3, "load8_u", [3]), 1); + +// memory_copy.wast:105 +assert_return(() => call($3, "load8_u", [4]), 4); + +// memory_copy.wast:106 +assert_return(() => call($3, "load8_u", [5]), 1); + +// memory_copy.wast:107 +assert_return(() => call($3, "load8_u", [6]), 0); + +// memory_copy.wast:108 +assert_return(() => call($3, "load8_u", [7]), 0); + +// memory_copy.wast:109 +assert_return(() => call($3, "load8_u", [8]), 0); + +// memory_copy.wast:110 +assert_return(() => call($3, "load8_u", [9]), 0); + +// memory_copy.wast:111 +assert_return(() => call($3, "load8_u", [10]), 0); + +// memory_copy.wast:112 +assert_return(() => call($3, "load8_u", [11]), 0); + +// memory_copy.wast:113 +assert_return(() => call($3, "load8_u", [12]), 7); + +// memory_copy.wast:114 +assert_return(() => call($3, "load8_u", [13]), 5); + +// memory_copy.wast:115 +assert_return(() => call($3, "load8_u", [14]), 2); + +// memory_copy.wast:116 +assert_return(() => call($3, "load8_u", [15]), 3); + +// memory_copy.wast:117 +assert_return(() => call($3, "load8_u", [16]), 6); + +// memory_copy.wast:118 +assert_return(() => call($3, "load8_u", [17]), 0); + +// memory_copy.wast:119 +assert_return(() => call($3, "load8_u", [18]), 0); + +// memory_copy.wast:120 +assert_return(() => call($3, "load8_u", [19]), 0); + +// memory_copy.wast:121 +assert_return(() => call($3, "load8_u", [20]), 0); + +// memory_copy.wast:122 +assert_return(() => call($3, "load8_u", [21]), 0); + +// memory_copy.wast:123 +assert_return(() => call($3, "load8_u", [22]), 0); + +// memory_copy.wast:124 +assert_return(() => call($3, "load8_u", [23]), 0); + +// memory_copy.wast:125 +assert_return(() => call($3, "load8_u", [24]), 0); + +// memory_copy.wast:126 +assert_return(() => call($3, "load8_u", [25]), 3); + +// memory_copy.wast:127 +assert_return(() => call($3, "load8_u", [26]), 6); + +// memory_copy.wast:128 +assert_return(() => call($3, "load8_u", [27]), 0); + +// memory_copy.wast:129 +assert_return(() => call($3, "load8_u", [28]), 0); + +// memory_copy.wast:130 +assert_return(() => call($3, "load8_u", [29]), 0); + +// memory_copy.wast:132 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x19\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:141 +run(() => call($4, "test", [])); + +// memory_copy.wast:143 +assert_return(() => call($4, "load8_u", [0]), 0); + +// memory_copy.wast:144 +assert_return(() => call($4, "load8_u", [1]), 0); + +// memory_copy.wast:145 +assert_return(() => call($4, "load8_u", [2]), 3); + +// memory_copy.wast:146 +assert_return(() => call($4, "load8_u", [3]), 1); + +// memory_copy.wast:147 +assert_return(() => call($4, "load8_u", [4]), 4); + +// memory_copy.wast:148 +assert_return(() => call($4, "load8_u", [5]), 1); + +// memory_copy.wast:149 +assert_return(() => call($4, "load8_u", [6]), 0); + +// memory_copy.wast:150 +assert_return(() => call($4, "load8_u", [7]), 0); + +// memory_copy.wast:151 +assert_return(() => call($4, "load8_u", [8]), 0); + +// memory_copy.wast:152 +assert_return(() => call($4, "load8_u", [9]), 0); + +// memory_copy.wast:153 +assert_return(() => call($4, "load8_u", [10]), 0); + +// memory_copy.wast:154 +assert_return(() => call($4, "load8_u", [11]), 0); + +// memory_copy.wast:155 +assert_return(() => call($4, "load8_u", [12]), 7); + +// memory_copy.wast:156 +assert_return(() => call($4, "load8_u", [13]), 0); + +// memory_copy.wast:157 +assert_return(() => call($4, "load8_u", [14]), 0); + +// memory_copy.wast:158 +assert_return(() => call($4, "load8_u", [15]), 0); + +// memory_copy.wast:159 +assert_return(() => call($4, "load8_u", [16]), 6); + +// memory_copy.wast:160 +assert_return(() => call($4, "load8_u", [17]), 0); + +// memory_copy.wast:161 +assert_return(() => call($4, "load8_u", [18]), 0); + +// memory_copy.wast:162 +assert_return(() => call($4, "load8_u", [19]), 0); + +// memory_copy.wast:163 +assert_return(() => call($4, "load8_u", [20]), 0); + +// memory_copy.wast:164 +assert_return(() => call($4, "load8_u", [21]), 0); + +// memory_copy.wast:165 +assert_return(() => call($4, "load8_u", [22]), 0); + +// memory_copy.wast:166 +assert_return(() => call($4, "load8_u", [23]), 0); + +// memory_copy.wast:167 +assert_return(() => call($4, "load8_u", [24]), 0); + +// memory_copy.wast:168 +assert_return(() => call($4, "load8_u", [25]), 0); + +// memory_copy.wast:169 +assert_return(() => call($4, "load8_u", [26]), 0); + +// memory_copy.wast:170 +assert_return(() => call($4, "load8_u", [27]), 0); + +// memory_copy.wast:171 +assert_return(() => call($4, "load8_u", [28]), 0); + +// memory_copy.wast:172 +assert_return(() => call($4, "load8_u", [29]), 0); + +// memory_copy.wast:174 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x14\x41\x16\x41\x04\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:183 +run(() => call($5, "test", [])); + +// memory_copy.wast:185 +assert_return(() => call($5, "load8_u", [0]), 0); + +// memory_copy.wast:186 +assert_return(() => call($5, "load8_u", [1]), 0); + +// memory_copy.wast:187 +assert_return(() => call($5, "load8_u", [2]), 3); + +// memory_copy.wast:188 +assert_return(() => call($5, "load8_u", [3]), 1); + +// memory_copy.wast:189 +assert_return(() => call($5, "load8_u", [4]), 4); + +// memory_copy.wast:190 +assert_return(() => call($5, "load8_u", [5]), 1); + +// memory_copy.wast:191 +assert_return(() => call($5, "load8_u", [6]), 0); + +// memory_copy.wast:192 +assert_return(() => call($5, "load8_u", [7]), 0); + +// memory_copy.wast:193 +assert_return(() => call($5, "load8_u", [8]), 0); + +// memory_copy.wast:194 +assert_return(() => call($5, "load8_u", [9]), 0); + +// memory_copy.wast:195 +assert_return(() => call($5, "load8_u", [10]), 0); + +// memory_copy.wast:196 +assert_return(() => call($5, "load8_u", [11]), 0); + +// memory_copy.wast:197 +assert_return(() => call($5, "load8_u", [12]), 7); + +// memory_copy.wast:198 +assert_return(() => call($5, "load8_u", [13]), 5); + +// memory_copy.wast:199 +assert_return(() => call($5, "load8_u", [14]), 2); + +// memory_copy.wast:200 +assert_return(() => call($5, "load8_u", [15]), 3); + +// memory_copy.wast:201 +assert_return(() => call($5, "load8_u", [16]), 6); + +// memory_copy.wast:202 +assert_return(() => call($5, "load8_u", [17]), 0); + +// memory_copy.wast:203 +assert_return(() => call($5, "load8_u", [18]), 0); + +// memory_copy.wast:204 +assert_return(() => call($5, "load8_u", [19]), 0); + +// memory_copy.wast:205 +assert_return(() => call($5, "load8_u", [20]), 0); + +// memory_copy.wast:206 +assert_return(() => call($5, "load8_u", [21]), 0); + +// memory_copy.wast:207 +assert_return(() => call($5, "load8_u", [22]), 0); + +// memory_copy.wast:208 +assert_return(() => call($5, "load8_u", [23]), 0); + +// memory_copy.wast:209 +assert_return(() => call($5, "load8_u", [24]), 0); + +// memory_copy.wast:210 +assert_return(() => call($5, "load8_u", [25]), 0); + +// memory_copy.wast:211 +assert_return(() => call($5, "load8_u", [26]), 0); + +// memory_copy.wast:212 +assert_return(() => call($5, "load8_u", [27]), 0); + +// memory_copy.wast:213 +assert_return(() => call($5, "load8_u", [28]), 0); + +// memory_copy.wast:214 +assert_return(() => call($5, "load8_u", [29]), 0); + +// memory_copy.wast:216 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x01\x41\x03\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:225 +run(() => call($6, "test", [])); + +// memory_copy.wast:227 +assert_return(() => call($6, "load8_u", [0]), 0); + +// memory_copy.wast:228 +assert_return(() => call($6, "load8_u", [1]), 0); + +// memory_copy.wast:229 +assert_return(() => call($6, "load8_u", [2]), 3); + +// memory_copy.wast:230 +assert_return(() => call($6, "load8_u", [3]), 1); + +// memory_copy.wast:231 +assert_return(() => call($6, "load8_u", [4]), 4); + +// memory_copy.wast:232 +assert_return(() => call($6, "load8_u", [5]), 1); + +// memory_copy.wast:233 +assert_return(() => call($6, "load8_u", [6]), 0); + +// memory_copy.wast:234 +assert_return(() => call($6, "load8_u", [7]), 0); + +// memory_copy.wast:235 +assert_return(() => call($6, "load8_u", [8]), 0); + +// memory_copy.wast:236 +assert_return(() => call($6, "load8_u", [9]), 0); + +// memory_copy.wast:237 +assert_return(() => call($6, "load8_u", [10]), 0); + +// memory_copy.wast:238 +assert_return(() => call($6, "load8_u", [11]), 0); + +// memory_copy.wast:239 +assert_return(() => call($6, "load8_u", [12]), 7); + +// memory_copy.wast:240 +assert_return(() => call($6, "load8_u", [13]), 5); + +// memory_copy.wast:241 +assert_return(() => call($6, "load8_u", [14]), 2); + +// memory_copy.wast:242 +assert_return(() => call($6, "load8_u", [15]), 3); + +// memory_copy.wast:243 +assert_return(() => call($6, "load8_u", [16]), 6); + +// memory_copy.wast:244 +assert_return(() => call($6, "load8_u", [17]), 0); + +// memory_copy.wast:245 +assert_return(() => call($6, "load8_u", [18]), 0); + +// memory_copy.wast:246 +assert_return(() => call($6, "load8_u", [19]), 0); + +// memory_copy.wast:247 +assert_return(() => call($6, "load8_u", [20]), 0); + +// memory_copy.wast:248 +assert_return(() => call($6, "load8_u", [21]), 0); + +// memory_copy.wast:249 +assert_return(() => call($6, "load8_u", [22]), 0); + +// memory_copy.wast:250 +assert_return(() => call($6, "load8_u", [23]), 0); + +// memory_copy.wast:251 +assert_return(() => call($6, "load8_u", [24]), 0); + +// memory_copy.wast:252 +assert_return(() => call($6, "load8_u", [25]), 0); + +// memory_copy.wast:253 +assert_return(() => call($6, "load8_u", [26]), 3); + +// memory_copy.wast:254 +assert_return(() => call($6, "load8_u", [27]), 1); + +// memory_copy.wast:255 +assert_return(() => call($6, "load8_u", [28]), 0); + +// memory_copy.wast:256 +assert_return(() => call($6, "load8_u", [29]), 0); + +// memory_copy.wast:258 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x0c\x41\x07\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:267 +run(() => call($7, "test", [])); + +// memory_copy.wast:269 +assert_return(() => call($7, "load8_u", [0]), 0); + +// memory_copy.wast:270 +assert_return(() => call($7, "load8_u", [1]), 0); + +// memory_copy.wast:271 +assert_return(() => call($7, "load8_u", [2]), 3); + +// memory_copy.wast:272 +assert_return(() => call($7, "load8_u", [3]), 1); + +// memory_copy.wast:273 +assert_return(() => call($7, "load8_u", [4]), 4); + +// memory_copy.wast:274 +assert_return(() => call($7, "load8_u", [5]), 1); + +// memory_copy.wast:275 +assert_return(() => call($7, "load8_u", [6]), 0); + +// memory_copy.wast:276 +assert_return(() => call($7, "load8_u", [7]), 0); + +// memory_copy.wast:277 +assert_return(() => call($7, "load8_u", [8]), 0); + +// memory_copy.wast:278 +assert_return(() => call($7, "load8_u", [9]), 0); + +// memory_copy.wast:279 +assert_return(() => call($7, "load8_u", [10]), 7); + +// memory_copy.wast:280 +assert_return(() => call($7, "load8_u", [11]), 5); + +// memory_copy.wast:281 +assert_return(() => call($7, "load8_u", [12]), 2); + +// memory_copy.wast:282 +assert_return(() => call($7, "load8_u", [13]), 3); + +// memory_copy.wast:283 +assert_return(() => call($7, "load8_u", [14]), 6); + +// memory_copy.wast:284 +assert_return(() => call($7, "load8_u", [15]), 0); + +// memory_copy.wast:285 +assert_return(() => call($7, "load8_u", [16]), 0); + +// memory_copy.wast:286 +assert_return(() => call($7, "load8_u", [17]), 0); + +// memory_copy.wast:287 +assert_return(() => call($7, "load8_u", [18]), 0); + +// memory_copy.wast:288 +assert_return(() => call($7, "load8_u", [19]), 0); + +// memory_copy.wast:289 +assert_return(() => call($7, "load8_u", [20]), 0); + +// memory_copy.wast:290 +assert_return(() => call($7, "load8_u", [21]), 0); + +// memory_copy.wast:291 +assert_return(() => call($7, "load8_u", [22]), 0); + +// memory_copy.wast:292 +assert_return(() => call($7, "load8_u", [23]), 0); + +// memory_copy.wast:293 +assert_return(() => call($7, "load8_u", [24]), 0); + +// memory_copy.wast:294 +assert_return(() => call($7, "load8_u", [25]), 0); + +// memory_copy.wast:295 +assert_return(() => call($7, "load8_u", [26]), 0); + +// memory_copy.wast:296 +assert_return(() => call($7, "load8_u", [27]), 0); + +// memory_copy.wast:297 +assert_return(() => call($7, "load8_u", [28]), 0); + +// memory_copy.wast:298 +assert_return(() => call($7, "load8_u", [29]), 0); + +// memory_copy.wast:300 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x0a\x41\x07\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06"); + +// memory_copy.wast:309 +run(() => call($8, "test", [])); + +// memory_copy.wast:311 +assert_return(() => call($8, "load8_u", [0]), 0); + +// memory_copy.wast:312 +assert_return(() => call($8, "load8_u", [1]), 0); + +// memory_copy.wast:313 +assert_return(() => call($8, "load8_u", [2]), 3); + +// memory_copy.wast:314 +assert_return(() => call($8, "load8_u", [3]), 1); + +// memory_copy.wast:315 +assert_return(() => call($8, "load8_u", [4]), 4); + +// memory_copy.wast:316 +assert_return(() => call($8, "load8_u", [5]), 1); + +// memory_copy.wast:317 +assert_return(() => call($8, "load8_u", [6]), 0); + +// memory_copy.wast:318 +assert_return(() => call($8, "load8_u", [7]), 0); + +// memory_copy.wast:319 +assert_return(() => call($8, "load8_u", [8]), 0); + +// memory_copy.wast:320 +assert_return(() => call($8, "load8_u", [9]), 0); + +// memory_copy.wast:321 +assert_return(() => call($8, "load8_u", [10]), 0); + +// memory_copy.wast:322 +assert_return(() => call($8, "load8_u", [11]), 0); + +// memory_copy.wast:323 +assert_return(() => call($8, "load8_u", [12]), 0); + +// memory_copy.wast:324 +assert_return(() => call($8, "load8_u", [13]), 0); + +// memory_copy.wast:325 +assert_return(() => call($8, "load8_u", [14]), 7); + +// memory_copy.wast:326 +assert_return(() => call($8, "load8_u", [15]), 5); + +// memory_copy.wast:327 +assert_return(() => call($8, "load8_u", [16]), 2); + +// memory_copy.wast:328 +assert_return(() => call($8, "load8_u", [17]), 3); + +// memory_copy.wast:329 +assert_return(() => call($8, "load8_u", [18]), 6); + +// memory_copy.wast:330 +assert_return(() => call($8, "load8_u", [19]), 0); + +// memory_copy.wast:331 +assert_return(() => call($8, "load8_u", [20]), 0); + +// memory_copy.wast:332 +assert_return(() => call($8, "load8_u", [21]), 0); + +// memory_copy.wast:333 +assert_return(() => call($8, "load8_u", [22]), 0); + +// memory_copy.wast:334 +assert_return(() => call($8, "load8_u", [23]), 0); + +// memory_copy.wast:335 +assert_return(() => call($8, "load8_u", [24]), 0); + +// memory_copy.wast:336 +assert_return(() => call($8, "load8_u", [25]), 0); + +// memory_copy.wast:337 +assert_return(() => call($8, "load8_u", [26]), 0); + +// memory_copy.wast:338 +assert_return(() => call($8, "load8_u", [27]), 0); + +// memory_copy.wast:339 +assert_return(() => call($8, "load8_u", [28]), 0); + +// memory_copy.wast:340 +assert_return(() => call($8, "load8_u", [29]), 0); + +// memory_copy.wast:342 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:350 +assert_trap(() => call($9, "run", [65_516, 0, 40])); + +// memory_copy.wast:353 +assert_return(() => call($9, "load8_u", [0]), 0); + +// memory_copy.wast:354 +assert_return(() => call($9, "load8_u", [1]), 1); + +// memory_copy.wast:355 +assert_return(() => call($9, "load8_u", [2]), 2); + +// memory_copy.wast:356 +assert_return(() => call($9, "load8_u", [3]), 3); + +// memory_copy.wast:357 +assert_return(() => call($9, "load8_u", [4]), 4); + +// memory_copy.wast:358 +assert_return(() => call($9, "load8_u", [5]), 5); + +// memory_copy.wast:359 +assert_return(() => call($9, "load8_u", [6]), 6); + +// memory_copy.wast:360 +assert_return(() => call($9, "load8_u", [7]), 7); + +// memory_copy.wast:361 +assert_return(() => call($9, "load8_u", [8]), 8); + +// memory_copy.wast:362 +assert_return(() => call($9, "load8_u", [9]), 9); + +// memory_copy.wast:363 +assert_return(() => call($9, "load8_u", [10]), 10); + +// memory_copy.wast:364 +assert_return(() => call($9, "load8_u", [11]), 11); + +// memory_copy.wast:365 +assert_return(() => call($9, "load8_u", [12]), 12); + +// memory_copy.wast:366 +assert_return(() => call($9, "load8_u", [13]), 13); + +// memory_copy.wast:367 +assert_return(() => call($9, "load8_u", [14]), 14); + +// memory_copy.wast:368 +assert_return(() => call($9, "load8_u", [15]), 15); + +// memory_copy.wast:369 +assert_return(() => call($9, "load8_u", [16]), 16); + +// memory_copy.wast:370 +assert_return(() => call($9, "load8_u", [17]), 17); + +// memory_copy.wast:371 +assert_return(() => call($9, "load8_u", [18]), 18); + +// memory_copy.wast:372 +assert_return(() => call($9, "load8_u", [19]), 19); + +// memory_copy.wast:373 +assert_return(() => call($9, "load8_u", [218]), 0); + +// memory_copy.wast:374 +assert_return(() => call($9, "load8_u", [417]), 0); + +// memory_copy.wast:375 +assert_return(() => call($9, "load8_u", [616]), 0); + +// memory_copy.wast:376 +assert_return(() => call($9, "load8_u", [815]), 0); + +// memory_copy.wast:377 +assert_return(() => call($9, "load8_u", [1_014]), 0); + +// memory_copy.wast:378 +assert_return(() => call($9, "load8_u", [1_213]), 0); + +// memory_copy.wast:379 +assert_return(() => call($9, "load8_u", [1_412]), 0); + +// memory_copy.wast:380 +assert_return(() => call($9, "load8_u", [1_611]), 0); + +// memory_copy.wast:381 +assert_return(() => call($9, "load8_u", [1_810]), 0); + +// memory_copy.wast:382 +assert_return(() => call($9, "load8_u", [2_009]), 0); + +// memory_copy.wast:383 +assert_return(() => call($9, "load8_u", [2_208]), 0); + +// memory_copy.wast:384 +assert_return(() => call($9, "load8_u", [2_407]), 0); + +// memory_copy.wast:385 +assert_return(() => call($9, "load8_u", [2_606]), 0); + +// memory_copy.wast:386 +assert_return(() => call($9, "load8_u", [2_805]), 0); + +// memory_copy.wast:387 +assert_return(() => call($9, "load8_u", [3_004]), 0); + +// memory_copy.wast:388 +assert_return(() => call($9, "load8_u", [3_203]), 0); + +// memory_copy.wast:389 +assert_return(() => call($9, "load8_u", [3_402]), 0); + +// memory_copy.wast:390 +assert_return(() => call($9, "load8_u", [3_601]), 0); + +// memory_copy.wast:391 +assert_return(() => call($9, "load8_u", [3_800]), 0); + +// memory_copy.wast:392 +assert_return(() => call($9, "load8_u", [3_999]), 0); + +// memory_copy.wast:393 +assert_return(() => call($9, "load8_u", [4_198]), 0); + +// memory_copy.wast:394 +assert_return(() => call($9, "load8_u", [4_397]), 0); + +// memory_copy.wast:395 +assert_return(() => call($9, "load8_u", [4_596]), 0); + +// memory_copy.wast:396 +assert_return(() => call($9, "load8_u", [4_795]), 0); + +// memory_copy.wast:397 +assert_return(() => call($9, "load8_u", [4_994]), 0); + +// memory_copy.wast:398 +assert_return(() => call($9, "load8_u", [5_193]), 0); + +// memory_copy.wast:399 +assert_return(() => call($9, "load8_u", [5_392]), 0); + +// memory_copy.wast:400 +assert_return(() => call($9, "load8_u", [5_591]), 0); + +// memory_copy.wast:401 +assert_return(() => call($9, "load8_u", [5_790]), 0); + +// memory_copy.wast:402 +assert_return(() => call($9, "load8_u", [5_989]), 0); + +// memory_copy.wast:403 +assert_return(() => call($9, "load8_u", [6_188]), 0); + +// memory_copy.wast:404 +assert_return(() => call($9, "load8_u", [6_387]), 0); + +// memory_copy.wast:405 +assert_return(() => call($9, "load8_u", [6_586]), 0); + +// memory_copy.wast:406 +assert_return(() => call($9, "load8_u", [6_785]), 0); + +// memory_copy.wast:407 +assert_return(() => call($9, "load8_u", [6_984]), 0); + +// memory_copy.wast:408 +assert_return(() => call($9, "load8_u", [7_183]), 0); + +// memory_copy.wast:409 +assert_return(() => call($9, "load8_u", [7_382]), 0); + +// memory_copy.wast:410 +assert_return(() => call($9, "load8_u", [7_581]), 0); + +// memory_copy.wast:411 +assert_return(() => call($9, "load8_u", [7_780]), 0); + +// memory_copy.wast:412 +assert_return(() => call($9, "load8_u", [7_979]), 0); + +// memory_copy.wast:413 +assert_return(() => call($9, "load8_u", [8_178]), 0); + +// memory_copy.wast:414 +assert_return(() => call($9, "load8_u", [8_377]), 0); + +// memory_copy.wast:415 +assert_return(() => call($9, "load8_u", [8_576]), 0); + +// memory_copy.wast:416 +assert_return(() => call($9, "load8_u", [8_775]), 0); + +// memory_copy.wast:417 +assert_return(() => call($9, "load8_u", [8_974]), 0); + +// memory_copy.wast:418 +assert_return(() => call($9, "load8_u", [9_173]), 0); + +// memory_copy.wast:419 +assert_return(() => call($9, "load8_u", [9_372]), 0); + +// memory_copy.wast:420 +assert_return(() => call($9, "load8_u", [9_571]), 0); + +// memory_copy.wast:421 +assert_return(() => call($9, "load8_u", [9_770]), 0); + +// memory_copy.wast:422 +assert_return(() => call($9, "load8_u", [9_969]), 0); + +// memory_copy.wast:423 +assert_return(() => call($9, "load8_u", [10_168]), 0); + +// memory_copy.wast:424 +assert_return(() => call($9, "load8_u", [10_367]), 0); + +// memory_copy.wast:425 +assert_return(() => call($9, "load8_u", [10_566]), 0); + +// memory_copy.wast:426 +assert_return(() => call($9, "load8_u", [10_765]), 0); + +// memory_copy.wast:427 +assert_return(() => call($9, "load8_u", [10_964]), 0); + +// memory_copy.wast:428 +assert_return(() => call($9, "load8_u", [11_163]), 0); + +// memory_copy.wast:429 +assert_return(() => call($9, "load8_u", [11_362]), 0); + +// memory_copy.wast:430 +assert_return(() => call($9, "load8_u", [11_561]), 0); + +// memory_copy.wast:431 +assert_return(() => call($9, "load8_u", [11_760]), 0); + +// memory_copy.wast:432 +assert_return(() => call($9, "load8_u", [11_959]), 0); + +// memory_copy.wast:433 +assert_return(() => call($9, "load8_u", [12_158]), 0); + +// memory_copy.wast:434 +assert_return(() => call($9, "load8_u", [12_357]), 0); + +// memory_copy.wast:435 +assert_return(() => call($9, "load8_u", [12_556]), 0); + +// memory_copy.wast:436 +assert_return(() => call($9, "load8_u", [12_755]), 0); + +// memory_copy.wast:437 +assert_return(() => call($9, "load8_u", [12_954]), 0); + +// memory_copy.wast:438 +assert_return(() => call($9, "load8_u", [13_153]), 0); + +// memory_copy.wast:439 +assert_return(() => call($9, "load8_u", [13_352]), 0); + +// memory_copy.wast:440 +assert_return(() => call($9, "load8_u", [13_551]), 0); + +// memory_copy.wast:441 +assert_return(() => call($9, "load8_u", [13_750]), 0); + +// memory_copy.wast:442 +assert_return(() => call($9, "load8_u", [13_949]), 0); + +// memory_copy.wast:443 +assert_return(() => call($9, "load8_u", [14_148]), 0); + +// memory_copy.wast:444 +assert_return(() => call($9, "load8_u", [14_347]), 0); + +// memory_copy.wast:445 +assert_return(() => call($9, "load8_u", [14_546]), 0); + +// memory_copy.wast:446 +assert_return(() => call($9, "load8_u", [14_745]), 0); + +// memory_copy.wast:447 +assert_return(() => call($9, "load8_u", [14_944]), 0); + +// memory_copy.wast:448 +assert_return(() => call($9, "load8_u", [15_143]), 0); + +// memory_copy.wast:449 +assert_return(() => call($9, "load8_u", [15_342]), 0); + +// memory_copy.wast:450 +assert_return(() => call($9, "load8_u", [15_541]), 0); + +// memory_copy.wast:451 +assert_return(() => call($9, "load8_u", [15_740]), 0); + +// memory_copy.wast:452 +assert_return(() => call($9, "load8_u", [15_939]), 0); + +// memory_copy.wast:453 +assert_return(() => call($9, "load8_u", [16_138]), 0); + +// memory_copy.wast:454 +assert_return(() => call($9, "load8_u", [16_337]), 0); + +// memory_copy.wast:455 +assert_return(() => call($9, "load8_u", [16_536]), 0); + +// memory_copy.wast:456 +assert_return(() => call($9, "load8_u", [16_735]), 0); + +// memory_copy.wast:457 +assert_return(() => call($9, "load8_u", [16_934]), 0); + +// memory_copy.wast:458 +assert_return(() => call($9, "load8_u", [17_133]), 0); + +// memory_copy.wast:459 +assert_return(() => call($9, "load8_u", [17_332]), 0); + +// memory_copy.wast:460 +assert_return(() => call($9, "load8_u", [17_531]), 0); + +// memory_copy.wast:461 +assert_return(() => call($9, "load8_u", [17_730]), 0); + +// memory_copy.wast:462 +assert_return(() => call($9, "load8_u", [17_929]), 0); + +// memory_copy.wast:463 +assert_return(() => call($9, "load8_u", [18_128]), 0); + +// memory_copy.wast:464 +assert_return(() => call($9, "load8_u", [18_327]), 0); + +// memory_copy.wast:465 +assert_return(() => call($9, "load8_u", [18_526]), 0); + +// memory_copy.wast:466 +assert_return(() => call($9, "load8_u", [18_725]), 0); + +// memory_copy.wast:467 +assert_return(() => call($9, "load8_u", [18_924]), 0); + +// memory_copy.wast:468 +assert_return(() => call($9, "load8_u", [19_123]), 0); + +// memory_copy.wast:469 +assert_return(() => call($9, "load8_u", [19_322]), 0); + +// memory_copy.wast:470 +assert_return(() => call($9, "load8_u", [19_521]), 0); + +// memory_copy.wast:471 +assert_return(() => call($9, "load8_u", [19_720]), 0); + +// memory_copy.wast:472 +assert_return(() => call($9, "load8_u", [19_919]), 0); + +// memory_copy.wast:473 +assert_return(() => call($9, "load8_u", [20_118]), 0); + +// memory_copy.wast:474 +assert_return(() => call($9, "load8_u", [20_317]), 0); + +// memory_copy.wast:475 +assert_return(() => call($9, "load8_u", [20_516]), 0); + +// memory_copy.wast:476 +assert_return(() => call($9, "load8_u", [20_715]), 0); + +// memory_copy.wast:477 +assert_return(() => call($9, "load8_u", [20_914]), 0); + +// memory_copy.wast:478 +assert_return(() => call($9, "load8_u", [21_113]), 0); + +// memory_copy.wast:479 +assert_return(() => call($9, "load8_u", [21_312]), 0); + +// memory_copy.wast:480 +assert_return(() => call($9, "load8_u", [21_511]), 0); + +// memory_copy.wast:481 +assert_return(() => call($9, "load8_u", [21_710]), 0); + +// memory_copy.wast:482 +assert_return(() => call($9, "load8_u", [21_909]), 0); + +// memory_copy.wast:483 +assert_return(() => call($9, "load8_u", [22_108]), 0); + +// memory_copy.wast:484 +assert_return(() => call($9, "load8_u", [22_307]), 0); + +// memory_copy.wast:485 +assert_return(() => call($9, "load8_u", [22_506]), 0); + +// memory_copy.wast:486 +assert_return(() => call($9, "load8_u", [22_705]), 0); + +// memory_copy.wast:487 +assert_return(() => call($9, "load8_u", [22_904]), 0); + +// memory_copy.wast:488 +assert_return(() => call($9, "load8_u", [23_103]), 0); + +// memory_copy.wast:489 +assert_return(() => call($9, "load8_u", [23_302]), 0); + +// memory_copy.wast:490 +assert_return(() => call($9, "load8_u", [23_501]), 0); + +// memory_copy.wast:491 +assert_return(() => call($9, "load8_u", [23_700]), 0); + +// memory_copy.wast:492 +assert_return(() => call($9, "load8_u", [23_899]), 0); + +// memory_copy.wast:493 +assert_return(() => call($9, "load8_u", [24_098]), 0); + +// memory_copy.wast:494 +assert_return(() => call($9, "load8_u", [24_297]), 0); + +// memory_copy.wast:495 +assert_return(() => call($9, "load8_u", [24_496]), 0); + +// memory_copy.wast:496 +assert_return(() => call($9, "load8_u", [24_695]), 0); + +// memory_copy.wast:497 +assert_return(() => call($9, "load8_u", [24_894]), 0); + +// memory_copy.wast:498 +assert_return(() => call($9, "load8_u", [25_093]), 0); + +// memory_copy.wast:499 +assert_return(() => call($9, "load8_u", [25_292]), 0); + +// memory_copy.wast:500 +assert_return(() => call($9, "load8_u", [25_491]), 0); + +// memory_copy.wast:501 +assert_return(() => call($9, "load8_u", [25_690]), 0); + +// memory_copy.wast:502 +assert_return(() => call($9, "load8_u", [25_889]), 0); + +// memory_copy.wast:503 +assert_return(() => call($9, "load8_u", [26_088]), 0); + +// memory_copy.wast:504 +assert_return(() => call($9, "load8_u", [26_287]), 0); + +// memory_copy.wast:505 +assert_return(() => call($9, "load8_u", [26_486]), 0); + +// memory_copy.wast:506 +assert_return(() => call($9, "load8_u", [26_685]), 0); + +// memory_copy.wast:507 +assert_return(() => call($9, "load8_u", [26_884]), 0); + +// memory_copy.wast:508 +assert_return(() => call($9, "load8_u", [27_083]), 0); + +// memory_copy.wast:509 +assert_return(() => call($9, "load8_u", [27_282]), 0); + +// memory_copy.wast:510 +assert_return(() => call($9, "load8_u", [27_481]), 0); + +// memory_copy.wast:511 +assert_return(() => call($9, "load8_u", [27_680]), 0); + +// memory_copy.wast:512 +assert_return(() => call($9, "load8_u", [27_879]), 0); + +// memory_copy.wast:513 +assert_return(() => call($9, "load8_u", [28_078]), 0); + +// memory_copy.wast:514 +assert_return(() => call($9, "load8_u", [28_277]), 0); + +// memory_copy.wast:515 +assert_return(() => call($9, "load8_u", [28_476]), 0); + +// memory_copy.wast:516 +assert_return(() => call($9, "load8_u", [28_675]), 0); + +// memory_copy.wast:517 +assert_return(() => call($9, "load8_u", [28_874]), 0); + +// memory_copy.wast:518 +assert_return(() => call($9, "load8_u", [29_073]), 0); + +// memory_copy.wast:519 +assert_return(() => call($9, "load8_u", [29_272]), 0); + +// memory_copy.wast:520 +assert_return(() => call($9, "load8_u", [29_471]), 0); + +// memory_copy.wast:521 +assert_return(() => call($9, "load8_u", [29_670]), 0); + +// memory_copy.wast:522 +assert_return(() => call($9, "load8_u", [29_869]), 0); + +// memory_copy.wast:523 +assert_return(() => call($9, "load8_u", [30_068]), 0); + +// memory_copy.wast:524 +assert_return(() => call($9, "load8_u", [30_267]), 0); + +// memory_copy.wast:525 +assert_return(() => call($9, "load8_u", [30_466]), 0); + +// memory_copy.wast:526 +assert_return(() => call($9, "load8_u", [30_665]), 0); + +// memory_copy.wast:527 +assert_return(() => call($9, "load8_u", [30_864]), 0); + +// memory_copy.wast:528 +assert_return(() => call($9, "load8_u", [31_063]), 0); + +// memory_copy.wast:529 +assert_return(() => call($9, "load8_u", [31_262]), 0); + +// memory_copy.wast:530 +assert_return(() => call($9, "load8_u", [31_461]), 0); + +// memory_copy.wast:531 +assert_return(() => call($9, "load8_u", [31_660]), 0); + +// memory_copy.wast:532 +assert_return(() => call($9, "load8_u", [31_859]), 0); + +// memory_copy.wast:533 +assert_return(() => call($9, "load8_u", [32_058]), 0); + +// memory_copy.wast:534 +assert_return(() => call($9, "load8_u", [32_257]), 0); + +// memory_copy.wast:535 +assert_return(() => call($9, "load8_u", [32_456]), 0); + +// memory_copy.wast:536 +assert_return(() => call($9, "load8_u", [32_655]), 0); + +// memory_copy.wast:537 +assert_return(() => call($9, "load8_u", [32_854]), 0); + +// memory_copy.wast:538 +assert_return(() => call($9, "load8_u", [33_053]), 0); + +// memory_copy.wast:539 +assert_return(() => call($9, "load8_u", [33_252]), 0); + +// memory_copy.wast:540 +assert_return(() => call($9, "load8_u", [33_451]), 0); + +// memory_copy.wast:541 +assert_return(() => call($9, "load8_u", [33_650]), 0); + +// memory_copy.wast:542 +assert_return(() => call($9, "load8_u", [33_849]), 0); + +// memory_copy.wast:543 +assert_return(() => call($9, "load8_u", [34_048]), 0); + +// memory_copy.wast:544 +assert_return(() => call($9, "load8_u", [34_247]), 0); + +// memory_copy.wast:545 +assert_return(() => call($9, "load8_u", [34_446]), 0); + +// memory_copy.wast:546 +assert_return(() => call($9, "load8_u", [34_645]), 0); + +// memory_copy.wast:547 +assert_return(() => call($9, "load8_u", [34_844]), 0); + +// memory_copy.wast:548 +assert_return(() => call($9, "load8_u", [35_043]), 0); + +// memory_copy.wast:549 +assert_return(() => call($9, "load8_u", [35_242]), 0); + +// memory_copy.wast:550 +assert_return(() => call($9, "load8_u", [35_441]), 0); + +// memory_copy.wast:551 +assert_return(() => call($9, "load8_u", [35_640]), 0); + +// memory_copy.wast:552 +assert_return(() => call($9, "load8_u", [35_839]), 0); + +// memory_copy.wast:553 +assert_return(() => call($9, "load8_u", [36_038]), 0); + +// memory_copy.wast:554 +assert_return(() => call($9, "load8_u", [36_237]), 0); + +// memory_copy.wast:555 +assert_return(() => call($9, "load8_u", [36_436]), 0); + +// memory_copy.wast:556 +assert_return(() => call($9, "load8_u", [36_635]), 0); + +// memory_copy.wast:557 +assert_return(() => call($9, "load8_u", [36_834]), 0); + +// memory_copy.wast:558 +assert_return(() => call($9, "load8_u", [37_033]), 0); + +// memory_copy.wast:559 +assert_return(() => call($9, "load8_u", [37_232]), 0); + +// memory_copy.wast:560 +assert_return(() => call($9, "load8_u", [37_431]), 0); + +// memory_copy.wast:561 +assert_return(() => call($9, "load8_u", [37_630]), 0); + +// memory_copy.wast:562 +assert_return(() => call($9, "load8_u", [37_829]), 0); + +// memory_copy.wast:563 +assert_return(() => call($9, "load8_u", [38_028]), 0); + +// memory_copy.wast:564 +assert_return(() => call($9, "load8_u", [38_227]), 0); + +// memory_copy.wast:565 +assert_return(() => call($9, "load8_u", [38_426]), 0); + +// memory_copy.wast:566 +assert_return(() => call($9, "load8_u", [38_625]), 0); + +// memory_copy.wast:567 +assert_return(() => call($9, "load8_u", [38_824]), 0); + +// memory_copy.wast:568 +assert_return(() => call($9, "load8_u", [39_023]), 0); + +// memory_copy.wast:569 +assert_return(() => call($9, "load8_u", [39_222]), 0); + +// memory_copy.wast:570 +assert_return(() => call($9, "load8_u", [39_421]), 0); + +// memory_copy.wast:571 +assert_return(() => call($9, "load8_u", [39_620]), 0); + +// memory_copy.wast:572 +assert_return(() => call($9, "load8_u", [39_819]), 0); + +// memory_copy.wast:573 +assert_return(() => call($9, "load8_u", [40_018]), 0); + +// memory_copy.wast:574 +assert_return(() => call($9, "load8_u", [40_217]), 0); + +// memory_copy.wast:575 +assert_return(() => call($9, "load8_u", [40_416]), 0); + +// memory_copy.wast:576 +assert_return(() => call($9, "load8_u", [40_615]), 0); + +// memory_copy.wast:577 +assert_return(() => call($9, "load8_u", [40_814]), 0); + +// memory_copy.wast:578 +assert_return(() => call($9, "load8_u", [41_013]), 0); + +// memory_copy.wast:579 +assert_return(() => call($9, "load8_u", [41_212]), 0); + +// memory_copy.wast:580 +assert_return(() => call($9, "load8_u", [41_411]), 0); + +// memory_copy.wast:581 +assert_return(() => call($9, "load8_u", [41_610]), 0); + +// memory_copy.wast:582 +assert_return(() => call($9, "load8_u", [41_809]), 0); + +// memory_copy.wast:583 +assert_return(() => call($9, "load8_u", [42_008]), 0); + +// memory_copy.wast:584 +assert_return(() => call($9, "load8_u", [42_207]), 0); + +// memory_copy.wast:585 +assert_return(() => call($9, "load8_u", [42_406]), 0); + +// memory_copy.wast:586 +assert_return(() => call($9, "load8_u", [42_605]), 0); + +// memory_copy.wast:587 +assert_return(() => call($9, "load8_u", [42_804]), 0); + +// memory_copy.wast:588 +assert_return(() => call($9, "load8_u", [43_003]), 0); + +// memory_copy.wast:589 +assert_return(() => call($9, "load8_u", [43_202]), 0); + +// memory_copy.wast:590 +assert_return(() => call($9, "load8_u", [43_401]), 0); + +// memory_copy.wast:591 +assert_return(() => call($9, "load8_u", [43_600]), 0); + +// memory_copy.wast:592 +assert_return(() => call($9, "load8_u", [43_799]), 0); + +// memory_copy.wast:593 +assert_return(() => call($9, "load8_u", [43_998]), 0); + +// memory_copy.wast:594 +assert_return(() => call($9, "load8_u", [44_197]), 0); + +// memory_copy.wast:595 +assert_return(() => call($9, "load8_u", [44_396]), 0); + +// memory_copy.wast:596 +assert_return(() => call($9, "load8_u", [44_595]), 0); + +// memory_copy.wast:597 +assert_return(() => call($9, "load8_u", [44_794]), 0); + +// memory_copy.wast:598 +assert_return(() => call($9, "load8_u", [44_993]), 0); + +// memory_copy.wast:599 +assert_return(() => call($9, "load8_u", [45_192]), 0); + +// memory_copy.wast:600 +assert_return(() => call($9, "load8_u", [45_391]), 0); + +// memory_copy.wast:601 +assert_return(() => call($9, "load8_u", [45_590]), 0); + +// memory_copy.wast:602 +assert_return(() => call($9, "load8_u", [45_789]), 0); + +// memory_copy.wast:603 +assert_return(() => call($9, "load8_u", [45_988]), 0); + +// memory_copy.wast:604 +assert_return(() => call($9, "load8_u", [46_187]), 0); + +// memory_copy.wast:605 +assert_return(() => call($9, "load8_u", [46_386]), 0); + +// memory_copy.wast:606 +assert_return(() => call($9, "load8_u", [46_585]), 0); + +// memory_copy.wast:607 +assert_return(() => call($9, "load8_u", [46_784]), 0); + +// memory_copy.wast:608 +assert_return(() => call($9, "load8_u", [46_983]), 0); + +// memory_copy.wast:609 +assert_return(() => call($9, "load8_u", [47_182]), 0); + +// memory_copy.wast:610 +assert_return(() => call($9, "load8_u", [47_381]), 0); + +// memory_copy.wast:611 +assert_return(() => call($9, "load8_u", [47_580]), 0); + +// memory_copy.wast:612 +assert_return(() => call($9, "load8_u", [47_779]), 0); + +// memory_copy.wast:613 +assert_return(() => call($9, "load8_u", [47_978]), 0); + +// memory_copy.wast:614 +assert_return(() => call($9, "load8_u", [48_177]), 0); + +// memory_copy.wast:615 +assert_return(() => call($9, "load8_u", [48_376]), 0); + +// memory_copy.wast:616 +assert_return(() => call($9, "load8_u", [48_575]), 0); + +// memory_copy.wast:617 +assert_return(() => call($9, "load8_u", [48_774]), 0); + +// memory_copy.wast:618 +assert_return(() => call($9, "load8_u", [48_973]), 0); + +// memory_copy.wast:619 +assert_return(() => call($9, "load8_u", [49_172]), 0); + +// memory_copy.wast:620 +assert_return(() => call($9, "load8_u", [49_371]), 0); + +// memory_copy.wast:621 +assert_return(() => call($9, "load8_u", [49_570]), 0); + +// memory_copy.wast:622 +assert_return(() => call($9, "load8_u", [49_769]), 0); + +// memory_copy.wast:623 +assert_return(() => call($9, "load8_u", [49_968]), 0); + +// memory_copy.wast:624 +assert_return(() => call($9, "load8_u", [50_167]), 0); + +// memory_copy.wast:625 +assert_return(() => call($9, "load8_u", [50_366]), 0); + +// memory_copy.wast:626 +assert_return(() => call($9, "load8_u", [50_565]), 0); + +// memory_copy.wast:627 +assert_return(() => call($9, "load8_u", [50_764]), 0); + +// memory_copy.wast:628 +assert_return(() => call($9, "load8_u", [50_963]), 0); + +// memory_copy.wast:629 +assert_return(() => call($9, "load8_u", [51_162]), 0); + +// memory_copy.wast:630 +assert_return(() => call($9, "load8_u", [51_361]), 0); + +// memory_copy.wast:631 +assert_return(() => call($9, "load8_u", [51_560]), 0); + +// memory_copy.wast:632 +assert_return(() => call($9, "load8_u", [51_759]), 0); + +// memory_copy.wast:633 +assert_return(() => call($9, "load8_u", [51_958]), 0); + +// memory_copy.wast:634 +assert_return(() => call($9, "load8_u", [52_157]), 0); + +// memory_copy.wast:635 +assert_return(() => call($9, "load8_u", [52_356]), 0); + +// memory_copy.wast:636 +assert_return(() => call($9, "load8_u", [52_555]), 0); + +// memory_copy.wast:637 +assert_return(() => call($9, "load8_u", [52_754]), 0); + +// memory_copy.wast:638 +assert_return(() => call($9, "load8_u", [52_953]), 0); + +// memory_copy.wast:639 +assert_return(() => call($9, "load8_u", [53_152]), 0); + +// memory_copy.wast:640 +assert_return(() => call($9, "load8_u", [53_351]), 0); + +// memory_copy.wast:641 +assert_return(() => call($9, "load8_u", [53_550]), 0); + +// memory_copy.wast:642 +assert_return(() => call($9, "load8_u", [53_749]), 0); + +// memory_copy.wast:643 +assert_return(() => call($9, "load8_u", [53_948]), 0); + +// memory_copy.wast:644 +assert_return(() => call($9, "load8_u", [54_147]), 0); + +// memory_copy.wast:645 +assert_return(() => call($9, "load8_u", [54_346]), 0); + +// memory_copy.wast:646 +assert_return(() => call($9, "load8_u", [54_545]), 0); + +// memory_copy.wast:647 +assert_return(() => call($9, "load8_u", [54_744]), 0); + +// memory_copy.wast:648 +assert_return(() => call($9, "load8_u", [54_943]), 0); + +// memory_copy.wast:649 +assert_return(() => call($9, "load8_u", [55_142]), 0); + +// memory_copy.wast:650 +assert_return(() => call($9, "load8_u", [55_341]), 0); + +// memory_copy.wast:651 +assert_return(() => call($9, "load8_u", [55_540]), 0); + +// memory_copy.wast:652 +assert_return(() => call($9, "load8_u", [55_739]), 0); + +// memory_copy.wast:653 +assert_return(() => call($9, "load8_u", [55_938]), 0); + +// memory_copy.wast:654 +assert_return(() => call($9, "load8_u", [56_137]), 0); + +// memory_copy.wast:655 +assert_return(() => call($9, "load8_u", [56_336]), 0); + +// memory_copy.wast:656 +assert_return(() => call($9, "load8_u", [56_535]), 0); + +// memory_copy.wast:657 +assert_return(() => call($9, "load8_u", [56_734]), 0); + +// memory_copy.wast:658 +assert_return(() => call($9, "load8_u", [56_933]), 0); + +// memory_copy.wast:659 +assert_return(() => call($9, "load8_u", [57_132]), 0); + +// memory_copy.wast:660 +assert_return(() => call($9, "load8_u", [57_331]), 0); + +// memory_copy.wast:661 +assert_return(() => call($9, "load8_u", [57_530]), 0); + +// memory_copy.wast:662 +assert_return(() => call($9, "load8_u", [57_729]), 0); + +// memory_copy.wast:663 +assert_return(() => call($9, "load8_u", [57_928]), 0); + +// memory_copy.wast:664 +assert_return(() => call($9, "load8_u", [58_127]), 0); + +// memory_copy.wast:665 +assert_return(() => call($9, "load8_u", [58_326]), 0); + +// memory_copy.wast:666 +assert_return(() => call($9, "load8_u", [58_525]), 0); + +// memory_copy.wast:667 +assert_return(() => call($9, "load8_u", [58_724]), 0); + +// memory_copy.wast:668 +assert_return(() => call($9, "load8_u", [58_923]), 0); + +// memory_copy.wast:669 +assert_return(() => call($9, "load8_u", [59_122]), 0); + +// memory_copy.wast:670 +assert_return(() => call($9, "load8_u", [59_321]), 0); + +// memory_copy.wast:671 +assert_return(() => call($9, "load8_u", [59_520]), 0); + +// memory_copy.wast:672 +assert_return(() => call($9, "load8_u", [59_719]), 0); + +// memory_copy.wast:673 +assert_return(() => call($9, "load8_u", [59_918]), 0); + +// memory_copy.wast:674 +assert_return(() => call($9, "load8_u", [60_117]), 0); + +// memory_copy.wast:675 +assert_return(() => call($9, "load8_u", [60_316]), 0); + +// memory_copy.wast:676 +assert_return(() => call($9, "load8_u", [60_515]), 0); + +// memory_copy.wast:677 +assert_return(() => call($9, "load8_u", [60_714]), 0); + +// memory_copy.wast:678 +assert_return(() => call($9, "load8_u", [60_913]), 0); + +// memory_copy.wast:679 +assert_return(() => call($9, "load8_u", [61_112]), 0); + +// memory_copy.wast:680 +assert_return(() => call($9, "load8_u", [61_311]), 0); + +// memory_copy.wast:681 +assert_return(() => call($9, "load8_u", [61_510]), 0); + +// memory_copy.wast:682 +assert_return(() => call($9, "load8_u", [61_709]), 0); + +// memory_copy.wast:683 +assert_return(() => call($9, "load8_u", [61_908]), 0); + +// memory_copy.wast:684 +assert_return(() => call($9, "load8_u", [62_107]), 0); + +// memory_copy.wast:685 +assert_return(() => call($9, "load8_u", [62_306]), 0); + +// memory_copy.wast:686 +assert_return(() => call($9, "load8_u", [62_505]), 0); + +// memory_copy.wast:687 +assert_return(() => call($9, "load8_u", [62_704]), 0); + +// memory_copy.wast:688 +assert_return(() => call($9, "load8_u", [62_903]), 0); + +// memory_copy.wast:689 +assert_return(() => call($9, "load8_u", [63_102]), 0); + +// memory_copy.wast:690 +assert_return(() => call($9, "load8_u", [63_301]), 0); + +// memory_copy.wast:691 +assert_return(() => call($9, "load8_u", [63_500]), 0); + +// memory_copy.wast:692 +assert_return(() => call($9, "load8_u", [63_699]), 0); + +// memory_copy.wast:693 +assert_return(() => call($9, "load8_u", [63_898]), 0); + +// memory_copy.wast:694 +assert_return(() => call($9, "load8_u", [64_097]), 0); + +// memory_copy.wast:695 +assert_return(() => call($9, "load8_u", [64_296]), 0); + +// memory_copy.wast:696 +assert_return(() => call($9, "load8_u", [64_495]), 0); + +// memory_copy.wast:697 +assert_return(() => call($9, "load8_u", [64_694]), 0); + +// memory_copy.wast:698 +assert_return(() => call($9, "load8_u", [64_893]), 0); + +// memory_copy.wast:699 +assert_return(() => call($9, "load8_u", [65_092]), 0); + +// memory_copy.wast:700 +assert_return(() => call($9, "load8_u", [65_291]), 0); + +// memory_copy.wast:701 +assert_return(() => call($9, "load8_u", [65_490]), 0); + +// memory_copy.wast:703 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9b\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x15\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"); + +// memory_copy.wast:711 +assert_trap(() => call($10, "run", [65_515, 0, 39])); + +// memory_copy.wast:714 +assert_return(() => call($10, "load8_u", [0]), 0); + +// memory_copy.wast:715 +assert_return(() => call($10, "load8_u", [1]), 1); + +// memory_copy.wast:716 +assert_return(() => call($10, "load8_u", [2]), 2); + +// memory_copy.wast:717 +assert_return(() => call($10, "load8_u", [3]), 3); + +// memory_copy.wast:718 +assert_return(() => call($10, "load8_u", [4]), 4); + +// memory_copy.wast:719 +assert_return(() => call($10, "load8_u", [5]), 5); + +// memory_copy.wast:720 +assert_return(() => call($10, "load8_u", [6]), 6); + +// memory_copy.wast:721 +assert_return(() => call($10, "load8_u", [7]), 7); + +// memory_copy.wast:722 +assert_return(() => call($10, "load8_u", [8]), 8); + +// memory_copy.wast:723 +assert_return(() => call($10, "load8_u", [9]), 9); + +// memory_copy.wast:724 +assert_return(() => call($10, "load8_u", [10]), 10); + +// memory_copy.wast:725 +assert_return(() => call($10, "load8_u", [11]), 11); + +// memory_copy.wast:726 +assert_return(() => call($10, "load8_u", [12]), 12); + +// memory_copy.wast:727 +assert_return(() => call($10, "load8_u", [13]), 13); + +// memory_copy.wast:728 +assert_return(() => call($10, "load8_u", [14]), 14); + +// memory_copy.wast:729 +assert_return(() => call($10, "load8_u", [15]), 15); + +// memory_copy.wast:730 +assert_return(() => call($10, "load8_u", [16]), 16); + +// memory_copy.wast:731 +assert_return(() => call($10, "load8_u", [17]), 17); + +// memory_copy.wast:732 +assert_return(() => call($10, "load8_u", [18]), 18); + +// memory_copy.wast:733 +assert_return(() => call($10, "load8_u", [19]), 19); + +// memory_copy.wast:734 +assert_return(() => call($10, "load8_u", [20]), 20); + +// memory_copy.wast:735 +assert_return(() => call($10, "load8_u", [219]), 0); + +// memory_copy.wast:736 +assert_return(() => call($10, "load8_u", [418]), 0); + +// memory_copy.wast:737 +assert_return(() => call($10, "load8_u", [617]), 0); + +// memory_copy.wast:738 +assert_return(() => call($10, "load8_u", [816]), 0); + +// memory_copy.wast:739 +assert_return(() => call($10, "load8_u", [1_015]), 0); + +// memory_copy.wast:740 +assert_return(() => call($10, "load8_u", [1_214]), 0); + +// memory_copy.wast:741 +assert_return(() => call($10, "load8_u", [1_413]), 0); + +// memory_copy.wast:742 +assert_return(() => call($10, "load8_u", [1_612]), 0); + +// memory_copy.wast:743 +assert_return(() => call($10, "load8_u", [1_811]), 0); + +// memory_copy.wast:744 +assert_return(() => call($10, "load8_u", [2_010]), 0); + +// memory_copy.wast:745 +assert_return(() => call($10, "load8_u", [2_209]), 0); + +// memory_copy.wast:746 +assert_return(() => call($10, "load8_u", [2_408]), 0); + +// memory_copy.wast:747 +assert_return(() => call($10, "load8_u", [2_607]), 0); + +// memory_copy.wast:748 +assert_return(() => call($10, "load8_u", [2_806]), 0); + +// memory_copy.wast:749 +assert_return(() => call($10, "load8_u", [3_005]), 0); + +// memory_copy.wast:750 +assert_return(() => call($10, "load8_u", [3_204]), 0); + +// memory_copy.wast:751 +assert_return(() => call($10, "load8_u", [3_403]), 0); + +// memory_copy.wast:752 +assert_return(() => call($10, "load8_u", [3_602]), 0); + +// memory_copy.wast:753 +assert_return(() => call($10, "load8_u", [3_801]), 0); + +// memory_copy.wast:754 +assert_return(() => call($10, "load8_u", [4_000]), 0); + +// memory_copy.wast:755 +assert_return(() => call($10, "load8_u", [4_199]), 0); + +// memory_copy.wast:756 +assert_return(() => call($10, "load8_u", [4_398]), 0); + +// memory_copy.wast:757 +assert_return(() => call($10, "load8_u", [4_597]), 0); + +// memory_copy.wast:758 +assert_return(() => call($10, "load8_u", [4_796]), 0); + +// memory_copy.wast:759 +assert_return(() => call($10, "load8_u", [4_995]), 0); + +// memory_copy.wast:760 +assert_return(() => call($10, "load8_u", [5_194]), 0); + +// memory_copy.wast:761 +assert_return(() => call($10, "load8_u", [5_393]), 0); + +// memory_copy.wast:762 +assert_return(() => call($10, "load8_u", [5_592]), 0); + +// memory_copy.wast:763 +assert_return(() => call($10, "load8_u", [5_791]), 0); + +// memory_copy.wast:764 +assert_return(() => call($10, "load8_u", [5_990]), 0); + +// memory_copy.wast:765 +assert_return(() => call($10, "load8_u", [6_189]), 0); + +// memory_copy.wast:766 +assert_return(() => call($10, "load8_u", [6_388]), 0); + +// memory_copy.wast:767 +assert_return(() => call($10, "load8_u", [6_587]), 0); + +// memory_copy.wast:768 +assert_return(() => call($10, "load8_u", [6_786]), 0); + +// memory_copy.wast:769 +assert_return(() => call($10, "load8_u", [6_985]), 0); + +// memory_copy.wast:770 +assert_return(() => call($10, "load8_u", [7_184]), 0); + +// memory_copy.wast:771 +assert_return(() => call($10, "load8_u", [7_383]), 0); + +// memory_copy.wast:772 +assert_return(() => call($10, "load8_u", [7_582]), 0); + +// memory_copy.wast:773 +assert_return(() => call($10, "load8_u", [7_781]), 0); + +// memory_copy.wast:774 +assert_return(() => call($10, "load8_u", [7_980]), 0); + +// memory_copy.wast:775 +assert_return(() => call($10, "load8_u", [8_179]), 0); + +// memory_copy.wast:776 +assert_return(() => call($10, "load8_u", [8_378]), 0); + +// memory_copy.wast:777 +assert_return(() => call($10, "load8_u", [8_577]), 0); + +// memory_copy.wast:778 +assert_return(() => call($10, "load8_u", [8_776]), 0); + +// memory_copy.wast:779 +assert_return(() => call($10, "load8_u", [8_975]), 0); + +// memory_copy.wast:780 +assert_return(() => call($10, "load8_u", [9_174]), 0); + +// memory_copy.wast:781 +assert_return(() => call($10, "load8_u", [9_373]), 0); + +// memory_copy.wast:782 +assert_return(() => call($10, "load8_u", [9_572]), 0); + +// memory_copy.wast:783 +assert_return(() => call($10, "load8_u", [9_771]), 0); + +// memory_copy.wast:784 +assert_return(() => call($10, "load8_u", [9_970]), 0); + +// memory_copy.wast:785 +assert_return(() => call($10, "load8_u", [10_169]), 0); + +// memory_copy.wast:786 +assert_return(() => call($10, "load8_u", [10_368]), 0); + +// memory_copy.wast:787 +assert_return(() => call($10, "load8_u", [10_567]), 0); + +// memory_copy.wast:788 +assert_return(() => call($10, "load8_u", [10_766]), 0); + +// memory_copy.wast:789 +assert_return(() => call($10, "load8_u", [10_965]), 0); + +// memory_copy.wast:790 +assert_return(() => call($10, "load8_u", [11_164]), 0); + +// memory_copy.wast:791 +assert_return(() => call($10, "load8_u", [11_363]), 0); + +// memory_copy.wast:792 +assert_return(() => call($10, "load8_u", [11_562]), 0); + +// memory_copy.wast:793 +assert_return(() => call($10, "load8_u", [11_761]), 0); + +// memory_copy.wast:794 +assert_return(() => call($10, "load8_u", [11_960]), 0); + +// memory_copy.wast:795 +assert_return(() => call($10, "load8_u", [12_159]), 0); + +// memory_copy.wast:796 +assert_return(() => call($10, "load8_u", [12_358]), 0); + +// memory_copy.wast:797 +assert_return(() => call($10, "load8_u", [12_557]), 0); + +// memory_copy.wast:798 +assert_return(() => call($10, "load8_u", [12_756]), 0); + +// memory_copy.wast:799 +assert_return(() => call($10, "load8_u", [12_955]), 0); + +// memory_copy.wast:800 +assert_return(() => call($10, "load8_u", [13_154]), 0); + +// memory_copy.wast:801 +assert_return(() => call($10, "load8_u", [13_353]), 0); + +// memory_copy.wast:802 +assert_return(() => call($10, "load8_u", [13_552]), 0); + +// memory_copy.wast:803 +assert_return(() => call($10, "load8_u", [13_751]), 0); + +// memory_copy.wast:804 +assert_return(() => call($10, "load8_u", [13_950]), 0); + +// memory_copy.wast:805 +assert_return(() => call($10, "load8_u", [14_149]), 0); + +// memory_copy.wast:806 +assert_return(() => call($10, "load8_u", [14_348]), 0); + +// memory_copy.wast:807 +assert_return(() => call($10, "load8_u", [14_547]), 0); + +// memory_copy.wast:808 +assert_return(() => call($10, "load8_u", [14_746]), 0); + +// memory_copy.wast:809 +assert_return(() => call($10, "load8_u", [14_945]), 0); + +// memory_copy.wast:810 +assert_return(() => call($10, "load8_u", [15_144]), 0); + +// memory_copy.wast:811 +assert_return(() => call($10, "load8_u", [15_343]), 0); + +// memory_copy.wast:812 +assert_return(() => call($10, "load8_u", [15_542]), 0); + +// memory_copy.wast:813 +assert_return(() => call($10, "load8_u", [15_741]), 0); + +// memory_copy.wast:814 +assert_return(() => call($10, "load8_u", [15_940]), 0); + +// memory_copy.wast:815 +assert_return(() => call($10, "load8_u", [16_139]), 0); + +// memory_copy.wast:816 +assert_return(() => call($10, "load8_u", [16_338]), 0); + +// memory_copy.wast:817 +assert_return(() => call($10, "load8_u", [16_537]), 0); + +// memory_copy.wast:818 +assert_return(() => call($10, "load8_u", [16_736]), 0); + +// memory_copy.wast:819 +assert_return(() => call($10, "load8_u", [16_935]), 0); + +// memory_copy.wast:820 +assert_return(() => call($10, "load8_u", [17_134]), 0); + +// memory_copy.wast:821 +assert_return(() => call($10, "load8_u", [17_333]), 0); + +// memory_copy.wast:822 +assert_return(() => call($10, "load8_u", [17_532]), 0); + +// memory_copy.wast:823 +assert_return(() => call($10, "load8_u", [17_731]), 0); + +// memory_copy.wast:824 +assert_return(() => call($10, "load8_u", [17_930]), 0); + +// memory_copy.wast:825 +assert_return(() => call($10, "load8_u", [18_129]), 0); + +// memory_copy.wast:826 +assert_return(() => call($10, "load8_u", [18_328]), 0); + +// memory_copy.wast:827 +assert_return(() => call($10, "load8_u", [18_527]), 0); + +// memory_copy.wast:828 +assert_return(() => call($10, "load8_u", [18_726]), 0); + +// memory_copy.wast:829 +assert_return(() => call($10, "load8_u", [18_925]), 0); + +// memory_copy.wast:830 +assert_return(() => call($10, "load8_u", [19_124]), 0); + +// memory_copy.wast:831 +assert_return(() => call($10, "load8_u", [19_323]), 0); + +// memory_copy.wast:832 +assert_return(() => call($10, "load8_u", [19_522]), 0); + +// memory_copy.wast:833 +assert_return(() => call($10, "load8_u", [19_721]), 0); + +// memory_copy.wast:834 +assert_return(() => call($10, "load8_u", [19_920]), 0); + +// memory_copy.wast:835 +assert_return(() => call($10, "load8_u", [20_119]), 0); + +// memory_copy.wast:836 +assert_return(() => call($10, "load8_u", [20_318]), 0); + +// memory_copy.wast:837 +assert_return(() => call($10, "load8_u", [20_517]), 0); + +// memory_copy.wast:838 +assert_return(() => call($10, "load8_u", [20_716]), 0); + +// memory_copy.wast:839 +assert_return(() => call($10, "load8_u", [20_915]), 0); + +// memory_copy.wast:840 +assert_return(() => call($10, "load8_u", [21_114]), 0); + +// memory_copy.wast:841 +assert_return(() => call($10, "load8_u", [21_313]), 0); + +// memory_copy.wast:842 +assert_return(() => call($10, "load8_u", [21_512]), 0); + +// memory_copy.wast:843 +assert_return(() => call($10, "load8_u", [21_711]), 0); + +// memory_copy.wast:844 +assert_return(() => call($10, "load8_u", [21_910]), 0); + +// memory_copy.wast:845 +assert_return(() => call($10, "load8_u", [22_109]), 0); + +// memory_copy.wast:846 +assert_return(() => call($10, "load8_u", [22_308]), 0); + +// memory_copy.wast:847 +assert_return(() => call($10, "load8_u", [22_507]), 0); + +// memory_copy.wast:848 +assert_return(() => call($10, "load8_u", [22_706]), 0); + +// memory_copy.wast:849 +assert_return(() => call($10, "load8_u", [22_905]), 0); + +// memory_copy.wast:850 +assert_return(() => call($10, "load8_u", [23_104]), 0); + +// memory_copy.wast:851 +assert_return(() => call($10, "load8_u", [23_303]), 0); + +// memory_copy.wast:852 +assert_return(() => call($10, "load8_u", [23_502]), 0); + +// memory_copy.wast:853 +assert_return(() => call($10, "load8_u", [23_701]), 0); + +// memory_copy.wast:854 +assert_return(() => call($10, "load8_u", [23_900]), 0); + +// memory_copy.wast:855 +assert_return(() => call($10, "load8_u", [24_099]), 0); + +// memory_copy.wast:856 +assert_return(() => call($10, "load8_u", [24_298]), 0); + +// memory_copy.wast:857 +assert_return(() => call($10, "load8_u", [24_497]), 0); + +// memory_copy.wast:858 +assert_return(() => call($10, "load8_u", [24_696]), 0); + +// memory_copy.wast:859 +assert_return(() => call($10, "load8_u", [24_895]), 0); + +// memory_copy.wast:860 +assert_return(() => call($10, "load8_u", [25_094]), 0); + +// memory_copy.wast:861 +assert_return(() => call($10, "load8_u", [25_293]), 0); + +// memory_copy.wast:862 +assert_return(() => call($10, "load8_u", [25_492]), 0); + +// memory_copy.wast:863 +assert_return(() => call($10, "load8_u", [25_691]), 0); + +// memory_copy.wast:864 +assert_return(() => call($10, "load8_u", [25_890]), 0); + +// memory_copy.wast:865 +assert_return(() => call($10, "load8_u", [26_089]), 0); + +// memory_copy.wast:866 +assert_return(() => call($10, "load8_u", [26_288]), 0); + +// memory_copy.wast:867 +assert_return(() => call($10, "load8_u", [26_487]), 0); + +// memory_copy.wast:868 +assert_return(() => call($10, "load8_u", [26_686]), 0); + +// memory_copy.wast:869 +assert_return(() => call($10, "load8_u", [26_885]), 0); + +// memory_copy.wast:870 +assert_return(() => call($10, "load8_u", [27_084]), 0); + +// memory_copy.wast:871 +assert_return(() => call($10, "load8_u", [27_283]), 0); + +// memory_copy.wast:872 +assert_return(() => call($10, "load8_u", [27_482]), 0); + +// memory_copy.wast:873 +assert_return(() => call($10, "load8_u", [27_681]), 0); + +// memory_copy.wast:874 +assert_return(() => call($10, "load8_u", [27_880]), 0); + +// memory_copy.wast:875 +assert_return(() => call($10, "load8_u", [28_079]), 0); + +// memory_copy.wast:876 +assert_return(() => call($10, "load8_u", [28_278]), 0); + +// memory_copy.wast:877 +assert_return(() => call($10, "load8_u", [28_477]), 0); + +// memory_copy.wast:878 +assert_return(() => call($10, "load8_u", [28_676]), 0); + +// memory_copy.wast:879 +assert_return(() => call($10, "load8_u", [28_875]), 0); + +// memory_copy.wast:880 +assert_return(() => call($10, "load8_u", [29_074]), 0); + +// memory_copy.wast:881 +assert_return(() => call($10, "load8_u", [29_273]), 0); + +// memory_copy.wast:882 +assert_return(() => call($10, "load8_u", [29_472]), 0); + +// memory_copy.wast:883 +assert_return(() => call($10, "load8_u", [29_671]), 0); + +// memory_copy.wast:884 +assert_return(() => call($10, "load8_u", [29_870]), 0); + +// memory_copy.wast:885 +assert_return(() => call($10, "load8_u", [30_069]), 0); + +// memory_copy.wast:886 +assert_return(() => call($10, "load8_u", [30_268]), 0); + +// memory_copy.wast:887 +assert_return(() => call($10, "load8_u", [30_467]), 0); + +// memory_copy.wast:888 +assert_return(() => call($10, "load8_u", [30_666]), 0); + +// memory_copy.wast:889 +assert_return(() => call($10, "load8_u", [30_865]), 0); + +// memory_copy.wast:890 +assert_return(() => call($10, "load8_u", [31_064]), 0); + +// memory_copy.wast:891 +assert_return(() => call($10, "load8_u", [31_263]), 0); + +// memory_copy.wast:892 +assert_return(() => call($10, "load8_u", [31_462]), 0); + +// memory_copy.wast:893 +assert_return(() => call($10, "load8_u", [31_661]), 0); + +// memory_copy.wast:894 +assert_return(() => call($10, "load8_u", [31_860]), 0); + +// memory_copy.wast:895 +assert_return(() => call($10, "load8_u", [32_059]), 0); + +// memory_copy.wast:896 +assert_return(() => call($10, "load8_u", [32_258]), 0); + +// memory_copy.wast:897 +assert_return(() => call($10, "load8_u", [32_457]), 0); + +// memory_copy.wast:898 +assert_return(() => call($10, "load8_u", [32_656]), 0); + +// memory_copy.wast:899 +assert_return(() => call($10, "load8_u", [32_855]), 0); + +// memory_copy.wast:900 +assert_return(() => call($10, "load8_u", [33_054]), 0); + +// memory_copy.wast:901 +assert_return(() => call($10, "load8_u", [33_253]), 0); + +// memory_copy.wast:902 +assert_return(() => call($10, "load8_u", [33_452]), 0); + +// memory_copy.wast:903 +assert_return(() => call($10, "load8_u", [33_651]), 0); + +// memory_copy.wast:904 +assert_return(() => call($10, "load8_u", [33_850]), 0); + +// memory_copy.wast:905 +assert_return(() => call($10, "load8_u", [34_049]), 0); + +// memory_copy.wast:906 +assert_return(() => call($10, "load8_u", [34_248]), 0); + +// memory_copy.wast:907 +assert_return(() => call($10, "load8_u", [34_447]), 0); + +// memory_copy.wast:908 +assert_return(() => call($10, "load8_u", [34_646]), 0); + +// memory_copy.wast:909 +assert_return(() => call($10, "load8_u", [34_845]), 0); + +// memory_copy.wast:910 +assert_return(() => call($10, "load8_u", [35_044]), 0); + +// memory_copy.wast:911 +assert_return(() => call($10, "load8_u", [35_243]), 0); + +// memory_copy.wast:912 +assert_return(() => call($10, "load8_u", [35_442]), 0); + +// memory_copy.wast:913 +assert_return(() => call($10, "load8_u", [35_641]), 0); + +// memory_copy.wast:914 +assert_return(() => call($10, "load8_u", [35_840]), 0); + +// memory_copy.wast:915 +assert_return(() => call($10, "load8_u", [36_039]), 0); + +// memory_copy.wast:916 +assert_return(() => call($10, "load8_u", [36_238]), 0); + +// memory_copy.wast:917 +assert_return(() => call($10, "load8_u", [36_437]), 0); + +// memory_copy.wast:918 +assert_return(() => call($10, "load8_u", [36_636]), 0); + +// memory_copy.wast:919 +assert_return(() => call($10, "load8_u", [36_835]), 0); + +// memory_copy.wast:920 +assert_return(() => call($10, "load8_u", [37_034]), 0); + +// memory_copy.wast:921 +assert_return(() => call($10, "load8_u", [37_233]), 0); + +// memory_copy.wast:922 +assert_return(() => call($10, "load8_u", [37_432]), 0); + +// memory_copy.wast:923 +assert_return(() => call($10, "load8_u", [37_631]), 0); + +// memory_copy.wast:924 +assert_return(() => call($10, "load8_u", [37_830]), 0); + +// memory_copy.wast:925 +assert_return(() => call($10, "load8_u", [38_029]), 0); + +// memory_copy.wast:926 +assert_return(() => call($10, "load8_u", [38_228]), 0); + +// memory_copy.wast:927 +assert_return(() => call($10, "load8_u", [38_427]), 0); + +// memory_copy.wast:928 +assert_return(() => call($10, "load8_u", [38_626]), 0); + +// memory_copy.wast:929 +assert_return(() => call($10, "load8_u", [38_825]), 0); + +// memory_copy.wast:930 +assert_return(() => call($10, "load8_u", [39_024]), 0); + +// memory_copy.wast:931 +assert_return(() => call($10, "load8_u", [39_223]), 0); + +// memory_copy.wast:932 +assert_return(() => call($10, "load8_u", [39_422]), 0); + +// memory_copy.wast:933 +assert_return(() => call($10, "load8_u", [39_621]), 0); + +// memory_copy.wast:934 +assert_return(() => call($10, "load8_u", [39_820]), 0); + +// memory_copy.wast:935 +assert_return(() => call($10, "load8_u", [40_019]), 0); + +// memory_copy.wast:936 +assert_return(() => call($10, "load8_u", [40_218]), 0); + +// memory_copy.wast:937 +assert_return(() => call($10, "load8_u", [40_417]), 0); + +// memory_copy.wast:938 +assert_return(() => call($10, "load8_u", [40_616]), 0); + +// memory_copy.wast:939 +assert_return(() => call($10, "load8_u", [40_815]), 0); + +// memory_copy.wast:940 +assert_return(() => call($10, "load8_u", [41_014]), 0); + +// memory_copy.wast:941 +assert_return(() => call($10, "load8_u", [41_213]), 0); + +// memory_copy.wast:942 +assert_return(() => call($10, "load8_u", [41_412]), 0); + +// memory_copy.wast:943 +assert_return(() => call($10, "load8_u", [41_611]), 0); + +// memory_copy.wast:944 +assert_return(() => call($10, "load8_u", [41_810]), 0); + +// memory_copy.wast:945 +assert_return(() => call($10, "load8_u", [42_009]), 0); + +// memory_copy.wast:946 +assert_return(() => call($10, "load8_u", [42_208]), 0); + +// memory_copy.wast:947 +assert_return(() => call($10, "load8_u", [42_407]), 0); + +// memory_copy.wast:948 +assert_return(() => call($10, "load8_u", [42_606]), 0); + +// memory_copy.wast:949 +assert_return(() => call($10, "load8_u", [42_805]), 0); + +// memory_copy.wast:950 +assert_return(() => call($10, "load8_u", [43_004]), 0); + +// memory_copy.wast:951 +assert_return(() => call($10, "load8_u", [43_203]), 0); + +// memory_copy.wast:952 +assert_return(() => call($10, "load8_u", [43_402]), 0); + +// memory_copy.wast:953 +assert_return(() => call($10, "load8_u", [43_601]), 0); + +// memory_copy.wast:954 +assert_return(() => call($10, "load8_u", [43_800]), 0); + +// memory_copy.wast:955 +assert_return(() => call($10, "load8_u", [43_999]), 0); + +// memory_copy.wast:956 +assert_return(() => call($10, "load8_u", [44_198]), 0); + +// memory_copy.wast:957 +assert_return(() => call($10, "load8_u", [44_397]), 0); + +// memory_copy.wast:958 +assert_return(() => call($10, "load8_u", [44_596]), 0); + +// memory_copy.wast:959 +assert_return(() => call($10, "load8_u", [44_795]), 0); + +// memory_copy.wast:960 +assert_return(() => call($10, "load8_u", [44_994]), 0); + +// memory_copy.wast:961 +assert_return(() => call($10, "load8_u", [45_193]), 0); + +// memory_copy.wast:962 +assert_return(() => call($10, "load8_u", [45_392]), 0); + +// memory_copy.wast:963 +assert_return(() => call($10, "load8_u", [45_591]), 0); + +// memory_copy.wast:964 +assert_return(() => call($10, "load8_u", [45_790]), 0); + +// memory_copy.wast:965 +assert_return(() => call($10, "load8_u", [45_989]), 0); + +// memory_copy.wast:966 +assert_return(() => call($10, "load8_u", [46_188]), 0); + +// memory_copy.wast:967 +assert_return(() => call($10, "load8_u", [46_387]), 0); + +// memory_copy.wast:968 +assert_return(() => call($10, "load8_u", [46_586]), 0); + +// memory_copy.wast:969 +assert_return(() => call($10, "load8_u", [46_785]), 0); + +// memory_copy.wast:970 +assert_return(() => call($10, "load8_u", [46_984]), 0); + +// memory_copy.wast:971 +assert_return(() => call($10, "load8_u", [47_183]), 0); + +// memory_copy.wast:972 +assert_return(() => call($10, "load8_u", [47_382]), 0); + +// memory_copy.wast:973 +assert_return(() => call($10, "load8_u", [47_581]), 0); + +// memory_copy.wast:974 +assert_return(() => call($10, "load8_u", [47_780]), 0); + +// memory_copy.wast:975 +assert_return(() => call($10, "load8_u", [47_979]), 0); + +// memory_copy.wast:976 +assert_return(() => call($10, "load8_u", [48_178]), 0); + +// memory_copy.wast:977 +assert_return(() => call($10, "load8_u", [48_377]), 0); + +// memory_copy.wast:978 +assert_return(() => call($10, "load8_u", [48_576]), 0); + +// memory_copy.wast:979 +assert_return(() => call($10, "load8_u", [48_775]), 0); + +// memory_copy.wast:980 +assert_return(() => call($10, "load8_u", [48_974]), 0); + +// memory_copy.wast:981 +assert_return(() => call($10, "load8_u", [49_173]), 0); + +// memory_copy.wast:982 +assert_return(() => call($10, "load8_u", [49_372]), 0); + +// memory_copy.wast:983 +assert_return(() => call($10, "load8_u", [49_571]), 0); + +// memory_copy.wast:984 +assert_return(() => call($10, "load8_u", [49_770]), 0); + +// memory_copy.wast:985 +assert_return(() => call($10, "load8_u", [49_969]), 0); + +// memory_copy.wast:986 +assert_return(() => call($10, "load8_u", [50_168]), 0); + +// memory_copy.wast:987 +assert_return(() => call($10, "load8_u", [50_367]), 0); + +// memory_copy.wast:988 +assert_return(() => call($10, "load8_u", [50_566]), 0); + +// memory_copy.wast:989 +assert_return(() => call($10, "load8_u", [50_765]), 0); + +// memory_copy.wast:990 +assert_return(() => call($10, "load8_u", [50_964]), 0); + +// memory_copy.wast:991 +assert_return(() => call($10, "load8_u", [51_163]), 0); + +// memory_copy.wast:992 +assert_return(() => call($10, "load8_u", [51_362]), 0); + +// memory_copy.wast:993 +assert_return(() => call($10, "load8_u", [51_561]), 0); + +// memory_copy.wast:994 +assert_return(() => call($10, "load8_u", [51_760]), 0); + +// memory_copy.wast:995 +assert_return(() => call($10, "load8_u", [51_959]), 0); + +// memory_copy.wast:996 +assert_return(() => call($10, "load8_u", [52_158]), 0); + +// memory_copy.wast:997 +assert_return(() => call($10, "load8_u", [52_357]), 0); + +// memory_copy.wast:998 +assert_return(() => call($10, "load8_u", [52_556]), 0); + +// memory_copy.wast:999 +assert_return(() => call($10, "load8_u", [52_755]), 0); + +// memory_copy.wast:1000 +assert_return(() => call($10, "load8_u", [52_954]), 0); + +// memory_copy.wast:1001 +assert_return(() => call($10, "load8_u", [53_153]), 0); + +// memory_copy.wast:1002 +assert_return(() => call($10, "load8_u", [53_352]), 0); + +// memory_copy.wast:1003 +assert_return(() => call($10, "load8_u", [53_551]), 0); + +// memory_copy.wast:1004 +assert_return(() => call($10, "load8_u", [53_750]), 0); + +// memory_copy.wast:1005 +assert_return(() => call($10, "load8_u", [53_949]), 0); + +// memory_copy.wast:1006 +assert_return(() => call($10, "load8_u", [54_148]), 0); + +// memory_copy.wast:1007 +assert_return(() => call($10, "load8_u", [54_347]), 0); + +// memory_copy.wast:1008 +assert_return(() => call($10, "load8_u", [54_546]), 0); + +// memory_copy.wast:1009 +assert_return(() => call($10, "load8_u", [54_745]), 0); + +// memory_copy.wast:1010 +assert_return(() => call($10, "load8_u", [54_944]), 0); + +// memory_copy.wast:1011 +assert_return(() => call($10, "load8_u", [55_143]), 0); + +// memory_copy.wast:1012 +assert_return(() => call($10, "load8_u", [55_342]), 0); + +// memory_copy.wast:1013 +assert_return(() => call($10, "load8_u", [55_541]), 0); + +// memory_copy.wast:1014 +assert_return(() => call($10, "load8_u", [55_740]), 0); + +// memory_copy.wast:1015 +assert_return(() => call($10, "load8_u", [55_939]), 0); + +// memory_copy.wast:1016 +assert_return(() => call($10, "load8_u", [56_138]), 0); + +// memory_copy.wast:1017 +assert_return(() => call($10, "load8_u", [56_337]), 0); + +// memory_copy.wast:1018 +assert_return(() => call($10, "load8_u", [56_536]), 0); + +// memory_copy.wast:1019 +assert_return(() => call($10, "load8_u", [56_735]), 0); + +// memory_copy.wast:1020 +assert_return(() => call($10, "load8_u", [56_934]), 0); + +// memory_copy.wast:1021 +assert_return(() => call($10, "load8_u", [57_133]), 0); + +// memory_copy.wast:1022 +assert_return(() => call($10, "load8_u", [57_332]), 0); + +// memory_copy.wast:1023 +assert_return(() => call($10, "load8_u", [57_531]), 0); + +// memory_copy.wast:1024 +assert_return(() => call($10, "load8_u", [57_730]), 0); + +// memory_copy.wast:1025 +assert_return(() => call($10, "load8_u", [57_929]), 0); + +// memory_copy.wast:1026 +assert_return(() => call($10, "load8_u", [58_128]), 0); + +// memory_copy.wast:1027 +assert_return(() => call($10, "load8_u", [58_327]), 0); + +// memory_copy.wast:1028 +assert_return(() => call($10, "load8_u", [58_526]), 0); + +// memory_copy.wast:1029 +assert_return(() => call($10, "load8_u", [58_725]), 0); + +// memory_copy.wast:1030 +assert_return(() => call($10, "load8_u", [58_924]), 0); + +// memory_copy.wast:1031 +assert_return(() => call($10, "load8_u", [59_123]), 0); + +// memory_copy.wast:1032 +assert_return(() => call($10, "load8_u", [59_322]), 0); + +// memory_copy.wast:1033 +assert_return(() => call($10, "load8_u", [59_521]), 0); + +// memory_copy.wast:1034 +assert_return(() => call($10, "load8_u", [59_720]), 0); + +// memory_copy.wast:1035 +assert_return(() => call($10, "load8_u", [59_919]), 0); + +// memory_copy.wast:1036 +assert_return(() => call($10, "load8_u", [60_118]), 0); + +// memory_copy.wast:1037 +assert_return(() => call($10, "load8_u", [60_317]), 0); + +// memory_copy.wast:1038 +assert_return(() => call($10, "load8_u", [60_516]), 0); + +// memory_copy.wast:1039 +assert_return(() => call($10, "load8_u", [60_715]), 0); + +// memory_copy.wast:1040 +assert_return(() => call($10, "load8_u", [60_914]), 0); + +// memory_copy.wast:1041 +assert_return(() => call($10, "load8_u", [61_113]), 0); + +// memory_copy.wast:1042 +assert_return(() => call($10, "load8_u", [61_312]), 0); + +// memory_copy.wast:1043 +assert_return(() => call($10, "load8_u", [61_511]), 0); + +// memory_copy.wast:1044 +assert_return(() => call($10, "load8_u", [61_710]), 0); + +// memory_copy.wast:1045 +assert_return(() => call($10, "load8_u", [61_909]), 0); + +// memory_copy.wast:1046 +assert_return(() => call($10, "load8_u", [62_108]), 0); + +// memory_copy.wast:1047 +assert_return(() => call($10, "load8_u", [62_307]), 0); + +// memory_copy.wast:1048 +assert_return(() => call($10, "load8_u", [62_506]), 0); + +// memory_copy.wast:1049 +assert_return(() => call($10, "load8_u", [62_705]), 0); + +// memory_copy.wast:1050 +assert_return(() => call($10, "load8_u", [62_904]), 0); + +// memory_copy.wast:1051 +assert_return(() => call($10, "load8_u", [63_103]), 0); + +// memory_copy.wast:1052 +assert_return(() => call($10, "load8_u", [63_302]), 0); + +// memory_copy.wast:1053 +assert_return(() => call($10, "load8_u", [63_501]), 0); + +// memory_copy.wast:1054 +assert_return(() => call($10, "load8_u", [63_700]), 0); + +// memory_copy.wast:1055 +assert_return(() => call($10, "load8_u", [63_899]), 0); + +// memory_copy.wast:1056 +assert_return(() => call($10, "load8_u", [64_098]), 0); + +// memory_copy.wast:1057 +assert_return(() => call($10, "load8_u", [64_297]), 0); + +// memory_copy.wast:1058 +assert_return(() => call($10, "load8_u", [64_496]), 0); + +// memory_copy.wast:1059 +assert_return(() => call($10, "load8_u", [64_695]), 0); + +// memory_copy.wast:1060 +assert_return(() => call($10, "load8_u", [64_894]), 0); + +// memory_copy.wast:1061 +assert_return(() => call($10, "load8_u", [65_093]), 0); + +// memory_copy.wast:1062 +assert_return(() => call($10, "load8_u", [65_292]), 0); + +// memory_copy.wast:1063 +assert_return(() => call($10, "load8_u", [65_491]), 0); + +// memory_copy.wast:1065 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:1073 +assert_trap(() => call($11, "run", [0, 65_516, 40])); + +// memory_copy.wast:1076 +assert_return(() => call($11, "load8_u", [198]), 0); + +// memory_copy.wast:1077 +assert_return(() => call($11, "load8_u", [397]), 0); + +// memory_copy.wast:1078 +assert_return(() => call($11, "load8_u", [596]), 0); + +// memory_copy.wast:1079 +assert_return(() => call($11, "load8_u", [795]), 0); + +// memory_copy.wast:1080 +assert_return(() => call($11, "load8_u", [994]), 0); + +// memory_copy.wast:1081 +assert_return(() => call($11, "load8_u", [1_193]), 0); + +// memory_copy.wast:1082 +assert_return(() => call($11, "load8_u", [1_392]), 0); + +// memory_copy.wast:1083 +assert_return(() => call($11, "load8_u", [1_591]), 0); + +// memory_copy.wast:1084 +assert_return(() => call($11, "load8_u", [1_790]), 0); + +// memory_copy.wast:1085 +assert_return(() => call($11, "load8_u", [1_989]), 0); + +// memory_copy.wast:1086 +assert_return(() => call($11, "load8_u", [2_188]), 0); + +// memory_copy.wast:1087 +assert_return(() => call($11, "load8_u", [2_387]), 0); + +// memory_copy.wast:1088 +assert_return(() => call($11, "load8_u", [2_586]), 0); + +// memory_copy.wast:1089 +assert_return(() => call($11, "load8_u", [2_785]), 0); + +// memory_copy.wast:1090 +assert_return(() => call($11, "load8_u", [2_984]), 0); + +// memory_copy.wast:1091 +assert_return(() => call($11, "load8_u", [3_183]), 0); + +// memory_copy.wast:1092 +assert_return(() => call($11, "load8_u", [3_382]), 0); + +// memory_copy.wast:1093 +assert_return(() => call($11, "load8_u", [3_581]), 0); + +// memory_copy.wast:1094 +assert_return(() => call($11, "load8_u", [3_780]), 0); + +// memory_copy.wast:1095 +assert_return(() => call($11, "load8_u", [3_979]), 0); + +// memory_copy.wast:1096 +assert_return(() => call($11, "load8_u", [4_178]), 0); + +// memory_copy.wast:1097 +assert_return(() => call($11, "load8_u", [4_377]), 0); + +// memory_copy.wast:1098 +assert_return(() => call($11, "load8_u", [4_576]), 0); + +// memory_copy.wast:1099 +assert_return(() => call($11, "load8_u", [4_775]), 0); + +// memory_copy.wast:1100 +assert_return(() => call($11, "load8_u", [4_974]), 0); + +// memory_copy.wast:1101 +assert_return(() => call($11, "load8_u", [5_173]), 0); + +// memory_copy.wast:1102 +assert_return(() => call($11, "load8_u", [5_372]), 0); + +// memory_copy.wast:1103 +assert_return(() => call($11, "load8_u", [5_571]), 0); + +// memory_copy.wast:1104 +assert_return(() => call($11, "load8_u", [5_770]), 0); + +// memory_copy.wast:1105 +assert_return(() => call($11, "load8_u", [5_969]), 0); + +// memory_copy.wast:1106 +assert_return(() => call($11, "load8_u", [6_168]), 0); + +// memory_copy.wast:1107 +assert_return(() => call($11, "load8_u", [6_367]), 0); + +// memory_copy.wast:1108 +assert_return(() => call($11, "load8_u", [6_566]), 0); + +// memory_copy.wast:1109 +assert_return(() => call($11, "load8_u", [6_765]), 0); + +// memory_copy.wast:1110 +assert_return(() => call($11, "load8_u", [6_964]), 0); + +// memory_copy.wast:1111 +assert_return(() => call($11, "load8_u", [7_163]), 0); + +// memory_copy.wast:1112 +assert_return(() => call($11, "load8_u", [7_362]), 0); + +// memory_copy.wast:1113 +assert_return(() => call($11, "load8_u", [7_561]), 0); + +// memory_copy.wast:1114 +assert_return(() => call($11, "load8_u", [7_760]), 0); + +// memory_copy.wast:1115 +assert_return(() => call($11, "load8_u", [7_959]), 0); + +// memory_copy.wast:1116 +assert_return(() => call($11, "load8_u", [8_158]), 0); + +// memory_copy.wast:1117 +assert_return(() => call($11, "load8_u", [8_357]), 0); + +// memory_copy.wast:1118 +assert_return(() => call($11, "load8_u", [8_556]), 0); + +// memory_copy.wast:1119 +assert_return(() => call($11, "load8_u", [8_755]), 0); + +// memory_copy.wast:1120 +assert_return(() => call($11, "load8_u", [8_954]), 0); + +// memory_copy.wast:1121 +assert_return(() => call($11, "load8_u", [9_153]), 0); + +// memory_copy.wast:1122 +assert_return(() => call($11, "load8_u", [9_352]), 0); + +// memory_copy.wast:1123 +assert_return(() => call($11, "load8_u", [9_551]), 0); + +// memory_copy.wast:1124 +assert_return(() => call($11, "load8_u", [9_750]), 0); + +// memory_copy.wast:1125 +assert_return(() => call($11, "load8_u", [9_949]), 0); + +// memory_copy.wast:1126 +assert_return(() => call($11, "load8_u", [10_148]), 0); + +// memory_copy.wast:1127 +assert_return(() => call($11, "load8_u", [10_347]), 0); + +// memory_copy.wast:1128 +assert_return(() => call($11, "load8_u", [10_546]), 0); + +// memory_copy.wast:1129 +assert_return(() => call($11, "load8_u", [10_745]), 0); + +// memory_copy.wast:1130 +assert_return(() => call($11, "load8_u", [10_944]), 0); + +// memory_copy.wast:1131 +assert_return(() => call($11, "load8_u", [11_143]), 0); + +// memory_copy.wast:1132 +assert_return(() => call($11, "load8_u", [11_342]), 0); + +// memory_copy.wast:1133 +assert_return(() => call($11, "load8_u", [11_541]), 0); + +// memory_copy.wast:1134 +assert_return(() => call($11, "load8_u", [11_740]), 0); + +// memory_copy.wast:1135 +assert_return(() => call($11, "load8_u", [11_939]), 0); + +// memory_copy.wast:1136 +assert_return(() => call($11, "load8_u", [12_138]), 0); + +// memory_copy.wast:1137 +assert_return(() => call($11, "load8_u", [12_337]), 0); + +// memory_copy.wast:1138 +assert_return(() => call($11, "load8_u", [12_536]), 0); + +// memory_copy.wast:1139 +assert_return(() => call($11, "load8_u", [12_735]), 0); + +// memory_copy.wast:1140 +assert_return(() => call($11, "load8_u", [12_934]), 0); + +// memory_copy.wast:1141 +assert_return(() => call($11, "load8_u", [13_133]), 0); + +// memory_copy.wast:1142 +assert_return(() => call($11, "load8_u", [13_332]), 0); + +// memory_copy.wast:1143 +assert_return(() => call($11, "load8_u", [13_531]), 0); + +// memory_copy.wast:1144 +assert_return(() => call($11, "load8_u", [13_730]), 0); + +// memory_copy.wast:1145 +assert_return(() => call($11, "load8_u", [13_929]), 0); + +// memory_copy.wast:1146 +assert_return(() => call($11, "load8_u", [14_128]), 0); + +// memory_copy.wast:1147 +assert_return(() => call($11, "load8_u", [14_327]), 0); + +// memory_copy.wast:1148 +assert_return(() => call($11, "load8_u", [14_526]), 0); + +// memory_copy.wast:1149 +assert_return(() => call($11, "load8_u", [14_725]), 0); + +// memory_copy.wast:1150 +assert_return(() => call($11, "load8_u", [14_924]), 0); + +// memory_copy.wast:1151 +assert_return(() => call($11, "load8_u", [15_123]), 0); + +// memory_copy.wast:1152 +assert_return(() => call($11, "load8_u", [15_322]), 0); + +// memory_copy.wast:1153 +assert_return(() => call($11, "load8_u", [15_521]), 0); + +// memory_copy.wast:1154 +assert_return(() => call($11, "load8_u", [15_720]), 0); + +// memory_copy.wast:1155 +assert_return(() => call($11, "load8_u", [15_919]), 0); + +// memory_copy.wast:1156 +assert_return(() => call($11, "load8_u", [16_118]), 0); + +// memory_copy.wast:1157 +assert_return(() => call($11, "load8_u", [16_317]), 0); + +// memory_copy.wast:1158 +assert_return(() => call($11, "load8_u", [16_516]), 0); + +// memory_copy.wast:1159 +assert_return(() => call($11, "load8_u", [16_715]), 0); + +// memory_copy.wast:1160 +assert_return(() => call($11, "load8_u", [16_914]), 0); + +// memory_copy.wast:1161 +assert_return(() => call($11, "load8_u", [17_113]), 0); + +// memory_copy.wast:1162 +assert_return(() => call($11, "load8_u", [17_312]), 0); + +// memory_copy.wast:1163 +assert_return(() => call($11, "load8_u", [17_511]), 0); + +// memory_copy.wast:1164 +assert_return(() => call($11, "load8_u", [17_710]), 0); + +// memory_copy.wast:1165 +assert_return(() => call($11, "load8_u", [17_909]), 0); + +// memory_copy.wast:1166 +assert_return(() => call($11, "load8_u", [18_108]), 0); + +// memory_copy.wast:1167 +assert_return(() => call($11, "load8_u", [18_307]), 0); + +// memory_copy.wast:1168 +assert_return(() => call($11, "load8_u", [18_506]), 0); + +// memory_copy.wast:1169 +assert_return(() => call($11, "load8_u", [18_705]), 0); + +// memory_copy.wast:1170 +assert_return(() => call($11, "load8_u", [18_904]), 0); + +// memory_copy.wast:1171 +assert_return(() => call($11, "load8_u", [19_103]), 0); + +// memory_copy.wast:1172 +assert_return(() => call($11, "load8_u", [19_302]), 0); + +// memory_copy.wast:1173 +assert_return(() => call($11, "load8_u", [19_501]), 0); + +// memory_copy.wast:1174 +assert_return(() => call($11, "load8_u", [19_700]), 0); + +// memory_copy.wast:1175 +assert_return(() => call($11, "load8_u", [19_899]), 0); + +// memory_copy.wast:1176 +assert_return(() => call($11, "load8_u", [20_098]), 0); + +// memory_copy.wast:1177 +assert_return(() => call($11, "load8_u", [20_297]), 0); + +// memory_copy.wast:1178 +assert_return(() => call($11, "load8_u", [20_496]), 0); + +// memory_copy.wast:1179 +assert_return(() => call($11, "load8_u", [20_695]), 0); + +// memory_copy.wast:1180 +assert_return(() => call($11, "load8_u", [20_894]), 0); + +// memory_copy.wast:1181 +assert_return(() => call($11, "load8_u", [21_093]), 0); + +// memory_copy.wast:1182 +assert_return(() => call($11, "load8_u", [21_292]), 0); + +// memory_copy.wast:1183 +assert_return(() => call($11, "load8_u", [21_491]), 0); + +// memory_copy.wast:1184 +assert_return(() => call($11, "load8_u", [21_690]), 0); + +// memory_copy.wast:1185 +assert_return(() => call($11, "load8_u", [21_889]), 0); + +// memory_copy.wast:1186 +assert_return(() => call($11, "load8_u", [22_088]), 0); + +// memory_copy.wast:1187 +assert_return(() => call($11, "load8_u", [22_287]), 0); + +// memory_copy.wast:1188 +assert_return(() => call($11, "load8_u", [22_486]), 0); + +// memory_copy.wast:1189 +assert_return(() => call($11, "load8_u", [22_685]), 0); + +// memory_copy.wast:1190 +assert_return(() => call($11, "load8_u", [22_884]), 0); + +// memory_copy.wast:1191 +assert_return(() => call($11, "load8_u", [23_083]), 0); + +// memory_copy.wast:1192 +assert_return(() => call($11, "load8_u", [23_282]), 0); + +// memory_copy.wast:1193 +assert_return(() => call($11, "load8_u", [23_481]), 0); + +// memory_copy.wast:1194 +assert_return(() => call($11, "load8_u", [23_680]), 0); + +// memory_copy.wast:1195 +assert_return(() => call($11, "load8_u", [23_879]), 0); + +// memory_copy.wast:1196 +assert_return(() => call($11, "load8_u", [24_078]), 0); + +// memory_copy.wast:1197 +assert_return(() => call($11, "load8_u", [24_277]), 0); + +// memory_copy.wast:1198 +assert_return(() => call($11, "load8_u", [24_476]), 0); + +// memory_copy.wast:1199 +assert_return(() => call($11, "load8_u", [24_675]), 0); + +// memory_copy.wast:1200 +assert_return(() => call($11, "load8_u", [24_874]), 0); + +// memory_copy.wast:1201 +assert_return(() => call($11, "load8_u", [25_073]), 0); + +// memory_copy.wast:1202 +assert_return(() => call($11, "load8_u", [25_272]), 0); + +// memory_copy.wast:1203 +assert_return(() => call($11, "load8_u", [25_471]), 0); + +// memory_copy.wast:1204 +assert_return(() => call($11, "load8_u", [25_670]), 0); + +// memory_copy.wast:1205 +assert_return(() => call($11, "load8_u", [25_869]), 0); + +// memory_copy.wast:1206 +assert_return(() => call($11, "load8_u", [26_068]), 0); + +// memory_copy.wast:1207 +assert_return(() => call($11, "load8_u", [26_267]), 0); + +// memory_copy.wast:1208 +assert_return(() => call($11, "load8_u", [26_466]), 0); + +// memory_copy.wast:1209 +assert_return(() => call($11, "load8_u", [26_665]), 0); + +// memory_copy.wast:1210 +assert_return(() => call($11, "load8_u", [26_864]), 0); + +// memory_copy.wast:1211 +assert_return(() => call($11, "load8_u", [27_063]), 0); + +// memory_copy.wast:1212 +assert_return(() => call($11, "load8_u", [27_262]), 0); + +// memory_copy.wast:1213 +assert_return(() => call($11, "load8_u", [27_461]), 0); + +// memory_copy.wast:1214 +assert_return(() => call($11, "load8_u", [27_660]), 0); + +// memory_copy.wast:1215 +assert_return(() => call($11, "load8_u", [27_859]), 0); + +// memory_copy.wast:1216 +assert_return(() => call($11, "load8_u", [28_058]), 0); + +// memory_copy.wast:1217 +assert_return(() => call($11, "load8_u", [28_257]), 0); + +// memory_copy.wast:1218 +assert_return(() => call($11, "load8_u", [28_456]), 0); + +// memory_copy.wast:1219 +assert_return(() => call($11, "load8_u", [28_655]), 0); + +// memory_copy.wast:1220 +assert_return(() => call($11, "load8_u", [28_854]), 0); + +// memory_copy.wast:1221 +assert_return(() => call($11, "load8_u", [29_053]), 0); + +// memory_copy.wast:1222 +assert_return(() => call($11, "load8_u", [29_252]), 0); + +// memory_copy.wast:1223 +assert_return(() => call($11, "load8_u", [29_451]), 0); + +// memory_copy.wast:1224 +assert_return(() => call($11, "load8_u", [29_650]), 0); + +// memory_copy.wast:1225 +assert_return(() => call($11, "load8_u", [29_849]), 0); + +// memory_copy.wast:1226 +assert_return(() => call($11, "load8_u", [30_048]), 0); + +// memory_copy.wast:1227 +assert_return(() => call($11, "load8_u", [30_247]), 0); + +// memory_copy.wast:1228 +assert_return(() => call($11, "load8_u", [30_446]), 0); + +// memory_copy.wast:1229 +assert_return(() => call($11, "load8_u", [30_645]), 0); + +// memory_copy.wast:1230 +assert_return(() => call($11, "load8_u", [30_844]), 0); + +// memory_copy.wast:1231 +assert_return(() => call($11, "load8_u", [31_043]), 0); + +// memory_copy.wast:1232 +assert_return(() => call($11, "load8_u", [31_242]), 0); + +// memory_copy.wast:1233 +assert_return(() => call($11, "load8_u", [31_441]), 0); + +// memory_copy.wast:1234 +assert_return(() => call($11, "load8_u", [31_640]), 0); + +// memory_copy.wast:1235 +assert_return(() => call($11, "load8_u", [31_839]), 0); + +// memory_copy.wast:1236 +assert_return(() => call($11, "load8_u", [32_038]), 0); + +// memory_copy.wast:1237 +assert_return(() => call($11, "load8_u", [32_237]), 0); + +// memory_copy.wast:1238 +assert_return(() => call($11, "load8_u", [32_436]), 0); + +// memory_copy.wast:1239 +assert_return(() => call($11, "load8_u", [32_635]), 0); + +// memory_copy.wast:1240 +assert_return(() => call($11, "load8_u", [32_834]), 0); + +// memory_copy.wast:1241 +assert_return(() => call($11, "load8_u", [33_033]), 0); + +// memory_copy.wast:1242 +assert_return(() => call($11, "load8_u", [33_232]), 0); + +// memory_copy.wast:1243 +assert_return(() => call($11, "load8_u", [33_431]), 0); + +// memory_copy.wast:1244 +assert_return(() => call($11, "load8_u", [33_630]), 0); + +// memory_copy.wast:1245 +assert_return(() => call($11, "load8_u", [33_829]), 0); + +// memory_copy.wast:1246 +assert_return(() => call($11, "load8_u", [34_028]), 0); + +// memory_copy.wast:1247 +assert_return(() => call($11, "load8_u", [34_227]), 0); + +// memory_copy.wast:1248 +assert_return(() => call($11, "load8_u", [34_426]), 0); + +// memory_copy.wast:1249 +assert_return(() => call($11, "load8_u", [34_625]), 0); + +// memory_copy.wast:1250 +assert_return(() => call($11, "load8_u", [34_824]), 0); + +// memory_copy.wast:1251 +assert_return(() => call($11, "load8_u", [35_023]), 0); + +// memory_copy.wast:1252 +assert_return(() => call($11, "load8_u", [35_222]), 0); + +// memory_copy.wast:1253 +assert_return(() => call($11, "load8_u", [35_421]), 0); + +// memory_copy.wast:1254 +assert_return(() => call($11, "load8_u", [35_620]), 0); + +// memory_copy.wast:1255 +assert_return(() => call($11, "load8_u", [35_819]), 0); + +// memory_copy.wast:1256 +assert_return(() => call($11, "load8_u", [36_018]), 0); + +// memory_copy.wast:1257 +assert_return(() => call($11, "load8_u", [36_217]), 0); + +// memory_copy.wast:1258 +assert_return(() => call($11, "load8_u", [36_416]), 0); + +// memory_copy.wast:1259 +assert_return(() => call($11, "load8_u", [36_615]), 0); + +// memory_copy.wast:1260 +assert_return(() => call($11, "load8_u", [36_814]), 0); + +// memory_copy.wast:1261 +assert_return(() => call($11, "load8_u", [37_013]), 0); + +// memory_copy.wast:1262 +assert_return(() => call($11, "load8_u", [37_212]), 0); + +// memory_copy.wast:1263 +assert_return(() => call($11, "load8_u", [37_411]), 0); + +// memory_copy.wast:1264 +assert_return(() => call($11, "load8_u", [37_610]), 0); + +// memory_copy.wast:1265 +assert_return(() => call($11, "load8_u", [37_809]), 0); + +// memory_copy.wast:1266 +assert_return(() => call($11, "load8_u", [38_008]), 0); + +// memory_copy.wast:1267 +assert_return(() => call($11, "load8_u", [38_207]), 0); + +// memory_copy.wast:1268 +assert_return(() => call($11, "load8_u", [38_406]), 0); + +// memory_copy.wast:1269 +assert_return(() => call($11, "load8_u", [38_605]), 0); + +// memory_copy.wast:1270 +assert_return(() => call($11, "load8_u", [38_804]), 0); + +// memory_copy.wast:1271 +assert_return(() => call($11, "load8_u", [39_003]), 0); + +// memory_copy.wast:1272 +assert_return(() => call($11, "load8_u", [39_202]), 0); + +// memory_copy.wast:1273 +assert_return(() => call($11, "load8_u", [39_401]), 0); + +// memory_copy.wast:1274 +assert_return(() => call($11, "load8_u", [39_600]), 0); + +// memory_copy.wast:1275 +assert_return(() => call($11, "load8_u", [39_799]), 0); + +// memory_copy.wast:1276 +assert_return(() => call($11, "load8_u", [39_998]), 0); + +// memory_copy.wast:1277 +assert_return(() => call($11, "load8_u", [40_197]), 0); + +// memory_copy.wast:1278 +assert_return(() => call($11, "load8_u", [40_396]), 0); + +// memory_copy.wast:1279 +assert_return(() => call($11, "load8_u", [40_595]), 0); + +// memory_copy.wast:1280 +assert_return(() => call($11, "load8_u", [40_794]), 0); + +// memory_copy.wast:1281 +assert_return(() => call($11, "load8_u", [40_993]), 0); + +// memory_copy.wast:1282 +assert_return(() => call($11, "load8_u", [41_192]), 0); + +// memory_copy.wast:1283 +assert_return(() => call($11, "load8_u", [41_391]), 0); + +// memory_copy.wast:1284 +assert_return(() => call($11, "load8_u", [41_590]), 0); + +// memory_copy.wast:1285 +assert_return(() => call($11, "load8_u", [41_789]), 0); + +// memory_copy.wast:1286 +assert_return(() => call($11, "load8_u", [41_988]), 0); + +// memory_copy.wast:1287 +assert_return(() => call($11, "load8_u", [42_187]), 0); + +// memory_copy.wast:1288 +assert_return(() => call($11, "load8_u", [42_386]), 0); + +// memory_copy.wast:1289 +assert_return(() => call($11, "load8_u", [42_585]), 0); + +// memory_copy.wast:1290 +assert_return(() => call($11, "load8_u", [42_784]), 0); + +// memory_copy.wast:1291 +assert_return(() => call($11, "load8_u", [42_983]), 0); + +// memory_copy.wast:1292 +assert_return(() => call($11, "load8_u", [43_182]), 0); + +// memory_copy.wast:1293 +assert_return(() => call($11, "load8_u", [43_381]), 0); + +// memory_copy.wast:1294 +assert_return(() => call($11, "load8_u", [43_580]), 0); + +// memory_copy.wast:1295 +assert_return(() => call($11, "load8_u", [43_779]), 0); + +// memory_copy.wast:1296 +assert_return(() => call($11, "load8_u", [43_978]), 0); + +// memory_copy.wast:1297 +assert_return(() => call($11, "load8_u", [44_177]), 0); + +// memory_copy.wast:1298 +assert_return(() => call($11, "load8_u", [44_376]), 0); + +// memory_copy.wast:1299 +assert_return(() => call($11, "load8_u", [44_575]), 0); + +// memory_copy.wast:1300 +assert_return(() => call($11, "load8_u", [44_774]), 0); + +// memory_copy.wast:1301 +assert_return(() => call($11, "load8_u", [44_973]), 0); + +// memory_copy.wast:1302 +assert_return(() => call($11, "load8_u", [45_172]), 0); + +// memory_copy.wast:1303 +assert_return(() => call($11, "load8_u", [45_371]), 0); + +// memory_copy.wast:1304 +assert_return(() => call($11, "load8_u", [45_570]), 0); + +// memory_copy.wast:1305 +assert_return(() => call($11, "load8_u", [45_769]), 0); + +// memory_copy.wast:1306 +assert_return(() => call($11, "load8_u", [45_968]), 0); + +// memory_copy.wast:1307 +assert_return(() => call($11, "load8_u", [46_167]), 0); + +// memory_copy.wast:1308 +assert_return(() => call($11, "load8_u", [46_366]), 0); + +// memory_copy.wast:1309 +assert_return(() => call($11, "load8_u", [46_565]), 0); + +// memory_copy.wast:1310 +assert_return(() => call($11, "load8_u", [46_764]), 0); + +// memory_copy.wast:1311 +assert_return(() => call($11, "load8_u", [46_963]), 0); + +// memory_copy.wast:1312 +assert_return(() => call($11, "load8_u", [47_162]), 0); + +// memory_copy.wast:1313 +assert_return(() => call($11, "load8_u", [47_361]), 0); + +// memory_copy.wast:1314 +assert_return(() => call($11, "load8_u", [47_560]), 0); + +// memory_copy.wast:1315 +assert_return(() => call($11, "load8_u", [47_759]), 0); + +// memory_copy.wast:1316 +assert_return(() => call($11, "load8_u", [47_958]), 0); + +// memory_copy.wast:1317 +assert_return(() => call($11, "load8_u", [48_157]), 0); + +// memory_copy.wast:1318 +assert_return(() => call($11, "load8_u", [48_356]), 0); + +// memory_copy.wast:1319 +assert_return(() => call($11, "load8_u", [48_555]), 0); + +// memory_copy.wast:1320 +assert_return(() => call($11, "load8_u", [48_754]), 0); + +// memory_copy.wast:1321 +assert_return(() => call($11, "load8_u", [48_953]), 0); + +// memory_copy.wast:1322 +assert_return(() => call($11, "load8_u", [49_152]), 0); + +// memory_copy.wast:1323 +assert_return(() => call($11, "load8_u", [49_351]), 0); + +// memory_copy.wast:1324 +assert_return(() => call($11, "load8_u", [49_550]), 0); + +// memory_copy.wast:1325 +assert_return(() => call($11, "load8_u", [49_749]), 0); + +// memory_copy.wast:1326 +assert_return(() => call($11, "load8_u", [49_948]), 0); + +// memory_copy.wast:1327 +assert_return(() => call($11, "load8_u", [50_147]), 0); + +// memory_copy.wast:1328 +assert_return(() => call($11, "load8_u", [50_346]), 0); + +// memory_copy.wast:1329 +assert_return(() => call($11, "load8_u", [50_545]), 0); + +// memory_copy.wast:1330 +assert_return(() => call($11, "load8_u", [50_744]), 0); + +// memory_copy.wast:1331 +assert_return(() => call($11, "load8_u", [50_943]), 0); + +// memory_copy.wast:1332 +assert_return(() => call($11, "load8_u", [51_142]), 0); + +// memory_copy.wast:1333 +assert_return(() => call($11, "load8_u", [51_341]), 0); + +// memory_copy.wast:1334 +assert_return(() => call($11, "load8_u", [51_540]), 0); + +// memory_copy.wast:1335 +assert_return(() => call($11, "load8_u", [51_739]), 0); + +// memory_copy.wast:1336 +assert_return(() => call($11, "load8_u", [51_938]), 0); + +// memory_copy.wast:1337 +assert_return(() => call($11, "load8_u", [52_137]), 0); + +// memory_copy.wast:1338 +assert_return(() => call($11, "load8_u", [52_336]), 0); + +// memory_copy.wast:1339 +assert_return(() => call($11, "load8_u", [52_535]), 0); + +// memory_copy.wast:1340 +assert_return(() => call($11, "load8_u", [52_734]), 0); + +// memory_copy.wast:1341 +assert_return(() => call($11, "load8_u", [52_933]), 0); + +// memory_copy.wast:1342 +assert_return(() => call($11, "load8_u", [53_132]), 0); + +// memory_copy.wast:1343 +assert_return(() => call($11, "load8_u", [53_331]), 0); + +// memory_copy.wast:1344 +assert_return(() => call($11, "load8_u", [53_530]), 0); + +// memory_copy.wast:1345 +assert_return(() => call($11, "load8_u", [53_729]), 0); + +// memory_copy.wast:1346 +assert_return(() => call($11, "load8_u", [53_928]), 0); + +// memory_copy.wast:1347 +assert_return(() => call($11, "load8_u", [54_127]), 0); + +// memory_copy.wast:1348 +assert_return(() => call($11, "load8_u", [54_326]), 0); + +// memory_copy.wast:1349 +assert_return(() => call($11, "load8_u", [54_525]), 0); + +// memory_copy.wast:1350 +assert_return(() => call($11, "load8_u", [54_724]), 0); + +// memory_copy.wast:1351 +assert_return(() => call($11, "load8_u", [54_923]), 0); + +// memory_copy.wast:1352 +assert_return(() => call($11, "load8_u", [55_122]), 0); + +// memory_copy.wast:1353 +assert_return(() => call($11, "load8_u", [55_321]), 0); + +// memory_copy.wast:1354 +assert_return(() => call($11, "load8_u", [55_520]), 0); + +// memory_copy.wast:1355 +assert_return(() => call($11, "load8_u", [55_719]), 0); + +// memory_copy.wast:1356 +assert_return(() => call($11, "load8_u", [55_918]), 0); + +// memory_copy.wast:1357 +assert_return(() => call($11, "load8_u", [56_117]), 0); + +// memory_copy.wast:1358 +assert_return(() => call($11, "load8_u", [56_316]), 0); + +// memory_copy.wast:1359 +assert_return(() => call($11, "load8_u", [56_515]), 0); + +// memory_copy.wast:1360 +assert_return(() => call($11, "load8_u", [56_714]), 0); + +// memory_copy.wast:1361 +assert_return(() => call($11, "load8_u", [56_913]), 0); + +// memory_copy.wast:1362 +assert_return(() => call($11, "load8_u", [57_112]), 0); + +// memory_copy.wast:1363 +assert_return(() => call($11, "load8_u", [57_311]), 0); + +// memory_copy.wast:1364 +assert_return(() => call($11, "load8_u", [57_510]), 0); + +// memory_copy.wast:1365 +assert_return(() => call($11, "load8_u", [57_709]), 0); + +// memory_copy.wast:1366 +assert_return(() => call($11, "load8_u", [57_908]), 0); + +// memory_copy.wast:1367 +assert_return(() => call($11, "load8_u", [58_107]), 0); + +// memory_copy.wast:1368 +assert_return(() => call($11, "load8_u", [58_306]), 0); + +// memory_copy.wast:1369 +assert_return(() => call($11, "load8_u", [58_505]), 0); + +// memory_copy.wast:1370 +assert_return(() => call($11, "load8_u", [58_704]), 0); + +// memory_copy.wast:1371 +assert_return(() => call($11, "load8_u", [58_903]), 0); + +// memory_copy.wast:1372 +assert_return(() => call($11, "load8_u", [59_102]), 0); + +// memory_copy.wast:1373 +assert_return(() => call($11, "load8_u", [59_301]), 0); + +// memory_copy.wast:1374 +assert_return(() => call($11, "load8_u", [59_500]), 0); + +// memory_copy.wast:1375 +assert_return(() => call($11, "load8_u", [59_699]), 0); + +// memory_copy.wast:1376 +assert_return(() => call($11, "load8_u", [59_898]), 0); + +// memory_copy.wast:1377 +assert_return(() => call($11, "load8_u", [60_097]), 0); + +// memory_copy.wast:1378 +assert_return(() => call($11, "load8_u", [60_296]), 0); + +// memory_copy.wast:1379 +assert_return(() => call($11, "load8_u", [60_495]), 0); + +// memory_copy.wast:1380 +assert_return(() => call($11, "load8_u", [60_694]), 0); + +// memory_copy.wast:1381 +assert_return(() => call($11, "load8_u", [60_893]), 0); + +// memory_copy.wast:1382 +assert_return(() => call($11, "load8_u", [61_092]), 0); + +// memory_copy.wast:1383 +assert_return(() => call($11, "load8_u", [61_291]), 0); + +// memory_copy.wast:1384 +assert_return(() => call($11, "load8_u", [61_490]), 0); + +// memory_copy.wast:1385 +assert_return(() => call($11, "load8_u", [61_689]), 0); + +// memory_copy.wast:1386 +assert_return(() => call($11, "load8_u", [61_888]), 0); + +// memory_copy.wast:1387 +assert_return(() => call($11, "load8_u", [62_087]), 0); + +// memory_copy.wast:1388 +assert_return(() => call($11, "load8_u", [62_286]), 0); + +// memory_copy.wast:1389 +assert_return(() => call($11, "load8_u", [62_485]), 0); + +// memory_copy.wast:1390 +assert_return(() => call($11, "load8_u", [62_684]), 0); + +// memory_copy.wast:1391 +assert_return(() => call($11, "load8_u", [62_883]), 0); + +// memory_copy.wast:1392 +assert_return(() => call($11, "load8_u", [63_082]), 0); + +// memory_copy.wast:1393 +assert_return(() => call($11, "load8_u", [63_281]), 0); + +// memory_copy.wast:1394 +assert_return(() => call($11, "load8_u", [63_480]), 0); + +// memory_copy.wast:1395 +assert_return(() => call($11, "load8_u", [63_679]), 0); + +// memory_copy.wast:1396 +assert_return(() => call($11, "load8_u", [63_878]), 0); + +// memory_copy.wast:1397 +assert_return(() => call($11, "load8_u", [64_077]), 0); + +// memory_copy.wast:1398 +assert_return(() => call($11, "load8_u", [64_276]), 0); + +// memory_copy.wast:1399 +assert_return(() => call($11, "load8_u", [64_475]), 0); + +// memory_copy.wast:1400 +assert_return(() => call($11, "load8_u", [64_674]), 0); + +// memory_copy.wast:1401 +assert_return(() => call($11, "load8_u", [64_873]), 0); + +// memory_copy.wast:1402 +assert_return(() => call($11, "load8_u", [65_072]), 0); + +// memory_copy.wast:1403 +assert_return(() => call($11, "load8_u", [65_271]), 0); + +// memory_copy.wast:1404 +assert_return(() => call($11, "load8_u", [65_470]), 0); + +// memory_copy.wast:1405 +assert_return(() => call($11, "load8_u", [65_516]), 0); + +// memory_copy.wast:1406 +assert_return(() => call($11, "load8_u", [65_517]), 1); + +// memory_copy.wast:1407 +assert_return(() => call($11, "load8_u", [65_518]), 2); + +// memory_copy.wast:1408 +assert_return(() => call($11, "load8_u", [65_519]), 3); + +// memory_copy.wast:1409 +assert_return(() => call($11, "load8_u", [65_520]), 4); + +// memory_copy.wast:1410 +assert_return(() => call($11, "load8_u", [65_521]), 5); + +// memory_copy.wast:1411 +assert_return(() => call($11, "load8_u", [65_522]), 6); + +// memory_copy.wast:1412 +assert_return(() => call($11, "load8_u", [65_523]), 7); + +// memory_copy.wast:1413 +assert_return(() => call($11, "load8_u", [65_524]), 8); + +// memory_copy.wast:1414 +assert_return(() => call($11, "load8_u", [65_525]), 9); + +// memory_copy.wast:1415 +assert_return(() => call($11, "load8_u", [65_526]), 10); + +// memory_copy.wast:1416 +assert_return(() => call($11, "load8_u", [65_527]), 11); + +// memory_copy.wast:1417 +assert_return(() => call($11, "load8_u", [65_528]), 12); + +// memory_copy.wast:1418 +assert_return(() => call($11, "load8_u", [65_529]), 13); + +// memory_copy.wast:1419 +assert_return(() => call($11, "load8_u", [65_530]), 14); + +// memory_copy.wast:1420 +assert_return(() => call($11, "load8_u", [65_531]), 15); + +// memory_copy.wast:1421 +assert_return(() => call($11, "load8_u", [65_532]), 16); + +// memory_copy.wast:1422 +assert_return(() => call($11, "load8_u", [65_533]), 17); + +// memory_copy.wast:1423 +assert_return(() => call($11, "load8_u", [65_534]), 18); + +// memory_copy.wast:1424 +assert_return(() => call($11, "load8_u", [65_535]), 19); + +// memory_copy.wast:1426 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9d\x80\x80\x80\x00\x01\x00\x41\xeb\xff\x03\x0b\x15\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"); + +// memory_copy.wast:1434 +assert_trap(() => call($12, "run", [0, 65_515, 39])); + +// memory_copy.wast:1437 +assert_return(() => call($12, "load8_u", [198]), 0); + +// memory_copy.wast:1438 +assert_return(() => call($12, "load8_u", [397]), 0); + +// memory_copy.wast:1439 +assert_return(() => call($12, "load8_u", [596]), 0); + +// memory_copy.wast:1440 +assert_return(() => call($12, "load8_u", [795]), 0); + +// memory_copy.wast:1441 +assert_return(() => call($12, "load8_u", [994]), 0); + +// memory_copy.wast:1442 +assert_return(() => call($12, "load8_u", [1_193]), 0); + +// memory_copy.wast:1443 +assert_return(() => call($12, "load8_u", [1_392]), 0); + +// memory_copy.wast:1444 +assert_return(() => call($12, "load8_u", [1_591]), 0); + +// memory_copy.wast:1445 +assert_return(() => call($12, "load8_u", [1_790]), 0); + +// memory_copy.wast:1446 +assert_return(() => call($12, "load8_u", [1_989]), 0); + +// memory_copy.wast:1447 +assert_return(() => call($12, "load8_u", [2_188]), 0); + +// memory_copy.wast:1448 +assert_return(() => call($12, "load8_u", [2_387]), 0); + +// memory_copy.wast:1449 +assert_return(() => call($12, "load8_u", [2_586]), 0); + +// memory_copy.wast:1450 +assert_return(() => call($12, "load8_u", [2_785]), 0); + +// memory_copy.wast:1451 +assert_return(() => call($12, "load8_u", [2_984]), 0); + +// memory_copy.wast:1452 +assert_return(() => call($12, "load8_u", [3_183]), 0); + +// memory_copy.wast:1453 +assert_return(() => call($12, "load8_u", [3_382]), 0); + +// memory_copy.wast:1454 +assert_return(() => call($12, "load8_u", [3_581]), 0); + +// memory_copy.wast:1455 +assert_return(() => call($12, "load8_u", [3_780]), 0); + +// memory_copy.wast:1456 +assert_return(() => call($12, "load8_u", [3_979]), 0); + +// memory_copy.wast:1457 +assert_return(() => call($12, "load8_u", [4_178]), 0); + +// memory_copy.wast:1458 +assert_return(() => call($12, "load8_u", [4_377]), 0); + +// memory_copy.wast:1459 +assert_return(() => call($12, "load8_u", [4_576]), 0); + +// memory_copy.wast:1460 +assert_return(() => call($12, "load8_u", [4_775]), 0); + +// memory_copy.wast:1461 +assert_return(() => call($12, "load8_u", [4_974]), 0); + +// memory_copy.wast:1462 +assert_return(() => call($12, "load8_u", [5_173]), 0); + +// memory_copy.wast:1463 +assert_return(() => call($12, "load8_u", [5_372]), 0); + +// memory_copy.wast:1464 +assert_return(() => call($12, "load8_u", [5_571]), 0); + +// memory_copy.wast:1465 +assert_return(() => call($12, "load8_u", [5_770]), 0); + +// memory_copy.wast:1466 +assert_return(() => call($12, "load8_u", [5_969]), 0); + +// memory_copy.wast:1467 +assert_return(() => call($12, "load8_u", [6_168]), 0); + +// memory_copy.wast:1468 +assert_return(() => call($12, "load8_u", [6_367]), 0); + +// memory_copy.wast:1469 +assert_return(() => call($12, "load8_u", [6_566]), 0); + +// memory_copy.wast:1470 +assert_return(() => call($12, "load8_u", [6_765]), 0); + +// memory_copy.wast:1471 +assert_return(() => call($12, "load8_u", [6_964]), 0); + +// memory_copy.wast:1472 +assert_return(() => call($12, "load8_u", [7_163]), 0); + +// memory_copy.wast:1473 +assert_return(() => call($12, "load8_u", [7_362]), 0); + +// memory_copy.wast:1474 +assert_return(() => call($12, "load8_u", [7_561]), 0); + +// memory_copy.wast:1475 +assert_return(() => call($12, "load8_u", [7_760]), 0); + +// memory_copy.wast:1476 +assert_return(() => call($12, "load8_u", [7_959]), 0); + +// memory_copy.wast:1477 +assert_return(() => call($12, "load8_u", [8_158]), 0); + +// memory_copy.wast:1478 +assert_return(() => call($12, "load8_u", [8_357]), 0); + +// memory_copy.wast:1479 +assert_return(() => call($12, "load8_u", [8_556]), 0); + +// memory_copy.wast:1480 +assert_return(() => call($12, "load8_u", [8_755]), 0); + +// memory_copy.wast:1481 +assert_return(() => call($12, "load8_u", [8_954]), 0); + +// memory_copy.wast:1482 +assert_return(() => call($12, "load8_u", [9_153]), 0); + +// memory_copy.wast:1483 +assert_return(() => call($12, "load8_u", [9_352]), 0); + +// memory_copy.wast:1484 +assert_return(() => call($12, "load8_u", [9_551]), 0); + +// memory_copy.wast:1485 +assert_return(() => call($12, "load8_u", [9_750]), 0); + +// memory_copy.wast:1486 +assert_return(() => call($12, "load8_u", [9_949]), 0); + +// memory_copy.wast:1487 +assert_return(() => call($12, "load8_u", [10_148]), 0); + +// memory_copy.wast:1488 +assert_return(() => call($12, "load8_u", [10_347]), 0); + +// memory_copy.wast:1489 +assert_return(() => call($12, "load8_u", [10_546]), 0); + +// memory_copy.wast:1490 +assert_return(() => call($12, "load8_u", [10_745]), 0); + +// memory_copy.wast:1491 +assert_return(() => call($12, "load8_u", [10_944]), 0); + +// memory_copy.wast:1492 +assert_return(() => call($12, "load8_u", [11_143]), 0); + +// memory_copy.wast:1493 +assert_return(() => call($12, "load8_u", [11_342]), 0); + +// memory_copy.wast:1494 +assert_return(() => call($12, "load8_u", [11_541]), 0); + +// memory_copy.wast:1495 +assert_return(() => call($12, "load8_u", [11_740]), 0); + +// memory_copy.wast:1496 +assert_return(() => call($12, "load8_u", [11_939]), 0); + +// memory_copy.wast:1497 +assert_return(() => call($12, "load8_u", [12_138]), 0); + +// memory_copy.wast:1498 +assert_return(() => call($12, "load8_u", [12_337]), 0); + +// memory_copy.wast:1499 +assert_return(() => call($12, "load8_u", [12_536]), 0); + +// memory_copy.wast:1500 +assert_return(() => call($12, "load8_u", [12_735]), 0); + +// memory_copy.wast:1501 +assert_return(() => call($12, "load8_u", [12_934]), 0); + +// memory_copy.wast:1502 +assert_return(() => call($12, "load8_u", [13_133]), 0); + +// memory_copy.wast:1503 +assert_return(() => call($12, "load8_u", [13_332]), 0); + +// memory_copy.wast:1504 +assert_return(() => call($12, "load8_u", [13_531]), 0); + +// memory_copy.wast:1505 +assert_return(() => call($12, "load8_u", [13_730]), 0); + +// memory_copy.wast:1506 +assert_return(() => call($12, "load8_u", [13_929]), 0); + +// memory_copy.wast:1507 +assert_return(() => call($12, "load8_u", [14_128]), 0); + +// memory_copy.wast:1508 +assert_return(() => call($12, "load8_u", [14_327]), 0); + +// memory_copy.wast:1509 +assert_return(() => call($12, "load8_u", [14_526]), 0); + +// memory_copy.wast:1510 +assert_return(() => call($12, "load8_u", [14_725]), 0); + +// memory_copy.wast:1511 +assert_return(() => call($12, "load8_u", [14_924]), 0); + +// memory_copy.wast:1512 +assert_return(() => call($12, "load8_u", [15_123]), 0); + +// memory_copy.wast:1513 +assert_return(() => call($12, "load8_u", [15_322]), 0); + +// memory_copy.wast:1514 +assert_return(() => call($12, "load8_u", [15_521]), 0); + +// memory_copy.wast:1515 +assert_return(() => call($12, "load8_u", [15_720]), 0); + +// memory_copy.wast:1516 +assert_return(() => call($12, "load8_u", [15_919]), 0); + +// memory_copy.wast:1517 +assert_return(() => call($12, "load8_u", [16_118]), 0); + +// memory_copy.wast:1518 +assert_return(() => call($12, "load8_u", [16_317]), 0); + +// memory_copy.wast:1519 +assert_return(() => call($12, "load8_u", [16_516]), 0); + +// memory_copy.wast:1520 +assert_return(() => call($12, "load8_u", [16_715]), 0); + +// memory_copy.wast:1521 +assert_return(() => call($12, "load8_u", [16_914]), 0); + +// memory_copy.wast:1522 +assert_return(() => call($12, "load8_u", [17_113]), 0); + +// memory_copy.wast:1523 +assert_return(() => call($12, "load8_u", [17_312]), 0); + +// memory_copy.wast:1524 +assert_return(() => call($12, "load8_u", [17_511]), 0); + +// memory_copy.wast:1525 +assert_return(() => call($12, "load8_u", [17_710]), 0); + +// memory_copy.wast:1526 +assert_return(() => call($12, "load8_u", [17_909]), 0); + +// memory_copy.wast:1527 +assert_return(() => call($12, "load8_u", [18_108]), 0); + +// memory_copy.wast:1528 +assert_return(() => call($12, "load8_u", [18_307]), 0); + +// memory_copy.wast:1529 +assert_return(() => call($12, "load8_u", [18_506]), 0); + +// memory_copy.wast:1530 +assert_return(() => call($12, "load8_u", [18_705]), 0); + +// memory_copy.wast:1531 +assert_return(() => call($12, "load8_u", [18_904]), 0); + +// memory_copy.wast:1532 +assert_return(() => call($12, "load8_u", [19_103]), 0); + +// memory_copy.wast:1533 +assert_return(() => call($12, "load8_u", [19_302]), 0); + +// memory_copy.wast:1534 +assert_return(() => call($12, "load8_u", [19_501]), 0); + +// memory_copy.wast:1535 +assert_return(() => call($12, "load8_u", [19_700]), 0); + +// memory_copy.wast:1536 +assert_return(() => call($12, "load8_u", [19_899]), 0); + +// memory_copy.wast:1537 +assert_return(() => call($12, "load8_u", [20_098]), 0); + +// memory_copy.wast:1538 +assert_return(() => call($12, "load8_u", [20_297]), 0); + +// memory_copy.wast:1539 +assert_return(() => call($12, "load8_u", [20_496]), 0); + +// memory_copy.wast:1540 +assert_return(() => call($12, "load8_u", [20_695]), 0); + +// memory_copy.wast:1541 +assert_return(() => call($12, "load8_u", [20_894]), 0); + +// memory_copy.wast:1542 +assert_return(() => call($12, "load8_u", [21_093]), 0); + +// memory_copy.wast:1543 +assert_return(() => call($12, "load8_u", [21_292]), 0); + +// memory_copy.wast:1544 +assert_return(() => call($12, "load8_u", [21_491]), 0); + +// memory_copy.wast:1545 +assert_return(() => call($12, "load8_u", [21_690]), 0); + +// memory_copy.wast:1546 +assert_return(() => call($12, "load8_u", [21_889]), 0); + +// memory_copy.wast:1547 +assert_return(() => call($12, "load8_u", [22_088]), 0); + +// memory_copy.wast:1548 +assert_return(() => call($12, "load8_u", [22_287]), 0); + +// memory_copy.wast:1549 +assert_return(() => call($12, "load8_u", [22_486]), 0); + +// memory_copy.wast:1550 +assert_return(() => call($12, "load8_u", [22_685]), 0); + +// memory_copy.wast:1551 +assert_return(() => call($12, "load8_u", [22_884]), 0); + +// memory_copy.wast:1552 +assert_return(() => call($12, "load8_u", [23_083]), 0); + +// memory_copy.wast:1553 +assert_return(() => call($12, "load8_u", [23_282]), 0); + +// memory_copy.wast:1554 +assert_return(() => call($12, "load8_u", [23_481]), 0); + +// memory_copy.wast:1555 +assert_return(() => call($12, "load8_u", [23_680]), 0); + +// memory_copy.wast:1556 +assert_return(() => call($12, "load8_u", [23_879]), 0); + +// memory_copy.wast:1557 +assert_return(() => call($12, "load8_u", [24_078]), 0); + +// memory_copy.wast:1558 +assert_return(() => call($12, "load8_u", [24_277]), 0); + +// memory_copy.wast:1559 +assert_return(() => call($12, "load8_u", [24_476]), 0); + +// memory_copy.wast:1560 +assert_return(() => call($12, "load8_u", [24_675]), 0); + +// memory_copy.wast:1561 +assert_return(() => call($12, "load8_u", [24_874]), 0); + +// memory_copy.wast:1562 +assert_return(() => call($12, "load8_u", [25_073]), 0); + +// memory_copy.wast:1563 +assert_return(() => call($12, "load8_u", [25_272]), 0); + +// memory_copy.wast:1564 +assert_return(() => call($12, "load8_u", [25_471]), 0); + +// memory_copy.wast:1565 +assert_return(() => call($12, "load8_u", [25_670]), 0); + +// memory_copy.wast:1566 +assert_return(() => call($12, "load8_u", [25_869]), 0); + +// memory_copy.wast:1567 +assert_return(() => call($12, "load8_u", [26_068]), 0); + +// memory_copy.wast:1568 +assert_return(() => call($12, "load8_u", [26_267]), 0); + +// memory_copy.wast:1569 +assert_return(() => call($12, "load8_u", [26_466]), 0); + +// memory_copy.wast:1570 +assert_return(() => call($12, "load8_u", [26_665]), 0); + +// memory_copy.wast:1571 +assert_return(() => call($12, "load8_u", [26_864]), 0); + +// memory_copy.wast:1572 +assert_return(() => call($12, "load8_u", [27_063]), 0); + +// memory_copy.wast:1573 +assert_return(() => call($12, "load8_u", [27_262]), 0); + +// memory_copy.wast:1574 +assert_return(() => call($12, "load8_u", [27_461]), 0); + +// memory_copy.wast:1575 +assert_return(() => call($12, "load8_u", [27_660]), 0); + +// memory_copy.wast:1576 +assert_return(() => call($12, "load8_u", [27_859]), 0); + +// memory_copy.wast:1577 +assert_return(() => call($12, "load8_u", [28_058]), 0); + +// memory_copy.wast:1578 +assert_return(() => call($12, "load8_u", [28_257]), 0); + +// memory_copy.wast:1579 +assert_return(() => call($12, "load8_u", [28_456]), 0); + +// memory_copy.wast:1580 +assert_return(() => call($12, "load8_u", [28_655]), 0); + +// memory_copy.wast:1581 +assert_return(() => call($12, "load8_u", [28_854]), 0); + +// memory_copy.wast:1582 +assert_return(() => call($12, "load8_u", [29_053]), 0); + +// memory_copy.wast:1583 +assert_return(() => call($12, "load8_u", [29_252]), 0); + +// memory_copy.wast:1584 +assert_return(() => call($12, "load8_u", [29_451]), 0); + +// memory_copy.wast:1585 +assert_return(() => call($12, "load8_u", [29_650]), 0); + +// memory_copy.wast:1586 +assert_return(() => call($12, "load8_u", [29_849]), 0); + +// memory_copy.wast:1587 +assert_return(() => call($12, "load8_u", [30_048]), 0); + +// memory_copy.wast:1588 +assert_return(() => call($12, "load8_u", [30_247]), 0); + +// memory_copy.wast:1589 +assert_return(() => call($12, "load8_u", [30_446]), 0); + +// memory_copy.wast:1590 +assert_return(() => call($12, "load8_u", [30_645]), 0); + +// memory_copy.wast:1591 +assert_return(() => call($12, "load8_u", [30_844]), 0); + +// memory_copy.wast:1592 +assert_return(() => call($12, "load8_u", [31_043]), 0); + +// memory_copy.wast:1593 +assert_return(() => call($12, "load8_u", [31_242]), 0); + +// memory_copy.wast:1594 +assert_return(() => call($12, "load8_u", [31_441]), 0); + +// memory_copy.wast:1595 +assert_return(() => call($12, "load8_u", [31_640]), 0); + +// memory_copy.wast:1596 +assert_return(() => call($12, "load8_u", [31_839]), 0); + +// memory_copy.wast:1597 +assert_return(() => call($12, "load8_u", [32_038]), 0); + +// memory_copy.wast:1598 +assert_return(() => call($12, "load8_u", [32_237]), 0); + +// memory_copy.wast:1599 +assert_return(() => call($12, "load8_u", [32_436]), 0); + +// memory_copy.wast:1600 +assert_return(() => call($12, "load8_u", [32_635]), 0); + +// memory_copy.wast:1601 +assert_return(() => call($12, "load8_u", [32_834]), 0); + +// memory_copy.wast:1602 +assert_return(() => call($12, "load8_u", [33_033]), 0); + +// memory_copy.wast:1603 +assert_return(() => call($12, "load8_u", [33_232]), 0); + +// memory_copy.wast:1604 +assert_return(() => call($12, "load8_u", [33_431]), 0); + +// memory_copy.wast:1605 +assert_return(() => call($12, "load8_u", [33_630]), 0); + +// memory_copy.wast:1606 +assert_return(() => call($12, "load8_u", [33_829]), 0); + +// memory_copy.wast:1607 +assert_return(() => call($12, "load8_u", [34_028]), 0); + +// memory_copy.wast:1608 +assert_return(() => call($12, "load8_u", [34_227]), 0); + +// memory_copy.wast:1609 +assert_return(() => call($12, "load8_u", [34_426]), 0); + +// memory_copy.wast:1610 +assert_return(() => call($12, "load8_u", [34_625]), 0); + +// memory_copy.wast:1611 +assert_return(() => call($12, "load8_u", [34_824]), 0); + +// memory_copy.wast:1612 +assert_return(() => call($12, "load8_u", [35_023]), 0); + +// memory_copy.wast:1613 +assert_return(() => call($12, "load8_u", [35_222]), 0); + +// memory_copy.wast:1614 +assert_return(() => call($12, "load8_u", [35_421]), 0); + +// memory_copy.wast:1615 +assert_return(() => call($12, "load8_u", [35_620]), 0); + +// memory_copy.wast:1616 +assert_return(() => call($12, "load8_u", [35_819]), 0); + +// memory_copy.wast:1617 +assert_return(() => call($12, "load8_u", [36_018]), 0); + +// memory_copy.wast:1618 +assert_return(() => call($12, "load8_u", [36_217]), 0); + +// memory_copy.wast:1619 +assert_return(() => call($12, "load8_u", [36_416]), 0); + +// memory_copy.wast:1620 +assert_return(() => call($12, "load8_u", [36_615]), 0); + +// memory_copy.wast:1621 +assert_return(() => call($12, "load8_u", [36_814]), 0); + +// memory_copy.wast:1622 +assert_return(() => call($12, "load8_u", [37_013]), 0); + +// memory_copy.wast:1623 +assert_return(() => call($12, "load8_u", [37_212]), 0); + +// memory_copy.wast:1624 +assert_return(() => call($12, "load8_u", [37_411]), 0); + +// memory_copy.wast:1625 +assert_return(() => call($12, "load8_u", [37_610]), 0); + +// memory_copy.wast:1626 +assert_return(() => call($12, "load8_u", [37_809]), 0); + +// memory_copy.wast:1627 +assert_return(() => call($12, "load8_u", [38_008]), 0); + +// memory_copy.wast:1628 +assert_return(() => call($12, "load8_u", [38_207]), 0); + +// memory_copy.wast:1629 +assert_return(() => call($12, "load8_u", [38_406]), 0); + +// memory_copy.wast:1630 +assert_return(() => call($12, "load8_u", [38_605]), 0); + +// memory_copy.wast:1631 +assert_return(() => call($12, "load8_u", [38_804]), 0); + +// memory_copy.wast:1632 +assert_return(() => call($12, "load8_u", [39_003]), 0); + +// memory_copy.wast:1633 +assert_return(() => call($12, "load8_u", [39_202]), 0); + +// memory_copy.wast:1634 +assert_return(() => call($12, "load8_u", [39_401]), 0); + +// memory_copy.wast:1635 +assert_return(() => call($12, "load8_u", [39_600]), 0); + +// memory_copy.wast:1636 +assert_return(() => call($12, "load8_u", [39_799]), 0); + +// memory_copy.wast:1637 +assert_return(() => call($12, "load8_u", [39_998]), 0); + +// memory_copy.wast:1638 +assert_return(() => call($12, "load8_u", [40_197]), 0); + +// memory_copy.wast:1639 +assert_return(() => call($12, "load8_u", [40_396]), 0); + +// memory_copy.wast:1640 +assert_return(() => call($12, "load8_u", [40_595]), 0); + +// memory_copy.wast:1641 +assert_return(() => call($12, "load8_u", [40_794]), 0); + +// memory_copy.wast:1642 +assert_return(() => call($12, "load8_u", [40_993]), 0); + +// memory_copy.wast:1643 +assert_return(() => call($12, "load8_u", [41_192]), 0); + +// memory_copy.wast:1644 +assert_return(() => call($12, "load8_u", [41_391]), 0); + +// memory_copy.wast:1645 +assert_return(() => call($12, "load8_u", [41_590]), 0); + +// memory_copy.wast:1646 +assert_return(() => call($12, "load8_u", [41_789]), 0); + +// memory_copy.wast:1647 +assert_return(() => call($12, "load8_u", [41_988]), 0); + +// memory_copy.wast:1648 +assert_return(() => call($12, "load8_u", [42_187]), 0); + +// memory_copy.wast:1649 +assert_return(() => call($12, "load8_u", [42_386]), 0); + +// memory_copy.wast:1650 +assert_return(() => call($12, "load8_u", [42_585]), 0); + +// memory_copy.wast:1651 +assert_return(() => call($12, "load8_u", [42_784]), 0); + +// memory_copy.wast:1652 +assert_return(() => call($12, "load8_u", [42_983]), 0); + +// memory_copy.wast:1653 +assert_return(() => call($12, "load8_u", [43_182]), 0); + +// memory_copy.wast:1654 +assert_return(() => call($12, "load8_u", [43_381]), 0); + +// memory_copy.wast:1655 +assert_return(() => call($12, "load8_u", [43_580]), 0); + +// memory_copy.wast:1656 +assert_return(() => call($12, "load8_u", [43_779]), 0); + +// memory_copy.wast:1657 +assert_return(() => call($12, "load8_u", [43_978]), 0); + +// memory_copy.wast:1658 +assert_return(() => call($12, "load8_u", [44_177]), 0); + +// memory_copy.wast:1659 +assert_return(() => call($12, "load8_u", [44_376]), 0); + +// memory_copy.wast:1660 +assert_return(() => call($12, "load8_u", [44_575]), 0); + +// memory_copy.wast:1661 +assert_return(() => call($12, "load8_u", [44_774]), 0); + +// memory_copy.wast:1662 +assert_return(() => call($12, "load8_u", [44_973]), 0); + +// memory_copy.wast:1663 +assert_return(() => call($12, "load8_u", [45_172]), 0); + +// memory_copy.wast:1664 +assert_return(() => call($12, "load8_u", [45_371]), 0); + +// memory_copy.wast:1665 +assert_return(() => call($12, "load8_u", [45_570]), 0); + +// memory_copy.wast:1666 +assert_return(() => call($12, "load8_u", [45_769]), 0); + +// memory_copy.wast:1667 +assert_return(() => call($12, "load8_u", [45_968]), 0); + +// memory_copy.wast:1668 +assert_return(() => call($12, "load8_u", [46_167]), 0); + +// memory_copy.wast:1669 +assert_return(() => call($12, "load8_u", [46_366]), 0); + +// memory_copy.wast:1670 +assert_return(() => call($12, "load8_u", [46_565]), 0); + +// memory_copy.wast:1671 +assert_return(() => call($12, "load8_u", [46_764]), 0); + +// memory_copy.wast:1672 +assert_return(() => call($12, "load8_u", [46_963]), 0); + +// memory_copy.wast:1673 +assert_return(() => call($12, "load8_u", [47_162]), 0); + +// memory_copy.wast:1674 +assert_return(() => call($12, "load8_u", [47_361]), 0); + +// memory_copy.wast:1675 +assert_return(() => call($12, "load8_u", [47_560]), 0); + +// memory_copy.wast:1676 +assert_return(() => call($12, "load8_u", [47_759]), 0); + +// memory_copy.wast:1677 +assert_return(() => call($12, "load8_u", [47_958]), 0); + +// memory_copy.wast:1678 +assert_return(() => call($12, "load8_u", [48_157]), 0); + +// memory_copy.wast:1679 +assert_return(() => call($12, "load8_u", [48_356]), 0); + +// memory_copy.wast:1680 +assert_return(() => call($12, "load8_u", [48_555]), 0); + +// memory_copy.wast:1681 +assert_return(() => call($12, "load8_u", [48_754]), 0); + +// memory_copy.wast:1682 +assert_return(() => call($12, "load8_u", [48_953]), 0); + +// memory_copy.wast:1683 +assert_return(() => call($12, "load8_u", [49_152]), 0); + +// memory_copy.wast:1684 +assert_return(() => call($12, "load8_u", [49_351]), 0); + +// memory_copy.wast:1685 +assert_return(() => call($12, "load8_u", [49_550]), 0); + +// memory_copy.wast:1686 +assert_return(() => call($12, "load8_u", [49_749]), 0); + +// memory_copy.wast:1687 +assert_return(() => call($12, "load8_u", [49_948]), 0); + +// memory_copy.wast:1688 +assert_return(() => call($12, "load8_u", [50_147]), 0); + +// memory_copy.wast:1689 +assert_return(() => call($12, "load8_u", [50_346]), 0); + +// memory_copy.wast:1690 +assert_return(() => call($12, "load8_u", [50_545]), 0); + +// memory_copy.wast:1691 +assert_return(() => call($12, "load8_u", [50_744]), 0); + +// memory_copy.wast:1692 +assert_return(() => call($12, "load8_u", [50_943]), 0); + +// memory_copy.wast:1693 +assert_return(() => call($12, "load8_u", [51_142]), 0); + +// memory_copy.wast:1694 +assert_return(() => call($12, "load8_u", [51_341]), 0); + +// memory_copy.wast:1695 +assert_return(() => call($12, "load8_u", [51_540]), 0); + +// memory_copy.wast:1696 +assert_return(() => call($12, "load8_u", [51_739]), 0); + +// memory_copy.wast:1697 +assert_return(() => call($12, "load8_u", [51_938]), 0); + +// memory_copy.wast:1698 +assert_return(() => call($12, "load8_u", [52_137]), 0); + +// memory_copy.wast:1699 +assert_return(() => call($12, "load8_u", [52_336]), 0); + +// memory_copy.wast:1700 +assert_return(() => call($12, "load8_u", [52_535]), 0); + +// memory_copy.wast:1701 +assert_return(() => call($12, "load8_u", [52_734]), 0); + +// memory_copy.wast:1702 +assert_return(() => call($12, "load8_u", [52_933]), 0); + +// memory_copy.wast:1703 +assert_return(() => call($12, "load8_u", [53_132]), 0); + +// memory_copy.wast:1704 +assert_return(() => call($12, "load8_u", [53_331]), 0); + +// memory_copy.wast:1705 +assert_return(() => call($12, "load8_u", [53_530]), 0); + +// memory_copy.wast:1706 +assert_return(() => call($12, "load8_u", [53_729]), 0); + +// memory_copy.wast:1707 +assert_return(() => call($12, "load8_u", [53_928]), 0); + +// memory_copy.wast:1708 +assert_return(() => call($12, "load8_u", [54_127]), 0); + +// memory_copy.wast:1709 +assert_return(() => call($12, "load8_u", [54_326]), 0); + +// memory_copy.wast:1710 +assert_return(() => call($12, "load8_u", [54_525]), 0); + +// memory_copy.wast:1711 +assert_return(() => call($12, "load8_u", [54_724]), 0); + +// memory_copy.wast:1712 +assert_return(() => call($12, "load8_u", [54_923]), 0); + +// memory_copy.wast:1713 +assert_return(() => call($12, "load8_u", [55_122]), 0); + +// memory_copy.wast:1714 +assert_return(() => call($12, "load8_u", [55_321]), 0); + +// memory_copy.wast:1715 +assert_return(() => call($12, "load8_u", [55_520]), 0); + +// memory_copy.wast:1716 +assert_return(() => call($12, "load8_u", [55_719]), 0); + +// memory_copy.wast:1717 +assert_return(() => call($12, "load8_u", [55_918]), 0); + +// memory_copy.wast:1718 +assert_return(() => call($12, "load8_u", [56_117]), 0); + +// memory_copy.wast:1719 +assert_return(() => call($12, "load8_u", [56_316]), 0); + +// memory_copy.wast:1720 +assert_return(() => call($12, "load8_u", [56_515]), 0); + +// memory_copy.wast:1721 +assert_return(() => call($12, "load8_u", [56_714]), 0); + +// memory_copy.wast:1722 +assert_return(() => call($12, "load8_u", [56_913]), 0); + +// memory_copy.wast:1723 +assert_return(() => call($12, "load8_u", [57_112]), 0); + +// memory_copy.wast:1724 +assert_return(() => call($12, "load8_u", [57_311]), 0); + +// memory_copy.wast:1725 +assert_return(() => call($12, "load8_u", [57_510]), 0); + +// memory_copy.wast:1726 +assert_return(() => call($12, "load8_u", [57_709]), 0); + +// memory_copy.wast:1727 +assert_return(() => call($12, "load8_u", [57_908]), 0); + +// memory_copy.wast:1728 +assert_return(() => call($12, "load8_u", [58_107]), 0); + +// memory_copy.wast:1729 +assert_return(() => call($12, "load8_u", [58_306]), 0); + +// memory_copy.wast:1730 +assert_return(() => call($12, "load8_u", [58_505]), 0); + +// memory_copy.wast:1731 +assert_return(() => call($12, "load8_u", [58_704]), 0); + +// memory_copy.wast:1732 +assert_return(() => call($12, "load8_u", [58_903]), 0); + +// memory_copy.wast:1733 +assert_return(() => call($12, "load8_u", [59_102]), 0); + +// memory_copy.wast:1734 +assert_return(() => call($12, "load8_u", [59_301]), 0); + +// memory_copy.wast:1735 +assert_return(() => call($12, "load8_u", [59_500]), 0); + +// memory_copy.wast:1736 +assert_return(() => call($12, "load8_u", [59_699]), 0); + +// memory_copy.wast:1737 +assert_return(() => call($12, "load8_u", [59_898]), 0); + +// memory_copy.wast:1738 +assert_return(() => call($12, "load8_u", [60_097]), 0); + +// memory_copy.wast:1739 +assert_return(() => call($12, "load8_u", [60_296]), 0); + +// memory_copy.wast:1740 +assert_return(() => call($12, "load8_u", [60_495]), 0); + +// memory_copy.wast:1741 +assert_return(() => call($12, "load8_u", [60_694]), 0); + +// memory_copy.wast:1742 +assert_return(() => call($12, "load8_u", [60_893]), 0); + +// memory_copy.wast:1743 +assert_return(() => call($12, "load8_u", [61_092]), 0); + +// memory_copy.wast:1744 +assert_return(() => call($12, "load8_u", [61_291]), 0); + +// memory_copy.wast:1745 +assert_return(() => call($12, "load8_u", [61_490]), 0); + +// memory_copy.wast:1746 +assert_return(() => call($12, "load8_u", [61_689]), 0); + +// memory_copy.wast:1747 +assert_return(() => call($12, "load8_u", [61_888]), 0); + +// memory_copy.wast:1748 +assert_return(() => call($12, "load8_u", [62_087]), 0); + +// memory_copy.wast:1749 +assert_return(() => call($12, "load8_u", [62_286]), 0); + +// memory_copy.wast:1750 +assert_return(() => call($12, "load8_u", [62_485]), 0); + +// memory_copy.wast:1751 +assert_return(() => call($12, "load8_u", [62_684]), 0); + +// memory_copy.wast:1752 +assert_return(() => call($12, "load8_u", [62_883]), 0); + +// memory_copy.wast:1753 +assert_return(() => call($12, "load8_u", [63_082]), 0); + +// memory_copy.wast:1754 +assert_return(() => call($12, "load8_u", [63_281]), 0); + +// memory_copy.wast:1755 +assert_return(() => call($12, "load8_u", [63_480]), 0); + +// memory_copy.wast:1756 +assert_return(() => call($12, "load8_u", [63_679]), 0); + +// memory_copy.wast:1757 +assert_return(() => call($12, "load8_u", [63_878]), 0); + +// memory_copy.wast:1758 +assert_return(() => call($12, "load8_u", [64_077]), 0); + +// memory_copy.wast:1759 +assert_return(() => call($12, "load8_u", [64_276]), 0); + +// memory_copy.wast:1760 +assert_return(() => call($12, "load8_u", [64_475]), 0); + +// memory_copy.wast:1761 +assert_return(() => call($12, "load8_u", [64_674]), 0); + +// memory_copy.wast:1762 +assert_return(() => call($12, "load8_u", [64_873]), 0); + +// memory_copy.wast:1763 +assert_return(() => call($12, "load8_u", [65_072]), 0); + +// memory_copy.wast:1764 +assert_return(() => call($12, "load8_u", [65_271]), 0); + +// memory_copy.wast:1765 +assert_return(() => call($12, "load8_u", [65_470]), 0); + +// memory_copy.wast:1766 +assert_return(() => call($12, "load8_u", [65_515]), 0); + +// memory_copy.wast:1767 +assert_return(() => call($12, "load8_u", [65_516]), 1); + +// memory_copy.wast:1768 +assert_return(() => call($12, "load8_u", [65_517]), 2); + +// memory_copy.wast:1769 +assert_return(() => call($12, "load8_u", [65_518]), 3); + +// memory_copy.wast:1770 +assert_return(() => call($12, "load8_u", [65_519]), 4); + +// memory_copy.wast:1771 +assert_return(() => call($12, "load8_u", [65_520]), 5); + +// memory_copy.wast:1772 +assert_return(() => call($12, "load8_u", [65_521]), 6); + +// memory_copy.wast:1773 +assert_return(() => call($12, "load8_u", [65_522]), 7); + +// memory_copy.wast:1774 +assert_return(() => call($12, "load8_u", [65_523]), 8); + +// memory_copy.wast:1775 +assert_return(() => call($12, "load8_u", [65_524]), 9); + +// memory_copy.wast:1776 +assert_return(() => call($12, "load8_u", [65_525]), 10); + +// memory_copy.wast:1777 +assert_return(() => call($12, "load8_u", [65_526]), 11); + +// memory_copy.wast:1778 +assert_return(() => call($12, "load8_u", [65_527]), 12); + +// memory_copy.wast:1779 +assert_return(() => call($12, "load8_u", [65_528]), 13); + +// memory_copy.wast:1780 +assert_return(() => call($12, "load8_u", [65_529]), 14); + +// memory_copy.wast:1781 +assert_return(() => call($12, "load8_u", [65_530]), 15); + +// memory_copy.wast:1782 +assert_return(() => call($12, "load8_u", [65_531]), 16); + +// memory_copy.wast:1783 +assert_return(() => call($12, "load8_u", [65_532]), 17); + +// memory_copy.wast:1784 +assert_return(() => call($12, "load8_u", [65_533]), 18); + +// memory_copy.wast:1785 +assert_return(() => call($12, "load8_u", [65_534]), 19); + +// memory_copy.wast:1786 +assert_return(() => call($12, "load8_u", [65_535]), 20); + +// memory_copy.wast:1788 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xce\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:1796 +assert_trap(() => call($13, "run", [65_516, 65_486, 40])); + +// memory_copy.wast:1799 +assert_return(() => call($13, "load8_u", [198]), 0); + +// memory_copy.wast:1800 +assert_return(() => call($13, "load8_u", [397]), 0); + +// memory_copy.wast:1801 +assert_return(() => call($13, "load8_u", [596]), 0); + +// memory_copy.wast:1802 +assert_return(() => call($13, "load8_u", [795]), 0); + +// memory_copy.wast:1803 +assert_return(() => call($13, "load8_u", [994]), 0); + +// memory_copy.wast:1804 +assert_return(() => call($13, "load8_u", [1_193]), 0); + +// memory_copy.wast:1805 +assert_return(() => call($13, "load8_u", [1_392]), 0); + +// memory_copy.wast:1806 +assert_return(() => call($13, "load8_u", [1_591]), 0); + +// memory_copy.wast:1807 +assert_return(() => call($13, "load8_u", [1_790]), 0); + +// memory_copy.wast:1808 +assert_return(() => call($13, "load8_u", [1_989]), 0); + +// memory_copy.wast:1809 +assert_return(() => call($13, "load8_u", [2_188]), 0); + +// memory_copy.wast:1810 +assert_return(() => call($13, "load8_u", [2_387]), 0); + +// memory_copy.wast:1811 +assert_return(() => call($13, "load8_u", [2_586]), 0); + +// memory_copy.wast:1812 +assert_return(() => call($13, "load8_u", [2_785]), 0); + +// memory_copy.wast:1813 +assert_return(() => call($13, "load8_u", [2_984]), 0); + +// memory_copy.wast:1814 +assert_return(() => call($13, "load8_u", [3_183]), 0); + +// memory_copy.wast:1815 +assert_return(() => call($13, "load8_u", [3_382]), 0); + +// memory_copy.wast:1816 +assert_return(() => call($13, "load8_u", [3_581]), 0); + +// memory_copy.wast:1817 +assert_return(() => call($13, "load8_u", [3_780]), 0); + +// memory_copy.wast:1818 +assert_return(() => call($13, "load8_u", [3_979]), 0); + +// memory_copy.wast:1819 +assert_return(() => call($13, "load8_u", [4_178]), 0); + +// memory_copy.wast:1820 +assert_return(() => call($13, "load8_u", [4_377]), 0); + +// memory_copy.wast:1821 +assert_return(() => call($13, "load8_u", [4_576]), 0); + +// memory_copy.wast:1822 +assert_return(() => call($13, "load8_u", [4_775]), 0); + +// memory_copy.wast:1823 +assert_return(() => call($13, "load8_u", [4_974]), 0); + +// memory_copy.wast:1824 +assert_return(() => call($13, "load8_u", [5_173]), 0); + +// memory_copy.wast:1825 +assert_return(() => call($13, "load8_u", [5_372]), 0); + +// memory_copy.wast:1826 +assert_return(() => call($13, "load8_u", [5_571]), 0); + +// memory_copy.wast:1827 +assert_return(() => call($13, "load8_u", [5_770]), 0); + +// memory_copy.wast:1828 +assert_return(() => call($13, "load8_u", [5_969]), 0); + +// memory_copy.wast:1829 +assert_return(() => call($13, "load8_u", [6_168]), 0); + +// memory_copy.wast:1830 +assert_return(() => call($13, "load8_u", [6_367]), 0); + +// memory_copy.wast:1831 +assert_return(() => call($13, "load8_u", [6_566]), 0); + +// memory_copy.wast:1832 +assert_return(() => call($13, "load8_u", [6_765]), 0); + +// memory_copy.wast:1833 +assert_return(() => call($13, "load8_u", [6_964]), 0); + +// memory_copy.wast:1834 +assert_return(() => call($13, "load8_u", [7_163]), 0); + +// memory_copy.wast:1835 +assert_return(() => call($13, "load8_u", [7_362]), 0); + +// memory_copy.wast:1836 +assert_return(() => call($13, "load8_u", [7_561]), 0); + +// memory_copy.wast:1837 +assert_return(() => call($13, "load8_u", [7_760]), 0); + +// memory_copy.wast:1838 +assert_return(() => call($13, "load8_u", [7_959]), 0); + +// memory_copy.wast:1839 +assert_return(() => call($13, "load8_u", [8_158]), 0); + +// memory_copy.wast:1840 +assert_return(() => call($13, "load8_u", [8_357]), 0); + +// memory_copy.wast:1841 +assert_return(() => call($13, "load8_u", [8_556]), 0); + +// memory_copy.wast:1842 +assert_return(() => call($13, "load8_u", [8_755]), 0); + +// memory_copy.wast:1843 +assert_return(() => call($13, "load8_u", [8_954]), 0); + +// memory_copy.wast:1844 +assert_return(() => call($13, "load8_u", [9_153]), 0); + +// memory_copy.wast:1845 +assert_return(() => call($13, "load8_u", [9_352]), 0); + +// memory_copy.wast:1846 +assert_return(() => call($13, "load8_u", [9_551]), 0); + +// memory_copy.wast:1847 +assert_return(() => call($13, "load8_u", [9_750]), 0); + +// memory_copy.wast:1848 +assert_return(() => call($13, "load8_u", [9_949]), 0); + +// memory_copy.wast:1849 +assert_return(() => call($13, "load8_u", [10_148]), 0); + +// memory_copy.wast:1850 +assert_return(() => call($13, "load8_u", [10_347]), 0); + +// memory_copy.wast:1851 +assert_return(() => call($13, "load8_u", [10_546]), 0); + +// memory_copy.wast:1852 +assert_return(() => call($13, "load8_u", [10_745]), 0); + +// memory_copy.wast:1853 +assert_return(() => call($13, "load8_u", [10_944]), 0); + +// memory_copy.wast:1854 +assert_return(() => call($13, "load8_u", [11_143]), 0); + +// memory_copy.wast:1855 +assert_return(() => call($13, "load8_u", [11_342]), 0); + +// memory_copy.wast:1856 +assert_return(() => call($13, "load8_u", [11_541]), 0); + +// memory_copy.wast:1857 +assert_return(() => call($13, "load8_u", [11_740]), 0); + +// memory_copy.wast:1858 +assert_return(() => call($13, "load8_u", [11_939]), 0); + +// memory_copy.wast:1859 +assert_return(() => call($13, "load8_u", [12_138]), 0); + +// memory_copy.wast:1860 +assert_return(() => call($13, "load8_u", [12_337]), 0); + +// memory_copy.wast:1861 +assert_return(() => call($13, "load8_u", [12_536]), 0); + +// memory_copy.wast:1862 +assert_return(() => call($13, "load8_u", [12_735]), 0); + +// memory_copy.wast:1863 +assert_return(() => call($13, "load8_u", [12_934]), 0); + +// memory_copy.wast:1864 +assert_return(() => call($13, "load8_u", [13_133]), 0); + +// memory_copy.wast:1865 +assert_return(() => call($13, "load8_u", [13_332]), 0); + +// memory_copy.wast:1866 +assert_return(() => call($13, "load8_u", [13_531]), 0); + +// memory_copy.wast:1867 +assert_return(() => call($13, "load8_u", [13_730]), 0); + +// memory_copy.wast:1868 +assert_return(() => call($13, "load8_u", [13_929]), 0); + +// memory_copy.wast:1869 +assert_return(() => call($13, "load8_u", [14_128]), 0); + +// memory_copy.wast:1870 +assert_return(() => call($13, "load8_u", [14_327]), 0); + +// memory_copy.wast:1871 +assert_return(() => call($13, "load8_u", [14_526]), 0); + +// memory_copy.wast:1872 +assert_return(() => call($13, "load8_u", [14_725]), 0); + +// memory_copy.wast:1873 +assert_return(() => call($13, "load8_u", [14_924]), 0); + +// memory_copy.wast:1874 +assert_return(() => call($13, "load8_u", [15_123]), 0); + +// memory_copy.wast:1875 +assert_return(() => call($13, "load8_u", [15_322]), 0); + +// memory_copy.wast:1876 +assert_return(() => call($13, "load8_u", [15_521]), 0); + +// memory_copy.wast:1877 +assert_return(() => call($13, "load8_u", [15_720]), 0); + +// memory_copy.wast:1878 +assert_return(() => call($13, "load8_u", [15_919]), 0); + +// memory_copy.wast:1879 +assert_return(() => call($13, "load8_u", [16_118]), 0); + +// memory_copy.wast:1880 +assert_return(() => call($13, "load8_u", [16_317]), 0); + +// memory_copy.wast:1881 +assert_return(() => call($13, "load8_u", [16_516]), 0); + +// memory_copy.wast:1882 +assert_return(() => call($13, "load8_u", [16_715]), 0); + +// memory_copy.wast:1883 +assert_return(() => call($13, "load8_u", [16_914]), 0); + +// memory_copy.wast:1884 +assert_return(() => call($13, "load8_u", [17_113]), 0); + +// memory_copy.wast:1885 +assert_return(() => call($13, "load8_u", [17_312]), 0); + +// memory_copy.wast:1886 +assert_return(() => call($13, "load8_u", [17_511]), 0); + +// memory_copy.wast:1887 +assert_return(() => call($13, "load8_u", [17_710]), 0); + +// memory_copy.wast:1888 +assert_return(() => call($13, "load8_u", [17_909]), 0); + +// memory_copy.wast:1889 +assert_return(() => call($13, "load8_u", [18_108]), 0); + +// memory_copy.wast:1890 +assert_return(() => call($13, "load8_u", [18_307]), 0); + +// memory_copy.wast:1891 +assert_return(() => call($13, "load8_u", [18_506]), 0); + +// memory_copy.wast:1892 +assert_return(() => call($13, "load8_u", [18_705]), 0); + +// memory_copy.wast:1893 +assert_return(() => call($13, "load8_u", [18_904]), 0); + +// memory_copy.wast:1894 +assert_return(() => call($13, "load8_u", [19_103]), 0); + +// memory_copy.wast:1895 +assert_return(() => call($13, "load8_u", [19_302]), 0); + +// memory_copy.wast:1896 +assert_return(() => call($13, "load8_u", [19_501]), 0); + +// memory_copy.wast:1897 +assert_return(() => call($13, "load8_u", [19_700]), 0); + +// memory_copy.wast:1898 +assert_return(() => call($13, "load8_u", [19_899]), 0); + +// memory_copy.wast:1899 +assert_return(() => call($13, "load8_u", [20_098]), 0); + +// memory_copy.wast:1900 +assert_return(() => call($13, "load8_u", [20_297]), 0); + +// memory_copy.wast:1901 +assert_return(() => call($13, "load8_u", [20_496]), 0); + +// memory_copy.wast:1902 +assert_return(() => call($13, "load8_u", [20_695]), 0); + +// memory_copy.wast:1903 +assert_return(() => call($13, "load8_u", [20_894]), 0); + +// memory_copy.wast:1904 +assert_return(() => call($13, "load8_u", [21_093]), 0); + +// memory_copy.wast:1905 +assert_return(() => call($13, "load8_u", [21_292]), 0); + +// memory_copy.wast:1906 +assert_return(() => call($13, "load8_u", [21_491]), 0); + +// memory_copy.wast:1907 +assert_return(() => call($13, "load8_u", [21_690]), 0); + +// memory_copy.wast:1908 +assert_return(() => call($13, "load8_u", [21_889]), 0); + +// memory_copy.wast:1909 +assert_return(() => call($13, "load8_u", [22_088]), 0); + +// memory_copy.wast:1910 +assert_return(() => call($13, "load8_u", [22_287]), 0); + +// memory_copy.wast:1911 +assert_return(() => call($13, "load8_u", [22_486]), 0); + +// memory_copy.wast:1912 +assert_return(() => call($13, "load8_u", [22_685]), 0); + +// memory_copy.wast:1913 +assert_return(() => call($13, "load8_u", [22_884]), 0); + +// memory_copy.wast:1914 +assert_return(() => call($13, "load8_u", [23_083]), 0); + +// memory_copy.wast:1915 +assert_return(() => call($13, "load8_u", [23_282]), 0); + +// memory_copy.wast:1916 +assert_return(() => call($13, "load8_u", [23_481]), 0); + +// memory_copy.wast:1917 +assert_return(() => call($13, "load8_u", [23_680]), 0); + +// memory_copy.wast:1918 +assert_return(() => call($13, "load8_u", [23_879]), 0); + +// memory_copy.wast:1919 +assert_return(() => call($13, "load8_u", [24_078]), 0); + +// memory_copy.wast:1920 +assert_return(() => call($13, "load8_u", [24_277]), 0); + +// memory_copy.wast:1921 +assert_return(() => call($13, "load8_u", [24_476]), 0); + +// memory_copy.wast:1922 +assert_return(() => call($13, "load8_u", [24_675]), 0); + +// memory_copy.wast:1923 +assert_return(() => call($13, "load8_u", [24_874]), 0); + +// memory_copy.wast:1924 +assert_return(() => call($13, "load8_u", [25_073]), 0); + +// memory_copy.wast:1925 +assert_return(() => call($13, "load8_u", [25_272]), 0); + +// memory_copy.wast:1926 +assert_return(() => call($13, "load8_u", [25_471]), 0); + +// memory_copy.wast:1927 +assert_return(() => call($13, "load8_u", [25_670]), 0); + +// memory_copy.wast:1928 +assert_return(() => call($13, "load8_u", [25_869]), 0); + +// memory_copy.wast:1929 +assert_return(() => call($13, "load8_u", [26_068]), 0); + +// memory_copy.wast:1930 +assert_return(() => call($13, "load8_u", [26_267]), 0); + +// memory_copy.wast:1931 +assert_return(() => call($13, "load8_u", [26_466]), 0); + +// memory_copy.wast:1932 +assert_return(() => call($13, "load8_u", [26_665]), 0); + +// memory_copy.wast:1933 +assert_return(() => call($13, "load8_u", [26_864]), 0); + +// memory_copy.wast:1934 +assert_return(() => call($13, "load8_u", [27_063]), 0); + +// memory_copy.wast:1935 +assert_return(() => call($13, "load8_u", [27_262]), 0); + +// memory_copy.wast:1936 +assert_return(() => call($13, "load8_u", [27_461]), 0); + +// memory_copy.wast:1937 +assert_return(() => call($13, "load8_u", [27_660]), 0); + +// memory_copy.wast:1938 +assert_return(() => call($13, "load8_u", [27_859]), 0); + +// memory_copy.wast:1939 +assert_return(() => call($13, "load8_u", [28_058]), 0); + +// memory_copy.wast:1940 +assert_return(() => call($13, "load8_u", [28_257]), 0); + +// memory_copy.wast:1941 +assert_return(() => call($13, "load8_u", [28_456]), 0); + +// memory_copy.wast:1942 +assert_return(() => call($13, "load8_u", [28_655]), 0); + +// memory_copy.wast:1943 +assert_return(() => call($13, "load8_u", [28_854]), 0); + +// memory_copy.wast:1944 +assert_return(() => call($13, "load8_u", [29_053]), 0); + +// memory_copy.wast:1945 +assert_return(() => call($13, "load8_u", [29_252]), 0); + +// memory_copy.wast:1946 +assert_return(() => call($13, "load8_u", [29_451]), 0); + +// memory_copy.wast:1947 +assert_return(() => call($13, "load8_u", [29_650]), 0); + +// memory_copy.wast:1948 +assert_return(() => call($13, "load8_u", [29_849]), 0); + +// memory_copy.wast:1949 +assert_return(() => call($13, "load8_u", [30_048]), 0); + +// memory_copy.wast:1950 +assert_return(() => call($13, "load8_u", [30_247]), 0); + +// memory_copy.wast:1951 +assert_return(() => call($13, "load8_u", [30_446]), 0); + +// memory_copy.wast:1952 +assert_return(() => call($13, "load8_u", [30_645]), 0); + +// memory_copy.wast:1953 +assert_return(() => call($13, "load8_u", [30_844]), 0); + +// memory_copy.wast:1954 +assert_return(() => call($13, "load8_u", [31_043]), 0); + +// memory_copy.wast:1955 +assert_return(() => call($13, "load8_u", [31_242]), 0); + +// memory_copy.wast:1956 +assert_return(() => call($13, "load8_u", [31_441]), 0); + +// memory_copy.wast:1957 +assert_return(() => call($13, "load8_u", [31_640]), 0); + +// memory_copy.wast:1958 +assert_return(() => call($13, "load8_u", [31_839]), 0); + +// memory_copy.wast:1959 +assert_return(() => call($13, "load8_u", [32_038]), 0); + +// memory_copy.wast:1960 +assert_return(() => call($13, "load8_u", [32_237]), 0); + +// memory_copy.wast:1961 +assert_return(() => call($13, "load8_u", [32_436]), 0); + +// memory_copy.wast:1962 +assert_return(() => call($13, "load8_u", [32_635]), 0); + +// memory_copy.wast:1963 +assert_return(() => call($13, "load8_u", [32_834]), 0); + +// memory_copy.wast:1964 +assert_return(() => call($13, "load8_u", [33_033]), 0); + +// memory_copy.wast:1965 +assert_return(() => call($13, "load8_u", [33_232]), 0); + +// memory_copy.wast:1966 +assert_return(() => call($13, "load8_u", [33_431]), 0); + +// memory_copy.wast:1967 +assert_return(() => call($13, "load8_u", [33_630]), 0); + +// memory_copy.wast:1968 +assert_return(() => call($13, "load8_u", [33_829]), 0); + +// memory_copy.wast:1969 +assert_return(() => call($13, "load8_u", [34_028]), 0); + +// memory_copy.wast:1970 +assert_return(() => call($13, "load8_u", [34_227]), 0); + +// memory_copy.wast:1971 +assert_return(() => call($13, "load8_u", [34_426]), 0); + +// memory_copy.wast:1972 +assert_return(() => call($13, "load8_u", [34_625]), 0); + +// memory_copy.wast:1973 +assert_return(() => call($13, "load8_u", [34_824]), 0); + +// memory_copy.wast:1974 +assert_return(() => call($13, "load8_u", [35_023]), 0); + +// memory_copy.wast:1975 +assert_return(() => call($13, "load8_u", [35_222]), 0); + +// memory_copy.wast:1976 +assert_return(() => call($13, "load8_u", [35_421]), 0); + +// memory_copy.wast:1977 +assert_return(() => call($13, "load8_u", [35_620]), 0); + +// memory_copy.wast:1978 +assert_return(() => call($13, "load8_u", [35_819]), 0); + +// memory_copy.wast:1979 +assert_return(() => call($13, "load8_u", [36_018]), 0); + +// memory_copy.wast:1980 +assert_return(() => call($13, "load8_u", [36_217]), 0); + +// memory_copy.wast:1981 +assert_return(() => call($13, "load8_u", [36_416]), 0); + +// memory_copy.wast:1982 +assert_return(() => call($13, "load8_u", [36_615]), 0); + +// memory_copy.wast:1983 +assert_return(() => call($13, "load8_u", [36_814]), 0); + +// memory_copy.wast:1984 +assert_return(() => call($13, "load8_u", [37_013]), 0); + +// memory_copy.wast:1985 +assert_return(() => call($13, "load8_u", [37_212]), 0); + +// memory_copy.wast:1986 +assert_return(() => call($13, "load8_u", [37_411]), 0); + +// memory_copy.wast:1987 +assert_return(() => call($13, "load8_u", [37_610]), 0); + +// memory_copy.wast:1988 +assert_return(() => call($13, "load8_u", [37_809]), 0); + +// memory_copy.wast:1989 +assert_return(() => call($13, "load8_u", [38_008]), 0); + +// memory_copy.wast:1990 +assert_return(() => call($13, "load8_u", [38_207]), 0); + +// memory_copy.wast:1991 +assert_return(() => call($13, "load8_u", [38_406]), 0); + +// memory_copy.wast:1992 +assert_return(() => call($13, "load8_u", [38_605]), 0); + +// memory_copy.wast:1993 +assert_return(() => call($13, "load8_u", [38_804]), 0); + +// memory_copy.wast:1994 +assert_return(() => call($13, "load8_u", [39_003]), 0); + +// memory_copy.wast:1995 +assert_return(() => call($13, "load8_u", [39_202]), 0); + +// memory_copy.wast:1996 +assert_return(() => call($13, "load8_u", [39_401]), 0); + +// memory_copy.wast:1997 +assert_return(() => call($13, "load8_u", [39_600]), 0); + +// memory_copy.wast:1998 +assert_return(() => call($13, "load8_u", [39_799]), 0); + +// memory_copy.wast:1999 +assert_return(() => call($13, "load8_u", [39_998]), 0); + +// memory_copy.wast:2000 +assert_return(() => call($13, "load8_u", [40_197]), 0); + +// memory_copy.wast:2001 +assert_return(() => call($13, "load8_u", [40_396]), 0); + +// memory_copy.wast:2002 +assert_return(() => call($13, "load8_u", [40_595]), 0); + +// memory_copy.wast:2003 +assert_return(() => call($13, "load8_u", [40_794]), 0); + +// memory_copy.wast:2004 +assert_return(() => call($13, "load8_u", [40_993]), 0); + +// memory_copy.wast:2005 +assert_return(() => call($13, "load8_u", [41_192]), 0); + +// memory_copy.wast:2006 +assert_return(() => call($13, "load8_u", [41_391]), 0); + +// memory_copy.wast:2007 +assert_return(() => call($13, "load8_u", [41_590]), 0); + +// memory_copy.wast:2008 +assert_return(() => call($13, "load8_u", [41_789]), 0); + +// memory_copy.wast:2009 +assert_return(() => call($13, "load8_u", [41_988]), 0); + +// memory_copy.wast:2010 +assert_return(() => call($13, "load8_u", [42_187]), 0); + +// memory_copy.wast:2011 +assert_return(() => call($13, "load8_u", [42_386]), 0); + +// memory_copy.wast:2012 +assert_return(() => call($13, "load8_u", [42_585]), 0); + +// memory_copy.wast:2013 +assert_return(() => call($13, "load8_u", [42_784]), 0); + +// memory_copy.wast:2014 +assert_return(() => call($13, "load8_u", [42_983]), 0); + +// memory_copy.wast:2015 +assert_return(() => call($13, "load8_u", [43_182]), 0); + +// memory_copy.wast:2016 +assert_return(() => call($13, "load8_u", [43_381]), 0); + +// memory_copy.wast:2017 +assert_return(() => call($13, "load8_u", [43_580]), 0); + +// memory_copy.wast:2018 +assert_return(() => call($13, "load8_u", [43_779]), 0); + +// memory_copy.wast:2019 +assert_return(() => call($13, "load8_u", [43_978]), 0); + +// memory_copy.wast:2020 +assert_return(() => call($13, "load8_u", [44_177]), 0); + +// memory_copy.wast:2021 +assert_return(() => call($13, "load8_u", [44_376]), 0); + +// memory_copy.wast:2022 +assert_return(() => call($13, "load8_u", [44_575]), 0); + +// memory_copy.wast:2023 +assert_return(() => call($13, "load8_u", [44_774]), 0); + +// memory_copy.wast:2024 +assert_return(() => call($13, "load8_u", [44_973]), 0); + +// memory_copy.wast:2025 +assert_return(() => call($13, "load8_u", [45_172]), 0); + +// memory_copy.wast:2026 +assert_return(() => call($13, "load8_u", [45_371]), 0); + +// memory_copy.wast:2027 +assert_return(() => call($13, "load8_u", [45_570]), 0); + +// memory_copy.wast:2028 +assert_return(() => call($13, "load8_u", [45_769]), 0); + +// memory_copy.wast:2029 +assert_return(() => call($13, "load8_u", [45_968]), 0); + +// memory_copy.wast:2030 +assert_return(() => call($13, "load8_u", [46_167]), 0); + +// memory_copy.wast:2031 +assert_return(() => call($13, "load8_u", [46_366]), 0); + +// memory_copy.wast:2032 +assert_return(() => call($13, "load8_u", [46_565]), 0); + +// memory_copy.wast:2033 +assert_return(() => call($13, "load8_u", [46_764]), 0); + +// memory_copy.wast:2034 +assert_return(() => call($13, "load8_u", [46_963]), 0); + +// memory_copy.wast:2035 +assert_return(() => call($13, "load8_u", [47_162]), 0); + +// memory_copy.wast:2036 +assert_return(() => call($13, "load8_u", [47_361]), 0); + +// memory_copy.wast:2037 +assert_return(() => call($13, "load8_u", [47_560]), 0); + +// memory_copy.wast:2038 +assert_return(() => call($13, "load8_u", [47_759]), 0); + +// memory_copy.wast:2039 +assert_return(() => call($13, "load8_u", [47_958]), 0); + +// memory_copy.wast:2040 +assert_return(() => call($13, "load8_u", [48_157]), 0); + +// memory_copy.wast:2041 +assert_return(() => call($13, "load8_u", [48_356]), 0); + +// memory_copy.wast:2042 +assert_return(() => call($13, "load8_u", [48_555]), 0); + +// memory_copy.wast:2043 +assert_return(() => call($13, "load8_u", [48_754]), 0); + +// memory_copy.wast:2044 +assert_return(() => call($13, "load8_u", [48_953]), 0); + +// memory_copy.wast:2045 +assert_return(() => call($13, "load8_u", [49_152]), 0); + +// memory_copy.wast:2046 +assert_return(() => call($13, "load8_u", [49_351]), 0); + +// memory_copy.wast:2047 +assert_return(() => call($13, "load8_u", [49_550]), 0); + +// memory_copy.wast:2048 +assert_return(() => call($13, "load8_u", [49_749]), 0); + +// memory_copy.wast:2049 +assert_return(() => call($13, "load8_u", [49_948]), 0); + +// memory_copy.wast:2050 +assert_return(() => call($13, "load8_u", [50_147]), 0); + +// memory_copy.wast:2051 +assert_return(() => call($13, "load8_u", [50_346]), 0); + +// memory_copy.wast:2052 +assert_return(() => call($13, "load8_u", [50_545]), 0); + +// memory_copy.wast:2053 +assert_return(() => call($13, "load8_u", [50_744]), 0); + +// memory_copy.wast:2054 +assert_return(() => call($13, "load8_u", [50_943]), 0); + +// memory_copy.wast:2055 +assert_return(() => call($13, "load8_u", [51_142]), 0); + +// memory_copy.wast:2056 +assert_return(() => call($13, "load8_u", [51_341]), 0); + +// memory_copy.wast:2057 +assert_return(() => call($13, "load8_u", [51_540]), 0); + +// memory_copy.wast:2058 +assert_return(() => call($13, "load8_u", [51_739]), 0); + +// memory_copy.wast:2059 +assert_return(() => call($13, "load8_u", [51_938]), 0); + +// memory_copy.wast:2060 +assert_return(() => call($13, "load8_u", [52_137]), 0); + +// memory_copy.wast:2061 +assert_return(() => call($13, "load8_u", [52_336]), 0); + +// memory_copy.wast:2062 +assert_return(() => call($13, "load8_u", [52_535]), 0); + +// memory_copy.wast:2063 +assert_return(() => call($13, "load8_u", [52_734]), 0); + +// memory_copy.wast:2064 +assert_return(() => call($13, "load8_u", [52_933]), 0); + +// memory_copy.wast:2065 +assert_return(() => call($13, "load8_u", [53_132]), 0); + +// memory_copy.wast:2066 +assert_return(() => call($13, "load8_u", [53_331]), 0); + +// memory_copy.wast:2067 +assert_return(() => call($13, "load8_u", [53_530]), 0); + +// memory_copy.wast:2068 +assert_return(() => call($13, "load8_u", [53_729]), 0); + +// memory_copy.wast:2069 +assert_return(() => call($13, "load8_u", [53_928]), 0); + +// memory_copy.wast:2070 +assert_return(() => call($13, "load8_u", [54_127]), 0); + +// memory_copy.wast:2071 +assert_return(() => call($13, "load8_u", [54_326]), 0); + +// memory_copy.wast:2072 +assert_return(() => call($13, "load8_u", [54_525]), 0); + +// memory_copy.wast:2073 +assert_return(() => call($13, "load8_u", [54_724]), 0); + +// memory_copy.wast:2074 +assert_return(() => call($13, "load8_u", [54_923]), 0); + +// memory_copy.wast:2075 +assert_return(() => call($13, "load8_u", [55_122]), 0); + +// memory_copy.wast:2076 +assert_return(() => call($13, "load8_u", [55_321]), 0); + +// memory_copy.wast:2077 +assert_return(() => call($13, "load8_u", [55_520]), 0); + +// memory_copy.wast:2078 +assert_return(() => call($13, "load8_u", [55_719]), 0); + +// memory_copy.wast:2079 +assert_return(() => call($13, "load8_u", [55_918]), 0); + +// memory_copy.wast:2080 +assert_return(() => call($13, "load8_u", [56_117]), 0); + +// memory_copy.wast:2081 +assert_return(() => call($13, "load8_u", [56_316]), 0); + +// memory_copy.wast:2082 +assert_return(() => call($13, "load8_u", [56_515]), 0); + +// memory_copy.wast:2083 +assert_return(() => call($13, "load8_u", [56_714]), 0); + +// memory_copy.wast:2084 +assert_return(() => call($13, "load8_u", [56_913]), 0); + +// memory_copy.wast:2085 +assert_return(() => call($13, "load8_u", [57_112]), 0); + +// memory_copy.wast:2086 +assert_return(() => call($13, "load8_u", [57_311]), 0); + +// memory_copy.wast:2087 +assert_return(() => call($13, "load8_u", [57_510]), 0); + +// memory_copy.wast:2088 +assert_return(() => call($13, "load8_u", [57_709]), 0); + +// memory_copy.wast:2089 +assert_return(() => call($13, "load8_u", [57_908]), 0); + +// memory_copy.wast:2090 +assert_return(() => call($13, "load8_u", [58_107]), 0); + +// memory_copy.wast:2091 +assert_return(() => call($13, "load8_u", [58_306]), 0); + +// memory_copy.wast:2092 +assert_return(() => call($13, "load8_u", [58_505]), 0); + +// memory_copy.wast:2093 +assert_return(() => call($13, "load8_u", [58_704]), 0); + +// memory_copy.wast:2094 +assert_return(() => call($13, "load8_u", [58_903]), 0); + +// memory_copy.wast:2095 +assert_return(() => call($13, "load8_u", [59_102]), 0); + +// memory_copy.wast:2096 +assert_return(() => call($13, "load8_u", [59_301]), 0); + +// memory_copy.wast:2097 +assert_return(() => call($13, "load8_u", [59_500]), 0); + +// memory_copy.wast:2098 +assert_return(() => call($13, "load8_u", [59_699]), 0); + +// memory_copy.wast:2099 +assert_return(() => call($13, "load8_u", [59_898]), 0); + +// memory_copy.wast:2100 +assert_return(() => call($13, "load8_u", [60_097]), 0); + +// memory_copy.wast:2101 +assert_return(() => call($13, "load8_u", [60_296]), 0); + +// memory_copy.wast:2102 +assert_return(() => call($13, "load8_u", [60_495]), 0); + +// memory_copy.wast:2103 +assert_return(() => call($13, "load8_u", [60_694]), 0); + +// memory_copy.wast:2104 +assert_return(() => call($13, "load8_u", [60_893]), 0); + +// memory_copy.wast:2105 +assert_return(() => call($13, "load8_u", [61_092]), 0); + +// memory_copy.wast:2106 +assert_return(() => call($13, "load8_u", [61_291]), 0); + +// memory_copy.wast:2107 +assert_return(() => call($13, "load8_u", [61_490]), 0); + +// memory_copy.wast:2108 +assert_return(() => call($13, "load8_u", [61_689]), 0); + +// memory_copy.wast:2109 +assert_return(() => call($13, "load8_u", [61_888]), 0); + +// memory_copy.wast:2110 +assert_return(() => call($13, "load8_u", [62_087]), 0); + +// memory_copy.wast:2111 +assert_return(() => call($13, "load8_u", [62_286]), 0); + +// memory_copy.wast:2112 +assert_return(() => call($13, "load8_u", [62_485]), 0); + +// memory_copy.wast:2113 +assert_return(() => call($13, "load8_u", [62_684]), 0); + +// memory_copy.wast:2114 +assert_return(() => call($13, "load8_u", [62_883]), 0); + +// memory_copy.wast:2115 +assert_return(() => call($13, "load8_u", [63_082]), 0); + +// memory_copy.wast:2116 +assert_return(() => call($13, "load8_u", [63_281]), 0); + +// memory_copy.wast:2117 +assert_return(() => call($13, "load8_u", [63_480]), 0); + +// memory_copy.wast:2118 +assert_return(() => call($13, "load8_u", [63_679]), 0); + +// memory_copy.wast:2119 +assert_return(() => call($13, "load8_u", [63_878]), 0); + +// memory_copy.wast:2120 +assert_return(() => call($13, "load8_u", [64_077]), 0); + +// memory_copy.wast:2121 +assert_return(() => call($13, "load8_u", [64_276]), 0); + +// memory_copy.wast:2122 +assert_return(() => call($13, "load8_u", [64_475]), 0); + +// memory_copy.wast:2123 +assert_return(() => call($13, "load8_u", [64_674]), 0); + +// memory_copy.wast:2124 +assert_return(() => call($13, "load8_u", [64_873]), 0); + +// memory_copy.wast:2125 +assert_return(() => call($13, "load8_u", [65_072]), 0); + +// memory_copy.wast:2126 +assert_return(() => call($13, "load8_u", [65_271]), 0); + +// memory_copy.wast:2127 +assert_return(() => call($13, "load8_u", [65_470]), 0); + +// memory_copy.wast:2128 +assert_return(() => call($13, "load8_u", [65_486]), 0); + +// memory_copy.wast:2129 +assert_return(() => call($13, "load8_u", [65_487]), 1); + +// memory_copy.wast:2130 +assert_return(() => call($13, "load8_u", [65_488]), 2); + +// memory_copy.wast:2131 +assert_return(() => call($13, "load8_u", [65_489]), 3); + +// memory_copy.wast:2132 +assert_return(() => call($13, "load8_u", [65_490]), 4); + +// memory_copy.wast:2133 +assert_return(() => call($13, "load8_u", [65_491]), 5); + +// memory_copy.wast:2134 +assert_return(() => call($13, "load8_u", [65_492]), 6); + +// memory_copy.wast:2135 +assert_return(() => call($13, "load8_u", [65_493]), 7); + +// memory_copy.wast:2136 +assert_return(() => call($13, "load8_u", [65_494]), 8); + +// memory_copy.wast:2137 +assert_return(() => call($13, "load8_u", [65_495]), 9); + +// memory_copy.wast:2138 +assert_return(() => call($13, "load8_u", [65_496]), 10); + +// memory_copy.wast:2139 +assert_return(() => call($13, "load8_u", [65_497]), 11); + +// memory_copy.wast:2140 +assert_return(() => call($13, "load8_u", [65_498]), 12); + +// memory_copy.wast:2141 +assert_return(() => call($13, "load8_u", [65_499]), 13); + +// memory_copy.wast:2142 +assert_return(() => call($13, "load8_u", [65_500]), 14); + +// memory_copy.wast:2143 +assert_return(() => call($13, "load8_u", [65_501]), 15); + +// memory_copy.wast:2144 +assert_return(() => call($13, "load8_u", [65_502]), 16); + +// memory_copy.wast:2145 +assert_return(() => call($13, "load8_u", [65_503]), 17); + +// memory_copy.wast:2146 +assert_return(() => call($13, "load8_u", [65_504]), 18); + +// memory_copy.wast:2147 +assert_return(() => call($13, "load8_u", [65_505]), 19); + +// memory_copy.wast:2149 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2157 +assert_trap(() => call($14, "run", [65_486, 65_516, 40])); + +// memory_copy.wast:2160 +assert_return(() => call($14, "load8_u", [198]), 0); + +// memory_copy.wast:2161 +assert_return(() => call($14, "load8_u", [397]), 0); + +// memory_copy.wast:2162 +assert_return(() => call($14, "load8_u", [596]), 0); + +// memory_copy.wast:2163 +assert_return(() => call($14, "load8_u", [795]), 0); + +// memory_copy.wast:2164 +assert_return(() => call($14, "load8_u", [994]), 0); + +// memory_copy.wast:2165 +assert_return(() => call($14, "load8_u", [1_193]), 0); + +// memory_copy.wast:2166 +assert_return(() => call($14, "load8_u", [1_392]), 0); + +// memory_copy.wast:2167 +assert_return(() => call($14, "load8_u", [1_591]), 0); + +// memory_copy.wast:2168 +assert_return(() => call($14, "load8_u", [1_790]), 0); + +// memory_copy.wast:2169 +assert_return(() => call($14, "load8_u", [1_989]), 0); + +// memory_copy.wast:2170 +assert_return(() => call($14, "load8_u", [2_188]), 0); + +// memory_copy.wast:2171 +assert_return(() => call($14, "load8_u", [2_387]), 0); + +// memory_copy.wast:2172 +assert_return(() => call($14, "load8_u", [2_586]), 0); + +// memory_copy.wast:2173 +assert_return(() => call($14, "load8_u", [2_785]), 0); + +// memory_copy.wast:2174 +assert_return(() => call($14, "load8_u", [2_984]), 0); + +// memory_copy.wast:2175 +assert_return(() => call($14, "load8_u", [3_183]), 0); + +// memory_copy.wast:2176 +assert_return(() => call($14, "load8_u", [3_382]), 0); + +// memory_copy.wast:2177 +assert_return(() => call($14, "load8_u", [3_581]), 0); + +// memory_copy.wast:2178 +assert_return(() => call($14, "load8_u", [3_780]), 0); + +// memory_copy.wast:2179 +assert_return(() => call($14, "load8_u", [3_979]), 0); + +// memory_copy.wast:2180 +assert_return(() => call($14, "load8_u", [4_178]), 0); + +// memory_copy.wast:2181 +assert_return(() => call($14, "load8_u", [4_377]), 0); + +// memory_copy.wast:2182 +assert_return(() => call($14, "load8_u", [4_576]), 0); + +// memory_copy.wast:2183 +assert_return(() => call($14, "load8_u", [4_775]), 0); + +// memory_copy.wast:2184 +assert_return(() => call($14, "load8_u", [4_974]), 0); + +// memory_copy.wast:2185 +assert_return(() => call($14, "load8_u", [5_173]), 0); + +// memory_copy.wast:2186 +assert_return(() => call($14, "load8_u", [5_372]), 0); + +// memory_copy.wast:2187 +assert_return(() => call($14, "load8_u", [5_571]), 0); + +// memory_copy.wast:2188 +assert_return(() => call($14, "load8_u", [5_770]), 0); + +// memory_copy.wast:2189 +assert_return(() => call($14, "load8_u", [5_969]), 0); + +// memory_copy.wast:2190 +assert_return(() => call($14, "load8_u", [6_168]), 0); + +// memory_copy.wast:2191 +assert_return(() => call($14, "load8_u", [6_367]), 0); + +// memory_copy.wast:2192 +assert_return(() => call($14, "load8_u", [6_566]), 0); + +// memory_copy.wast:2193 +assert_return(() => call($14, "load8_u", [6_765]), 0); + +// memory_copy.wast:2194 +assert_return(() => call($14, "load8_u", [6_964]), 0); + +// memory_copy.wast:2195 +assert_return(() => call($14, "load8_u", [7_163]), 0); + +// memory_copy.wast:2196 +assert_return(() => call($14, "load8_u", [7_362]), 0); + +// memory_copy.wast:2197 +assert_return(() => call($14, "load8_u", [7_561]), 0); + +// memory_copy.wast:2198 +assert_return(() => call($14, "load8_u", [7_760]), 0); + +// memory_copy.wast:2199 +assert_return(() => call($14, "load8_u", [7_959]), 0); + +// memory_copy.wast:2200 +assert_return(() => call($14, "load8_u", [8_158]), 0); + +// memory_copy.wast:2201 +assert_return(() => call($14, "load8_u", [8_357]), 0); + +// memory_copy.wast:2202 +assert_return(() => call($14, "load8_u", [8_556]), 0); + +// memory_copy.wast:2203 +assert_return(() => call($14, "load8_u", [8_755]), 0); + +// memory_copy.wast:2204 +assert_return(() => call($14, "load8_u", [8_954]), 0); + +// memory_copy.wast:2205 +assert_return(() => call($14, "load8_u", [9_153]), 0); + +// memory_copy.wast:2206 +assert_return(() => call($14, "load8_u", [9_352]), 0); + +// memory_copy.wast:2207 +assert_return(() => call($14, "load8_u", [9_551]), 0); + +// memory_copy.wast:2208 +assert_return(() => call($14, "load8_u", [9_750]), 0); + +// memory_copy.wast:2209 +assert_return(() => call($14, "load8_u", [9_949]), 0); + +// memory_copy.wast:2210 +assert_return(() => call($14, "load8_u", [10_148]), 0); + +// memory_copy.wast:2211 +assert_return(() => call($14, "load8_u", [10_347]), 0); + +// memory_copy.wast:2212 +assert_return(() => call($14, "load8_u", [10_546]), 0); + +// memory_copy.wast:2213 +assert_return(() => call($14, "load8_u", [10_745]), 0); + +// memory_copy.wast:2214 +assert_return(() => call($14, "load8_u", [10_944]), 0); + +// memory_copy.wast:2215 +assert_return(() => call($14, "load8_u", [11_143]), 0); + +// memory_copy.wast:2216 +assert_return(() => call($14, "load8_u", [11_342]), 0); + +// memory_copy.wast:2217 +assert_return(() => call($14, "load8_u", [11_541]), 0); + +// memory_copy.wast:2218 +assert_return(() => call($14, "load8_u", [11_740]), 0); + +// memory_copy.wast:2219 +assert_return(() => call($14, "load8_u", [11_939]), 0); + +// memory_copy.wast:2220 +assert_return(() => call($14, "load8_u", [12_138]), 0); + +// memory_copy.wast:2221 +assert_return(() => call($14, "load8_u", [12_337]), 0); + +// memory_copy.wast:2222 +assert_return(() => call($14, "load8_u", [12_536]), 0); + +// memory_copy.wast:2223 +assert_return(() => call($14, "load8_u", [12_735]), 0); + +// memory_copy.wast:2224 +assert_return(() => call($14, "load8_u", [12_934]), 0); + +// memory_copy.wast:2225 +assert_return(() => call($14, "load8_u", [13_133]), 0); + +// memory_copy.wast:2226 +assert_return(() => call($14, "load8_u", [13_332]), 0); + +// memory_copy.wast:2227 +assert_return(() => call($14, "load8_u", [13_531]), 0); + +// memory_copy.wast:2228 +assert_return(() => call($14, "load8_u", [13_730]), 0); + +// memory_copy.wast:2229 +assert_return(() => call($14, "load8_u", [13_929]), 0); + +// memory_copy.wast:2230 +assert_return(() => call($14, "load8_u", [14_128]), 0); + +// memory_copy.wast:2231 +assert_return(() => call($14, "load8_u", [14_327]), 0); + +// memory_copy.wast:2232 +assert_return(() => call($14, "load8_u", [14_526]), 0); + +// memory_copy.wast:2233 +assert_return(() => call($14, "load8_u", [14_725]), 0); + +// memory_copy.wast:2234 +assert_return(() => call($14, "load8_u", [14_924]), 0); + +// memory_copy.wast:2235 +assert_return(() => call($14, "load8_u", [15_123]), 0); + +// memory_copy.wast:2236 +assert_return(() => call($14, "load8_u", [15_322]), 0); + +// memory_copy.wast:2237 +assert_return(() => call($14, "load8_u", [15_521]), 0); + +// memory_copy.wast:2238 +assert_return(() => call($14, "load8_u", [15_720]), 0); + +// memory_copy.wast:2239 +assert_return(() => call($14, "load8_u", [15_919]), 0); + +// memory_copy.wast:2240 +assert_return(() => call($14, "load8_u", [16_118]), 0); + +// memory_copy.wast:2241 +assert_return(() => call($14, "load8_u", [16_317]), 0); + +// memory_copy.wast:2242 +assert_return(() => call($14, "load8_u", [16_516]), 0); + +// memory_copy.wast:2243 +assert_return(() => call($14, "load8_u", [16_715]), 0); + +// memory_copy.wast:2244 +assert_return(() => call($14, "load8_u", [16_914]), 0); + +// memory_copy.wast:2245 +assert_return(() => call($14, "load8_u", [17_113]), 0); + +// memory_copy.wast:2246 +assert_return(() => call($14, "load8_u", [17_312]), 0); + +// memory_copy.wast:2247 +assert_return(() => call($14, "load8_u", [17_511]), 0); + +// memory_copy.wast:2248 +assert_return(() => call($14, "load8_u", [17_710]), 0); + +// memory_copy.wast:2249 +assert_return(() => call($14, "load8_u", [17_909]), 0); + +// memory_copy.wast:2250 +assert_return(() => call($14, "load8_u", [18_108]), 0); + +// memory_copy.wast:2251 +assert_return(() => call($14, "load8_u", [18_307]), 0); + +// memory_copy.wast:2252 +assert_return(() => call($14, "load8_u", [18_506]), 0); + +// memory_copy.wast:2253 +assert_return(() => call($14, "load8_u", [18_705]), 0); + +// memory_copy.wast:2254 +assert_return(() => call($14, "load8_u", [18_904]), 0); + +// memory_copy.wast:2255 +assert_return(() => call($14, "load8_u", [19_103]), 0); + +// memory_copy.wast:2256 +assert_return(() => call($14, "load8_u", [19_302]), 0); + +// memory_copy.wast:2257 +assert_return(() => call($14, "load8_u", [19_501]), 0); + +// memory_copy.wast:2258 +assert_return(() => call($14, "load8_u", [19_700]), 0); + +// memory_copy.wast:2259 +assert_return(() => call($14, "load8_u", [19_899]), 0); + +// memory_copy.wast:2260 +assert_return(() => call($14, "load8_u", [20_098]), 0); + +// memory_copy.wast:2261 +assert_return(() => call($14, "load8_u", [20_297]), 0); + +// memory_copy.wast:2262 +assert_return(() => call($14, "load8_u", [20_496]), 0); + +// memory_copy.wast:2263 +assert_return(() => call($14, "load8_u", [20_695]), 0); + +// memory_copy.wast:2264 +assert_return(() => call($14, "load8_u", [20_894]), 0); + +// memory_copy.wast:2265 +assert_return(() => call($14, "load8_u", [21_093]), 0); + +// memory_copy.wast:2266 +assert_return(() => call($14, "load8_u", [21_292]), 0); + +// memory_copy.wast:2267 +assert_return(() => call($14, "load8_u", [21_491]), 0); + +// memory_copy.wast:2268 +assert_return(() => call($14, "load8_u", [21_690]), 0); + +// memory_copy.wast:2269 +assert_return(() => call($14, "load8_u", [21_889]), 0); + +// memory_copy.wast:2270 +assert_return(() => call($14, "load8_u", [22_088]), 0); + +// memory_copy.wast:2271 +assert_return(() => call($14, "load8_u", [22_287]), 0); + +// memory_copy.wast:2272 +assert_return(() => call($14, "load8_u", [22_486]), 0); + +// memory_copy.wast:2273 +assert_return(() => call($14, "load8_u", [22_685]), 0); + +// memory_copy.wast:2274 +assert_return(() => call($14, "load8_u", [22_884]), 0); + +// memory_copy.wast:2275 +assert_return(() => call($14, "load8_u", [23_083]), 0); + +// memory_copy.wast:2276 +assert_return(() => call($14, "load8_u", [23_282]), 0); + +// memory_copy.wast:2277 +assert_return(() => call($14, "load8_u", [23_481]), 0); + +// memory_copy.wast:2278 +assert_return(() => call($14, "load8_u", [23_680]), 0); + +// memory_copy.wast:2279 +assert_return(() => call($14, "load8_u", [23_879]), 0); + +// memory_copy.wast:2280 +assert_return(() => call($14, "load8_u", [24_078]), 0); + +// memory_copy.wast:2281 +assert_return(() => call($14, "load8_u", [24_277]), 0); + +// memory_copy.wast:2282 +assert_return(() => call($14, "load8_u", [24_476]), 0); + +// memory_copy.wast:2283 +assert_return(() => call($14, "load8_u", [24_675]), 0); + +// memory_copy.wast:2284 +assert_return(() => call($14, "load8_u", [24_874]), 0); + +// memory_copy.wast:2285 +assert_return(() => call($14, "load8_u", [25_073]), 0); + +// memory_copy.wast:2286 +assert_return(() => call($14, "load8_u", [25_272]), 0); + +// memory_copy.wast:2287 +assert_return(() => call($14, "load8_u", [25_471]), 0); + +// memory_copy.wast:2288 +assert_return(() => call($14, "load8_u", [25_670]), 0); + +// memory_copy.wast:2289 +assert_return(() => call($14, "load8_u", [25_869]), 0); + +// memory_copy.wast:2290 +assert_return(() => call($14, "load8_u", [26_068]), 0); + +// memory_copy.wast:2291 +assert_return(() => call($14, "load8_u", [26_267]), 0); + +// memory_copy.wast:2292 +assert_return(() => call($14, "load8_u", [26_466]), 0); + +// memory_copy.wast:2293 +assert_return(() => call($14, "load8_u", [26_665]), 0); + +// memory_copy.wast:2294 +assert_return(() => call($14, "load8_u", [26_864]), 0); + +// memory_copy.wast:2295 +assert_return(() => call($14, "load8_u", [27_063]), 0); + +// memory_copy.wast:2296 +assert_return(() => call($14, "load8_u", [27_262]), 0); + +// memory_copy.wast:2297 +assert_return(() => call($14, "load8_u", [27_461]), 0); + +// memory_copy.wast:2298 +assert_return(() => call($14, "load8_u", [27_660]), 0); + +// memory_copy.wast:2299 +assert_return(() => call($14, "load8_u", [27_859]), 0); + +// memory_copy.wast:2300 +assert_return(() => call($14, "load8_u", [28_058]), 0); + +// memory_copy.wast:2301 +assert_return(() => call($14, "load8_u", [28_257]), 0); + +// memory_copy.wast:2302 +assert_return(() => call($14, "load8_u", [28_456]), 0); + +// memory_copy.wast:2303 +assert_return(() => call($14, "load8_u", [28_655]), 0); + +// memory_copy.wast:2304 +assert_return(() => call($14, "load8_u", [28_854]), 0); + +// memory_copy.wast:2305 +assert_return(() => call($14, "load8_u", [29_053]), 0); + +// memory_copy.wast:2306 +assert_return(() => call($14, "load8_u", [29_252]), 0); + +// memory_copy.wast:2307 +assert_return(() => call($14, "load8_u", [29_451]), 0); + +// memory_copy.wast:2308 +assert_return(() => call($14, "load8_u", [29_650]), 0); + +// memory_copy.wast:2309 +assert_return(() => call($14, "load8_u", [29_849]), 0); + +// memory_copy.wast:2310 +assert_return(() => call($14, "load8_u", [30_048]), 0); + +// memory_copy.wast:2311 +assert_return(() => call($14, "load8_u", [30_247]), 0); + +// memory_copy.wast:2312 +assert_return(() => call($14, "load8_u", [30_446]), 0); + +// memory_copy.wast:2313 +assert_return(() => call($14, "load8_u", [30_645]), 0); + +// memory_copy.wast:2314 +assert_return(() => call($14, "load8_u", [30_844]), 0); + +// memory_copy.wast:2315 +assert_return(() => call($14, "load8_u", [31_043]), 0); + +// memory_copy.wast:2316 +assert_return(() => call($14, "load8_u", [31_242]), 0); + +// memory_copy.wast:2317 +assert_return(() => call($14, "load8_u", [31_441]), 0); + +// memory_copy.wast:2318 +assert_return(() => call($14, "load8_u", [31_640]), 0); + +// memory_copy.wast:2319 +assert_return(() => call($14, "load8_u", [31_839]), 0); + +// memory_copy.wast:2320 +assert_return(() => call($14, "load8_u", [32_038]), 0); + +// memory_copy.wast:2321 +assert_return(() => call($14, "load8_u", [32_237]), 0); + +// memory_copy.wast:2322 +assert_return(() => call($14, "load8_u", [32_436]), 0); + +// memory_copy.wast:2323 +assert_return(() => call($14, "load8_u", [32_635]), 0); + +// memory_copy.wast:2324 +assert_return(() => call($14, "load8_u", [32_834]), 0); + +// memory_copy.wast:2325 +assert_return(() => call($14, "load8_u", [33_033]), 0); + +// memory_copy.wast:2326 +assert_return(() => call($14, "load8_u", [33_232]), 0); + +// memory_copy.wast:2327 +assert_return(() => call($14, "load8_u", [33_431]), 0); + +// memory_copy.wast:2328 +assert_return(() => call($14, "load8_u", [33_630]), 0); + +// memory_copy.wast:2329 +assert_return(() => call($14, "load8_u", [33_829]), 0); + +// memory_copy.wast:2330 +assert_return(() => call($14, "load8_u", [34_028]), 0); + +// memory_copy.wast:2331 +assert_return(() => call($14, "load8_u", [34_227]), 0); + +// memory_copy.wast:2332 +assert_return(() => call($14, "load8_u", [34_426]), 0); + +// memory_copy.wast:2333 +assert_return(() => call($14, "load8_u", [34_625]), 0); + +// memory_copy.wast:2334 +assert_return(() => call($14, "load8_u", [34_824]), 0); + +// memory_copy.wast:2335 +assert_return(() => call($14, "load8_u", [35_023]), 0); + +// memory_copy.wast:2336 +assert_return(() => call($14, "load8_u", [35_222]), 0); + +// memory_copy.wast:2337 +assert_return(() => call($14, "load8_u", [35_421]), 0); + +// memory_copy.wast:2338 +assert_return(() => call($14, "load8_u", [35_620]), 0); + +// memory_copy.wast:2339 +assert_return(() => call($14, "load8_u", [35_819]), 0); + +// memory_copy.wast:2340 +assert_return(() => call($14, "load8_u", [36_018]), 0); + +// memory_copy.wast:2341 +assert_return(() => call($14, "load8_u", [36_217]), 0); + +// memory_copy.wast:2342 +assert_return(() => call($14, "load8_u", [36_416]), 0); + +// memory_copy.wast:2343 +assert_return(() => call($14, "load8_u", [36_615]), 0); + +// memory_copy.wast:2344 +assert_return(() => call($14, "load8_u", [36_814]), 0); + +// memory_copy.wast:2345 +assert_return(() => call($14, "load8_u", [37_013]), 0); + +// memory_copy.wast:2346 +assert_return(() => call($14, "load8_u", [37_212]), 0); + +// memory_copy.wast:2347 +assert_return(() => call($14, "load8_u", [37_411]), 0); + +// memory_copy.wast:2348 +assert_return(() => call($14, "load8_u", [37_610]), 0); + +// memory_copy.wast:2349 +assert_return(() => call($14, "load8_u", [37_809]), 0); + +// memory_copy.wast:2350 +assert_return(() => call($14, "load8_u", [38_008]), 0); + +// memory_copy.wast:2351 +assert_return(() => call($14, "load8_u", [38_207]), 0); + +// memory_copy.wast:2352 +assert_return(() => call($14, "load8_u", [38_406]), 0); + +// memory_copy.wast:2353 +assert_return(() => call($14, "load8_u", [38_605]), 0); + +// memory_copy.wast:2354 +assert_return(() => call($14, "load8_u", [38_804]), 0); + +// memory_copy.wast:2355 +assert_return(() => call($14, "load8_u", [39_003]), 0); + +// memory_copy.wast:2356 +assert_return(() => call($14, "load8_u", [39_202]), 0); + +// memory_copy.wast:2357 +assert_return(() => call($14, "load8_u", [39_401]), 0); + +// memory_copy.wast:2358 +assert_return(() => call($14, "load8_u", [39_600]), 0); + +// memory_copy.wast:2359 +assert_return(() => call($14, "load8_u", [39_799]), 0); + +// memory_copy.wast:2360 +assert_return(() => call($14, "load8_u", [39_998]), 0); + +// memory_copy.wast:2361 +assert_return(() => call($14, "load8_u", [40_197]), 0); + +// memory_copy.wast:2362 +assert_return(() => call($14, "load8_u", [40_396]), 0); + +// memory_copy.wast:2363 +assert_return(() => call($14, "load8_u", [40_595]), 0); + +// memory_copy.wast:2364 +assert_return(() => call($14, "load8_u", [40_794]), 0); + +// memory_copy.wast:2365 +assert_return(() => call($14, "load8_u", [40_993]), 0); + +// memory_copy.wast:2366 +assert_return(() => call($14, "load8_u", [41_192]), 0); + +// memory_copy.wast:2367 +assert_return(() => call($14, "load8_u", [41_391]), 0); + +// memory_copy.wast:2368 +assert_return(() => call($14, "load8_u", [41_590]), 0); + +// memory_copy.wast:2369 +assert_return(() => call($14, "load8_u", [41_789]), 0); + +// memory_copy.wast:2370 +assert_return(() => call($14, "load8_u", [41_988]), 0); + +// memory_copy.wast:2371 +assert_return(() => call($14, "load8_u", [42_187]), 0); + +// memory_copy.wast:2372 +assert_return(() => call($14, "load8_u", [42_386]), 0); + +// memory_copy.wast:2373 +assert_return(() => call($14, "load8_u", [42_585]), 0); + +// memory_copy.wast:2374 +assert_return(() => call($14, "load8_u", [42_784]), 0); + +// memory_copy.wast:2375 +assert_return(() => call($14, "load8_u", [42_983]), 0); + +// memory_copy.wast:2376 +assert_return(() => call($14, "load8_u", [43_182]), 0); + +// memory_copy.wast:2377 +assert_return(() => call($14, "load8_u", [43_381]), 0); + +// memory_copy.wast:2378 +assert_return(() => call($14, "load8_u", [43_580]), 0); + +// memory_copy.wast:2379 +assert_return(() => call($14, "load8_u", [43_779]), 0); + +// memory_copy.wast:2380 +assert_return(() => call($14, "load8_u", [43_978]), 0); + +// memory_copy.wast:2381 +assert_return(() => call($14, "load8_u", [44_177]), 0); + +// memory_copy.wast:2382 +assert_return(() => call($14, "load8_u", [44_376]), 0); + +// memory_copy.wast:2383 +assert_return(() => call($14, "load8_u", [44_575]), 0); + +// memory_copy.wast:2384 +assert_return(() => call($14, "load8_u", [44_774]), 0); + +// memory_copy.wast:2385 +assert_return(() => call($14, "load8_u", [44_973]), 0); + +// memory_copy.wast:2386 +assert_return(() => call($14, "load8_u", [45_172]), 0); + +// memory_copy.wast:2387 +assert_return(() => call($14, "load8_u", [45_371]), 0); + +// memory_copy.wast:2388 +assert_return(() => call($14, "load8_u", [45_570]), 0); + +// memory_copy.wast:2389 +assert_return(() => call($14, "load8_u", [45_769]), 0); + +// memory_copy.wast:2390 +assert_return(() => call($14, "load8_u", [45_968]), 0); + +// memory_copy.wast:2391 +assert_return(() => call($14, "load8_u", [46_167]), 0); + +// memory_copy.wast:2392 +assert_return(() => call($14, "load8_u", [46_366]), 0); + +// memory_copy.wast:2393 +assert_return(() => call($14, "load8_u", [46_565]), 0); + +// memory_copy.wast:2394 +assert_return(() => call($14, "load8_u", [46_764]), 0); + +// memory_copy.wast:2395 +assert_return(() => call($14, "load8_u", [46_963]), 0); + +// memory_copy.wast:2396 +assert_return(() => call($14, "load8_u", [47_162]), 0); + +// memory_copy.wast:2397 +assert_return(() => call($14, "load8_u", [47_361]), 0); + +// memory_copy.wast:2398 +assert_return(() => call($14, "load8_u", [47_560]), 0); + +// memory_copy.wast:2399 +assert_return(() => call($14, "load8_u", [47_759]), 0); + +// memory_copy.wast:2400 +assert_return(() => call($14, "load8_u", [47_958]), 0); + +// memory_copy.wast:2401 +assert_return(() => call($14, "load8_u", [48_157]), 0); + +// memory_copy.wast:2402 +assert_return(() => call($14, "load8_u", [48_356]), 0); + +// memory_copy.wast:2403 +assert_return(() => call($14, "load8_u", [48_555]), 0); + +// memory_copy.wast:2404 +assert_return(() => call($14, "load8_u", [48_754]), 0); + +// memory_copy.wast:2405 +assert_return(() => call($14, "load8_u", [48_953]), 0); + +// memory_copy.wast:2406 +assert_return(() => call($14, "load8_u", [49_152]), 0); + +// memory_copy.wast:2407 +assert_return(() => call($14, "load8_u", [49_351]), 0); + +// memory_copy.wast:2408 +assert_return(() => call($14, "load8_u", [49_550]), 0); + +// memory_copy.wast:2409 +assert_return(() => call($14, "load8_u", [49_749]), 0); + +// memory_copy.wast:2410 +assert_return(() => call($14, "load8_u", [49_948]), 0); + +// memory_copy.wast:2411 +assert_return(() => call($14, "load8_u", [50_147]), 0); + +// memory_copy.wast:2412 +assert_return(() => call($14, "load8_u", [50_346]), 0); + +// memory_copy.wast:2413 +assert_return(() => call($14, "load8_u", [50_545]), 0); + +// memory_copy.wast:2414 +assert_return(() => call($14, "load8_u", [50_744]), 0); + +// memory_copy.wast:2415 +assert_return(() => call($14, "load8_u", [50_943]), 0); + +// memory_copy.wast:2416 +assert_return(() => call($14, "load8_u", [51_142]), 0); + +// memory_copy.wast:2417 +assert_return(() => call($14, "load8_u", [51_341]), 0); + +// memory_copy.wast:2418 +assert_return(() => call($14, "load8_u", [51_540]), 0); + +// memory_copy.wast:2419 +assert_return(() => call($14, "load8_u", [51_739]), 0); + +// memory_copy.wast:2420 +assert_return(() => call($14, "load8_u", [51_938]), 0); + +// memory_copy.wast:2421 +assert_return(() => call($14, "load8_u", [52_137]), 0); + +// memory_copy.wast:2422 +assert_return(() => call($14, "load8_u", [52_336]), 0); + +// memory_copy.wast:2423 +assert_return(() => call($14, "load8_u", [52_535]), 0); + +// memory_copy.wast:2424 +assert_return(() => call($14, "load8_u", [52_734]), 0); + +// memory_copy.wast:2425 +assert_return(() => call($14, "load8_u", [52_933]), 0); + +// memory_copy.wast:2426 +assert_return(() => call($14, "load8_u", [53_132]), 0); + +// memory_copy.wast:2427 +assert_return(() => call($14, "load8_u", [53_331]), 0); + +// memory_copy.wast:2428 +assert_return(() => call($14, "load8_u", [53_530]), 0); + +// memory_copy.wast:2429 +assert_return(() => call($14, "load8_u", [53_729]), 0); + +// memory_copy.wast:2430 +assert_return(() => call($14, "load8_u", [53_928]), 0); + +// memory_copy.wast:2431 +assert_return(() => call($14, "load8_u", [54_127]), 0); + +// memory_copy.wast:2432 +assert_return(() => call($14, "load8_u", [54_326]), 0); + +// memory_copy.wast:2433 +assert_return(() => call($14, "load8_u", [54_525]), 0); + +// memory_copy.wast:2434 +assert_return(() => call($14, "load8_u", [54_724]), 0); + +// memory_copy.wast:2435 +assert_return(() => call($14, "load8_u", [54_923]), 0); + +// memory_copy.wast:2436 +assert_return(() => call($14, "load8_u", [55_122]), 0); + +// memory_copy.wast:2437 +assert_return(() => call($14, "load8_u", [55_321]), 0); + +// memory_copy.wast:2438 +assert_return(() => call($14, "load8_u", [55_520]), 0); + +// memory_copy.wast:2439 +assert_return(() => call($14, "load8_u", [55_719]), 0); + +// memory_copy.wast:2440 +assert_return(() => call($14, "load8_u", [55_918]), 0); + +// memory_copy.wast:2441 +assert_return(() => call($14, "load8_u", [56_117]), 0); + +// memory_copy.wast:2442 +assert_return(() => call($14, "load8_u", [56_316]), 0); + +// memory_copy.wast:2443 +assert_return(() => call($14, "load8_u", [56_515]), 0); + +// memory_copy.wast:2444 +assert_return(() => call($14, "load8_u", [56_714]), 0); + +// memory_copy.wast:2445 +assert_return(() => call($14, "load8_u", [56_913]), 0); + +// memory_copy.wast:2446 +assert_return(() => call($14, "load8_u", [57_112]), 0); + +// memory_copy.wast:2447 +assert_return(() => call($14, "load8_u", [57_311]), 0); + +// memory_copy.wast:2448 +assert_return(() => call($14, "load8_u", [57_510]), 0); + +// memory_copy.wast:2449 +assert_return(() => call($14, "load8_u", [57_709]), 0); + +// memory_copy.wast:2450 +assert_return(() => call($14, "load8_u", [57_908]), 0); + +// memory_copy.wast:2451 +assert_return(() => call($14, "load8_u", [58_107]), 0); + +// memory_copy.wast:2452 +assert_return(() => call($14, "load8_u", [58_306]), 0); + +// memory_copy.wast:2453 +assert_return(() => call($14, "load8_u", [58_505]), 0); + +// memory_copy.wast:2454 +assert_return(() => call($14, "load8_u", [58_704]), 0); + +// memory_copy.wast:2455 +assert_return(() => call($14, "load8_u", [58_903]), 0); + +// memory_copy.wast:2456 +assert_return(() => call($14, "load8_u", [59_102]), 0); + +// memory_copy.wast:2457 +assert_return(() => call($14, "load8_u", [59_301]), 0); + +// memory_copy.wast:2458 +assert_return(() => call($14, "load8_u", [59_500]), 0); + +// memory_copy.wast:2459 +assert_return(() => call($14, "load8_u", [59_699]), 0); + +// memory_copy.wast:2460 +assert_return(() => call($14, "load8_u", [59_898]), 0); + +// memory_copy.wast:2461 +assert_return(() => call($14, "load8_u", [60_097]), 0); + +// memory_copy.wast:2462 +assert_return(() => call($14, "load8_u", [60_296]), 0); + +// memory_copy.wast:2463 +assert_return(() => call($14, "load8_u", [60_495]), 0); + +// memory_copy.wast:2464 +assert_return(() => call($14, "load8_u", [60_694]), 0); + +// memory_copy.wast:2465 +assert_return(() => call($14, "load8_u", [60_893]), 0); + +// memory_copy.wast:2466 +assert_return(() => call($14, "load8_u", [61_092]), 0); + +// memory_copy.wast:2467 +assert_return(() => call($14, "load8_u", [61_291]), 0); + +// memory_copy.wast:2468 +assert_return(() => call($14, "load8_u", [61_490]), 0); + +// memory_copy.wast:2469 +assert_return(() => call($14, "load8_u", [61_689]), 0); + +// memory_copy.wast:2470 +assert_return(() => call($14, "load8_u", [61_888]), 0); + +// memory_copy.wast:2471 +assert_return(() => call($14, "load8_u", [62_087]), 0); + +// memory_copy.wast:2472 +assert_return(() => call($14, "load8_u", [62_286]), 0); + +// memory_copy.wast:2473 +assert_return(() => call($14, "load8_u", [62_485]), 0); + +// memory_copy.wast:2474 +assert_return(() => call($14, "load8_u", [62_684]), 0); + +// memory_copy.wast:2475 +assert_return(() => call($14, "load8_u", [62_883]), 0); + +// memory_copy.wast:2476 +assert_return(() => call($14, "load8_u", [63_082]), 0); + +// memory_copy.wast:2477 +assert_return(() => call($14, "load8_u", [63_281]), 0); + +// memory_copy.wast:2478 +assert_return(() => call($14, "load8_u", [63_480]), 0); + +// memory_copy.wast:2479 +assert_return(() => call($14, "load8_u", [63_679]), 0); + +// memory_copy.wast:2480 +assert_return(() => call($14, "load8_u", [63_878]), 0); + +// memory_copy.wast:2481 +assert_return(() => call($14, "load8_u", [64_077]), 0); + +// memory_copy.wast:2482 +assert_return(() => call($14, "load8_u", [64_276]), 0); + +// memory_copy.wast:2483 +assert_return(() => call($14, "load8_u", [64_475]), 0); + +// memory_copy.wast:2484 +assert_return(() => call($14, "load8_u", [64_674]), 0); + +// memory_copy.wast:2485 +assert_return(() => call($14, "load8_u", [64_873]), 0); + +// memory_copy.wast:2486 +assert_return(() => call($14, "load8_u", [65_072]), 0); + +// memory_copy.wast:2487 +assert_return(() => call($14, "load8_u", [65_271]), 0); + +// memory_copy.wast:2488 +assert_return(() => call($14, "load8_u", [65_470]), 0); + +// memory_copy.wast:2489 +assert_return(() => call($14, "load8_u", [65_516]), 0); + +// memory_copy.wast:2490 +assert_return(() => call($14, "load8_u", [65_517]), 1); + +// memory_copy.wast:2491 +assert_return(() => call($14, "load8_u", [65_518]), 2); + +// memory_copy.wast:2492 +assert_return(() => call($14, "load8_u", [65_519]), 3); + +// memory_copy.wast:2493 +assert_return(() => call($14, "load8_u", [65_520]), 4); + +// memory_copy.wast:2494 +assert_return(() => call($14, "load8_u", [65_521]), 5); + +// memory_copy.wast:2495 +assert_return(() => call($14, "load8_u", [65_522]), 6); + +// memory_copy.wast:2496 +assert_return(() => call($14, "load8_u", [65_523]), 7); + +// memory_copy.wast:2497 +assert_return(() => call($14, "load8_u", [65_524]), 8); + +// memory_copy.wast:2498 +assert_return(() => call($14, "load8_u", [65_525]), 9); + +// memory_copy.wast:2499 +assert_return(() => call($14, "load8_u", [65_526]), 10); + +// memory_copy.wast:2500 +assert_return(() => call($14, "load8_u", [65_527]), 11); + +// memory_copy.wast:2501 +assert_return(() => call($14, "load8_u", [65_528]), 12); + +// memory_copy.wast:2502 +assert_return(() => call($14, "load8_u", [65_529]), 13); + +// memory_copy.wast:2503 +assert_return(() => call($14, "load8_u", [65_530]), 14); + +// memory_copy.wast:2504 +assert_return(() => call($14, "load8_u", [65_531]), 15); + +// memory_copy.wast:2505 +assert_return(() => call($14, "load8_u", [65_532]), 16); + +// memory_copy.wast:2506 +assert_return(() => call($14, "load8_u", [65_533]), 17); + +// memory_copy.wast:2507 +assert_return(() => call($14, "load8_u", [65_534]), 18); + +// memory_copy.wast:2508 +assert_return(() => call($14, "load8_u", [65_535]), 19); + +// memory_copy.wast:2510 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xe2\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2518 +assert_trap(() => call($15, "run", [65_516, 65_506, 40])); + +// memory_copy.wast:2521 +assert_return(() => call($15, "load8_u", [198]), 0); + +// memory_copy.wast:2522 +assert_return(() => call($15, "load8_u", [397]), 0); + +// memory_copy.wast:2523 +assert_return(() => call($15, "load8_u", [596]), 0); + +// memory_copy.wast:2524 +assert_return(() => call($15, "load8_u", [795]), 0); + +// memory_copy.wast:2525 +assert_return(() => call($15, "load8_u", [994]), 0); + +// memory_copy.wast:2526 +assert_return(() => call($15, "load8_u", [1_193]), 0); + +// memory_copy.wast:2527 +assert_return(() => call($15, "load8_u", [1_392]), 0); + +// memory_copy.wast:2528 +assert_return(() => call($15, "load8_u", [1_591]), 0); + +// memory_copy.wast:2529 +assert_return(() => call($15, "load8_u", [1_790]), 0); + +// memory_copy.wast:2530 +assert_return(() => call($15, "load8_u", [1_989]), 0); + +// memory_copy.wast:2531 +assert_return(() => call($15, "load8_u", [2_188]), 0); + +// memory_copy.wast:2532 +assert_return(() => call($15, "load8_u", [2_387]), 0); + +// memory_copy.wast:2533 +assert_return(() => call($15, "load8_u", [2_586]), 0); + +// memory_copy.wast:2534 +assert_return(() => call($15, "load8_u", [2_785]), 0); + +// memory_copy.wast:2535 +assert_return(() => call($15, "load8_u", [2_984]), 0); + +// memory_copy.wast:2536 +assert_return(() => call($15, "load8_u", [3_183]), 0); + +// memory_copy.wast:2537 +assert_return(() => call($15, "load8_u", [3_382]), 0); + +// memory_copy.wast:2538 +assert_return(() => call($15, "load8_u", [3_581]), 0); + +// memory_copy.wast:2539 +assert_return(() => call($15, "load8_u", [3_780]), 0); + +// memory_copy.wast:2540 +assert_return(() => call($15, "load8_u", [3_979]), 0); + +// memory_copy.wast:2541 +assert_return(() => call($15, "load8_u", [4_178]), 0); + +// memory_copy.wast:2542 +assert_return(() => call($15, "load8_u", [4_377]), 0); + +// memory_copy.wast:2543 +assert_return(() => call($15, "load8_u", [4_576]), 0); + +// memory_copy.wast:2544 +assert_return(() => call($15, "load8_u", [4_775]), 0); + +// memory_copy.wast:2545 +assert_return(() => call($15, "load8_u", [4_974]), 0); + +// memory_copy.wast:2546 +assert_return(() => call($15, "load8_u", [5_173]), 0); + +// memory_copy.wast:2547 +assert_return(() => call($15, "load8_u", [5_372]), 0); + +// memory_copy.wast:2548 +assert_return(() => call($15, "load8_u", [5_571]), 0); + +// memory_copy.wast:2549 +assert_return(() => call($15, "load8_u", [5_770]), 0); + +// memory_copy.wast:2550 +assert_return(() => call($15, "load8_u", [5_969]), 0); + +// memory_copy.wast:2551 +assert_return(() => call($15, "load8_u", [6_168]), 0); + +// memory_copy.wast:2552 +assert_return(() => call($15, "load8_u", [6_367]), 0); + +// memory_copy.wast:2553 +assert_return(() => call($15, "load8_u", [6_566]), 0); + +// memory_copy.wast:2554 +assert_return(() => call($15, "load8_u", [6_765]), 0); + +// memory_copy.wast:2555 +assert_return(() => call($15, "load8_u", [6_964]), 0); + +// memory_copy.wast:2556 +assert_return(() => call($15, "load8_u", [7_163]), 0); + +// memory_copy.wast:2557 +assert_return(() => call($15, "load8_u", [7_362]), 0); + +// memory_copy.wast:2558 +assert_return(() => call($15, "load8_u", [7_561]), 0); + +// memory_copy.wast:2559 +assert_return(() => call($15, "load8_u", [7_760]), 0); + +// memory_copy.wast:2560 +assert_return(() => call($15, "load8_u", [7_959]), 0); + +// memory_copy.wast:2561 +assert_return(() => call($15, "load8_u", [8_158]), 0); + +// memory_copy.wast:2562 +assert_return(() => call($15, "load8_u", [8_357]), 0); + +// memory_copy.wast:2563 +assert_return(() => call($15, "load8_u", [8_556]), 0); + +// memory_copy.wast:2564 +assert_return(() => call($15, "load8_u", [8_755]), 0); + +// memory_copy.wast:2565 +assert_return(() => call($15, "load8_u", [8_954]), 0); + +// memory_copy.wast:2566 +assert_return(() => call($15, "load8_u", [9_153]), 0); + +// memory_copy.wast:2567 +assert_return(() => call($15, "load8_u", [9_352]), 0); + +// memory_copy.wast:2568 +assert_return(() => call($15, "load8_u", [9_551]), 0); + +// memory_copy.wast:2569 +assert_return(() => call($15, "load8_u", [9_750]), 0); + +// memory_copy.wast:2570 +assert_return(() => call($15, "load8_u", [9_949]), 0); + +// memory_copy.wast:2571 +assert_return(() => call($15, "load8_u", [10_148]), 0); + +// memory_copy.wast:2572 +assert_return(() => call($15, "load8_u", [10_347]), 0); + +// memory_copy.wast:2573 +assert_return(() => call($15, "load8_u", [10_546]), 0); + +// memory_copy.wast:2574 +assert_return(() => call($15, "load8_u", [10_745]), 0); + +// memory_copy.wast:2575 +assert_return(() => call($15, "load8_u", [10_944]), 0); + +// memory_copy.wast:2576 +assert_return(() => call($15, "load8_u", [11_143]), 0); + +// memory_copy.wast:2577 +assert_return(() => call($15, "load8_u", [11_342]), 0); + +// memory_copy.wast:2578 +assert_return(() => call($15, "load8_u", [11_541]), 0); + +// memory_copy.wast:2579 +assert_return(() => call($15, "load8_u", [11_740]), 0); + +// memory_copy.wast:2580 +assert_return(() => call($15, "load8_u", [11_939]), 0); + +// memory_copy.wast:2581 +assert_return(() => call($15, "load8_u", [12_138]), 0); + +// memory_copy.wast:2582 +assert_return(() => call($15, "load8_u", [12_337]), 0); + +// memory_copy.wast:2583 +assert_return(() => call($15, "load8_u", [12_536]), 0); + +// memory_copy.wast:2584 +assert_return(() => call($15, "load8_u", [12_735]), 0); + +// memory_copy.wast:2585 +assert_return(() => call($15, "load8_u", [12_934]), 0); + +// memory_copy.wast:2586 +assert_return(() => call($15, "load8_u", [13_133]), 0); + +// memory_copy.wast:2587 +assert_return(() => call($15, "load8_u", [13_332]), 0); + +// memory_copy.wast:2588 +assert_return(() => call($15, "load8_u", [13_531]), 0); + +// memory_copy.wast:2589 +assert_return(() => call($15, "load8_u", [13_730]), 0); + +// memory_copy.wast:2590 +assert_return(() => call($15, "load8_u", [13_929]), 0); + +// memory_copy.wast:2591 +assert_return(() => call($15, "load8_u", [14_128]), 0); + +// memory_copy.wast:2592 +assert_return(() => call($15, "load8_u", [14_327]), 0); + +// memory_copy.wast:2593 +assert_return(() => call($15, "load8_u", [14_526]), 0); + +// memory_copy.wast:2594 +assert_return(() => call($15, "load8_u", [14_725]), 0); + +// memory_copy.wast:2595 +assert_return(() => call($15, "load8_u", [14_924]), 0); + +// memory_copy.wast:2596 +assert_return(() => call($15, "load8_u", [15_123]), 0); + +// memory_copy.wast:2597 +assert_return(() => call($15, "load8_u", [15_322]), 0); + +// memory_copy.wast:2598 +assert_return(() => call($15, "load8_u", [15_521]), 0); + +// memory_copy.wast:2599 +assert_return(() => call($15, "load8_u", [15_720]), 0); + +// memory_copy.wast:2600 +assert_return(() => call($15, "load8_u", [15_919]), 0); + +// memory_copy.wast:2601 +assert_return(() => call($15, "load8_u", [16_118]), 0); + +// memory_copy.wast:2602 +assert_return(() => call($15, "load8_u", [16_317]), 0); + +// memory_copy.wast:2603 +assert_return(() => call($15, "load8_u", [16_516]), 0); + +// memory_copy.wast:2604 +assert_return(() => call($15, "load8_u", [16_715]), 0); + +// memory_copy.wast:2605 +assert_return(() => call($15, "load8_u", [16_914]), 0); + +// memory_copy.wast:2606 +assert_return(() => call($15, "load8_u", [17_113]), 0); + +// memory_copy.wast:2607 +assert_return(() => call($15, "load8_u", [17_312]), 0); + +// memory_copy.wast:2608 +assert_return(() => call($15, "load8_u", [17_511]), 0); + +// memory_copy.wast:2609 +assert_return(() => call($15, "load8_u", [17_710]), 0); + +// memory_copy.wast:2610 +assert_return(() => call($15, "load8_u", [17_909]), 0); + +// memory_copy.wast:2611 +assert_return(() => call($15, "load8_u", [18_108]), 0); + +// memory_copy.wast:2612 +assert_return(() => call($15, "load8_u", [18_307]), 0); + +// memory_copy.wast:2613 +assert_return(() => call($15, "load8_u", [18_506]), 0); + +// memory_copy.wast:2614 +assert_return(() => call($15, "load8_u", [18_705]), 0); + +// memory_copy.wast:2615 +assert_return(() => call($15, "load8_u", [18_904]), 0); + +// memory_copy.wast:2616 +assert_return(() => call($15, "load8_u", [19_103]), 0); + +// memory_copy.wast:2617 +assert_return(() => call($15, "load8_u", [19_302]), 0); + +// memory_copy.wast:2618 +assert_return(() => call($15, "load8_u", [19_501]), 0); + +// memory_copy.wast:2619 +assert_return(() => call($15, "load8_u", [19_700]), 0); + +// memory_copy.wast:2620 +assert_return(() => call($15, "load8_u", [19_899]), 0); + +// memory_copy.wast:2621 +assert_return(() => call($15, "load8_u", [20_098]), 0); + +// memory_copy.wast:2622 +assert_return(() => call($15, "load8_u", [20_297]), 0); + +// memory_copy.wast:2623 +assert_return(() => call($15, "load8_u", [20_496]), 0); + +// memory_copy.wast:2624 +assert_return(() => call($15, "load8_u", [20_695]), 0); + +// memory_copy.wast:2625 +assert_return(() => call($15, "load8_u", [20_894]), 0); + +// memory_copy.wast:2626 +assert_return(() => call($15, "load8_u", [21_093]), 0); + +// memory_copy.wast:2627 +assert_return(() => call($15, "load8_u", [21_292]), 0); + +// memory_copy.wast:2628 +assert_return(() => call($15, "load8_u", [21_491]), 0); + +// memory_copy.wast:2629 +assert_return(() => call($15, "load8_u", [21_690]), 0); + +// memory_copy.wast:2630 +assert_return(() => call($15, "load8_u", [21_889]), 0); + +// memory_copy.wast:2631 +assert_return(() => call($15, "load8_u", [22_088]), 0); + +// memory_copy.wast:2632 +assert_return(() => call($15, "load8_u", [22_287]), 0); + +// memory_copy.wast:2633 +assert_return(() => call($15, "load8_u", [22_486]), 0); + +// memory_copy.wast:2634 +assert_return(() => call($15, "load8_u", [22_685]), 0); + +// memory_copy.wast:2635 +assert_return(() => call($15, "load8_u", [22_884]), 0); + +// memory_copy.wast:2636 +assert_return(() => call($15, "load8_u", [23_083]), 0); + +// memory_copy.wast:2637 +assert_return(() => call($15, "load8_u", [23_282]), 0); + +// memory_copy.wast:2638 +assert_return(() => call($15, "load8_u", [23_481]), 0); + +// memory_copy.wast:2639 +assert_return(() => call($15, "load8_u", [23_680]), 0); + +// memory_copy.wast:2640 +assert_return(() => call($15, "load8_u", [23_879]), 0); + +// memory_copy.wast:2641 +assert_return(() => call($15, "load8_u", [24_078]), 0); + +// memory_copy.wast:2642 +assert_return(() => call($15, "load8_u", [24_277]), 0); + +// memory_copy.wast:2643 +assert_return(() => call($15, "load8_u", [24_476]), 0); + +// memory_copy.wast:2644 +assert_return(() => call($15, "load8_u", [24_675]), 0); + +// memory_copy.wast:2645 +assert_return(() => call($15, "load8_u", [24_874]), 0); + +// memory_copy.wast:2646 +assert_return(() => call($15, "load8_u", [25_073]), 0); + +// memory_copy.wast:2647 +assert_return(() => call($15, "load8_u", [25_272]), 0); + +// memory_copy.wast:2648 +assert_return(() => call($15, "load8_u", [25_471]), 0); + +// memory_copy.wast:2649 +assert_return(() => call($15, "load8_u", [25_670]), 0); + +// memory_copy.wast:2650 +assert_return(() => call($15, "load8_u", [25_869]), 0); + +// memory_copy.wast:2651 +assert_return(() => call($15, "load8_u", [26_068]), 0); + +// memory_copy.wast:2652 +assert_return(() => call($15, "load8_u", [26_267]), 0); + +// memory_copy.wast:2653 +assert_return(() => call($15, "load8_u", [26_466]), 0); + +// memory_copy.wast:2654 +assert_return(() => call($15, "load8_u", [26_665]), 0); + +// memory_copy.wast:2655 +assert_return(() => call($15, "load8_u", [26_864]), 0); + +// memory_copy.wast:2656 +assert_return(() => call($15, "load8_u", [27_063]), 0); + +// memory_copy.wast:2657 +assert_return(() => call($15, "load8_u", [27_262]), 0); + +// memory_copy.wast:2658 +assert_return(() => call($15, "load8_u", [27_461]), 0); + +// memory_copy.wast:2659 +assert_return(() => call($15, "load8_u", [27_660]), 0); + +// memory_copy.wast:2660 +assert_return(() => call($15, "load8_u", [27_859]), 0); + +// memory_copy.wast:2661 +assert_return(() => call($15, "load8_u", [28_058]), 0); + +// memory_copy.wast:2662 +assert_return(() => call($15, "load8_u", [28_257]), 0); + +// memory_copy.wast:2663 +assert_return(() => call($15, "load8_u", [28_456]), 0); + +// memory_copy.wast:2664 +assert_return(() => call($15, "load8_u", [28_655]), 0); + +// memory_copy.wast:2665 +assert_return(() => call($15, "load8_u", [28_854]), 0); + +// memory_copy.wast:2666 +assert_return(() => call($15, "load8_u", [29_053]), 0); + +// memory_copy.wast:2667 +assert_return(() => call($15, "load8_u", [29_252]), 0); + +// memory_copy.wast:2668 +assert_return(() => call($15, "load8_u", [29_451]), 0); + +// memory_copy.wast:2669 +assert_return(() => call($15, "load8_u", [29_650]), 0); + +// memory_copy.wast:2670 +assert_return(() => call($15, "load8_u", [29_849]), 0); + +// memory_copy.wast:2671 +assert_return(() => call($15, "load8_u", [30_048]), 0); + +// memory_copy.wast:2672 +assert_return(() => call($15, "load8_u", [30_247]), 0); + +// memory_copy.wast:2673 +assert_return(() => call($15, "load8_u", [30_446]), 0); + +// memory_copy.wast:2674 +assert_return(() => call($15, "load8_u", [30_645]), 0); + +// memory_copy.wast:2675 +assert_return(() => call($15, "load8_u", [30_844]), 0); + +// memory_copy.wast:2676 +assert_return(() => call($15, "load8_u", [31_043]), 0); + +// memory_copy.wast:2677 +assert_return(() => call($15, "load8_u", [31_242]), 0); + +// memory_copy.wast:2678 +assert_return(() => call($15, "load8_u", [31_441]), 0); + +// memory_copy.wast:2679 +assert_return(() => call($15, "load8_u", [31_640]), 0); + +// memory_copy.wast:2680 +assert_return(() => call($15, "load8_u", [31_839]), 0); + +// memory_copy.wast:2681 +assert_return(() => call($15, "load8_u", [32_038]), 0); + +// memory_copy.wast:2682 +assert_return(() => call($15, "load8_u", [32_237]), 0); + +// memory_copy.wast:2683 +assert_return(() => call($15, "load8_u", [32_436]), 0); + +// memory_copy.wast:2684 +assert_return(() => call($15, "load8_u", [32_635]), 0); + +// memory_copy.wast:2685 +assert_return(() => call($15, "load8_u", [32_834]), 0); + +// memory_copy.wast:2686 +assert_return(() => call($15, "load8_u", [33_033]), 0); + +// memory_copy.wast:2687 +assert_return(() => call($15, "load8_u", [33_232]), 0); + +// memory_copy.wast:2688 +assert_return(() => call($15, "load8_u", [33_431]), 0); + +// memory_copy.wast:2689 +assert_return(() => call($15, "load8_u", [33_630]), 0); + +// memory_copy.wast:2690 +assert_return(() => call($15, "load8_u", [33_829]), 0); + +// memory_copy.wast:2691 +assert_return(() => call($15, "load8_u", [34_028]), 0); + +// memory_copy.wast:2692 +assert_return(() => call($15, "load8_u", [34_227]), 0); + +// memory_copy.wast:2693 +assert_return(() => call($15, "load8_u", [34_426]), 0); + +// memory_copy.wast:2694 +assert_return(() => call($15, "load8_u", [34_625]), 0); + +// memory_copy.wast:2695 +assert_return(() => call($15, "load8_u", [34_824]), 0); + +// memory_copy.wast:2696 +assert_return(() => call($15, "load8_u", [35_023]), 0); + +// memory_copy.wast:2697 +assert_return(() => call($15, "load8_u", [35_222]), 0); + +// memory_copy.wast:2698 +assert_return(() => call($15, "load8_u", [35_421]), 0); + +// memory_copy.wast:2699 +assert_return(() => call($15, "load8_u", [35_620]), 0); + +// memory_copy.wast:2700 +assert_return(() => call($15, "load8_u", [35_819]), 0); + +// memory_copy.wast:2701 +assert_return(() => call($15, "load8_u", [36_018]), 0); + +// memory_copy.wast:2702 +assert_return(() => call($15, "load8_u", [36_217]), 0); + +// memory_copy.wast:2703 +assert_return(() => call($15, "load8_u", [36_416]), 0); + +// memory_copy.wast:2704 +assert_return(() => call($15, "load8_u", [36_615]), 0); + +// memory_copy.wast:2705 +assert_return(() => call($15, "load8_u", [36_814]), 0); + +// memory_copy.wast:2706 +assert_return(() => call($15, "load8_u", [37_013]), 0); + +// memory_copy.wast:2707 +assert_return(() => call($15, "load8_u", [37_212]), 0); + +// memory_copy.wast:2708 +assert_return(() => call($15, "load8_u", [37_411]), 0); + +// memory_copy.wast:2709 +assert_return(() => call($15, "load8_u", [37_610]), 0); + +// memory_copy.wast:2710 +assert_return(() => call($15, "load8_u", [37_809]), 0); + +// memory_copy.wast:2711 +assert_return(() => call($15, "load8_u", [38_008]), 0); + +// memory_copy.wast:2712 +assert_return(() => call($15, "load8_u", [38_207]), 0); + +// memory_copy.wast:2713 +assert_return(() => call($15, "load8_u", [38_406]), 0); + +// memory_copy.wast:2714 +assert_return(() => call($15, "load8_u", [38_605]), 0); + +// memory_copy.wast:2715 +assert_return(() => call($15, "load8_u", [38_804]), 0); + +// memory_copy.wast:2716 +assert_return(() => call($15, "load8_u", [39_003]), 0); + +// memory_copy.wast:2717 +assert_return(() => call($15, "load8_u", [39_202]), 0); + +// memory_copy.wast:2718 +assert_return(() => call($15, "load8_u", [39_401]), 0); + +// memory_copy.wast:2719 +assert_return(() => call($15, "load8_u", [39_600]), 0); + +// memory_copy.wast:2720 +assert_return(() => call($15, "load8_u", [39_799]), 0); + +// memory_copy.wast:2721 +assert_return(() => call($15, "load8_u", [39_998]), 0); + +// memory_copy.wast:2722 +assert_return(() => call($15, "load8_u", [40_197]), 0); + +// memory_copy.wast:2723 +assert_return(() => call($15, "load8_u", [40_396]), 0); + +// memory_copy.wast:2724 +assert_return(() => call($15, "load8_u", [40_595]), 0); + +// memory_copy.wast:2725 +assert_return(() => call($15, "load8_u", [40_794]), 0); + +// memory_copy.wast:2726 +assert_return(() => call($15, "load8_u", [40_993]), 0); + +// memory_copy.wast:2727 +assert_return(() => call($15, "load8_u", [41_192]), 0); + +// memory_copy.wast:2728 +assert_return(() => call($15, "load8_u", [41_391]), 0); + +// memory_copy.wast:2729 +assert_return(() => call($15, "load8_u", [41_590]), 0); + +// memory_copy.wast:2730 +assert_return(() => call($15, "load8_u", [41_789]), 0); + +// memory_copy.wast:2731 +assert_return(() => call($15, "load8_u", [41_988]), 0); + +// memory_copy.wast:2732 +assert_return(() => call($15, "load8_u", [42_187]), 0); + +// memory_copy.wast:2733 +assert_return(() => call($15, "load8_u", [42_386]), 0); + +// memory_copy.wast:2734 +assert_return(() => call($15, "load8_u", [42_585]), 0); + +// memory_copy.wast:2735 +assert_return(() => call($15, "load8_u", [42_784]), 0); + +// memory_copy.wast:2736 +assert_return(() => call($15, "load8_u", [42_983]), 0); + +// memory_copy.wast:2737 +assert_return(() => call($15, "load8_u", [43_182]), 0); + +// memory_copy.wast:2738 +assert_return(() => call($15, "load8_u", [43_381]), 0); + +// memory_copy.wast:2739 +assert_return(() => call($15, "load8_u", [43_580]), 0); + +// memory_copy.wast:2740 +assert_return(() => call($15, "load8_u", [43_779]), 0); + +// memory_copy.wast:2741 +assert_return(() => call($15, "load8_u", [43_978]), 0); + +// memory_copy.wast:2742 +assert_return(() => call($15, "load8_u", [44_177]), 0); + +// memory_copy.wast:2743 +assert_return(() => call($15, "load8_u", [44_376]), 0); + +// memory_copy.wast:2744 +assert_return(() => call($15, "load8_u", [44_575]), 0); + +// memory_copy.wast:2745 +assert_return(() => call($15, "load8_u", [44_774]), 0); + +// memory_copy.wast:2746 +assert_return(() => call($15, "load8_u", [44_973]), 0); + +// memory_copy.wast:2747 +assert_return(() => call($15, "load8_u", [45_172]), 0); + +// memory_copy.wast:2748 +assert_return(() => call($15, "load8_u", [45_371]), 0); + +// memory_copy.wast:2749 +assert_return(() => call($15, "load8_u", [45_570]), 0); + +// memory_copy.wast:2750 +assert_return(() => call($15, "load8_u", [45_769]), 0); + +// memory_copy.wast:2751 +assert_return(() => call($15, "load8_u", [45_968]), 0); + +// memory_copy.wast:2752 +assert_return(() => call($15, "load8_u", [46_167]), 0); + +// memory_copy.wast:2753 +assert_return(() => call($15, "load8_u", [46_366]), 0); + +// memory_copy.wast:2754 +assert_return(() => call($15, "load8_u", [46_565]), 0); + +// memory_copy.wast:2755 +assert_return(() => call($15, "load8_u", [46_764]), 0); + +// memory_copy.wast:2756 +assert_return(() => call($15, "load8_u", [46_963]), 0); + +// memory_copy.wast:2757 +assert_return(() => call($15, "load8_u", [47_162]), 0); + +// memory_copy.wast:2758 +assert_return(() => call($15, "load8_u", [47_361]), 0); + +// memory_copy.wast:2759 +assert_return(() => call($15, "load8_u", [47_560]), 0); + +// memory_copy.wast:2760 +assert_return(() => call($15, "load8_u", [47_759]), 0); + +// memory_copy.wast:2761 +assert_return(() => call($15, "load8_u", [47_958]), 0); + +// memory_copy.wast:2762 +assert_return(() => call($15, "load8_u", [48_157]), 0); + +// memory_copy.wast:2763 +assert_return(() => call($15, "load8_u", [48_356]), 0); + +// memory_copy.wast:2764 +assert_return(() => call($15, "load8_u", [48_555]), 0); + +// memory_copy.wast:2765 +assert_return(() => call($15, "load8_u", [48_754]), 0); + +// memory_copy.wast:2766 +assert_return(() => call($15, "load8_u", [48_953]), 0); + +// memory_copy.wast:2767 +assert_return(() => call($15, "load8_u", [49_152]), 0); + +// memory_copy.wast:2768 +assert_return(() => call($15, "load8_u", [49_351]), 0); + +// memory_copy.wast:2769 +assert_return(() => call($15, "load8_u", [49_550]), 0); + +// memory_copy.wast:2770 +assert_return(() => call($15, "load8_u", [49_749]), 0); + +// memory_copy.wast:2771 +assert_return(() => call($15, "load8_u", [49_948]), 0); + +// memory_copy.wast:2772 +assert_return(() => call($15, "load8_u", [50_147]), 0); + +// memory_copy.wast:2773 +assert_return(() => call($15, "load8_u", [50_346]), 0); + +// memory_copy.wast:2774 +assert_return(() => call($15, "load8_u", [50_545]), 0); + +// memory_copy.wast:2775 +assert_return(() => call($15, "load8_u", [50_744]), 0); + +// memory_copy.wast:2776 +assert_return(() => call($15, "load8_u", [50_943]), 0); + +// memory_copy.wast:2777 +assert_return(() => call($15, "load8_u", [51_142]), 0); + +// memory_copy.wast:2778 +assert_return(() => call($15, "load8_u", [51_341]), 0); + +// memory_copy.wast:2779 +assert_return(() => call($15, "load8_u", [51_540]), 0); + +// memory_copy.wast:2780 +assert_return(() => call($15, "load8_u", [51_739]), 0); + +// memory_copy.wast:2781 +assert_return(() => call($15, "load8_u", [51_938]), 0); + +// memory_copy.wast:2782 +assert_return(() => call($15, "load8_u", [52_137]), 0); + +// memory_copy.wast:2783 +assert_return(() => call($15, "load8_u", [52_336]), 0); + +// memory_copy.wast:2784 +assert_return(() => call($15, "load8_u", [52_535]), 0); + +// memory_copy.wast:2785 +assert_return(() => call($15, "load8_u", [52_734]), 0); + +// memory_copy.wast:2786 +assert_return(() => call($15, "load8_u", [52_933]), 0); + +// memory_copy.wast:2787 +assert_return(() => call($15, "load8_u", [53_132]), 0); + +// memory_copy.wast:2788 +assert_return(() => call($15, "load8_u", [53_331]), 0); + +// memory_copy.wast:2789 +assert_return(() => call($15, "load8_u", [53_530]), 0); + +// memory_copy.wast:2790 +assert_return(() => call($15, "load8_u", [53_729]), 0); + +// memory_copy.wast:2791 +assert_return(() => call($15, "load8_u", [53_928]), 0); + +// memory_copy.wast:2792 +assert_return(() => call($15, "load8_u", [54_127]), 0); + +// memory_copy.wast:2793 +assert_return(() => call($15, "load8_u", [54_326]), 0); + +// memory_copy.wast:2794 +assert_return(() => call($15, "load8_u", [54_525]), 0); + +// memory_copy.wast:2795 +assert_return(() => call($15, "load8_u", [54_724]), 0); + +// memory_copy.wast:2796 +assert_return(() => call($15, "load8_u", [54_923]), 0); + +// memory_copy.wast:2797 +assert_return(() => call($15, "load8_u", [55_122]), 0); + +// memory_copy.wast:2798 +assert_return(() => call($15, "load8_u", [55_321]), 0); + +// memory_copy.wast:2799 +assert_return(() => call($15, "load8_u", [55_520]), 0); + +// memory_copy.wast:2800 +assert_return(() => call($15, "load8_u", [55_719]), 0); + +// memory_copy.wast:2801 +assert_return(() => call($15, "load8_u", [55_918]), 0); + +// memory_copy.wast:2802 +assert_return(() => call($15, "load8_u", [56_117]), 0); + +// memory_copy.wast:2803 +assert_return(() => call($15, "load8_u", [56_316]), 0); + +// memory_copy.wast:2804 +assert_return(() => call($15, "load8_u", [56_515]), 0); + +// memory_copy.wast:2805 +assert_return(() => call($15, "load8_u", [56_714]), 0); + +// memory_copy.wast:2806 +assert_return(() => call($15, "load8_u", [56_913]), 0); + +// memory_copy.wast:2807 +assert_return(() => call($15, "load8_u", [57_112]), 0); + +// memory_copy.wast:2808 +assert_return(() => call($15, "load8_u", [57_311]), 0); + +// memory_copy.wast:2809 +assert_return(() => call($15, "load8_u", [57_510]), 0); + +// memory_copy.wast:2810 +assert_return(() => call($15, "load8_u", [57_709]), 0); + +// memory_copy.wast:2811 +assert_return(() => call($15, "load8_u", [57_908]), 0); + +// memory_copy.wast:2812 +assert_return(() => call($15, "load8_u", [58_107]), 0); + +// memory_copy.wast:2813 +assert_return(() => call($15, "load8_u", [58_306]), 0); + +// memory_copy.wast:2814 +assert_return(() => call($15, "load8_u", [58_505]), 0); + +// memory_copy.wast:2815 +assert_return(() => call($15, "load8_u", [58_704]), 0); + +// memory_copy.wast:2816 +assert_return(() => call($15, "load8_u", [58_903]), 0); + +// memory_copy.wast:2817 +assert_return(() => call($15, "load8_u", [59_102]), 0); + +// memory_copy.wast:2818 +assert_return(() => call($15, "load8_u", [59_301]), 0); + +// memory_copy.wast:2819 +assert_return(() => call($15, "load8_u", [59_500]), 0); + +// memory_copy.wast:2820 +assert_return(() => call($15, "load8_u", [59_699]), 0); + +// memory_copy.wast:2821 +assert_return(() => call($15, "load8_u", [59_898]), 0); + +// memory_copy.wast:2822 +assert_return(() => call($15, "load8_u", [60_097]), 0); + +// memory_copy.wast:2823 +assert_return(() => call($15, "load8_u", [60_296]), 0); + +// memory_copy.wast:2824 +assert_return(() => call($15, "load8_u", [60_495]), 0); + +// memory_copy.wast:2825 +assert_return(() => call($15, "load8_u", [60_694]), 0); + +// memory_copy.wast:2826 +assert_return(() => call($15, "load8_u", [60_893]), 0); + +// memory_copy.wast:2827 +assert_return(() => call($15, "load8_u", [61_092]), 0); + +// memory_copy.wast:2828 +assert_return(() => call($15, "load8_u", [61_291]), 0); + +// memory_copy.wast:2829 +assert_return(() => call($15, "load8_u", [61_490]), 0); + +// memory_copy.wast:2830 +assert_return(() => call($15, "load8_u", [61_689]), 0); + +// memory_copy.wast:2831 +assert_return(() => call($15, "load8_u", [61_888]), 0); + +// memory_copy.wast:2832 +assert_return(() => call($15, "load8_u", [62_087]), 0); + +// memory_copy.wast:2833 +assert_return(() => call($15, "load8_u", [62_286]), 0); + +// memory_copy.wast:2834 +assert_return(() => call($15, "load8_u", [62_485]), 0); + +// memory_copy.wast:2835 +assert_return(() => call($15, "load8_u", [62_684]), 0); + +// memory_copy.wast:2836 +assert_return(() => call($15, "load8_u", [62_883]), 0); + +// memory_copy.wast:2837 +assert_return(() => call($15, "load8_u", [63_082]), 0); + +// memory_copy.wast:2838 +assert_return(() => call($15, "load8_u", [63_281]), 0); + +// memory_copy.wast:2839 +assert_return(() => call($15, "load8_u", [63_480]), 0); + +// memory_copy.wast:2840 +assert_return(() => call($15, "load8_u", [63_679]), 0); + +// memory_copy.wast:2841 +assert_return(() => call($15, "load8_u", [63_878]), 0); + +// memory_copy.wast:2842 +assert_return(() => call($15, "load8_u", [64_077]), 0); + +// memory_copy.wast:2843 +assert_return(() => call($15, "load8_u", [64_276]), 0); + +// memory_copy.wast:2844 +assert_return(() => call($15, "load8_u", [64_475]), 0); + +// memory_copy.wast:2845 +assert_return(() => call($15, "load8_u", [64_674]), 0); + +// memory_copy.wast:2846 +assert_return(() => call($15, "load8_u", [64_873]), 0); + +// memory_copy.wast:2847 +assert_return(() => call($15, "load8_u", [65_072]), 0); + +// memory_copy.wast:2848 +assert_return(() => call($15, "load8_u", [65_271]), 0); + +// memory_copy.wast:2849 +assert_return(() => call($15, "load8_u", [65_470]), 0); + +// memory_copy.wast:2850 +assert_return(() => call($15, "load8_u", [65_506]), 0); + +// memory_copy.wast:2851 +assert_return(() => call($15, "load8_u", [65_507]), 1); + +// memory_copy.wast:2852 +assert_return(() => call($15, "load8_u", [65_508]), 2); + +// memory_copy.wast:2853 +assert_return(() => call($15, "load8_u", [65_509]), 3); + +// memory_copy.wast:2854 +assert_return(() => call($15, "load8_u", [65_510]), 4); + +// memory_copy.wast:2855 +assert_return(() => call($15, "load8_u", [65_511]), 5); + +// memory_copy.wast:2856 +assert_return(() => call($15, "load8_u", [65_512]), 6); + +// memory_copy.wast:2857 +assert_return(() => call($15, "load8_u", [65_513]), 7); + +// memory_copy.wast:2858 +assert_return(() => call($15, "load8_u", [65_514]), 8); + +// memory_copy.wast:2859 +assert_return(() => call($15, "load8_u", [65_515]), 9); + +// memory_copy.wast:2860 +assert_return(() => call($15, "load8_u", [65_516]), 10); + +// memory_copy.wast:2861 +assert_return(() => call($15, "load8_u", [65_517]), 11); + +// memory_copy.wast:2862 +assert_return(() => call($15, "load8_u", [65_518]), 12); + +// memory_copy.wast:2863 +assert_return(() => call($15, "load8_u", [65_519]), 13); + +// memory_copy.wast:2864 +assert_return(() => call($15, "load8_u", [65_520]), 14); + +// memory_copy.wast:2865 +assert_return(() => call($15, "load8_u", [65_521]), 15); + +// memory_copy.wast:2866 +assert_return(() => call($15, "load8_u", [65_522]), 16); + +// memory_copy.wast:2867 +assert_return(() => call($15, "load8_u", [65_523]), 17); + +// memory_copy.wast:2868 +assert_return(() => call($15, "load8_u", [65_524]), 18); + +// memory_copy.wast:2869 +assert_return(() => call($15, "load8_u", [65_525]), 19); + +// memory_copy.wast:2871 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:2879 +assert_trap(() => call($16, "run", [65_506, 65_516, 40])); + +// memory_copy.wast:2882 +assert_return(() => call($16, "load8_u", [198]), 0); + +// memory_copy.wast:2883 +assert_return(() => call($16, "load8_u", [397]), 0); + +// memory_copy.wast:2884 +assert_return(() => call($16, "load8_u", [596]), 0); + +// memory_copy.wast:2885 +assert_return(() => call($16, "load8_u", [795]), 0); + +// memory_copy.wast:2886 +assert_return(() => call($16, "load8_u", [994]), 0); + +// memory_copy.wast:2887 +assert_return(() => call($16, "load8_u", [1_193]), 0); + +// memory_copy.wast:2888 +assert_return(() => call($16, "load8_u", [1_392]), 0); + +// memory_copy.wast:2889 +assert_return(() => call($16, "load8_u", [1_591]), 0); + +// memory_copy.wast:2890 +assert_return(() => call($16, "load8_u", [1_790]), 0); + +// memory_copy.wast:2891 +assert_return(() => call($16, "load8_u", [1_989]), 0); + +// memory_copy.wast:2892 +assert_return(() => call($16, "load8_u", [2_188]), 0); + +// memory_copy.wast:2893 +assert_return(() => call($16, "load8_u", [2_387]), 0); + +// memory_copy.wast:2894 +assert_return(() => call($16, "load8_u", [2_586]), 0); + +// memory_copy.wast:2895 +assert_return(() => call($16, "load8_u", [2_785]), 0); + +// memory_copy.wast:2896 +assert_return(() => call($16, "load8_u", [2_984]), 0); + +// memory_copy.wast:2897 +assert_return(() => call($16, "load8_u", [3_183]), 0); + +// memory_copy.wast:2898 +assert_return(() => call($16, "load8_u", [3_382]), 0); + +// memory_copy.wast:2899 +assert_return(() => call($16, "load8_u", [3_581]), 0); + +// memory_copy.wast:2900 +assert_return(() => call($16, "load8_u", [3_780]), 0); + +// memory_copy.wast:2901 +assert_return(() => call($16, "load8_u", [3_979]), 0); + +// memory_copy.wast:2902 +assert_return(() => call($16, "load8_u", [4_178]), 0); + +// memory_copy.wast:2903 +assert_return(() => call($16, "load8_u", [4_377]), 0); + +// memory_copy.wast:2904 +assert_return(() => call($16, "load8_u", [4_576]), 0); + +// memory_copy.wast:2905 +assert_return(() => call($16, "load8_u", [4_775]), 0); + +// memory_copy.wast:2906 +assert_return(() => call($16, "load8_u", [4_974]), 0); + +// memory_copy.wast:2907 +assert_return(() => call($16, "load8_u", [5_173]), 0); + +// memory_copy.wast:2908 +assert_return(() => call($16, "load8_u", [5_372]), 0); + +// memory_copy.wast:2909 +assert_return(() => call($16, "load8_u", [5_571]), 0); + +// memory_copy.wast:2910 +assert_return(() => call($16, "load8_u", [5_770]), 0); + +// memory_copy.wast:2911 +assert_return(() => call($16, "load8_u", [5_969]), 0); + +// memory_copy.wast:2912 +assert_return(() => call($16, "load8_u", [6_168]), 0); + +// memory_copy.wast:2913 +assert_return(() => call($16, "load8_u", [6_367]), 0); + +// memory_copy.wast:2914 +assert_return(() => call($16, "load8_u", [6_566]), 0); + +// memory_copy.wast:2915 +assert_return(() => call($16, "load8_u", [6_765]), 0); + +// memory_copy.wast:2916 +assert_return(() => call($16, "load8_u", [6_964]), 0); + +// memory_copy.wast:2917 +assert_return(() => call($16, "load8_u", [7_163]), 0); + +// memory_copy.wast:2918 +assert_return(() => call($16, "load8_u", [7_362]), 0); + +// memory_copy.wast:2919 +assert_return(() => call($16, "load8_u", [7_561]), 0); + +// memory_copy.wast:2920 +assert_return(() => call($16, "load8_u", [7_760]), 0); + +// memory_copy.wast:2921 +assert_return(() => call($16, "load8_u", [7_959]), 0); + +// memory_copy.wast:2922 +assert_return(() => call($16, "load8_u", [8_158]), 0); + +// memory_copy.wast:2923 +assert_return(() => call($16, "load8_u", [8_357]), 0); + +// memory_copy.wast:2924 +assert_return(() => call($16, "load8_u", [8_556]), 0); + +// memory_copy.wast:2925 +assert_return(() => call($16, "load8_u", [8_755]), 0); + +// memory_copy.wast:2926 +assert_return(() => call($16, "load8_u", [8_954]), 0); + +// memory_copy.wast:2927 +assert_return(() => call($16, "load8_u", [9_153]), 0); + +// memory_copy.wast:2928 +assert_return(() => call($16, "load8_u", [9_352]), 0); + +// memory_copy.wast:2929 +assert_return(() => call($16, "load8_u", [9_551]), 0); + +// memory_copy.wast:2930 +assert_return(() => call($16, "load8_u", [9_750]), 0); + +// memory_copy.wast:2931 +assert_return(() => call($16, "load8_u", [9_949]), 0); + +// memory_copy.wast:2932 +assert_return(() => call($16, "load8_u", [10_148]), 0); + +// memory_copy.wast:2933 +assert_return(() => call($16, "load8_u", [10_347]), 0); + +// memory_copy.wast:2934 +assert_return(() => call($16, "load8_u", [10_546]), 0); + +// memory_copy.wast:2935 +assert_return(() => call($16, "load8_u", [10_745]), 0); + +// memory_copy.wast:2936 +assert_return(() => call($16, "load8_u", [10_944]), 0); + +// memory_copy.wast:2937 +assert_return(() => call($16, "load8_u", [11_143]), 0); + +// memory_copy.wast:2938 +assert_return(() => call($16, "load8_u", [11_342]), 0); + +// memory_copy.wast:2939 +assert_return(() => call($16, "load8_u", [11_541]), 0); + +// memory_copy.wast:2940 +assert_return(() => call($16, "load8_u", [11_740]), 0); + +// memory_copy.wast:2941 +assert_return(() => call($16, "load8_u", [11_939]), 0); + +// memory_copy.wast:2942 +assert_return(() => call($16, "load8_u", [12_138]), 0); + +// memory_copy.wast:2943 +assert_return(() => call($16, "load8_u", [12_337]), 0); + +// memory_copy.wast:2944 +assert_return(() => call($16, "load8_u", [12_536]), 0); + +// memory_copy.wast:2945 +assert_return(() => call($16, "load8_u", [12_735]), 0); + +// memory_copy.wast:2946 +assert_return(() => call($16, "load8_u", [12_934]), 0); + +// memory_copy.wast:2947 +assert_return(() => call($16, "load8_u", [13_133]), 0); + +// memory_copy.wast:2948 +assert_return(() => call($16, "load8_u", [13_332]), 0); + +// memory_copy.wast:2949 +assert_return(() => call($16, "load8_u", [13_531]), 0); + +// memory_copy.wast:2950 +assert_return(() => call($16, "load8_u", [13_730]), 0); + +// memory_copy.wast:2951 +assert_return(() => call($16, "load8_u", [13_929]), 0); + +// memory_copy.wast:2952 +assert_return(() => call($16, "load8_u", [14_128]), 0); + +// memory_copy.wast:2953 +assert_return(() => call($16, "load8_u", [14_327]), 0); + +// memory_copy.wast:2954 +assert_return(() => call($16, "load8_u", [14_526]), 0); + +// memory_copy.wast:2955 +assert_return(() => call($16, "load8_u", [14_725]), 0); + +// memory_copy.wast:2956 +assert_return(() => call($16, "load8_u", [14_924]), 0); + +// memory_copy.wast:2957 +assert_return(() => call($16, "load8_u", [15_123]), 0); + +// memory_copy.wast:2958 +assert_return(() => call($16, "load8_u", [15_322]), 0); + +// memory_copy.wast:2959 +assert_return(() => call($16, "load8_u", [15_521]), 0); + +// memory_copy.wast:2960 +assert_return(() => call($16, "load8_u", [15_720]), 0); + +// memory_copy.wast:2961 +assert_return(() => call($16, "load8_u", [15_919]), 0); + +// memory_copy.wast:2962 +assert_return(() => call($16, "load8_u", [16_118]), 0); + +// memory_copy.wast:2963 +assert_return(() => call($16, "load8_u", [16_317]), 0); + +// memory_copy.wast:2964 +assert_return(() => call($16, "load8_u", [16_516]), 0); + +// memory_copy.wast:2965 +assert_return(() => call($16, "load8_u", [16_715]), 0); + +// memory_copy.wast:2966 +assert_return(() => call($16, "load8_u", [16_914]), 0); + +// memory_copy.wast:2967 +assert_return(() => call($16, "load8_u", [17_113]), 0); + +// memory_copy.wast:2968 +assert_return(() => call($16, "load8_u", [17_312]), 0); + +// memory_copy.wast:2969 +assert_return(() => call($16, "load8_u", [17_511]), 0); + +// memory_copy.wast:2970 +assert_return(() => call($16, "load8_u", [17_710]), 0); + +// memory_copy.wast:2971 +assert_return(() => call($16, "load8_u", [17_909]), 0); + +// memory_copy.wast:2972 +assert_return(() => call($16, "load8_u", [18_108]), 0); + +// memory_copy.wast:2973 +assert_return(() => call($16, "load8_u", [18_307]), 0); + +// memory_copy.wast:2974 +assert_return(() => call($16, "load8_u", [18_506]), 0); + +// memory_copy.wast:2975 +assert_return(() => call($16, "load8_u", [18_705]), 0); + +// memory_copy.wast:2976 +assert_return(() => call($16, "load8_u", [18_904]), 0); + +// memory_copy.wast:2977 +assert_return(() => call($16, "load8_u", [19_103]), 0); + +// memory_copy.wast:2978 +assert_return(() => call($16, "load8_u", [19_302]), 0); + +// memory_copy.wast:2979 +assert_return(() => call($16, "load8_u", [19_501]), 0); + +// memory_copy.wast:2980 +assert_return(() => call($16, "load8_u", [19_700]), 0); + +// memory_copy.wast:2981 +assert_return(() => call($16, "load8_u", [19_899]), 0); + +// memory_copy.wast:2982 +assert_return(() => call($16, "load8_u", [20_098]), 0); + +// memory_copy.wast:2983 +assert_return(() => call($16, "load8_u", [20_297]), 0); + +// memory_copy.wast:2984 +assert_return(() => call($16, "load8_u", [20_496]), 0); + +// memory_copy.wast:2985 +assert_return(() => call($16, "load8_u", [20_695]), 0); + +// memory_copy.wast:2986 +assert_return(() => call($16, "load8_u", [20_894]), 0); + +// memory_copy.wast:2987 +assert_return(() => call($16, "load8_u", [21_093]), 0); + +// memory_copy.wast:2988 +assert_return(() => call($16, "load8_u", [21_292]), 0); + +// memory_copy.wast:2989 +assert_return(() => call($16, "load8_u", [21_491]), 0); + +// memory_copy.wast:2990 +assert_return(() => call($16, "load8_u", [21_690]), 0); + +// memory_copy.wast:2991 +assert_return(() => call($16, "load8_u", [21_889]), 0); + +// memory_copy.wast:2992 +assert_return(() => call($16, "load8_u", [22_088]), 0); + +// memory_copy.wast:2993 +assert_return(() => call($16, "load8_u", [22_287]), 0); + +// memory_copy.wast:2994 +assert_return(() => call($16, "load8_u", [22_486]), 0); + +// memory_copy.wast:2995 +assert_return(() => call($16, "load8_u", [22_685]), 0); + +// memory_copy.wast:2996 +assert_return(() => call($16, "load8_u", [22_884]), 0); + +// memory_copy.wast:2997 +assert_return(() => call($16, "load8_u", [23_083]), 0); + +// memory_copy.wast:2998 +assert_return(() => call($16, "load8_u", [23_282]), 0); + +// memory_copy.wast:2999 +assert_return(() => call($16, "load8_u", [23_481]), 0); + +// memory_copy.wast:3000 +assert_return(() => call($16, "load8_u", [23_680]), 0); + +// memory_copy.wast:3001 +assert_return(() => call($16, "load8_u", [23_879]), 0); + +// memory_copy.wast:3002 +assert_return(() => call($16, "load8_u", [24_078]), 0); + +// memory_copy.wast:3003 +assert_return(() => call($16, "load8_u", [24_277]), 0); + +// memory_copy.wast:3004 +assert_return(() => call($16, "load8_u", [24_476]), 0); + +// memory_copy.wast:3005 +assert_return(() => call($16, "load8_u", [24_675]), 0); + +// memory_copy.wast:3006 +assert_return(() => call($16, "load8_u", [24_874]), 0); + +// memory_copy.wast:3007 +assert_return(() => call($16, "load8_u", [25_073]), 0); + +// memory_copy.wast:3008 +assert_return(() => call($16, "load8_u", [25_272]), 0); + +// memory_copy.wast:3009 +assert_return(() => call($16, "load8_u", [25_471]), 0); + +// memory_copy.wast:3010 +assert_return(() => call($16, "load8_u", [25_670]), 0); + +// memory_copy.wast:3011 +assert_return(() => call($16, "load8_u", [25_869]), 0); + +// memory_copy.wast:3012 +assert_return(() => call($16, "load8_u", [26_068]), 0); + +// memory_copy.wast:3013 +assert_return(() => call($16, "load8_u", [26_267]), 0); + +// memory_copy.wast:3014 +assert_return(() => call($16, "load8_u", [26_466]), 0); + +// memory_copy.wast:3015 +assert_return(() => call($16, "load8_u", [26_665]), 0); + +// memory_copy.wast:3016 +assert_return(() => call($16, "load8_u", [26_864]), 0); + +// memory_copy.wast:3017 +assert_return(() => call($16, "load8_u", [27_063]), 0); + +// memory_copy.wast:3018 +assert_return(() => call($16, "load8_u", [27_262]), 0); + +// memory_copy.wast:3019 +assert_return(() => call($16, "load8_u", [27_461]), 0); + +// memory_copy.wast:3020 +assert_return(() => call($16, "load8_u", [27_660]), 0); + +// memory_copy.wast:3021 +assert_return(() => call($16, "load8_u", [27_859]), 0); + +// memory_copy.wast:3022 +assert_return(() => call($16, "load8_u", [28_058]), 0); + +// memory_copy.wast:3023 +assert_return(() => call($16, "load8_u", [28_257]), 0); + +// memory_copy.wast:3024 +assert_return(() => call($16, "load8_u", [28_456]), 0); + +// memory_copy.wast:3025 +assert_return(() => call($16, "load8_u", [28_655]), 0); + +// memory_copy.wast:3026 +assert_return(() => call($16, "load8_u", [28_854]), 0); + +// memory_copy.wast:3027 +assert_return(() => call($16, "load8_u", [29_053]), 0); + +// memory_copy.wast:3028 +assert_return(() => call($16, "load8_u", [29_252]), 0); + +// memory_copy.wast:3029 +assert_return(() => call($16, "load8_u", [29_451]), 0); + +// memory_copy.wast:3030 +assert_return(() => call($16, "load8_u", [29_650]), 0); + +// memory_copy.wast:3031 +assert_return(() => call($16, "load8_u", [29_849]), 0); + +// memory_copy.wast:3032 +assert_return(() => call($16, "load8_u", [30_048]), 0); + +// memory_copy.wast:3033 +assert_return(() => call($16, "load8_u", [30_247]), 0); + +// memory_copy.wast:3034 +assert_return(() => call($16, "load8_u", [30_446]), 0); + +// memory_copy.wast:3035 +assert_return(() => call($16, "load8_u", [30_645]), 0); + +// memory_copy.wast:3036 +assert_return(() => call($16, "load8_u", [30_844]), 0); + +// memory_copy.wast:3037 +assert_return(() => call($16, "load8_u", [31_043]), 0); + +// memory_copy.wast:3038 +assert_return(() => call($16, "load8_u", [31_242]), 0); + +// memory_copy.wast:3039 +assert_return(() => call($16, "load8_u", [31_441]), 0); + +// memory_copy.wast:3040 +assert_return(() => call($16, "load8_u", [31_640]), 0); + +// memory_copy.wast:3041 +assert_return(() => call($16, "load8_u", [31_839]), 0); + +// memory_copy.wast:3042 +assert_return(() => call($16, "load8_u", [32_038]), 0); + +// memory_copy.wast:3043 +assert_return(() => call($16, "load8_u", [32_237]), 0); + +// memory_copy.wast:3044 +assert_return(() => call($16, "load8_u", [32_436]), 0); + +// memory_copy.wast:3045 +assert_return(() => call($16, "load8_u", [32_635]), 0); + +// memory_copy.wast:3046 +assert_return(() => call($16, "load8_u", [32_834]), 0); + +// memory_copy.wast:3047 +assert_return(() => call($16, "load8_u", [33_033]), 0); + +// memory_copy.wast:3048 +assert_return(() => call($16, "load8_u", [33_232]), 0); + +// memory_copy.wast:3049 +assert_return(() => call($16, "load8_u", [33_431]), 0); + +// memory_copy.wast:3050 +assert_return(() => call($16, "load8_u", [33_630]), 0); + +// memory_copy.wast:3051 +assert_return(() => call($16, "load8_u", [33_829]), 0); + +// memory_copy.wast:3052 +assert_return(() => call($16, "load8_u", [34_028]), 0); + +// memory_copy.wast:3053 +assert_return(() => call($16, "load8_u", [34_227]), 0); + +// memory_copy.wast:3054 +assert_return(() => call($16, "load8_u", [34_426]), 0); + +// memory_copy.wast:3055 +assert_return(() => call($16, "load8_u", [34_625]), 0); + +// memory_copy.wast:3056 +assert_return(() => call($16, "load8_u", [34_824]), 0); + +// memory_copy.wast:3057 +assert_return(() => call($16, "load8_u", [35_023]), 0); + +// memory_copy.wast:3058 +assert_return(() => call($16, "load8_u", [35_222]), 0); + +// memory_copy.wast:3059 +assert_return(() => call($16, "load8_u", [35_421]), 0); + +// memory_copy.wast:3060 +assert_return(() => call($16, "load8_u", [35_620]), 0); + +// memory_copy.wast:3061 +assert_return(() => call($16, "load8_u", [35_819]), 0); + +// memory_copy.wast:3062 +assert_return(() => call($16, "load8_u", [36_018]), 0); + +// memory_copy.wast:3063 +assert_return(() => call($16, "load8_u", [36_217]), 0); + +// memory_copy.wast:3064 +assert_return(() => call($16, "load8_u", [36_416]), 0); + +// memory_copy.wast:3065 +assert_return(() => call($16, "load8_u", [36_615]), 0); + +// memory_copy.wast:3066 +assert_return(() => call($16, "load8_u", [36_814]), 0); + +// memory_copy.wast:3067 +assert_return(() => call($16, "load8_u", [37_013]), 0); + +// memory_copy.wast:3068 +assert_return(() => call($16, "load8_u", [37_212]), 0); + +// memory_copy.wast:3069 +assert_return(() => call($16, "load8_u", [37_411]), 0); + +// memory_copy.wast:3070 +assert_return(() => call($16, "load8_u", [37_610]), 0); + +// memory_copy.wast:3071 +assert_return(() => call($16, "load8_u", [37_809]), 0); + +// memory_copy.wast:3072 +assert_return(() => call($16, "load8_u", [38_008]), 0); + +// memory_copy.wast:3073 +assert_return(() => call($16, "load8_u", [38_207]), 0); + +// memory_copy.wast:3074 +assert_return(() => call($16, "load8_u", [38_406]), 0); + +// memory_copy.wast:3075 +assert_return(() => call($16, "load8_u", [38_605]), 0); + +// memory_copy.wast:3076 +assert_return(() => call($16, "load8_u", [38_804]), 0); + +// memory_copy.wast:3077 +assert_return(() => call($16, "load8_u", [39_003]), 0); + +// memory_copy.wast:3078 +assert_return(() => call($16, "load8_u", [39_202]), 0); + +// memory_copy.wast:3079 +assert_return(() => call($16, "load8_u", [39_401]), 0); + +// memory_copy.wast:3080 +assert_return(() => call($16, "load8_u", [39_600]), 0); + +// memory_copy.wast:3081 +assert_return(() => call($16, "load8_u", [39_799]), 0); + +// memory_copy.wast:3082 +assert_return(() => call($16, "load8_u", [39_998]), 0); + +// memory_copy.wast:3083 +assert_return(() => call($16, "load8_u", [40_197]), 0); + +// memory_copy.wast:3084 +assert_return(() => call($16, "load8_u", [40_396]), 0); + +// memory_copy.wast:3085 +assert_return(() => call($16, "load8_u", [40_595]), 0); + +// memory_copy.wast:3086 +assert_return(() => call($16, "load8_u", [40_794]), 0); + +// memory_copy.wast:3087 +assert_return(() => call($16, "load8_u", [40_993]), 0); + +// memory_copy.wast:3088 +assert_return(() => call($16, "load8_u", [41_192]), 0); + +// memory_copy.wast:3089 +assert_return(() => call($16, "load8_u", [41_391]), 0); + +// memory_copy.wast:3090 +assert_return(() => call($16, "load8_u", [41_590]), 0); + +// memory_copy.wast:3091 +assert_return(() => call($16, "load8_u", [41_789]), 0); + +// memory_copy.wast:3092 +assert_return(() => call($16, "load8_u", [41_988]), 0); + +// memory_copy.wast:3093 +assert_return(() => call($16, "load8_u", [42_187]), 0); + +// memory_copy.wast:3094 +assert_return(() => call($16, "load8_u", [42_386]), 0); + +// memory_copy.wast:3095 +assert_return(() => call($16, "load8_u", [42_585]), 0); + +// memory_copy.wast:3096 +assert_return(() => call($16, "load8_u", [42_784]), 0); + +// memory_copy.wast:3097 +assert_return(() => call($16, "load8_u", [42_983]), 0); + +// memory_copy.wast:3098 +assert_return(() => call($16, "load8_u", [43_182]), 0); + +// memory_copy.wast:3099 +assert_return(() => call($16, "load8_u", [43_381]), 0); + +// memory_copy.wast:3100 +assert_return(() => call($16, "load8_u", [43_580]), 0); + +// memory_copy.wast:3101 +assert_return(() => call($16, "load8_u", [43_779]), 0); + +// memory_copy.wast:3102 +assert_return(() => call($16, "load8_u", [43_978]), 0); + +// memory_copy.wast:3103 +assert_return(() => call($16, "load8_u", [44_177]), 0); + +// memory_copy.wast:3104 +assert_return(() => call($16, "load8_u", [44_376]), 0); + +// memory_copy.wast:3105 +assert_return(() => call($16, "load8_u", [44_575]), 0); + +// memory_copy.wast:3106 +assert_return(() => call($16, "load8_u", [44_774]), 0); + +// memory_copy.wast:3107 +assert_return(() => call($16, "load8_u", [44_973]), 0); + +// memory_copy.wast:3108 +assert_return(() => call($16, "load8_u", [45_172]), 0); + +// memory_copy.wast:3109 +assert_return(() => call($16, "load8_u", [45_371]), 0); + +// memory_copy.wast:3110 +assert_return(() => call($16, "load8_u", [45_570]), 0); + +// memory_copy.wast:3111 +assert_return(() => call($16, "load8_u", [45_769]), 0); + +// memory_copy.wast:3112 +assert_return(() => call($16, "load8_u", [45_968]), 0); + +// memory_copy.wast:3113 +assert_return(() => call($16, "load8_u", [46_167]), 0); + +// memory_copy.wast:3114 +assert_return(() => call($16, "load8_u", [46_366]), 0); + +// memory_copy.wast:3115 +assert_return(() => call($16, "load8_u", [46_565]), 0); + +// memory_copy.wast:3116 +assert_return(() => call($16, "load8_u", [46_764]), 0); + +// memory_copy.wast:3117 +assert_return(() => call($16, "load8_u", [46_963]), 0); + +// memory_copy.wast:3118 +assert_return(() => call($16, "load8_u", [47_162]), 0); + +// memory_copy.wast:3119 +assert_return(() => call($16, "load8_u", [47_361]), 0); + +// memory_copy.wast:3120 +assert_return(() => call($16, "load8_u", [47_560]), 0); + +// memory_copy.wast:3121 +assert_return(() => call($16, "load8_u", [47_759]), 0); + +// memory_copy.wast:3122 +assert_return(() => call($16, "load8_u", [47_958]), 0); + +// memory_copy.wast:3123 +assert_return(() => call($16, "load8_u", [48_157]), 0); + +// memory_copy.wast:3124 +assert_return(() => call($16, "load8_u", [48_356]), 0); + +// memory_copy.wast:3125 +assert_return(() => call($16, "load8_u", [48_555]), 0); + +// memory_copy.wast:3126 +assert_return(() => call($16, "load8_u", [48_754]), 0); + +// memory_copy.wast:3127 +assert_return(() => call($16, "load8_u", [48_953]), 0); + +// memory_copy.wast:3128 +assert_return(() => call($16, "load8_u", [49_152]), 0); + +// memory_copy.wast:3129 +assert_return(() => call($16, "load8_u", [49_351]), 0); + +// memory_copy.wast:3130 +assert_return(() => call($16, "load8_u", [49_550]), 0); + +// memory_copy.wast:3131 +assert_return(() => call($16, "load8_u", [49_749]), 0); + +// memory_copy.wast:3132 +assert_return(() => call($16, "load8_u", [49_948]), 0); + +// memory_copy.wast:3133 +assert_return(() => call($16, "load8_u", [50_147]), 0); + +// memory_copy.wast:3134 +assert_return(() => call($16, "load8_u", [50_346]), 0); + +// memory_copy.wast:3135 +assert_return(() => call($16, "load8_u", [50_545]), 0); + +// memory_copy.wast:3136 +assert_return(() => call($16, "load8_u", [50_744]), 0); + +// memory_copy.wast:3137 +assert_return(() => call($16, "load8_u", [50_943]), 0); + +// memory_copy.wast:3138 +assert_return(() => call($16, "load8_u", [51_142]), 0); + +// memory_copy.wast:3139 +assert_return(() => call($16, "load8_u", [51_341]), 0); + +// memory_copy.wast:3140 +assert_return(() => call($16, "load8_u", [51_540]), 0); + +// memory_copy.wast:3141 +assert_return(() => call($16, "load8_u", [51_739]), 0); + +// memory_copy.wast:3142 +assert_return(() => call($16, "load8_u", [51_938]), 0); + +// memory_copy.wast:3143 +assert_return(() => call($16, "load8_u", [52_137]), 0); + +// memory_copy.wast:3144 +assert_return(() => call($16, "load8_u", [52_336]), 0); + +// memory_copy.wast:3145 +assert_return(() => call($16, "load8_u", [52_535]), 0); + +// memory_copy.wast:3146 +assert_return(() => call($16, "load8_u", [52_734]), 0); + +// memory_copy.wast:3147 +assert_return(() => call($16, "load8_u", [52_933]), 0); + +// memory_copy.wast:3148 +assert_return(() => call($16, "load8_u", [53_132]), 0); + +// memory_copy.wast:3149 +assert_return(() => call($16, "load8_u", [53_331]), 0); + +// memory_copy.wast:3150 +assert_return(() => call($16, "load8_u", [53_530]), 0); + +// memory_copy.wast:3151 +assert_return(() => call($16, "load8_u", [53_729]), 0); + +// memory_copy.wast:3152 +assert_return(() => call($16, "load8_u", [53_928]), 0); + +// memory_copy.wast:3153 +assert_return(() => call($16, "load8_u", [54_127]), 0); + +// memory_copy.wast:3154 +assert_return(() => call($16, "load8_u", [54_326]), 0); + +// memory_copy.wast:3155 +assert_return(() => call($16, "load8_u", [54_525]), 0); + +// memory_copy.wast:3156 +assert_return(() => call($16, "load8_u", [54_724]), 0); + +// memory_copy.wast:3157 +assert_return(() => call($16, "load8_u", [54_923]), 0); + +// memory_copy.wast:3158 +assert_return(() => call($16, "load8_u", [55_122]), 0); + +// memory_copy.wast:3159 +assert_return(() => call($16, "load8_u", [55_321]), 0); + +// memory_copy.wast:3160 +assert_return(() => call($16, "load8_u", [55_520]), 0); + +// memory_copy.wast:3161 +assert_return(() => call($16, "load8_u", [55_719]), 0); + +// memory_copy.wast:3162 +assert_return(() => call($16, "load8_u", [55_918]), 0); + +// memory_copy.wast:3163 +assert_return(() => call($16, "load8_u", [56_117]), 0); + +// memory_copy.wast:3164 +assert_return(() => call($16, "load8_u", [56_316]), 0); + +// memory_copy.wast:3165 +assert_return(() => call($16, "load8_u", [56_515]), 0); + +// memory_copy.wast:3166 +assert_return(() => call($16, "load8_u", [56_714]), 0); + +// memory_copy.wast:3167 +assert_return(() => call($16, "load8_u", [56_913]), 0); + +// memory_copy.wast:3168 +assert_return(() => call($16, "load8_u", [57_112]), 0); + +// memory_copy.wast:3169 +assert_return(() => call($16, "load8_u", [57_311]), 0); + +// memory_copy.wast:3170 +assert_return(() => call($16, "load8_u", [57_510]), 0); + +// memory_copy.wast:3171 +assert_return(() => call($16, "load8_u", [57_709]), 0); + +// memory_copy.wast:3172 +assert_return(() => call($16, "load8_u", [57_908]), 0); + +// memory_copy.wast:3173 +assert_return(() => call($16, "load8_u", [58_107]), 0); + +// memory_copy.wast:3174 +assert_return(() => call($16, "load8_u", [58_306]), 0); + +// memory_copy.wast:3175 +assert_return(() => call($16, "load8_u", [58_505]), 0); + +// memory_copy.wast:3176 +assert_return(() => call($16, "load8_u", [58_704]), 0); + +// memory_copy.wast:3177 +assert_return(() => call($16, "load8_u", [58_903]), 0); + +// memory_copy.wast:3178 +assert_return(() => call($16, "load8_u", [59_102]), 0); + +// memory_copy.wast:3179 +assert_return(() => call($16, "load8_u", [59_301]), 0); + +// memory_copy.wast:3180 +assert_return(() => call($16, "load8_u", [59_500]), 0); + +// memory_copy.wast:3181 +assert_return(() => call($16, "load8_u", [59_699]), 0); + +// memory_copy.wast:3182 +assert_return(() => call($16, "load8_u", [59_898]), 0); + +// memory_copy.wast:3183 +assert_return(() => call($16, "load8_u", [60_097]), 0); + +// memory_copy.wast:3184 +assert_return(() => call($16, "load8_u", [60_296]), 0); + +// memory_copy.wast:3185 +assert_return(() => call($16, "load8_u", [60_495]), 0); + +// memory_copy.wast:3186 +assert_return(() => call($16, "load8_u", [60_694]), 0); + +// memory_copy.wast:3187 +assert_return(() => call($16, "load8_u", [60_893]), 0); + +// memory_copy.wast:3188 +assert_return(() => call($16, "load8_u", [61_092]), 0); + +// memory_copy.wast:3189 +assert_return(() => call($16, "load8_u", [61_291]), 0); + +// memory_copy.wast:3190 +assert_return(() => call($16, "load8_u", [61_490]), 0); + +// memory_copy.wast:3191 +assert_return(() => call($16, "load8_u", [61_689]), 0); + +// memory_copy.wast:3192 +assert_return(() => call($16, "load8_u", [61_888]), 0); + +// memory_copy.wast:3193 +assert_return(() => call($16, "load8_u", [62_087]), 0); + +// memory_copy.wast:3194 +assert_return(() => call($16, "load8_u", [62_286]), 0); + +// memory_copy.wast:3195 +assert_return(() => call($16, "load8_u", [62_485]), 0); + +// memory_copy.wast:3196 +assert_return(() => call($16, "load8_u", [62_684]), 0); + +// memory_copy.wast:3197 +assert_return(() => call($16, "load8_u", [62_883]), 0); + +// memory_copy.wast:3198 +assert_return(() => call($16, "load8_u", [63_082]), 0); + +// memory_copy.wast:3199 +assert_return(() => call($16, "load8_u", [63_281]), 0); + +// memory_copy.wast:3200 +assert_return(() => call($16, "load8_u", [63_480]), 0); + +// memory_copy.wast:3201 +assert_return(() => call($16, "load8_u", [63_679]), 0); + +// memory_copy.wast:3202 +assert_return(() => call($16, "load8_u", [63_878]), 0); + +// memory_copy.wast:3203 +assert_return(() => call($16, "load8_u", [64_077]), 0); + +// memory_copy.wast:3204 +assert_return(() => call($16, "load8_u", [64_276]), 0); + +// memory_copy.wast:3205 +assert_return(() => call($16, "load8_u", [64_475]), 0); + +// memory_copy.wast:3206 +assert_return(() => call($16, "load8_u", [64_674]), 0); + +// memory_copy.wast:3207 +assert_return(() => call($16, "load8_u", [64_873]), 0); + +// memory_copy.wast:3208 +assert_return(() => call($16, "load8_u", [65_072]), 0); + +// memory_copy.wast:3209 +assert_return(() => call($16, "load8_u", [65_271]), 0); + +// memory_copy.wast:3210 +assert_return(() => call($16, "load8_u", [65_470]), 0); + +// memory_copy.wast:3211 +assert_return(() => call($16, "load8_u", [65_516]), 0); + +// memory_copy.wast:3212 +assert_return(() => call($16, "load8_u", [65_517]), 1); + +// memory_copy.wast:3213 +assert_return(() => call($16, "load8_u", [65_518]), 2); + +// memory_copy.wast:3214 +assert_return(() => call($16, "load8_u", [65_519]), 3); + +// memory_copy.wast:3215 +assert_return(() => call($16, "load8_u", [65_520]), 4); + +// memory_copy.wast:3216 +assert_return(() => call($16, "load8_u", [65_521]), 5); + +// memory_copy.wast:3217 +assert_return(() => call($16, "load8_u", [65_522]), 6); + +// memory_copy.wast:3218 +assert_return(() => call($16, "load8_u", [65_523]), 7); + +// memory_copy.wast:3219 +assert_return(() => call($16, "load8_u", [65_524]), 8); + +// memory_copy.wast:3220 +assert_return(() => call($16, "load8_u", [65_525]), 9); + +// memory_copy.wast:3221 +assert_return(() => call($16, "load8_u", [65_526]), 10); + +// memory_copy.wast:3222 +assert_return(() => call($16, "load8_u", [65_527]), 11); + +// memory_copy.wast:3223 +assert_return(() => call($16, "load8_u", [65_528]), 12); + +// memory_copy.wast:3224 +assert_return(() => call($16, "load8_u", [65_529]), 13); + +// memory_copy.wast:3225 +assert_return(() => call($16, "load8_u", [65_530]), 14); + +// memory_copy.wast:3226 +assert_return(() => call($16, "load8_u", [65_531]), 15); + +// memory_copy.wast:3227 +assert_return(() => call($16, "load8_u", [65_532]), 16); + +// memory_copy.wast:3228 +assert_return(() => call($16, "load8_u", [65_533]), 17); + +// memory_copy.wast:3229 +assert_return(() => call($16, "load8_u", [65_534]), 18); + +// memory_copy.wast:3230 +assert_return(() => call($16, "load8_u", [65_535]), 19); + +// memory_copy.wast:3232 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3240 +assert_trap(() => call($17, "run", [65_516, 65_516, 40])); + +// memory_copy.wast:3243 +assert_return(() => call($17, "load8_u", [198]), 0); + +// memory_copy.wast:3244 +assert_return(() => call($17, "load8_u", [397]), 0); + +// memory_copy.wast:3245 +assert_return(() => call($17, "load8_u", [596]), 0); + +// memory_copy.wast:3246 +assert_return(() => call($17, "load8_u", [795]), 0); + +// memory_copy.wast:3247 +assert_return(() => call($17, "load8_u", [994]), 0); + +// memory_copy.wast:3248 +assert_return(() => call($17, "load8_u", [1_193]), 0); + +// memory_copy.wast:3249 +assert_return(() => call($17, "load8_u", [1_392]), 0); + +// memory_copy.wast:3250 +assert_return(() => call($17, "load8_u", [1_591]), 0); + +// memory_copy.wast:3251 +assert_return(() => call($17, "load8_u", [1_790]), 0); + +// memory_copy.wast:3252 +assert_return(() => call($17, "load8_u", [1_989]), 0); + +// memory_copy.wast:3253 +assert_return(() => call($17, "load8_u", [2_188]), 0); + +// memory_copy.wast:3254 +assert_return(() => call($17, "load8_u", [2_387]), 0); + +// memory_copy.wast:3255 +assert_return(() => call($17, "load8_u", [2_586]), 0); + +// memory_copy.wast:3256 +assert_return(() => call($17, "load8_u", [2_785]), 0); + +// memory_copy.wast:3257 +assert_return(() => call($17, "load8_u", [2_984]), 0); + +// memory_copy.wast:3258 +assert_return(() => call($17, "load8_u", [3_183]), 0); + +// memory_copy.wast:3259 +assert_return(() => call($17, "load8_u", [3_382]), 0); + +// memory_copy.wast:3260 +assert_return(() => call($17, "load8_u", [3_581]), 0); + +// memory_copy.wast:3261 +assert_return(() => call($17, "load8_u", [3_780]), 0); + +// memory_copy.wast:3262 +assert_return(() => call($17, "load8_u", [3_979]), 0); + +// memory_copy.wast:3263 +assert_return(() => call($17, "load8_u", [4_178]), 0); + +// memory_copy.wast:3264 +assert_return(() => call($17, "load8_u", [4_377]), 0); + +// memory_copy.wast:3265 +assert_return(() => call($17, "load8_u", [4_576]), 0); + +// memory_copy.wast:3266 +assert_return(() => call($17, "load8_u", [4_775]), 0); + +// memory_copy.wast:3267 +assert_return(() => call($17, "load8_u", [4_974]), 0); + +// memory_copy.wast:3268 +assert_return(() => call($17, "load8_u", [5_173]), 0); + +// memory_copy.wast:3269 +assert_return(() => call($17, "load8_u", [5_372]), 0); + +// memory_copy.wast:3270 +assert_return(() => call($17, "load8_u", [5_571]), 0); + +// memory_copy.wast:3271 +assert_return(() => call($17, "load8_u", [5_770]), 0); + +// memory_copy.wast:3272 +assert_return(() => call($17, "load8_u", [5_969]), 0); + +// memory_copy.wast:3273 +assert_return(() => call($17, "load8_u", [6_168]), 0); + +// memory_copy.wast:3274 +assert_return(() => call($17, "load8_u", [6_367]), 0); + +// memory_copy.wast:3275 +assert_return(() => call($17, "load8_u", [6_566]), 0); + +// memory_copy.wast:3276 +assert_return(() => call($17, "load8_u", [6_765]), 0); + +// memory_copy.wast:3277 +assert_return(() => call($17, "load8_u", [6_964]), 0); + +// memory_copy.wast:3278 +assert_return(() => call($17, "load8_u", [7_163]), 0); + +// memory_copy.wast:3279 +assert_return(() => call($17, "load8_u", [7_362]), 0); + +// memory_copy.wast:3280 +assert_return(() => call($17, "load8_u", [7_561]), 0); + +// memory_copy.wast:3281 +assert_return(() => call($17, "load8_u", [7_760]), 0); + +// memory_copy.wast:3282 +assert_return(() => call($17, "load8_u", [7_959]), 0); + +// memory_copy.wast:3283 +assert_return(() => call($17, "load8_u", [8_158]), 0); + +// memory_copy.wast:3284 +assert_return(() => call($17, "load8_u", [8_357]), 0); + +// memory_copy.wast:3285 +assert_return(() => call($17, "load8_u", [8_556]), 0); + +// memory_copy.wast:3286 +assert_return(() => call($17, "load8_u", [8_755]), 0); + +// memory_copy.wast:3287 +assert_return(() => call($17, "load8_u", [8_954]), 0); + +// memory_copy.wast:3288 +assert_return(() => call($17, "load8_u", [9_153]), 0); + +// memory_copy.wast:3289 +assert_return(() => call($17, "load8_u", [9_352]), 0); + +// memory_copy.wast:3290 +assert_return(() => call($17, "load8_u", [9_551]), 0); + +// memory_copy.wast:3291 +assert_return(() => call($17, "load8_u", [9_750]), 0); + +// memory_copy.wast:3292 +assert_return(() => call($17, "load8_u", [9_949]), 0); + +// memory_copy.wast:3293 +assert_return(() => call($17, "load8_u", [10_148]), 0); + +// memory_copy.wast:3294 +assert_return(() => call($17, "load8_u", [10_347]), 0); + +// memory_copy.wast:3295 +assert_return(() => call($17, "load8_u", [10_546]), 0); + +// memory_copy.wast:3296 +assert_return(() => call($17, "load8_u", [10_745]), 0); + +// memory_copy.wast:3297 +assert_return(() => call($17, "load8_u", [10_944]), 0); + +// memory_copy.wast:3298 +assert_return(() => call($17, "load8_u", [11_143]), 0); + +// memory_copy.wast:3299 +assert_return(() => call($17, "load8_u", [11_342]), 0); + +// memory_copy.wast:3300 +assert_return(() => call($17, "load8_u", [11_541]), 0); + +// memory_copy.wast:3301 +assert_return(() => call($17, "load8_u", [11_740]), 0); + +// memory_copy.wast:3302 +assert_return(() => call($17, "load8_u", [11_939]), 0); + +// memory_copy.wast:3303 +assert_return(() => call($17, "load8_u", [12_138]), 0); + +// memory_copy.wast:3304 +assert_return(() => call($17, "load8_u", [12_337]), 0); + +// memory_copy.wast:3305 +assert_return(() => call($17, "load8_u", [12_536]), 0); + +// memory_copy.wast:3306 +assert_return(() => call($17, "load8_u", [12_735]), 0); + +// memory_copy.wast:3307 +assert_return(() => call($17, "load8_u", [12_934]), 0); + +// memory_copy.wast:3308 +assert_return(() => call($17, "load8_u", [13_133]), 0); + +// memory_copy.wast:3309 +assert_return(() => call($17, "load8_u", [13_332]), 0); + +// memory_copy.wast:3310 +assert_return(() => call($17, "load8_u", [13_531]), 0); + +// memory_copy.wast:3311 +assert_return(() => call($17, "load8_u", [13_730]), 0); + +// memory_copy.wast:3312 +assert_return(() => call($17, "load8_u", [13_929]), 0); + +// memory_copy.wast:3313 +assert_return(() => call($17, "load8_u", [14_128]), 0); + +// memory_copy.wast:3314 +assert_return(() => call($17, "load8_u", [14_327]), 0); + +// memory_copy.wast:3315 +assert_return(() => call($17, "load8_u", [14_526]), 0); + +// memory_copy.wast:3316 +assert_return(() => call($17, "load8_u", [14_725]), 0); + +// memory_copy.wast:3317 +assert_return(() => call($17, "load8_u", [14_924]), 0); + +// memory_copy.wast:3318 +assert_return(() => call($17, "load8_u", [15_123]), 0); + +// memory_copy.wast:3319 +assert_return(() => call($17, "load8_u", [15_322]), 0); + +// memory_copy.wast:3320 +assert_return(() => call($17, "load8_u", [15_521]), 0); + +// memory_copy.wast:3321 +assert_return(() => call($17, "load8_u", [15_720]), 0); + +// memory_copy.wast:3322 +assert_return(() => call($17, "load8_u", [15_919]), 0); + +// memory_copy.wast:3323 +assert_return(() => call($17, "load8_u", [16_118]), 0); + +// memory_copy.wast:3324 +assert_return(() => call($17, "load8_u", [16_317]), 0); + +// memory_copy.wast:3325 +assert_return(() => call($17, "load8_u", [16_516]), 0); + +// memory_copy.wast:3326 +assert_return(() => call($17, "load8_u", [16_715]), 0); + +// memory_copy.wast:3327 +assert_return(() => call($17, "load8_u", [16_914]), 0); + +// memory_copy.wast:3328 +assert_return(() => call($17, "load8_u", [17_113]), 0); + +// memory_copy.wast:3329 +assert_return(() => call($17, "load8_u", [17_312]), 0); + +// memory_copy.wast:3330 +assert_return(() => call($17, "load8_u", [17_511]), 0); + +// memory_copy.wast:3331 +assert_return(() => call($17, "load8_u", [17_710]), 0); + +// memory_copy.wast:3332 +assert_return(() => call($17, "load8_u", [17_909]), 0); + +// memory_copy.wast:3333 +assert_return(() => call($17, "load8_u", [18_108]), 0); + +// memory_copy.wast:3334 +assert_return(() => call($17, "load8_u", [18_307]), 0); + +// memory_copy.wast:3335 +assert_return(() => call($17, "load8_u", [18_506]), 0); + +// memory_copy.wast:3336 +assert_return(() => call($17, "load8_u", [18_705]), 0); + +// memory_copy.wast:3337 +assert_return(() => call($17, "load8_u", [18_904]), 0); + +// memory_copy.wast:3338 +assert_return(() => call($17, "load8_u", [19_103]), 0); + +// memory_copy.wast:3339 +assert_return(() => call($17, "load8_u", [19_302]), 0); + +// memory_copy.wast:3340 +assert_return(() => call($17, "load8_u", [19_501]), 0); + +// memory_copy.wast:3341 +assert_return(() => call($17, "load8_u", [19_700]), 0); + +// memory_copy.wast:3342 +assert_return(() => call($17, "load8_u", [19_899]), 0); + +// memory_copy.wast:3343 +assert_return(() => call($17, "load8_u", [20_098]), 0); + +// memory_copy.wast:3344 +assert_return(() => call($17, "load8_u", [20_297]), 0); + +// memory_copy.wast:3345 +assert_return(() => call($17, "load8_u", [20_496]), 0); + +// memory_copy.wast:3346 +assert_return(() => call($17, "load8_u", [20_695]), 0); + +// memory_copy.wast:3347 +assert_return(() => call($17, "load8_u", [20_894]), 0); + +// memory_copy.wast:3348 +assert_return(() => call($17, "load8_u", [21_093]), 0); + +// memory_copy.wast:3349 +assert_return(() => call($17, "load8_u", [21_292]), 0); + +// memory_copy.wast:3350 +assert_return(() => call($17, "load8_u", [21_491]), 0); + +// memory_copy.wast:3351 +assert_return(() => call($17, "load8_u", [21_690]), 0); + +// memory_copy.wast:3352 +assert_return(() => call($17, "load8_u", [21_889]), 0); + +// memory_copy.wast:3353 +assert_return(() => call($17, "load8_u", [22_088]), 0); + +// memory_copy.wast:3354 +assert_return(() => call($17, "load8_u", [22_287]), 0); + +// memory_copy.wast:3355 +assert_return(() => call($17, "load8_u", [22_486]), 0); + +// memory_copy.wast:3356 +assert_return(() => call($17, "load8_u", [22_685]), 0); + +// memory_copy.wast:3357 +assert_return(() => call($17, "load8_u", [22_884]), 0); + +// memory_copy.wast:3358 +assert_return(() => call($17, "load8_u", [23_083]), 0); + +// memory_copy.wast:3359 +assert_return(() => call($17, "load8_u", [23_282]), 0); + +// memory_copy.wast:3360 +assert_return(() => call($17, "load8_u", [23_481]), 0); + +// memory_copy.wast:3361 +assert_return(() => call($17, "load8_u", [23_680]), 0); + +// memory_copy.wast:3362 +assert_return(() => call($17, "load8_u", [23_879]), 0); + +// memory_copy.wast:3363 +assert_return(() => call($17, "load8_u", [24_078]), 0); + +// memory_copy.wast:3364 +assert_return(() => call($17, "load8_u", [24_277]), 0); + +// memory_copy.wast:3365 +assert_return(() => call($17, "load8_u", [24_476]), 0); + +// memory_copy.wast:3366 +assert_return(() => call($17, "load8_u", [24_675]), 0); + +// memory_copy.wast:3367 +assert_return(() => call($17, "load8_u", [24_874]), 0); + +// memory_copy.wast:3368 +assert_return(() => call($17, "load8_u", [25_073]), 0); + +// memory_copy.wast:3369 +assert_return(() => call($17, "load8_u", [25_272]), 0); + +// memory_copy.wast:3370 +assert_return(() => call($17, "load8_u", [25_471]), 0); + +// memory_copy.wast:3371 +assert_return(() => call($17, "load8_u", [25_670]), 0); + +// memory_copy.wast:3372 +assert_return(() => call($17, "load8_u", [25_869]), 0); + +// memory_copy.wast:3373 +assert_return(() => call($17, "load8_u", [26_068]), 0); + +// memory_copy.wast:3374 +assert_return(() => call($17, "load8_u", [26_267]), 0); + +// memory_copy.wast:3375 +assert_return(() => call($17, "load8_u", [26_466]), 0); + +// memory_copy.wast:3376 +assert_return(() => call($17, "load8_u", [26_665]), 0); + +// memory_copy.wast:3377 +assert_return(() => call($17, "load8_u", [26_864]), 0); + +// memory_copy.wast:3378 +assert_return(() => call($17, "load8_u", [27_063]), 0); + +// memory_copy.wast:3379 +assert_return(() => call($17, "load8_u", [27_262]), 0); + +// memory_copy.wast:3380 +assert_return(() => call($17, "load8_u", [27_461]), 0); + +// memory_copy.wast:3381 +assert_return(() => call($17, "load8_u", [27_660]), 0); + +// memory_copy.wast:3382 +assert_return(() => call($17, "load8_u", [27_859]), 0); + +// memory_copy.wast:3383 +assert_return(() => call($17, "load8_u", [28_058]), 0); + +// memory_copy.wast:3384 +assert_return(() => call($17, "load8_u", [28_257]), 0); + +// memory_copy.wast:3385 +assert_return(() => call($17, "load8_u", [28_456]), 0); + +// memory_copy.wast:3386 +assert_return(() => call($17, "load8_u", [28_655]), 0); + +// memory_copy.wast:3387 +assert_return(() => call($17, "load8_u", [28_854]), 0); + +// memory_copy.wast:3388 +assert_return(() => call($17, "load8_u", [29_053]), 0); + +// memory_copy.wast:3389 +assert_return(() => call($17, "load8_u", [29_252]), 0); + +// memory_copy.wast:3390 +assert_return(() => call($17, "load8_u", [29_451]), 0); + +// memory_copy.wast:3391 +assert_return(() => call($17, "load8_u", [29_650]), 0); + +// memory_copy.wast:3392 +assert_return(() => call($17, "load8_u", [29_849]), 0); + +// memory_copy.wast:3393 +assert_return(() => call($17, "load8_u", [30_048]), 0); + +// memory_copy.wast:3394 +assert_return(() => call($17, "load8_u", [30_247]), 0); + +// memory_copy.wast:3395 +assert_return(() => call($17, "load8_u", [30_446]), 0); + +// memory_copy.wast:3396 +assert_return(() => call($17, "load8_u", [30_645]), 0); + +// memory_copy.wast:3397 +assert_return(() => call($17, "load8_u", [30_844]), 0); + +// memory_copy.wast:3398 +assert_return(() => call($17, "load8_u", [31_043]), 0); + +// memory_copy.wast:3399 +assert_return(() => call($17, "load8_u", [31_242]), 0); + +// memory_copy.wast:3400 +assert_return(() => call($17, "load8_u", [31_441]), 0); + +// memory_copy.wast:3401 +assert_return(() => call($17, "load8_u", [31_640]), 0); + +// memory_copy.wast:3402 +assert_return(() => call($17, "load8_u", [31_839]), 0); + +// memory_copy.wast:3403 +assert_return(() => call($17, "load8_u", [32_038]), 0); + +// memory_copy.wast:3404 +assert_return(() => call($17, "load8_u", [32_237]), 0); + +// memory_copy.wast:3405 +assert_return(() => call($17, "load8_u", [32_436]), 0); + +// memory_copy.wast:3406 +assert_return(() => call($17, "load8_u", [32_635]), 0); + +// memory_copy.wast:3407 +assert_return(() => call($17, "load8_u", [32_834]), 0); + +// memory_copy.wast:3408 +assert_return(() => call($17, "load8_u", [33_033]), 0); + +// memory_copy.wast:3409 +assert_return(() => call($17, "load8_u", [33_232]), 0); + +// memory_copy.wast:3410 +assert_return(() => call($17, "load8_u", [33_431]), 0); + +// memory_copy.wast:3411 +assert_return(() => call($17, "load8_u", [33_630]), 0); + +// memory_copy.wast:3412 +assert_return(() => call($17, "load8_u", [33_829]), 0); + +// memory_copy.wast:3413 +assert_return(() => call($17, "load8_u", [34_028]), 0); + +// memory_copy.wast:3414 +assert_return(() => call($17, "load8_u", [34_227]), 0); + +// memory_copy.wast:3415 +assert_return(() => call($17, "load8_u", [34_426]), 0); + +// memory_copy.wast:3416 +assert_return(() => call($17, "load8_u", [34_625]), 0); + +// memory_copy.wast:3417 +assert_return(() => call($17, "load8_u", [34_824]), 0); + +// memory_copy.wast:3418 +assert_return(() => call($17, "load8_u", [35_023]), 0); + +// memory_copy.wast:3419 +assert_return(() => call($17, "load8_u", [35_222]), 0); + +// memory_copy.wast:3420 +assert_return(() => call($17, "load8_u", [35_421]), 0); + +// memory_copy.wast:3421 +assert_return(() => call($17, "load8_u", [35_620]), 0); + +// memory_copy.wast:3422 +assert_return(() => call($17, "load8_u", [35_819]), 0); + +// memory_copy.wast:3423 +assert_return(() => call($17, "load8_u", [36_018]), 0); + +// memory_copy.wast:3424 +assert_return(() => call($17, "load8_u", [36_217]), 0); + +// memory_copy.wast:3425 +assert_return(() => call($17, "load8_u", [36_416]), 0); + +// memory_copy.wast:3426 +assert_return(() => call($17, "load8_u", [36_615]), 0); + +// memory_copy.wast:3427 +assert_return(() => call($17, "load8_u", [36_814]), 0); + +// memory_copy.wast:3428 +assert_return(() => call($17, "load8_u", [37_013]), 0); + +// memory_copy.wast:3429 +assert_return(() => call($17, "load8_u", [37_212]), 0); + +// memory_copy.wast:3430 +assert_return(() => call($17, "load8_u", [37_411]), 0); + +// memory_copy.wast:3431 +assert_return(() => call($17, "load8_u", [37_610]), 0); + +// memory_copy.wast:3432 +assert_return(() => call($17, "load8_u", [37_809]), 0); + +// memory_copy.wast:3433 +assert_return(() => call($17, "load8_u", [38_008]), 0); + +// memory_copy.wast:3434 +assert_return(() => call($17, "load8_u", [38_207]), 0); + +// memory_copy.wast:3435 +assert_return(() => call($17, "load8_u", [38_406]), 0); + +// memory_copy.wast:3436 +assert_return(() => call($17, "load8_u", [38_605]), 0); + +// memory_copy.wast:3437 +assert_return(() => call($17, "load8_u", [38_804]), 0); + +// memory_copy.wast:3438 +assert_return(() => call($17, "load8_u", [39_003]), 0); + +// memory_copy.wast:3439 +assert_return(() => call($17, "load8_u", [39_202]), 0); + +// memory_copy.wast:3440 +assert_return(() => call($17, "load8_u", [39_401]), 0); + +// memory_copy.wast:3441 +assert_return(() => call($17, "load8_u", [39_600]), 0); + +// memory_copy.wast:3442 +assert_return(() => call($17, "load8_u", [39_799]), 0); + +// memory_copy.wast:3443 +assert_return(() => call($17, "load8_u", [39_998]), 0); + +// memory_copy.wast:3444 +assert_return(() => call($17, "load8_u", [40_197]), 0); + +// memory_copy.wast:3445 +assert_return(() => call($17, "load8_u", [40_396]), 0); + +// memory_copy.wast:3446 +assert_return(() => call($17, "load8_u", [40_595]), 0); + +// memory_copy.wast:3447 +assert_return(() => call($17, "load8_u", [40_794]), 0); + +// memory_copy.wast:3448 +assert_return(() => call($17, "load8_u", [40_993]), 0); + +// memory_copy.wast:3449 +assert_return(() => call($17, "load8_u", [41_192]), 0); + +// memory_copy.wast:3450 +assert_return(() => call($17, "load8_u", [41_391]), 0); + +// memory_copy.wast:3451 +assert_return(() => call($17, "load8_u", [41_590]), 0); + +// memory_copy.wast:3452 +assert_return(() => call($17, "load8_u", [41_789]), 0); + +// memory_copy.wast:3453 +assert_return(() => call($17, "load8_u", [41_988]), 0); + +// memory_copy.wast:3454 +assert_return(() => call($17, "load8_u", [42_187]), 0); + +// memory_copy.wast:3455 +assert_return(() => call($17, "load8_u", [42_386]), 0); + +// memory_copy.wast:3456 +assert_return(() => call($17, "load8_u", [42_585]), 0); + +// memory_copy.wast:3457 +assert_return(() => call($17, "load8_u", [42_784]), 0); + +// memory_copy.wast:3458 +assert_return(() => call($17, "load8_u", [42_983]), 0); + +// memory_copy.wast:3459 +assert_return(() => call($17, "load8_u", [43_182]), 0); + +// memory_copy.wast:3460 +assert_return(() => call($17, "load8_u", [43_381]), 0); + +// memory_copy.wast:3461 +assert_return(() => call($17, "load8_u", [43_580]), 0); + +// memory_copy.wast:3462 +assert_return(() => call($17, "load8_u", [43_779]), 0); + +// memory_copy.wast:3463 +assert_return(() => call($17, "load8_u", [43_978]), 0); + +// memory_copy.wast:3464 +assert_return(() => call($17, "load8_u", [44_177]), 0); + +// memory_copy.wast:3465 +assert_return(() => call($17, "load8_u", [44_376]), 0); + +// memory_copy.wast:3466 +assert_return(() => call($17, "load8_u", [44_575]), 0); + +// memory_copy.wast:3467 +assert_return(() => call($17, "load8_u", [44_774]), 0); + +// memory_copy.wast:3468 +assert_return(() => call($17, "load8_u", [44_973]), 0); + +// memory_copy.wast:3469 +assert_return(() => call($17, "load8_u", [45_172]), 0); + +// memory_copy.wast:3470 +assert_return(() => call($17, "load8_u", [45_371]), 0); + +// memory_copy.wast:3471 +assert_return(() => call($17, "load8_u", [45_570]), 0); + +// memory_copy.wast:3472 +assert_return(() => call($17, "load8_u", [45_769]), 0); + +// memory_copy.wast:3473 +assert_return(() => call($17, "load8_u", [45_968]), 0); + +// memory_copy.wast:3474 +assert_return(() => call($17, "load8_u", [46_167]), 0); + +// memory_copy.wast:3475 +assert_return(() => call($17, "load8_u", [46_366]), 0); + +// memory_copy.wast:3476 +assert_return(() => call($17, "load8_u", [46_565]), 0); + +// memory_copy.wast:3477 +assert_return(() => call($17, "load8_u", [46_764]), 0); + +// memory_copy.wast:3478 +assert_return(() => call($17, "load8_u", [46_963]), 0); + +// memory_copy.wast:3479 +assert_return(() => call($17, "load8_u", [47_162]), 0); + +// memory_copy.wast:3480 +assert_return(() => call($17, "load8_u", [47_361]), 0); + +// memory_copy.wast:3481 +assert_return(() => call($17, "load8_u", [47_560]), 0); + +// memory_copy.wast:3482 +assert_return(() => call($17, "load8_u", [47_759]), 0); + +// memory_copy.wast:3483 +assert_return(() => call($17, "load8_u", [47_958]), 0); + +// memory_copy.wast:3484 +assert_return(() => call($17, "load8_u", [48_157]), 0); + +// memory_copy.wast:3485 +assert_return(() => call($17, "load8_u", [48_356]), 0); + +// memory_copy.wast:3486 +assert_return(() => call($17, "load8_u", [48_555]), 0); + +// memory_copy.wast:3487 +assert_return(() => call($17, "load8_u", [48_754]), 0); + +// memory_copy.wast:3488 +assert_return(() => call($17, "load8_u", [48_953]), 0); + +// memory_copy.wast:3489 +assert_return(() => call($17, "load8_u", [49_152]), 0); + +// memory_copy.wast:3490 +assert_return(() => call($17, "load8_u", [49_351]), 0); + +// memory_copy.wast:3491 +assert_return(() => call($17, "load8_u", [49_550]), 0); + +// memory_copy.wast:3492 +assert_return(() => call($17, "load8_u", [49_749]), 0); + +// memory_copy.wast:3493 +assert_return(() => call($17, "load8_u", [49_948]), 0); + +// memory_copy.wast:3494 +assert_return(() => call($17, "load8_u", [50_147]), 0); + +// memory_copy.wast:3495 +assert_return(() => call($17, "load8_u", [50_346]), 0); + +// memory_copy.wast:3496 +assert_return(() => call($17, "load8_u", [50_545]), 0); + +// memory_copy.wast:3497 +assert_return(() => call($17, "load8_u", [50_744]), 0); + +// memory_copy.wast:3498 +assert_return(() => call($17, "load8_u", [50_943]), 0); + +// memory_copy.wast:3499 +assert_return(() => call($17, "load8_u", [51_142]), 0); + +// memory_copy.wast:3500 +assert_return(() => call($17, "load8_u", [51_341]), 0); + +// memory_copy.wast:3501 +assert_return(() => call($17, "load8_u", [51_540]), 0); + +// memory_copy.wast:3502 +assert_return(() => call($17, "load8_u", [51_739]), 0); + +// memory_copy.wast:3503 +assert_return(() => call($17, "load8_u", [51_938]), 0); + +// memory_copy.wast:3504 +assert_return(() => call($17, "load8_u", [52_137]), 0); + +// memory_copy.wast:3505 +assert_return(() => call($17, "load8_u", [52_336]), 0); + +// memory_copy.wast:3506 +assert_return(() => call($17, "load8_u", [52_535]), 0); + +// memory_copy.wast:3507 +assert_return(() => call($17, "load8_u", [52_734]), 0); + +// memory_copy.wast:3508 +assert_return(() => call($17, "load8_u", [52_933]), 0); + +// memory_copy.wast:3509 +assert_return(() => call($17, "load8_u", [53_132]), 0); + +// memory_copy.wast:3510 +assert_return(() => call($17, "load8_u", [53_331]), 0); + +// memory_copy.wast:3511 +assert_return(() => call($17, "load8_u", [53_530]), 0); + +// memory_copy.wast:3512 +assert_return(() => call($17, "load8_u", [53_729]), 0); + +// memory_copy.wast:3513 +assert_return(() => call($17, "load8_u", [53_928]), 0); + +// memory_copy.wast:3514 +assert_return(() => call($17, "load8_u", [54_127]), 0); + +// memory_copy.wast:3515 +assert_return(() => call($17, "load8_u", [54_326]), 0); + +// memory_copy.wast:3516 +assert_return(() => call($17, "load8_u", [54_525]), 0); + +// memory_copy.wast:3517 +assert_return(() => call($17, "load8_u", [54_724]), 0); + +// memory_copy.wast:3518 +assert_return(() => call($17, "load8_u", [54_923]), 0); + +// memory_copy.wast:3519 +assert_return(() => call($17, "load8_u", [55_122]), 0); + +// memory_copy.wast:3520 +assert_return(() => call($17, "load8_u", [55_321]), 0); + +// memory_copy.wast:3521 +assert_return(() => call($17, "load8_u", [55_520]), 0); + +// memory_copy.wast:3522 +assert_return(() => call($17, "load8_u", [55_719]), 0); + +// memory_copy.wast:3523 +assert_return(() => call($17, "load8_u", [55_918]), 0); + +// memory_copy.wast:3524 +assert_return(() => call($17, "load8_u", [56_117]), 0); + +// memory_copy.wast:3525 +assert_return(() => call($17, "load8_u", [56_316]), 0); + +// memory_copy.wast:3526 +assert_return(() => call($17, "load8_u", [56_515]), 0); + +// memory_copy.wast:3527 +assert_return(() => call($17, "load8_u", [56_714]), 0); + +// memory_copy.wast:3528 +assert_return(() => call($17, "load8_u", [56_913]), 0); + +// memory_copy.wast:3529 +assert_return(() => call($17, "load8_u", [57_112]), 0); + +// memory_copy.wast:3530 +assert_return(() => call($17, "load8_u", [57_311]), 0); + +// memory_copy.wast:3531 +assert_return(() => call($17, "load8_u", [57_510]), 0); + +// memory_copy.wast:3532 +assert_return(() => call($17, "load8_u", [57_709]), 0); + +// memory_copy.wast:3533 +assert_return(() => call($17, "load8_u", [57_908]), 0); + +// memory_copy.wast:3534 +assert_return(() => call($17, "load8_u", [58_107]), 0); + +// memory_copy.wast:3535 +assert_return(() => call($17, "load8_u", [58_306]), 0); + +// memory_copy.wast:3536 +assert_return(() => call($17, "load8_u", [58_505]), 0); + +// memory_copy.wast:3537 +assert_return(() => call($17, "load8_u", [58_704]), 0); + +// memory_copy.wast:3538 +assert_return(() => call($17, "load8_u", [58_903]), 0); + +// memory_copy.wast:3539 +assert_return(() => call($17, "load8_u", [59_102]), 0); + +// memory_copy.wast:3540 +assert_return(() => call($17, "load8_u", [59_301]), 0); + +// memory_copy.wast:3541 +assert_return(() => call($17, "load8_u", [59_500]), 0); + +// memory_copy.wast:3542 +assert_return(() => call($17, "load8_u", [59_699]), 0); + +// memory_copy.wast:3543 +assert_return(() => call($17, "load8_u", [59_898]), 0); + +// memory_copy.wast:3544 +assert_return(() => call($17, "load8_u", [60_097]), 0); + +// memory_copy.wast:3545 +assert_return(() => call($17, "load8_u", [60_296]), 0); + +// memory_copy.wast:3546 +assert_return(() => call($17, "load8_u", [60_495]), 0); + +// memory_copy.wast:3547 +assert_return(() => call($17, "load8_u", [60_694]), 0); + +// memory_copy.wast:3548 +assert_return(() => call($17, "load8_u", [60_893]), 0); + +// memory_copy.wast:3549 +assert_return(() => call($17, "load8_u", [61_092]), 0); + +// memory_copy.wast:3550 +assert_return(() => call($17, "load8_u", [61_291]), 0); + +// memory_copy.wast:3551 +assert_return(() => call($17, "load8_u", [61_490]), 0); + +// memory_copy.wast:3552 +assert_return(() => call($17, "load8_u", [61_689]), 0); + +// memory_copy.wast:3553 +assert_return(() => call($17, "load8_u", [61_888]), 0); + +// memory_copy.wast:3554 +assert_return(() => call($17, "load8_u", [62_087]), 0); + +// memory_copy.wast:3555 +assert_return(() => call($17, "load8_u", [62_286]), 0); + +// memory_copy.wast:3556 +assert_return(() => call($17, "load8_u", [62_485]), 0); + +// memory_copy.wast:3557 +assert_return(() => call($17, "load8_u", [62_684]), 0); + +// memory_copy.wast:3558 +assert_return(() => call($17, "load8_u", [62_883]), 0); + +// memory_copy.wast:3559 +assert_return(() => call($17, "load8_u", [63_082]), 0); + +// memory_copy.wast:3560 +assert_return(() => call($17, "load8_u", [63_281]), 0); + +// memory_copy.wast:3561 +assert_return(() => call($17, "load8_u", [63_480]), 0); + +// memory_copy.wast:3562 +assert_return(() => call($17, "load8_u", [63_679]), 0); + +// memory_copy.wast:3563 +assert_return(() => call($17, "load8_u", [63_878]), 0); + +// memory_copy.wast:3564 +assert_return(() => call($17, "load8_u", [64_077]), 0); + +// memory_copy.wast:3565 +assert_return(() => call($17, "load8_u", [64_276]), 0); + +// memory_copy.wast:3566 +assert_return(() => call($17, "load8_u", [64_475]), 0); + +// memory_copy.wast:3567 +assert_return(() => call($17, "load8_u", [64_674]), 0); + +// memory_copy.wast:3568 +assert_return(() => call($17, "load8_u", [64_873]), 0); + +// memory_copy.wast:3569 +assert_return(() => call($17, "load8_u", [65_072]), 0); + +// memory_copy.wast:3570 +assert_return(() => call($17, "load8_u", [65_271]), 0); + +// memory_copy.wast:3571 +assert_return(() => call($17, "load8_u", [65_470]), 0); + +// memory_copy.wast:3572 +assert_return(() => call($17, "load8_u", [65_516]), 0); + +// memory_copy.wast:3573 +assert_return(() => call($17, "load8_u", [65_517]), 1); + +// memory_copy.wast:3574 +assert_return(() => call($17, "load8_u", [65_518]), 2); + +// memory_copy.wast:3575 +assert_return(() => call($17, "load8_u", [65_519]), 3); + +// memory_copy.wast:3576 +assert_return(() => call($17, "load8_u", [65_520]), 4); + +// memory_copy.wast:3577 +assert_return(() => call($17, "load8_u", [65_521]), 5); + +// memory_copy.wast:3578 +assert_return(() => call($17, "load8_u", [65_522]), 6); + +// memory_copy.wast:3579 +assert_return(() => call($17, "load8_u", [65_523]), 7); + +// memory_copy.wast:3580 +assert_return(() => call($17, "load8_u", [65_524]), 8); + +// memory_copy.wast:3581 +assert_return(() => call($17, "load8_u", [65_525]), 9); + +// memory_copy.wast:3582 +assert_return(() => call($17, "load8_u", [65_526]), 10); + +// memory_copy.wast:3583 +assert_return(() => call($17, "load8_u", [65_527]), 11); + +// memory_copy.wast:3584 +assert_return(() => call($17, "load8_u", [65_528]), 12); + +// memory_copy.wast:3585 +assert_return(() => call($17, "load8_u", [65_529]), 13); + +// memory_copy.wast:3586 +assert_return(() => call($17, "load8_u", [65_530]), 14); + +// memory_copy.wast:3587 +assert_return(() => call($17, "load8_u", [65_531]), 15); + +// memory_copy.wast:3588 +assert_return(() => call($17, "load8_u", [65_532]), 16); + +// memory_copy.wast:3589 +assert_return(() => call($17, "load8_u", [65_533]), 17); + +// memory_copy.wast:3590 +assert_return(() => call($17, "load8_u", [65_534]), 18); + +// memory_copy.wast:3591 +assert_return(() => call($17, "load8_u", [65_535]), 19); + +// memory_copy.wast:3593 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\xec\xff\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3601 +assert_trap(() => call($18, "run", [0, 65_516, -4_096])); + +// memory_copy.wast:3604 +assert_return(() => call($18, "load8_u", [198]), 0); + +// memory_copy.wast:3605 +assert_return(() => call($18, "load8_u", [397]), 0); + +// memory_copy.wast:3606 +assert_return(() => call($18, "load8_u", [596]), 0); + +// memory_copy.wast:3607 +assert_return(() => call($18, "load8_u", [795]), 0); + +// memory_copy.wast:3608 +assert_return(() => call($18, "load8_u", [994]), 0); + +// memory_copy.wast:3609 +assert_return(() => call($18, "load8_u", [1_193]), 0); + +// memory_copy.wast:3610 +assert_return(() => call($18, "load8_u", [1_392]), 0); + +// memory_copy.wast:3611 +assert_return(() => call($18, "load8_u", [1_591]), 0); + +// memory_copy.wast:3612 +assert_return(() => call($18, "load8_u", [1_790]), 0); + +// memory_copy.wast:3613 +assert_return(() => call($18, "load8_u", [1_989]), 0); + +// memory_copy.wast:3614 +assert_return(() => call($18, "load8_u", [2_188]), 0); + +// memory_copy.wast:3615 +assert_return(() => call($18, "load8_u", [2_387]), 0); + +// memory_copy.wast:3616 +assert_return(() => call($18, "load8_u", [2_586]), 0); + +// memory_copy.wast:3617 +assert_return(() => call($18, "load8_u", [2_785]), 0); + +// memory_copy.wast:3618 +assert_return(() => call($18, "load8_u", [2_984]), 0); + +// memory_copy.wast:3619 +assert_return(() => call($18, "load8_u", [3_183]), 0); + +// memory_copy.wast:3620 +assert_return(() => call($18, "load8_u", [3_382]), 0); + +// memory_copy.wast:3621 +assert_return(() => call($18, "load8_u", [3_581]), 0); + +// memory_copy.wast:3622 +assert_return(() => call($18, "load8_u", [3_780]), 0); + +// memory_copy.wast:3623 +assert_return(() => call($18, "load8_u", [3_979]), 0); + +// memory_copy.wast:3624 +assert_return(() => call($18, "load8_u", [4_178]), 0); + +// memory_copy.wast:3625 +assert_return(() => call($18, "load8_u", [4_377]), 0); + +// memory_copy.wast:3626 +assert_return(() => call($18, "load8_u", [4_576]), 0); + +// memory_copy.wast:3627 +assert_return(() => call($18, "load8_u", [4_775]), 0); + +// memory_copy.wast:3628 +assert_return(() => call($18, "load8_u", [4_974]), 0); + +// memory_copy.wast:3629 +assert_return(() => call($18, "load8_u", [5_173]), 0); + +// memory_copy.wast:3630 +assert_return(() => call($18, "load8_u", [5_372]), 0); + +// memory_copy.wast:3631 +assert_return(() => call($18, "load8_u", [5_571]), 0); + +// memory_copy.wast:3632 +assert_return(() => call($18, "load8_u", [5_770]), 0); + +// memory_copy.wast:3633 +assert_return(() => call($18, "load8_u", [5_969]), 0); + +// memory_copy.wast:3634 +assert_return(() => call($18, "load8_u", [6_168]), 0); + +// memory_copy.wast:3635 +assert_return(() => call($18, "load8_u", [6_367]), 0); + +// memory_copy.wast:3636 +assert_return(() => call($18, "load8_u", [6_566]), 0); + +// memory_copy.wast:3637 +assert_return(() => call($18, "load8_u", [6_765]), 0); + +// memory_copy.wast:3638 +assert_return(() => call($18, "load8_u", [6_964]), 0); + +// memory_copy.wast:3639 +assert_return(() => call($18, "load8_u", [7_163]), 0); + +// memory_copy.wast:3640 +assert_return(() => call($18, "load8_u", [7_362]), 0); + +// memory_copy.wast:3641 +assert_return(() => call($18, "load8_u", [7_561]), 0); + +// memory_copy.wast:3642 +assert_return(() => call($18, "load8_u", [7_760]), 0); + +// memory_copy.wast:3643 +assert_return(() => call($18, "load8_u", [7_959]), 0); + +// memory_copy.wast:3644 +assert_return(() => call($18, "load8_u", [8_158]), 0); + +// memory_copy.wast:3645 +assert_return(() => call($18, "load8_u", [8_357]), 0); + +// memory_copy.wast:3646 +assert_return(() => call($18, "load8_u", [8_556]), 0); + +// memory_copy.wast:3647 +assert_return(() => call($18, "load8_u", [8_755]), 0); + +// memory_copy.wast:3648 +assert_return(() => call($18, "load8_u", [8_954]), 0); + +// memory_copy.wast:3649 +assert_return(() => call($18, "load8_u", [9_153]), 0); + +// memory_copy.wast:3650 +assert_return(() => call($18, "load8_u", [9_352]), 0); + +// memory_copy.wast:3651 +assert_return(() => call($18, "load8_u", [9_551]), 0); + +// memory_copy.wast:3652 +assert_return(() => call($18, "load8_u", [9_750]), 0); + +// memory_copy.wast:3653 +assert_return(() => call($18, "load8_u", [9_949]), 0); + +// memory_copy.wast:3654 +assert_return(() => call($18, "load8_u", [10_148]), 0); + +// memory_copy.wast:3655 +assert_return(() => call($18, "load8_u", [10_347]), 0); + +// memory_copy.wast:3656 +assert_return(() => call($18, "load8_u", [10_546]), 0); + +// memory_copy.wast:3657 +assert_return(() => call($18, "load8_u", [10_745]), 0); + +// memory_copy.wast:3658 +assert_return(() => call($18, "load8_u", [10_944]), 0); + +// memory_copy.wast:3659 +assert_return(() => call($18, "load8_u", [11_143]), 0); + +// memory_copy.wast:3660 +assert_return(() => call($18, "load8_u", [11_342]), 0); + +// memory_copy.wast:3661 +assert_return(() => call($18, "load8_u", [11_541]), 0); + +// memory_copy.wast:3662 +assert_return(() => call($18, "load8_u", [11_740]), 0); + +// memory_copy.wast:3663 +assert_return(() => call($18, "load8_u", [11_939]), 0); + +// memory_copy.wast:3664 +assert_return(() => call($18, "load8_u", [12_138]), 0); + +// memory_copy.wast:3665 +assert_return(() => call($18, "load8_u", [12_337]), 0); + +// memory_copy.wast:3666 +assert_return(() => call($18, "load8_u", [12_536]), 0); + +// memory_copy.wast:3667 +assert_return(() => call($18, "load8_u", [12_735]), 0); + +// memory_copy.wast:3668 +assert_return(() => call($18, "load8_u", [12_934]), 0); + +// memory_copy.wast:3669 +assert_return(() => call($18, "load8_u", [13_133]), 0); + +// memory_copy.wast:3670 +assert_return(() => call($18, "load8_u", [13_332]), 0); + +// memory_copy.wast:3671 +assert_return(() => call($18, "load8_u", [13_531]), 0); + +// memory_copy.wast:3672 +assert_return(() => call($18, "load8_u", [13_730]), 0); + +// memory_copy.wast:3673 +assert_return(() => call($18, "load8_u", [13_929]), 0); + +// memory_copy.wast:3674 +assert_return(() => call($18, "load8_u", [14_128]), 0); + +// memory_copy.wast:3675 +assert_return(() => call($18, "load8_u", [14_327]), 0); + +// memory_copy.wast:3676 +assert_return(() => call($18, "load8_u", [14_526]), 0); + +// memory_copy.wast:3677 +assert_return(() => call($18, "load8_u", [14_725]), 0); + +// memory_copy.wast:3678 +assert_return(() => call($18, "load8_u", [14_924]), 0); + +// memory_copy.wast:3679 +assert_return(() => call($18, "load8_u", [15_123]), 0); + +// memory_copy.wast:3680 +assert_return(() => call($18, "load8_u", [15_322]), 0); + +// memory_copy.wast:3681 +assert_return(() => call($18, "load8_u", [15_521]), 0); + +// memory_copy.wast:3682 +assert_return(() => call($18, "load8_u", [15_720]), 0); + +// memory_copy.wast:3683 +assert_return(() => call($18, "load8_u", [15_919]), 0); + +// memory_copy.wast:3684 +assert_return(() => call($18, "load8_u", [16_118]), 0); + +// memory_copy.wast:3685 +assert_return(() => call($18, "load8_u", [16_317]), 0); + +// memory_copy.wast:3686 +assert_return(() => call($18, "load8_u", [16_516]), 0); + +// memory_copy.wast:3687 +assert_return(() => call($18, "load8_u", [16_715]), 0); + +// memory_copy.wast:3688 +assert_return(() => call($18, "load8_u", [16_914]), 0); + +// memory_copy.wast:3689 +assert_return(() => call($18, "load8_u", [17_113]), 0); + +// memory_copy.wast:3690 +assert_return(() => call($18, "load8_u", [17_312]), 0); + +// memory_copy.wast:3691 +assert_return(() => call($18, "load8_u", [17_511]), 0); + +// memory_copy.wast:3692 +assert_return(() => call($18, "load8_u", [17_710]), 0); + +// memory_copy.wast:3693 +assert_return(() => call($18, "load8_u", [17_909]), 0); + +// memory_copy.wast:3694 +assert_return(() => call($18, "load8_u", [18_108]), 0); + +// memory_copy.wast:3695 +assert_return(() => call($18, "load8_u", [18_307]), 0); + +// memory_copy.wast:3696 +assert_return(() => call($18, "load8_u", [18_506]), 0); + +// memory_copy.wast:3697 +assert_return(() => call($18, "load8_u", [18_705]), 0); + +// memory_copy.wast:3698 +assert_return(() => call($18, "load8_u", [18_904]), 0); + +// memory_copy.wast:3699 +assert_return(() => call($18, "load8_u", [19_103]), 0); + +// memory_copy.wast:3700 +assert_return(() => call($18, "load8_u", [19_302]), 0); + +// memory_copy.wast:3701 +assert_return(() => call($18, "load8_u", [19_501]), 0); + +// memory_copy.wast:3702 +assert_return(() => call($18, "load8_u", [19_700]), 0); + +// memory_copy.wast:3703 +assert_return(() => call($18, "load8_u", [19_899]), 0); + +// memory_copy.wast:3704 +assert_return(() => call($18, "load8_u", [20_098]), 0); + +// memory_copy.wast:3705 +assert_return(() => call($18, "load8_u", [20_297]), 0); + +// memory_copy.wast:3706 +assert_return(() => call($18, "load8_u", [20_496]), 0); + +// memory_copy.wast:3707 +assert_return(() => call($18, "load8_u", [20_695]), 0); + +// memory_copy.wast:3708 +assert_return(() => call($18, "load8_u", [20_894]), 0); + +// memory_copy.wast:3709 +assert_return(() => call($18, "load8_u", [21_093]), 0); + +// memory_copy.wast:3710 +assert_return(() => call($18, "load8_u", [21_292]), 0); + +// memory_copy.wast:3711 +assert_return(() => call($18, "load8_u", [21_491]), 0); + +// memory_copy.wast:3712 +assert_return(() => call($18, "load8_u", [21_690]), 0); + +// memory_copy.wast:3713 +assert_return(() => call($18, "load8_u", [21_889]), 0); + +// memory_copy.wast:3714 +assert_return(() => call($18, "load8_u", [22_088]), 0); + +// memory_copy.wast:3715 +assert_return(() => call($18, "load8_u", [22_287]), 0); + +// memory_copy.wast:3716 +assert_return(() => call($18, "load8_u", [22_486]), 0); + +// memory_copy.wast:3717 +assert_return(() => call($18, "load8_u", [22_685]), 0); + +// memory_copy.wast:3718 +assert_return(() => call($18, "load8_u", [22_884]), 0); + +// memory_copy.wast:3719 +assert_return(() => call($18, "load8_u", [23_083]), 0); + +// memory_copy.wast:3720 +assert_return(() => call($18, "load8_u", [23_282]), 0); + +// memory_copy.wast:3721 +assert_return(() => call($18, "load8_u", [23_481]), 0); + +// memory_copy.wast:3722 +assert_return(() => call($18, "load8_u", [23_680]), 0); + +// memory_copy.wast:3723 +assert_return(() => call($18, "load8_u", [23_879]), 0); + +// memory_copy.wast:3724 +assert_return(() => call($18, "load8_u", [24_078]), 0); + +// memory_copy.wast:3725 +assert_return(() => call($18, "load8_u", [24_277]), 0); + +// memory_copy.wast:3726 +assert_return(() => call($18, "load8_u", [24_476]), 0); + +// memory_copy.wast:3727 +assert_return(() => call($18, "load8_u", [24_675]), 0); + +// memory_copy.wast:3728 +assert_return(() => call($18, "load8_u", [24_874]), 0); + +// memory_copy.wast:3729 +assert_return(() => call($18, "load8_u", [25_073]), 0); + +// memory_copy.wast:3730 +assert_return(() => call($18, "load8_u", [25_272]), 0); + +// memory_copy.wast:3731 +assert_return(() => call($18, "load8_u", [25_471]), 0); + +// memory_copy.wast:3732 +assert_return(() => call($18, "load8_u", [25_670]), 0); + +// memory_copy.wast:3733 +assert_return(() => call($18, "load8_u", [25_869]), 0); + +// memory_copy.wast:3734 +assert_return(() => call($18, "load8_u", [26_068]), 0); + +// memory_copy.wast:3735 +assert_return(() => call($18, "load8_u", [26_267]), 0); + +// memory_copy.wast:3736 +assert_return(() => call($18, "load8_u", [26_466]), 0); + +// memory_copy.wast:3737 +assert_return(() => call($18, "load8_u", [26_665]), 0); + +// memory_copy.wast:3738 +assert_return(() => call($18, "load8_u", [26_864]), 0); + +// memory_copy.wast:3739 +assert_return(() => call($18, "load8_u", [27_063]), 0); + +// memory_copy.wast:3740 +assert_return(() => call($18, "load8_u", [27_262]), 0); + +// memory_copy.wast:3741 +assert_return(() => call($18, "load8_u", [27_461]), 0); + +// memory_copy.wast:3742 +assert_return(() => call($18, "load8_u", [27_660]), 0); + +// memory_copy.wast:3743 +assert_return(() => call($18, "load8_u", [27_859]), 0); + +// memory_copy.wast:3744 +assert_return(() => call($18, "load8_u", [28_058]), 0); + +// memory_copy.wast:3745 +assert_return(() => call($18, "load8_u", [28_257]), 0); + +// memory_copy.wast:3746 +assert_return(() => call($18, "load8_u", [28_456]), 0); + +// memory_copy.wast:3747 +assert_return(() => call($18, "load8_u", [28_655]), 0); + +// memory_copy.wast:3748 +assert_return(() => call($18, "load8_u", [28_854]), 0); + +// memory_copy.wast:3749 +assert_return(() => call($18, "load8_u", [29_053]), 0); + +// memory_copy.wast:3750 +assert_return(() => call($18, "load8_u", [29_252]), 0); + +// memory_copy.wast:3751 +assert_return(() => call($18, "load8_u", [29_451]), 0); + +// memory_copy.wast:3752 +assert_return(() => call($18, "load8_u", [29_650]), 0); + +// memory_copy.wast:3753 +assert_return(() => call($18, "load8_u", [29_849]), 0); + +// memory_copy.wast:3754 +assert_return(() => call($18, "load8_u", [30_048]), 0); + +// memory_copy.wast:3755 +assert_return(() => call($18, "load8_u", [30_247]), 0); + +// memory_copy.wast:3756 +assert_return(() => call($18, "load8_u", [30_446]), 0); + +// memory_copy.wast:3757 +assert_return(() => call($18, "load8_u", [30_645]), 0); + +// memory_copy.wast:3758 +assert_return(() => call($18, "load8_u", [30_844]), 0); + +// memory_copy.wast:3759 +assert_return(() => call($18, "load8_u", [31_043]), 0); + +// memory_copy.wast:3760 +assert_return(() => call($18, "load8_u", [31_242]), 0); + +// memory_copy.wast:3761 +assert_return(() => call($18, "load8_u", [31_441]), 0); + +// memory_copy.wast:3762 +assert_return(() => call($18, "load8_u", [31_640]), 0); + +// memory_copy.wast:3763 +assert_return(() => call($18, "load8_u", [31_839]), 0); + +// memory_copy.wast:3764 +assert_return(() => call($18, "load8_u", [32_038]), 0); + +// memory_copy.wast:3765 +assert_return(() => call($18, "load8_u", [32_237]), 0); + +// memory_copy.wast:3766 +assert_return(() => call($18, "load8_u", [32_436]), 0); + +// memory_copy.wast:3767 +assert_return(() => call($18, "load8_u", [32_635]), 0); + +// memory_copy.wast:3768 +assert_return(() => call($18, "load8_u", [32_834]), 0); + +// memory_copy.wast:3769 +assert_return(() => call($18, "load8_u", [33_033]), 0); + +// memory_copy.wast:3770 +assert_return(() => call($18, "load8_u", [33_232]), 0); + +// memory_copy.wast:3771 +assert_return(() => call($18, "load8_u", [33_431]), 0); + +// memory_copy.wast:3772 +assert_return(() => call($18, "load8_u", [33_630]), 0); + +// memory_copy.wast:3773 +assert_return(() => call($18, "load8_u", [33_829]), 0); + +// memory_copy.wast:3774 +assert_return(() => call($18, "load8_u", [34_028]), 0); + +// memory_copy.wast:3775 +assert_return(() => call($18, "load8_u", [34_227]), 0); + +// memory_copy.wast:3776 +assert_return(() => call($18, "load8_u", [34_426]), 0); + +// memory_copy.wast:3777 +assert_return(() => call($18, "load8_u", [34_625]), 0); + +// memory_copy.wast:3778 +assert_return(() => call($18, "load8_u", [34_824]), 0); + +// memory_copy.wast:3779 +assert_return(() => call($18, "load8_u", [35_023]), 0); + +// memory_copy.wast:3780 +assert_return(() => call($18, "load8_u", [35_222]), 0); + +// memory_copy.wast:3781 +assert_return(() => call($18, "load8_u", [35_421]), 0); + +// memory_copy.wast:3782 +assert_return(() => call($18, "load8_u", [35_620]), 0); + +// memory_copy.wast:3783 +assert_return(() => call($18, "load8_u", [35_819]), 0); + +// memory_copy.wast:3784 +assert_return(() => call($18, "load8_u", [36_018]), 0); + +// memory_copy.wast:3785 +assert_return(() => call($18, "load8_u", [36_217]), 0); + +// memory_copy.wast:3786 +assert_return(() => call($18, "load8_u", [36_416]), 0); + +// memory_copy.wast:3787 +assert_return(() => call($18, "load8_u", [36_615]), 0); + +// memory_copy.wast:3788 +assert_return(() => call($18, "load8_u", [36_814]), 0); + +// memory_copy.wast:3789 +assert_return(() => call($18, "load8_u", [37_013]), 0); + +// memory_copy.wast:3790 +assert_return(() => call($18, "load8_u", [37_212]), 0); + +// memory_copy.wast:3791 +assert_return(() => call($18, "load8_u", [37_411]), 0); + +// memory_copy.wast:3792 +assert_return(() => call($18, "load8_u", [37_610]), 0); + +// memory_copy.wast:3793 +assert_return(() => call($18, "load8_u", [37_809]), 0); + +// memory_copy.wast:3794 +assert_return(() => call($18, "load8_u", [38_008]), 0); + +// memory_copy.wast:3795 +assert_return(() => call($18, "load8_u", [38_207]), 0); + +// memory_copy.wast:3796 +assert_return(() => call($18, "load8_u", [38_406]), 0); + +// memory_copy.wast:3797 +assert_return(() => call($18, "load8_u", [38_605]), 0); + +// memory_copy.wast:3798 +assert_return(() => call($18, "load8_u", [38_804]), 0); + +// memory_copy.wast:3799 +assert_return(() => call($18, "load8_u", [39_003]), 0); + +// memory_copy.wast:3800 +assert_return(() => call($18, "load8_u", [39_202]), 0); + +// memory_copy.wast:3801 +assert_return(() => call($18, "load8_u", [39_401]), 0); + +// memory_copy.wast:3802 +assert_return(() => call($18, "load8_u", [39_600]), 0); + +// memory_copy.wast:3803 +assert_return(() => call($18, "load8_u", [39_799]), 0); + +// memory_copy.wast:3804 +assert_return(() => call($18, "load8_u", [39_998]), 0); + +// memory_copy.wast:3805 +assert_return(() => call($18, "load8_u", [40_197]), 0); + +// memory_copy.wast:3806 +assert_return(() => call($18, "load8_u", [40_396]), 0); + +// memory_copy.wast:3807 +assert_return(() => call($18, "load8_u", [40_595]), 0); + +// memory_copy.wast:3808 +assert_return(() => call($18, "load8_u", [40_794]), 0); + +// memory_copy.wast:3809 +assert_return(() => call($18, "load8_u", [40_993]), 0); + +// memory_copy.wast:3810 +assert_return(() => call($18, "load8_u", [41_192]), 0); + +// memory_copy.wast:3811 +assert_return(() => call($18, "load8_u", [41_391]), 0); + +// memory_copy.wast:3812 +assert_return(() => call($18, "load8_u", [41_590]), 0); + +// memory_copy.wast:3813 +assert_return(() => call($18, "load8_u", [41_789]), 0); + +// memory_copy.wast:3814 +assert_return(() => call($18, "load8_u", [41_988]), 0); + +// memory_copy.wast:3815 +assert_return(() => call($18, "load8_u", [42_187]), 0); + +// memory_copy.wast:3816 +assert_return(() => call($18, "load8_u", [42_386]), 0); + +// memory_copy.wast:3817 +assert_return(() => call($18, "load8_u", [42_585]), 0); + +// memory_copy.wast:3818 +assert_return(() => call($18, "load8_u", [42_784]), 0); + +// memory_copy.wast:3819 +assert_return(() => call($18, "load8_u", [42_983]), 0); + +// memory_copy.wast:3820 +assert_return(() => call($18, "load8_u", [43_182]), 0); + +// memory_copy.wast:3821 +assert_return(() => call($18, "load8_u", [43_381]), 0); + +// memory_copy.wast:3822 +assert_return(() => call($18, "load8_u", [43_580]), 0); + +// memory_copy.wast:3823 +assert_return(() => call($18, "load8_u", [43_779]), 0); + +// memory_copy.wast:3824 +assert_return(() => call($18, "load8_u", [43_978]), 0); + +// memory_copy.wast:3825 +assert_return(() => call($18, "load8_u", [44_177]), 0); + +// memory_copy.wast:3826 +assert_return(() => call($18, "load8_u", [44_376]), 0); + +// memory_copy.wast:3827 +assert_return(() => call($18, "load8_u", [44_575]), 0); + +// memory_copy.wast:3828 +assert_return(() => call($18, "load8_u", [44_774]), 0); + +// memory_copy.wast:3829 +assert_return(() => call($18, "load8_u", [44_973]), 0); + +// memory_copy.wast:3830 +assert_return(() => call($18, "load8_u", [45_172]), 0); + +// memory_copy.wast:3831 +assert_return(() => call($18, "load8_u", [45_371]), 0); + +// memory_copy.wast:3832 +assert_return(() => call($18, "load8_u", [45_570]), 0); + +// memory_copy.wast:3833 +assert_return(() => call($18, "load8_u", [45_769]), 0); + +// memory_copy.wast:3834 +assert_return(() => call($18, "load8_u", [45_968]), 0); + +// memory_copy.wast:3835 +assert_return(() => call($18, "load8_u", [46_167]), 0); + +// memory_copy.wast:3836 +assert_return(() => call($18, "load8_u", [46_366]), 0); + +// memory_copy.wast:3837 +assert_return(() => call($18, "load8_u", [46_565]), 0); + +// memory_copy.wast:3838 +assert_return(() => call($18, "load8_u", [46_764]), 0); + +// memory_copy.wast:3839 +assert_return(() => call($18, "load8_u", [46_963]), 0); + +// memory_copy.wast:3840 +assert_return(() => call($18, "load8_u", [47_162]), 0); + +// memory_copy.wast:3841 +assert_return(() => call($18, "load8_u", [47_361]), 0); + +// memory_copy.wast:3842 +assert_return(() => call($18, "load8_u", [47_560]), 0); + +// memory_copy.wast:3843 +assert_return(() => call($18, "load8_u", [47_759]), 0); + +// memory_copy.wast:3844 +assert_return(() => call($18, "load8_u", [47_958]), 0); + +// memory_copy.wast:3845 +assert_return(() => call($18, "load8_u", [48_157]), 0); + +// memory_copy.wast:3846 +assert_return(() => call($18, "load8_u", [48_356]), 0); + +// memory_copy.wast:3847 +assert_return(() => call($18, "load8_u", [48_555]), 0); + +// memory_copy.wast:3848 +assert_return(() => call($18, "load8_u", [48_754]), 0); + +// memory_copy.wast:3849 +assert_return(() => call($18, "load8_u", [48_953]), 0); + +// memory_copy.wast:3850 +assert_return(() => call($18, "load8_u", [49_152]), 0); + +// memory_copy.wast:3851 +assert_return(() => call($18, "load8_u", [49_351]), 0); + +// memory_copy.wast:3852 +assert_return(() => call($18, "load8_u", [49_550]), 0); + +// memory_copy.wast:3853 +assert_return(() => call($18, "load8_u", [49_749]), 0); + +// memory_copy.wast:3854 +assert_return(() => call($18, "load8_u", [49_948]), 0); + +// memory_copy.wast:3855 +assert_return(() => call($18, "load8_u", [50_147]), 0); + +// memory_copy.wast:3856 +assert_return(() => call($18, "load8_u", [50_346]), 0); + +// memory_copy.wast:3857 +assert_return(() => call($18, "load8_u", [50_545]), 0); + +// memory_copy.wast:3858 +assert_return(() => call($18, "load8_u", [50_744]), 0); + +// memory_copy.wast:3859 +assert_return(() => call($18, "load8_u", [50_943]), 0); + +// memory_copy.wast:3860 +assert_return(() => call($18, "load8_u", [51_142]), 0); + +// memory_copy.wast:3861 +assert_return(() => call($18, "load8_u", [51_341]), 0); + +// memory_copy.wast:3862 +assert_return(() => call($18, "load8_u", [51_540]), 0); + +// memory_copy.wast:3863 +assert_return(() => call($18, "load8_u", [51_739]), 0); + +// memory_copy.wast:3864 +assert_return(() => call($18, "load8_u", [51_938]), 0); + +// memory_copy.wast:3865 +assert_return(() => call($18, "load8_u", [52_137]), 0); + +// memory_copy.wast:3866 +assert_return(() => call($18, "load8_u", [52_336]), 0); + +// memory_copy.wast:3867 +assert_return(() => call($18, "load8_u", [52_535]), 0); + +// memory_copy.wast:3868 +assert_return(() => call($18, "load8_u", [52_734]), 0); + +// memory_copy.wast:3869 +assert_return(() => call($18, "load8_u", [52_933]), 0); + +// memory_copy.wast:3870 +assert_return(() => call($18, "load8_u", [53_132]), 0); + +// memory_copy.wast:3871 +assert_return(() => call($18, "load8_u", [53_331]), 0); + +// memory_copy.wast:3872 +assert_return(() => call($18, "load8_u", [53_530]), 0); + +// memory_copy.wast:3873 +assert_return(() => call($18, "load8_u", [53_729]), 0); + +// memory_copy.wast:3874 +assert_return(() => call($18, "load8_u", [53_928]), 0); + +// memory_copy.wast:3875 +assert_return(() => call($18, "load8_u", [54_127]), 0); + +// memory_copy.wast:3876 +assert_return(() => call($18, "load8_u", [54_326]), 0); + +// memory_copy.wast:3877 +assert_return(() => call($18, "load8_u", [54_525]), 0); + +// memory_copy.wast:3878 +assert_return(() => call($18, "load8_u", [54_724]), 0); + +// memory_copy.wast:3879 +assert_return(() => call($18, "load8_u", [54_923]), 0); + +// memory_copy.wast:3880 +assert_return(() => call($18, "load8_u", [55_122]), 0); + +// memory_copy.wast:3881 +assert_return(() => call($18, "load8_u", [55_321]), 0); + +// memory_copy.wast:3882 +assert_return(() => call($18, "load8_u", [55_520]), 0); + +// memory_copy.wast:3883 +assert_return(() => call($18, "load8_u", [55_719]), 0); + +// memory_copy.wast:3884 +assert_return(() => call($18, "load8_u", [55_918]), 0); + +// memory_copy.wast:3885 +assert_return(() => call($18, "load8_u", [56_117]), 0); + +// memory_copy.wast:3886 +assert_return(() => call($18, "load8_u", [56_316]), 0); + +// memory_copy.wast:3887 +assert_return(() => call($18, "load8_u", [56_515]), 0); + +// memory_copy.wast:3888 +assert_return(() => call($18, "load8_u", [56_714]), 0); + +// memory_copy.wast:3889 +assert_return(() => call($18, "load8_u", [56_913]), 0); + +// memory_copy.wast:3890 +assert_return(() => call($18, "load8_u", [57_112]), 0); + +// memory_copy.wast:3891 +assert_return(() => call($18, "load8_u", [57_311]), 0); + +// memory_copy.wast:3892 +assert_return(() => call($18, "load8_u", [57_510]), 0); + +// memory_copy.wast:3893 +assert_return(() => call($18, "load8_u", [57_709]), 0); + +// memory_copy.wast:3894 +assert_return(() => call($18, "load8_u", [57_908]), 0); + +// memory_copy.wast:3895 +assert_return(() => call($18, "load8_u", [58_107]), 0); + +// memory_copy.wast:3896 +assert_return(() => call($18, "load8_u", [58_306]), 0); + +// memory_copy.wast:3897 +assert_return(() => call($18, "load8_u", [58_505]), 0); + +// memory_copy.wast:3898 +assert_return(() => call($18, "load8_u", [58_704]), 0); + +// memory_copy.wast:3899 +assert_return(() => call($18, "load8_u", [58_903]), 0); + +// memory_copy.wast:3900 +assert_return(() => call($18, "load8_u", [59_102]), 0); + +// memory_copy.wast:3901 +assert_return(() => call($18, "load8_u", [59_301]), 0); + +// memory_copy.wast:3902 +assert_return(() => call($18, "load8_u", [59_500]), 0); + +// memory_copy.wast:3903 +assert_return(() => call($18, "load8_u", [59_699]), 0); + +// memory_copy.wast:3904 +assert_return(() => call($18, "load8_u", [59_898]), 0); + +// memory_copy.wast:3905 +assert_return(() => call($18, "load8_u", [60_097]), 0); + +// memory_copy.wast:3906 +assert_return(() => call($18, "load8_u", [60_296]), 0); + +// memory_copy.wast:3907 +assert_return(() => call($18, "load8_u", [60_495]), 0); + +// memory_copy.wast:3908 +assert_return(() => call($18, "load8_u", [60_694]), 0); + +// memory_copy.wast:3909 +assert_return(() => call($18, "load8_u", [60_893]), 0); + +// memory_copy.wast:3910 +assert_return(() => call($18, "load8_u", [61_092]), 0); + +// memory_copy.wast:3911 +assert_return(() => call($18, "load8_u", [61_291]), 0); + +// memory_copy.wast:3912 +assert_return(() => call($18, "load8_u", [61_490]), 0); + +// memory_copy.wast:3913 +assert_return(() => call($18, "load8_u", [61_689]), 0); + +// memory_copy.wast:3914 +assert_return(() => call($18, "load8_u", [61_888]), 0); + +// memory_copy.wast:3915 +assert_return(() => call($18, "load8_u", [62_087]), 0); + +// memory_copy.wast:3916 +assert_return(() => call($18, "load8_u", [62_286]), 0); + +// memory_copy.wast:3917 +assert_return(() => call($18, "load8_u", [62_485]), 0); + +// memory_copy.wast:3918 +assert_return(() => call($18, "load8_u", [62_684]), 0); + +// memory_copy.wast:3919 +assert_return(() => call($18, "load8_u", [62_883]), 0); + +// memory_copy.wast:3920 +assert_return(() => call($18, "load8_u", [63_082]), 0); + +// memory_copy.wast:3921 +assert_return(() => call($18, "load8_u", [63_281]), 0); + +// memory_copy.wast:3922 +assert_return(() => call($18, "load8_u", [63_480]), 0); + +// memory_copy.wast:3923 +assert_return(() => call($18, "load8_u", [63_679]), 0); + +// memory_copy.wast:3924 +assert_return(() => call($18, "load8_u", [63_878]), 0); + +// memory_copy.wast:3925 +assert_return(() => call($18, "load8_u", [64_077]), 0); + +// memory_copy.wast:3926 +assert_return(() => call($18, "load8_u", [64_276]), 0); + +// memory_copy.wast:3927 +assert_return(() => call($18, "load8_u", [64_475]), 0); + +// memory_copy.wast:3928 +assert_return(() => call($18, "load8_u", [64_674]), 0); + +// memory_copy.wast:3929 +assert_return(() => call($18, "load8_u", [64_873]), 0); + +// memory_copy.wast:3930 +assert_return(() => call($18, "load8_u", [65_072]), 0); + +// memory_copy.wast:3931 +assert_return(() => call($18, "load8_u", [65_271]), 0); + +// memory_copy.wast:3932 +assert_return(() => call($18, "load8_u", [65_470]), 0); + +// memory_copy.wast:3933 +assert_return(() => call($18, "load8_u", [65_516]), 0); + +// memory_copy.wast:3934 +assert_return(() => call($18, "load8_u", [65_517]), 1); + +// memory_copy.wast:3935 +assert_return(() => call($18, "load8_u", [65_518]), 2); + +// memory_copy.wast:3936 +assert_return(() => call($18, "load8_u", [65_519]), 3); + +// memory_copy.wast:3937 +assert_return(() => call($18, "load8_u", [65_520]), 4); + +// memory_copy.wast:3938 +assert_return(() => call($18, "load8_u", [65_521]), 5); + +// memory_copy.wast:3939 +assert_return(() => call($18, "load8_u", [65_522]), 6); + +// memory_copy.wast:3940 +assert_return(() => call($18, "load8_u", [65_523]), 7); + +// memory_copy.wast:3941 +assert_return(() => call($18, "load8_u", [65_524]), 8); + +// memory_copy.wast:3942 +assert_return(() => call($18, "load8_u", [65_525]), 9); + +// memory_copy.wast:3943 +assert_return(() => call($18, "load8_u", [65_526]), 10); + +// memory_copy.wast:3944 +assert_return(() => call($18, "load8_u", [65_527]), 11); + +// memory_copy.wast:3945 +assert_return(() => call($18, "load8_u", [65_528]), 12); + +// memory_copy.wast:3946 +assert_return(() => call($18, "load8_u", [65_529]), 13); + +// memory_copy.wast:3947 +assert_return(() => call($18, "load8_u", [65_530]), 14); + +// memory_copy.wast:3948 +assert_return(() => call($18, "load8_u", [65_531]), 15); + +// memory_copy.wast:3949 +assert_return(() => call($18, "load8_u", [65_532]), 16); + +// memory_copy.wast:3950 +assert_return(() => call($18, "load8_u", [65_533]), 17); + +// memory_copy.wast:3951 +assert_return(() => call($18, "load8_u", [65_534]), 18); + +// memory_copy.wast:3952 +assert_return(() => call($18, "load8_u", [65_535]), 19); + +// memory_copy.wast:3954 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x97\x80\x80\x80\x00\x03\x03\x6d\x65\x6d\x02\x00\x03\x72\x75\x6e\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\x9c\x80\x80\x80\x00\x01\x00\x41\x80\xe0\x03\x0b\x14\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13"); + +// memory_copy.wast:3962 +assert_trap(() => call($19, "run", [65_516, 61_440, -256])); + +// memory_copy.wast:3965 +assert_return(() => call($19, "load8_u", [198]), 0); + +// memory_copy.wast:3966 +assert_return(() => call($19, "load8_u", [397]), 0); + +// memory_copy.wast:3967 +assert_return(() => call($19, "load8_u", [596]), 0); + +// memory_copy.wast:3968 +assert_return(() => call($19, "load8_u", [795]), 0); + +// memory_copy.wast:3969 +assert_return(() => call($19, "load8_u", [994]), 0); + +// memory_copy.wast:3970 +assert_return(() => call($19, "load8_u", [1_193]), 0); + +// memory_copy.wast:3971 +assert_return(() => call($19, "load8_u", [1_392]), 0); + +// memory_copy.wast:3972 +assert_return(() => call($19, "load8_u", [1_591]), 0); + +// memory_copy.wast:3973 +assert_return(() => call($19, "load8_u", [1_790]), 0); + +// memory_copy.wast:3974 +assert_return(() => call($19, "load8_u", [1_989]), 0); + +// memory_copy.wast:3975 +assert_return(() => call($19, "load8_u", [2_188]), 0); + +// memory_copy.wast:3976 +assert_return(() => call($19, "load8_u", [2_387]), 0); + +// memory_copy.wast:3977 +assert_return(() => call($19, "load8_u", [2_586]), 0); + +// memory_copy.wast:3978 +assert_return(() => call($19, "load8_u", [2_785]), 0); + +// memory_copy.wast:3979 +assert_return(() => call($19, "load8_u", [2_984]), 0); + +// memory_copy.wast:3980 +assert_return(() => call($19, "load8_u", [3_183]), 0); + +// memory_copy.wast:3981 +assert_return(() => call($19, "load8_u", [3_382]), 0); + +// memory_copy.wast:3982 +assert_return(() => call($19, "load8_u", [3_581]), 0); + +// memory_copy.wast:3983 +assert_return(() => call($19, "load8_u", [3_780]), 0); + +// memory_copy.wast:3984 +assert_return(() => call($19, "load8_u", [3_979]), 0); + +// memory_copy.wast:3985 +assert_return(() => call($19, "load8_u", [4_178]), 0); + +// memory_copy.wast:3986 +assert_return(() => call($19, "load8_u", [4_377]), 0); + +// memory_copy.wast:3987 +assert_return(() => call($19, "load8_u", [4_576]), 0); + +// memory_copy.wast:3988 +assert_return(() => call($19, "load8_u", [4_775]), 0); + +// memory_copy.wast:3989 +assert_return(() => call($19, "load8_u", [4_974]), 0); + +// memory_copy.wast:3990 +assert_return(() => call($19, "load8_u", [5_173]), 0); + +// memory_copy.wast:3991 +assert_return(() => call($19, "load8_u", [5_372]), 0); + +// memory_copy.wast:3992 +assert_return(() => call($19, "load8_u", [5_571]), 0); + +// memory_copy.wast:3993 +assert_return(() => call($19, "load8_u", [5_770]), 0); + +// memory_copy.wast:3994 +assert_return(() => call($19, "load8_u", [5_969]), 0); + +// memory_copy.wast:3995 +assert_return(() => call($19, "load8_u", [6_168]), 0); + +// memory_copy.wast:3996 +assert_return(() => call($19, "load8_u", [6_367]), 0); + +// memory_copy.wast:3997 +assert_return(() => call($19, "load8_u", [6_566]), 0); + +// memory_copy.wast:3998 +assert_return(() => call($19, "load8_u", [6_765]), 0); + +// memory_copy.wast:3999 +assert_return(() => call($19, "load8_u", [6_964]), 0); + +// memory_copy.wast:4000 +assert_return(() => call($19, "load8_u", [7_163]), 0); + +// memory_copy.wast:4001 +assert_return(() => call($19, "load8_u", [7_362]), 0); + +// memory_copy.wast:4002 +assert_return(() => call($19, "load8_u", [7_561]), 0); + +// memory_copy.wast:4003 +assert_return(() => call($19, "load8_u", [7_760]), 0); + +// memory_copy.wast:4004 +assert_return(() => call($19, "load8_u", [7_959]), 0); + +// memory_copy.wast:4005 +assert_return(() => call($19, "load8_u", [8_158]), 0); + +// memory_copy.wast:4006 +assert_return(() => call($19, "load8_u", [8_357]), 0); + +// memory_copy.wast:4007 +assert_return(() => call($19, "load8_u", [8_556]), 0); + +// memory_copy.wast:4008 +assert_return(() => call($19, "load8_u", [8_755]), 0); + +// memory_copy.wast:4009 +assert_return(() => call($19, "load8_u", [8_954]), 0); + +// memory_copy.wast:4010 +assert_return(() => call($19, "load8_u", [9_153]), 0); + +// memory_copy.wast:4011 +assert_return(() => call($19, "load8_u", [9_352]), 0); + +// memory_copy.wast:4012 +assert_return(() => call($19, "load8_u", [9_551]), 0); + +// memory_copy.wast:4013 +assert_return(() => call($19, "load8_u", [9_750]), 0); + +// memory_copy.wast:4014 +assert_return(() => call($19, "load8_u", [9_949]), 0); + +// memory_copy.wast:4015 +assert_return(() => call($19, "load8_u", [10_148]), 0); + +// memory_copy.wast:4016 +assert_return(() => call($19, "load8_u", [10_347]), 0); + +// memory_copy.wast:4017 +assert_return(() => call($19, "load8_u", [10_546]), 0); + +// memory_copy.wast:4018 +assert_return(() => call($19, "load8_u", [10_745]), 0); + +// memory_copy.wast:4019 +assert_return(() => call($19, "load8_u", [10_944]), 0); + +// memory_copy.wast:4020 +assert_return(() => call($19, "load8_u", [11_143]), 0); + +// memory_copy.wast:4021 +assert_return(() => call($19, "load8_u", [11_342]), 0); + +// memory_copy.wast:4022 +assert_return(() => call($19, "load8_u", [11_541]), 0); + +// memory_copy.wast:4023 +assert_return(() => call($19, "load8_u", [11_740]), 0); + +// memory_copy.wast:4024 +assert_return(() => call($19, "load8_u", [11_939]), 0); + +// memory_copy.wast:4025 +assert_return(() => call($19, "load8_u", [12_138]), 0); + +// memory_copy.wast:4026 +assert_return(() => call($19, "load8_u", [12_337]), 0); + +// memory_copy.wast:4027 +assert_return(() => call($19, "load8_u", [12_536]), 0); + +// memory_copy.wast:4028 +assert_return(() => call($19, "load8_u", [12_735]), 0); + +// memory_copy.wast:4029 +assert_return(() => call($19, "load8_u", [12_934]), 0); + +// memory_copy.wast:4030 +assert_return(() => call($19, "load8_u", [13_133]), 0); + +// memory_copy.wast:4031 +assert_return(() => call($19, "load8_u", [13_332]), 0); + +// memory_copy.wast:4032 +assert_return(() => call($19, "load8_u", [13_531]), 0); + +// memory_copy.wast:4033 +assert_return(() => call($19, "load8_u", [13_730]), 0); + +// memory_copy.wast:4034 +assert_return(() => call($19, "load8_u", [13_929]), 0); + +// memory_copy.wast:4035 +assert_return(() => call($19, "load8_u", [14_128]), 0); + +// memory_copy.wast:4036 +assert_return(() => call($19, "load8_u", [14_327]), 0); + +// memory_copy.wast:4037 +assert_return(() => call($19, "load8_u", [14_526]), 0); + +// memory_copy.wast:4038 +assert_return(() => call($19, "load8_u", [14_725]), 0); + +// memory_copy.wast:4039 +assert_return(() => call($19, "load8_u", [14_924]), 0); + +// memory_copy.wast:4040 +assert_return(() => call($19, "load8_u", [15_123]), 0); + +// memory_copy.wast:4041 +assert_return(() => call($19, "load8_u", [15_322]), 0); + +// memory_copy.wast:4042 +assert_return(() => call($19, "load8_u", [15_521]), 0); + +// memory_copy.wast:4043 +assert_return(() => call($19, "load8_u", [15_720]), 0); + +// memory_copy.wast:4044 +assert_return(() => call($19, "load8_u", [15_919]), 0); + +// memory_copy.wast:4045 +assert_return(() => call($19, "load8_u", [16_118]), 0); + +// memory_copy.wast:4046 +assert_return(() => call($19, "load8_u", [16_317]), 0); + +// memory_copy.wast:4047 +assert_return(() => call($19, "load8_u", [16_516]), 0); + +// memory_copy.wast:4048 +assert_return(() => call($19, "load8_u", [16_715]), 0); + +// memory_copy.wast:4049 +assert_return(() => call($19, "load8_u", [16_914]), 0); + +// memory_copy.wast:4050 +assert_return(() => call($19, "load8_u", [17_113]), 0); + +// memory_copy.wast:4051 +assert_return(() => call($19, "load8_u", [17_312]), 0); + +// memory_copy.wast:4052 +assert_return(() => call($19, "load8_u", [17_511]), 0); + +// memory_copy.wast:4053 +assert_return(() => call($19, "load8_u", [17_710]), 0); + +// memory_copy.wast:4054 +assert_return(() => call($19, "load8_u", [17_909]), 0); + +// memory_copy.wast:4055 +assert_return(() => call($19, "load8_u", [18_108]), 0); + +// memory_copy.wast:4056 +assert_return(() => call($19, "load8_u", [18_307]), 0); + +// memory_copy.wast:4057 +assert_return(() => call($19, "load8_u", [18_506]), 0); + +// memory_copy.wast:4058 +assert_return(() => call($19, "load8_u", [18_705]), 0); + +// memory_copy.wast:4059 +assert_return(() => call($19, "load8_u", [18_904]), 0); + +// memory_copy.wast:4060 +assert_return(() => call($19, "load8_u", [19_103]), 0); + +// memory_copy.wast:4061 +assert_return(() => call($19, "load8_u", [19_302]), 0); + +// memory_copy.wast:4062 +assert_return(() => call($19, "load8_u", [19_501]), 0); + +// memory_copy.wast:4063 +assert_return(() => call($19, "load8_u", [19_700]), 0); + +// memory_copy.wast:4064 +assert_return(() => call($19, "load8_u", [19_899]), 0); + +// memory_copy.wast:4065 +assert_return(() => call($19, "load8_u", [20_098]), 0); + +// memory_copy.wast:4066 +assert_return(() => call($19, "load8_u", [20_297]), 0); + +// memory_copy.wast:4067 +assert_return(() => call($19, "load8_u", [20_496]), 0); + +// memory_copy.wast:4068 +assert_return(() => call($19, "load8_u", [20_695]), 0); + +// memory_copy.wast:4069 +assert_return(() => call($19, "load8_u", [20_894]), 0); + +// memory_copy.wast:4070 +assert_return(() => call($19, "load8_u", [21_093]), 0); + +// memory_copy.wast:4071 +assert_return(() => call($19, "load8_u", [21_292]), 0); + +// memory_copy.wast:4072 +assert_return(() => call($19, "load8_u", [21_491]), 0); + +// memory_copy.wast:4073 +assert_return(() => call($19, "load8_u", [21_690]), 0); + +// memory_copy.wast:4074 +assert_return(() => call($19, "load8_u", [21_889]), 0); + +// memory_copy.wast:4075 +assert_return(() => call($19, "load8_u", [22_088]), 0); + +// memory_copy.wast:4076 +assert_return(() => call($19, "load8_u", [22_287]), 0); + +// memory_copy.wast:4077 +assert_return(() => call($19, "load8_u", [22_486]), 0); + +// memory_copy.wast:4078 +assert_return(() => call($19, "load8_u", [22_685]), 0); + +// memory_copy.wast:4079 +assert_return(() => call($19, "load8_u", [22_884]), 0); + +// memory_copy.wast:4080 +assert_return(() => call($19, "load8_u", [23_083]), 0); + +// memory_copy.wast:4081 +assert_return(() => call($19, "load8_u", [23_282]), 0); + +// memory_copy.wast:4082 +assert_return(() => call($19, "load8_u", [23_481]), 0); + +// memory_copy.wast:4083 +assert_return(() => call($19, "load8_u", [23_680]), 0); + +// memory_copy.wast:4084 +assert_return(() => call($19, "load8_u", [23_879]), 0); + +// memory_copy.wast:4085 +assert_return(() => call($19, "load8_u", [24_078]), 0); + +// memory_copy.wast:4086 +assert_return(() => call($19, "load8_u", [24_277]), 0); + +// memory_copy.wast:4087 +assert_return(() => call($19, "load8_u", [24_476]), 0); + +// memory_copy.wast:4088 +assert_return(() => call($19, "load8_u", [24_675]), 0); + +// memory_copy.wast:4089 +assert_return(() => call($19, "load8_u", [24_874]), 0); + +// memory_copy.wast:4090 +assert_return(() => call($19, "load8_u", [25_073]), 0); + +// memory_copy.wast:4091 +assert_return(() => call($19, "load8_u", [25_272]), 0); + +// memory_copy.wast:4092 +assert_return(() => call($19, "load8_u", [25_471]), 0); + +// memory_copy.wast:4093 +assert_return(() => call($19, "load8_u", [25_670]), 0); + +// memory_copy.wast:4094 +assert_return(() => call($19, "load8_u", [25_869]), 0); + +// memory_copy.wast:4095 +assert_return(() => call($19, "load8_u", [26_068]), 0); + +// memory_copy.wast:4096 +assert_return(() => call($19, "load8_u", [26_267]), 0); + +// memory_copy.wast:4097 +assert_return(() => call($19, "load8_u", [26_466]), 0); + +// memory_copy.wast:4098 +assert_return(() => call($19, "load8_u", [26_665]), 0); + +// memory_copy.wast:4099 +assert_return(() => call($19, "load8_u", [26_864]), 0); + +// memory_copy.wast:4100 +assert_return(() => call($19, "load8_u", [27_063]), 0); + +// memory_copy.wast:4101 +assert_return(() => call($19, "load8_u", [27_262]), 0); + +// memory_copy.wast:4102 +assert_return(() => call($19, "load8_u", [27_461]), 0); + +// memory_copy.wast:4103 +assert_return(() => call($19, "load8_u", [27_660]), 0); + +// memory_copy.wast:4104 +assert_return(() => call($19, "load8_u", [27_859]), 0); + +// memory_copy.wast:4105 +assert_return(() => call($19, "load8_u", [28_058]), 0); + +// memory_copy.wast:4106 +assert_return(() => call($19, "load8_u", [28_257]), 0); + +// memory_copy.wast:4107 +assert_return(() => call($19, "load8_u", [28_456]), 0); + +// memory_copy.wast:4108 +assert_return(() => call($19, "load8_u", [28_655]), 0); + +// memory_copy.wast:4109 +assert_return(() => call($19, "load8_u", [28_854]), 0); + +// memory_copy.wast:4110 +assert_return(() => call($19, "load8_u", [29_053]), 0); + +// memory_copy.wast:4111 +assert_return(() => call($19, "load8_u", [29_252]), 0); + +// memory_copy.wast:4112 +assert_return(() => call($19, "load8_u", [29_451]), 0); + +// memory_copy.wast:4113 +assert_return(() => call($19, "load8_u", [29_650]), 0); + +// memory_copy.wast:4114 +assert_return(() => call($19, "load8_u", [29_849]), 0); + +// memory_copy.wast:4115 +assert_return(() => call($19, "load8_u", [30_048]), 0); + +// memory_copy.wast:4116 +assert_return(() => call($19, "load8_u", [30_247]), 0); + +// memory_copy.wast:4117 +assert_return(() => call($19, "load8_u", [30_446]), 0); + +// memory_copy.wast:4118 +assert_return(() => call($19, "load8_u", [30_645]), 0); + +// memory_copy.wast:4119 +assert_return(() => call($19, "load8_u", [30_844]), 0); + +// memory_copy.wast:4120 +assert_return(() => call($19, "load8_u", [31_043]), 0); + +// memory_copy.wast:4121 +assert_return(() => call($19, "load8_u", [31_242]), 0); + +// memory_copy.wast:4122 +assert_return(() => call($19, "load8_u", [31_441]), 0); + +// memory_copy.wast:4123 +assert_return(() => call($19, "load8_u", [31_640]), 0); + +// memory_copy.wast:4124 +assert_return(() => call($19, "load8_u", [31_839]), 0); + +// memory_copy.wast:4125 +assert_return(() => call($19, "load8_u", [32_038]), 0); + +// memory_copy.wast:4126 +assert_return(() => call($19, "load8_u", [32_237]), 0); + +// memory_copy.wast:4127 +assert_return(() => call($19, "load8_u", [32_436]), 0); + +// memory_copy.wast:4128 +assert_return(() => call($19, "load8_u", [32_635]), 0); + +// memory_copy.wast:4129 +assert_return(() => call($19, "load8_u", [32_834]), 0); + +// memory_copy.wast:4130 +assert_return(() => call($19, "load8_u", [33_033]), 0); + +// memory_copy.wast:4131 +assert_return(() => call($19, "load8_u", [33_232]), 0); + +// memory_copy.wast:4132 +assert_return(() => call($19, "load8_u", [33_431]), 0); + +// memory_copy.wast:4133 +assert_return(() => call($19, "load8_u", [33_630]), 0); + +// memory_copy.wast:4134 +assert_return(() => call($19, "load8_u", [33_829]), 0); + +// memory_copy.wast:4135 +assert_return(() => call($19, "load8_u", [34_028]), 0); + +// memory_copy.wast:4136 +assert_return(() => call($19, "load8_u", [34_227]), 0); + +// memory_copy.wast:4137 +assert_return(() => call($19, "load8_u", [34_426]), 0); + +// memory_copy.wast:4138 +assert_return(() => call($19, "load8_u", [34_625]), 0); + +// memory_copy.wast:4139 +assert_return(() => call($19, "load8_u", [34_824]), 0); + +// memory_copy.wast:4140 +assert_return(() => call($19, "load8_u", [35_023]), 0); + +// memory_copy.wast:4141 +assert_return(() => call($19, "load8_u", [35_222]), 0); + +// memory_copy.wast:4142 +assert_return(() => call($19, "load8_u", [35_421]), 0); + +// memory_copy.wast:4143 +assert_return(() => call($19, "load8_u", [35_620]), 0); + +// memory_copy.wast:4144 +assert_return(() => call($19, "load8_u", [35_819]), 0); + +// memory_copy.wast:4145 +assert_return(() => call($19, "load8_u", [36_018]), 0); + +// memory_copy.wast:4146 +assert_return(() => call($19, "load8_u", [36_217]), 0); + +// memory_copy.wast:4147 +assert_return(() => call($19, "load8_u", [36_416]), 0); + +// memory_copy.wast:4148 +assert_return(() => call($19, "load8_u", [36_615]), 0); + +// memory_copy.wast:4149 +assert_return(() => call($19, "load8_u", [36_814]), 0); + +// memory_copy.wast:4150 +assert_return(() => call($19, "load8_u", [37_013]), 0); + +// memory_copy.wast:4151 +assert_return(() => call($19, "load8_u", [37_212]), 0); + +// memory_copy.wast:4152 +assert_return(() => call($19, "load8_u", [37_411]), 0); + +// memory_copy.wast:4153 +assert_return(() => call($19, "load8_u", [37_610]), 0); + +// memory_copy.wast:4154 +assert_return(() => call($19, "load8_u", [37_809]), 0); + +// memory_copy.wast:4155 +assert_return(() => call($19, "load8_u", [38_008]), 0); + +// memory_copy.wast:4156 +assert_return(() => call($19, "load8_u", [38_207]), 0); + +// memory_copy.wast:4157 +assert_return(() => call($19, "load8_u", [38_406]), 0); + +// memory_copy.wast:4158 +assert_return(() => call($19, "load8_u", [38_605]), 0); + +// memory_copy.wast:4159 +assert_return(() => call($19, "load8_u", [38_804]), 0); + +// memory_copy.wast:4160 +assert_return(() => call($19, "load8_u", [39_003]), 0); + +// memory_copy.wast:4161 +assert_return(() => call($19, "load8_u", [39_202]), 0); + +// memory_copy.wast:4162 +assert_return(() => call($19, "load8_u", [39_401]), 0); + +// memory_copy.wast:4163 +assert_return(() => call($19, "load8_u", [39_600]), 0); + +// memory_copy.wast:4164 +assert_return(() => call($19, "load8_u", [39_799]), 0); + +// memory_copy.wast:4165 +assert_return(() => call($19, "load8_u", [39_998]), 0); + +// memory_copy.wast:4166 +assert_return(() => call($19, "load8_u", [40_197]), 0); + +// memory_copy.wast:4167 +assert_return(() => call($19, "load8_u", [40_396]), 0); + +// memory_copy.wast:4168 +assert_return(() => call($19, "load8_u", [40_595]), 0); + +// memory_copy.wast:4169 +assert_return(() => call($19, "load8_u", [40_794]), 0); + +// memory_copy.wast:4170 +assert_return(() => call($19, "load8_u", [40_993]), 0); + +// memory_copy.wast:4171 +assert_return(() => call($19, "load8_u", [41_192]), 0); + +// memory_copy.wast:4172 +assert_return(() => call($19, "load8_u", [41_391]), 0); + +// memory_copy.wast:4173 +assert_return(() => call($19, "load8_u", [41_590]), 0); + +// memory_copy.wast:4174 +assert_return(() => call($19, "load8_u", [41_789]), 0); + +// memory_copy.wast:4175 +assert_return(() => call($19, "load8_u", [41_988]), 0); + +// memory_copy.wast:4176 +assert_return(() => call($19, "load8_u", [42_187]), 0); + +// memory_copy.wast:4177 +assert_return(() => call($19, "load8_u", [42_386]), 0); + +// memory_copy.wast:4178 +assert_return(() => call($19, "load8_u", [42_585]), 0); + +// memory_copy.wast:4179 +assert_return(() => call($19, "load8_u", [42_784]), 0); + +// memory_copy.wast:4180 +assert_return(() => call($19, "load8_u", [42_983]), 0); + +// memory_copy.wast:4181 +assert_return(() => call($19, "load8_u", [43_182]), 0); + +// memory_copy.wast:4182 +assert_return(() => call($19, "load8_u", [43_381]), 0); + +// memory_copy.wast:4183 +assert_return(() => call($19, "load8_u", [43_580]), 0); + +// memory_copy.wast:4184 +assert_return(() => call($19, "load8_u", [43_779]), 0); + +// memory_copy.wast:4185 +assert_return(() => call($19, "load8_u", [43_978]), 0); + +// memory_copy.wast:4186 +assert_return(() => call($19, "load8_u", [44_177]), 0); + +// memory_copy.wast:4187 +assert_return(() => call($19, "load8_u", [44_376]), 0); + +// memory_copy.wast:4188 +assert_return(() => call($19, "load8_u", [44_575]), 0); + +// memory_copy.wast:4189 +assert_return(() => call($19, "load8_u", [44_774]), 0); + +// memory_copy.wast:4190 +assert_return(() => call($19, "load8_u", [44_973]), 0); + +// memory_copy.wast:4191 +assert_return(() => call($19, "load8_u", [45_172]), 0); + +// memory_copy.wast:4192 +assert_return(() => call($19, "load8_u", [45_371]), 0); + +// memory_copy.wast:4193 +assert_return(() => call($19, "load8_u", [45_570]), 0); + +// memory_copy.wast:4194 +assert_return(() => call($19, "load8_u", [45_769]), 0); + +// memory_copy.wast:4195 +assert_return(() => call($19, "load8_u", [45_968]), 0); + +// memory_copy.wast:4196 +assert_return(() => call($19, "load8_u", [46_167]), 0); + +// memory_copy.wast:4197 +assert_return(() => call($19, "load8_u", [46_366]), 0); + +// memory_copy.wast:4198 +assert_return(() => call($19, "load8_u", [46_565]), 0); + +// memory_copy.wast:4199 +assert_return(() => call($19, "load8_u", [46_764]), 0); + +// memory_copy.wast:4200 +assert_return(() => call($19, "load8_u", [46_963]), 0); + +// memory_copy.wast:4201 +assert_return(() => call($19, "load8_u", [47_162]), 0); + +// memory_copy.wast:4202 +assert_return(() => call($19, "load8_u", [47_361]), 0); + +// memory_copy.wast:4203 +assert_return(() => call($19, "load8_u", [47_560]), 0); + +// memory_copy.wast:4204 +assert_return(() => call($19, "load8_u", [47_759]), 0); + +// memory_copy.wast:4205 +assert_return(() => call($19, "load8_u", [47_958]), 0); + +// memory_copy.wast:4206 +assert_return(() => call($19, "load8_u", [48_157]), 0); + +// memory_copy.wast:4207 +assert_return(() => call($19, "load8_u", [48_356]), 0); + +// memory_copy.wast:4208 +assert_return(() => call($19, "load8_u", [48_555]), 0); + +// memory_copy.wast:4209 +assert_return(() => call($19, "load8_u", [48_754]), 0); + +// memory_copy.wast:4210 +assert_return(() => call($19, "load8_u", [48_953]), 0); + +// memory_copy.wast:4211 +assert_return(() => call($19, "load8_u", [49_152]), 0); + +// memory_copy.wast:4212 +assert_return(() => call($19, "load8_u", [49_351]), 0); + +// memory_copy.wast:4213 +assert_return(() => call($19, "load8_u", [49_550]), 0); + +// memory_copy.wast:4214 +assert_return(() => call($19, "load8_u", [49_749]), 0); + +// memory_copy.wast:4215 +assert_return(() => call($19, "load8_u", [49_948]), 0); + +// memory_copy.wast:4216 +assert_return(() => call($19, "load8_u", [50_147]), 0); + +// memory_copy.wast:4217 +assert_return(() => call($19, "load8_u", [50_346]), 0); + +// memory_copy.wast:4218 +assert_return(() => call($19, "load8_u", [50_545]), 0); + +// memory_copy.wast:4219 +assert_return(() => call($19, "load8_u", [50_744]), 0); + +// memory_copy.wast:4220 +assert_return(() => call($19, "load8_u", [50_943]), 0); + +// memory_copy.wast:4221 +assert_return(() => call($19, "load8_u", [51_142]), 0); + +// memory_copy.wast:4222 +assert_return(() => call($19, "load8_u", [51_341]), 0); + +// memory_copy.wast:4223 +assert_return(() => call($19, "load8_u", [51_540]), 0); + +// memory_copy.wast:4224 +assert_return(() => call($19, "load8_u", [51_739]), 0); + +// memory_copy.wast:4225 +assert_return(() => call($19, "load8_u", [51_938]), 0); + +// memory_copy.wast:4226 +assert_return(() => call($19, "load8_u", [52_137]), 0); + +// memory_copy.wast:4227 +assert_return(() => call($19, "load8_u", [52_336]), 0); + +// memory_copy.wast:4228 +assert_return(() => call($19, "load8_u", [52_535]), 0); + +// memory_copy.wast:4229 +assert_return(() => call($19, "load8_u", [52_734]), 0); + +// memory_copy.wast:4230 +assert_return(() => call($19, "load8_u", [52_933]), 0); + +// memory_copy.wast:4231 +assert_return(() => call($19, "load8_u", [53_132]), 0); + +// memory_copy.wast:4232 +assert_return(() => call($19, "load8_u", [53_331]), 0); + +// memory_copy.wast:4233 +assert_return(() => call($19, "load8_u", [53_530]), 0); + +// memory_copy.wast:4234 +assert_return(() => call($19, "load8_u", [53_729]), 0); + +// memory_copy.wast:4235 +assert_return(() => call($19, "load8_u", [53_928]), 0); + +// memory_copy.wast:4236 +assert_return(() => call($19, "load8_u", [54_127]), 0); + +// memory_copy.wast:4237 +assert_return(() => call($19, "load8_u", [54_326]), 0); + +// memory_copy.wast:4238 +assert_return(() => call($19, "load8_u", [54_525]), 0); + +// memory_copy.wast:4239 +assert_return(() => call($19, "load8_u", [54_724]), 0); + +// memory_copy.wast:4240 +assert_return(() => call($19, "load8_u", [54_923]), 0); + +// memory_copy.wast:4241 +assert_return(() => call($19, "load8_u", [55_122]), 0); + +// memory_copy.wast:4242 +assert_return(() => call($19, "load8_u", [55_321]), 0); + +// memory_copy.wast:4243 +assert_return(() => call($19, "load8_u", [55_520]), 0); + +// memory_copy.wast:4244 +assert_return(() => call($19, "load8_u", [55_719]), 0); + +// memory_copy.wast:4245 +assert_return(() => call($19, "load8_u", [55_918]), 0); + +// memory_copy.wast:4246 +assert_return(() => call($19, "load8_u", [56_117]), 0); + +// memory_copy.wast:4247 +assert_return(() => call($19, "load8_u", [56_316]), 0); + +// memory_copy.wast:4248 +assert_return(() => call($19, "load8_u", [56_515]), 0); + +// memory_copy.wast:4249 +assert_return(() => call($19, "load8_u", [56_714]), 0); + +// memory_copy.wast:4250 +assert_return(() => call($19, "load8_u", [56_913]), 0); + +// memory_copy.wast:4251 +assert_return(() => call($19, "load8_u", [57_112]), 0); + +// memory_copy.wast:4252 +assert_return(() => call($19, "load8_u", [57_311]), 0); + +// memory_copy.wast:4253 +assert_return(() => call($19, "load8_u", [57_510]), 0); + +// memory_copy.wast:4254 +assert_return(() => call($19, "load8_u", [57_709]), 0); + +// memory_copy.wast:4255 +assert_return(() => call($19, "load8_u", [57_908]), 0); + +// memory_copy.wast:4256 +assert_return(() => call($19, "load8_u", [58_107]), 0); + +// memory_copy.wast:4257 +assert_return(() => call($19, "load8_u", [58_306]), 0); + +// memory_copy.wast:4258 +assert_return(() => call($19, "load8_u", [58_505]), 0); + +// memory_copy.wast:4259 +assert_return(() => call($19, "load8_u", [58_704]), 0); + +// memory_copy.wast:4260 +assert_return(() => call($19, "load8_u", [58_903]), 0); + +// memory_copy.wast:4261 +assert_return(() => call($19, "load8_u", [59_102]), 0); + +// memory_copy.wast:4262 +assert_return(() => call($19, "load8_u", [59_301]), 0); + +// memory_copy.wast:4263 +assert_return(() => call($19, "load8_u", [59_500]), 0); + +// memory_copy.wast:4264 +assert_return(() => call($19, "load8_u", [59_699]), 0); + +// memory_copy.wast:4265 +assert_return(() => call($19, "load8_u", [59_898]), 0); + +// memory_copy.wast:4266 +assert_return(() => call($19, "load8_u", [60_097]), 0); + +// memory_copy.wast:4267 +assert_return(() => call($19, "load8_u", [60_296]), 0); + +// memory_copy.wast:4268 +assert_return(() => call($19, "load8_u", [60_495]), 0); + +// memory_copy.wast:4269 +assert_return(() => call($19, "load8_u", [60_694]), 0); + +// memory_copy.wast:4270 +assert_return(() => call($19, "load8_u", [60_893]), 0); + +// memory_copy.wast:4271 +assert_return(() => call($19, "load8_u", [61_092]), 0); + +// memory_copy.wast:4272 +assert_return(() => call($19, "load8_u", [61_291]), 0); + +// memory_copy.wast:4273 +assert_return(() => call($19, "load8_u", [61_440]), 0); + +// memory_copy.wast:4274 +assert_return(() => call($19, "load8_u", [61_441]), 1); + +// memory_copy.wast:4275 +assert_return(() => call($19, "load8_u", [61_442]), 2); + +// memory_copy.wast:4276 +assert_return(() => call($19, "load8_u", [61_443]), 3); + +// memory_copy.wast:4277 +assert_return(() => call($19, "load8_u", [61_444]), 4); + +// memory_copy.wast:4278 +assert_return(() => call($19, "load8_u", [61_445]), 5); + +// memory_copy.wast:4279 +assert_return(() => call($19, "load8_u", [61_446]), 6); + +// memory_copy.wast:4280 +assert_return(() => call($19, "load8_u", [61_447]), 7); + +// memory_copy.wast:4281 +assert_return(() => call($19, "load8_u", [61_448]), 8); + +// memory_copy.wast:4282 +assert_return(() => call($19, "load8_u", [61_449]), 9); + +// memory_copy.wast:4283 +assert_return(() => call($19, "load8_u", [61_450]), 10); + +// memory_copy.wast:4284 +assert_return(() => call($19, "load8_u", [61_451]), 11); + +// memory_copy.wast:4285 +assert_return(() => call($19, "load8_u", [61_452]), 12); + +// memory_copy.wast:4286 +assert_return(() => call($19, "load8_u", [61_453]), 13); + +// memory_copy.wast:4287 +assert_return(() => call($19, "load8_u", [61_454]), 14); + +// memory_copy.wast:4288 +assert_return(() => call($19, "load8_u", [61_455]), 15); + +// memory_copy.wast:4289 +assert_return(() => call($19, "load8_u", [61_456]), 16); + +// memory_copy.wast:4290 +assert_return(() => call($19, "load8_u", [61_457]), 17); + +// memory_copy.wast:4291 +assert_return(() => call($19, "load8_u", [61_458]), 18); + +// memory_copy.wast:4292 +assert_return(() => call($19, "load8_u", [61_459]), 19); + +// memory_copy.wast:4293 +assert_return(() => call($19, "load8_u", [61_510]), 0); + +// memory_copy.wast:4294 +assert_return(() => call($19, "load8_u", [61_709]), 0); + +// memory_copy.wast:4295 +assert_return(() => call($19, "load8_u", [61_908]), 0); + +// memory_copy.wast:4296 +assert_return(() => call($19, "load8_u", [62_107]), 0); + +// memory_copy.wast:4297 +assert_return(() => call($19, "load8_u", [62_306]), 0); + +// memory_copy.wast:4298 +assert_return(() => call($19, "load8_u", [62_505]), 0); + +// memory_copy.wast:4299 +assert_return(() => call($19, "load8_u", [62_704]), 0); + +// memory_copy.wast:4300 +assert_return(() => call($19, "load8_u", [62_903]), 0); + +// memory_copy.wast:4301 +assert_return(() => call($19, "load8_u", [63_102]), 0); + +// memory_copy.wast:4302 +assert_return(() => call($19, "load8_u", [63_301]), 0); + +// memory_copy.wast:4303 +assert_return(() => call($19, "load8_u", [63_500]), 0); + +// memory_copy.wast:4304 +assert_return(() => call($19, "load8_u", [63_699]), 0); + +// memory_copy.wast:4305 +assert_return(() => call($19, "load8_u", [63_898]), 0); + +// memory_copy.wast:4306 +assert_return(() => call($19, "load8_u", [64_097]), 0); + +// memory_copy.wast:4307 +assert_return(() => call($19, "load8_u", [64_296]), 0); + +// memory_copy.wast:4308 +assert_return(() => call($19, "load8_u", [64_495]), 0); + +// memory_copy.wast:4309 +assert_return(() => call($19, "load8_u", [64_694]), 0); + +// memory_copy.wast:4310 +assert_return(() => call($19, "load8_u", [64_893]), 0); + +// memory_copy.wast:4311 +assert_return(() => call($19, "load8_u", [65_092]), 0); + +// memory_copy.wast:4312 +assert_return(() => call($19, "load8_u", [65_291]), 0); + +// memory_copy.wast:4313 +assert_return(() => call($19, "load8_u", [65_490]), 0); + +// memory_copy.wast:4315 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4321 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4328 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4335 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4342 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4349 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4356 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4363 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4370 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4377 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4384 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4391 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4398 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4405 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4412 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4419 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4426 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4433 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4440 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4447 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4454 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4461 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4468 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4475 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4482 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4489 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4496 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4503 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4510 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4517 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4524 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4531 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4538 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4545 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4552 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4559 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4566 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4573 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4580 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4587 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4594 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4601 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4608 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4615 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4622 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4629 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4636 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4643 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4650 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4657 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4664 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4671 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4678 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4685 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4692 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4699 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4706 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4713 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4720 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4727 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4734 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4741 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4748 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4755 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4763 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\x96\x80\x80\x80\x00\x00\x41\x0a\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x09\x41\x0a\x41\x05\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4780 +run(() => call($20, "test", [])); + +// memory_copy.wast:4782 +assert_return(() => call($20, "checkRange", [0, 9, 0]), -1); + +// memory_copy.wast:4784 +assert_return(() => call($20, "checkRange", [9, 20, 85]), -1); + +// memory_copy.wast:4786 +assert_return(() => call($20, "checkRange", [20, 65_536, 0]), -1); + +// memory_copy.wast:4789 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\x96\x80\x80\x80\x00\x00\x41\x0a\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x10\x41\x0f\x41\x05\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4806 +run(() => call($21, "test", [])); + +// memory_copy.wast:4808 +assert_return(() => call($21, "checkRange", [0, 10, 0]), -1); + +// memory_copy.wast:4810 +assert_return(() => call($21, "checkRange", [10, 21, 85]), -1); + +// memory_copy.wast:4812 +assert_return(() => call($21, "checkRange", [21, 65_536, 0]), -1); + +// memory_copy.wast:4815 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\x80\x80\x02\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4819 +assert_trap(() => call($22, "test", [])); + +// memory_copy.wast:4821 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x7e\x41\x80\x80\x01\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4825 +assert_trap(() => call($23, "test", [])); + +// memory_copy.wast:4827 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x80\x80\x02\x41\x80\xfe\x03\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4831 +assert_trap(() => call($24, "test", [])); + +// memory_copy.wast:4833 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x01\x41\x80\x7e\x41\x81\x02\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4837 +assert_trap(() => call($25, "test", [])); + +// memory_copy.wast:4839 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xdc\x80\x80\x80\x00\x02\xaa\x80\x80\x80\x00\x00\x41\x00\x41\xd5\x00\x41\x80\x80\x02\xfc\x0b\x00\x41\x80\x80\x02\x41\xaa\x01\x41\x80\x80\x02\xfc\x0b\x00\x41\x80\xa0\x02\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:4857 +run(() => call($26, "test", [])); + +// memory_copy.wast:4859 +assert_return(() => call($26, "checkRange", [0, 32_768, 85]), -1); + +// memory_copy.wast:4861 +assert_return(() => call($26, "checkRange", [32_768, 65_536, 170]), -1); + +// memory_copy.wast:4863 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4867 +run(() => call($27, "test", [])); + +// memory_copy.wast:4869 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\x80\xe0\x01\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4873 +assert_trap(() => call($28, "test", [])); + +// memory_copy.wast:4875 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\xa0\x02\x41\x80\x80\x04\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4879 +run(() => call($29, "test", [])); + +// memory_copy.wast:4881 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\xa0\x02\x41\x80\x80\x08\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4885 +assert_trap(() => call($30, "test", [])); + +// memory_copy.wast:4887 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x80\x80\x04\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4891 +run(() => call($31, "test", [])); + +// memory_copy.wast:4893 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\x80\x80\x08\x41\x00\xfc\x0a\x00\x00\x0b"); + +// memory_copy.wast:4897 +assert_trap(() => call($32, "test", [])); + +// memory_copy.wast:4899 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x00\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x01\x0a\xbe\x95\x80\x80\x00\x02\x8c\x95\x80\x80\x00\x00\x41\xe7\x8a\x01\x41\x01\x41\xc0\x0a\xfc\x0b\x00\x41\xe9\xb0\x02\x41\x02\x41\x9f\x08\xfc\x0b\x00\x41\xd1\xb8\x03\x41\x03\x41\xdc\x07\xfc\x0b\x00\x41\xca\xa8\x02\x41\x04\x41\xc2\x02\xfc\x0b\x00\x41\xa9\x3e\x41\x05\x41\xca\x0f\xfc\x0b\x00\x41\xba\xb1\x01\x41\x06\x41\xdc\x17\xfc\x0b\x00\x41\xf2\x83\x01\x41\x07\x41\xc4\x12\xfc\x0b\x00\x41\xe3\xd3\x02\x41\x08\x41\xc3\x06\xfc\x0b\x00\x41\xfc\x00\x41\x09\x41\xf1\x0a\xfc\x0b\x00\x41\xd4\x10\x41\x0a\x41\xc6\x15\xfc\x0b\x00\x41\x9b\xc6\x00\x41\x0b\x41\x9a\x18\xfc\x0b\x00\x41\xe7\x9b\x03\x41\x0c\x41\xe5\x05\xfc\x0b\x00\x41\xf6\x1e\x41\x0d\x41\x87\x16\xfc\x0b\x00\x41\xb3\x84\x03\x41\x0e\x41\x80\x0a\xfc\x0b\x00\x41\xc9\x89\x03\x41\x0f\x41\xba\x0b\xfc\x0b\x00\x41\x8d\xa0\x01\x41\x10\x41\xd6\x18\xfc\x0b\x00\x41\xb1\xf4\x02\x41\x11\x41\xa0\x04\xfc\x0b\x00\x41\xa3\xe1\x00\x41\x12\x41\xed\x14\xfc\x0b\x00\x41\xa5\xc2\x01\x41\x13\x41\xdb\x14\xfc\x0b\x00\x41\x85\xe2\x02\x41\x14\x41\xa2\x0c\xfc\x0b\x00\x41\xd8\xd0\x02\x41\x15\x41\x9b\x0d\xfc\x0b\x00\x41\xde\x88\x02\x41\x16\x41\x86\x05\xfc\x0b\x00\x41\xab\xfb\x02\x41\x17\x41\xc2\x0e\xfc\x0b\x00\x41\xcd\xa1\x03\x41\x18\x41\xe1\x14\xfc\x0b\x00\x41\x9b\xed\x01\x41\x19\x41\xd5\x07\xfc\x0b\x00\x41\xd4\xc8\x00\x41\x1a\x41\x8f\x0e\xfc\x0b\x00\x41\x8e\x88\x03\x41\x1b\x41\xe7\x03\xfc\x0b\x00\x41\xa1\xea\x03\x41\x1c\x41\x92\x04\xfc\x0b\x00\x41\xdc\x9b\x02\x41\x1d\x41\xaf\x07\xfc\x0b\x00\x41\xf0\x34\x41\x1e\x41\xfd\x02\xfc\x0b\x00\x41\xbe\x90\x03\x41\x1f\x41\x91\x18\xfc\x0b\x00\x41\xc1\x84\x03\x41\x20\x41\x92\x05\xfc\x0b\x00\x41\xfc\xdb\x02\x41\x21\x41\xa6\x0d\xfc\x0b\x00\x41\xbe\x84\x02\x41\x22\x41\xc4\x08\xfc\x0b\x00\x41\xfe\x8c\x03\x41\x23\x41\x82\x0b\xfc\x0b\x00\x41\xea\xf3\x02\x41\x24\x41\x9c\x11\xfc\x0b\x00\x41\xeb\xa6\x03\x41\x25\x41\xda\x12\xfc\x0b\x00\x41\x8f\xaf\x03\x41\x26\x41\xfa\x01\xfc\x0b\x00\x41\xdc\xb0\x01\x41\x27\x41\xb1\x10\xfc\x0b\x00\x41\xec\x85\x01\x41\x28\x41\xc0\x19\xfc\x0b\x00\x41\xbb\xa8\x03\x41\x29\x41\xe3\x19\xfc\x0b\x00\x41\xb2\xb4\x02\x41\x2a\x41\xec\x15\xfc\x0b\x00\x41\xbc\x9a\x02\x41\x2b\x41\x96\x10\xfc\x0b\x00\x41\xec\x93\x02\x41\x2c\x41\xcb\x15\xfc\x0b\x00\x41\xdb\xff\x01\x41\x2d\x41\xb8\x02\xfc\x0b\x00\x41\x82\xf2\x03\x41\x2e\x41\xc0\x01\xfc\x0b\x00\x41\xfe\xf1\x01\x41\x2f\x41\xd4\x04\xfc\x0b\x00\x41\xfb\x81\x01\x41\x30\x41\xf5\x03\xfc\x0b\x00\x41\xaa\xbd\x03\x41\x31\x41\xae\x05\xfc\x0b\x00\x41\xfb\x8b\x02\x41\x32\x41\x81\x03\xfc\x0b\x00\x41\xd1\xdb\x03\x41\x33\x41\x87\x07\xfc\x0b\x00\x41\x85\xe0\x03\x41\x34\x41\xd6\x12\xfc\x0b\x00\x41\xfc\xee\x02\x41\x35\x41\xa1\x0b\xfc\x0b\x00\x41\xf5\xca\x01\x41\x36\x41\xda\x18\xfc\x0b\x00\x41\xbe\x2b\x41\x37\x41\xd7\x10\xfc\x0b\x00\x41\x89\x99\x02\x41\x38\x41\x87\x04\xfc\x0b\x00\x41\xdc\xde\x02\x41\x39\x41\xd0\x19\xfc\x0b\x00\x41\xa8\xed\x02\x41\x3a\x41\x8e\x0d\xfc\x0b\x00\x41\x8f\xec\x02\x41\x3b\x41\xe0\x18\xfc\x0b\x00\x41\xb1\xaf\x01\x41\x3c\x41\xa1\x0b\xfc\x0b\x00\x41\xf1\xc9\x03\x41\x3d\x41\x97\x05\xfc\x0b\x00\x41\x85\xfc\x01\x41\x3e\x41\x87\x0d\xfc\x0b\x00\x41\xf7\x17\x41\x3f\x41\xd1\x05\xfc\x0b\x00\x41\xe9\x89\x02\x41\xc0\x00\x41\xd4\x00\xfc\x0b\x00\x41\xba\x84\x02\x41\xc1\x00\x41\xed\x0f\xfc\x0b\x00\x41\xca\x9f\x02\x41\xc2\x00\x41\x1d\xfc\x0b\x00\x41\xcb\x95\x01\x41\xc3\x00\x41\xda\x17\xfc\x0b\x00\x41\xc8\xe2\x00\x41\xc4\x00\x41\x93\x08\xfc\x0b\x00\x41\xe4\x8e\x01\x41\xc5\x00\x41\xfc\x19\xfc\x0b\x00\x41\x9f\x24\x41\xc6\x00\x41\xc3\x08\xfc\x0b\x00\x41\x9e\xfe\x00\x41\xc7\x00\x41\xcd\x0f\xfc\x0b\x00\x41\x9c\x8e\x01\x41\xc8\x00\x41\xd3\x11\xfc\x0b\x00\x41\xe4\x8a\x03\x41\xc9\x00\x41\xf5\x18\xfc\x0b\x00\x41\x94\xd6\x00\x41\xca\x00\x41\xb0\x0f\xfc\x0b\x00\x41\xda\xfc\x00\x41\xcb\x00\x41\xaf\x0b\xfc\x0b\x00\x41\xde\xe2\x02\x41\xcc\x00\x41\x99\x09\xfc\x0b\x00\x41\xf9\xa6\x03\x41\xcd\x00\x41\xa0\x0c\xfc\x0b\x00\x41\xbb\x82\x02\x41\xce\x00\x41\xea\x0c\xfc\x0b\x00\x41\xe4\xdc\x03\x41\xcf\x00\x41\xd4\x19\xfc\x0b\x00\x41\x91\x94\x03\x41\xd0\x00\x41\xdf\x01\xfc\x0b\x00\x41\x89\x22\x41\xd1\x00\x41\xfb\x10\xfc\x0b\x00\x41\xaa\xc1\x03\x41\xd2\x00\x41\xaa\x0a\xfc\x0b\x00\x41\xac\xb3\x03\x41\xd3\x00\x41\xd8\x14\xfc\x0b\x00\x41\x9b\xbc\x01\x41\xd4\x00\x41\x95\x08\xfc\x0b\x00\x41\xaf\xd1\x02\x41\xd5\x00\x41\x99\x18\xfc\x0b\x00\x41\xb3\xfc\x01\x41\xd6\x00\x41\xec\x15\xfc\x0b\x00\x41\xe3\x1d\x41\xd7\x00\x41\xda\x0f\xfc\x0b\x00\x41\xc8\xac\x03\x41\xd8\x00\x41\x00\xfc\x0b\x00\x41\x95\x86\x03\x41\xd9\x00\x41\x95\x10\xfc\x0b\x00\x41\xbb\x9f\x01\x41\xda\x00\x41\xd0\x16\xfc\x0b\x00\x41\xa2\x88\x02\x41\xdb\x00\x41\xc0\x01\xfc\x0b\x00\x41\xba\xc9\x00\x41\xdc\x00\x41\x93\x11\xfc\x0b\x00\x41\xfd\xe0\x00\x41\xdd\x00\x41\x18\xfc\x0b\x00\x41\x8b\xee\x00\x41\xde\x00\x41\xc1\x04\xfc\x0b\x00\x41\x9a\xd8\x02\x41\xdf\x00\x41\xa9\x10\xfc\x0b\x00\x41\xff\x9e\x02\x41\xe0\x00\x41\xec\x1a\xfc\x0b\x00\x41\xf8\xb5\x01\x41\xe1\x00\x41\xcd\x15\xfc\x0b\x00\x41\xf8\x31\x41\xe2\x00\x41\xbe\x06\xfc\x0b\x00\x41\x9b\x84\x02\x41\xe3\x00\x41\x92\x0f\xfc\x0b\x00\x41\xb5\xab\x01\x41\xe4\x00\x41\xbe\x15\xfc\x0b\x00\x41\xce\xce\x03\x41\xe8\xa7\x03\x41\xb2\x10\xfc\x0a\x00\x00\x41\xb2\xec\x03\x41\xb8\xb2\x02\x41\xe6\x01\xfc\x0a\x00\x00\x41\xf9\x94\x03\x41\xcd\xb8\x01\x41\xfc\x11\xfc\x0a\x00\x00\x41\xb4\x34\x41\xbc\xbb\x01\x41\xff\x04\xfc\x0a\x00\x00\x41\xce\x36\x41\xf7\x84\x02\x41\xc9\x08\xfc\x0a\x00\x00\x41\xcb\x97\x01\x41\xec\xd0\x00\x41\xfd\x18\xfc\x0a\x00\x00\x41\xac\xd5\x01\x41\x86\xa9\x03\x41\xe4\x00\xfc\x0a\x00\x00\x41\xd5\xd4\x01\x41\xa2\xd5\x02\x41\xb5\x0d\xfc\x0a\x00\x00\x41\xf0\xd8\x03\x41\xb5\xc3\x00\x41\xf7\x00\xfc\x0a\x00\x00\x41\xbb\x2e\x41\x84\x12\x41\x92\x05\xfc\x0a\x00\x00\x41\xb3\x25\x41\xaf\x93\x03\x41\xdd\x11\xfc\x0a\x00\x00\x41\xc9\xe2\x00\x41\xfd\x95\x01\x41\xc1\x06\xfc\x0a\x00\x00\x41\xce\xdc\x00\x41\xa9\xeb\x02\x41\xe4\x19\xfc\x0a\x00\x00\x41\xf0\xd8\x00\x41\xd4\xdf\x02\x41\xe9\x11\xfc\x0a\x00\x00\x41\x8a\x8b\x02\x41\xa9\x34\x41\x8c\x14\xfc\x0a\x00\x00\x41\xc8\x26\x41\x9a\x0d\x41\xb0\x0a\xfc\x0a\x00\x00\x41\xbc\xed\x03\x41\xd5\x3b\x41\x86\x0d\xfc\x0a\x00\x00\x41\x98\xdc\x02\x41\xa8\x8f\x01\x41\x21\xfc\x0a\x00\x00\x41\x8e\xd7\x02\x41\xcc\xae\x01\x41\x93\x0b\xfc\x0a\x00\x00\x41\xad\xec\x02\x41\x9b\x85\x03\x41\x9a\x0b\xfc\x0a\x00\x00\x41\xc4\xf1\x03\x41\xb3\xc4\x00\x41\xc2\x06\xfc\x0a\x00\x00\x41\xcd\x85\x02\x41\xa3\x9d\x01\x41\xf5\x19\xfc\x0a\x00\x00\x41\xff\xbc\x02\x41\xad\xa8\x03\x41\x81\x19\xfc\x0a\x00\x00\x41\xd4\xc9\x01\x41\xf6\xce\x03\x41\x94\x13\xfc\x0a\x00\x00\x41\xde\x99\x01\x41\xb2\xbc\x03\x41\xda\x02\xfc\x0a\x00\x00\x41\xec\xfb\x00\x41\xca\x98\x02\x41\xfe\x12\xfc\x0a\x00\x00\x41\xb0\xdc\x00\x41\xf6\x95\x02\x41\xac\x02\xfc\x0a\x00\x00\x41\xa3\xd0\x03\x41\x85\xed\x00\x41\xd1\x18\xfc\x0a\x00\x00\x41\xfb\x8b\x02\x41\xb2\xd9\x03\x41\x81\x0a\xfc\x0a\x00\x00\x41\x84\xc6\x00\x41\xf4\xdf\x00\x41\xaf\x07\xfc\x0a\x00\x00\x41\x8b\x16\x41\xb9\xd1\x00\x41\xdf\x0e\xfc\x0a\x00\x00\x41\xba\xd1\x02\x41\x86\xd7\x02\x41\xe2\x05\xfc\x0a\x00\x00\x41\xbe\xec\x03\x41\x85\x94\x01\x41\xfa\x00\xfc\x0a\x00\x00\x41\xec\xbb\x01\x41\xd9\xdd\x02\x41\xdb\x0d\xfc\x0a\x00\x00\x41\xd0\xb0\x01\x41\xa3\xf3\x00\x41\xbe\x05\xfc\x0a\x00\x00\x41\x94\xd8\x00\x41\xd3\xcf\x01\x41\xa6\x0e\xfc\x0a\x00\x00\x41\xb4\xb4\x01\x41\xf7\x9f\x01\x41\xa8\x08\xfc\x0a\x00\x00\x41\xa0\xbf\x03\x41\xf2\xab\x03\x41\xc7\x14\xfc\x0a\x00\x00\x41\x94\xc7\x01\x41\x81\x08\x41\xa9\x18\xfc\x0a\x00\x00\x41\xb4\x83\x03\x41\xbc\xd9\x02\x41\xcf\x07\xfc\x0a\x00\x00\x41\xf8\xdc\x01\x41\xfa\xc5\x02\x41\xa0\x12\xfc\x0a\x00\x00\x41\xe9\xde\x03\x41\xe6\x01\x41\xb8\x16\xfc\x0a\x00\x00\x41\xd0\xaf\x01\x41\x9a\x9a\x03\x41\x95\x11\xfc\x0a\x00\x00\x41\xe9\xbc\x02\x41\xea\xca\x00\x41\xa6\x0f\xfc\x0a\x00\x00\x41\xcc\xe2\x01\x41\xfe\xa2\x01\x41\x8a\x11\xfc\x0a\x00\x00\x41\xa5\x9e\x03\x41\xb3\xd7\x02\x41\x8d\x08\xfc\x0a\x00\x00\x41\x84\xc7\x01\x41\xd3\x96\x02\x41\xf2\x0c\xfc\x0a\x00\x00\x41\x94\xc9\x03\x41\xfb\xe5\x02\x41\xc2\x0f\xfc\x0a\x00\x00\x41\x99\xab\x02\x41\x90\x2d\x41\xa3\x0f\xfc\x0a\x00\x00\x41\xd7\xde\x01\x41\xc4\xb0\x03\x41\xc0\x12\xfc\x0a\x00\x00\x41\x9b\xe9\x03\x41\xbc\x8d\x01\x41\xcc\x0a\xfc\x0a\x00\x00\x41\xe5\x87\x03\x41\xa5\xec\x00\x41\xfe\x02\xfc\x0a\x00\x00\x41\x88\x84\x01\x41\xf5\x9b\x02\x41\xec\x0e\xfc\x0a\x00\x00\x41\xe2\xf7\x02\x41\xde\xd8\x00\x41\xf7\x15\xfc\x0a\x00\x00\x41\xe0\xde\x01\x41\xaa\xbb\x02\x41\xc3\x02\xfc\x0a\x00\x00\x41\xb2\x95\x02\x41\xd0\xd9\x01\x41\x86\x0d\xfc\x0a\x00\x00\x41\xfa\xeb\x03\x41\xd4\xa0\x03\x41\xbd\x0a\xfc\x0a\x00\x00\x41\xb5\xee\x00\x41\xe8\xe9\x02\x41\x84\x05\xfc\x0a\x00\x00\x41\xe6\xe2\x01\x41\x82\x95\x01\x41\xf0\x03\xfc\x0a\x00\x00\x41\x98\xdf\x02\x41\xd9\xf3\x02\x41\xe0\x15\xfc\x0a\x00\x00\x41\x87\xb5\x02\x41\xf5\xdc\x02\x41\xc6\x0a\xfc\x0a\x00\x00\x41\xf0\xd0\x00\x41\xda\xe4\x01\x41\xc3\x0b\xfc\x0a\x00\x00\x41\xbf\xee\x02\x41\xe2\xe8\x02\x41\xbb\x0b\xfc\x0a\x00\x00\x41\xa9\x26\x41\xc4\xe0\x01\x41\xe7\x0e\xfc\x0a\x00\x00\x41\xfc\xa8\x02\x41\xa5\xbf\x03\x41\xd7\x0d\xfc\x0a\x00\x00\x41\xce\xce\x01\x41\xd7\xd4\x01\x41\xe7\x08\xfc\x0a\x00\x00\x41\xd3\xcb\x03\x41\xd1\xc0\x01\x41\xa7\x08\xfc\x0a\x00\x00\x41\xac\xdf\x03\x41\x86\xaf\x02\x41\xfe\x05\xfc\x0a\x00\x00\x41\x80\xd9\x02\x41\xec\x11\x41\xf0\x0b\xfc\x0a\x00\x00\x41\xe4\xff\x01\x41\x85\xf1\x02\x41\xc6\x17\xfc\x0a\x00\x00\x41\x8c\xd7\x00\x41\x8c\xa6\x01\x41\xf3\x07\xfc\x0a\x00\x00\x41\xf1\x3b\x41\xfc\xf6\x01\x41\xda\x17\xfc\x0a\x00\x00\x41\xfc\x8c\x01\x41\xbb\xe5\x00\x41\xf8\x19\xfc\x0a\x00\x00\x41\xda\xbf\x03\x41\xe1\xb4\x03\x41\xb4\x02\xfc\x0a\x00\x00\x41\xe3\xc0\x01\x41\xaf\x83\x01\x41\x83\x09\xfc\x0a\x00\x00\x41\xbc\x9b\x01\x41\x83\xcf\x00\x41\xd2\x05\xfc\x0a\x00\x00\x41\xe9\x16\x41\xaf\x2e\x41\xc2\x12\xfc\x0a\x00\x00\x41\xff\xfb\x01\x41\xaf\x87\x03\x41\xee\x16\xfc\x0a\x00\x00\x41\x96\xf6\x00\x41\x93\x87\x01\x41\xaf\x14\xfc\x0a\x00\x00\x41\x87\xe4\x02\x41\x9f\xde\x01\x41\xfd\x0f\xfc\x0a\x00\x00\x41\xed\xae\x03\x41\x91\x9a\x02\x41\xa4\x14\xfc\x0a\x00\x00\x41\xad\xde\x01\x41\x8d\xa7\x03\x41\x90\x09\xfc\x0a\x00\x00\x41\xcf\xf6\x02\x41\x89\xa1\x03\x41\xc1\x18\xfc\x0a\x00\x00\x41\xb6\xef\x01\x41\xe3\xe0\x02\x41\xd9\x14\xfc\x0a\x00\x00\x41\xc1\x27\x41\xc7\x21\x41\x34\xfc\x0a\x00\x00\x41\xa4\x34\x41\x83\xbd\x01\x41\xb9\x03\xfc\x0a\x00\x00\x41\xd8\x81\x02\x41\xed\xd3\x01\x41\xf5\x1a\xfc\x0a\x00\x00\x41\x92\xfe\x01\x41\xec\xcf\x03\x41\xe1\x15\xfc\x0a\x00\x00\x41\xb9\x8c\x02\x41\x82\xc6\x00\x41\xe6\x12\xfc\x0a\x00\x00\x41\xe5\x8b\x01\x41\x8a\xaa\x03\x41\xb5\x1a\xfc\x0a\x00\x00\x41\x9d\xb1\x01\x41\xf7\xd8\x02\x41\x88\x01\xfc\x0a\x00\x00\x41\xd1\xcd\x03\x41\xa5\x37\x41\x95\x08\xfc\x0a\x00\x00\x41\xc1\xcf\x02\x41\xf4\xad\x03\x41\xd5\x12\xfc\x0a\x00\x00\x41\x95\xdd\x02\x41\xaa\x9d\x01\x41\xed\x06\xfc\x0a\x00\x00\x41\xca\x9f\x02\x41\xec\xc4\x01\x41\xf7\x1a\xfc\x0a\x00\x00\x41\xae\xe5\x02\x41\x90\xf9\x01\x41\xd6\x06\xfc\x0a\x00\x00\x41\xac\xbd\x01\x41\xfa\xf8\x01\x41\xe1\x0a\xfc\x0a\x00\x00\x41\xf2\x87\x02\x41\xb4\x05\x41\xba\x0c\xfc\x0a\x00\x00\x41\xca\xd9\x03\x41\x99\x91\x01\x41\xab\x17\xfc\x0a\x00\x00\x41\xc2\x89\x03\x41\xb7\xc2\x02\x41\xfe\x0a\xfc\x0a\x00\x00\x0b\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b"); + +// memory_copy.wast:5115 +run(() => call($33, "test", [])); + +// memory_copy.wast:5117 +assert_return(() => call($33, "checkRange", [0, 124, 0]), -1); + +// memory_copy.wast:5119 +assert_return(() => call($33, "checkRange", [124, 1_517, 9]), -1); + +// memory_copy.wast:5121 +assert_return(() => call($33, "checkRange", [1_517, 2_132, 0]), -1); + +// memory_copy.wast:5123 +assert_return(() => call($33, "checkRange", [2_132, 2_827, 10]), -1); + +// memory_copy.wast:5125 +assert_return(() => call($33, "checkRange", [2_827, 2_921, 92]), -1); + +// memory_copy.wast:5127 +assert_return(() => call($33, "checkRange", [2_921, 3_538, 83]), -1); + +// memory_copy.wast:5129 +assert_return(() => call($33, "checkRange", [3_538, 3_786, 77]), -1); + +// memory_copy.wast:5131 +assert_return(() => call($33, "checkRange", [3_786, 4_042, 97]), -1); + +// memory_copy.wast:5133 +assert_return(() => call($33, "checkRange", [4_042, 4_651, 99]), -1); + +// memory_copy.wast:5135 +assert_return(() => call($33, "checkRange", [4_651, 5_057, 0]), -1); + +// memory_copy.wast:5137 +assert_return(() => call($33, "checkRange", [5_057, 5_109, 99]), -1); + +// memory_copy.wast:5139 +assert_return(() => call($33, "checkRange", [5_109, 5_291, 0]), -1); + +// memory_copy.wast:5141 +assert_return(() => call($33, "checkRange", [5_291, 5_524, 72]), -1); + +// memory_copy.wast:5143 +assert_return(() => call($33, "checkRange", [5_524, 5_691, 92]), -1); + +// memory_copy.wast:5145 +assert_return(() => call($33, "checkRange", [5_691, 6_552, 83]), -1); + +// memory_copy.wast:5147 +assert_return(() => call($33, "checkRange", [6_552, 7_133, 77]), -1); + +// memory_copy.wast:5149 +assert_return(() => call($33, "checkRange", [7_133, 7_665, 99]), -1); + +// memory_copy.wast:5151 +assert_return(() => call($33, "checkRange", [7_665, 8_314, 0]), -1); + +// memory_copy.wast:5153 +assert_return(() => call($33, "checkRange", [8_314, 8_360, 62]), -1); + +// memory_copy.wast:5155 +assert_return(() => call($33, "checkRange", [8_360, 8_793, 86]), -1); + +// memory_copy.wast:5157 +assert_return(() => call($33, "checkRange", [8_793, 8_979, 83]), -1); + +// memory_copy.wast:5159 +assert_return(() => call($33, "checkRange", [8_979, 9_373, 79]), -1); + +// memory_copy.wast:5161 +assert_return(() => call($33, "checkRange", [9_373, 9_518, 95]), -1); + +// memory_copy.wast:5163 +assert_return(() => call($33, "checkRange", [9_518, 9_934, 59]), -1); + +// memory_copy.wast:5165 +assert_return(() => call($33, "checkRange", [9_934, 10_087, 77]), -1); + +// memory_copy.wast:5167 +assert_return(() => call($33, "checkRange", [10_087, 10_206, 5]), -1); + +// memory_copy.wast:5169 +assert_return(() => call($33, "checkRange", [10_206, 10_230, 77]), -1); + +// memory_copy.wast:5171 +assert_return(() => call($33, "checkRange", [10_230, 10_249, 41]), -1); + +// memory_copy.wast:5173 +assert_return(() => call($33, "checkRange", [10_249, 11_148, 83]), -1); + +// memory_copy.wast:5175 +assert_return(() => call($33, "checkRange", [11_148, 11_356, 74]), -1); + +// memory_copy.wast:5177 +assert_return(() => call($33, "checkRange", [11_356, 11_380, 93]), -1); + +// memory_copy.wast:5179 +assert_return(() => call($33, "checkRange", [11_380, 11_939, 74]), -1); + +// memory_copy.wast:5181 +assert_return(() => call($33, "checkRange", [11_939, 12_159, 68]), -1); + +// memory_copy.wast:5183 +assert_return(() => call($33, "checkRange", [12_159, 12_575, 83]), -1); + +// memory_copy.wast:5185 +assert_return(() => call($33, "checkRange", [12_575, 12_969, 79]), -1); + +// memory_copy.wast:5187 +assert_return(() => call($33, "checkRange", [12_969, 13_114, 95]), -1); + +// memory_copy.wast:5189 +assert_return(() => call($33, "checkRange", [13_114, 14_133, 59]), -1); + +// memory_copy.wast:5191 +assert_return(() => call($33, "checkRange", [14_133, 14_404, 76]), -1); + +// memory_copy.wast:5193 +assert_return(() => call($33, "checkRange", [14_404, 14_428, 57]), -1); + +// memory_copy.wast:5195 +assert_return(() => call($33, "checkRange", [14_428, 14_458, 59]), -1); + +// memory_copy.wast:5197 +assert_return(() => call($33, "checkRange", [14_458, 14_580, 32]), -1); + +// memory_copy.wast:5199 +assert_return(() => call($33, "checkRange", [14_580, 14_777, 89]), -1); + +// memory_copy.wast:5201 +assert_return(() => call($33, "checkRange", [14_777, 15_124, 59]), -1); + +// memory_copy.wast:5203 +assert_return(() => call($33, "checkRange", [15_124, 15_126, 36]), -1); + +// memory_copy.wast:5205 +assert_return(() => call($33, "checkRange", [15_126, 15_192, 100]), -1); + +// memory_copy.wast:5207 +assert_return(() => call($33, "checkRange", [15_192, 15_871, 96]), -1); + +// memory_copy.wast:5209 +assert_return(() => call($33, "checkRange", [15_871, 15_998, 95]), -1); + +// memory_copy.wast:5211 +assert_return(() => call($33, "checkRange", [15_998, 17_017, 59]), -1); + +// memory_copy.wast:5213 +assert_return(() => call($33, "checkRange", [17_017, 17_288, 76]), -1); + +// memory_copy.wast:5215 +assert_return(() => call($33, "checkRange", [17_288, 17_312, 57]), -1); + +// memory_copy.wast:5217 +assert_return(() => call($33, "checkRange", [17_312, 17_342, 59]), -1); + +// memory_copy.wast:5219 +assert_return(() => call($33, "checkRange", [17_342, 17_464, 32]), -1); + +// memory_copy.wast:5221 +assert_return(() => call($33, "checkRange", [17_464, 17_661, 89]), -1); + +// memory_copy.wast:5223 +assert_return(() => call($33, "checkRange", [17_661, 17_727, 59]), -1); + +// memory_copy.wast:5225 +assert_return(() => call($33, "checkRange", [17_727, 17_733, 5]), -1); + +// memory_copy.wast:5227 +assert_return(() => call($33, "checkRange", [17_733, 17_893, 96]), -1); + +// memory_copy.wast:5229 +assert_return(() => call($33, "checkRange", [17_893, 18_553, 77]), -1); + +// memory_copy.wast:5231 +assert_return(() => call($33, "checkRange", [18_553, 18_744, 42]), -1); + +// memory_copy.wast:5233 +assert_return(() => call($33, "checkRange", [18_744, 18_801, 76]), -1); + +// memory_copy.wast:5235 +assert_return(() => call($33, "checkRange", [18_801, 18_825, 57]), -1); + +// memory_copy.wast:5237 +assert_return(() => call($33, "checkRange", [18_825, 18_876, 59]), -1); + +// memory_copy.wast:5239 +assert_return(() => call($33, "checkRange", [18_876, 18_885, 77]), -1); + +// memory_copy.wast:5241 +assert_return(() => call($33, "checkRange", [18_885, 18_904, 41]), -1); + +// memory_copy.wast:5243 +assert_return(() => call($33, "checkRange", [18_904, 19_567, 83]), -1); + +// memory_copy.wast:5245 +assert_return(() => call($33, "checkRange", [19_567, 20_403, 96]), -1); + +// memory_copy.wast:5247 +assert_return(() => call($33, "checkRange", [20_403, 21_274, 77]), -1); + +// memory_copy.wast:5249 +assert_return(() => call($33, "checkRange", [21_274, 21_364, 100]), -1); + +// memory_copy.wast:5251 +assert_return(() => call($33, "checkRange", [21_364, 21_468, 74]), -1); + +// memory_copy.wast:5253 +assert_return(() => call($33, "checkRange", [21_468, 21_492, 93]), -1); + +// memory_copy.wast:5255 +assert_return(() => call($33, "checkRange", [21_492, 22_051, 74]), -1); + +// memory_copy.wast:5257 +assert_return(() => call($33, "checkRange", [22_051, 22_480, 68]), -1); + +// memory_copy.wast:5259 +assert_return(() => call($33, "checkRange", [22_480, 22_685, 100]), -1); + +// memory_copy.wast:5261 +assert_return(() => call($33, "checkRange", [22_685, 22_694, 68]), -1); + +// memory_copy.wast:5263 +assert_return(() => call($33, "checkRange", [22_694, 22_821, 10]), -1); + +// memory_copy.wast:5265 +assert_return(() => call($33, "checkRange", [22_821, 22_869, 100]), -1); + +// memory_copy.wast:5267 +assert_return(() => call($33, "checkRange", [22_869, 24_107, 97]), -1); + +// memory_copy.wast:5269 +assert_return(() => call($33, "checkRange", [24_107, 24_111, 37]), -1); + +// memory_copy.wast:5271 +assert_return(() => call($33, "checkRange", [24_111, 24_236, 77]), -1); + +// memory_copy.wast:5273 +assert_return(() => call($33, "checkRange", [24_236, 24_348, 72]), -1); + +// memory_copy.wast:5275 +assert_return(() => call($33, "checkRange", [24_348, 24_515, 92]), -1); + +// memory_copy.wast:5277 +assert_return(() => call($33, "checkRange", [24_515, 24_900, 83]), -1); + +// memory_copy.wast:5279 +assert_return(() => call($33, "checkRange", [24_900, 25_136, 95]), -1); + +// memory_copy.wast:5281 +assert_return(() => call($33, "checkRange", [25_136, 25_182, 85]), -1); + +// memory_copy.wast:5283 +assert_return(() => call($33, "checkRange", [25_182, 25_426, 68]), -1); + +// memory_copy.wast:5285 +assert_return(() => call($33, "checkRange", [25_426, 25_613, 89]), -1); + +// memory_copy.wast:5287 +assert_return(() => call($33, "checkRange", [25_613, 25_830, 96]), -1); + +// memory_copy.wast:5289 +assert_return(() => call($33, "checkRange", [25_830, 26_446, 100]), -1); + +// memory_copy.wast:5291 +assert_return(() => call($33, "checkRange", [26_446, 26_517, 10]), -1); + +// memory_copy.wast:5293 +assert_return(() => call($33, "checkRange", [26_517, 27_468, 92]), -1); + +// memory_copy.wast:5295 +assert_return(() => call($33, "checkRange", [27_468, 27_503, 95]), -1); + +// memory_copy.wast:5297 +assert_return(() => call($33, "checkRange", [27_503, 27_573, 77]), -1); + +// memory_copy.wast:5299 +assert_return(() => call($33, "checkRange", [27_573, 28_245, 92]), -1); + +// memory_copy.wast:5301 +assert_return(() => call($33, "checkRange", [28_245, 28_280, 95]), -1); + +// memory_copy.wast:5303 +assert_return(() => call($33, "checkRange", [28_280, 29_502, 77]), -1); + +// memory_copy.wast:5305 +assert_return(() => call($33, "checkRange", [29_502, 29_629, 42]), -1); + +// memory_copy.wast:5307 +assert_return(() => call($33, "checkRange", [29_629, 30_387, 83]), -1); + +// memory_copy.wast:5309 +assert_return(() => call($33, "checkRange", [30_387, 30_646, 77]), -1); + +// memory_copy.wast:5311 +assert_return(() => call($33, "checkRange", [30_646, 31_066, 92]), -1); + +// memory_copy.wast:5313 +assert_return(() => call($33, "checkRange", [31_066, 31_131, 77]), -1); + +// memory_copy.wast:5315 +assert_return(() => call($33, "checkRange", [31_131, 31_322, 42]), -1); + +// memory_copy.wast:5317 +assert_return(() => call($33, "checkRange", [31_322, 31_379, 76]), -1); + +// memory_copy.wast:5319 +assert_return(() => call($33, "checkRange", [31_379, 31_403, 57]), -1); + +// memory_copy.wast:5321 +assert_return(() => call($33, "checkRange", [31_403, 31_454, 59]), -1); + +// memory_copy.wast:5323 +assert_return(() => call($33, "checkRange", [31_454, 31_463, 77]), -1); + +// memory_copy.wast:5325 +assert_return(() => call($33, "checkRange", [31_463, 31_482, 41]), -1); + +// memory_copy.wast:5327 +assert_return(() => call($33, "checkRange", [31_482, 31_649, 83]), -1); + +// memory_copy.wast:5329 +assert_return(() => call($33, "checkRange", [31_649, 31_978, 72]), -1); + +// memory_copy.wast:5331 +assert_return(() => call($33, "checkRange", [31_978, 32_145, 92]), -1); + +// memory_copy.wast:5333 +assert_return(() => call($33, "checkRange", [32_145, 32_530, 83]), -1); + +// memory_copy.wast:5335 +assert_return(() => call($33, "checkRange", [32_530, 32_766, 95]), -1); + +// memory_copy.wast:5337 +assert_return(() => call($33, "checkRange", [32_766, 32_812, 85]), -1); + +// memory_copy.wast:5339 +assert_return(() => call($33, "checkRange", [32_812, 33_056, 68]), -1); + +// memory_copy.wast:5341 +assert_return(() => call($33, "checkRange", [33_056, 33_660, 89]), -1); + +// memory_copy.wast:5343 +assert_return(() => call($33, "checkRange", [33_660, 33_752, 59]), -1); + +// memory_copy.wast:5345 +assert_return(() => call($33, "checkRange", [33_752, 33_775, 36]), -1); + +// memory_copy.wast:5347 +assert_return(() => call($33, "checkRange", [33_775, 33_778, 32]), -1); + +// memory_copy.wast:5349 +assert_return(() => call($33, "checkRange", [33_778, 34_603, 9]), -1); + +// memory_copy.wast:5351 +assert_return(() => call($33, "checkRange", [34_603, 35_218, 0]), -1); + +// memory_copy.wast:5353 +assert_return(() => call($33, "checkRange", [35_218, 35_372, 10]), -1); + +// memory_copy.wast:5355 +assert_return(() => call($33, "checkRange", [35_372, 35_486, 77]), -1); + +// memory_copy.wast:5357 +assert_return(() => call($33, "checkRange", [35_486, 35_605, 5]), -1); + +// memory_copy.wast:5359 +assert_return(() => call($33, "checkRange", [35_605, 35_629, 77]), -1); + +// memory_copy.wast:5361 +assert_return(() => call($33, "checkRange", [35_629, 35_648, 41]), -1); + +// memory_copy.wast:5363 +assert_return(() => call($33, "checkRange", [35_648, 36_547, 83]), -1); + +// memory_copy.wast:5365 +assert_return(() => call($33, "checkRange", [36_547, 36_755, 74]), -1); + +// memory_copy.wast:5367 +assert_return(() => call($33, "checkRange", [36_755, 36_767, 93]), -1); + +// memory_copy.wast:5369 +assert_return(() => call($33, "checkRange", [36_767, 36_810, 83]), -1); + +// memory_copy.wast:5371 +assert_return(() => call($33, "checkRange", [36_810, 36_839, 100]), -1); + +// memory_copy.wast:5373 +assert_return(() => call($33, "checkRange", [36_839, 37_444, 96]), -1); + +// memory_copy.wast:5375 +assert_return(() => call($33, "checkRange", [37_444, 38_060, 100]), -1); + +// memory_copy.wast:5377 +assert_return(() => call($33, "checkRange", [38_060, 38_131, 10]), -1); + +// memory_copy.wast:5379 +assert_return(() => call($33, "checkRange", [38_131, 39_082, 92]), -1); + +// memory_copy.wast:5381 +assert_return(() => call($33, "checkRange", [39_082, 39_117, 95]), -1); + +// memory_copy.wast:5383 +assert_return(() => call($33, "checkRange", [39_117, 39_187, 77]), -1); + +// memory_copy.wast:5385 +assert_return(() => call($33, "checkRange", [39_187, 39_859, 92]), -1); + +// memory_copy.wast:5387 +assert_return(() => call($33, "checkRange", [39_859, 39_894, 95]), -1); + +// memory_copy.wast:5389 +assert_return(() => call($33, "checkRange", [39_894, 40_257, 77]), -1); + +// memory_copy.wast:5391 +assert_return(() => call($33, "checkRange", [40_257, 40_344, 89]), -1); + +// memory_copy.wast:5393 +assert_return(() => call($33, "checkRange", [40_344, 40_371, 59]), -1); + +// memory_copy.wast:5395 +assert_return(() => call($33, "checkRange", [40_371, 40_804, 77]), -1); + +// memory_copy.wast:5397 +assert_return(() => call($33, "checkRange", [40_804, 40_909, 5]), -1); + +// memory_copy.wast:5399 +assert_return(() => call($33, "checkRange", [40_909, 42_259, 92]), -1); + +// memory_copy.wast:5401 +assert_return(() => call($33, "checkRange", [42_259, 42_511, 77]), -1); + +// memory_copy.wast:5403 +assert_return(() => call($33, "checkRange", [42_511, 42_945, 83]), -1); + +// memory_copy.wast:5405 +assert_return(() => call($33, "checkRange", [42_945, 43_115, 77]), -1); + +// memory_copy.wast:5407 +assert_return(() => call($33, "checkRange", [43_115, 43_306, 42]), -1); + +// memory_copy.wast:5409 +assert_return(() => call($33, "checkRange", [43_306, 43_363, 76]), -1); + +// memory_copy.wast:5411 +assert_return(() => call($33, "checkRange", [43_363, 43_387, 57]), -1); + +// memory_copy.wast:5413 +assert_return(() => call($33, "checkRange", [43_387, 43_438, 59]), -1); + +// memory_copy.wast:5415 +assert_return(() => call($33, "checkRange", [43_438, 43_447, 77]), -1); + +// memory_copy.wast:5417 +assert_return(() => call($33, "checkRange", [43_447, 43_466, 41]), -1); + +// memory_copy.wast:5419 +assert_return(() => call($33, "checkRange", [43_466, 44_129, 83]), -1); + +// memory_copy.wast:5421 +assert_return(() => call($33, "checkRange", [44_129, 44_958, 96]), -1); + +// memory_copy.wast:5423 +assert_return(() => call($33, "checkRange", [44_958, 45_570, 77]), -1); + +// memory_copy.wast:5425 +assert_return(() => call($33, "checkRange", [45_570, 45_575, 92]), -1); + +// memory_copy.wast:5427 +assert_return(() => call($33, "checkRange", [45_575, 45_640, 77]), -1); + +// memory_copy.wast:5429 +assert_return(() => call($33, "checkRange", [45_640, 45_742, 42]), -1); + +// memory_copy.wast:5431 +assert_return(() => call($33, "checkRange", [45_742, 45_832, 72]), -1); + +// memory_copy.wast:5433 +assert_return(() => call($33, "checkRange", [45_832, 45_999, 92]), -1); + +// memory_copy.wast:5435 +assert_return(() => call($33, "checkRange", [45_999, 46_384, 83]), -1); + +// memory_copy.wast:5437 +assert_return(() => call($33, "checkRange", [46_384, 46_596, 95]), -1); + +// memory_copy.wast:5439 +assert_return(() => call($33, "checkRange", [46_596, 46_654, 92]), -1); + +// memory_copy.wast:5441 +assert_return(() => call($33, "checkRange", [46_654, 47_515, 83]), -1); + +// memory_copy.wast:5443 +assert_return(() => call($33, "checkRange", [47_515, 47_620, 77]), -1); + +// memory_copy.wast:5445 +assert_return(() => call($33, "checkRange", [47_620, 47_817, 79]), -1); + +// memory_copy.wast:5447 +assert_return(() => call($33, "checkRange", [47_817, 47_951, 95]), -1); + +// memory_copy.wast:5449 +assert_return(() => call($33, "checkRange", [47_951, 48_632, 100]), -1); + +// memory_copy.wast:5451 +assert_return(() => call($33, "checkRange", [48_632, 48_699, 97]), -1); + +// memory_copy.wast:5453 +assert_return(() => call($33, "checkRange", [48_699, 48_703, 37]), -1); + +// memory_copy.wast:5455 +assert_return(() => call($33, "checkRange", [48_703, 49_764, 77]), -1); + +// memory_copy.wast:5457 +assert_return(() => call($33, "checkRange", [49_764, 49_955, 42]), -1); + +// memory_copy.wast:5459 +assert_return(() => call($33, "checkRange", [49_955, 50_012, 76]), -1); + +// memory_copy.wast:5461 +assert_return(() => call($33, "checkRange", [50_012, 50_036, 57]), -1); + +// memory_copy.wast:5463 +assert_return(() => call($33, "checkRange", [50_036, 50_087, 59]), -1); + +// memory_copy.wast:5465 +assert_return(() => call($33, "checkRange", [50_087, 50_096, 77]), -1); + +// memory_copy.wast:5467 +assert_return(() => call($33, "checkRange", [50_096, 50_115, 41]), -1); + +// memory_copy.wast:5469 +assert_return(() => call($33, "checkRange", [50_115, 50_370, 83]), -1); + +// memory_copy.wast:5471 +assert_return(() => call($33, "checkRange", [50_370, 51_358, 92]), -1); + +// memory_copy.wast:5473 +assert_return(() => call($33, "checkRange", [51_358, 51_610, 77]), -1); + +// memory_copy.wast:5475 +assert_return(() => call($33, "checkRange", [51_610, 51_776, 83]), -1); + +// memory_copy.wast:5477 +assert_return(() => call($33, "checkRange", [51_776, 51_833, 89]), -1); + +// memory_copy.wast:5479 +assert_return(() => call($33, "checkRange", [51_833, 52_895, 100]), -1); + +// memory_copy.wast:5481 +assert_return(() => call($33, "checkRange", [52_895, 53_029, 97]), -1); + +// memory_copy.wast:5483 +assert_return(() => call($33, "checkRange", [53_029, 53_244, 68]), -1); + +// memory_copy.wast:5485 +assert_return(() => call($33, "checkRange", [53_244, 54_066, 100]), -1); + +// memory_copy.wast:5487 +assert_return(() => call($33, "checkRange", [54_066, 54_133, 97]), -1); + +// memory_copy.wast:5489 +assert_return(() => call($33, "checkRange", [54_133, 54_137, 37]), -1); + +// memory_copy.wast:5491 +assert_return(() => call($33, "checkRange", [54_137, 55_198, 77]), -1); + +// memory_copy.wast:5493 +assert_return(() => call($33, "checkRange", [55_198, 55_389, 42]), -1); + +// memory_copy.wast:5495 +assert_return(() => call($33, "checkRange", [55_389, 55_446, 76]), -1); + +// memory_copy.wast:5497 +assert_return(() => call($33, "checkRange", [55_446, 55_470, 57]), -1); + +// memory_copy.wast:5499 +assert_return(() => call($33, "checkRange", [55_470, 55_521, 59]), -1); + +// memory_copy.wast:5501 +assert_return(() => call($33, "checkRange", [55_521, 55_530, 77]), -1); + +// memory_copy.wast:5503 +assert_return(() => call($33, "checkRange", [55_530, 55_549, 41]), -1); + +// memory_copy.wast:5505 +assert_return(() => call($33, "checkRange", [55_549, 56_212, 83]), -1); + +// memory_copy.wast:5507 +assert_return(() => call($33, "checkRange", [56_212, 57_048, 96]), -1); + +// memory_copy.wast:5509 +assert_return(() => call($33, "checkRange", [57_048, 58_183, 77]), -1); + +// memory_copy.wast:5511 +assert_return(() => call($33, "checkRange", [58_183, 58_202, 41]), -1); + +// memory_copy.wast:5513 +assert_return(() => call($33, "checkRange", [58_202, 58_516, 83]), -1); + +// memory_copy.wast:5515 +assert_return(() => call($33, "checkRange", [58_516, 58_835, 95]), -1); + +// memory_copy.wast:5517 +assert_return(() => call($33, "checkRange", [58_835, 58_855, 77]), -1); + +// memory_copy.wast:5519 +assert_return(() => call($33, "checkRange", [58_855, 59_089, 95]), -1); + +// memory_copy.wast:5521 +assert_return(() => call($33, "checkRange", [59_089, 59_145, 77]), -1); + +// memory_copy.wast:5523 +assert_return(() => call($33, "checkRange", [59_145, 59_677, 99]), -1); + +// memory_copy.wast:5525 +assert_return(() => call($33, "checkRange", [59_677, 60_134, 0]), -1); + +// memory_copy.wast:5527 +assert_return(() => call($33, "checkRange", [60_134, 60_502, 89]), -1); + +// memory_copy.wast:5529 +assert_return(() => call($33, "checkRange", [60_502, 60_594, 59]), -1); + +// memory_copy.wast:5531 +assert_return(() => call($33, "checkRange", [60_594, 60_617, 36]), -1); + +// memory_copy.wast:5533 +assert_return(() => call($33, "checkRange", [60_617, 60_618, 32]), -1); + +// memory_copy.wast:5535 +assert_return(() => call($33, "checkRange", [60_618, 60_777, 42]), -1); + +// memory_copy.wast:5537 +assert_return(() => call($33, "checkRange", [60_777, 60_834, 76]), -1); + +// memory_copy.wast:5539 +assert_return(() => call($33, "checkRange", [60_834, 60_858, 57]), -1); + +// memory_copy.wast:5541 +assert_return(() => call($33, "checkRange", [60_858, 60_909, 59]), -1); + +// memory_copy.wast:5543 +assert_return(() => call($33, "checkRange", [60_909, 60_918, 77]), -1); + +// memory_copy.wast:5545 +assert_return(() => call($33, "checkRange", [60_918, 60_937, 41]), -1); + +// memory_copy.wast:5547 +assert_return(() => call($33, "checkRange", [60_937, 61_600, 83]), -1); + +// memory_copy.wast:5549 +assert_return(() => call($33, "checkRange", [61_600, 62_436, 96]), -1); + +// memory_copy.wast:5551 +assert_return(() => call($33, "checkRange", [62_436, 63_307, 77]), -1); + +// memory_copy.wast:5553 +assert_return(() => call($33, "checkRange", [63_307, 63_397, 100]), -1); + +// memory_copy.wast:5555 +assert_return(() => call($33, "checkRange", [63_397, 63_501, 74]), -1); + +// memory_copy.wast:5557 +assert_return(() => call($33, "checkRange", [63_501, 63_525, 93]), -1); + +// memory_copy.wast:5559 +assert_return(() => call($33, "checkRange", [63_525, 63_605, 74]), -1); + +// memory_copy.wast:5561 +assert_return(() => call($33, "checkRange", [63_605, 63_704, 100]), -1); + +// memory_copy.wast:5563 +assert_return(() => call($33, "checkRange", [63_704, 63_771, 97]), -1); + +// memory_copy.wast:5565 +assert_return(() => call($33, "checkRange", [63_771, 63_775, 37]), -1); + +// memory_copy.wast:5567 +assert_return(() => call($33, "checkRange", [63_775, 64_311, 77]), -1); + +// memory_copy.wast:5569 +assert_return(() => call($33, "checkRange", [64_311, 64_331, 26]), -1); + +// memory_copy.wast:5571 +assert_return(() => call($33, "checkRange", [64_331, 64_518, 92]), -1); + +// memory_copy.wast:5573 +assert_return(() => call($33, "checkRange", [64_518, 64_827, 11]), -1); + +// memory_copy.wast:5575 +assert_return(() => call($33, "checkRange", [64_827, 64_834, 26]), -1); + +// memory_copy.wast:5577 +assert_return(() => call($33, "checkRange", [64_834, 65_536, 0]), -1); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/memory_fill.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/memory_fill.wast.js new file mode 100644 index 0000000000..297433fd5d --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/memory_fill.wast.js @@ -0,0 +1,300 @@ + +// memory_fill.wast:6 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc1\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8f\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\xd5\x00\x41\x80\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:22 +run(() => call($1, "test", [])); + +// memory_fill.wast:24 +assert_return(() => call($1, "checkRange", [0, 65_280, 0]), -1); + +// memory_fill.wast:26 +assert_return(() => call($1, "checkRange", [65_280, 65_536, 85]), -1); + +// memory_fill.wast:28 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc1\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8f\x80\x80\x80\x00\x00\x41\x80\xfe\x03\x41\xd5\x00\x41\x81\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:44 +assert_trap(() => call($2, "test", [])); + +// memory_fill.wast:46 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x7e\x41\xd5\x00\x41\x81\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:62 +assert_trap(() => call($3, "test", [])); + +// memory_fill.wast:64 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x41\x12\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:80 +run(() => call($4, "test", [])); + +// memory_fill.wast:82 +assert_return(() => call($4, "checkRange", [0, 65_536, 0]), -1); + +// memory_fill.wast:84 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:100 +run(() => call($5, "test", [])); + +// memory_fill.wast:102 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x08\x41\xd5\x00\x41\x00\xfc\x0b\x00\x0b"); + +// memory_fill.wast:118 +assert_trap(() => call($6, "test", [])); + +// memory_fill.wast:120 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc0\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\x41\xaa\x01\x41\xfe\xff\x03\xfc\x0b\x00\x0b"); + +// memory_fill.wast:136 +run(() => call($7, "test", [])); + +// memory_fill.wast:138 +assert_return(() => call($7, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:140 +assert_return(() => call($7, "checkRange", [1, 65_535, 170]), -1); + +// memory_fill.wast:142 +assert_return(() => call($7, "checkRange", [65_535, 65_536, 0]), -1); + +// memory_fill.wast:145 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x95\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x04\x74\x65\x73\x74\x00\x01\x0a\xc8\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x96\x80\x80\x80\x00\x00\x41\x12\x41\xd5\x00\x41\x0a\xfc\x0b\x00\x41\x15\x41\xaa\x01\x41\x04\xfc\x0b\x00\x0b"); + +// memory_fill.wast:162 +run(() => call($8, "test", [])); + +// memory_fill.wast:164 +assert_return(() => call($8, "checkRange", [0, 18, 0]), -1); + +// memory_fill.wast:166 +assert_return(() => call($8, "checkRange", [18, 21, 85]), -1); + +// memory_fill.wast:168 +assert_return(() => call($8, "checkRange", [21, 25, 170]), -1); + +// memory_fill.wast:170 +assert_return(() => call($8, "checkRange", [25, 28, 85]), -1); + +// memory_fill.wast:172 +assert_return(() => call($8, "checkRange", [28, 65_536, 0]), -1); + +// memory_fill.wast:174 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:180 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:187 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:194 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:201 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:208 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:215 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:222 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x41\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:229 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:236 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:243 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:250 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:257 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:264 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:271 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:278 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x41\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:285 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:292 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:299 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:306 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:313 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:320 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:327 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:334 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:341 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:348 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:355 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:362 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:369 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:376 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:383 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:390 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:397 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:404 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:411 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:418 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:425 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:432 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:439 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:446 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x42\x0a\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:453 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:460 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:467 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:474 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:481 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:488 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:495 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:502 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x42\x0a\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:509 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:516 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:523 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:530 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x41\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:537 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:544 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:551 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:558 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x43\x00\x00\xa0\x41\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:565 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:572 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:579 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:586 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x42\x14\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:593 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x41\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:600 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x43\x00\x00\xf0\x41\xfc\x0b\x00\x0b"); + +// memory_fill.wast:607 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x42\x1e\xfc\x0b\x00\x0b"); + +// memory_fill.wast:614 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8a\x80\x80\x80\x00\x01\x06\x74\x65\x73\x74\x66\x6e\x00\x00\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x44\x00\x00\x00\x00\x00\x00\x3e\x40\xfc\x0b\x00\x0b"); + +// memory_fill.wast:621 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:638 +assert_trap(() => call($9, "run", [65_280, 37, 512])); + +// memory_fill.wast:641 +assert_return(() => call($9, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:643 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:660 +assert_trap(() => call($10, "run", [65_279, 37, 514])); + +// memory_fill.wast:663 +assert_return(() => call($10, "checkRange", [0, 1, 0]), -1); + +// memory_fill.wast:665 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0a\xbd\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0b\x00\x0b"); + +// memory_fill.wast:682 +assert_trap(() => call($11, "run", [65_279, 37, -1])); + +// memory_fill.wast:685 +assert_return(() => call($11, "checkRange", [0, 1, 0]), -1); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/memory_grow.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/memory_grow.wast.js new file mode 100644 index 0000000000..a53bab115a --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/memory_grow.wast.js @@ -0,0 +1,288 @@ + +// memory_grow.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x87\x80\x80\x80\x00\x06\x00\x01\x00\x01\x02\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x07\xd7\x80\x80\x80\x00\x06\x0c\x6c\x6f\x61\x64\x5f\x61\x74\x5f\x7a\x65\x72\x6f\x00\x00\x0d\x73\x74\x6f\x72\x65\x5f\x61\x74\x5f\x7a\x65\x72\x6f\x00\x01\x11\x6c\x6f\x61\x64\x5f\x61\x74\x5f\x70\x61\x67\x65\x5f\x73\x69\x7a\x65\x00\x02\x12\x73\x74\x6f\x72\x65\x5f\x61\x74\x5f\x70\x61\x67\x65\x5f\x73\x69\x7a\x65\x00\x03\x04\x67\x72\x6f\x77\x00\x04\x04\x73\x69\x7a\x65\x00\x05\x0a\xcd\x80\x80\x80\x00\x06\x87\x80\x80\x80\x00\x00\x41\x00\x28\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x41\x02\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x80\x80\x04\x28\x02\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x03\x36\x02\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x3f\x00\x0b"); + +// memory_grow.wast:14 +assert_return(() => call($1, "size", []), 0); + +// memory_grow.wast:15 +assert_trap(() => call($1, "store_at_zero", [])); + +// memory_grow.wast:16 +assert_trap(() => call($1, "load_at_zero", [])); + +// memory_grow.wast:17 +assert_trap(() => call($1, "store_at_page_size", [])); + +// memory_grow.wast:18 +assert_trap(() => call($1, "load_at_page_size", [])); + +// memory_grow.wast:19 +assert_return(() => call($1, "grow", [1]), 0); + +// memory_grow.wast:20 +assert_return(() => call($1, "size", []), 1); + +// memory_grow.wast:21 +assert_return(() => call($1, "load_at_zero", []), 0); + +// memory_grow.wast:22 +assert_return(() => call($1, "store_at_zero", [])); + +// memory_grow.wast:23 +assert_return(() => call($1, "load_at_zero", []), 2); + +// memory_grow.wast:24 +assert_trap(() => call($1, "store_at_page_size", [])); + +// memory_grow.wast:25 +assert_trap(() => call($1, "load_at_page_size", [])); + +// memory_grow.wast:26 +assert_return(() => call($1, "grow", [4]), 1); + +// memory_grow.wast:27 +assert_return(() => call($1, "size", []), 5); + +// memory_grow.wast:28 +assert_return(() => call($1, "load_at_zero", []), 2); + +// memory_grow.wast:29 +assert_return(() => call($1, "store_at_zero", [])); + +// memory_grow.wast:30 +assert_return(() => call($1, "load_at_zero", []), 2); + +// memory_grow.wast:31 +assert_return(() => call($1, "load_at_page_size", []), 0); + +// memory_grow.wast:32 +assert_return(() => call($1, "store_at_page_size", [])); + +// memory_grow.wast:33 +assert_return(() => call($1, "load_at_page_size", []), 3); + +// memory_grow.wast:36 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x07\x88\x80\x80\x80\x00\x01\x04\x67\x72\x6f\x77\x00\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x20\x00\x40\x00\x0b"); + +// memory_grow.wast:41 +assert_return(() => call($2, "grow", [0]), 0); + +// memory_grow.wast:42 +assert_return(() => call($2, "grow", [1]), 0); + +// memory_grow.wast:43 +assert_return(() => call($2, "grow", [0]), 1); + +// memory_grow.wast:44 +assert_return(() => call($2, "grow", [2]), 1); + +// memory_grow.wast:45 +assert_return(() => call($2, "grow", [800]), 3); + +// memory_grow.wast:46 +assert_return(() => call($2, "grow", [65_536]), -1); + +// memory_grow.wast:47 +assert_return(() => call($2, "grow", [64_736]), -1); + +// memory_grow.wast:48 +assert_return(() => call($2, "grow", [1]), 803); + +// memory_grow.wast:50 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x67\x72\x6f\x77\x00\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x20\x00\x40\x00\x0b"); + +// memory_grow.wast:55 +assert_return(() => call($3, "grow", [0]), 0); + +// memory_grow.wast:56 +assert_return(() => call($3, "grow", [1]), 0); + +// memory_grow.wast:57 +assert_return(() => call($3, "grow", [1]), 1); + +// memory_grow.wast:58 +assert_return(() => call($3, "grow", [2]), 2); + +// memory_grow.wast:59 +assert_return(() => call($3, "grow", [6]), 4); + +// memory_grow.wast:60 +assert_return(() => call($3, "grow", [0]), 10); + +// memory_grow.wast:61 +assert_return(() => call($3, "grow", [1]), -1); + +// memory_grow.wast:62 +assert_return(() => call($3, "grow", [65_536]), -1); + +// memory_grow.wast:66 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x9c\x80\x80\x80\x00\x02\x04\x67\x72\x6f\x77\x00\x00\x11\x63\x68\x65\x63\x6b\x2d\x6d\x65\x6d\x6f\x72\x79\x2d\x7a\x65\x72\x6f\x00\x01\x0a\xc4\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x20\x00\x40\x00\x0b\xb3\x80\x80\x80\x00\x01\x01\x7f\x41\x01\x21\x02\x02\x40\x03\x40\x20\x00\x2d\x00\x00\x21\x02\x20\x02\x41\x00\x47\x0d\x01\x20\x00\x20\x01\x4f\x0d\x01\x20\x00\x41\x01\x6a\x21\x00\x20\x00\x20\x01\x4d\x0d\x00\x0b\x0b\x20\x02\x0b"); + +// memory_grow.wast:87 +assert_return(() => call($4, "check-memory-zero", [0, 65_535]), 0); + +// memory_grow.wast:88 +assert_return(() => call($4, "grow", [1]), 1); + +// memory_grow.wast:89 +assert_return(() => call($4, "check-memory-zero", [65_536, 131_071]), 0); + +// memory_grow.wast:90 +assert_return(() => call($4, "grow", [1]), 2); + +// memory_grow.wast:91 +assert_return(() => call($4, "check-memory-zero", [131_072, 196_607]), 0); + +// memory_grow.wast:92 +assert_return(() => call($4, "grow", [1]), 3); + +// memory_grow.wast:93 +assert_return(() => call($4, "check-memory-zero", [196_608, 262_143]), 0); + +// memory_grow.wast:94 +assert_return(() => call($4, "grow", [1]), 4); + +// memory_grow.wast:95 +assert_return(() => call($4, "check-memory-zero", [262_144, 327_679]), 0); + +// memory_grow.wast:96 +assert_return(() => call($4, "grow", [1]), 5); + +// memory_grow.wast:97 +assert_return(() => call($4, "check-memory-zero", [327_680, 393_215]), 0); + +// memory_grow.wast:101 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x95\x80\x80\x80\x00\x04\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x01\x7f\x60\x00\x00\x60\x02\x7f\x7f\x01\x7f\x03\xa7\x80\x80\x80\x00\x26\x01\x02\x01\x01\x02\x01\x01\x01\x01\x01\x01\x03\x03\x01\x00\x01\x01\x01\x01\x01\x01\x01\x02\x01\x02\x01\x01\x02\x02\x02\x02\x01\x01\x01\x01\x01\x01\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x07\xb7\x85\x80\x80\x00\x25\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x00\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x63\x6f\x6e\x64\x00\x01\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x02\x13\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x03\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x69\x6e\x64\x65\x78\x00\x04\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x05\x17\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x06\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x07\x0a\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x00\x08\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x09\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x0a\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x0b\x10\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x73\x65\x63\x6f\x6e\x64\x00\x0c\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x63\x6f\x6e\x64\x00\x0d\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x66\x69\x72\x73\x74\x00\x0f\x0b\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6d\x69\x64\x00\x10\x0c\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6c\x61\x73\x74\x00\x11\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x12\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x13\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x14\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x69\x6e\x64\x65\x78\x00\x15\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x16\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x17\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x18\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x19\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x1a\x10\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x1b\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x76\x61\x6c\x75\x65\x00\x1c\x11\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x1d\x0f\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x76\x61\x6c\x75\x65\x00\x1e\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1f\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x20\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x21\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x22\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x23\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x24\x13\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x73\x69\x7a\x65\x00\x25\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x0e\x0a\xf2\x84\x80\x80\x00\x26\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x40\x00\x0c\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x00\x40\x00\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x40\x00\x41\x01\x0d\x00\x1a\x41\x07\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x00\x40\x00\x0d\x00\x1a\x41\x07\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x40\x41\x00\x40\x00\x0e\x02\x00\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x40\x00\x41\x01\x0e\x02\x00\x00\x00\x41\x07\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x00\x40\x00\x0e\x01\x00\x00\x41\x07\x0b\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x0f\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x40\x00\x04\x7f\x41\x00\x05\x41\x01\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x00\x40\x00\x05\x41\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x41\x00\x05\x41\x00\x40\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x40\x00\x20\x00\x20\x01\x1b\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x41\x00\x40\x00\x20\x01\x1b\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x01\x41\x00\x40\x00\x1b\x0b\x84\x80\x80\x80\x00\x00\x41\x7f\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x02\x41\x03\x10\x0e\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x00\x40\x00\x41\x03\x10\x0e\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x00\x40\x00\x10\x0e\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x02\x41\x03\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x00\x40\x00\x41\x03\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x00\x40\x00\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x03\x41\x00\x40\x00\x11\x00\x00\x0b\x8a\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x40\x00\x21\x00\x0b\x8a\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x40\x00\x22\x00\x0b\x8a\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x40\x00\x24\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x40\x00\x28\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x40\x00\x2c\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x07\x36\x02\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x02\x41\x00\x40\x00\x36\x02\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x07\x3a\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x02\x41\x00\x40\x00\x3b\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x67\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x0a\x6a\x0b\x89\x80\x80\x80\x00\x00\x41\x0a\x41\x00\x40\x00\x6b\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x45\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x40\x00\x41\x0a\x4c\x0b\x89\x80\x80\x80\x00\x00\x41\x0a\x41\x00\x40\x00\x47\x0b\x88\x80\x80\x80\x00\x00\x41\x00\x40\x00\x40\x00\x0b"); + +// memory_grow.wast:259 +assert_return(() => call($5, "as-br-value", []), 1); + +// memory_grow.wast:261 +assert_return(() => call($5, "as-br_if-cond", [])); + +// memory_grow.wast:262 +assert_return(() => call($5, "as-br_if-value", []), 1); + +// memory_grow.wast:263 +assert_return(() => call($5, "as-br_if-value-cond", []), 6); + +// memory_grow.wast:265 +assert_return(() => call($5, "as-br_table-index", [])); + +// memory_grow.wast:266 +assert_return(() => call($5, "as-br_table-value", []), 1); + +// memory_grow.wast:267 +assert_return(() => call($5, "as-br_table-value-index", []), 6); + +// memory_grow.wast:269 +assert_return(() => call($5, "as-return-value", []), 1); + +// memory_grow.wast:271 +assert_return(() => call($5, "as-if-cond", []), 0); + +// memory_grow.wast:272 +assert_return(() => call($5, "as-if-then", []), 1); + +// memory_grow.wast:273 +assert_return(() => call($5, "as-if-else", []), 1); + +// memory_grow.wast:275 +assert_return(() => call($5, "as-select-first", [0, 1]), 1); + +// memory_grow.wast:276 +assert_return(() => call($5, "as-select-second", [0, 0]), 1); + +// memory_grow.wast:277 +assert_return(() => call($5, "as-select-cond", []), 0); + +// memory_grow.wast:279 +assert_return(() => call($5, "as-call-first", []), -1); + +// memory_grow.wast:280 +assert_return(() => call($5, "as-call-mid", []), -1); + +// memory_grow.wast:281 +assert_return(() => call($5, "as-call-last", []), -1); + +// memory_grow.wast:283 +assert_return(() => call($5, "as-call_indirect-first", []), -1); + +// memory_grow.wast:284 +assert_return(() => call($5, "as-call_indirect-mid", []), -1); + +// memory_grow.wast:285 +assert_return(() => call($5, "as-call_indirect-last", []), -1); + +// memory_grow.wast:286 +assert_trap(() => call($5, "as-call_indirect-index", [])); + +// memory_grow.wast:288 +assert_return(() => call($5, "as-local.set-value", [])); + +// memory_grow.wast:289 +assert_return(() => call($5, "as-local.tee-value", []), 1); + +// memory_grow.wast:290 +assert_return(() => call($5, "as-global.set-value", [])); + +// memory_grow.wast:292 +assert_return(() => call($5, "as-load-address", []), 0); + +// memory_grow.wast:293 +assert_return(() => call($5, "as-loadN-address", []), 0); + +// memory_grow.wast:294 +assert_return(() => call($5, "as-store-address", [])); + +// memory_grow.wast:295 +assert_return(() => call($5, "as-store-value", [])); + +// memory_grow.wast:296 +assert_return(() => call($5, "as-storeN-address", [])); + +// memory_grow.wast:297 +assert_return(() => call($5, "as-storeN-value", [])); + +// memory_grow.wast:299 +assert_return(() => call($5, "as-unary-operand", []), 31); + +// memory_grow.wast:301 +assert_return(() => call($5, "as-binary-left", []), 11); + +// memory_grow.wast:302 +assert_return(() => call($5, "as-binary-right", []), 9); + +// memory_grow.wast:304 +assert_return(() => call($5, "as-test-operand", []), 0); + +// memory_grow.wast:306 +assert_return(() => call($5, "as-compare-left", []), 1); + +// memory_grow.wast:307 +assert_return(() => call($5, "as-compare-right", []), 1); + +// memory_grow.wast:309 +assert_return(() => call($5, "as-memory.grow-size", []), 1); + +// memory_grow.wast:312 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x40\x00\x0b"); + +// memory_grow.wast:321 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x02\x7f\x40\x00\x0b\x0b"); + +// memory_grow.wast:331 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x03\x7f\x40\x00\x0b\x0b"); + +// memory_grow.wast:341 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x40\x00\x0b\x0b"); + +// memory_grow.wast:352 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x40\x00\x0b"); + +// memory_grow.wast:362 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x40\x00\x0b"); + +// memory_grow.wast:371 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x40\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/memory_init.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/memory_init.wast.js new file mode 100644 index 0000000000..07d4e6b323 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/memory_init.wast.js @@ -0,0 +1,720 @@ + +// memory_init.wast:6 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:17 +run(() => call($1, "test", [])); + +// memory_init.wast:19 +assert_return(() => call($1, "load8_u", [0]), 0); + +// memory_init.wast:20 +assert_return(() => call($1, "load8_u", [1]), 0); + +// memory_init.wast:21 +assert_return(() => call($1, "load8_u", [2]), 3); + +// memory_init.wast:22 +assert_return(() => call($1, "load8_u", [3]), 1); + +// memory_init.wast:23 +assert_return(() => call($1, "load8_u", [4]), 4); + +// memory_init.wast:24 +assert_return(() => call($1, "load8_u", [5]), 1); + +// memory_init.wast:25 +assert_return(() => call($1, "load8_u", [6]), 0); + +// memory_init.wast:26 +assert_return(() => call($1, "load8_u", [7]), 0); + +// memory_init.wast:27 +assert_return(() => call($1, "load8_u", [8]), 0); + +// memory_init.wast:28 +assert_return(() => call($1, "load8_u", [9]), 0); + +// memory_init.wast:29 +assert_return(() => call($1, "load8_u", [10]), 0); + +// memory_init.wast:30 +assert_return(() => call($1, "load8_u", [11]), 0); + +// memory_init.wast:31 +assert_return(() => call($1, "load8_u", [12]), 7); + +// memory_init.wast:32 +assert_return(() => call($1, "load8_u", [13]), 5); + +// memory_init.wast:33 +assert_return(() => call($1, "load8_u", [14]), 2); + +// memory_init.wast:34 +assert_return(() => call($1, "load8_u", [15]), 3); + +// memory_init.wast:35 +assert_return(() => call($1, "load8_u", [16]), 6); + +// memory_init.wast:36 +assert_return(() => call($1, "load8_u", [17]), 0); + +// memory_init.wast:37 +assert_return(() => call($1, "load8_u", [18]), 0); + +// memory_init.wast:38 +assert_return(() => call($1, "load8_u", [19]), 0); + +// memory_init.wast:39 +assert_return(() => call($1, "load8_u", [20]), 0); + +// memory_init.wast:40 +assert_return(() => call($1, "load8_u", [21]), 0); + +// memory_init.wast:41 +assert_return(() => call($1, "load8_u", [22]), 0); + +// memory_init.wast:42 +assert_return(() => call($1, "load8_u", [23]), 0); + +// memory_init.wast:43 +assert_return(() => call($1, "load8_u", [24]), 0); + +// memory_init.wast:44 +assert_return(() => call($1, "load8_u", [25]), 0); + +// memory_init.wast:45 +assert_return(() => call($1, "load8_u", [26]), 0); + +// memory_init.wast:46 +assert_return(() => call($1, "load8_u", [27]), 0); + +// memory_init.wast:47 +assert_return(() => call($1, "load8_u", [28]), 0); + +// memory_init.wast:48 +assert_return(() => call($1, "load8_u", [29]), 0); + +// memory_init.wast:50 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x08\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:61 +run(() => call($2, "test", [])); + +// memory_init.wast:63 +assert_return(() => call($2, "load8_u", [0]), 0); + +// memory_init.wast:64 +assert_return(() => call($2, "load8_u", [1]), 0); + +// memory_init.wast:65 +assert_return(() => call($2, "load8_u", [2]), 3); + +// memory_init.wast:66 +assert_return(() => call($2, "load8_u", [3]), 1); + +// memory_init.wast:67 +assert_return(() => call($2, "load8_u", [4]), 4); + +// memory_init.wast:68 +assert_return(() => call($2, "load8_u", [5]), 1); + +// memory_init.wast:69 +assert_return(() => call($2, "load8_u", [6]), 0); + +// memory_init.wast:70 +assert_return(() => call($2, "load8_u", [7]), 2); + +// memory_init.wast:71 +assert_return(() => call($2, "load8_u", [8]), 7); + +// memory_init.wast:72 +assert_return(() => call($2, "load8_u", [9]), 1); + +// memory_init.wast:73 +assert_return(() => call($2, "load8_u", [10]), 8); + +// memory_init.wast:74 +assert_return(() => call($2, "load8_u", [11]), 0); + +// memory_init.wast:75 +assert_return(() => call($2, "load8_u", [12]), 7); + +// memory_init.wast:76 +assert_return(() => call($2, "load8_u", [13]), 5); + +// memory_init.wast:77 +assert_return(() => call($2, "load8_u", [14]), 2); + +// memory_init.wast:78 +assert_return(() => call($2, "load8_u", [15]), 3); + +// memory_init.wast:79 +assert_return(() => call($2, "load8_u", [16]), 6); + +// memory_init.wast:80 +assert_return(() => call($2, "load8_u", [17]), 0); + +// memory_init.wast:81 +assert_return(() => call($2, "load8_u", [18]), 0); + +// memory_init.wast:82 +assert_return(() => call($2, "load8_u", [19]), 0); + +// memory_init.wast:83 +assert_return(() => call($2, "load8_u", [20]), 0); + +// memory_init.wast:84 +assert_return(() => call($2, "load8_u", [21]), 0); + +// memory_init.wast:85 +assert_return(() => call($2, "load8_u", [22]), 0); + +// memory_init.wast:86 +assert_return(() => call($2, "load8_u", [23]), 0); + +// memory_init.wast:87 +assert_return(() => call($2, "load8_u", [24]), 0); + +// memory_init.wast:88 +assert_return(() => call($2, "load8_u", [25]), 0); + +// memory_init.wast:89 +assert_return(() => call($2, "load8_u", [26]), 0); + +// memory_init.wast:90 +assert_return(() => call($2, "load8_u", [27]), 0); + +// memory_init.wast:91 +assert_return(() => call($2, "load8_u", [28]), 0); + +// memory_init.wast:92 +assert_return(() => call($2, "load8_u", [29]), 0); + +// memory_init.wast:94 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\x9e\x80\x80\x80\x00\x02\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x01\x41\x03\xfc\x08\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:105 +run(() => call($3, "test", [])); + +// memory_init.wast:107 +assert_return(() => call($3, "load8_u", [0]), 0); + +// memory_init.wast:108 +assert_return(() => call($3, "load8_u", [1]), 0); + +// memory_init.wast:109 +assert_return(() => call($3, "load8_u", [2]), 3); + +// memory_init.wast:110 +assert_return(() => call($3, "load8_u", [3]), 1); + +// memory_init.wast:111 +assert_return(() => call($3, "load8_u", [4]), 4); + +// memory_init.wast:112 +assert_return(() => call($3, "load8_u", [5]), 1); + +// memory_init.wast:113 +assert_return(() => call($3, "load8_u", [6]), 0); + +// memory_init.wast:114 +assert_return(() => call($3, "load8_u", [7]), 0); + +// memory_init.wast:115 +assert_return(() => call($3, "load8_u", [8]), 0); + +// memory_init.wast:116 +assert_return(() => call($3, "load8_u", [9]), 0); + +// memory_init.wast:117 +assert_return(() => call($3, "load8_u", [10]), 0); + +// memory_init.wast:118 +assert_return(() => call($3, "load8_u", [11]), 0); + +// memory_init.wast:119 +assert_return(() => call($3, "load8_u", [12]), 7); + +// memory_init.wast:120 +assert_return(() => call($3, "load8_u", [13]), 5); + +// memory_init.wast:121 +assert_return(() => call($3, "load8_u", [14]), 2); + +// memory_init.wast:122 +assert_return(() => call($3, "load8_u", [15]), 9); + +// memory_init.wast:123 +assert_return(() => call($3, "load8_u", [16]), 2); + +// memory_init.wast:124 +assert_return(() => call($3, "load8_u", [17]), 7); + +// memory_init.wast:125 +assert_return(() => call($3, "load8_u", [18]), 0); + +// memory_init.wast:126 +assert_return(() => call($3, "load8_u", [19]), 0); + +// memory_init.wast:127 +assert_return(() => call($3, "load8_u", [20]), 0); + +// memory_init.wast:128 +assert_return(() => call($3, "load8_u", [21]), 0); + +// memory_init.wast:129 +assert_return(() => call($3, "load8_u", [22]), 0); + +// memory_init.wast:130 +assert_return(() => call($3, "load8_u", [23]), 0); + +// memory_init.wast:131 +assert_return(() => call($3, "load8_u", [24]), 0); + +// memory_init.wast:132 +assert_return(() => call($3, "load8_u", [25]), 0); + +// memory_init.wast:133 +assert_return(() => call($3, "load8_u", [26]), 0); + +// memory_init.wast:134 +assert_return(() => call($3, "load8_u", [27]), 0); + +// memory_init.wast:135 +assert_return(() => call($3, "load8_u", [28]), 0); + +// memory_init.wast:136 +assert_return(() => call($3, "load8_u", [29]), 0); + +// memory_init.wast:138 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x9c\x80\x80\x80\x00\x03\x07\x6d\x65\x6d\x6f\x72\x79\x30\x02\x00\x04\x74\x65\x73\x74\x00\x00\x07\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x0c\x81\x80\x80\x80\x00\x04\x0a\xe0\x80\x80\x80\x00\x02\xce\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x08\x01\x00\xfc\x09\x01\x41\x0f\x41\x01\x41\x03\xfc\x08\x03\x00\xfc\x09\x03\x41\x14\x41\x0f\x41\x05\xfc\x0a\x00\x00\x41\x15\x41\x1d\x41\x01\xfc\x0a\x00\x00\x41\x18\x41\x0a\x41\x01\xfc\x0a\x00\x00\x41\x0d\x41\x0b\x41\x04\xfc\x0a\x00\x00\x41\x13\x41\x14\x41\x05\xfc\x0a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x0b\xa1\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x05\x05\x09\x02\x07\x06"); + +// memory_init.wast:157 +run(() => call($4, "test", [])); + +// memory_init.wast:159 +assert_return(() => call($4, "load8_u", [0]), 0); + +// memory_init.wast:160 +assert_return(() => call($4, "load8_u", [1]), 0); + +// memory_init.wast:161 +assert_return(() => call($4, "load8_u", [2]), 3); + +// memory_init.wast:162 +assert_return(() => call($4, "load8_u", [3]), 1); + +// memory_init.wast:163 +assert_return(() => call($4, "load8_u", [4]), 4); + +// memory_init.wast:164 +assert_return(() => call($4, "load8_u", [5]), 1); + +// memory_init.wast:165 +assert_return(() => call($4, "load8_u", [6]), 0); + +// memory_init.wast:166 +assert_return(() => call($4, "load8_u", [7]), 2); + +// memory_init.wast:167 +assert_return(() => call($4, "load8_u", [8]), 7); + +// memory_init.wast:168 +assert_return(() => call($4, "load8_u", [9]), 1); + +// memory_init.wast:169 +assert_return(() => call($4, "load8_u", [10]), 8); + +// memory_init.wast:170 +assert_return(() => call($4, "load8_u", [11]), 0); + +// memory_init.wast:171 +assert_return(() => call($4, "load8_u", [12]), 7); + +// memory_init.wast:172 +assert_return(() => call($4, "load8_u", [13]), 0); + +// memory_init.wast:173 +assert_return(() => call($4, "load8_u", [14]), 7); + +// memory_init.wast:174 +assert_return(() => call($4, "load8_u", [15]), 5); + +// memory_init.wast:175 +assert_return(() => call($4, "load8_u", [16]), 2); + +// memory_init.wast:176 +assert_return(() => call($4, "load8_u", [17]), 7); + +// memory_init.wast:177 +assert_return(() => call($4, "load8_u", [18]), 0); + +// memory_init.wast:178 +assert_return(() => call($4, "load8_u", [19]), 9); + +// memory_init.wast:179 +assert_return(() => call($4, "load8_u", [20]), 0); + +// memory_init.wast:180 +assert_return(() => call($4, "load8_u", [21]), 7); + +// memory_init.wast:181 +assert_return(() => call($4, "load8_u", [22]), 0); + +// memory_init.wast:182 +assert_return(() => call($4, "load8_u", [23]), 8); + +// memory_init.wast:183 +assert_return(() => call($4, "load8_u", [24]), 8); + +// memory_init.wast:184 +assert_return(() => call($4, "load8_u", [25]), 0); + +// memory_init.wast:185 +assert_return(() => call($4, "load8_u", [26]), 0); + +// memory_init.wast:186 +assert_return(() => call($4, "load8_u", [27]), 0); + +// memory_init.wast:187 +assert_return(() => call($4, "load8_u", [28]), 0); + +// memory_init.wast:188 +assert_return(() => call($4, "load8_u", [29]), 0); + +// memory_init.wast:189 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x00\x0b"); + +// memory_init.wast:195 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x09\x04\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:203 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\xfc\x09\x00\xfc\x09\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:209 +run(() => call($5, "test", [])); + +// memory_init.wast:211 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\xfc\x09\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:217 +assert_trap(() => call($6, "test", [])); + +// memory_init.wast:219 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x37"); + +// memory_init.wast:224 +assert_trap(() => call($7, "test", [])); + +// memory_init.wast:226 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x01\x00\x0b"); + +// memory_init.wast:232 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x01\xfc\x08\x01\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:240 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x41\x00\x41\x01\xfc\x08\x00\x00\x41\x01\x41\x00\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:246 +run(() => call($8, "test", [])); + +// memory_init.wast:248 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x00\x41\x05\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:253 +assert_trap(() => call($9, "test", [])); + +// memory_init.wast:255 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x02\x41\x03\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:260 +assert_trap(() => call($10, "test", [])); + +// memory_init.wast:262 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\xfe\xff\x03\x41\x01\x41\x03\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:267 +assert_trap(() => call($11, "test", [])); + +// memory_init.wast:269 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x04\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:274 +assert_trap(() => call($12, "test", [])); + +// memory_init.wast:276 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\xd2\x09\x41\x01\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:281 +run(() => call($13, "test", [])); + +// memory_init.wast:283 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x81\x80\x04\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:288 +assert_trap(() => call($14, "test", [])); + +// memory_init.wast:290 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x00\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:295 +run(() => call($15, "test", [])); + +// memory_init.wast:297 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x80\x80\x04\x41\x01\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:302 +run(() => call($16, "test", [])); + +// memory_init.wast:304 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x81\x80\x04\x41\x04\x41\x00\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:309 +assert_trap(() => call($17, "test", [])); + +// memory_init.wast:311 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:319 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:327 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:335 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:343 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:351 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:359 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:367 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:375 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:383 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:391 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:399 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:407 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:415 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:423 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:431 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:439 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:447 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:455 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:463 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:471 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:479 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:487 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:495 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:503 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:511 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:519 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:527 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:535 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:543 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:551 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:559 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:567 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:575 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:583 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:591 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:599 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:607 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:615 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:623 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:631 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x42\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:639 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:647 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:655 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:663 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:671 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:679 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:687 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:695 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:703 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:711 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:719 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:727 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:735 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:743 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:751 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:759 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:767 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:775 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:783 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:791 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:799 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:807 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0c\x81\x80\x80\x80\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x08\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x01\x01\x01\x37"); + +// memory_init.wast:815 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:833 +assert_trap(() => call($18, "run", [65_528, 16])); + +// memory_init.wast:836 +assert_return(() => call($18, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:838 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:856 +assert_trap(() => call($19, "run", [65_527, 16])); + +// memory_init.wast:859 +assert_return(() => call($19, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:861 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:879 +assert_trap(() => call($20, "run", [65_472, 30])); + +// memory_init.wast:882 +assert_return(() => call($20, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:884 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:902 +assert_trap(() => call($21, "run", [65_473, 31])); + +// memory_init.wast:905 +assert_return(() => call($21, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:907 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:925 +assert_trap(() => call($22, "run", [65_528, -256])); + +// memory_init.wast:928 +assert_return(() => call($22, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:930 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x02\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\x94\x80\x80\x80\x00\x02\x0a\x63\x68\x65\x63\x6b\x52\x61\x6e\x67\x65\x00\x00\x03\x72\x75\x6e\x00\x01\x0c\x81\x80\x80\x80\x00\x01\x0a\xbe\x80\x80\x80\x00\x02\xa7\x80\x80\x80\x00\x00\x03\x40\x20\x00\x20\x01\x46\x04\x40\x41\x7f\x0f\x0b\x20\x00\x2d\x00\x00\x20\x02\x46\x04\x40\x20\x00\x41\x01\x6a\x21\x00\x0c\x01\x0b\x0b\x20\x00\x0f\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x08\x00\x00\x0b\x0b\x93\x80\x80\x80\x00\x01\x01\x10\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"); + +// memory_init.wast:948 +assert_trap(() => call($23, "run", [0, -4])); + +// memory_init.wast:951 +assert_return(() => call($23, "checkRange", [0, 1, 0]), -1); + +// memory_init.wast:954 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0c\x81\x80\x80\x80\x00\x41\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\xfc\x08\x40\x00\x0b\x0b\x83\x81\x80\x80\x00\x41\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/ref_func.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/ref_func.wast.js new file mode 100644 index 0000000000..e7aa8a460f --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/ref_func.wast.js @@ -0,0 +1,51 @@ + +// ref_func.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// ref_func.wast:4 +register("M", $1) + +// ref_func.wast:6 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x01\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x02\x87\x80\x80\x80\x00\x01\x01\x4d\x01\x66\x00\x00\x03\x8f\x80\x80\x80\x00\x0e\x00\x01\x01\x01\x01\x01\x02\x02\x02\x01\x01\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x06\x9a\x80\x80\x80\x00\x05\x70\x00\xd2\x00\x0b\x70\x00\xd2\x01\x0b\x70\x01\xd2\x00\x0b\x70\x00\xd2\x03\x0b\x70\x00\xd2\x04\x0b\x07\xd0\x80\x80\x80\x00\x08\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x66\x00\x07\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x67\x00\x08\x09\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x76\x00\x09\x05\x73\x65\x74\x2d\x66\x00\x0a\x05\x73\x65\x74\x2d\x67\x00\x0b\x06\x63\x61\x6c\x6c\x2d\x66\x00\x0c\x06\x63\x61\x6c\x6c\x2d\x67\x00\x0d\x06\x63\x61\x6c\x6c\x2d\x76\x00\x0e\x09\x90\x80\x80\x80\x00\x03\x03\x00\x02\x03\x05\x03\x00\x02\x04\x06\x03\x00\x02\x00\x01\x0a\xa9\x81\x80\x80\x00\x0e\x87\x80\x80\x80\x00\x00\x20\x00\x41\x01\x6a\x0b\x88\x80\x80\x80\x00\x00\xd2\x05\x1a\xd2\x06\x1a\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x86\x80\x80\x80\x00\x00\xd2\x00\xd1\x70\x0b\x86\x80\x80\x80\x00\x00\xd2\x01\xd1\x70\x0b\x86\x80\x80\x80\x00\x00\x23\x02\xd1\x70\x0b\x86\x80\x80\x80\x00\x00\xd2\x00\x24\x02\x0b\x86\x80\x80\x80\x00\x00\xd2\x01\x24\x02\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\xd2\x00\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\xd2\x01\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\x23\x02\x26\x00\x20\x00\x41\x00\x11\x00\x00\x0b"); + +// ref_func.wast:56 +assert_return(() => call($2, "is_null-f", []), 0); + +// ref_func.wast:57 +assert_return(() => call($2, "is_null-g", []), 0); + +// ref_func.wast:58 +assert_return(() => call($2, "is_null-v", []), 0); + +// ref_func.wast:60 +assert_return(() => call($2, "call-f", [4]), 4); + +// ref_func.wast:61 +assert_return(() => call($2, "call-g", [4]), 5); + +// ref_func.wast:62 +assert_return(() => call($2, "call-v", [4]), 4); + +// ref_func.wast:63 +run(() => call($2, "set-g", [])); + +// ref_func.wast:64 +assert_return(() => call($2, "call-v", [4]), 5); + +// ref_func.wast:65 +run(() => call($2, "set-f", [])); + +// ref_func.wast:66 +assert_return(() => call($2, "call-v", [4]), 4); + +// ref_func.wast:68 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x02\x8d\x80\x80\x80\x00\x02\x01\x4d\x01\x66\x00\x00\x01\x4d\x01\x67\x00\x00\x06\x86\x80\x80\x80\x00\x01\x70\x00\xd2\x07\x0b"); + +// ref_func.wast:80 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x06\x86\x80\x80\x80\x00\x01\x70\x00\xd2\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x01\x09\x95\x80\x80\x80\x00\x04\x00\x41\x00\x0b\x01\x02\x00\x41\x00\x0b\x01\x03\x01\x00\x01\x04\x01\x00\x01\x05\x0a\xbf\x80\x80\x80\x00\x07\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\xd2\x00\xd2\x01\xd2\x02\xd2\x03\xd2\x04\xd2\x05\x0f\x0b"); + +// ref_func.wast:108 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xd2\x00\x1a\x0b"); + +// ref_func.wast:112 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x08\x81\x80\x80\x80\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xd2\x00\x1a\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/ref_is_null.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/ref_is_null.wast.js new file mode 100644 index 0000000000..f4922d3bfc --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/ref_is_null.wast.js @@ -0,0 +1,42 @@ + +// ref_is_null.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x05\x60\x01\x70\x01\x7f\x60\x01\x6f\x01\x7f\x60\x00\x00\x60\x01\x6f\x00\x60\x01\x7f\x01\x7f\x03\x88\x80\x80\x80\x00\x07\x00\x01\x02\x03\x02\x04\x04\x04\x87\x80\x80\x80\x00\x02\x70\x00\x02\x6f\x00\x02\x07\xc7\x80\x80\x80\x00\x06\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x00\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x04\x69\x6e\x69\x74\x00\x03\x06\x64\x65\x69\x6e\x69\x74\x00\x04\x0c\x66\x75\x6e\x63\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x05\x0e\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x2d\x65\x6c\x65\x6d\x00\x06\x09\x87\x80\x80\x80\x00\x01\x00\x41\x01\x0b\x01\x02\x0a\xd8\x80\x80\x80\x00\x07\x86\x80\x80\x80\x00\x00\x20\x00\xd1\x70\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xd1\x6f\x0b\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x01\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\xd0\x70\x26\x00\x41\x01\xd0\x6f\x26\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x00\x10\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x25\x01\x10\x01\x0b"); + +// ref_is_null.wast:30 +assert_return(() => call($1, "funcref", [null]), 1); + +// ref_is_null.wast:31 +assert_return(() => call($1, "externref", [null]), 1); + +// ref_is_null.wast:33 +assert_return(() => call($1, "externref", [externref(1)]), 0); + +// ref_is_null.wast:35 +run(() => call($1, "init", [externref(0)])); + +// ref_is_null.wast:37 +assert_return(() => call($1, "funcref-elem", [0]), 1); + +// ref_is_null.wast:38 +assert_return(() => call($1, "externref-elem", [0]), 1); + +// ref_is_null.wast:40 +assert_return(() => call($1, "funcref-elem", [1]), 0); + +// ref_is_null.wast:41 +assert_return(() => call($1, "externref-elem", [1]), 0); + +// ref_is_null.wast:43 +run(() => call($1, "deinit", [])); + +// ref_is_null.wast:45 +assert_return(() => call($1, "funcref-elem", [0]), 1); + +// ref_is_null.wast:46 +assert_return(() => call($1, "externref-elem", [0]), 1); + +// ref_is_null.wast:48 +assert_return(() => call($1, "funcref-elem", [1]), 1); + +// ref_is_null.wast:49 +assert_return(() => call($1, "externref-elem", [1]), 1); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/ref_null.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/ref_null.wast.js new file mode 100644 index 0000000000..2ab8e71dc8 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/ref_null.wast.js @@ -0,0 +1,9 @@ + +// ref_null.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x01\x6f\x60\x00\x01\x70\x03\x83\x80\x80\x80\x00\x02\x00\x01\x06\x8b\x80\x80\x80\x00\x02\x6f\x00\xd0\x6f\x0b\x70\x00\xd0\x70\x0b\x07\x97\x80\x80\x80\x00\x02\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x00\x07\x66\x75\x6e\x63\x72\x65\x66\x00\x01\x0a\x93\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\xd0\x6f\x0b\x84\x80\x80\x80\x00\x00\xd0\x70\x0b"); + +// ref_null.wast:9 +assert_return(() => call($1, "externref", []), null); + +// ref_null.wast:10 +assert_return(() => call($1, "funcref", []), null); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/select.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/select.wast.js new file mode 100644 index 0000000000..dd098d8dc9 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/select.wast.js @@ -0,0 +1,423 @@ + +// select.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xbd\x80\x80\x80\x00\x0a\x60\x02\x7f\x7f\x01\x7f\x60\x00\x00\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x60\x03\x7d\x7d\x7f\x01\x7d\x60\x03\x7c\x7c\x7f\x01\x7c\x60\x03\x70\x70\x7f\x01\x70\x60\x03\x6f\x6f\x7f\x01\x6f\x60\x01\x7f\x01\x7f\x60\x01\x7f\x00\x03\xb2\x80\x80\x80\x00\x31\x01\x02\x03\x04\x05\x02\x03\x04\x05\x06\x07\x08\x08\x01\x08\x08\x08\x08\x08\x08\x09\x08\x08\x08\x08\x08\x08\x00\x08\x08\x08\x09\x09\x08\x08\x08\x08\x09\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x04\x89\x80\x80\x80\x00\x02\x70\x01\x01\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xaa\x86\x80\x80\x00\x2e\x0a\x73\x65\x6c\x65\x63\x74\x2d\x69\x33\x32\x00\x01\x0a\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x00\x02\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x03\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x04\x0c\x73\x65\x6c\x65\x63\x74\x2d\x69\x33\x32\x2d\x74\x00\x05\x0c\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x2d\x74\x00\x06\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x07\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x08\x0e\x73\x65\x6c\x65\x63\x74\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x09\x10\x73\x65\x6c\x65\x63\x74\x2d\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x0a\x10\x73\x65\x6c\x65\x63\x74\x2d\x74\x72\x61\x70\x2d\x6c\x65\x66\x74\x00\x0b\x11\x73\x65\x6c\x65\x63\x74\x2d\x74\x72\x61\x70\x2d\x72\x69\x67\x68\x74\x00\x0c\x10\x73\x65\x6c\x65\x63\x74\x2d\x75\x6e\x72\x65\x61\x63\x68\x65\x64\x00\x0d\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x0e\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x0f\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x10\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x11\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x12\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x13\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x14\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x15\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x16\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x17\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x18\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x19\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x1a\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x1c\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x1d\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x1e\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x1f\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x20\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x21\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x23\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x24\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x25\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x26\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x27\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x28\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x29\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2a\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2b\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2c\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2d\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x2e\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x2f\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x30\x09\x8f\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x01\x00\x02\x01\x41\x00\x0b\x00\x01\x1b\x0a\xef\x86\x80\x80\x00\x31\x82\x80\x80\x80\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1b\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1b\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1b\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1b\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x7f\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x7e\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x7d\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x7c\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x70\x0b\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\x1c\x01\x6f\x0b\x88\x80\x80\x80\x00\x00\x00\x41\x00\x20\x00\x1b\x0b\x88\x80\x80\x80\x00\x00\x41\x00\x00\x20\x00\x1b\x0b\x98\x80\x80\x80\x00\x00\x00\x1b\x00\x41\x00\x1b\x00\x41\x00\x41\x00\x1b\x00\x43\x00\x00\x00\x00\x41\x00\x1b\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x01\x20\x00\x1b\x41\x02\x41\x03\x1b\x0b\x8e\x80\x80\x80\x00\x00\x41\x02\x41\x00\x41\x01\x20\x00\x1b\x41\x03\x1b\x0b\x8e\x80\x80\x80\x00\x00\x41\x02\x41\x03\x41\x00\x41\x01\x20\x00\x1b\x1b\x0b\x90\x80\x80\x80\x00\x00\x03\x7f\x41\x02\x41\x03\x20\x00\x1b\x10\x00\x10\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x41\x02\x41\x03\x20\x00\x1b\x10\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x10\x00\x41\x02\x41\x03\x20\x00\x1b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x02\x41\x03\x20\x00\x1b\x04\x40\x10\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x02\x41\x03\x20\x00\x1b\x05\x41\x04\x0b\x0b\x91\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x41\x02\x05\x41\x02\x41\x03\x20\x00\x1b\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x03\x20\x00\x1b\x41\x04\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x02\x41\x03\x20\x00\x1b\x0d\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x03\x20\x00\x1b\x41\x02\x0e\x01\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x02\x41\x03\x20\x00\x1b\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x03\x20\x00\x1b\x41\x01\x41\x00\x11\x00\x01\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x03\x20\x00\x1b\x41\x00\x11\x00\x01\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x41\x02\x41\x03\x20\x00\x1b\x11\x00\x01\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x04\x20\x00\x1b\x41\x01\x36\x02\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x41\x01\x41\x02\x20\x00\x1b\x36\x02\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x10\x22\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x0f\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x1a\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x20\x00\x1b\x0c\x00\x0b\x0b\x8f\x80\x80\x80\x00\x01\x01\x7f\x41\x01\x41\x02\x20\x00\x1b\x21\x00\x20\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x22\x00\x0b\x8d\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x24\x00\x23\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x04\x20\x00\x1b\x28\x02\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x00\x41\x01\x20\x00\x1b\x45\x0b\x91\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x1b\x41\x01\x41\x02\x20\x00\x1b\x6c\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x20\x00\x1b\x45\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x20\x00\x1b\x41\x01\x4c\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x00\x41\x01\x20\x00\x1b\x47\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x42\x00\x20\x00\x1b\xa7\x0b\x0b"); + +// select.wast:200 +assert_return(() => call($1, "select-i32", [1, 2, 1]), 1); + +// select.wast:201 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\x01\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64", [int64("2"), int64("1"), 1]), int64("2")) + +// select.wast:202 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x00\x40\x41\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [1., 2., 1]), 1.) + +// select.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [1., 2., 1]), 1.) + +// select.wast:205 +assert_return(() => call($1, "select-i32", [1, 2, 0]), 2); + +// select.wast:206 +assert_return(() => call($1, "select-i32", [2, 1, 0]), 1); + +// select.wast:207 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\x7f\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64", [int64("2"), int64("1"), -1]), int64("2")) + +// select.wast:208 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\xf0\xe1\xc3\x87\x7f\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64", [int64("2"), int64("1"), -252_645_136]), int64("2")) + +// select.wast:210 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x43\x00\x00\x80\x3f\x41\x01\x10\x00\xbc\x43\x00\x00\xc0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [NaN, 1., 1]), NaN) + +// select.wast:211 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x04\x03\x82\x7f\x43\x00\x00\x80\x3f\x41\x01\x10\x00\xbc\x43\x04\x03\x82\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [NaN, 1., 1]), NaN) + +// select.wast:212 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x43\x00\x00\x80\x3f\x41\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [NaN, 1., 0]), 1.) + +// select.wast:213 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x04\x03\x82\x7f\x43\x00\x00\x80\x3f\x41\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [NaN, 1., 0]), 1.) + +// select.wast:214 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\xc0\x7f\x41\x01\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [2., NaN, 1]), 2.) + +// select.wast:215 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x04\x03\x82\x7f\x41\x01\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [2., NaN, 1]), 2.) + +// select.wast:216 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\xc0\x7f\x41\x00\x10\x00\xbc\x43\x00\x00\xc0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [2., NaN, 0]), NaN) + +// select.wast:217 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x04\x03\x82\x7f\x41\x00\x10\x00\xbc\x43\x04\x03\x82\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32", [2., NaN, 0]), NaN) + +// select.wast:219 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [NaN, 1., 1]), NaN) + +// select.wast:220 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\xbd\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [NaN, 1., 1]), NaN) + +// select.wast:221 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [NaN, 1., 0]), 1.) + +// select.wast:222 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [NaN, 1., 0]), 1.) + +// select.wast:223 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [2., NaN, 1]), 2.) + +// select.wast:224 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [2., NaN, 1]), 2.) + +// select.wast:225 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [2., NaN, 0]), NaN) + +// select.wast:226 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x86\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0a\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x41\x00\x10\x00\xbd\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64", [2., NaN, 0]), NaN) + +// select.wast:228 +assert_return(() => call($1, "select-i32-t", [1, 2, 1]), 1); + +// select.wast:229 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\x01\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64-t", [int64("2"), int64("1"), 1]), int64("2")) + +// select.wast:230 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x00\x40\x41\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [1., 2., 1]), 1.) + +// select.wast:231 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [1., 2., 1]), 1.) + +// select.wast:232 +assert_return(() => call($1, "select-funcref", [null, null, 1]), null); + +// select.wast:233 +assert_return(() => call($1, "select-externref", [externref(1), externref(2), 1]), externref(1)); + +// select.wast:235 +assert_return(() => call($1, "select-i32-t", [1, 2, 0]), 2); + +// select.wast:236 +assert_return(() => call($1, "select-i32-t", [2, 1, 0]), 1); + +// select.wast:237 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\x7f\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64-t", [int64("2"), int64("1"), -1]), int64("2")) + +// select.wast:238 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7e\x7e\x7f\x01\x7e\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x69\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x01\x41\xf0\xe1\xc3\x87\x7f\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-i64-t", [int64("2"), int64("1"), -252_645_136]), int64("2")) + +// select.wast:239 +assert_return(() => call($1, "select-externref", [externref(1), externref(2), 0]), externref(2)); + +// select.wast:240 +assert_return(() => call($1, "select-externref", [externref(2), externref(1), 0]), externref(1)); + +// select.wast:242 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x43\x00\x00\x80\x3f\x41\x01\x10\x00\xbc\x43\x00\x00\xc0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [NaN, 1., 1]), NaN) + +// select.wast:243 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x04\x03\x82\x7f\x43\x00\x00\x80\x3f\x41\x01\x10\x00\xbc\x43\x04\x03\x82\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [NaN, 1., 1]), NaN) + +// select.wast:244 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x43\x00\x00\x80\x3f\x41\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [NaN, 1., 0]), 1.) + +// select.wast:245 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x04\x03\x82\x7f\x43\x00\x00\x80\x3f\x41\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [NaN, 1., 0]), 1.) + +// select.wast:246 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\xc0\x7f\x41\x01\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [2., NaN, 1]), 2.) + +// select.wast:247 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x04\x03\x82\x7f\x41\x01\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [2., NaN, 1]), 2.) + +// select.wast:248 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\xc0\x7f\x41\x00\x10\x00\xbc\x43\x00\x00\xc0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [2., NaN, 0]), NaN) + +// select.wast:249 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7d\x7d\x7f\x01\x7d\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x33\x32\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x04\x03\x82\x7f\x41\x00\x10\x00\xbc\x43\x04\x03\x82\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f32-t", [2., NaN, 0]), NaN) + +// select.wast:251 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [NaN, 1., 1]), NaN) + +// select.wast:252 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\xbd\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [NaN, 1., 1]), NaN) + +// select.wast:253 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [NaN, 1., 0]), 1.) + +// select.wast:254 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [NaN, 1., 0]), 1.) + +// select.wast:255 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [2., NaN, 1]), 2.) + +// select.wast:256 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [2., NaN, 1]), 2.) + +// select.wast:257 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [2., NaN, 0]), NaN) + +// select.wast:258 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa6\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x6f\x01\x7f\x60\x01\x70\x01\x7f\x60\x02\x6f\x6f\x01\x7f\x60\x02\x70\x70\x01\x7f\x60\x03\x7c\x7c\x7f\x01\x7c\x02\x88\x81\x80\x80\x00\x06\x06\x6d\x6f\x64\x75\x6c\x65\x0c\x73\x65\x6c\x65\x63\x74\x2d\x66\x36\x34\x2d\x74\x00\x06\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x69\x73\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x69\x73\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0c\x65\x71\x5f\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x04\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x65\x71\x5f\x66\x75\x6e\x63\x72\x65\x66\x00\x05\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x06\x0a\xb2\x80\x80\x80\x00\x01\xac\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\x41\x00\x10\x00\xbd\x44\x04\x03\x02\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports($1)), "run", [])); // assert_return(() => call($1, "select-f64-t", [2., NaN, 0]), NaN) + +// select.wast:260 +assert_trap(() => call($1, "select-trap-left", [1])); + +// select.wast:261 +assert_trap(() => call($1, "select-trap-left", [0])); + +// select.wast:262 +assert_trap(() => call($1, "select-trap-right", [1])); + +// select.wast:263 +assert_trap(() => call($1, "select-trap-right", [0])); + +// select.wast:265 +assert_return(() => call($1, "as-select-first", [0]), 1); + +// select.wast:266 +assert_return(() => call($1, "as-select-first", [1]), 0); + +// select.wast:267 +assert_return(() => call($1, "as-select-mid", [0]), 2); + +// select.wast:268 +assert_return(() => call($1, "as-select-mid", [1]), 2); + +// select.wast:269 +assert_return(() => call($1, "as-select-last", [0]), 2); + +// select.wast:270 +assert_return(() => call($1, "as-select-last", [1]), 3); + +// select.wast:272 +assert_return(() => call($1, "as-loop-first", [0]), 3); + +// select.wast:273 +assert_return(() => call($1, "as-loop-first", [1]), 2); + +// select.wast:274 +assert_return(() => call($1, "as-loop-mid", [0]), 3); + +// select.wast:275 +assert_return(() => call($1, "as-loop-mid", [1]), 2); + +// select.wast:276 +assert_return(() => call($1, "as-loop-last", [0]), 3); + +// select.wast:277 +assert_return(() => call($1, "as-loop-last", [1]), 2); + +// select.wast:279 +assert_return(() => call($1, "as-if-condition", [0])); + +// select.wast:280 +assert_return(() => call($1, "as-if-condition", [1])); + +// select.wast:281 +assert_return(() => call($1, "as-if-then", [0]), 3); + +// select.wast:282 +assert_return(() => call($1, "as-if-then", [1]), 2); + +// select.wast:283 +assert_return(() => call($1, "as-if-else", [0]), 3); + +// select.wast:284 +assert_return(() => call($1, "as-if-else", [1]), 2); + +// select.wast:286 +assert_return(() => call($1, "as-br_if-first", [0]), 3); + +// select.wast:287 +assert_return(() => call($1, "as-br_if-first", [1]), 2); + +// select.wast:288 +assert_return(() => call($1, "as-br_if-last", [0]), 2); + +// select.wast:289 +assert_return(() => call($1, "as-br_if-last", [1]), 2); + +// select.wast:291 +assert_return(() => call($1, "as-br_table-first", [0]), 3); + +// select.wast:292 +assert_return(() => call($1, "as-br_table-first", [1]), 2); + +// select.wast:293 +assert_return(() => call($1, "as-br_table-last", [0]), 2); + +// select.wast:294 +assert_return(() => call($1, "as-br_table-last", [1]), 2); + +// select.wast:296 +assert_return(() => call($1, "as-call_indirect-first", [0]), 3); + +// select.wast:298 +assert_return(() => call($1, "as-call_indirect-mid", [0]), 1); + +// select.wast:299 +assert_return(() => call($1, "as-call_indirect-mid", [1]), 1); + +// select.wast:300 +assert_trap(() => call($1, "as-call_indirect-last", [0])); + +// select.wast:301 +assert_trap(() => call($1, "as-call_indirect-last", [1])); + +// select.wast:303 +assert_return(() => call($1, "as-store-first", [0])); + +// select.wast:304 +assert_return(() => call($1, "as-store-first", [1])); + +// select.wast:305 +assert_return(() => call($1, "as-store-last", [0])); + +// select.wast:306 +assert_return(() => call($1, "as-store-last", [1])); + +// select.wast:308 +assert_return(() => call($1, "as-memory.grow-value", [0]), 1); + +// select.wast:309 +assert_return(() => call($1, "as-memory.grow-value", [1]), 3); + +// select.wast:311 +assert_return(() => call($1, "as-call-value", [0]), 2); + +// select.wast:312 +assert_return(() => call($1, "as-call-value", [1]), 1); + +// select.wast:313 +assert_return(() => call($1, "as-return-value", [0]), 2); + +// select.wast:314 +assert_return(() => call($1, "as-return-value", [1]), 1); + +// select.wast:315 +assert_return(() => call($1, "as-drop-operand", [0])); + +// select.wast:316 +assert_return(() => call($1, "as-drop-operand", [1])); + +// select.wast:317 +assert_return(() => call($1, "as-br-value", [0]), 2); + +// select.wast:318 +assert_return(() => call($1, "as-br-value", [1]), 1); + +// select.wast:319 +assert_return(() => call($1, "as-local.set-value", [0]), 2); + +// select.wast:320 +assert_return(() => call($1, "as-local.set-value", [1]), 1); + +// select.wast:321 +assert_return(() => call($1, "as-local.tee-value", [0]), 2); + +// select.wast:322 +assert_return(() => call($1, "as-local.tee-value", [1]), 1); + +// select.wast:323 +assert_return(() => call($1, "as-global.set-value", [0]), 2); + +// select.wast:324 +assert_return(() => call($1, "as-global.set-value", [1]), 1); + +// select.wast:325 +assert_return(() => call($1, "as-load-operand", [0]), 1); + +// select.wast:326 +assert_return(() => call($1, "as-load-operand", [1]), 1); + +// select.wast:328 +assert_return(() => call($1, "as-unary-operand", [0]), 0); + +// select.wast:329 +assert_return(() => call($1, "as-unary-operand", [1]), 1); + +// select.wast:330 +assert_return(() => call($1, "as-binary-operand", [0]), 4); + +// select.wast:331 +assert_return(() => call($1, "as-binary-operand", [1]), 1); + +// select.wast:332 +assert_return(() => call($1, "as-test-operand", [0]), 0); + +// select.wast:333 +assert_return(() => call($1, "as-test-operand", [1]), 1); + +// select.wast:334 +assert_return(() => call($1, "as-compare-left", [0]), 0); + +// select.wast:335 +assert_return(() => call($1, "as-compare-left", [1]), 1); + +// select.wast:336 +assert_return(() => call($1, "as-compare-right", [0]), 0); + +// select.wast:337 +assert_return(() => call($1, "as-compare-right", [1]), 1); + +// select.wast:338 +assert_return(() => call($1, "as-convert-operand", [0]), 0); + +// select.wast:339 +assert_return(() => call($1, "as-convert-operand", [1]), 1); + +// select.wast:341 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x01\x01\x41\x01\x1b\x0b"); + +// select.wast:345 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x01\x01\x41\x01\x1c\x00\x0b"); + +// select.wast:349 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x01\x1c\x02\x7f\x7f\x0b"); + +// select.wast:361 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x6f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x20\x00\x20\x00\x41\x01\x1b\x1a\x0b"); + +// select.wast:368 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x42\x01\x41\x01\x1b\x1a\x0b"); + +// select.wast:374 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x41\x01\x1b\x1a\x0b"); + +// select.wast:380 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x1b\x1a\x0b"); + +// select.wast:388 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x1b\x1a\x0b"); + +// select.wast:396 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x1b\x1a\x0b"); + +// select.wast:404 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x41\x00\x1b\x1a\x0b"); + +// select.wast:412 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x02\x40\x1b\x1a\x0b\x0b"); + +// select.wast:421 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x02\x40\x41\x00\x1b\x1a\x0b\x0b"); + +// select.wast:430 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x02\x40\x41\x00\x41\x00\x1b\x1a\x0b\x0b"); + +// select.wast:439 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x03\x40\x1b\x1a\x0b\x0b"); + +// select.wast:448 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x03\x40\x41\x00\x1b\x1a\x0b\x0b"); + +// select.wast:457 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x03\x40\x41\x00\x41\x00\x1b\x1a\x0b\x0b"); + +// select.wast:466 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x04\x40\x1b\x1a\x0b\x0b"); + +// select.wast:475 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x41\x00\x1b\x1a\x0b\x0b"); + +// select.wast:484 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x04\x40\x41\x00\x41\x00\x1b\x1a\x0b\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table-sub.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table-sub.wast.js new file mode 100644 index 0000000000..0bd74f83e2 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table-sub.wast.js @@ -0,0 +1,6 @@ + +// table-sub.wast:1 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x87\x80\x80\x80\x00\x02\x70\x00\x0a\x6f\x00\x0a\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x01\x41\x02\xfc\x0e\x00\x01\x0b"); + +// table-sub.wast:12 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x09\x84\x80\x80\x80\x00\x01\x05\x6f\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x01\x41\x02\xfc\x0c\x00\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_copy.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_copy.wast.js new file mode 100644 index 0000000000..58d9d17daf --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_copy.wast.js @@ -0,0 +1,5184 @@ + +// table_copy.wast:6 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x00\x00\x07\x9f\x80\x80\x80\x00\x05\x03\x65\x66\x30\x00\x00\x03\x65\x66\x31\x00\x01\x03\x65\x66\x32\x00\x02\x03\x65\x66\x33\x00\x03\x03\x65\x66\x34\x00\x04\x0a\xae\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b"); + +// table_copy.wast:13 +register("a", $1) + +// table_copy.wast:15 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xce\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:45 +run(() => call($2, "test", [])); + +// table_copy.wast:46 +assert_trap(() => call($2, "check_t0", [0])); + +// table_copy.wast:47 +assert_trap(() => call($2, "check_t0", [1])); + +// table_copy.wast:48 +assert_return(() => call($2, "check_t0", [2]), 3); + +// table_copy.wast:49 +assert_return(() => call($2, "check_t0", [3]), 1); + +// table_copy.wast:50 +assert_return(() => call($2, "check_t0", [4]), 4); + +// table_copy.wast:51 +assert_return(() => call($2, "check_t0", [5]), 1); + +// table_copy.wast:52 +assert_trap(() => call($2, "check_t0", [6])); + +// table_copy.wast:53 +assert_trap(() => call($2, "check_t0", [7])); + +// table_copy.wast:54 +assert_trap(() => call($2, "check_t0", [8])); + +// table_copy.wast:55 +assert_trap(() => call($2, "check_t0", [9])); + +// table_copy.wast:56 +assert_trap(() => call($2, "check_t0", [10])); + +// table_copy.wast:57 +assert_trap(() => call($2, "check_t0", [11])); + +// table_copy.wast:58 +assert_return(() => call($2, "check_t0", [12]), 7); + +// table_copy.wast:59 +assert_return(() => call($2, "check_t0", [13]), 5); + +// table_copy.wast:60 +assert_return(() => call($2, "check_t0", [14]), 2); + +// table_copy.wast:61 +assert_return(() => call($2, "check_t0", [15]), 3); + +// table_copy.wast:62 +assert_return(() => call($2, "check_t0", [16]), 6); + +// table_copy.wast:63 +assert_trap(() => call($2, "check_t0", [17])); + +// table_copy.wast:64 +assert_trap(() => call($2, "check_t0", [18])); + +// table_copy.wast:65 +assert_trap(() => call($2, "check_t0", [19])); + +// table_copy.wast:66 +assert_trap(() => call($2, "check_t0", [20])); + +// table_copy.wast:67 +assert_trap(() => call($2, "check_t0", [21])); + +// table_copy.wast:68 +assert_trap(() => call($2, "check_t0", [22])); + +// table_copy.wast:69 +assert_trap(() => call($2, "check_t0", [23])); + +// table_copy.wast:70 +assert_trap(() => call($2, "check_t0", [24])); + +// table_copy.wast:71 +assert_trap(() => call($2, "check_t0", [25])); + +// table_copy.wast:72 +assert_trap(() => call($2, "check_t0", [26])); + +// table_copy.wast:73 +assert_trap(() => call($2, "check_t0", [27])); + +// table_copy.wast:74 +assert_trap(() => call($2, "check_t0", [28])); + +// table_copy.wast:75 +assert_trap(() => call($2, "check_t0", [29])); + +// table_copy.wast:76 +assert_trap(() => call($2, "check_t1", [0])); + +// table_copy.wast:77 +assert_trap(() => call($2, "check_t1", [1])); + +// table_copy.wast:78 +assert_trap(() => call($2, "check_t1", [2])); + +// table_copy.wast:79 +assert_return(() => call($2, "check_t1", [3]), 1); + +// table_copy.wast:80 +assert_return(() => call($2, "check_t1", [4]), 3); + +// table_copy.wast:81 +assert_return(() => call($2, "check_t1", [5]), 1); + +// table_copy.wast:82 +assert_return(() => call($2, "check_t1", [6]), 4); + +// table_copy.wast:83 +assert_trap(() => call($2, "check_t1", [7])); + +// table_copy.wast:84 +assert_trap(() => call($2, "check_t1", [8])); + +// table_copy.wast:85 +assert_trap(() => call($2, "check_t1", [9])); + +// table_copy.wast:86 +assert_trap(() => call($2, "check_t1", [10])); + +// table_copy.wast:87 +assert_return(() => call($2, "check_t1", [11]), 6); + +// table_copy.wast:88 +assert_return(() => call($2, "check_t1", [12]), 3); + +// table_copy.wast:89 +assert_return(() => call($2, "check_t1", [13]), 2); + +// table_copy.wast:90 +assert_return(() => call($2, "check_t1", [14]), 5); + +// table_copy.wast:91 +assert_return(() => call($2, "check_t1", [15]), 7); + +// table_copy.wast:92 +assert_trap(() => call($2, "check_t1", [16])); + +// table_copy.wast:93 +assert_trap(() => call($2, "check_t1", [17])); + +// table_copy.wast:94 +assert_trap(() => call($2, "check_t1", [18])); + +// table_copy.wast:95 +assert_trap(() => call($2, "check_t1", [19])); + +// table_copy.wast:96 +assert_trap(() => call($2, "check_t1", [20])); + +// table_copy.wast:97 +assert_trap(() => call($2, "check_t1", [21])); + +// table_copy.wast:98 +assert_trap(() => call($2, "check_t1", [22])); + +// table_copy.wast:99 +assert_trap(() => call($2, "check_t1", [23])); + +// table_copy.wast:100 +assert_trap(() => call($2, "check_t1", [24])); + +// table_copy.wast:101 +assert_trap(() => call($2, "check_t1", [25])); + +// table_copy.wast:102 +assert_trap(() => call($2, "check_t1", [26])); + +// table_copy.wast:103 +assert_trap(() => call($2, "check_t1", [27])); + +// table_copy.wast:104 +assert_trap(() => call($2, "check_t1", [28])); + +// table_copy.wast:105 +assert_trap(() => call($2, "check_t1", [29])); + +// table_copy.wast:107 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x02\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:137 +run(() => call($3, "test", [])); + +// table_copy.wast:138 +assert_trap(() => call($3, "check_t0", [0])); + +// table_copy.wast:139 +assert_trap(() => call($3, "check_t0", [1])); + +// table_copy.wast:140 +assert_return(() => call($3, "check_t0", [2]), 3); + +// table_copy.wast:141 +assert_return(() => call($3, "check_t0", [3]), 1); + +// table_copy.wast:142 +assert_return(() => call($3, "check_t0", [4]), 4); + +// table_copy.wast:143 +assert_return(() => call($3, "check_t0", [5]), 1); + +// table_copy.wast:144 +assert_trap(() => call($3, "check_t0", [6])); + +// table_copy.wast:145 +assert_trap(() => call($3, "check_t0", [7])); + +// table_copy.wast:146 +assert_trap(() => call($3, "check_t0", [8])); + +// table_copy.wast:147 +assert_trap(() => call($3, "check_t0", [9])); + +// table_copy.wast:148 +assert_trap(() => call($3, "check_t0", [10])); + +// table_copy.wast:149 +assert_trap(() => call($3, "check_t0", [11])); + +// table_copy.wast:150 +assert_return(() => call($3, "check_t0", [12]), 7); + +// table_copy.wast:151 +assert_return(() => call($3, "check_t0", [13]), 3); + +// table_copy.wast:152 +assert_return(() => call($3, "check_t0", [14]), 1); + +// table_copy.wast:153 +assert_return(() => call($3, "check_t0", [15]), 4); + +// table_copy.wast:154 +assert_return(() => call($3, "check_t0", [16]), 6); + +// table_copy.wast:155 +assert_trap(() => call($3, "check_t0", [17])); + +// table_copy.wast:156 +assert_trap(() => call($3, "check_t0", [18])); + +// table_copy.wast:157 +assert_trap(() => call($3, "check_t0", [19])); + +// table_copy.wast:158 +assert_trap(() => call($3, "check_t0", [20])); + +// table_copy.wast:159 +assert_trap(() => call($3, "check_t0", [21])); + +// table_copy.wast:160 +assert_trap(() => call($3, "check_t0", [22])); + +// table_copy.wast:161 +assert_trap(() => call($3, "check_t0", [23])); + +// table_copy.wast:162 +assert_trap(() => call($3, "check_t0", [24])); + +// table_copy.wast:163 +assert_trap(() => call($3, "check_t0", [25])); + +// table_copy.wast:164 +assert_trap(() => call($3, "check_t0", [26])); + +// table_copy.wast:165 +assert_trap(() => call($3, "check_t0", [27])); + +// table_copy.wast:166 +assert_trap(() => call($3, "check_t0", [28])); + +// table_copy.wast:167 +assert_trap(() => call($3, "check_t0", [29])); + +// table_copy.wast:168 +assert_trap(() => call($3, "check_t1", [0])); + +// table_copy.wast:169 +assert_trap(() => call($3, "check_t1", [1])); + +// table_copy.wast:170 +assert_trap(() => call($3, "check_t1", [2])); + +// table_copy.wast:171 +assert_return(() => call($3, "check_t1", [3]), 1); + +// table_copy.wast:172 +assert_return(() => call($3, "check_t1", [4]), 3); + +// table_copy.wast:173 +assert_return(() => call($3, "check_t1", [5]), 1); + +// table_copy.wast:174 +assert_return(() => call($3, "check_t1", [6]), 4); + +// table_copy.wast:175 +assert_trap(() => call($3, "check_t1", [7])); + +// table_copy.wast:176 +assert_trap(() => call($3, "check_t1", [8])); + +// table_copy.wast:177 +assert_trap(() => call($3, "check_t1", [9])); + +// table_copy.wast:178 +assert_trap(() => call($3, "check_t1", [10])); + +// table_copy.wast:179 +assert_return(() => call($3, "check_t1", [11]), 6); + +// table_copy.wast:180 +assert_return(() => call($3, "check_t1", [12]), 3); + +// table_copy.wast:181 +assert_return(() => call($3, "check_t1", [13]), 2); + +// table_copy.wast:182 +assert_return(() => call($3, "check_t1", [14]), 5); + +// table_copy.wast:183 +assert_return(() => call($3, "check_t1", [15]), 7); + +// table_copy.wast:184 +assert_trap(() => call($3, "check_t1", [16])); + +// table_copy.wast:185 +assert_trap(() => call($3, "check_t1", [17])); + +// table_copy.wast:186 +assert_trap(() => call($3, "check_t1", [18])); + +// table_copy.wast:187 +assert_trap(() => call($3, "check_t1", [19])); + +// table_copy.wast:188 +assert_trap(() => call($3, "check_t1", [20])); + +// table_copy.wast:189 +assert_trap(() => call($3, "check_t1", [21])); + +// table_copy.wast:190 +assert_trap(() => call($3, "check_t1", [22])); + +// table_copy.wast:191 +assert_trap(() => call($3, "check_t1", [23])); + +// table_copy.wast:192 +assert_trap(() => call($3, "check_t1", [24])); + +// table_copy.wast:193 +assert_trap(() => call($3, "check_t1", [25])); + +// table_copy.wast:194 +assert_trap(() => call($3, "check_t1", [26])); + +// table_copy.wast:195 +assert_trap(() => call($3, "check_t1", [27])); + +// table_copy.wast:196 +assert_trap(() => call($3, "check_t1", [28])); + +// table_copy.wast:197 +assert_trap(() => call($3, "check_t1", [29])); + +// table_copy.wast:199 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x0f\x41\x02\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:229 +run(() => call($4, "test", [])); + +// table_copy.wast:230 +assert_trap(() => call($4, "check_t0", [0])); + +// table_copy.wast:231 +assert_trap(() => call($4, "check_t0", [1])); + +// table_copy.wast:232 +assert_return(() => call($4, "check_t0", [2]), 3); + +// table_copy.wast:233 +assert_return(() => call($4, "check_t0", [3]), 1); + +// table_copy.wast:234 +assert_return(() => call($4, "check_t0", [4]), 4); + +// table_copy.wast:235 +assert_return(() => call($4, "check_t0", [5]), 1); + +// table_copy.wast:236 +assert_trap(() => call($4, "check_t0", [6])); + +// table_copy.wast:237 +assert_trap(() => call($4, "check_t0", [7])); + +// table_copy.wast:238 +assert_trap(() => call($4, "check_t0", [8])); + +// table_copy.wast:239 +assert_trap(() => call($4, "check_t0", [9])); + +// table_copy.wast:240 +assert_trap(() => call($4, "check_t0", [10])); + +// table_copy.wast:241 +assert_trap(() => call($4, "check_t0", [11])); + +// table_copy.wast:242 +assert_return(() => call($4, "check_t0", [12]), 7); + +// table_copy.wast:243 +assert_return(() => call($4, "check_t0", [13]), 5); + +// table_copy.wast:244 +assert_return(() => call($4, "check_t0", [14]), 2); + +// table_copy.wast:245 +assert_return(() => call($4, "check_t0", [15]), 3); + +// table_copy.wast:246 +assert_return(() => call($4, "check_t0", [16]), 6); + +// table_copy.wast:247 +assert_trap(() => call($4, "check_t0", [17])); + +// table_copy.wast:248 +assert_trap(() => call($4, "check_t0", [18])); + +// table_copy.wast:249 +assert_trap(() => call($4, "check_t0", [19])); + +// table_copy.wast:250 +assert_trap(() => call($4, "check_t0", [20])); + +// table_copy.wast:251 +assert_trap(() => call($4, "check_t0", [21])); + +// table_copy.wast:252 +assert_trap(() => call($4, "check_t0", [22])); + +// table_copy.wast:253 +assert_trap(() => call($4, "check_t0", [23])); + +// table_copy.wast:254 +assert_trap(() => call($4, "check_t0", [24])); + +// table_copy.wast:255 +assert_return(() => call($4, "check_t0", [25]), 3); + +// table_copy.wast:256 +assert_return(() => call($4, "check_t0", [26]), 6); + +// table_copy.wast:257 +assert_trap(() => call($4, "check_t0", [27])); + +// table_copy.wast:258 +assert_trap(() => call($4, "check_t0", [28])); + +// table_copy.wast:259 +assert_trap(() => call($4, "check_t0", [29])); + +// table_copy.wast:260 +assert_trap(() => call($4, "check_t1", [0])); + +// table_copy.wast:261 +assert_trap(() => call($4, "check_t1", [1])); + +// table_copy.wast:262 +assert_trap(() => call($4, "check_t1", [2])); + +// table_copy.wast:263 +assert_return(() => call($4, "check_t1", [3]), 1); + +// table_copy.wast:264 +assert_return(() => call($4, "check_t1", [4]), 3); + +// table_copy.wast:265 +assert_return(() => call($4, "check_t1", [5]), 1); + +// table_copy.wast:266 +assert_return(() => call($4, "check_t1", [6]), 4); + +// table_copy.wast:267 +assert_trap(() => call($4, "check_t1", [7])); + +// table_copy.wast:268 +assert_trap(() => call($4, "check_t1", [8])); + +// table_copy.wast:269 +assert_trap(() => call($4, "check_t1", [9])); + +// table_copy.wast:270 +assert_trap(() => call($4, "check_t1", [10])); + +// table_copy.wast:271 +assert_return(() => call($4, "check_t1", [11]), 6); + +// table_copy.wast:272 +assert_return(() => call($4, "check_t1", [12]), 3); + +// table_copy.wast:273 +assert_return(() => call($4, "check_t1", [13]), 2); + +// table_copy.wast:274 +assert_return(() => call($4, "check_t1", [14]), 5); + +// table_copy.wast:275 +assert_return(() => call($4, "check_t1", [15]), 7); + +// table_copy.wast:276 +assert_trap(() => call($4, "check_t1", [16])); + +// table_copy.wast:277 +assert_trap(() => call($4, "check_t1", [17])); + +// table_copy.wast:278 +assert_trap(() => call($4, "check_t1", [18])); + +// table_copy.wast:279 +assert_trap(() => call($4, "check_t1", [19])); + +// table_copy.wast:280 +assert_trap(() => call($4, "check_t1", [20])); + +// table_copy.wast:281 +assert_trap(() => call($4, "check_t1", [21])); + +// table_copy.wast:282 +assert_trap(() => call($4, "check_t1", [22])); + +// table_copy.wast:283 +assert_trap(() => call($4, "check_t1", [23])); + +// table_copy.wast:284 +assert_trap(() => call($4, "check_t1", [24])); + +// table_copy.wast:285 +assert_trap(() => call($4, "check_t1", [25])); + +// table_copy.wast:286 +assert_trap(() => call($4, "check_t1", [26])); + +// table_copy.wast:287 +assert_trap(() => call($4, "check_t1", [27])); + +// table_copy.wast:288 +assert_trap(() => call($4, "check_t1", [28])); + +// table_copy.wast:289 +assert_trap(() => call($4, "check_t1", [29])); + +// table_copy.wast:291 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x19\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:321 +run(() => call($5, "test", [])); + +// table_copy.wast:322 +assert_trap(() => call($5, "check_t0", [0])); + +// table_copy.wast:323 +assert_trap(() => call($5, "check_t0", [1])); + +// table_copy.wast:324 +assert_return(() => call($5, "check_t0", [2]), 3); + +// table_copy.wast:325 +assert_return(() => call($5, "check_t0", [3]), 1); + +// table_copy.wast:326 +assert_return(() => call($5, "check_t0", [4]), 4); + +// table_copy.wast:327 +assert_return(() => call($5, "check_t0", [5]), 1); + +// table_copy.wast:328 +assert_trap(() => call($5, "check_t0", [6])); + +// table_copy.wast:329 +assert_trap(() => call($5, "check_t0", [7])); + +// table_copy.wast:330 +assert_trap(() => call($5, "check_t0", [8])); + +// table_copy.wast:331 +assert_trap(() => call($5, "check_t0", [9])); + +// table_copy.wast:332 +assert_trap(() => call($5, "check_t0", [10])); + +// table_copy.wast:333 +assert_trap(() => call($5, "check_t0", [11])); + +// table_copy.wast:334 +assert_return(() => call($5, "check_t0", [12]), 7); + +// table_copy.wast:335 +assert_trap(() => call($5, "check_t0", [13])); + +// table_copy.wast:336 +assert_trap(() => call($5, "check_t0", [14])); + +// table_copy.wast:337 +assert_trap(() => call($5, "check_t0", [15])); + +// table_copy.wast:338 +assert_return(() => call($5, "check_t0", [16]), 6); + +// table_copy.wast:339 +assert_trap(() => call($5, "check_t0", [17])); + +// table_copy.wast:340 +assert_trap(() => call($5, "check_t0", [18])); + +// table_copy.wast:341 +assert_trap(() => call($5, "check_t0", [19])); + +// table_copy.wast:342 +assert_trap(() => call($5, "check_t0", [20])); + +// table_copy.wast:343 +assert_trap(() => call($5, "check_t0", [21])); + +// table_copy.wast:344 +assert_trap(() => call($5, "check_t0", [22])); + +// table_copy.wast:345 +assert_trap(() => call($5, "check_t0", [23])); + +// table_copy.wast:346 +assert_trap(() => call($5, "check_t0", [24])); + +// table_copy.wast:347 +assert_trap(() => call($5, "check_t0", [25])); + +// table_copy.wast:348 +assert_trap(() => call($5, "check_t0", [26])); + +// table_copy.wast:349 +assert_trap(() => call($5, "check_t0", [27])); + +// table_copy.wast:350 +assert_trap(() => call($5, "check_t0", [28])); + +// table_copy.wast:351 +assert_trap(() => call($5, "check_t0", [29])); + +// table_copy.wast:352 +assert_trap(() => call($5, "check_t1", [0])); + +// table_copy.wast:353 +assert_trap(() => call($5, "check_t1", [1])); + +// table_copy.wast:354 +assert_trap(() => call($5, "check_t1", [2])); + +// table_copy.wast:355 +assert_return(() => call($5, "check_t1", [3]), 1); + +// table_copy.wast:356 +assert_return(() => call($5, "check_t1", [4]), 3); + +// table_copy.wast:357 +assert_return(() => call($5, "check_t1", [5]), 1); + +// table_copy.wast:358 +assert_return(() => call($5, "check_t1", [6]), 4); + +// table_copy.wast:359 +assert_trap(() => call($5, "check_t1", [7])); + +// table_copy.wast:360 +assert_trap(() => call($5, "check_t1", [8])); + +// table_copy.wast:361 +assert_trap(() => call($5, "check_t1", [9])); + +// table_copy.wast:362 +assert_trap(() => call($5, "check_t1", [10])); + +// table_copy.wast:363 +assert_return(() => call($5, "check_t1", [11]), 6); + +// table_copy.wast:364 +assert_return(() => call($5, "check_t1", [12]), 3); + +// table_copy.wast:365 +assert_return(() => call($5, "check_t1", [13]), 2); + +// table_copy.wast:366 +assert_return(() => call($5, "check_t1", [14]), 5); + +// table_copy.wast:367 +assert_return(() => call($5, "check_t1", [15]), 7); + +// table_copy.wast:368 +assert_trap(() => call($5, "check_t1", [16])); + +// table_copy.wast:369 +assert_trap(() => call($5, "check_t1", [17])); + +// table_copy.wast:370 +assert_trap(() => call($5, "check_t1", [18])); + +// table_copy.wast:371 +assert_trap(() => call($5, "check_t1", [19])); + +// table_copy.wast:372 +assert_trap(() => call($5, "check_t1", [20])); + +// table_copy.wast:373 +assert_trap(() => call($5, "check_t1", [21])); + +// table_copy.wast:374 +assert_trap(() => call($5, "check_t1", [22])); + +// table_copy.wast:375 +assert_trap(() => call($5, "check_t1", [23])); + +// table_copy.wast:376 +assert_trap(() => call($5, "check_t1", [24])); + +// table_copy.wast:377 +assert_trap(() => call($5, "check_t1", [25])); + +// table_copy.wast:378 +assert_trap(() => call($5, "check_t1", [26])); + +// table_copy.wast:379 +assert_trap(() => call($5, "check_t1", [27])); + +// table_copy.wast:380 +assert_trap(() => call($5, "check_t1", [28])); + +// table_copy.wast:381 +assert_trap(() => call($5, "check_t1", [29])); + +// table_copy.wast:383 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x14\x41\x16\x41\x04\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:413 +run(() => call($6, "test", [])); + +// table_copy.wast:414 +assert_trap(() => call($6, "check_t0", [0])); + +// table_copy.wast:415 +assert_trap(() => call($6, "check_t0", [1])); + +// table_copy.wast:416 +assert_return(() => call($6, "check_t0", [2]), 3); + +// table_copy.wast:417 +assert_return(() => call($6, "check_t0", [3]), 1); + +// table_copy.wast:418 +assert_return(() => call($6, "check_t0", [4]), 4); + +// table_copy.wast:419 +assert_return(() => call($6, "check_t0", [5]), 1); + +// table_copy.wast:420 +assert_trap(() => call($6, "check_t0", [6])); + +// table_copy.wast:421 +assert_trap(() => call($6, "check_t0", [7])); + +// table_copy.wast:422 +assert_trap(() => call($6, "check_t0", [8])); + +// table_copy.wast:423 +assert_trap(() => call($6, "check_t0", [9])); + +// table_copy.wast:424 +assert_trap(() => call($6, "check_t0", [10])); + +// table_copy.wast:425 +assert_trap(() => call($6, "check_t0", [11])); + +// table_copy.wast:426 +assert_return(() => call($6, "check_t0", [12]), 7); + +// table_copy.wast:427 +assert_return(() => call($6, "check_t0", [13]), 5); + +// table_copy.wast:428 +assert_return(() => call($6, "check_t0", [14]), 2); + +// table_copy.wast:429 +assert_return(() => call($6, "check_t0", [15]), 3); + +// table_copy.wast:430 +assert_return(() => call($6, "check_t0", [16]), 6); + +// table_copy.wast:431 +assert_trap(() => call($6, "check_t0", [17])); + +// table_copy.wast:432 +assert_trap(() => call($6, "check_t0", [18])); + +// table_copy.wast:433 +assert_trap(() => call($6, "check_t0", [19])); + +// table_copy.wast:434 +assert_trap(() => call($6, "check_t0", [20])); + +// table_copy.wast:435 +assert_trap(() => call($6, "check_t0", [21])); + +// table_copy.wast:436 +assert_trap(() => call($6, "check_t0", [22])); + +// table_copy.wast:437 +assert_trap(() => call($6, "check_t0", [23])); + +// table_copy.wast:438 +assert_trap(() => call($6, "check_t0", [24])); + +// table_copy.wast:439 +assert_trap(() => call($6, "check_t0", [25])); + +// table_copy.wast:440 +assert_trap(() => call($6, "check_t0", [26])); + +// table_copy.wast:441 +assert_trap(() => call($6, "check_t0", [27])); + +// table_copy.wast:442 +assert_trap(() => call($6, "check_t0", [28])); + +// table_copy.wast:443 +assert_trap(() => call($6, "check_t0", [29])); + +// table_copy.wast:444 +assert_trap(() => call($6, "check_t1", [0])); + +// table_copy.wast:445 +assert_trap(() => call($6, "check_t1", [1])); + +// table_copy.wast:446 +assert_trap(() => call($6, "check_t1", [2])); + +// table_copy.wast:447 +assert_return(() => call($6, "check_t1", [3]), 1); + +// table_copy.wast:448 +assert_return(() => call($6, "check_t1", [4]), 3); + +// table_copy.wast:449 +assert_return(() => call($6, "check_t1", [5]), 1); + +// table_copy.wast:450 +assert_return(() => call($6, "check_t1", [6]), 4); + +// table_copy.wast:451 +assert_trap(() => call($6, "check_t1", [7])); + +// table_copy.wast:452 +assert_trap(() => call($6, "check_t1", [8])); + +// table_copy.wast:453 +assert_trap(() => call($6, "check_t1", [9])); + +// table_copy.wast:454 +assert_trap(() => call($6, "check_t1", [10])); + +// table_copy.wast:455 +assert_return(() => call($6, "check_t1", [11]), 6); + +// table_copy.wast:456 +assert_return(() => call($6, "check_t1", [12]), 3); + +// table_copy.wast:457 +assert_return(() => call($6, "check_t1", [13]), 2); + +// table_copy.wast:458 +assert_return(() => call($6, "check_t1", [14]), 5); + +// table_copy.wast:459 +assert_return(() => call($6, "check_t1", [15]), 7); + +// table_copy.wast:460 +assert_trap(() => call($6, "check_t1", [16])); + +// table_copy.wast:461 +assert_trap(() => call($6, "check_t1", [17])); + +// table_copy.wast:462 +assert_trap(() => call($6, "check_t1", [18])); + +// table_copy.wast:463 +assert_trap(() => call($6, "check_t1", [19])); + +// table_copy.wast:464 +assert_trap(() => call($6, "check_t1", [20])); + +// table_copy.wast:465 +assert_trap(() => call($6, "check_t1", [21])); + +// table_copy.wast:466 +assert_trap(() => call($6, "check_t1", [22])); + +// table_copy.wast:467 +assert_trap(() => call($6, "check_t1", [23])); + +// table_copy.wast:468 +assert_trap(() => call($6, "check_t1", [24])); + +// table_copy.wast:469 +assert_trap(() => call($6, "check_t1", [25])); + +// table_copy.wast:470 +assert_trap(() => call($6, "check_t1", [26])); + +// table_copy.wast:471 +assert_trap(() => call($6, "check_t1", [27])); + +// table_copy.wast:472 +assert_trap(() => call($6, "check_t1", [28])); + +// table_copy.wast:473 +assert_trap(() => call($6, "check_t1", [29])); + +// table_copy.wast:475 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x01\x41\x03\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:505 +run(() => call($7, "test", [])); + +// table_copy.wast:506 +assert_trap(() => call($7, "check_t0", [0])); + +// table_copy.wast:507 +assert_trap(() => call($7, "check_t0", [1])); + +// table_copy.wast:508 +assert_return(() => call($7, "check_t0", [2]), 3); + +// table_copy.wast:509 +assert_return(() => call($7, "check_t0", [3]), 1); + +// table_copy.wast:510 +assert_return(() => call($7, "check_t0", [4]), 4); + +// table_copy.wast:511 +assert_return(() => call($7, "check_t0", [5]), 1); + +// table_copy.wast:512 +assert_trap(() => call($7, "check_t0", [6])); + +// table_copy.wast:513 +assert_trap(() => call($7, "check_t0", [7])); + +// table_copy.wast:514 +assert_trap(() => call($7, "check_t0", [8])); + +// table_copy.wast:515 +assert_trap(() => call($7, "check_t0", [9])); + +// table_copy.wast:516 +assert_trap(() => call($7, "check_t0", [10])); + +// table_copy.wast:517 +assert_trap(() => call($7, "check_t0", [11])); + +// table_copy.wast:518 +assert_return(() => call($7, "check_t0", [12]), 7); + +// table_copy.wast:519 +assert_return(() => call($7, "check_t0", [13]), 5); + +// table_copy.wast:520 +assert_return(() => call($7, "check_t0", [14]), 2); + +// table_copy.wast:521 +assert_return(() => call($7, "check_t0", [15]), 3); + +// table_copy.wast:522 +assert_return(() => call($7, "check_t0", [16]), 6); + +// table_copy.wast:523 +assert_trap(() => call($7, "check_t0", [17])); + +// table_copy.wast:524 +assert_trap(() => call($7, "check_t0", [18])); + +// table_copy.wast:525 +assert_trap(() => call($7, "check_t0", [19])); + +// table_copy.wast:526 +assert_trap(() => call($7, "check_t0", [20])); + +// table_copy.wast:527 +assert_trap(() => call($7, "check_t0", [21])); + +// table_copy.wast:528 +assert_trap(() => call($7, "check_t0", [22])); + +// table_copy.wast:529 +assert_trap(() => call($7, "check_t0", [23])); + +// table_copy.wast:530 +assert_trap(() => call($7, "check_t0", [24])); + +// table_copy.wast:531 +assert_trap(() => call($7, "check_t0", [25])); + +// table_copy.wast:532 +assert_return(() => call($7, "check_t0", [26]), 3); + +// table_copy.wast:533 +assert_return(() => call($7, "check_t0", [27]), 1); + +// table_copy.wast:534 +assert_trap(() => call($7, "check_t0", [28])); + +// table_copy.wast:535 +assert_trap(() => call($7, "check_t0", [29])); + +// table_copy.wast:536 +assert_trap(() => call($7, "check_t1", [0])); + +// table_copy.wast:537 +assert_trap(() => call($7, "check_t1", [1])); + +// table_copy.wast:538 +assert_trap(() => call($7, "check_t1", [2])); + +// table_copy.wast:539 +assert_return(() => call($7, "check_t1", [3]), 1); + +// table_copy.wast:540 +assert_return(() => call($7, "check_t1", [4]), 3); + +// table_copy.wast:541 +assert_return(() => call($7, "check_t1", [5]), 1); + +// table_copy.wast:542 +assert_return(() => call($7, "check_t1", [6]), 4); + +// table_copy.wast:543 +assert_trap(() => call($7, "check_t1", [7])); + +// table_copy.wast:544 +assert_trap(() => call($7, "check_t1", [8])); + +// table_copy.wast:545 +assert_trap(() => call($7, "check_t1", [9])); + +// table_copy.wast:546 +assert_trap(() => call($7, "check_t1", [10])); + +// table_copy.wast:547 +assert_return(() => call($7, "check_t1", [11]), 6); + +// table_copy.wast:548 +assert_return(() => call($7, "check_t1", [12]), 3); + +// table_copy.wast:549 +assert_return(() => call($7, "check_t1", [13]), 2); + +// table_copy.wast:550 +assert_return(() => call($7, "check_t1", [14]), 5); + +// table_copy.wast:551 +assert_return(() => call($7, "check_t1", [15]), 7); + +// table_copy.wast:552 +assert_trap(() => call($7, "check_t1", [16])); + +// table_copy.wast:553 +assert_trap(() => call($7, "check_t1", [17])); + +// table_copy.wast:554 +assert_trap(() => call($7, "check_t1", [18])); + +// table_copy.wast:555 +assert_trap(() => call($7, "check_t1", [19])); + +// table_copy.wast:556 +assert_trap(() => call($7, "check_t1", [20])); + +// table_copy.wast:557 +assert_trap(() => call($7, "check_t1", [21])); + +// table_copy.wast:558 +assert_trap(() => call($7, "check_t1", [22])); + +// table_copy.wast:559 +assert_trap(() => call($7, "check_t1", [23])); + +// table_copy.wast:560 +assert_trap(() => call($7, "check_t1", [24])); + +// table_copy.wast:561 +assert_trap(() => call($7, "check_t1", [25])); + +// table_copy.wast:562 +assert_trap(() => call($7, "check_t1", [26])); + +// table_copy.wast:563 +assert_trap(() => call($7, "check_t1", [27])); + +// table_copy.wast:564 +assert_trap(() => call($7, "check_t1", [28])); + +// table_copy.wast:565 +assert_trap(() => call($7, "check_t1", [29])); + +// table_copy.wast:567 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x0c\x41\x07\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:597 +run(() => call($8, "test", [])); + +// table_copy.wast:598 +assert_trap(() => call($8, "check_t0", [0])); + +// table_copy.wast:599 +assert_trap(() => call($8, "check_t0", [1])); + +// table_copy.wast:600 +assert_return(() => call($8, "check_t0", [2]), 3); + +// table_copy.wast:601 +assert_return(() => call($8, "check_t0", [3]), 1); + +// table_copy.wast:602 +assert_return(() => call($8, "check_t0", [4]), 4); + +// table_copy.wast:603 +assert_return(() => call($8, "check_t0", [5]), 1); + +// table_copy.wast:604 +assert_trap(() => call($8, "check_t0", [6])); + +// table_copy.wast:605 +assert_trap(() => call($8, "check_t0", [7])); + +// table_copy.wast:606 +assert_trap(() => call($8, "check_t0", [8])); + +// table_copy.wast:607 +assert_trap(() => call($8, "check_t0", [9])); + +// table_copy.wast:608 +assert_return(() => call($8, "check_t0", [10]), 7); + +// table_copy.wast:609 +assert_return(() => call($8, "check_t0", [11]), 5); + +// table_copy.wast:610 +assert_return(() => call($8, "check_t0", [12]), 2); + +// table_copy.wast:611 +assert_return(() => call($8, "check_t0", [13]), 3); + +// table_copy.wast:612 +assert_return(() => call($8, "check_t0", [14]), 6); + +// table_copy.wast:613 +assert_trap(() => call($8, "check_t0", [15])); + +// table_copy.wast:614 +assert_trap(() => call($8, "check_t0", [16])); + +// table_copy.wast:615 +assert_trap(() => call($8, "check_t0", [17])); + +// table_copy.wast:616 +assert_trap(() => call($8, "check_t0", [18])); + +// table_copy.wast:617 +assert_trap(() => call($8, "check_t0", [19])); + +// table_copy.wast:618 +assert_trap(() => call($8, "check_t0", [20])); + +// table_copy.wast:619 +assert_trap(() => call($8, "check_t0", [21])); + +// table_copy.wast:620 +assert_trap(() => call($8, "check_t0", [22])); + +// table_copy.wast:621 +assert_trap(() => call($8, "check_t0", [23])); + +// table_copy.wast:622 +assert_trap(() => call($8, "check_t0", [24])); + +// table_copy.wast:623 +assert_trap(() => call($8, "check_t0", [25])); + +// table_copy.wast:624 +assert_trap(() => call($8, "check_t0", [26])); + +// table_copy.wast:625 +assert_trap(() => call($8, "check_t0", [27])); + +// table_copy.wast:626 +assert_trap(() => call($8, "check_t0", [28])); + +// table_copy.wast:627 +assert_trap(() => call($8, "check_t0", [29])); + +// table_copy.wast:628 +assert_trap(() => call($8, "check_t1", [0])); + +// table_copy.wast:629 +assert_trap(() => call($8, "check_t1", [1])); + +// table_copy.wast:630 +assert_trap(() => call($8, "check_t1", [2])); + +// table_copy.wast:631 +assert_return(() => call($8, "check_t1", [3]), 1); + +// table_copy.wast:632 +assert_return(() => call($8, "check_t1", [4]), 3); + +// table_copy.wast:633 +assert_return(() => call($8, "check_t1", [5]), 1); + +// table_copy.wast:634 +assert_return(() => call($8, "check_t1", [6]), 4); + +// table_copy.wast:635 +assert_trap(() => call($8, "check_t1", [7])); + +// table_copy.wast:636 +assert_trap(() => call($8, "check_t1", [8])); + +// table_copy.wast:637 +assert_trap(() => call($8, "check_t1", [9])); + +// table_copy.wast:638 +assert_trap(() => call($8, "check_t1", [10])); + +// table_copy.wast:639 +assert_return(() => call($8, "check_t1", [11]), 6); + +// table_copy.wast:640 +assert_return(() => call($8, "check_t1", [12]), 3); + +// table_copy.wast:641 +assert_return(() => call($8, "check_t1", [13]), 2); + +// table_copy.wast:642 +assert_return(() => call($8, "check_t1", [14]), 5); + +// table_copy.wast:643 +assert_return(() => call($8, "check_t1", [15]), 7); + +// table_copy.wast:644 +assert_trap(() => call($8, "check_t1", [16])); + +// table_copy.wast:645 +assert_trap(() => call($8, "check_t1", [17])); + +// table_copy.wast:646 +assert_trap(() => call($8, "check_t1", [18])); + +// table_copy.wast:647 +assert_trap(() => call($8, "check_t1", [19])); + +// table_copy.wast:648 +assert_trap(() => call($8, "check_t1", [20])); + +// table_copy.wast:649 +assert_trap(() => call($8, "check_t1", [21])); + +// table_copy.wast:650 +assert_trap(() => call($8, "check_t1", [22])); + +// table_copy.wast:651 +assert_trap(() => call($8, "check_t1", [23])); + +// table_copy.wast:652 +assert_trap(() => call($8, "check_t1", [24])); + +// table_copy.wast:653 +assert_trap(() => call($8, "check_t1", [25])); + +// table_copy.wast:654 +assert_trap(() => call($8, "check_t1", [26])); + +// table_copy.wast:655 +assert_trap(() => call($8, "check_t1", [27])); + +// table_copy.wast:656 +assert_trap(() => call($8, "check_t1", [28])); + +// table_copy.wast:657 +assert_trap(() => call($8, "check_t1", [29])); + +// table_copy.wast:659 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x0a\x41\x07\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:689 +run(() => call($9, "test", [])); + +// table_copy.wast:690 +assert_trap(() => call($9, "check_t0", [0])); + +// table_copy.wast:691 +assert_trap(() => call($9, "check_t0", [1])); + +// table_copy.wast:692 +assert_return(() => call($9, "check_t0", [2]), 3); + +// table_copy.wast:693 +assert_return(() => call($9, "check_t0", [3]), 1); + +// table_copy.wast:694 +assert_return(() => call($9, "check_t0", [4]), 4); + +// table_copy.wast:695 +assert_return(() => call($9, "check_t0", [5]), 1); + +// table_copy.wast:696 +assert_trap(() => call($9, "check_t0", [6])); + +// table_copy.wast:697 +assert_trap(() => call($9, "check_t0", [7])); + +// table_copy.wast:698 +assert_trap(() => call($9, "check_t0", [8])); + +// table_copy.wast:699 +assert_trap(() => call($9, "check_t0", [9])); + +// table_copy.wast:700 +assert_trap(() => call($9, "check_t0", [10])); + +// table_copy.wast:701 +assert_trap(() => call($9, "check_t0", [11])); + +// table_copy.wast:702 +assert_trap(() => call($9, "check_t0", [12])); + +// table_copy.wast:703 +assert_trap(() => call($9, "check_t0", [13])); + +// table_copy.wast:704 +assert_return(() => call($9, "check_t0", [14]), 7); + +// table_copy.wast:705 +assert_return(() => call($9, "check_t0", [15]), 5); + +// table_copy.wast:706 +assert_return(() => call($9, "check_t0", [16]), 2); + +// table_copy.wast:707 +assert_return(() => call($9, "check_t0", [17]), 3); + +// table_copy.wast:708 +assert_return(() => call($9, "check_t0", [18]), 6); + +// table_copy.wast:709 +assert_trap(() => call($9, "check_t0", [19])); + +// table_copy.wast:710 +assert_trap(() => call($9, "check_t0", [20])); + +// table_copy.wast:711 +assert_trap(() => call($9, "check_t0", [21])); + +// table_copy.wast:712 +assert_trap(() => call($9, "check_t0", [22])); + +// table_copy.wast:713 +assert_trap(() => call($9, "check_t0", [23])); + +// table_copy.wast:714 +assert_trap(() => call($9, "check_t0", [24])); + +// table_copy.wast:715 +assert_trap(() => call($9, "check_t0", [25])); + +// table_copy.wast:716 +assert_trap(() => call($9, "check_t0", [26])); + +// table_copy.wast:717 +assert_trap(() => call($9, "check_t0", [27])); + +// table_copy.wast:718 +assert_trap(() => call($9, "check_t0", [28])); + +// table_copy.wast:719 +assert_trap(() => call($9, "check_t0", [29])); + +// table_copy.wast:720 +assert_trap(() => call($9, "check_t1", [0])); + +// table_copy.wast:721 +assert_trap(() => call($9, "check_t1", [1])); + +// table_copy.wast:722 +assert_trap(() => call($9, "check_t1", [2])); + +// table_copy.wast:723 +assert_return(() => call($9, "check_t1", [3]), 1); + +// table_copy.wast:724 +assert_return(() => call($9, "check_t1", [4]), 3); + +// table_copy.wast:725 +assert_return(() => call($9, "check_t1", [5]), 1); + +// table_copy.wast:726 +assert_return(() => call($9, "check_t1", [6]), 4); + +// table_copy.wast:727 +assert_trap(() => call($9, "check_t1", [7])); + +// table_copy.wast:728 +assert_trap(() => call($9, "check_t1", [8])); + +// table_copy.wast:729 +assert_trap(() => call($9, "check_t1", [9])); + +// table_copy.wast:730 +assert_trap(() => call($9, "check_t1", [10])); + +// table_copy.wast:731 +assert_return(() => call($9, "check_t1", [11]), 6); + +// table_copy.wast:732 +assert_return(() => call($9, "check_t1", [12]), 3); + +// table_copy.wast:733 +assert_return(() => call($9, "check_t1", [13]), 2); + +// table_copy.wast:734 +assert_return(() => call($9, "check_t1", [14]), 5); + +// table_copy.wast:735 +assert_return(() => call($9, "check_t1", [15]), 7); + +// table_copy.wast:736 +assert_trap(() => call($9, "check_t1", [16])); + +// table_copy.wast:737 +assert_trap(() => call($9, "check_t1", [17])); + +// table_copy.wast:738 +assert_trap(() => call($9, "check_t1", [18])); + +// table_copy.wast:739 +assert_trap(() => call($9, "check_t1", [19])); + +// table_copy.wast:740 +assert_trap(() => call($9, "check_t1", [20])); + +// table_copy.wast:741 +assert_trap(() => call($9, "check_t1", [21])); + +// table_copy.wast:742 +assert_trap(() => call($9, "check_t1", [22])); + +// table_copy.wast:743 +assert_trap(() => call($9, "check_t1", [23])); + +// table_copy.wast:744 +assert_trap(() => call($9, "check_t1", [24])); + +// table_copy.wast:745 +assert_trap(() => call($9, "check_t1", [25])); + +// table_copy.wast:746 +assert_trap(() => call($9, "check_t1", [26])); + +// table_copy.wast:747 +assert_trap(() => call($9, "check_t1", [27])); + +// table_copy.wast:748 +assert_trap(() => call($9, "check_t1", [28])); + +// table_copy.wast:749 +assert_trap(() => call($9, "check_t1", [29])); + +// table_copy.wast:751 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x02\x01\x41\x03\x0b\x00\x04\x01\x03\x01\x04\x02\x01\x41\x0b\x0b\x00\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x00\x41\x14\xfc\x0e\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_copy.wast:781 +run(() => call($10, "test", [])); + +// table_copy.wast:782 +assert_trap(() => call($10, "check_t0", [0])); + +// table_copy.wast:783 +assert_trap(() => call($10, "check_t0", [1])); + +// table_copy.wast:784 +assert_return(() => call($10, "check_t0", [2]), 3); + +// table_copy.wast:785 +assert_return(() => call($10, "check_t0", [3]), 1); + +// table_copy.wast:786 +assert_return(() => call($10, "check_t0", [4]), 4); + +// table_copy.wast:787 +assert_return(() => call($10, "check_t0", [5]), 1); + +// table_copy.wast:788 +assert_trap(() => call($10, "check_t0", [6])); + +// table_copy.wast:789 +assert_trap(() => call($10, "check_t0", [7])); + +// table_copy.wast:790 +assert_trap(() => call($10, "check_t0", [8])); + +// table_copy.wast:791 +assert_trap(() => call($10, "check_t0", [9])); + +// table_copy.wast:792 +assert_trap(() => call($10, "check_t0", [10])); + +// table_copy.wast:793 +assert_trap(() => call($10, "check_t0", [11])); + +// table_copy.wast:794 +assert_return(() => call($10, "check_t0", [12]), 7); + +// table_copy.wast:795 +assert_return(() => call($10, "check_t0", [13]), 5); + +// table_copy.wast:796 +assert_return(() => call($10, "check_t0", [14]), 2); + +// table_copy.wast:797 +assert_return(() => call($10, "check_t0", [15]), 3); + +// table_copy.wast:798 +assert_return(() => call($10, "check_t0", [16]), 6); + +// table_copy.wast:799 +assert_trap(() => call($10, "check_t0", [17])); + +// table_copy.wast:800 +assert_trap(() => call($10, "check_t0", [18])); + +// table_copy.wast:801 +assert_trap(() => call($10, "check_t0", [19])); + +// table_copy.wast:802 +assert_trap(() => call($10, "check_t0", [20])); + +// table_copy.wast:803 +assert_trap(() => call($10, "check_t0", [21])); + +// table_copy.wast:804 +assert_trap(() => call($10, "check_t0", [22])); + +// table_copy.wast:805 +assert_trap(() => call($10, "check_t0", [23])); + +// table_copy.wast:806 +assert_trap(() => call($10, "check_t0", [24])); + +// table_copy.wast:807 +assert_trap(() => call($10, "check_t0", [25])); + +// table_copy.wast:808 +assert_trap(() => call($10, "check_t0", [26])); + +// table_copy.wast:809 +assert_trap(() => call($10, "check_t0", [27])); + +// table_copy.wast:810 +assert_trap(() => call($10, "check_t0", [28])); + +// table_copy.wast:811 +assert_trap(() => call($10, "check_t0", [29])); + +// table_copy.wast:812 +assert_trap(() => call($10, "check_t1", [0])); + +// table_copy.wast:813 +assert_trap(() => call($10, "check_t1", [1])); + +// table_copy.wast:814 +assert_trap(() => call($10, "check_t1", [2])); + +// table_copy.wast:815 +assert_return(() => call($10, "check_t1", [3]), 1); + +// table_copy.wast:816 +assert_return(() => call($10, "check_t1", [4]), 3); + +// table_copy.wast:817 +assert_return(() => call($10, "check_t1", [5]), 1); + +// table_copy.wast:818 +assert_return(() => call($10, "check_t1", [6]), 4); + +// table_copy.wast:819 +assert_trap(() => call($10, "check_t1", [7])); + +// table_copy.wast:820 +assert_trap(() => call($10, "check_t1", [8])); + +// table_copy.wast:821 +assert_trap(() => call($10, "check_t1", [9])); + +// table_copy.wast:822 +assert_trap(() => call($10, "check_t1", [10])); + +// table_copy.wast:823 +assert_trap(() => call($10, "check_t1", [11])); + +// table_copy.wast:824 +assert_return(() => call($10, "check_t1", [12]), 3); + +// table_copy.wast:825 +assert_return(() => call($10, "check_t1", [13]), 1); + +// table_copy.wast:826 +assert_return(() => call($10, "check_t1", [14]), 4); + +// table_copy.wast:827 +assert_return(() => call($10, "check_t1", [15]), 1); + +// table_copy.wast:828 +assert_trap(() => call($10, "check_t1", [16])); + +// table_copy.wast:829 +assert_trap(() => call($10, "check_t1", [17])); + +// table_copy.wast:830 +assert_trap(() => call($10, "check_t1", [18])); + +// table_copy.wast:831 +assert_trap(() => call($10, "check_t1", [19])); + +// table_copy.wast:832 +assert_trap(() => call($10, "check_t1", [20])); + +// table_copy.wast:833 +assert_trap(() => call($10, "check_t1", [21])); + +// table_copy.wast:834 +assert_return(() => call($10, "check_t1", [22]), 7); + +// table_copy.wast:835 +assert_return(() => call($10, "check_t1", [23]), 5); + +// table_copy.wast:836 +assert_return(() => call($10, "check_t1", [24]), 2); + +// table_copy.wast:837 +assert_return(() => call($10, "check_t1", [25]), 3); + +// table_copy.wast:838 +assert_return(() => call($10, "check_t1", [26]), 6); + +// table_copy.wast:839 +assert_trap(() => call($10, "check_t1", [27])); + +// table_copy.wast:840 +assert_trap(() => call($10, "check_t1", [28])); + +// table_copy.wast:841 +assert_trap(() => call($10, "check_t1", [29])); + +// table_copy.wast:843 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xce\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x83\x80\x80\x80\x00\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:873 +run(() => call($11, "test", [])); + +// table_copy.wast:874 +assert_trap(() => call($11, "check_t0", [0])); + +// table_copy.wast:875 +assert_trap(() => call($11, "check_t0", [1])); + +// table_copy.wast:876 +assert_return(() => call($11, "check_t0", [2]), 3); + +// table_copy.wast:877 +assert_return(() => call($11, "check_t0", [3]), 1); + +// table_copy.wast:878 +assert_return(() => call($11, "check_t0", [4]), 4); + +// table_copy.wast:879 +assert_return(() => call($11, "check_t0", [5]), 1); + +// table_copy.wast:880 +assert_trap(() => call($11, "check_t0", [6])); + +// table_copy.wast:881 +assert_trap(() => call($11, "check_t0", [7])); + +// table_copy.wast:882 +assert_trap(() => call($11, "check_t0", [8])); + +// table_copy.wast:883 +assert_trap(() => call($11, "check_t0", [9])); + +// table_copy.wast:884 +assert_trap(() => call($11, "check_t0", [10])); + +// table_copy.wast:885 +assert_trap(() => call($11, "check_t0", [11])); + +// table_copy.wast:886 +assert_return(() => call($11, "check_t0", [12]), 7); + +// table_copy.wast:887 +assert_return(() => call($11, "check_t0", [13]), 5); + +// table_copy.wast:888 +assert_return(() => call($11, "check_t0", [14]), 2); + +// table_copy.wast:889 +assert_return(() => call($11, "check_t0", [15]), 3); + +// table_copy.wast:890 +assert_return(() => call($11, "check_t0", [16]), 6); + +// table_copy.wast:891 +assert_trap(() => call($11, "check_t0", [17])); + +// table_copy.wast:892 +assert_trap(() => call($11, "check_t0", [18])); + +// table_copy.wast:893 +assert_trap(() => call($11, "check_t0", [19])); + +// table_copy.wast:894 +assert_trap(() => call($11, "check_t0", [20])); + +// table_copy.wast:895 +assert_trap(() => call($11, "check_t0", [21])); + +// table_copy.wast:896 +assert_trap(() => call($11, "check_t0", [22])); + +// table_copy.wast:897 +assert_trap(() => call($11, "check_t0", [23])); + +// table_copy.wast:898 +assert_trap(() => call($11, "check_t0", [24])); + +// table_copy.wast:899 +assert_trap(() => call($11, "check_t0", [25])); + +// table_copy.wast:900 +assert_trap(() => call($11, "check_t0", [26])); + +// table_copy.wast:901 +assert_trap(() => call($11, "check_t0", [27])); + +// table_copy.wast:902 +assert_trap(() => call($11, "check_t0", [28])); + +// table_copy.wast:903 +assert_trap(() => call($11, "check_t0", [29])); + +// table_copy.wast:904 +assert_trap(() => call($11, "check_t1", [0])); + +// table_copy.wast:905 +assert_trap(() => call($11, "check_t1", [1])); + +// table_copy.wast:906 +assert_trap(() => call($11, "check_t1", [2])); + +// table_copy.wast:907 +assert_return(() => call($11, "check_t1", [3]), 1); + +// table_copy.wast:908 +assert_return(() => call($11, "check_t1", [4]), 3); + +// table_copy.wast:909 +assert_return(() => call($11, "check_t1", [5]), 1); + +// table_copy.wast:910 +assert_return(() => call($11, "check_t1", [6]), 4); + +// table_copy.wast:911 +assert_trap(() => call($11, "check_t1", [7])); + +// table_copy.wast:912 +assert_trap(() => call($11, "check_t1", [8])); + +// table_copy.wast:913 +assert_trap(() => call($11, "check_t1", [9])); + +// table_copy.wast:914 +assert_trap(() => call($11, "check_t1", [10])); + +// table_copy.wast:915 +assert_return(() => call($11, "check_t1", [11]), 6); + +// table_copy.wast:916 +assert_return(() => call($11, "check_t1", [12]), 3); + +// table_copy.wast:917 +assert_return(() => call($11, "check_t1", [13]), 2); + +// table_copy.wast:918 +assert_return(() => call($11, "check_t1", [14]), 5); + +// table_copy.wast:919 +assert_return(() => call($11, "check_t1", [15]), 7); + +// table_copy.wast:920 +assert_trap(() => call($11, "check_t1", [16])); + +// table_copy.wast:921 +assert_trap(() => call($11, "check_t1", [17])); + +// table_copy.wast:922 +assert_trap(() => call($11, "check_t1", [18])); + +// table_copy.wast:923 +assert_trap(() => call($11, "check_t1", [19])); + +// table_copy.wast:924 +assert_trap(() => call($11, "check_t1", [20])); + +// table_copy.wast:925 +assert_trap(() => call($11, "check_t1", [21])); + +// table_copy.wast:926 +assert_trap(() => call($11, "check_t1", [22])); + +// table_copy.wast:927 +assert_trap(() => call($11, "check_t1", [23])); + +// table_copy.wast:928 +assert_trap(() => call($11, "check_t1", [24])); + +// table_copy.wast:929 +assert_trap(() => call($11, "check_t1", [25])); + +// table_copy.wast:930 +assert_trap(() => call($11, "check_t1", [26])); + +// table_copy.wast:931 +assert_trap(() => call($11, "check_t1", [27])); + +// table_copy.wast:932 +assert_trap(() => call($11, "check_t1", [28])); + +// table_copy.wast:933 +assert_trap(() => call($11, "check_t1", [29])); + +// table_copy.wast:935 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x02\x41\x03\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:965 +run(() => call($12, "test", [])); + +// table_copy.wast:966 +assert_trap(() => call($12, "check_t0", [0])); + +// table_copy.wast:967 +assert_trap(() => call($12, "check_t0", [1])); + +// table_copy.wast:968 +assert_return(() => call($12, "check_t0", [2]), 3); + +// table_copy.wast:969 +assert_return(() => call($12, "check_t0", [3]), 1); + +// table_copy.wast:970 +assert_return(() => call($12, "check_t0", [4]), 4); + +// table_copy.wast:971 +assert_return(() => call($12, "check_t0", [5]), 1); + +// table_copy.wast:972 +assert_trap(() => call($12, "check_t0", [6])); + +// table_copy.wast:973 +assert_trap(() => call($12, "check_t0", [7])); + +// table_copy.wast:974 +assert_trap(() => call($12, "check_t0", [8])); + +// table_copy.wast:975 +assert_trap(() => call($12, "check_t0", [9])); + +// table_copy.wast:976 +assert_trap(() => call($12, "check_t0", [10])); + +// table_copy.wast:977 +assert_trap(() => call($12, "check_t0", [11])); + +// table_copy.wast:978 +assert_return(() => call($12, "check_t0", [12]), 7); + +// table_copy.wast:979 +assert_return(() => call($12, "check_t0", [13]), 3); + +// table_copy.wast:980 +assert_return(() => call($12, "check_t0", [14]), 1); + +// table_copy.wast:981 +assert_return(() => call($12, "check_t0", [15]), 4); + +// table_copy.wast:982 +assert_return(() => call($12, "check_t0", [16]), 6); + +// table_copy.wast:983 +assert_trap(() => call($12, "check_t0", [17])); + +// table_copy.wast:984 +assert_trap(() => call($12, "check_t0", [18])); + +// table_copy.wast:985 +assert_trap(() => call($12, "check_t0", [19])); + +// table_copy.wast:986 +assert_trap(() => call($12, "check_t0", [20])); + +// table_copy.wast:987 +assert_trap(() => call($12, "check_t0", [21])); + +// table_copy.wast:988 +assert_trap(() => call($12, "check_t0", [22])); + +// table_copy.wast:989 +assert_trap(() => call($12, "check_t0", [23])); + +// table_copy.wast:990 +assert_trap(() => call($12, "check_t0", [24])); + +// table_copy.wast:991 +assert_trap(() => call($12, "check_t0", [25])); + +// table_copy.wast:992 +assert_trap(() => call($12, "check_t0", [26])); + +// table_copy.wast:993 +assert_trap(() => call($12, "check_t0", [27])); + +// table_copy.wast:994 +assert_trap(() => call($12, "check_t0", [28])); + +// table_copy.wast:995 +assert_trap(() => call($12, "check_t0", [29])); + +// table_copy.wast:996 +assert_trap(() => call($12, "check_t1", [0])); + +// table_copy.wast:997 +assert_trap(() => call($12, "check_t1", [1])); + +// table_copy.wast:998 +assert_trap(() => call($12, "check_t1", [2])); + +// table_copy.wast:999 +assert_return(() => call($12, "check_t1", [3]), 1); + +// table_copy.wast:1000 +assert_return(() => call($12, "check_t1", [4]), 3); + +// table_copy.wast:1001 +assert_return(() => call($12, "check_t1", [5]), 1); + +// table_copy.wast:1002 +assert_return(() => call($12, "check_t1", [6]), 4); + +// table_copy.wast:1003 +assert_trap(() => call($12, "check_t1", [7])); + +// table_copy.wast:1004 +assert_trap(() => call($12, "check_t1", [8])); + +// table_copy.wast:1005 +assert_trap(() => call($12, "check_t1", [9])); + +// table_copy.wast:1006 +assert_trap(() => call($12, "check_t1", [10])); + +// table_copy.wast:1007 +assert_return(() => call($12, "check_t1", [11]), 6); + +// table_copy.wast:1008 +assert_return(() => call($12, "check_t1", [12]), 3); + +// table_copy.wast:1009 +assert_return(() => call($12, "check_t1", [13]), 2); + +// table_copy.wast:1010 +assert_return(() => call($12, "check_t1", [14]), 5); + +// table_copy.wast:1011 +assert_return(() => call($12, "check_t1", [15]), 7); + +// table_copy.wast:1012 +assert_trap(() => call($12, "check_t1", [16])); + +// table_copy.wast:1013 +assert_trap(() => call($12, "check_t1", [17])); + +// table_copy.wast:1014 +assert_trap(() => call($12, "check_t1", [18])); + +// table_copy.wast:1015 +assert_trap(() => call($12, "check_t1", [19])); + +// table_copy.wast:1016 +assert_trap(() => call($12, "check_t1", [20])); + +// table_copy.wast:1017 +assert_trap(() => call($12, "check_t1", [21])); + +// table_copy.wast:1018 +assert_trap(() => call($12, "check_t1", [22])); + +// table_copy.wast:1019 +assert_trap(() => call($12, "check_t1", [23])); + +// table_copy.wast:1020 +assert_trap(() => call($12, "check_t1", [24])); + +// table_copy.wast:1021 +assert_trap(() => call($12, "check_t1", [25])); + +// table_copy.wast:1022 +assert_trap(() => call($12, "check_t1", [26])); + +// table_copy.wast:1023 +assert_trap(() => call($12, "check_t1", [27])); + +// table_copy.wast:1024 +assert_trap(() => call($12, "check_t1", [28])); + +// table_copy.wast:1025 +assert_trap(() => call($12, "check_t1", [29])); + +// table_copy.wast:1027 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x0f\x41\x02\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1057 +run(() => call($13, "test", [])); + +// table_copy.wast:1058 +assert_trap(() => call($13, "check_t0", [0])); + +// table_copy.wast:1059 +assert_trap(() => call($13, "check_t0", [1])); + +// table_copy.wast:1060 +assert_return(() => call($13, "check_t0", [2]), 3); + +// table_copy.wast:1061 +assert_return(() => call($13, "check_t0", [3]), 1); + +// table_copy.wast:1062 +assert_return(() => call($13, "check_t0", [4]), 4); + +// table_copy.wast:1063 +assert_return(() => call($13, "check_t0", [5]), 1); + +// table_copy.wast:1064 +assert_trap(() => call($13, "check_t0", [6])); + +// table_copy.wast:1065 +assert_trap(() => call($13, "check_t0", [7])); + +// table_copy.wast:1066 +assert_trap(() => call($13, "check_t0", [8])); + +// table_copy.wast:1067 +assert_trap(() => call($13, "check_t0", [9])); + +// table_copy.wast:1068 +assert_trap(() => call($13, "check_t0", [10])); + +// table_copy.wast:1069 +assert_trap(() => call($13, "check_t0", [11])); + +// table_copy.wast:1070 +assert_return(() => call($13, "check_t0", [12]), 7); + +// table_copy.wast:1071 +assert_return(() => call($13, "check_t0", [13]), 5); + +// table_copy.wast:1072 +assert_return(() => call($13, "check_t0", [14]), 2); + +// table_copy.wast:1073 +assert_return(() => call($13, "check_t0", [15]), 3); + +// table_copy.wast:1074 +assert_return(() => call($13, "check_t0", [16]), 6); + +// table_copy.wast:1075 +assert_trap(() => call($13, "check_t0", [17])); + +// table_copy.wast:1076 +assert_trap(() => call($13, "check_t0", [18])); + +// table_copy.wast:1077 +assert_trap(() => call($13, "check_t0", [19])); + +// table_copy.wast:1078 +assert_trap(() => call($13, "check_t0", [20])); + +// table_copy.wast:1079 +assert_trap(() => call($13, "check_t0", [21])); + +// table_copy.wast:1080 +assert_trap(() => call($13, "check_t0", [22])); + +// table_copy.wast:1081 +assert_trap(() => call($13, "check_t0", [23])); + +// table_copy.wast:1082 +assert_trap(() => call($13, "check_t0", [24])); + +// table_copy.wast:1083 +assert_return(() => call($13, "check_t0", [25]), 3); + +// table_copy.wast:1084 +assert_return(() => call($13, "check_t0", [26]), 6); + +// table_copy.wast:1085 +assert_trap(() => call($13, "check_t0", [27])); + +// table_copy.wast:1086 +assert_trap(() => call($13, "check_t0", [28])); + +// table_copy.wast:1087 +assert_trap(() => call($13, "check_t0", [29])); + +// table_copy.wast:1088 +assert_trap(() => call($13, "check_t1", [0])); + +// table_copy.wast:1089 +assert_trap(() => call($13, "check_t1", [1])); + +// table_copy.wast:1090 +assert_trap(() => call($13, "check_t1", [2])); + +// table_copy.wast:1091 +assert_return(() => call($13, "check_t1", [3]), 1); + +// table_copy.wast:1092 +assert_return(() => call($13, "check_t1", [4]), 3); + +// table_copy.wast:1093 +assert_return(() => call($13, "check_t1", [5]), 1); + +// table_copy.wast:1094 +assert_return(() => call($13, "check_t1", [6]), 4); + +// table_copy.wast:1095 +assert_trap(() => call($13, "check_t1", [7])); + +// table_copy.wast:1096 +assert_trap(() => call($13, "check_t1", [8])); + +// table_copy.wast:1097 +assert_trap(() => call($13, "check_t1", [9])); + +// table_copy.wast:1098 +assert_trap(() => call($13, "check_t1", [10])); + +// table_copy.wast:1099 +assert_return(() => call($13, "check_t1", [11]), 6); + +// table_copy.wast:1100 +assert_return(() => call($13, "check_t1", [12]), 3); + +// table_copy.wast:1101 +assert_return(() => call($13, "check_t1", [13]), 2); + +// table_copy.wast:1102 +assert_return(() => call($13, "check_t1", [14]), 5); + +// table_copy.wast:1103 +assert_return(() => call($13, "check_t1", [15]), 7); + +// table_copy.wast:1104 +assert_trap(() => call($13, "check_t1", [16])); + +// table_copy.wast:1105 +assert_trap(() => call($13, "check_t1", [17])); + +// table_copy.wast:1106 +assert_trap(() => call($13, "check_t1", [18])); + +// table_copy.wast:1107 +assert_trap(() => call($13, "check_t1", [19])); + +// table_copy.wast:1108 +assert_trap(() => call($13, "check_t1", [20])); + +// table_copy.wast:1109 +assert_trap(() => call($13, "check_t1", [21])); + +// table_copy.wast:1110 +assert_trap(() => call($13, "check_t1", [22])); + +// table_copy.wast:1111 +assert_trap(() => call($13, "check_t1", [23])); + +// table_copy.wast:1112 +assert_trap(() => call($13, "check_t1", [24])); + +// table_copy.wast:1113 +assert_trap(() => call($13, "check_t1", [25])); + +// table_copy.wast:1114 +assert_trap(() => call($13, "check_t1", [26])); + +// table_copy.wast:1115 +assert_trap(() => call($13, "check_t1", [27])); + +// table_copy.wast:1116 +assert_trap(() => call($13, "check_t1", [28])); + +// table_copy.wast:1117 +assert_trap(() => call($13, "check_t1", [29])); + +// table_copy.wast:1119 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0d\x41\x19\x41\x03\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1149 +run(() => call($14, "test", [])); + +// table_copy.wast:1150 +assert_trap(() => call($14, "check_t0", [0])); + +// table_copy.wast:1151 +assert_trap(() => call($14, "check_t0", [1])); + +// table_copy.wast:1152 +assert_return(() => call($14, "check_t0", [2]), 3); + +// table_copy.wast:1153 +assert_return(() => call($14, "check_t0", [3]), 1); + +// table_copy.wast:1154 +assert_return(() => call($14, "check_t0", [4]), 4); + +// table_copy.wast:1155 +assert_return(() => call($14, "check_t0", [5]), 1); + +// table_copy.wast:1156 +assert_trap(() => call($14, "check_t0", [6])); + +// table_copy.wast:1157 +assert_trap(() => call($14, "check_t0", [7])); + +// table_copy.wast:1158 +assert_trap(() => call($14, "check_t0", [8])); + +// table_copy.wast:1159 +assert_trap(() => call($14, "check_t0", [9])); + +// table_copy.wast:1160 +assert_trap(() => call($14, "check_t0", [10])); + +// table_copy.wast:1161 +assert_trap(() => call($14, "check_t0", [11])); + +// table_copy.wast:1162 +assert_return(() => call($14, "check_t0", [12]), 7); + +// table_copy.wast:1163 +assert_trap(() => call($14, "check_t0", [13])); + +// table_copy.wast:1164 +assert_trap(() => call($14, "check_t0", [14])); + +// table_copy.wast:1165 +assert_trap(() => call($14, "check_t0", [15])); + +// table_copy.wast:1166 +assert_return(() => call($14, "check_t0", [16]), 6); + +// table_copy.wast:1167 +assert_trap(() => call($14, "check_t0", [17])); + +// table_copy.wast:1168 +assert_trap(() => call($14, "check_t0", [18])); + +// table_copy.wast:1169 +assert_trap(() => call($14, "check_t0", [19])); + +// table_copy.wast:1170 +assert_trap(() => call($14, "check_t0", [20])); + +// table_copy.wast:1171 +assert_trap(() => call($14, "check_t0", [21])); + +// table_copy.wast:1172 +assert_trap(() => call($14, "check_t0", [22])); + +// table_copy.wast:1173 +assert_trap(() => call($14, "check_t0", [23])); + +// table_copy.wast:1174 +assert_trap(() => call($14, "check_t0", [24])); + +// table_copy.wast:1175 +assert_trap(() => call($14, "check_t0", [25])); + +// table_copy.wast:1176 +assert_trap(() => call($14, "check_t0", [26])); + +// table_copy.wast:1177 +assert_trap(() => call($14, "check_t0", [27])); + +// table_copy.wast:1178 +assert_trap(() => call($14, "check_t0", [28])); + +// table_copy.wast:1179 +assert_trap(() => call($14, "check_t0", [29])); + +// table_copy.wast:1180 +assert_trap(() => call($14, "check_t1", [0])); + +// table_copy.wast:1181 +assert_trap(() => call($14, "check_t1", [1])); + +// table_copy.wast:1182 +assert_trap(() => call($14, "check_t1", [2])); + +// table_copy.wast:1183 +assert_return(() => call($14, "check_t1", [3]), 1); + +// table_copy.wast:1184 +assert_return(() => call($14, "check_t1", [4]), 3); + +// table_copy.wast:1185 +assert_return(() => call($14, "check_t1", [5]), 1); + +// table_copy.wast:1186 +assert_return(() => call($14, "check_t1", [6]), 4); + +// table_copy.wast:1187 +assert_trap(() => call($14, "check_t1", [7])); + +// table_copy.wast:1188 +assert_trap(() => call($14, "check_t1", [8])); + +// table_copy.wast:1189 +assert_trap(() => call($14, "check_t1", [9])); + +// table_copy.wast:1190 +assert_trap(() => call($14, "check_t1", [10])); + +// table_copy.wast:1191 +assert_return(() => call($14, "check_t1", [11]), 6); + +// table_copy.wast:1192 +assert_return(() => call($14, "check_t1", [12]), 3); + +// table_copy.wast:1193 +assert_return(() => call($14, "check_t1", [13]), 2); + +// table_copy.wast:1194 +assert_return(() => call($14, "check_t1", [14]), 5); + +// table_copy.wast:1195 +assert_return(() => call($14, "check_t1", [15]), 7); + +// table_copy.wast:1196 +assert_trap(() => call($14, "check_t1", [16])); + +// table_copy.wast:1197 +assert_trap(() => call($14, "check_t1", [17])); + +// table_copy.wast:1198 +assert_trap(() => call($14, "check_t1", [18])); + +// table_copy.wast:1199 +assert_trap(() => call($14, "check_t1", [19])); + +// table_copy.wast:1200 +assert_trap(() => call($14, "check_t1", [20])); + +// table_copy.wast:1201 +assert_trap(() => call($14, "check_t1", [21])); + +// table_copy.wast:1202 +assert_trap(() => call($14, "check_t1", [22])); + +// table_copy.wast:1203 +assert_trap(() => call($14, "check_t1", [23])); + +// table_copy.wast:1204 +assert_trap(() => call($14, "check_t1", [24])); + +// table_copy.wast:1205 +assert_trap(() => call($14, "check_t1", [25])); + +// table_copy.wast:1206 +assert_trap(() => call($14, "check_t1", [26])); + +// table_copy.wast:1207 +assert_trap(() => call($14, "check_t1", [27])); + +// table_copy.wast:1208 +assert_trap(() => call($14, "check_t1", [28])); + +// table_copy.wast:1209 +assert_trap(() => call($14, "check_t1", [29])); + +// table_copy.wast:1211 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x14\x41\x16\x41\x04\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1241 +run(() => call($15, "test", [])); + +// table_copy.wast:1242 +assert_trap(() => call($15, "check_t0", [0])); + +// table_copy.wast:1243 +assert_trap(() => call($15, "check_t0", [1])); + +// table_copy.wast:1244 +assert_return(() => call($15, "check_t0", [2]), 3); + +// table_copy.wast:1245 +assert_return(() => call($15, "check_t0", [3]), 1); + +// table_copy.wast:1246 +assert_return(() => call($15, "check_t0", [4]), 4); + +// table_copy.wast:1247 +assert_return(() => call($15, "check_t0", [5]), 1); + +// table_copy.wast:1248 +assert_trap(() => call($15, "check_t0", [6])); + +// table_copy.wast:1249 +assert_trap(() => call($15, "check_t0", [7])); + +// table_copy.wast:1250 +assert_trap(() => call($15, "check_t0", [8])); + +// table_copy.wast:1251 +assert_trap(() => call($15, "check_t0", [9])); + +// table_copy.wast:1252 +assert_trap(() => call($15, "check_t0", [10])); + +// table_copy.wast:1253 +assert_trap(() => call($15, "check_t0", [11])); + +// table_copy.wast:1254 +assert_return(() => call($15, "check_t0", [12]), 7); + +// table_copy.wast:1255 +assert_return(() => call($15, "check_t0", [13]), 5); + +// table_copy.wast:1256 +assert_return(() => call($15, "check_t0", [14]), 2); + +// table_copy.wast:1257 +assert_return(() => call($15, "check_t0", [15]), 3); + +// table_copy.wast:1258 +assert_return(() => call($15, "check_t0", [16]), 6); + +// table_copy.wast:1259 +assert_trap(() => call($15, "check_t0", [17])); + +// table_copy.wast:1260 +assert_trap(() => call($15, "check_t0", [18])); + +// table_copy.wast:1261 +assert_trap(() => call($15, "check_t0", [19])); + +// table_copy.wast:1262 +assert_trap(() => call($15, "check_t0", [20])); + +// table_copy.wast:1263 +assert_trap(() => call($15, "check_t0", [21])); + +// table_copy.wast:1264 +assert_trap(() => call($15, "check_t0", [22])); + +// table_copy.wast:1265 +assert_trap(() => call($15, "check_t0", [23])); + +// table_copy.wast:1266 +assert_trap(() => call($15, "check_t0", [24])); + +// table_copy.wast:1267 +assert_trap(() => call($15, "check_t0", [25])); + +// table_copy.wast:1268 +assert_trap(() => call($15, "check_t0", [26])); + +// table_copy.wast:1269 +assert_trap(() => call($15, "check_t0", [27])); + +// table_copy.wast:1270 +assert_trap(() => call($15, "check_t0", [28])); + +// table_copy.wast:1271 +assert_trap(() => call($15, "check_t0", [29])); + +// table_copy.wast:1272 +assert_trap(() => call($15, "check_t1", [0])); + +// table_copy.wast:1273 +assert_trap(() => call($15, "check_t1", [1])); + +// table_copy.wast:1274 +assert_trap(() => call($15, "check_t1", [2])); + +// table_copy.wast:1275 +assert_return(() => call($15, "check_t1", [3]), 1); + +// table_copy.wast:1276 +assert_return(() => call($15, "check_t1", [4]), 3); + +// table_copy.wast:1277 +assert_return(() => call($15, "check_t1", [5]), 1); + +// table_copy.wast:1278 +assert_return(() => call($15, "check_t1", [6]), 4); + +// table_copy.wast:1279 +assert_trap(() => call($15, "check_t1", [7])); + +// table_copy.wast:1280 +assert_trap(() => call($15, "check_t1", [8])); + +// table_copy.wast:1281 +assert_trap(() => call($15, "check_t1", [9])); + +// table_copy.wast:1282 +assert_trap(() => call($15, "check_t1", [10])); + +// table_copy.wast:1283 +assert_return(() => call($15, "check_t1", [11]), 6); + +// table_copy.wast:1284 +assert_return(() => call($15, "check_t1", [12]), 3); + +// table_copy.wast:1285 +assert_return(() => call($15, "check_t1", [13]), 2); + +// table_copy.wast:1286 +assert_return(() => call($15, "check_t1", [14]), 5); + +// table_copy.wast:1287 +assert_return(() => call($15, "check_t1", [15]), 7); + +// table_copy.wast:1288 +assert_trap(() => call($15, "check_t1", [16])); + +// table_copy.wast:1289 +assert_trap(() => call($15, "check_t1", [17])); + +// table_copy.wast:1290 +assert_trap(() => call($15, "check_t1", [18])); + +// table_copy.wast:1291 +assert_trap(() => call($15, "check_t1", [19])); + +// table_copy.wast:1292 +assert_trap(() => call($15, "check_t1", [20])); + +// table_copy.wast:1293 +assert_trap(() => call($15, "check_t1", [21])); + +// table_copy.wast:1294 +assert_trap(() => call($15, "check_t1", [22])); + +// table_copy.wast:1295 +assert_trap(() => call($15, "check_t1", [23])); + +// table_copy.wast:1296 +assert_trap(() => call($15, "check_t1", [24])); + +// table_copy.wast:1297 +assert_trap(() => call($15, "check_t1", [25])); + +// table_copy.wast:1298 +assert_trap(() => call($15, "check_t1", [26])); + +// table_copy.wast:1299 +assert_trap(() => call($15, "check_t1", [27])); + +// table_copy.wast:1300 +assert_trap(() => call($15, "check_t1", [28])); + +// table_copy.wast:1301 +assert_trap(() => call($15, "check_t1", [29])); + +// table_copy.wast:1303 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x19\x41\x01\x41\x03\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1333 +run(() => call($16, "test", [])); + +// table_copy.wast:1334 +assert_trap(() => call($16, "check_t0", [0])); + +// table_copy.wast:1335 +assert_trap(() => call($16, "check_t0", [1])); + +// table_copy.wast:1336 +assert_return(() => call($16, "check_t0", [2]), 3); + +// table_copy.wast:1337 +assert_return(() => call($16, "check_t0", [3]), 1); + +// table_copy.wast:1338 +assert_return(() => call($16, "check_t0", [4]), 4); + +// table_copy.wast:1339 +assert_return(() => call($16, "check_t0", [5]), 1); + +// table_copy.wast:1340 +assert_trap(() => call($16, "check_t0", [6])); + +// table_copy.wast:1341 +assert_trap(() => call($16, "check_t0", [7])); + +// table_copy.wast:1342 +assert_trap(() => call($16, "check_t0", [8])); + +// table_copy.wast:1343 +assert_trap(() => call($16, "check_t0", [9])); + +// table_copy.wast:1344 +assert_trap(() => call($16, "check_t0", [10])); + +// table_copy.wast:1345 +assert_trap(() => call($16, "check_t0", [11])); + +// table_copy.wast:1346 +assert_return(() => call($16, "check_t0", [12]), 7); + +// table_copy.wast:1347 +assert_return(() => call($16, "check_t0", [13]), 5); + +// table_copy.wast:1348 +assert_return(() => call($16, "check_t0", [14]), 2); + +// table_copy.wast:1349 +assert_return(() => call($16, "check_t0", [15]), 3); + +// table_copy.wast:1350 +assert_return(() => call($16, "check_t0", [16]), 6); + +// table_copy.wast:1351 +assert_trap(() => call($16, "check_t0", [17])); + +// table_copy.wast:1352 +assert_trap(() => call($16, "check_t0", [18])); + +// table_copy.wast:1353 +assert_trap(() => call($16, "check_t0", [19])); + +// table_copy.wast:1354 +assert_trap(() => call($16, "check_t0", [20])); + +// table_copy.wast:1355 +assert_trap(() => call($16, "check_t0", [21])); + +// table_copy.wast:1356 +assert_trap(() => call($16, "check_t0", [22])); + +// table_copy.wast:1357 +assert_trap(() => call($16, "check_t0", [23])); + +// table_copy.wast:1358 +assert_trap(() => call($16, "check_t0", [24])); + +// table_copy.wast:1359 +assert_trap(() => call($16, "check_t0", [25])); + +// table_copy.wast:1360 +assert_return(() => call($16, "check_t0", [26]), 3); + +// table_copy.wast:1361 +assert_return(() => call($16, "check_t0", [27]), 1); + +// table_copy.wast:1362 +assert_trap(() => call($16, "check_t0", [28])); + +// table_copy.wast:1363 +assert_trap(() => call($16, "check_t0", [29])); + +// table_copy.wast:1364 +assert_trap(() => call($16, "check_t1", [0])); + +// table_copy.wast:1365 +assert_trap(() => call($16, "check_t1", [1])); + +// table_copy.wast:1366 +assert_trap(() => call($16, "check_t1", [2])); + +// table_copy.wast:1367 +assert_return(() => call($16, "check_t1", [3]), 1); + +// table_copy.wast:1368 +assert_return(() => call($16, "check_t1", [4]), 3); + +// table_copy.wast:1369 +assert_return(() => call($16, "check_t1", [5]), 1); + +// table_copy.wast:1370 +assert_return(() => call($16, "check_t1", [6]), 4); + +// table_copy.wast:1371 +assert_trap(() => call($16, "check_t1", [7])); + +// table_copy.wast:1372 +assert_trap(() => call($16, "check_t1", [8])); + +// table_copy.wast:1373 +assert_trap(() => call($16, "check_t1", [9])); + +// table_copy.wast:1374 +assert_trap(() => call($16, "check_t1", [10])); + +// table_copy.wast:1375 +assert_return(() => call($16, "check_t1", [11]), 6); + +// table_copy.wast:1376 +assert_return(() => call($16, "check_t1", [12]), 3); + +// table_copy.wast:1377 +assert_return(() => call($16, "check_t1", [13]), 2); + +// table_copy.wast:1378 +assert_return(() => call($16, "check_t1", [14]), 5); + +// table_copy.wast:1379 +assert_return(() => call($16, "check_t1", [15]), 7); + +// table_copy.wast:1380 +assert_trap(() => call($16, "check_t1", [16])); + +// table_copy.wast:1381 +assert_trap(() => call($16, "check_t1", [17])); + +// table_copy.wast:1382 +assert_trap(() => call($16, "check_t1", [18])); + +// table_copy.wast:1383 +assert_trap(() => call($16, "check_t1", [19])); + +// table_copy.wast:1384 +assert_trap(() => call($16, "check_t1", [20])); + +// table_copy.wast:1385 +assert_trap(() => call($16, "check_t1", [21])); + +// table_copy.wast:1386 +assert_trap(() => call($16, "check_t1", [22])); + +// table_copy.wast:1387 +assert_trap(() => call($16, "check_t1", [23])); + +// table_copy.wast:1388 +assert_trap(() => call($16, "check_t1", [24])); + +// table_copy.wast:1389 +assert_trap(() => call($16, "check_t1", [25])); + +// table_copy.wast:1390 +assert_trap(() => call($16, "check_t1", [26])); + +// table_copy.wast:1391 +assert_trap(() => call($16, "check_t1", [27])); + +// table_copy.wast:1392 +assert_trap(() => call($16, "check_t1", [28])); + +// table_copy.wast:1393 +assert_trap(() => call($16, "check_t1", [29])); + +// table_copy.wast:1395 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x0c\x41\x07\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1425 +run(() => call($17, "test", [])); + +// table_copy.wast:1426 +assert_trap(() => call($17, "check_t0", [0])); + +// table_copy.wast:1427 +assert_trap(() => call($17, "check_t0", [1])); + +// table_copy.wast:1428 +assert_return(() => call($17, "check_t0", [2]), 3); + +// table_copy.wast:1429 +assert_return(() => call($17, "check_t0", [3]), 1); + +// table_copy.wast:1430 +assert_return(() => call($17, "check_t0", [4]), 4); + +// table_copy.wast:1431 +assert_return(() => call($17, "check_t0", [5]), 1); + +// table_copy.wast:1432 +assert_trap(() => call($17, "check_t0", [6])); + +// table_copy.wast:1433 +assert_trap(() => call($17, "check_t0", [7])); + +// table_copy.wast:1434 +assert_trap(() => call($17, "check_t0", [8])); + +// table_copy.wast:1435 +assert_trap(() => call($17, "check_t0", [9])); + +// table_copy.wast:1436 +assert_return(() => call($17, "check_t0", [10]), 7); + +// table_copy.wast:1437 +assert_return(() => call($17, "check_t0", [11]), 5); + +// table_copy.wast:1438 +assert_return(() => call($17, "check_t0", [12]), 2); + +// table_copy.wast:1439 +assert_return(() => call($17, "check_t0", [13]), 3); + +// table_copy.wast:1440 +assert_return(() => call($17, "check_t0", [14]), 6); + +// table_copy.wast:1441 +assert_trap(() => call($17, "check_t0", [15])); + +// table_copy.wast:1442 +assert_trap(() => call($17, "check_t0", [16])); + +// table_copy.wast:1443 +assert_trap(() => call($17, "check_t0", [17])); + +// table_copy.wast:1444 +assert_trap(() => call($17, "check_t0", [18])); + +// table_copy.wast:1445 +assert_trap(() => call($17, "check_t0", [19])); + +// table_copy.wast:1446 +assert_trap(() => call($17, "check_t0", [20])); + +// table_copy.wast:1447 +assert_trap(() => call($17, "check_t0", [21])); + +// table_copy.wast:1448 +assert_trap(() => call($17, "check_t0", [22])); + +// table_copy.wast:1449 +assert_trap(() => call($17, "check_t0", [23])); + +// table_copy.wast:1450 +assert_trap(() => call($17, "check_t0", [24])); + +// table_copy.wast:1451 +assert_trap(() => call($17, "check_t0", [25])); + +// table_copy.wast:1452 +assert_trap(() => call($17, "check_t0", [26])); + +// table_copy.wast:1453 +assert_trap(() => call($17, "check_t0", [27])); + +// table_copy.wast:1454 +assert_trap(() => call($17, "check_t0", [28])); + +// table_copy.wast:1455 +assert_trap(() => call($17, "check_t0", [29])); + +// table_copy.wast:1456 +assert_trap(() => call($17, "check_t1", [0])); + +// table_copy.wast:1457 +assert_trap(() => call($17, "check_t1", [1])); + +// table_copy.wast:1458 +assert_trap(() => call($17, "check_t1", [2])); + +// table_copy.wast:1459 +assert_return(() => call($17, "check_t1", [3]), 1); + +// table_copy.wast:1460 +assert_return(() => call($17, "check_t1", [4]), 3); + +// table_copy.wast:1461 +assert_return(() => call($17, "check_t1", [5]), 1); + +// table_copy.wast:1462 +assert_return(() => call($17, "check_t1", [6]), 4); + +// table_copy.wast:1463 +assert_trap(() => call($17, "check_t1", [7])); + +// table_copy.wast:1464 +assert_trap(() => call($17, "check_t1", [8])); + +// table_copy.wast:1465 +assert_trap(() => call($17, "check_t1", [9])); + +// table_copy.wast:1466 +assert_trap(() => call($17, "check_t1", [10])); + +// table_copy.wast:1467 +assert_return(() => call($17, "check_t1", [11]), 6); + +// table_copy.wast:1468 +assert_return(() => call($17, "check_t1", [12]), 3); + +// table_copy.wast:1469 +assert_return(() => call($17, "check_t1", [13]), 2); + +// table_copy.wast:1470 +assert_return(() => call($17, "check_t1", [14]), 5); + +// table_copy.wast:1471 +assert_return(() => call($17, "check_t1", [15]), 7); + +// table_copy.wast:1472 +assert_trap(() => call($17, "check_t1", [16])); + +// table_copy.wast:1473 +assert_trap(() => call($17, "check_t1", [17])); + +// table_copy.wast:1474 +assert_trap(() => call($17, "check_t1", [18])); + +// table_copy.wast:1475 +assert_trap(() => call($17, "check_t1", [19])); + +// table_copy.wast:1476 +assert_trap(() => call($17, "check_t1", [20])); + +// table_copy.wast:1477 +assert_trap(() => call($17, "check_t1", [21])); + +// table_copy.wast:1478 +assert_trap(() => call($17, "check_t1", [22])); + +// table_copy.wast:1479 +assert_trap(() => call($17, "check_t1", [23])); + +// table_copy.wast:1480 +assert_trap(() => call($17, "check_t1", [24])); + +// table_copy.wast:1481 +assert_trap(() => call($17, "check_t1", [25])); + +// table_copy.wast:1482 +assert_trap(() => call($17, "check_t1", [26])); + +// table_copy.wast:1483 +assert_trap(() => call($17, "check_t1", [27])); + +// table_copy.wast:1484 +assert_trap(() => call($17, "check_t1", [28])); + +// table_copy.wast:1485 +assert_trap(() => call($17, "check_t1", [29])); + +// table_copy.wast:1487 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x0a\x41\x07\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1517 +run(() => call($18, "test", [])); + +// table_copy.wast:1518 +assert_trap(() => call($18, "check_t0", [0])); + +// table_copy.wast:1519 +assert_trap(() => call($18, "check_t0", [1])); + +// table_copy.wast:1520 +assert_return(() => call($18, "check_t0", [2]), 3); + +// table_copy.wast:1521 +assert_return(() => call($18, "check_t0", [3]), 1); + +// table_copy.wast:1522 +assert_return(() => call($18, "check_t0", [4]), 4); + +// table_copy.wast:1523 +assert_return(() => call($18, "check_t0", [5]), 1); + +// table_copy.wast:1524 +assert_trap(() => call($18, "check_t0", [6])); + +// table_copy.wast:1525 +assert_trap(() => call($18, "check_t0", [7])); + +// table_copy.wast:1526 +assert_trap(() => call($18, "check_t0", [8])); + +// table_copy.wast:1527 +assert_trap(() => call($18, "check_t0", [9])); + +// table_copy.wast:1528 +assert_trap(() => call($18, "check_t0", [10])); + +// table_copy.wast:1529 +assert_trap(() => call($18, "check_t0", [11])); + +// table_copy.wast:1530 +assert_trap(() => call($18, "check_t0", [12])); + +// table_copy.wast:1531 +assert_trap(() => call($18, "check_t0", [13])); + +// table_copy.wast:1532 +assert_return(() => call($18, "check_t0", [14]), 7); + +// table_copy.wast:1533 +assert_return(() => call($18, "check_t0", [15]), 5); + +// table_copy.wast:1534 +assert_return(() => call($18, "check_t0", [16]), 2); + +// table_copy.wast:1535 +assert_return(() => call($18, "check_t0", [17]), 3); + +// table_copy.wast:1536 +assert_return(() => call($18, "check_t0", [18]), 6); + +// table_copy.wast:1537 +assert_trap(() => call($18, "check_t0", [19])); + +// table_copy.wast:1538 +assert_trap(() => call($18, "check_t0", [20])); + +// table_copy.wast:1539 +assert_trap(() => call($18, "check_t0", [21])); + +// table_copy.wast:1540 +assert_trap(() => call($18, "check_t0", [22])); + +// table_copy.wast:1541 +assert_trap(() => call($18, "check_t0", [23])); + +// table_copy.wast:1542 +assert_trap(() => call($18, "check_t0", [24])); + +// table_copy.wast:1543 +assert_trap(() => call($18, "check_t0", [25])); + +// table_copy.wast:1544 +assert_trap(() => call($18, "check_t0", [26])); + +// table_copy.wast:1545 +assert_trap(() => call($18, "check_t0", [27])); + +// table_copy.wast:1546 +assert_trap(() => call($18, "check_t0", [28])); + +// table_copy.wast:1547 +assert_trap(() => call($18, "check_t0", [29])); + +// table_copy.wast:1548 +assert_trap(() => call($18, "check_t1", [0])); + +// table_copy.wast:1549 +assert_trap(() => call($18, "check_t1", [1])); + +// table_copy.wast:1550 +assert_trap(() => call($18, "check_t1", [2])); + +// table_copy.wast:1551 +assert_return(() => call($18, "check_t1", [3]), 1); + +// table_copy.wast:1552 +assert_return(() => call($18, "check_t1", [4]), 3); + +// table_copy.wast:1553 +assert_return(() => call($18, "check_t1", [5]), 1); + +// table_copy.wast:1554 +assert_return(() => call($18, "check_t1", [6]), 4); + +// table_copy.wast:1555 +assert_trap(() => call($18, "check_t1", [7])); + +// table_copy.wast:1556 +assert_trap(() => call($18, "check_t1", [8])); + +// table_copy.wast:1557 +assert_trap(() => call($18, "check_t1", [9])); + +// table_copy.wast:1558 +assert_trap(() => call($18, "check_t1", [10])); + +// table_copy.wast:1559 +assert_return(() => call($18, "check_t1", [11]), 6); + +// table_copy.wast:1560 +assert_return(() => call($18, "check_t1", [12]), 3); + +// table_copy.wast:1561 +assert_return(() => call($18, "check_t1", [13]), 2); + +// table_copy.wast:1562 +assert_return(() => call($18, "check_t1", [14]), 5); + +// table_copy.wast:1563 +assert_return(() => call($18, "check_t1", [15]), 7); + +// table_copy.wast:1564 +assert_trap(() => call($18, "check_t1", [16])); + +// table_copy.wast:1565 +assert_trap(() => call($18, "check_t1", [17])); + +// table_copy.wast:1566 +assert_trap(() => call($18, "check_t1", [18])); + +// table_copy.wast:1567 +assert_trap(() => call($18, "check_t1", [19])); + +// table_copy.wast:1568 +assert_trap(() => call($18, "check_t1", [20])); + +// table_copy.wast:1569 +assert_trap(() => call($18, "check_t1", [21])); + +// table_copy.wast:1570 +assert_trap(() => call($18, "check_t1", [22])); + +// table_copy.wast:1571 +assert_trap(() => call($18, "check_t1", [23])); + +// table_copy.wast:1572 +assert_trap(() => call($18, "check_t1", [24])); + +// table_copy.wast:1573 +assert_trap(() => call($18, "check_t1", [25])); + +// table_copy.wast:1574 +assert_trap(() => call($18, "check_t1", [26])); + +// table_copy.wast:1575 +assert_trap(() => call($18, "check_t1", [27])); + +// table_copy.wast:1576 +assert_trap(() => call($18, "check_t1", [28])); + +// table_copy.wast:1577 +assert_trap(() => call($18, "check_t1", [29])); + +// table_copy.wast:1579 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x9e\x80\x80\x80\x00\x03\x04\x74\x65\x73\x74\x00\x0a\x08\x63\x68\x65\x63\x6b\x5f\x74\x30\x00\x0b\x08\x63\x68\x65\x63\x6b\x5f\x74\x31\x00\x0c\x09\xba\x80\x80\x80\x00\x06\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x00\x41\x03\x0b\x04\x01\x03\x01\x04\x00\x41\x0b\x0b\x05\x06\x03\x02\x05\x07\x0a\xd7\x80\x80\x80\x00\x08\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x00\x41\x14\xfc\x0e\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_copy.wast:1609 +run(() => call($19, "test", [])); + +// table_copy.wast:1610 +assert_trap(() => call($19, "check_t0", [0])); + +// table_copy.wast:1611 +assert_trap(() => call($19, "check_t0", [1])); + +// table_copy.wast:1612 +assert_return(() => call($19, "check_t0", [2]), 3); + +// table_copy.wast:1613 +assert_return(() => call($19, "check_t0", [3]), 1); + +// table_copy.wast:1614 +assert_return(() => call($19, "check_t0", [4]), 4); + +// table_copy.wast:1615 +assert_return(() => call($19, "check_t0", [5]), 1); + +// table_copy.wast:1616 +assert_trap(() => call($19, "check_t0", [6])); + +// table_copy.wast:1617 +assert_trap(() => call($19, "check_t0", [7])); + +// table_copy.wast:1618 +assert_trap(() => call($19, "check_t0", [8])); + +// table_copy.wast:1619 +assert_trap(() => call($19, "check_t0", [9])); + +// table_copy.wast:1620 +assert_trap(() => call($19, "check_t0", [10])); + +// table_copy.wast:1621 +assert_trap(() => call($19, "check_t0", [11])); + +// table_copy.wast:1622 +assert_return(() => call($19, "check_t0", [12]), 7); + +// table_copy.wast:1623 +assert_return(() => call($19, "check_t0", [13]), 5); + +// table_copy.wast:1624 +assert_return(() => call($19, "check_t0", [14]), 2); + +// table_copy.wast:1625 +assert_return(() => call($19, "check_t0", [15]), 3); + +// table_copy.wast:1626 +assert_return(() => call($19, "check_t0", [16]), 6); + +// table_copy.wast:1627 +assert_trap(() => call($19, "check_t0", [17])); + +// table_copy.wast:1628 +assert_trap(() => call($19, "check_t0", [18])); + +// table_copy.wast:1629 +assert_trap(() => call($19, "check_t0", [19])); + +// table_copy.wast:1630 +assert_trap(() => call($19, "check_t0", [20])); + +// table_copy.wast:1631 +assert_trap(() => call($19, "check_t0", [21])); + +// table_copy.wast:1632 +assert_trap(() => call($19, "check_t0", [22])); + +// table_copy.wast:1633 +assert_trap(() => call($19, "check_t0", [23])); + +// table_copy.wast:1634 +assert_trap(() => call($19, "check_t0", [24])); + +// table_copy.wast:1635 +assert_trap(() => call($19, "check_t0", [25])); + +// table_copy.wast:1636 +assert_trap(() => call($19, "check_t0", [26])); + +// table_copy.wast:1637 +assert_trap(() => call($19, "check_t0", [27])); + +// table_copy.wast:1638 +assert_trap(() => call($19, "check_t0", [28])); + +// table_copy.wast:1639 +assert_trap(() => call($19, "check_t0", [29])); + +// table_copy.wast:1640 +assert_trap(() => call($19, "check_t1", [0])); + +// table_copy.wast:1641 +assert_trap(() => call($19, "check_t1", [1])); + +// table_copy.wast:1642 +assert_trap(() => call($19, "check_t1", [2])); + +// table_copy.wast:1643 +assert_return(() => call($19, "check_t1", [3]), 1); + +// table_copy.wast:1644 +assert_return(() => call($19, "check_t1", [4]), 3); + +// table_copy.wast:1645 +assert_return(() => call($19, "check_t1", [5]), 1); + +// table_copy.wast:1646 +assert_return(() => call($19, "check_t1", [6]), 4); + +// table_copy.wast:1647 +assert_trap(() => call($19, "check_t1", [7])); + +// table_copy.wast:1648 +assert_trap(() => call($19, "check_t1", [8])); + +// table_copy.wast:1649 +assert_trap(() => call($19, "check_t1", [9])); + +// table_copy.wast:1650 +assert_trap(() => call($19, "check_t1", [10])); + +// table_copy.wast:1651 +assert_trap(() => call($19, "check_t1", [11])); + +// table_copy.wast:1652 +assert_return(() => call($19, "check_t1", [12]), 3); + +// table_copy.wast:1653 +assert_return(() => call($19, "check_t1", [13]), 1); + +// table_copy.wast:1654 +assert_return(() => call($19, "check_t1", [14]), 4); + +// table_copy.wast:1655 +assert_return(() => call($19, "check_t1", [15]), 1); + +// table_copy.wast:1656 +assert_trap(() => call($19, "check_t1", [16])); + +// table_copy.wast:1657 +assert_trap(() => call($19, "check_t1", [17])); + +// table_copy.wast:1658 +assert_trap(() => call($19, "check_t1", [18])); + +// table_copy.wast:1659 +assert_trap(() => call($19, "check_t1", [19])); + +// table_copy.wast:1660 +assert_trap(() => call($19, "check_t1", [20])); + +// table_copy.wast:1661 +assert_trap(() => call($19, "check_t1", [21])); + +// table_copy.wast:1662 +assert_return(() => call($19, "check_t1", [22]), 7); + +// table_copy.wast:1663 +assert_return(() => call($19, "check_t1", [23]), 5); + +// table_copy.wast:1664 +assert_return(() => call($19, "check_t1", [24]), 2); + +// table_copy.wast:1665 +assert_return(() => call($19, "check_t1", [25]), 3); + +// table_copy.wast:1666 +assert_return(() => call($19, "check_t1", [26]), 6); + +// table_copy.wast:1667 +assert_trap(() => call($19, "check_t1", [27])); + +// table_copy.wast:1668 +assert_trap(() => call($19, "check_t1", [28])); + +// table_copy.wast:1669 +assert_trap(() => call($19, "check_t1", [29])); + +// table_copy.wast:1671 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x01\x41\x03\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1694 +assert_trap(() => call($20, "test", [])); + +// table_copy.wast:1696 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x7e\x41\x01\x41\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1719 +assert_trap(() => call($21, "test", [])); + +// table_copy.wast:1721 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x06\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1744 +assert_trap(() => call($22, "test", [])); + +// table_copy.wast:1746 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x7e\x41\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1769 +assert_trap(() => call($23, "test", [])); + +// table_copy.wast:1771 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1794 +run(() => call($24, "test", [])); + +// table_copy.wast:1796 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x0f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1819 +run(() => call($25, "test", [])); + +// table_copy.wast:1821 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x0f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1844 +assert_trap(() => call($26, "test", [])); + +// table_copy.wast:1846 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1e\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1869 +run(() => call($27, "test", [])); + +// table_copy.wast:1871 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1894 +assert_trap(() => call($28, "test", [])); + +// table_copy.wast:1896 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x1e\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1919 +run(() => call($29, "test", [])); + +// table_copy.wast:1921 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x1f\x41\x00\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:1944 +assert_trap(() => call($30, "test", [])); + +// table_copy.wast:1946 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x01\x41\x03\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:1969 +assert_trap(() => call($31, "test", [])); + +// table_copy.wast:1971 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x7e\x41\x01\x41\x02\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:1994 +assert_trap(() => call($32, "test", [])); + +// table_copy.wast:1996 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x06\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2019 +assert_trap(() => call($33, "test", [])); + +// table_copy.wast:2021 +let $34 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x7e\x41\x02\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2044 +assert_trap(() => call($34, "test", [])); + +// table_copy.wast:2046 +let $35 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x19\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2069 +run(() => call($35, "test", [])); + +// table_copy.wast:2071 +let $36 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x0f\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2094 +run(() => call($36, "test", [])); + +// table_copy.wast:2096 +let $37 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x0f\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2119 +assert_trap(() => call($37, "test", [])); + +// table_copy.wast:2121 +let $38 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1e\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2144 +run(() => call($38, "test", [])); + +// table_copy.wast:2146 +let $39 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x1f\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2169 +assert_trap(() => call($39, "test", [])); + +// table_copy.wast:2171 +let $40 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x1e\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2194 +run(() => call($40, "test", [])); + +// table_copy.wast:2196 +let $41 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x1f\x41\x00\xfc\x0e\x01\x00\x0b"); + +// table_copy.wast:2219 +assert_trap(() => call($41, "test", [])); + +// table_copy.wast:2221 +let $42 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2247 +assert_trap(() => call($42, "run", [24, 0, 16])); + +// table_copy.wast:2249 +assert_return(() => call($42, "test", [0]), 0); + +// table_copy.wast:2250 +assert_return(() => call($42, "test", [1]), 1); + +// table_copy.wast:2251 +assert_return(() => call($42, "test", [2]), 2); + +// table_copy.wast:2252 +assert_return(() => call($42, "test", [3]), 3); + +// table_copy.wast:2253 +assert_return(() => call($42, "test", [4]), 4); + +// table_copy.wast:2254 +assert_return(() => call($42, "test", [5]), 5); + +// table_copy.wast:2255 +assert_return(() => call($42, "test", [6]), 6); + +// table_copy.wast:2256 +assert_return(() => call($42, "test", [7]), 7); + +// table_copy.wast:2257 +assert_trap(() => call($42, "test", [8])); + +// table_copy.wast:2258 +assert_trap(() => call($42, "test", [9])); + +// table_copy.wast:2259 +assert_trap(() => call($42, "test", [10])); + +// table_copy.wast:2260 +assert_trap(() => call($42, "test", [11])); + +// table_copy.wast:2261 +assert_trap(() => call($42, "test", [12])); + +// table_copy.wast:2262 +assert_trap(() => call($42, "test", [13])); + +// table_copy.wast:2263 +assert_trap(() => call($42, "test", [14])); + +// table_copy.wast:2264 +assert_trap(() => call($42, "test", [15])); + +// table_copy.wast:2265 +assert_trap(() => call($42, "test", [16])); + +// table_copy.wast:2266 +assert_trap(() => call($42, "test", [17])); + +// table_copy.wast:2267 +assert_trap(() => call($42, "test", [18])); + +// table_copy.wast:2268 +assert_trap(() => call($42, "test", [19])); + +// table_copy.wast:2269 +assert_trap(() => call($42, "test", [20])); + +// table_copy.wast:2270 +assert_trap(() => call($42, "test", [21])); + +// table_copy.wast:2271 +assert_trap(() => call($42, "test", [22])); + +// table_copy.wast:2272 +assert_trap(() => call($42, "test", [23])); + +// table_copy.wast:2273 +assert_trap(() => call($42, "test", [24])); + +// table_copy.wast:2274 +assert_trap(() => call($42, "test", [25])); + +// table_copy.wast:2275 +assert_trap(() => call($42, "test", [26])); + +// table_copy.wast:2276 +assert_trap(() => call($42, "test", [27])); + +// table_copy.wast:2277 +assert_trap(() => call($42, "test", [28])); + +// table_copy.wast:2278 +assert_trap(() => call($42, "test", [29])); + +// table_copy.wast:2279 +assert_trap(() => call($42, "test", [30])); + +// table_copy.wast:2280 +assert_trap(() => call($42, "test", [31])); + +// table_copy.wast:2282 +let $43 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8f\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x09\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2308 +assert_trap(() => call($43, "run", [23, 0, 15])); + +// table_copy.wast:2310 +assert_return(() => call($43, "test", [0]), 0); + +// table_copy.wast:2311 +assert_return(() => call($43, "test", [1]), 1); + +// table_copy.wast:2312 +assert_return(() => call($43, "test", [2]), 2); + +// table_copy.wast:2313 +assert_return(() => call($43, "test", [3]), 3); + +// table_copy.wast:2314 +assert_return(() => call($43, "test", [4]), 4); + +// table_copy.wast:2315 +assert_return(() => call($43, "test", [5]), 5); + +// table_copy.wast:2316 +assert_return(() => call($43, "test", [6]), 6); + +// table_copy.wast:2317 +assert_return(() => call($43, "test", [7]), 7); + +// table_copy.wast:2318 +assert_return(() => call($43, "test", [8]), 8); + +// table_copy.wast:2319 +assert_trap(() => call($43, "test", [9])); + +// table_copy.wast:2320 +assert_trap(() => call($43, "test", [10])); + +// table_copy.wast:2321 +assert_trap(() => call($43, "test", [11])); + +// table_copy.wast:2322 +assert_trap(() => call($43, "test", [12])); + +// table_copy.wast:2323 +assert_trap(() => call($43, "test", [13])); + +// table_copy.wast:2324 +assert_trap(() => call($43, "test", [14])); + +// table_copy.wast:2325 +assert_trap(() => call($43, "test", [15])); + +// table_copy.wast:2326 +assert_trap(() => call($43, "test", [16])); + +// table_copy.wast:2327 +assert_trap(() => call($43, "test", [17])); + +// table_copy.wast:2328 +assert_trap(() => call($43, "test", [18])); + +// table_copy.wast:2329 +assert_trap(() => call($43, "test", [19])); + +// table_copy.wast:2330 +assert_trap(() => call($43, "test", [20])); + +// table_copy.wast:2331 +assert_trap(() => call($43, "test", [21])); + +// table_copy.wast:2332 +assert_trap(() => call($43, "test", [22])); + +// table_copy.wast:2333 +assert_trap(() => call($43, "test", [23])); + +// table_copy.wast:2334 +assert_trap(() => call($43, "test", [24])); + +// table_copy.wast:2335 +assert_trap(() => call($43, "test", [25])); + +// table_copy.wast:2336 +assert_trap(() => call($43, "test", [26])); + +// table_copy.wast:2337 +assert_trap(() => call($43, "test", [27])); + +// table_copy.wast:2338 +assert_trap(() => call($43, "test", [28])); + +// table_copy.wast:2339 +assert_trap(() => call($43, "test", [29])); + +// table_copy.wast:2340 +assert_trap(() => call($43, "test", [30])); + +// table_copy.wast:2341 +assert_trap(() => call($43, "test", [31])); + +// table_copy.wast:2343 +let $44 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2369 +assert_trap(() => call($44, "run", [0, 24, 16])); + +// table_copy.wast:2371 +assert_trap(() => call($44, "test", [0])); + +// table_copy.wast:2372 +assert_trap(() => call($44, "test", [1])); + +// table_copy.wast:2373 +assert_trap(() => call($44, "test", [2])); + +// table_copy.wast:2374 +assert_trap(() => call($44, "test", [3])); + +// table_copy.wast:2375 +assert_trap(() => call($44, "test", [4])); + +// table_copy.wast:2376 +assert_trap(() => call($44, "test", [5])); + +// table_copy.wast:2377 +assert_trap(() => call($44, "test", [6])); + +// table_copy.wast:2378 +assert_trap(() => call($44, "test", [7])); + +// table_copy.wast:2379 +assert_trap(() => call($44, "test", [8])); + +// table_copy.wast:2380 +assert_trap(() => call($44, "test", [9])); + +// table_copy.wast:2381 +assert_trap(() => call($44, "test", [10])); + +// table_copy.wast:2382 +assert_trap(() => call($44, "test", [11])); + +// table_copy.wast:2383 +assert_trap(() => call($44, "test", [12])); + +// table_copy.wast:2384 +assert_trap(() => call($44, "test", [13])); + +// table_copy.wast:2385 +assert_trap(() => call($44, "test", [14])); + +// table_copy.wast:2386 +assert_trap(() => call($44, "test", [15])); + +// table_copy.wast:2387 +assert_trap(() => call($44, "test", [16])); + +// table_copy.wast:2388 +assert_trap(() => call($44, "test", [17])); + +// table_copy.wast:2389 +assert_trap(() => call($44, "test", [18])); + +// table_copy.wast:2390 +assert_trap(() => call($44, "test", [19])); + +// table_copy.wast:2391 +assert_trap(() => call($44, "test", [20])); + +// table_copy.wast:2392 +assert_trap(() => call($44, "test", [21])); + +// table_copy.wast:2393 +assert_trap(() => call($44, "test", [22])); + +// table_copy.wast:2394 +assert_trap(() => call($44, "test", [23])); + +// table_copy.wast:2395 +assert_return(() => call($44, "test", [24]), 0); + +// table_copy.wast:2396 +assert_return(() => call($44, "test", [25]), 1); + +// table_copy.wast:2397 +assert_return(() => call($44, "test", [26]), 2); + +// table_copy.wast:2398 +assert_return(() => call($44, "test", [27]), 3); + +// table_copy.wast:2399 +assert_return(() => call($44, "test", [28]), 4); + +// table_copy.wast:2400 +assert_return(() => call($44, "test", [29]), 5); + +// table_copy.wast:2401 +assert_return(() => call($44, "test", [30]), 6); + +// table_copy.wast:2402 +assert_return(() => call($44, "test", [31]), 7); + +// table_copy.wast:2404 +let $45 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8f\x80\x80\x80\x00\x01\x00\x41\x17\x0b\x09\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2430 +assert_trap(() => call($45, "run", [0, 23, 15])); + +// table_copy.wast:2432 +assert_trap(() => call($45, "test", [0])); + +// table_copy.wast:2433 +assert_trap(() => call($45, "test", [1])); + +// table_copy.wast:2434 +assert_trap(() => call($45, "test", [2])); + +// table_copy.wast:2435 +assert_trap(() => call($45, "test", [3])); + +// table_copy.wast:2436 +assert_trap(() => call($45, "test", [4])); + +// table_copy.wast:2437 +assert_trap(() => call($45, "test", [5])); + +// table_copy.wast:2438 +assert_trap(() => call($45, "test", [6])); + +// table_copy.wast:2439 +assert_trap(() => call($45, "test", [7])); + +// table_copy.wast:2440 +assert_trap(() => call($45, "test", [8])); + +// table_copy.wast:2441 +assert_trap(() => call($45, "test", [9])); + +// table_copy.wast:2442 +assert_trap(() => call($45, "test", [10])); + +// table_copy.wast:2443 +assert_trap(() => call($45, "test", [11])); + +// table_copy.wast:2444 +assert_trap(() => call($45, "test", [12])); + +// table_copy.wast:2445 +assert_trap(() => call($45, "test", [13])); + +// table_copy.wast:2446 +assert_trap(() => call($45, "test", [14])); + +// table_copy.wast:2447 +assert_trap(() => call($45, "test", [15])); + +// table_copy.wast:2448 +assert_trap(() => call($45, "test", [16])); + +// table_copy.wast:2449 +assert_trap(() => call($45, "test", [17])); + +// table_copy.wast:2450 +assert_trap(() => call($45, "test", [18])); + +// table_copy.wast:2451 +assert_trap(() => call($45, "test", [19])); + +// table_copy.wast:2452 +assert_trap(() => call($45, "test", [20])); + +// table_copy.wast:2453 +assert_trap(() => call($45, "test", [21])); + +// table_copy.wast:2454 +assert_trap(() => call($45, "test", [22])); + +// table_copy.wast:2455 +assert_return(() => call($45, "test", [23]), 0); + +// table_copy.wast:2456 +assert_return(() => call($45, "test", [24]), 1); + +// table_copy.wast:2457 +assert_return(() => call($45, "test", [25]), 2); + +// table_copy.wast:2458 +assert_return(() => call($45, "test", [26]), 3); + +// table_copy.wast:2459 +assert_return(() => call($45, "test", [27]), 4); + +// table_copy.wast:2460 +assert_return(() => call($45, "test", [28]), 5); + +// table_copy.wast:2461 +assert_return(() => call($45, "test", [29]), 6); + +// table_copy.wast:2462 +assert_return(() => call($45, "test", [30]), 7); + +// table_copy.wast:2463 +assert_return(() => call($45, "test", [31]), 8); + +// table_copy.wast:2465 +let $46 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x0b\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2491 +assert_trap(() => call($46, "run", [24, 11, 16])); + +// table_copy.wast:2493 +assert_trap(() => call($46, "test", [0])); + +// table_copy.wast:2494 +assert_trap(() => call($46, "test", [1])); + +// table_copy.wast:2495 +assert_trap(() => call($46, "test", [2])); + +// table_copy.wast:2496 +assert_trap(() => call($46, "test", [3])); + +// table_copy.wast:2497 +assert_trap(() => call($46, "test", [4])); + +// table_copy.wast:2498 +assert_trap(() => call($46, "test", [5])); + +// table_copy.wast:2499 +assert_trap(() => call($46, "test", [6])); + +// table_copy.wast:2500 +assert_trap(() => call($46, "test", [7])); + +// table_copy.wast:2501 +assert_trap(() => call($46, "test", [8])); + +// table_copy.wast:2502 +assert_trap(() => call($46, "test", [9])); + +// table_copy.wast:2503 +assert_trap(() => call($46, "test", [10])); + +// table_copy.wast:2504 +assert_return(() => call($46, "test", [11]), 0); + +// table_copy.wast:2505 +assert_return(() => call($46, "test", [12]), 1); + +// table_copy.wast:2506 +assert_return(() => call($46, "test", [13]), 2); + +// table_copy.wast:2507 +assert_return(() => call($46, "test", [14]), 3); + +// table_copy.wast:2508 +assert_return(() => call($46, "test", [15]), 4); + +// table_copy.wast:2509 +assert_return(() => call($46, "test", [16]), 5); + +// table_copy.wast:2510 +assert_return(() => call($46, "test", [17]), 6); + +// table_copy.wast:2511 +assert_return(() => call($46, "test", [18]), 7); + +// table_copy.wast:2512 +assert_trap(() => call($46, "test", [19])); + +// table_copy.wast:2513 +assert_trap(() => call($46, "test", [20])); + +// table_copy.wast:2514 +assert_trap(() => call($46, "test", [21])); + +// table_copy.wast:2515 +assert_trap(() => call($46, "test", [22])); + +// table_copy.wast:2516 +assert_trap(() => call($46, "test", [23])); + +// table_copy.wast:2517 +assert_trap(() => call($46, "test", [24])); + +// table_copy.wast:2518 +assert_trap(() => call($46, "test", [25])); + +// table_copy.wast:2519 +assert_trap(() => call($46, "test", [26])); + +// table_copy.wast:2520 +assert_trap(() => call($46, "test", [27])); + +// table_copy.wast:2521 +assert_trap(() => call($46, "test", [28])); + +// table_copy.wast:2522 +assert_trap(() => call($46, "test", [29])); + +// table_copy.wast:2523 +assert_trap(() => call($46, "test", [30])); + +// table_copy.wast:2524 +assert_trap(() => call($46, "test", [31])); + +// table_copy.wast:2526 +let $47 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2552 +assert_trap(() => call($47, "run", [11, 24, 16])); + +// table_copy.wast:2554 +assert_trap(() => call($47, "test", [0])); + +// table_copy.wast:2555 +assert_trap(() => call($47, "test", [1])); + +// table_copy.wast:2556 +assert_trap(() => call($47, "test", [2])); + +// table_copy.wast:2557 +assert_trap(() => call($47, "test", [3])); + +// table_copy.wast:2558 +assert_trap(() => call($47, "test", [4])); + +// table_copy.wast:2559 +assert_trap(() => call($47, "test", [5])); + +// table_copy.wast:2560 +assert_trap(() => call($47, "test", [6])); + +// table_copy.wast:2561 +assert_trap(() => call($47, "test", [7])); + +// table_copy.wast:2562 +assert_trap(() => call($47, "test", [8])); + +// table_copy.wast:2563 +assert_trap(() => call($47, "test", [9])); + +// table_copy.wast:2564 +assert_trap(() => call($47, "test", [10])); + +// table_copy.wast:2565 +assert_trap(() => call($47, "test", [11])); + +// table_copy.wast:2566 +assert_trap(() => call($47, "test", [12])); + +// table_copy.wast:2567 +assert_trap(() => call($47, "test", [13])); + +// table_copy.wast:2568 +assert_trap(() => call($47, "test", [14])); + +// table_copy.wast:2569 +assert_trap(() => call($47, "test", [15])); + +// table_copy.wast:2570 +assert_trap(() => call($47, "test", [16])); + +// table_copy.wast:2571 +assert_trap(() => call($47, "test", [17])); + +// table_copy.wast:2572 +assert_trap(() => call($47, "test", [18])); + +// table_copy.wast:2573 +assert_trap(() => call($47, "test", [19])); + +// table_copy.wast:2574 +assert_trap(() => call($47, "test", [20])); + +// table_copy.wast:2575 +assert_trap(() => call($47, "test", [21])); + +// table_copy.wast:2576 +assert_trap(() => call($47, "test", [22])); + +// table_copy.wast:2577 +assert_trap(() => call($47, "test", [23])); + +// table_copy.wast:2578 +assert_return(() => call($47, "test", [24]), 0); + +// table_copy.wast:2579 +assert_return(() => call($47, "test", [25]), 1); + +// table_copy.wast:2580 +assert_return(() => call($47, "test", [26]), 2); + +// table_copy.wast:2581 +assert_return(() => call($47, "test", [27]), 3); + +// table_copy.wast:2582 +assert_return(() => call($47, "test", [28]), 4); + +// table_copy.wast:2583 +assert_return(() => call($47, "test", [29]), 5); + +// table_copy.wast:2584 +assert_return(() => call($47, "test", [30]), 6); + +// table_copy.wast:2585 +assert_return(() => call($47, "test", [31]), 7); + +// table_copy.wast:2587 +let $48 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x15\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2613 +assert_trap(() => call($48, "run", [24, 21, 16])); + +// table_copy.wast:2615 +assert_trap(() => call($48, "test", [0])); + +// table_copy.wast:2616 +assert_trap(() => call($48, "test", [1])); + +// table_copy.wast:2617 +assert_trap(() => call($48, "test", [2])); + +// table_copy.wast:2618 +assert_trap(() => call($48, "test", [3])); + +// table_copy.wast:2619 +assert_trap(() => call($48, "test", [4])); + +// table_copy.wast:2620 +assert_trap(() => call($48, "test", [5])); + +// table_copy.wast:2621 +assert_trap(() => call($48, "test", [6])); + +// table_copy.wast:2622 +assert_trap(() => call($48, "test", [7])); + +// table_copy.wast:2623 +assert_trap(() => call($48, "test", [8])); + +// table_copy.wast:2624 +assert_trap(() => call($48, "test", [9])); + +// table_copy.wast:2625 +assert_trap(() => call($48, "test", [10])); + +// table_copy.wast:2626 +assert_trap(() => call($48, "test", [11])); + +// table_copy.wast:2627 +assert_trap(() => call($48, "test", [12])); + +// table_copy.wast:2628 +assert_trap(() => call($48, "test", [13])); + +// table_copy.wast:2629 +assert_trap(() => call($48, "test", [14])); + +// table_copy.wast:2630 +assert_trap(() => call($48, "test", [15])); + +// table_copy.wast:2631 +assert_trap(() => call($48, "test", [16])); + +// table_copy.wast:2632 +assert_trap(() => call($48, "test", [17])); + +// table_copy.wast:2633 +assert_trap(() => call($48, "test", [18])); + +// table_copy.wast:2634 +assert_trap(() => call($48, "test", [19])); + +// table_copy.wast:2635 +assert_trap(() => call($48, "test", [20])); + +// table_copy.wast:2636 +assert_return(() => call($48, "test", [21]), 0); + +// table_copy.wast:2637 +assert_return(() => call($48, "test", [22]), 1); + +// table_copy.wast:2638 +assert_return(() => call($48, "test", [23]), 2); + +// table_copy.wast:2639 +assert_return(() => call($48, "test", [24]), 3); + +// table_copy.wast:2640 +assert_return(() => call($48, "test", [25]), 4); + +// table_copy.wast:2641 +assert_return(() => call($48, "test", [26]), 5); + +// table_copy.wast:2642 +assert_return(() => call($48, "test", [27]), 6); + +// table_copy.wast:2643 +assert_return(() => call($48, "test", [28]), 7); + +// table_copy.wast:2644 +assert_trap(() => call($48, "test", [29])); + +// table_copy.wast:2645 +assert_trap(() => call($48, "test", [30])); + +// table_copy.wast:2646 +assert_trap(() => call($48, "test", [31])); + +// table_copy.wast:2648 +let $49 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x8e\x80\x80\x80\x00\x01\x00\x41\x18\x0b\x08\x00\x01\x02\x03\x04\x05\x06\x07\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2674 +assert_trap(() => call($49, "run", [21, 24, 16])); + +// table_copy.wast:2676 +assert_trap(() => call($49, "test", [0])); + +// table_copy.wast:2677 +assert_trap(() => call($49, "test", [1])); + +// table_copy.wast:2678 +assert_trap(() => call($49, "test", [2])); + +// table_copy.wast:2679 +assert_trap(() => call($49, "test", [3])); + +// table_copy.wast:2680 +assert_trap(() => call($49, "test", [4])); + +// table_copy.wast:2681 +assert_trap(() => call($49, "test", [5])); + +// table_copy.wast:2682 +assert_trap(() => call($49, "test", [6])); + +// table_copy.wast:2683 +assert_trap(() => call($49, "test", [7])); + +// table_copy.wast:2684 +assert_trap(() => call($49, "test", [8])); + +// table_copy.wast:2685 +assert_trap(() => call($49, "test", [9])); + +// table_copy.wast:2686 +assert_trap(() => call($49, "test", [10])); + +// table_copy.wast:2687 +assert_trap(() => call($49, "test", [11])); + +// table_copy.wast:2688 +assert_trap(() => call($49, "test", [12])); + +// table_copy.wast:2689 +assert_trap(() => call($49, "test", [13])); + +// table_copy.wast:2690 +assert_trap(() => call($49, "test", [14])); + +// table_copy.wast:2691 +assert_trap(() => call($49, "test", [15])); + +// table_copy.wast:2692 +assert_trap(() => call($49, "test", [16])); + +// table_copy.wast:2693 +assert_trap(() => call($49, "test", [17])); + +// table_copy.wast:2694 +assert_trap(() => call($49, "test", [18])); + +// table_copy.wast:2695 +assert_trap(() => call($49, "test", [19])); + +// table_copy.wast:2696 +assert_trap(() => call($49, "test", [20])); + +// table_copy.wast:2697 +assert_trap(() => call($49, "test", [21])); + +// table_copy.wast:2698 +assert_trap(() => call($49, "test", [22])); + +// table_copy.wast:2699 +assert_trap(() => call($49, "test", [23])); + +// table_copy.wast:2700 +assert_return(() => call($49, "test", [24]), 0); + +// table_copy.wast:2701 +assert_return(() => call($49, "test", [25]), 1); + +// table_copy.wast:2702 +assert_return(() => call($49, "test", [26]), 2); + +// table_copy.wast:2703 +assert_return(() => call($49, "test", [27]), 3); + +// table_copy.wast:2704 +assert_return(() => call($49, "test", [28]), 4); + +// table_copy.wast:2705 +assert_return(() => call($49, "test", [29]), 5); + +// table_copy.wast:2706 +assert_return(() => call($49, "test", [30]), 6); + +// table_copy.wast:2707 +assert_return(() => call($49, "test", [31]), 7); + +// table_copy.wast:2709 +let $50 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x91\x80\x80\x80\x00\x01\x00\x41\x15\x0b\x0b\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2735 +assert_trap(() => call($50, "run", [21, 21, 16])); + +// table_copy.wast:2737 +assert_trap(() => call($50, "test", [0])); + +// table_copy.wast:2738 +assert_trap(() => call($50, "test", [1])); + +// table_copy.wast:2739 +assert_trap(() => call($50, "test", [2])); + +// table_copy.wast:2740 +assert_trap(() => call($50, "test", [3])); + +// table_copy.wast:2741 +assert_trap(() => call($50, "test", [4])); + +// table_copy.wast:2742 +assert_trap(() => call($50, "test", [5])); + +// table_copy.wast:2743 +assert_trap(() => call($50, "test", [6])); + +// table_copy.wast:2744 +assert_trap(() => call($50, "test", [7])); + +// table_copy.wast:2745 +assert_trap(() => call($50, "test", [8])); + +// table_copy.wast:2746 +assert_trap(() => call($50, "test", [9])); + +// table_copy.wast:2747 +assert_trap(() => call($50, "test", [10])); + +// table_copy.wast:2748 +assert_trap(() => call($50, "test", [11])); + +// table_copy.wast:2749 +assert_trap(() => call($50, "test", [12])); + +// table_copy.wast:2750 +assert_trap(() => call($50, "test", [13])); + +// table_copy.wast:2751 +assert_trap(() => call($50, "test", [14])); + +// table_copy.wast:2752 +assert_trap(() => call($50, "test", [15])); + +// table_copy.wast:2753 +assert_trap(() => call($50, "test", [16])); + +// table_copy.wast:2754 +assert_trap(() => call($50, "test", [17])); + +// table_copy.wast:2755 +assert_trap(() => call($50, "test", [18])); + +// table_copy.wast:2756 +assert_trap(() => call($50, "test", [19])); + +// table_copy.wast:2757 +assert_trap(() => call($50, "test", [20])); + +// table_copy.wast:2758 +assert_return(() => call($50, "test", [21]), 0); + +// table_copy.wast:2759 +assert_return(() => call($50, "test", [22]), 1); + +// table_copy.wast:2760 +assert_return(() => call($50, "test", [23]), 2); + +// table_copy.wast:2761 +assert_return(() => call($50, "test", [24]), 3); + +// table_copy.wast:2762 +assert_return(() => call($50, "test", [25]), 4); + +// table_copy.wast:2763 +assert_return(() => call($50, "test", [26]), 5); + +// table_copy.wast:2764 +assert_return(() => call($50, "test", [27]), 6); + +// table_copy.wast:2765 +assert_return(() => call($50, "test", [28]), 7); + +// table_copy.wast:2766 +assert_return(() => call($50, "test", [29]), 8); + +// table_copy.wast:2767 +assert_return(() => call($50, "test", [30]), 9); + +// table_copy.wast:2768 +assert_return(() => call($50, "test", [31]), 10); + +// table_copy.wast:2770 +let $51 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\x80\x01\x80\x01\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x97\x80\x80\x80\x00\x01\x00\x41\xf0\x00\x0b\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2796 +assert_trap(() => call($51, "run", [0, 112, -32])); + +// table_copy.wast:2798 +assert_trap(() => call($51, "test", [0])); + +// table_copy.wast:2799 +assert_trap(() => call($51, "test", [1])); + +// table_copy.wast:2800 +assert_trap(() => call($51, "test", [2])); + +// table_copy.wast:2801 +assert_trap(() => call($51, "test", [3])); + +// table_copy.wast:2802 +assert_trap(() => call($51, "test", [4])); + +// table_copy.wast:2803 +assert_trap(() => call($51, "test", [5])); + +// table_copy.wast:2804 +assert_trap(() => call($51, "test", [6])); + +// table_copy.wast:2805 +assert_trap(() => call($51, "test", [7])); + +// table_copy.wast:2806 +assert_trap(() => call($51, "test", [8])); + +// table_copy.wast:2807 +assert_trap(() => call($51, "test", [9])); + +// table_copy.wast:2808 +assert_trap(() => call($51, "test", [10])); + +// table_copy.wast:2809 +assert_trap(() => call($51, "test", [11])); + +// table_copy.wast:2810 +assert_trap(() => call($51, "test", [12])); + +// table_copy.wast:2811 +assert_trap(() => call($51, "test", [13])); + +// table_copy.wast:2812 +assert_trap(() => call($51, "test", [14])); + +// table_copy.wast:2813 +assert_trap(() => call($51, "test", [15])); + +// table_copy.wast:2814 +assert_trap(() => call($51, "test", [16])); + +// table_copy.wast:2815 +assert_trap(() => call($51, "test", [17])); + +// table_copy.wast:2816 +assert_trap(() => call($51, "test", [18])); + +// table_copy.wast:2817 +assert_trap(() => call($51, "test", [19])); + +// table_copy.wast:2818 +assert_trap(() => call($51, "test", [20])); + +// table_copy.wast:2819 +assert_trap(() => call($51, "test", [21])); + +// table_copy.wast:2820 +assert_trap(() => call($51, "test", [22])); + +// table_copy.wast:2821 +assert_trap(() => call($51, "test", [23])); + +// table_copy.wast:2822 +assert_trap(() => call($51, "test", [24])); + +// table_copy.wast:2823 +assert_trap(() => call($51, "test", [25])); + +// table_copy.wast:2824 +assert_trap(() => call($51, "test", [26])); + +// table_copy.wast:2825 +assert_trap(() => call($51, "test", [27])); + +// table_copy.wast:2826 +assert_trap(() => call($51, "test", [28])); + +// table_copy.wast:2827 +assert_trap(() => call($51, "test", [29])); + +// table_copy.wast:2828 +assert_trap(() => call($51, "test", [30])); + +// table_copy.wast:2829 +assert_trap(() => call($51, "test", [31])); + +// table_copy.wast:2830 +assert_trap(() => call($51, "test", [32])); + +// table_copy.wast:2831 +assert_trap(() => call($51, "test", [33])); + +// table_copy.wast:2832 +assert_trap(() => call($51, "test", [34])); + +// table_copy.wast:2833 +assert_trap(() => call($51, "test", [35])); + +// table_copy.wast:2834 +assert_trap(() => call($51, "test", [36])); + +// table_copy.wast:2835 +assert_trap(() => call($51, "test", [37])); + +// table_copy.wast:2836 +assert_trap(() => call($51, "test", [38])); + +// table_copy.wast:2837 +assert_trap(() => call($51, "test", [39])); + +// table_copy.wast:2838 +assert_trap(() => call($51, "test", [40])); + +// table_copy.wast:2839 +assert_trap(() => call($51, "test", [41])); + +// table_copy.wast:2840 +assert_trap(() => call($51, "test", [42])); + +// table_copy.wast:2841 +assert_trap(() => call($51, "test", [43])); + +// table_copy.wast:2842 +assert_trap(() => call($51, "test", [44])); + +// table_copy.wast:2843 +assert_trap(() => call($51, "test", [45])); + +// table_copy.wast:2844 +assert_trap(() => call($51, "test", [46])); + +// table_copy.wast:2845 +assert_trap(() => call($51, "test", [47])); + +// table_copy.wast:2846 +assert_trap(() => call($51, "test", [48])); + +// table_copy.wast:2847 +assert_trap(() => call($51, "test", [49])); + +// table_copy.wast:2848 +assert_trap(() => call($51, "test", [50])); + +// table_copy.wast:2849 +assert_trap(() => call($51, "test", [51])); + +// table_copy.wast:2850 +assert_trap(() => call($51, "test", [52])); + +// table_copy.wast:2851 +assert_trap(() => call($51, "test", [53])); + +// table_copy.wast:2852 +assert_trap(() => call($51, "test", [54])); + +// table_copy.wast:2853 +assert_trap(() => call($51, "test", [55])); + +// table_copy.wast:2854 +assert_trap(() => call($51, "test", [56])); + +// table_copy.wast:2855 +assert_trap(() => call($51, "test", [57])); + +// table_copy.wast:2856 +assert_trap(() => call($51, "test", [58])); + +// table_copy.wast:2857 +assert_trap(() => call($51, "test", [59])); + +// table_copy.wast:2858 +assert_trap(() => call($51, "test", [60])); + +// table_copy.wast:2859 +assert_trap(() => call($51, "test", [61])); + +// table_copy.wast:2860 +assert_trap(() => call($51, "test", [62])); + +// table_copy.wast:2861 +assert_trap(() => call($51, "test", [63])); + +// table_copy.wast:2862 +assert_trap(() => call($51, "test", [64])); + +// table_copy.wast:2863 +assert_trap(() => call($51, "test", [65])); + +// table_copy.wast:2864 +assert_trap(() => call($51, "test", [66])); + +// table_copy.wast:2865 +assert_trap(() => call($51, "test", [67])); + +// table_copy.wast:2866 +assert_trap(() => call($51, "test", [68])); + +// table_copy.wast:2867 +assert_trap(() => call($51, "test", [69])); + +// table_copy.wast:2868 +assert_trap(() => call($51, "test", [70])); + +// table_copy.wast:2869 +assert_trap(() => call($51, "test", [71])); + +// table_copy.wast:2870 +assert_trap(() => call($51, "test", [72])); + +// table_copy.wast:2871 +assert_trap(() => call($51, "test", [73])); + +// table_copy.wast:2872 +assert_trap(() => call($51, "test", [74])); + +// table_copy.wast:2873 +assert_trap(() => call($51, "test", [75])); + +// table_copy.wast:2874 +assert_trap(() => call($51, "test", [76])); + +// table_copy.wast:2875 +assert_trap(() => call($51, "test", [77])); + +// table_copy.wast:2876 +assert_trap(() => call($51, "test", [78])); + +// table_copy.wast:2877 +assert_trap(() => call($51, "test", [79])); + +// table_copy.wast:2878 +assert_trap(() => call($51, "test", [80])); + +// table_copy.wast:2879 +assert_trap(() => call($51, "test", [81])); + +// table_copy.wast:2880 +assert_trap(() => call($51, "test", [82])); + +// table_copy.wast:2881 +assert_trap(() => call($51, "test", [83])); + +// table_copy.wast:2882 +assert_trap(() => call($51, "test", [84])); + +// table_copy.wast:2883 +assert_trap(() => call($51, "test", [85])); + +// table_copy.wast:2884 +assert_trap(() => call($51, "test", [86])); + +// table_copy.wast:2885 +assert_trap(() => call($51, "test", [87])); + +// table_copy.wast:2886 +assert_trap(() => call($51, "test", [88])); + +// table_copy.wast:2887 +assert_trap(() => call($51, "test", [89])); + +// table_copy.wast:2888 +assert_trap(() => call($51, "test", [90])); + +// table_copy.wast:2889 +assert_trap(() => call($51, "test", [91])); + +// table_copy.wast:2890 +assert_trap(() => call($51, "test", [92])); + +// table_copy.wast:2891 +assert_trap(() => call($51, "test", [93])); + +// table_copy.wast:2892 +assert_trap(() => call($51, "test", [94])); + +// table_copy.wast:2893 +assert_trap(() => call($51, "test", [95])); + +// table_copy.wast:2894 +assert_trap(() => call($51, "test", [96])); + +// table_copy.wast:2895 +assert_trap(() => call($51, "test", [97])); + +// table_copy.wast:2896 +assert_trap(() => call($51, "test", [98])); + +// table_copy.wast:2897 +assert_trap(() => call($51, "test", [99])); + +// table_copy.wast:2898 +assert_trap(() => call($51, "test", [100])); + +// table_copy.wast:2899 +assert_trap(() => call($51, "test", [101])); + +// table_copy.wast:2900 +assert_trap(() => call($51, "test", [102])); + +// table_copy.wast:2901 +assert_trap(() => call($51, "test", [103])); + +// table_copy.wast:2902 +assert_trap(() => call($51, "test", [104])); + +// table_copy.wast:2903 +assert_trap(() => call($51, "test", [105])); + +// table_copy.wast:2904 +assert_trap(() => call($51, "test", [106])); + +// table_copy.wast:2905 +assert_trap(() => call($51, "test", [107])); + +// table_copy.wast:2906 +assert_trap(() => call($51, "test", [108])); + +// table_copy.wast:2907 +assert_trap(() => call($51, "test", [109])); + +// table_copy.wast:2908 +assert_trap(() => call($51, "test", [110])); + +// table_copy.wast:2909 +assert_trap(() => call($51, "test", [111])); + +// table_copy.wast:2910 +assert_return(() => call($51, "test", [112]), 0); + +// table_copy.wast:2911 +assert_return(() => call($51, "test", [113]), 1); + +// table_copy.wast:2912 +assert_return(() => call($51, "test", [114]), 2); + +// table_copy.wast:2913 +assert_return(() => call($51, "test", [115]), 3); + +// table_copy.wast:2914 +assert_return(() => call($51, "test", [116]), 4); + +// table_copy.wast:2915 +assert_return(() => call($51, "test", [117]), 5); + +// table_copy.wast:2916 +assert_return(() => call($51, "test", [118]), 6); + +// table_copy.wast:2917 +assert_return(() => call($51, "test", [119]), 7); + +// table_copy.wast:2918 +assert_return(() => call($51, "test", [120]), 8); + +// table_copy.wast:2919 +assert_return(() => call($51, "test", [121]), 9); + +// table_copy.wast:2920 +assert_return(() => call($51, "test", [122]), 10); + +// table_copy.wast:2921 +assert_return(() => call($51, "test", [123]), 11); + +// table_copy.wast:2922 +assert_return(() => call($51, "test", [124]), 12); + +// table_copy.wast:2923 +assert_return(() => call($51, "test", [125]), 13); + +// table_copy.wast:2924 +assert_return(() => call($51, "test", [126]), 14); + +// table_copy.wast:2925 +assert_return(() => call($51, "test", [127]), 15); + +// table_copy.wast:2927 +let $52 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x90\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x03\x7f\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\x80\x01\x80\x01\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x96\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x0e\x00\x00\x0b"); + +// table_copy.wast:2953 +assert_trap(() => call($52, "run", [112, 0, -32])); + +// table_copy.wast:2955 +assert_return(() => call($52, "test", [0]), 0); + +// table_copy.wast:2956 +assert_return(() => call($52, "test", [1]), 1); + +// table_copy.wast:2957 +assert_return(() => call($52, "test", [2]), 2); + +// table_copy.wast:2958 +assert_return(() => call($52, "test", [3]), 3); + +// table_copy.wast:2959 +assert_return(() => call($52, "test", [4]), 4); + +// table_copy.wast:2960 +assert_return(() => call($52, "test", [5]), 5); + +// table_copy.wast:2961 +assert_return(() => call($52, "test", [6]), 6); + +// table_copy.wast:2962 +assert_return(() => call($52, "test", [7]), 7); + +// table_copy.wast:2963 +assert_return(() => call($52, "test", [8]), 8); + +// table_copy.wast:2964 +assert_return(() => call($52, "test", [9]), 9); + +// table_copy.wast:2965 +assert_return(() => call($52, "test", [10]), 10); + +// table_copy.wast:2966 +assert_return(() => call($52, "test", [11]), 11); + +// table_copy.wast:2967 +assert_return(() => call($52, "test", [12]), 12); + +// table_copy.wast:2968 +assert_return(() => call($52, "test", [13]), 13); + +// table_copy.wast:2969 +assert_return(() => call($52, "test", [14]), 14); + +// table_copy.wast:2970 +assert_return(() => call($52, "test", [15]), 15); + +// table_copy.wast:2971 +assert_trap(() => call($52, "test", [16])); + +// table_copy.wast:2972 +assert_trap(() => call($52, "test", [17])); + +// table_copy.wast:2973 +assert_trap(() => call($52, "test", [18])); + +// table_copy.wast:2974 +assert_trap(() => call($52, "test", [19])); + +// table_copy.wast:2975 +assert_trap(() => call($52, "test", [20])); + +// table_copy.wast:2976 +assert_trap(() => call($52, "test", [21])); + +// table_copy.wast:2977 +assert_trap(() => call($52, "test", [22])); + +// table_copy.wast:2978 +assert_trap(() => call($52, "test", [23])); + +// table_copy.wast:2979 +assert_trap(() => call($52, "test", [24])); + +// table_copy.wast:2980 +assert_trap(() => call($52, "test", [25])); + +// table_copy.wast:2981 +assert_trap(() => call($52, "test", [26])); + +// table_copy.wast:2982 +assert_trap(() => call($52, "test", [27])); + +// table_copy.wast:2983 +assert_trap(() => call($52, "test", [28])); + +// table_copy.wast:2984 +assert_trap(() => call($52, "test", [29])); + +// table_copy.wast:2985 +assert_trap(() => call($52, "test", [30])); + +// table_copy.wast:2986 +assert_trap(() => call($52, "test", [31])); + +// table_copy.wast:2987 +assert_trap(() => call($52, "test", [32])); + +// table_copy.wast:2988 +assert_trap(() => call($52, "test", [33])); + +// table_copy.wast:2989 +assert_trap(() => call($52, "test", [34])); + +// table_copy.wast:2990 +assert_trap(() => call($52, "test", [35])); + +// table_copy.wast:2991 +assert_trap(() => call($52, "test", [36])); + +// table_copy.wast:2992 +assert_trap(() => call($52, "test", [37])); + +// table_copy.wast:2993 +assert_trap(() => call($52, "test", [38])); + +// table_copy.wast:2994 +assert_trap(() => call($52, "test", [39])); + +// table_copy.wast:2995 +assert_trap(() => call($52, "test", [40])); + +// table_copy.wast:2996 +assert_trap(() => call($52, "test", [41])); + +// table_copy.wast:2997 +assert_trap(() => call($52, "test", [42])); + +// table_copy.wast:2998 +assert_trap(() => call($52, "test", [43])); + +// table_copy.wast:2999 +assert_trap(() => call($52, "test", [44])); + +// table_copy.wast:3000 +assert_trap(() => call($52, "test", [45])); + +// table_copy.wast:3001 +assert_trap(() => call($52, "test", [46])); + +// table_copy.wast:3002 +assert_trap(() => call($52, "test", [47])); + +// table_copy.wast:3003 +assert_trap(() => call($52, "test", [48])); + +// table_copy.wast:3004 +assert_trap(() => call($52, "test", [49])); + +// table_copy.wast:3005 +assert_trap(() => call($52, "test", [50])); + +// table_copy.wast:3006 +assert_trap(() => call($52, "test", [51])); + +// table_copy.wast:3007 +assert_trap(() => call($52, "test", [52])); + +// table_copy.wast:3008 +assert_trap(() => call($52, "test", [53])); + +// table_copy.wast:3009 +assert_trap(() => call($52, "test", [54])); + +// table_copy.wast:3010 +assert_trap(() => call($52, "test", [55])); + +// table_copy.wast:3011 +assert_trap(() => call($52, "test", [56])); + +// table_copy.wast:3012 +assert_trap(() => call($52, "test", [57])); + +// table_copy.wast:3013 +assert_trap(() => call($52, "test", [58])); + +// table_copy.wast:3014 +assert_trap(() => call($52, "test", [59])); + +// table_copy.wast:3015 +assert_trap(() => call($52, "test", [60])); + +// table_copy.wast:3016 +assert_trap(() => call($52, "test", [61])); + +// table_copy.wast:3017 +assert_trap(() => call($52, "test", [62])); + +// table_copy.wast:3018 +assert_trap(() => call($52, "test", [63])); + +// table_copy.wast:3019 +assert_trap(() => call($52, "test", [64])); + +// table_copy.wast:3020 +assert_trap(() => call($52, "test", [65])); + +// table_copy.wast:3021 +assert_trap(() => call($52, "test", [66])); + +// table_copy.wast:3022 +assert_trap(() => call($52, "test", [67])); + +// table_copy.wast:3023 +assert_trap(() => call($52, "test", [68])); + +// table_copy.wast:3024 +assert_trap(() => call($52, "test", [69])); + +// table_copy.wast:3025 +assert_trap(() => call($52, "test", [70])); + +// table_copy.wast:3026 +assert_trap(() => call($52, "test", [71])); + +// table_copy.wast:3027 +assert_trap(() => call($52, "test", [72])); + +// table_copy.wast:3028 +assert_trap(() => call($52, "test", [73])); + +// table_copy.wast:3029 +assert_trap(() => call($52, "test", [74])); + +// table_copy.wast:3030 +assert_trap(() => call($52, "test", [75])); + +// table_copy.wast:3031 +assert_trap(() => call($52, "test", [76])); + +// table_copy.wast:3032 +assert_trap(() => call($52, "test", [77])); + +// table_copy.wast:3033 +assert_trap(() => call($52, "test", [78])); + +// table_copy.wast:3034 +assert_trap(() => call($52, "test", [79])); + +// table_copy.wast:3035 +assert_trap(() => call($52, "test", [80])); + +// table_copy.wast:3036 +assert_trap(() => call($52, "test", [81])); + +// table_copy.wast:3037 +assert_trap(() => call($52, "test", [82])); + +// table_copy.wast:3038 +assert_trap(() => call($52, "test", [83])); + +// table_copy.wast:3039 +assert_trap(() => call($52, "test", [84])); + +// table_copy.wast:3040 +assert_trap(() => call($52, "test", [85])); + +// table_copy.wast:3041 +assert_trap(() => call($52, "test", [86])); + +// table_copy.wast:3042 +assert_trap(() => call($52, "test", [87])); + +// table_copy.wast:3043 +assert_trap(() => call($52, "test", [88])); + +// table_copy.wast:3044 +assert_trap(() => call($52, "test", [89])); + +// table_copy.wast:3045 +assert_trap(() => call($52, "test", [90])); + +// table_copy.wast:3046 +assert_trap(() => call($52, "test", [91])); + +// table_copy.wast:3047 +assert_trap(() => call($52, "test", [92])); + +// table_copy.wast:3048 +assert_trap(() => call($52, "test", [93])); + +// table_copy.wast:3049 +assert_trap(() => call($52, "test", [94])); + +// table_copy.wast:3050 +assert_trap(() => call($52, "test", [95])); + +// table_copy.wast:3051 +assert_trap(() => call($52, "test", [96])); + +// table_copy.wast:3052 +assert_trap(() => call($52, "test", [97])); + +// table_copy.wast:3053 +assert_trap(() => call($52, "test", [98])); + +// table_copy.wast:3054 +assert_trap(() => call($52, "test", [99])); + +// table_copy.wast:3055 +assert_trap(() => call($52, "test", [100])); + +// table_copy.wast:3056 +assert_trap(() => call($52, "test", [101])); + +// table_copy.wast:3057 +assert_trap(() => call($52, "test", [102])); + +// table_copy.wast:3058 +assert_trap(() => call($52, "test", [103])); + +// table_copy.wast:3059 +assert_trap(() => call($52, "test", [104])); + +// table_copy.wast:3060 +assert_trap(() => call($52, "test", [105])); + +// table_copy.wast:3061 +assert_trap(() => call($52, "test", [106])); + +// table_copy.wast:3062 +assert_trap(() => call($52, "test", [107])); + +// table_copy.wast:3063 +assert_trap(() => call($52, "test", [108])); + +// table_copy.wast:3064 +assert_trap(() => call($52, "test", [109])); + +// table_copy.wast:3065 +assert_trap(() => call($52, "test", [110])); + +// table_copy.wast:3066 +assert_trap(() => call($52, "test", [111])); + +// table_copy.wast:3067 +assert_trap(() => call($52, "test", [112])); + +// table_copy.wast:3068 +assert_trap(() => call($52, "test", [113])); + +// table_copy.wast:3069 +assert_trap(() => call($52, "test", [114])); + +// table_copy.wast:3070 +assert_trap(() => call($52, "test", [115])); + +// table_copy.wast:3071 +assert_trap(() => call($52, "test", [116])); + +// table_copy.wast:3072 +assert_trap(() => call($52, "test", [117])); + +// table_copy.wast:3073 +assert_trap(() => call($52, "test", [118])); + +// table_copy.wast:3074 +assert_trap(() => call($52, "test", [119])); + +// table_copy.wast:3075 +assert_trap(() => call($52, "test", [120])); + +// table_copy.wast:3076 +assert_trap(() => call($52, "test", [121])); + +// table_copy.wast:3077 +assert_trap(() => call($52, "test", [122])); + +// table_copy.wast:3078 +assert_trap(() => call($52, "test", [123])); + +// table_copy.wast:3079 +assert_trap(() => call($52, "test", [124])); + +// table_copy.wast:3080 +assert_trap(() => call($52, "test", [125])); + +// table_copy.wast:3081 +assert_trap(() => call($52, "test", [126])); + +// table_copy.wast:3082 +assert_trap(() => call($52, "test", [127])); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_fill.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_fill.wast.js new file mode 100644 index 0000000000..eae79a7262 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_fill.wast.js @@ -0,0 +1,135 @@ + +// table_fill.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x03\x7f\x6f\x7f\x00\x60\x01\x7f\x01\x6f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x07\x8e\x80\x80\x80\x00\x02\x04\x66\x69\x6c\x6c\x00\x00\x03\x67\x65\x74\x00\x01\x0a\x9c\x80\x80\x80\x00\x02\x8b\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x02\xfc\x11\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x25\x00\x0b"); + +// table_fill.wast:13 +assert_return(() => call($1, "get", [1]), null); + +// table_fill.wast:14 +assert_return(() => call($1, "get", [2]), null); + +// table_fill.wast:15 +assert_return(() => call($1, "get", [3]), null); + +// table_fill.wast:16 +assert_return(() => call($1, "get", [4]), null); + +// table_fill.wast:17 +assert_return(() => call($1, "get", [5]), null); + +// table_fill.wast:19 +assert_return(() => call($1, "fill", [2, externref(1), 3])); + +// table_fill.wast:20 +assert_return(() => call($1, "get", [1]), null); + +// table_fill.wast:21 +assert_return(() => call($1, "get", [2]), externref(1)); + +// table_fill.wast:22 +assert_return(() => call($1, "get", [3]), externref(1)); + +// table_fill.wast:23 +assert_return(() => call($1, "get", [4]), externref(1)); + +// table_fill.wast:24 +assert_return(() => call($1, "get", [5]), null); + +// table_fill.wast:26 +assert_return(() => call($1, "fill", [4, externref(2), 2])); + +// table_fill.wast:27 +assert_return(() => call($1, "get", [3]), externref(1)); + +// table_fill.wast:28 +assert_return(() => call($1, "get", [4]), externref(2)); + +// table_fill.wast:29 +assert_return(() => call($1, "get", [5]), externref(2)); + +// table_fill.wast:30 +assert_return(() => call($1, "get", [6]), null); + +// table_fill.wast:32 +assert_return(() => call($1, "fill", [4, externref(3), 0])); + +// table_fill.wast:33 +assert_return(() => call($1, "get", [3]), externref(1)); + +// table_fill.wast:34 +assert_return(() => call($1, "get", [4]), externref(2)); + +// table_fill.wast:35 +assert_return(() => call($1, "get", [5]), externref(2)); + +// table_fill.wast:37 +assert_return(() => call($1, "fill", [8, externref(4), 2])); + +// table_fill.wast:38 +assert_return(() => call($1, "get", [7]), null); + +// table_fill.wast:39 +assert_return(() => call($1, "get", [8]), externref(4)); + +// table_fill.wast:40 +assert_return(() => call($1, "get", [9]), externref(4)); + +// table_fill.wast:42 +assert_return(() => call($1, "fill", [9, null, 1])); + +// table_fill.wast:43 +assert_return(() => call($1, "get", [8]), externref(4)); + +// table_fill.wast:44 +assert_return(() => call($1, "get", [9]), null); + +// table_fill.wast:46 +assert_return(() => call($1, "fill", [10, externref(5), 0])); + +// table_fill.wast:47 +assert_return(() => call($1, "get", [9]), null); + +// table_fill.wast:49 +assert_trap(() => call($1, "fill", [8, externref(6), 3])); + +// table_fill.wast:53 +assert_return(() => call($1, "get", [7]), null); + +// table_fill.wast:54 +assert_return(() => call($1, "get", [8]), externref(4)); + +// table_fill.wast:55 +assert_return(() => call($1, "get", [9]), null); + +// table_fill.wast:57 +assert_trap(() => call($1, "fill", [11, null, 0])); + +// table_fill.wast:62 +assert_trap(() => call($1, "fill", [11, null, 10])); + +// table_fill.wast:70 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x11\x00\x0b"); + +// table_fill.wast:79 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd0\x6f\x41\x01\xfc\x11\x00\x0b"); + +// table_fill.wast:88 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x41\x01\xfc\x11\x00\x0b"); + +// table_fill.wast:97 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\xd0\x6f\xfc\x11\x00\x0b"); + +// table_fill.wast:106 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\xd0\x6f\x41\x01\xfc\x11\x00\x0b"); + +// table_fill.wast:115 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x6f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x20\x00\x41\x01\xfc\x11\x00\x0b"); + +// table_fill.wast:124 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\xd0\x6f\x43\x00\x00\x80\x3f\xfc\x11\x00\x0b"); + +// table_fill.wast:134 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x6f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x01\x70\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x20\x00\x41\x01\xfc\x11\x01\x0b"); + +// table_fill.wast:145 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\xd0\x6f\x41\x01\xfc\x11\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_get.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_get.wast.js new file mode 100644 index 0000000000..2f5d25d748 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_get.wast.js @@ -0,0 +1,48 @@ + +// table_get.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x05\x60\x00\x00\x60\x01\x6f\x00\x60\x01\x7f\x01\x6f\x60\x01\x7f\x01\x70\x60\x01\x7f\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x03\x04\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x02\x70\x00\x03\x07\xb8\x80\x80\x80\x00\x04\x04\x69\x6e\x69\x74\x00\x01\x0d\x67\x65\x74\x2d\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x02\x0b\x67\x65\x74\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x03\x0f\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x04\x09\x89\x80\x80\x80\x00\x01\x02\x01\x41\x01\x0b\x00\x01\x00\x0a\xc0\x80\x80\x80\x00\x05\x82\x80\x80\x80\x00\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x00\x41\x02\x41\x01\x25\x01\x26\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x25\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x25\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x10\x03\xd1\x70\x0b"); + +// table_get.wast:24 +run(() => call($1, "init", [externref(1)])); + +// table_get.wast:26 +assert_return(() => call($1, "get-externref", [0]), null); + +// table_get.wast:27 +assert_return(() => call($1, "get-externref", [1]), externref(1)); + +// table_get.wast:29 +assert_return(() => call($1, "get-funcref", [0]), null); + +// table_get.wast:30 +assert_return(() => call($1, "is_null-funcref", [1]), 0); + +// table_get.wast:31 +assert_return(() => call($1, "is_null-funcref", [2]), 0); + +// table_get.wast:33 +assert_trap(() => call($1, "get-externref", [2])); + +// table_get.wast:34 +assert_trap(() => call($1, "get-funcref", [3])); + +// table_get.wast:35 +assert_trap(() => call($1, "get-externref", [-1])); + +// table_get.wast:36 +assert_trap(() => call($1, "get-funcref", [-1])); + +// table_get.wast:41 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x6f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x25\x00\x0b"); + +// table_get.wast:50 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x6f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x25\x00\x0b"); + +// table_get.wast:60 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x25\x00\x0b"); + +// table_get.wast:69 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x70\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x01\x25\x00\x0b"); + +// table_get.wast:79 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x70\x03\x82\x80\x80\x80\x00\x01\x00\x04\x87\x80\x80\x80\x00\x02\x70\x00\x01\x6f\x00\x01\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x25\x01\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_grow.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_grow.wast.js new file mode 100644 index 0000000000..b8346e102a --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_grow.wast.js @@ -0,0 +1,150 @@ + +// table_grow.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x95\x80\x80\x80\x00\x04\x60\x01\x7f\x01\x6f\x60\x02\x7f\x6f\x00\x60\x02\x7f\x6f\x01\x7f\x60\x00\x01\x7f\x03\x85\x80\x80\x80\x00\x04\x00\x01\x02\x03\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x07\x9b\x80\x80\x80\x00\x04\x03\x67\x65\x74\x00\x00\x03\x73\x65\x74\x00\x01\x04\x67\x72\x6f\x77\x00\x02\x04\x73\x69\x7a\x65\x00\x03\x0a\xb1\x80\x80\x80\x00\x04\x86\x80\x80\x80\x00\x00\x20\x00\x25\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x20\x01\x26\x00\x0b\x89\x80\x80\x80\x00\x00\x20\x01\x20\x00\xfc\x0f\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x10\x00\x0b"); + +// table_grow.wast:13 +assert_return(() => call($1, "size", []), 0); + +// table_grow.wast:14 +assert_trap(() => call($1, "set", [0, externref(2)])); + +// table_grow.wast:15 +assert_trap(() => call($1, "get", [0])); + +// table_grow.wast:17 +assert_return(() => call($1, "grow", [1, null]), 0); + +// table_grow.wast:18 +assert_return(() => call($1, "size", []), 1); + +// table_grow.wast:19 +assert_return(() => call($1, "get", [0]), null); + +// table_grow.wast:20 +assert_return(() => call($1, "set", [0, externref(2)])); + +// table_grow.wast:21 +assert_return(() => call($1, "get", [0]), externref(2)); + +// table_grow.wast:22 +assert_trap(() => call($1, "set", [1, externref(2)])); + +// table_grow.wast:23 +assert_trap(() => call($1, "get", [1])); + +// table_grow.wast:25 +assert_return(() => call($1, "grow", [4, externref(3)]), 1); + +// table_grow.wast:26 +assert_return(() => call($1, "size", []), 5); + +// table_grow.wast:27 +assert_return(() => call($1, "get", [0]), externref(2)); + +// table_grow.wast:28 +assert_return(() => call($1, "set", [0, externref(2)])); + +// table_grow.wast:29 +assert_return(() => call($1, "get", [0]), externref(2)); + +// table_grow.wast:30 +assert_return(() => call($1, "get", [1]), externref(3)); + +// table_grow.wast:31 +assert_return(() => call($1, "get", [4]), externref(3)); + +// table_grow.wast:32 +assert_return(() => call($1, "set", [4, externref(4)])); + +// table_grow.wast:33 +assert_return(() => call($1, "get", [4]), externref(4)); + +// table_grow.wast:34 +assert_trap(() => call($1, "set", [5, externref(2)])); + +// table_grow.wast:35 +assert_trap(() => call($1, "get", [5])); + +// table_grow.wast:39 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x10\x07\x88\x80\x80\x80\x00\x01\x04\x67\x72\x6f\x77\x00\x00\x09\x85\x80\x80\x80\x00\x01\x03\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd2\x00\x41\x70\xfc\x0f\x00\x0b"); + +// table_grow.wast:47 +assert_return(() => call($2, "grow", []), -1); + +// table_grow.wast:50 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x07\x88\x80\x80\x80\x00\x01\x04\x67\x72\x6f\x77\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x00\x0b"); + +// table_grow.wast:57 +assert_return(() => call($3, "grow", [0]), 0); + +// table_grow.wast:58 +assert_return(() => call($3, "grow", [1]), 0); + +// table_grow.wast:59 +assert_return(() => call($3, "grow", [0]), 1); + +// table_grow.wast:60 +assert_return(() => call($3, "grow", [2]), 1); + +// table_grow.wast:61 +assert_return(() => call($3, "grow", [800]), 3); + +// table_grow.wast:64 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x85\x80\x80\x80\x00\x01\x6f\x01\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x67\x72\x6f\x77\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x00\x0b"); + +// table_grow.wast:71 +assert_return(() => call($4, "grow", [0]), 0); + +// table_grow.wast:72 +assert_return(() => call($4, "grow", [1]), 0); + +// table_grow.wast:73 +assert_return(() => call($4, "grow", [1]), 1); + +// table_grow.wast:74 +assert_return(() => call($4, "grow", [2]), 2); + +// table_grow.wast:75 +assert_return(() => call($4, "grow", [6]), 4); + +// table_grow.wast:76 +assert_return(() => call($4, "grow", [0]), 10); + +// table_grow.wast:77 +assert_return(() => call($4, "grow", [1]), -1); + +// table_grow.wast:78 +assert_return(() => call($4, "grow", [65_536]), -1); + +// table_grow.wast:81 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x01\x70\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x9b\x80\x80\x80\x00\x02\x04\x67\x72\x6f\x77\x00\x00\x10\x63\x68\x65\x63\x6b\x2d\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6c\x6c\x00\x01\x09\x85\x80\x80\x80\x00\x01\x03\x00\x01\x01\x0a\xc6\x80\x80\x80\x00\x02\x89\x80\x80\x80\x00\x00\xd0\x70\x20\x00\xfc\x0f\x00\x0b\xb2\x80\x80\x80\x00\x01\x01\x70\xd2\x01\x21\x02\x02\x40\x03\x40\x20\x00\x25\x00\x21\x02\x20\x02\xd1\x70\x45\x0d\x01\x20\x00\x20\x01\x4f\x0d\x01\x20\x00\x41\x01\x6a\x21\x00\x20\x00\x20\x01\x4d\x0d\x00\x0b\x0b\x20\x02\x0b"); + +// table_grow.wast:103 +assert_return(() => call($5, "check-table-null", [0, 9]), null); + +// table_grow.wast:104 +assert_return(() => call($5, "grow", [10]), 10); + +// table_grow.wast:105 +assert_return(() => call($5, "check-table-null", [0, 19]), null); + +// table_grow.wast:110 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0f\x00\x0b"); + +// table_grow.wast:119 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\xd0\x6f\xfc\x0f\x00\x0b"); + +// table_grow.wast:128 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x01\xfc\x0f\x00\x0b"); + +// table_grow.wast:137 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\xd0\x6f\x43\x00\x00\x80\x3f\xfc\x0f\x00\x0b"); + +// table_grow.wast:146 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x6f\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x20\x00\x41\x01\xfc\x0f\x00\x0b"); + +// table_grow.wast:156 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x01\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd0\x6f\x41\x00\xfc\x0f\x00\x0b"); + +// table_grow.wast:165 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x01\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\xd0\x6f\x41\x00\xfc\x0f\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_init.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_init.wast.js new file mode 100644 index 0000000000..dc6a6b431b --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_init.wast.js @@ -0,0 +1,2340 @@ + +// table_init.wast:6 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x86\x80\x80\x80\x00\x05\x00\x00\x00\x00\x00\x07\x9f\x80\x80\x80\x00\x05\x03\x65\x66\x30\x00\x00\x03\x65\x66\x31\x00\x01\x03\x65\x66\x32\x00\x02\x03\x65\x66\x33\x00\x03\x03\x65\x66\x34\x00\x04\x0a\xae\x80\x80\x80\x00\x05\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b"); + +// table_init.wast:13 +register("a", $1) + +// table_init.wast:15 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:41 +run(() => call($2, "test", [])); + +// table_init.wast:42 +assert_trap(() => call($2, "check", [0])); + +// table_init.wast:43 +assert_trap(() => call($2, "check", [1])); + +// table_init.wast:44 +assert_return(() => call($2, "check", [2]), 3); + +// table_init.wast:45 +assert_return(() => call($2, "check", [3]), 1); + +// table_init.wast:46 +assert_return(() => call($2, "check", [4]), 4); + +// table_init.wast:47 +assert_return(() => call($2, "check", [5]), 1); + +// table_init.wast:48 +assert_trap(() => call($2, "check", [6])); + +// table_init.wast:49 +assert_return(() => call($2, "check", [7]), 2); + +// table_init.wast:50 +assert_return(() => call($2, "check", [8]), 7); + +// table_init.wast:51 +assert_return(() => call($2, "check", [9]), 1); + +// table_init.wast:52 +assert_return(() => call($2, "check", [10]), 8); + +// table_init.wast:53 +assert_trap(() => call($2, "check", [11])); + +// table_init.wast:54 +assert_return(() => call($2, "check", [12]), 7); + +// table_init.wast:55 +assert_return(() => call($2, "check", [13]), 5); + +// table_init.wast:56 +assert_return(() => call($2, "check", [14]), 2); + +// table_init.wast:57 +assert_return(() => call($2, "check", [15]), 3); + +// table_init.wast:58 +assert_return(() => call($2, "check", [16]), 6); + +// table_init.wast:59 +assert_trap(() => call($2, "check", [17])); + +// table_init.wast:60 +assert_trap(() => call($2, "check", [18])); + +// table_init.wast:61 +assert_trap(() => call($2, "check", [19])); + +// table_init.wast:62 +assert_trap(() => call($2, "check", [20])); + +// table_init.wast:63 +assert_trap(() => call($2, "check", [21])); + +// table_init.wast:64 +assert_trap(() => call($2, "check", [22])); + +// table_init.wast:65 +assert_trap(() => call($2, "check", [23])); + +// table_init.wast:66 +assert_trap(() => call($2, "check", [24])); + +// table_init.wast:67 +assert_trap(() => call($2, "check", [25])); + +// table_init.wast:68 +assert_trap(() => call($2, "check", [26])); + +// table_init.wast:69 +assert_trap(() => call($2, "check", [27])); + +// table_init.wast:70 +assert_trap(() => call($2, "check", [28])); + +// table_init.wast:71 +assert_trap(() => call($2, "check", [29])); + +// table_init.wast:73 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:99 +run(() => call($3, "test", [])); + +// table_init.wast:100 +assert_trap(() => call($3, "check", [0])); + +// table_init.wast:101 +assert_trap(() => call($3, "check", [1])); + +// table_init.wast:102 +assert_return(() => call($3, "check", [2]), 3); + +// table_init.wast:103 +assert_return(() => call($3, "check", [3]), 1); + +// table_init.wast:104 +assert_return(() => call($3, "check", [4]), 4); + +// table_init.wast:105 +assert_return(() => call($3, "check", [5]), 1); + +// table_init.wast:106 +assert_trap(() => call($3, "check", [6])); + +// table_init.wast:107 +assert_trap(() => call($3, "check", [7])); + +// table_init.wast:108 +assert_trap(() => call($3, "check", [8])); + +// table_init.wast:109 +assert_trap(() => call($3, "check", [9])); + +// table_init.wast:110 +assert_trap(() => call($3, "check", [10])); + +// table_init.wast:111 +assert_trap(() => call($3, "check", [11])); + +// table_init.wast:112 +assert_return(() => call($3, "check", [12]), 7); + +// table_init.wast:113 +assert_return(() => call($3, "check", [13]), 5); + +// table_init.wast:114 +assert_return(() => call($3, "check", [14]), 2); + +// table_init.wast:115 +assert_return(() => call($3, "check", [15]), 9); + +// table_init.wast:116 +assert_return(() => call($3, "check", [16]), 2); + +// table_init.wast:117 +assert_return(() => call($3, "check", [17]), 7); + +// table_init.wast:118 +assert_trap(() => call($3, "check", [18])); + +// table_init.wast:119 +assert_trap(() => call($3, "check", [19])); + +// table_init.wast:120 +assert_trap(() => call($3, "check", [20])); + +// table_init.wast:121 +assert_trap(() => call($3, "check", [21])); + +// table_init.wast:122 +assert_trap(() => call($3, "check", [22])); + +// table_init.wast:123 +assert_trap(() => call($3, "check", [23])); + +// table_init.wast:124 +assert_trap(() => call($3, "check", [24])); + +// table_init.wast:125 +assert_trap(() => call($3, "check", [25])); + +// table_init.wast:126 +assert_trap(() => call($3, "check", [26])); + +// table_init.wast:127 +assert_trap(() => call($3, "check", [27])); + +// table_init.wast:128 +assert_trap(() => call($3, "check", [28])); + +// table_init.wast:129 +assert_trap(() => call($3, "check", [29])); + +// table_init.wast:131 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\x8d\x81\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\xce\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x00\xfc\x0d\x01\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x00\xfc\x0d\x03\x41\x14\x41\x0f\x41\x05\xfc\x0e\x00\x00\x41\x15\x41\x1d\x41\x01\xfc\x0e\x00\x00\x41\x18\x41\x0a\x41\x01\xfc\x0e\x00\x00\x41\x0d\x41\x0b\x41\x04\xfc\x0e\x00\x00\x41\x13\x41\x14\x41\x05\xfc\x0e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b"); + +// table_init.wast:165 +run(() => call($4, "test", [])); + +// table_init.wast:166 +assert_trap(() => call($4, "check", [0])); + +// table_init.wast:167 +assert_trap(() => call($4, "check", [1])); + +// table_init.wast:168 +assert_return(() => call($4, "check", [2]), 3); + +// table_init.wast:169 +assert_return(() => call($4, "check", [3]), 1); + +// table_init.wast:170 +assert_return(() => call($4, "check", [4]), 4); + +// table_init.wast:171 +assert_return(() => call($4, "check", [5]), 1); + +// table_init.wast:172 +assert_trap(() => call($4, "check", [6])); + +// table_init.wast:173 +assert_return(() => call($4, "check", [7]), 2); + +// table_init.wast:174 +assert_return(() => call($4, "check", [8]), 7); + +// table_init.wast:175 +assert_return(() => call($4, "check", [9]), 1); + +// table_init.wast:176 +assert_return(() => call($4, "check", [10]), 8); + +// table_init.wast:177 +assert_trap(() => call($4, "check", [11])); + +// table_init.wast:178 +assert_return(() => call($4, "check", [12]), 7); + +// table_init.wast:179 +assert_trap(() => call($4, "check", [13])); + +// table_init.wast:180 +assert_return(() => call($4, "check", [14]), 7); + +// table_init.wast:181 +assert_return(() => call($4, "check", [15]), 5); + +// table_init.wast:182 +assert_return(() => call($4, "check", [16]), 2); + +// table_init.wast:183 +assert_return(() => call($4, "check", [17]), 7); + +// table_init.wast:184 +assert_trap(() => call($4, "check", [18])); + +// table_init.wast:185 +assert_return(() => call($4, "check", [19]), 9); + +// table_init.wast:186 +assert_trap(() => call($4, "check", [20])); + +// table_init.wast:187 +assert_return(() => call($4, "check", [21]), 7); + +// table_init.wast:188 +assert_trap(() => call($4, "check", [22])); + +// table_init.wast:189 +assert_return(() => call($4, "check", [23]), 8); + +// table_init.wast:190 +assert_return(() => call($4, "check", [24]), 8); + +// table_init.wast:191 +assert_trap(() => call($4, "check", [25])); + +// table_init.wast:192 +assert_trap(() => call($4, "check", [26])); + +// table_init.wast:193 +assert_trap(() => call($4, "check", [27])); + +// table_init.wast:194 +assert_trap(() => call($4, "check", [28])); + +// table_init.wast:195 +assert_trap(() => call($4, "check", [29])); + +// table_init.wast:197 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_init.wast:223 +run(() => call($5, "test", [])); + +// table_init.wast:224 +assert_trap(() => call($5, "check", [0])); + +// table_init.wast:225 +assert_trap(() => call($5, "check", [1])); + +// table_init.wast:226 +assert_return(() => call($5, "check", [2]), 3); + +// table_init.wast:227 +assert_return(() => call($5, "check", [3]), 1); + +// table_init.wast:228 +assert_return(() => call($5, "check", [4]), 4); + +// table_init.wast:229 +assert_return(() => call($5, "check", [5]), 1); + +// table_init.wast:230 +assert_trap(() => call($5, "check", [6])); + +// table_init.wast:231 +assert_return(() => call($5, "check", [7]), 2); + +// table_init.wast:232 +assert_return(() => call($5, "check", [8]), 7); + +// table_init.wast:233 +assert_return(() => call($5, "check", [9]), 1); + +// table_init.wast:234 +assert_return(() => call($5, "check", [10]), 8); + +// table_init.wast:235 +assert_trap(() => call($5, "check", [11])); + +// table_init.wast:236 +assert_return(() => call($5, "check", [12]), 7); + +// table_init.wast:237 +assert_return(() => call($5, "check", [13]), 5); + +// table_init.wast:238 +assert_return(() => call($5, "check", [14]), 2); + +// table_init.wast:239 +assert_return(() => call($5, "check", [15]), 3); + +// table_init.wast:240 +assert_return(() => call($5, "check", [16]), 6); + +// table_init.wast:241 +assert_trap(() => call($5, "check", [17])); + +// table_init.wast:242 +assert_trap(() => call($5, "check", [18])); + +// table_init.wast:243 +assert_trap(() => call($5, "check", [19])); + +// table_init.wast:244 +assert_trap(() => call($5, "check", [20])); + +// table_init.wast:245 +assert_trap(() => call($5, "check", [21])); + +// table_init.wast:246 +assert_trap(() => call($5, "check", [22])); + +// table_init.wast:247 +assert_trap(() => call($5, "check", [23])); + +// table_init.wast:248 +assert_trap(() => call($5, "check", [24])); + +// table_init.wast:249 +assert_trap(() => call($5, "check", [25])); + +// table_init.wast:250 +assert_trap(() => call($5, "check", [26])); + +// table_init.wast:251 +assert_trap(() => call($5, "check", [27])); + +// table_init.wast:252 +assert_trap(() => call($5, "check", [28])); + +// table_init.wast:253 +assert_trap(() => call($5, "check", [29])); + +// table_init.wast:255 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xcb\x80\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_init.wast:281 +run(() => call($6, "test", [])); + +// table_init.wast:282 +assert_trap(() => call($6, "check", [0])); + +// table_init.wast:283 +assert_trap(() => call($6, "check", [1])); + +// table_init.wast:284 +assert_return(() => call($6, "check", [2]), 3); + +// table_init.wast:285 +assert_return(() => call($6, "check", [3]), 1); + +// table_init.wast:286 +assert_return(() => call($6, "check", [4]), 4); + +// table_init.wast:287 +assert_return(() => call($6, "check", [5]), 1); + +// table_init.wast:288 +assert_trap(() => call($6, "check", [6])); + +// table_init.wast:289 +assert_trap(() => call($6, "check", [7])); + +// table_init.wast:290 +assert_trap(() => call($6, "check", [8])); + +// table_init.wast:291 +assert_trap(() => call($6, "check", [9])); + +// table_init.wast:292 +assert_trap(() => call($6, "check", [10])); + +// table_init.wast:293 +assert_trap(() => call($6, "check", [11])); + +// table_init.wast:294 +assert_return(() => call($6, "check", [12]), 7); + +// table_init.wast:295 +assert_return(() => call($6, "check", [13]), 5); + +// table_init.wast:296 +assert_return(() => call($6, "check", [14]), 2); + +// table_init.wast:297 +assert_return(() => call($6, "check", [15]), 9); + +// table_init.wast:298 +assert_return(() => call($6, "check", [16]), 2); + +// table_init.wast:299 +assert_return(() => call($6, "check", [17]), 7); + +// table_init.wast:300 +assert_trap(() => call($6, "check", [18])); + +// table_init.wast:301 +assert_trap(() => call($6, "check", [19])); + +// table_init.wast:302 +assert_trap(() => call($6, "check", [20])); + +// table_init.wast:303 +assert_trap(() => call($6, "check", [21])); + +// table_init.wast:304 +assert_trap(() => call($6, "check", [22])); + +// table_init.wast:305 +assert_trap(() => call($6, "check", [23])); + +// table_init.wast:306 +assert_trap(() => call($6, "check", [24])); + +// table_init.wast:307 +assert_trap(() => call($6, "check", [25])); + +// table_init.wast:308 +assert_trap(() => call($6, "check", [26])); + +// table_init.wast:309 +assert_trap(() => call($6, "check", [27])); + +// table_init.wast:310 +assert_trap(() => call($6, "check", [28])); + +// table_init.wast:311 +assert_trap(() => call($6, "check", [29])); + +// table_init.wast:313 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x00\x00\x60\x01\x7f\x01\x7f\x02\xa9\x80\x80\x80\x00\x05\x01\x61\x03\x65\x66\x30\x00\x00\x01\x61\x03\x65\x66\x31\x00\x00\x01\x61\x03\x65\x66\x32\x00\x00\x01\x61\x03\x65\x66\x33\x00\x00\x01\x61\x03\x65\x66\x34\x00\x00\x03\x88\x80\x80\x80\x00\x07\x00\x00\x00\x00\x00\x01\x02\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1e\x1e\x07\x90\x80\x80\x80\x00\x02\x04\x74\x65\x73\x74\x00\x0a\x05\x63\x68\x65\x63\x6b\x00\x0b\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\x8d\x81\x80\x80\x00\x07\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\xce\x80\x80\x80\x00\x00\x41\x07\x41\x00\x41\x04\xfc\x0c\x01\x01\xfc\x0d\x01\x41\x0f\x41\x01\x41\x03\xfc\x0c\x03\x01\xfc\x0d\x03\x41\x14\x41\x0f\x41\x05\xfc\x0e\x01\x01\x41\x15\x41\x1d\x41\x01\xfc\x0e\x01\x01\x41\x18\x41\x0a\x41\x01\xfc\x0e\x01\x01\x41\x0d\x41\x0b\x41\x04\xfc\x0e\x01\x01\x41\x13\x41\x14\x41\x05\xfc\x0e\x01\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x01\x0b"); + +// table_init.wast:347 +run(() => call($7, "test", [])); + +// table_init.wast:348 +assert_trap(() => call($7, "check", [0])); + +// table_init.wast:349 +assert_trap(() => call($7, "check", [1])); + +// table_init.wast:350 +assert_return(() => call($7, "check", [2]), 3); + +// table_init.wast:351 +assert_return(() => call($7, "check", [3]), 1); + +// table_init.wast:352 +assert_return(() => call($7, "check", [4]), 4); + +// table_init.wast:353 +assert_return(() => call($7, "check", [5]), 1); + +// table_init.wast:354 +assert_trap(() => call($7, "check", [6])); + +// table_init.wast:355 +assert_return(() => call($7, "check", [7]), 2); + +// table_init.wast:356 +assert_return(() => call($7, "check", [8]), 7); + +// table_init.wast:357 +assert_return(() => call($7, "check", [9]), 1); + +// table_init.wast:358 +assert_return(() => call($7, "check", [10]), 8); + +// table_init.wast:359 +assert_trap(() => call($7, "check", [11])); + +// table_init.wast:360 +assert_return(() => call($7, "check", [12]), 7); + +// table_init.wast:361 +assert_trap(() => call($7, "check", [13])); + +// table_init.wast:362 +assert_return(() => call($7, "check", [14]), 7); + +// table_init.wast:363 +assert_return(() => call($7, "check", [15]), 5); + +// table_init.wast:364 +assert_return(() => call($7, "check", [16]), 2); + +// table_init.wast:365 +assert_return(() => call($7, "check", [17]), 7); + +// table_init.wast:366 +assert_trap(() => call($7, "check", [18])); + +// table_init.wast:367 +assert_return(() => call($7, "check", [19]), 9); + +// table_init.wast:368 +assert_trap(() => call($7, "check", [20])); + +// table_init.wast:369 +assert_return(() => call($7, "check", [21]), 7); + +// table_init.wast:370 +assert_trap(() => call($7, "check", [22])); + +// table_init.wast:371 +assert_return(() => call($7, "check", [23]), 8); + +// table_init.wast:372 +assert_return(() => call($7, "check", [24]), 8); + +// table_init.wast:373 +assert_trap(() => call($7, "check", [25])); + +// table_init.wast:374 +assert_trap(() => call($7, "check", [26])); + +// table_init.wast:375 +assert_trap(() => call($7, "check", [27])); + +// table_init.wast:376 +assert_trap(() => call($7, "check", [28])); + +// table_init.wast:377 +assert_trap(() => call($7, "check", [29])); + +// table_init.wast:378 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x0d\x00\x0b"); + +// table_init.wast:384 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:390 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x04\x0b"); + +// table_init.wast:398 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x85\x80\x80\x80\x00\x01\x01\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x04\x00\x0b"); + +// table_init.wast:407 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xe5\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x85\x80\x80\x80\x00\x00\xfc\x0d\x02\x0b"); + +// table_init.wast:429 +run(() => call($8, "test", [])); + +// table_init.wast:431 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x02\x00\x0b"); + +// table_init.wast:453 +assert_trap(() => call($9, "test", [])); + +// table_init.wast:455 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xf6\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x96\x80\x80\x80\x00\x00\x41\x0c\x41\x01\x41\x01\xfc\x0c\x01\x00\x41\x15\x41\x01\x41\x01\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:477 +run(() => call($10, "test", [])); + +// table_init.wast:479 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xe8\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x88\x80\x80\x80\x00\x00\xfc\x0d\x01\xfc\x0d\x01\x0b"); + +// table_init.wast:501 +run(() => call($11, "test", [])); + +// table_init.wast:503 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xef\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8f\x80\x80\x80\x00\x00\xfc\x0d\x01\x41\x0c\x41\x01\x41\x01\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:525 +assert_trap(() => call($12, "test", [])); + +// table_init.wast:527 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x00\x41\x05\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:549 +assert_trap(() => call($13, "test", [])); + +// table_init.wast:551 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x02\x41\x03\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:573 +assert_trap(() => call($14, "test", [])); + +// table_init.wast:575 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x01\x41\x03\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:597 +assert_trap(() => call($15, "test", [])); + +// table_init.wast:599 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x04\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:621 +run(() => call($16, "test", [])); + +// table_init.wast:623 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x05\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:645 +assert_trap(() => call($17, "test", [])); + +// table_init.wast:647 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x02\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:669 +run(() => call($18, "test", [])); + +// table_init.wast:671 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x02\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:693 +assert_trap(() => call($19, "test", [])); + +// table_init.wast:695 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1e\x41\x04\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:717 +run(() => call($20, "test", [])); + +// table_init.wast:719 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa3\x80\x80\x80\x00\x04\x00\x41\x02\x0b\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x00\x41\x0c\x0b\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1f\x41\x05\x41\x00\xfc\x0c\x01\x00\x0b"); + +// table_init.wast:741 +assert_trap(() => call($21, "test", [])); + +// table_init.wast:743 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1a\x41\x01\x41\x03\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:765 +assert_trap(() => call($22, "test", [])); + +// table_init.wast:767 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x04\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:789 +run(() => call($23, "test", [])); + +// table_init.wast:791 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x0c\x41\x05\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:813 +assert_trap(() => call($24, "test", [])); + +// table_init.wast:815 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x02\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:837 +run(() => call($25, "test", [])); + +// table_init.wast:839 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1d\x41\x02\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:861 +assert_trap(() => call($26, "test", [])); + +// table_init.wast:863 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1c\x41\x04\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:885 +run(() => call($27, "test", [])); + +// table_init.wast:887 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x00\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x89\x80\x80\x80\x00\x02\x70\x01\x1e\x1e\x70\x01\x1c\x1c\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x0a\x09\xa7\x80\x80\x80\x00\x04\x02\x01\x41\x02\x0b\x00\x04\x03\x01\x04\x01\x01\x00\x04\x02\x07\x01\x08\x02\x01\x41\x0c\x0b\x00\x05\x07\x05\x02\x03\x06\x01\x00\x05\x05\x09\x02\x07\x06\x0a\xec\x80\x80\x80\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x8c\x80\x80\x80\x00\x00\x41\x1d\x41\x05\x41\x00\xfc\x0c\x01\x01\x0b"); + +// table_init.wast:909 +assert_trap(() => call($28, "test", [])); + +// table_init.wast:911 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:920 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:929 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:938 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:947 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:956 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:965 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:974 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:983 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:992 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1001 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1010 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1019 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1028 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1037 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1046 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1055 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1064 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1073 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1082 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1091 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa2\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x95\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1100 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1109 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1118 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1127 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1136 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1145 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1154 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1163 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1172 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1181 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1190 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1199 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1208 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1217 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1226 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1235 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9f\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x92\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1244 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1253 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x42\x01\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1262 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1271 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8f\x80\x80\x80\x00\x00\x42\x01\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1280 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x42\x01\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1289 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1298 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1307 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1316 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1325 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1334 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1343 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1352 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1361 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1370 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1379 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa6\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x99\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1388 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1397 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1406 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1415 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa3\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1424 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa0\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x93\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1433 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1442 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1451 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xaa\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x43\x00\x00\x80\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1460 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xa7\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x9a\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x42\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1469 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x07\x88\x80\x80\x80\x00\x01\x04\x74\x65\x73\x74\x00\x01\x09\x87\x80\x80\x80\x00\x01\x01\x00\x03\x00\x00\x00\x0a\xae\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\xa1\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1478 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1506 +assert_trap(() => call($29, "run", [24, 16])); + +// table_init.wast:1507 +assert_trap(() => call($29, "test", [0])); + +// table_init.wast:1508 +assert_trap(() => call($29, "test", [1])); + +// table_init.wast:1509 +assert_trap(() => call($29, "test", [2])); + +// table_init.wast:1510 +assert_trap(() => call($29, "test", [3])); + +// table_init.wast:1511 +assert_trap(() => call($29, "test", [4])); + +// table_init.wast:1512 +assert_trap(() => call($29, "test", [5])); + +// table_init.wast:1513 +assert_trap(() => call($29, "test", [6])); + +// table_init.wast:1514 +assert_trap(() => call($29, "test", [7])); + +// table_init.wast:1515 +assert_trap(() => call($29, "test", [8])); + +// table_init.wast:1516 +assert_trap(() => call($29, "test", [9])); + +// table_init.wast:1517 +assert_trap(() => call($29, "test", [10])); + +// table_init.wast:1518 +assert_trap(() => call($29, "test", [11])); + +// table_init.wast:1519 +assert_trap(() => call($29, "test", [12])); + +// table_init.wast:1520 +assert_trap(() => call($29, "test", [13])); + +// table_init.wast:1521 +assert_trap(() => call($29, "test", [14])); + +// table_init.wast:1522 +assert_trap(() => call($29, "test", [15])); + +// table_init.wast:1523 +assert_trap(() => call($29, "test", [16])); + +// table_init.wast:1524 +assert_trap(() => call($29, "test", [17])); + +// table_init.wast:1525 +assert_trap(() => call($29, "test", [18])); + +// table_init.wast:1526 +assert_trap(() => call($29, "test", [19])); + +// table_init.wast:1527 +assert_trap(() => call($29, "test", [20])); + +// table_init.wast:1528 +assert_trap(() => call($29, "test", [21])); + +// table_init.wast:1529 +assert_trap(() => call($29, "test", [22])); + +// table_init.wast:1530 +assert_trap(() => call($29, "test", [23])); + +// table_init.wast:1531 +assert_trap(() => call($29, "test", [24])); + +// table_init.wast:1532 +assert_trap(() => call($29, "test", [25])); + +// table_init.wast:1533 +assert_trap(() => call($29, "test", [26])); + +// table_init.wast:1534 +assert_trap(() => call($29, "test", [27])); + +// table_init.wast:1535 +assert_trap(() => call($29, "test", [28])); + +// table_init.wast:1536 +assert_trap(() => call($29, "test", [29])); + +// table_init.wast:1537 +assert_trap(() => call($29, "test", [30])); + +// table_init.wast:1538 +assert_trap(() => call($29, "test", [31])); + +// table_init.wast:1540 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1568 +assert_trap(() => call($30, "run", [25, 16])); + +// table_init.wast:1569 +assert_trap(() => call($30, "test", [0])); + +// table_init.wast:1570 +assert_trap(() => call($30, "test", [1])); + +// table_init.wast:1571 +assert_trap(() => call($30, "test", [2])); + +// table_init.wast:1572 +assert_trap(() => call($30, "test", [3])); + +// table_init.wast:1573 +assert_trap(() => call($30, "test", [4])); + +// table_init.wast:1574 +assert_trap(() => call($30, "test", [5])); + +// table_init.wast:1575 +assert_trap(() => call($30, "test", [6])); + +// table_init.wast:1576 +assert_trap(() => call($30, "test", [7])); + +// table_init.wast:1577 +assert_trap(() => call($30, "test", [8])); + +// table_init.wast:1578 +assert_trap(() => call($30, "test", [9])); + +// table_init.wast:1579 +assert_trap(() => call($30, "test", [10])); + +// table_init.wast:1580 +assert_trap(() => call($30, "test", [11])); + +// table_init.wast:1581 +assert_trap(() => call($30, "test", [12])); + +// table_init.wast:1582 +assert_trap(() => call($30, "test", [13])); + +// table_init.wast:1583 +assert_trap(() => call($30, "test", [14])); + +// table_init.wast:1584 +assert_trap(() => call($30, "test", [15])); + +// table_init.wast:1585 +assert_trap(() => call($30, "test", [16])); + +// table_init.wast:1586 +assert_trap(() => call($30, "test", [17])); + +// table_init.wast:1587 +assert_trap(() => call($30, "test", [18])); + +// table_init.wast:1588 +assert_trap(() => call($30, "test", [19])); + +// table_init.wast:1589 +assert_trap(() => call($30, "test", [20])); + +// table_init.wast:1590 +assert_trap(() => call($30, "test", [21])); + +// table_init.wast:1591 +assert_trap(() => call($30, "test", [22])); + +// table_init.wast:1592 +assert_trap(() => call($30, "test", [23])); + +// table_init.wast:1593 +assert_trap(() => call($30, "test", [24])); + +// table_init.wast:1594 +assert_trap(() => call($30, "test", [25])); + +// table_init.wast:1595 +assert_trap(() => call($30, "test", [26])); + +// table_init.wast:1596 +assert_trap(() => call($30, "test", [27])); + +// table_init.wast:1597 +assert_trap(() => call($30, "test", [28])); + +// table_init.wast:1598 +assert_trap(() => call($30, "test", [29])); + +// table_init.wast:1599 +assert_trap(() => call($30, "test", [30])); + +// table_init.wast:1600 +assert_trap(() => call($30, "test", [31])); + +// table_init.wast:1602 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\xa0\x01\xc0\x02\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1630 +assert_trap(() => call($31, "run", [96, 32])); + +// table_init.wast:1631 +assert_trap(() => call($31, "test", [0])); + +// table_init.wast:1632 +assert_trap(() => call($31, "test", [1])); + +// table_init.wast:1633 +assert_trap(() => call($31, "test", [2])); + +// table_init.wast:1634 +assert_trap(() => call($31, "test", [3])); + +// table_init.wast:1635 +assert_trap(() => call($31, "test", [4])); + +// table_init.wast:1636 +assert_trap(() => call($31, "test", [5])); + +// table_init.wast:1637 +assert_trap(() => call($31, "test", [6])); + +// table_init.wast:1638 +assert_trap(() => call($31, "test", [7])); + +// table_init.wast:1639 +assert_trap(() => call($31, "test", [8])); + +// table_init.wast:1640 +assert_trap(() => call($31, "test", [9])); + +// table_init.wast:1641 +assert_trap(() => call($31, "test", [10])); + +// table_init.wast:1642 +assert_trap(() => call($31, "test", [11])); + +// table_init.wast:1643 +assert_trap(() => call($31, "test", [12])); + +// table_init.wast:1644 +assert_trap(() => call($31, "test", [13])); + +// table_init.wast:1645 +assert_trap(() => call($31, "test", [14])); + +// table_init.wast:1646 +assert_trap(() => call($31, "test", [15])); + +// table_init.wast:1647 +assert_trap(() => call($31, "test", [16])); + +// table_init.wast:1648 +assert_trap(() => call($31, "test", [17])); + +// table_init.wast:1649 +assert_trap(() => call($31, "test", [18])); + +// table_init.wast:1650 +assert_trap(() => call($31, "test", [19])); + +// table_init.wast:1651 +assert_trap(() => call($31, "test", [20])); + +// table_init.wast:1652 +assert_trap(() => call($31, "test", [21])); + +// table_init.wast:1653 +assert_trap(() => call($31, "test", [22])); + +// table_init.wast:1654 +assert_trap(() => call($31, "test", [23])); + +// table_init.wast:1655 +assert_trap(() => call($31, "test", [24])); + +// table_init.wast:1656 +assert_trap(() => call($31, "test", [25])); + +// table_init.wast:1657 +assert_trap(() => call($31, "test", [26])); + +// table_init.wast:1658 +assert_trap(() => call($31, "test", [27])); + +// table_init.wast:1659 +assert_trap(() => call($31, "test", [28])); + +// table_init.wast:1660 +assert_trap(() => call($31, "test", [29])); + +// table_init.wast:1661 +assert_trap(() => call($31, "test", [30])); + +// table_init.wast:1662 +assert_trap(() => call($31, "test", [31])); + +// table_init.wast:1663 +assert_trap(() => call($31, "test", [32])); + +// table_init.wast:1664 +assert_trap(() => call($31, "test", [33])); + +// table_init.wast:1665 +assert_trap(() => call($31, "test", [34])); + +// table_init.wast:1666 +assert_trap(() => call($31, "test", [35])); + +// table_init.wast:1667 +assert_trap(() => call($31, "test", [36])); + +// table_init.wast:1668 +assert_trap(() => call($31, "test", [37])); + +// table_init.wast:1669 +assert_trap(() => call($31, "test", [38])); + +// table_init.wast:1670 +assert_trap(() => call($31, "test", [39])); + +// table_init.wast:1671 +assert_trap(() => call($31, "test", [40])); + +// table_init.wast:1672 +assert_trap(() => call($31, "test", [41])); + +// table_init.wast:1673 +assert_trap(() => call($31, "test", [42])); + +// table_init.wast:1674 +assert_trap(() => call($31, "test", [43])); + +// table_init.wast:1675 +assert_trap(() => call($31, "test", [44])); + +// table_init.wast:1676 +assert_trap(() => call($31, "test", [45])); + +// table_init.wast:1677 +assert_trap(() => call($31, "test", [46])); + +// table_init.wast:1678 +assert_trap(() => call($31, "test", [47])); + +// table_init.wast:1679 +assert_trap(() => call($31, "test", [48])); + +// table_init.wast:1680 +assert_trap(() => call($31, "test", [49])); + +// table_init.wast:1681 +assert_trap(() => call($31, "test", [50])); + +// table_init.wast:1682 +assert_trap(() => call($31, "test", [51])); + +// table_init.wast:1683 +assert_trap(() => call($31, "test", [52])); + +// table_init.wast:1684 +assert_trap(() => call($31, "test", [53])); + +// table_init.wast:1685 +assert_trap(() => call($31, "test", [54])); + +// table_init.wast:1686 +assert_trap(() => call($31, "test", [55])); + +// table_init.wast:1687 +assert_trap(() => call($31, "test", [56])); + +// table_init.wast:1688 +assert_trap(() => call($31, "test", [57])); + +// table_init.wast:1689 +assert_trap(() => call($31, "test", [58])); + +// table_init.wast:1690 +assert_trap(() => call($31, "test", [59])); + +// table_init.wast:1691 +assert_trap(() => call($31, "test", [60])); + +// table_init.wast:1692 +assert_trap(() => call($31, "test", [61])); + +// table_init.wast:1693 +assert_trap(() => call($31, "test", [62])); + +// table_init.wast:1694 +assert_trap(() => call($31, "test", [63])); + +// table_init.wast:1695 +assert_trap(() => call($31, "test", [64])); + +// table_init.wast:1696 +assert_trap(() => call($31, "test", [65])); + +// table_init.wast:1697 +assert_trap(() => call($31, "test", [66])); + +// table_init.wast:1698 +assert_trap(() => call($31, "test", [67])); + +// table_init.wast:1699 +assert_trap(() => call($31, "test", [68])); + +// table_init.wast:1700 +assert_trap(() => call($31, "test", [69])); + +// table_init.wast:1701 +assert_trap(() => call($31, "test", [70])); + +// table_init.wast:1702 +assert_trap(() => call($31, "test", [71])); + +// table_init.wast:1703 +assert_trap(() => call($31, "test", [72])); + +// table_init.wast:1704 +assert_trap(() => call($31, "test", [73])); + +// table_init.wast:1705 +assert_trap(() => call($31, "test", [74])); + +// table_init.wast:1706 +assert_trap(() => call($31, "test", [75])); + +// table_init.wast:1707 +assert_trap(() => call($31, "test", [76])); + +// table_init.wast:1708 +assert_trap(() => call($31, "test", [77])); + +// table_init.wast:1709 +assert_trap(() => call($31, "test", [78])); + +// table_init.wast:1710 +assert_trap(() => call($31, "test", [79])); + +// table_init.wast:1711 +assert_trap(() => call($31, "test", [80])); + +// table_init.wast:1712 +assert_trap(() => call($31, "test", [81])); + +// table_init.wast:1713 +assert_trap(() => call($31, "test", [82])); + +// table_init.wast:1714 +assert_trap(() => call($31, "test", [83])); + +// table_init.wast:1715 +assert_trap(() => call($31, "test", [84])); + +// table_init.wast:1716 +assert_trap(() => call($31, "test", [85])); + +// table_init.wast:1717 +assert_trap(() => call($31, "test", [86])); + +// table_init.wast:1718 +assert_trap(() => call($31, "test", [87])); + +// table_init.wast:1719 +assert_trap(() => call($31, "test", [88])); + +// table_init.wast:1720 +assert_trap(() => call($31, "test", [89])); + +// table_init.wast:1721 +assert_trap(() => call($31, "test", [90])); + +// table_init.wast:1722 +assert_trap(() => call($31, "test", [91])); + +// table_init.wast:1723 +assert_trap(() => call($31, "test", [92])); + +// table_init.wast:1724 +assert_trap(() => call($31, "test", [93])); + +// table_init.wast:1725 +assert_trap(() => call($31, "test", [94])); + +// table_init.wast:1726 +assert_trap(() => call($31, "test", [95])); + +// table_init.wast:1727 +assert_trap(() => call($31, "test", [96])); + +// table_init.wast:1728 +assert_trap(() => call($31, "test", [97])); + +// table_init.wast:1729 +assert_trap(() => call($31, "test", [98])); + +// table_init.wast:1730 +assert_trap(() => call($31, "test", [99])); + +// table_init.wast:1731 +assert_trap(() => call($31, "test", [100])); + +// table_init.wast:1732 +assert_trap(() => call($31, "test", [101])); + +// table_init.wast:1733 +assert_trap(() => call($31, "test", [102])); + +// table_init.wast:1734 +assert_trap(() => call($31, "test", [103])); + +// table_init.wast:1735 +assert_trap(() => call($31, "test", [104])); + +// table_init.wast:1736 +assert_trap(() => call($31, "test", [105])); + +// table_init.wast:1737 +assert_trap(() => call($31, "test", [106])); + +// table_init.wast:1738 +assert_trap(() => call($31, "test", [107])); + +// table_init.wast:1739 +assert_trap(() => call($31, "test", [108])); + +// table_init.wast:1740 +assert_trap(() => call($31, "test", [109])); + +// table_init.wast:1741 +assert_trap(() => call($31, "test", [110])); + +// table_init.wast:1742 +assert_trap(() => call($31, "test", [111])); + +// table_init.wast:1743 +assert_trap(() => call($31, "test", [112])); + +// table_init.wast:1744 +assert_trap(() => call($31, "test", [113])); + +// table_init.wast:1745 +assert_trap(() => call($31, "test", [114])); + +// table_init.wast:1746 +assert_trap(() => call($31, "test", [115])); + +// table_init.wast:1747 +assert_trap(() => call($31, "test", [116])); + +// table_init.wast:1748 +assert_trap(() => call($31, "test", [117])); + +// table_init.wast:1749 +assert_trap(() => call($31, "test", [118])); + +// table_init.wast:1750 +assert_trap(() => call($31, "test", [119])); + +// table_init.wast:1751 +assert_trap(() => call($31, "test", [120])); + +// table_init.wast:1752 +assert_trap(() => call($31, "test", [121])); + +// table_init.wast:1753 +assert_trap(() => call($31, "test", [122])); + +// table_init.wast:1754 +assert_trap(() => call($31, "test", [123])); + +// table_init.wast:1755 +assert_trap(() => call($31, "test", [124])); + +// table_init.wast:1756 +assert_trap(() => call($31, "test", [125])); + +// table_init.wast:1757 +assert_trap(() => call($31, "test", [126])); + +// table_init.wast:1758 +assert_trap(() => call($31, "test", [127])); + +// table_init.wast:1759 +assert_trap(() => call($31, "test", [128])); + +// table_init.wast:1760 +assert_trap(() => call($31, "test", [129])); + +// table_init.wast:1761 +assert_trap(() => call($31, "test", [130])); + +// table_init.wast:1762 +assert_trap(() => call($31, "test", [131])); + +// table_init.wast:1763 +assert_trap(() => call($31, "test", [132])); + +// table_init.wast:1764 +assert_trap(() => call($31, "test", [133])); + +// table_init.wast:1765 +assert_trap(() => call($31, "test", [134])); + +// table_init.wast:1766 +assert_trap(() => call($31, "test", [135])); + +// table_init.wast:1767 +assert_trap(() => call($31, "test", [136])); + +// table_init.wast:1768 +assert_trap(() => call($31, "test", [137])); + +// table_init.wast:1769 +assert_trap(() => call($31, "test", [138])); + +// table_init.wast:1770 +assert_trap(() => call($31, "test", [139])); + +// table_init.wast:1771 +assert_trap(() => call($31, "test", [140])); + +// table_init.wast:1772 +assert_trap(() => call($31, "test", [141])); + +// table_init.wast:1773 +assert_trap(() => call($31, "test", [142])); + +// table_init.wast:1774 +assert_trap(() => call($31, "test", [143])); + +// table_init.wast:1775 +assert_trap(() => call($31, "test", [144])); + +// table_init.wast:1776 +assert_trap(() => call($31, "test", [145])); + +// table_init.wast:1777 +assert_trap(() => call($31, "test", [146])); + +// table_init.wast:1778 +assert_trap(() => call($31, "test", [147])); + +// table_init.wast:1779 +assert_trap(() => call($31, "test", [148])); + +// table_init.wast:1780 +assert_trap(() => call($31, "test", [149])); + +// table_init.wast:1781 +assert_trap(() => call($31, "test", [150])); + +// table_init.wast:1782 +assert_trap(() => call($31, "test", [151])); + +// table_init.wast:1783 +assert_trap(() => call($31, "test", [152])); + +// table_init.wast:1784 +assert_trap(() => call($31, "test", [153])); + +// table_init.wast:1785 +assert_trap(() => call($31, "test", [154])); + +// table_init.wast:1786 +assert_trap(() => call($31, "test", [155])); + +// table_init.wast:1787 +assert_trap(() => call($31, "test", [156])); + +// table_init.wast:1788 +assert_trap(() => call($31, "test", [157])); + +// table_init.wast:1789 +assert_trap(() => call($31, "test", [158])); + +// table_init.wast:1790 +assert_trap(() => call($31, "test", [159])); + +// table_init.wast:1792 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x87\x80\x80\x80\x00\x01\x70\x01\xa0\x01\xc0\x02\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:1820 +assert_trap(() => call($32, "run", [97, 31])); + +// table_init.wast:1821 +assert_trap(() => call($32, "test", [0])); + +// table_init.wast:1822 +assert_trap(() => call($32, "test", [1])); + +// table_init.wast:1823 +assert_trap(() => call($32, "test", [2])); + +// table_init.wast:1824 +assert_trap(() => call($32, "test", [3])); + +// table_init.wast:1825 +assert_trap(() => call($32, "test", [4])); + +// table_init.wast:1826 +assert_trap(() => call($32, "test", [5])); + +// table_init.wast:1827 +assert_trap(() => call($32, "test", [6])); + +// table_init.wast:1828 +assert_trap(() => call($32, "test", [7])); + +// table_init.wast:1829 +assert_trap(() => call($32, "test", [8])); + +// table_init.wast:1830 +assert_trap(() => call($32, "test", [9])); + +// table_init.wast:1831 +assert_trap(() => call($32, "test", [10])); + +// table_init.wast:1832 +assert_trap(() => call($32, "test", [11])); + +// table_init.wast:1833 +assert_trap(() => call($32, "test", [12])); + +// table_init.wast:1834 +assert_trap(() => call($32, "test", [13])); + +// table_init.wast:1835 +assert_trap(() => call($32, "test", [14])); + +// table_init.wast:1836 +assert_trap(() => call($32, "test", [15])); + +// table_init.wast:1837 +assert_trap(() => call($32, "test", [16])); + +// table_init.wast:1838 +assert_trap(() => call($32, "test", [17])); + +// table_init.wast:1839 +assert_trap(() => call($32, "test", [18])); + +// table_init.wast:1840 +assert_trap(() => call($32, "test", [19])); + +// table_init.wast:1841 +assert_trap(() => call($32, "test", [20])); + +// table_init.wast:1842 +assert_trap(() => call($32, "test", [21])); + +// table_init.wast:1843 +assert_trap(() => call($32, "test", [22])); + +// table_init.wast:1844 +assert_trap(() => call($32, "test", [23])); + +// table_init.wast:1845 +assert_trap(() => call($32, "test", [24])); + +// table_init.wast:1846 +assert_trap(() => call($32, "test", [25])); + +// table_init.wast:1847 +assert_trap(() => call($32, "test", [26])); + +// table_init.wast:1848 +assert_trap(() => call($32, "test", [27])); + +// table_init.wast:1849 +assert_trap(() => call($32, "test", [28])); + +// table_init.wast:1850 +assert_trap(() => call($32, "test", [29])); + +// table_init.wast:1851 +assert_trap(() => call($32, "test", [30])); + +// table_init.wast:1852 +assert_trap(() => call($32, "test", [31])); + +// table_init.wast:1853 +assert_trap(() => call($32, "test", [32])); + +// table_init.wast:1854 +assert_trap(() => call($32, "test", [33])); + +// table_init.wast:1855 +assert_trap(() => call($32, "test", [34])); + +// table_init.wast:1856 +assert_trap(() => call($32, "test", [35])); + +// table_init.wast:1857 +assert_trap(() => call($32, "test", [36])); + +// table_init.wast:1858 +assert_trap(() => call($32, "test", [37])); + +// table_init.wast:1859 +assert_trap(() => call($32, "test", [38])); + +// table_init.wast:1860 +assert_trap(() => call($32, "test", [39])); + +// table_init.wast:1861 +assert_trap(() => call($32, "test", [40])); + +// table_init.wast:1862 +assert_trap(() => call($32, "test", [41])); + +// table_init.wast:1863 +assert_trap(() => call($32, "test", [42])); + +// table_init.wast:1864 +assert_trap(() => call($32, "test", [43])); + +// table_init.wast:1865 +assert_trap(() => call($32, "test", [44])); + +// table_init.wast:1866 +assert_trap(() => call($32, "test", [45])); + +// table_init.wast:1867 +assert_trap(() => call($32, "test", [46])); + +// table_init.wast:1868 +assert_trap(() => call($32, "test", [47])); + +// table_init.wast:1869 +assert_trap(() => call($32, "test", [48])); + +// table_init.wast:1870 +assert_trap(() => call($32, "test", [49])); + +// table_init.wast:1871 +assert_trap(() => call($32, "test", [50])); + +// table_init.wast:1872 +assert_trap(() => call($32, "test", [51])); + +// table_init.wast:1873 +assert_trap(() => call($32, "test", [52])); + +// table_init.wast:1874 +assert_trap(() => call($32, "test", [53])); + +// table_init.wast:1875 +assert_trap(() => call($32, "test", [54])); + +// table_init.wast:1876 +assert_trap(() => call($32, "test", [55])); + +// table_init.wast:1877 +assert_trap(() => call($32, "test", [56])); + +// table_init.wast:1878 +assert_trap(() => call($32, "test", [57])); + +// table_init.wast:1879 +assert_trap(() => call($32, "test", [58])); + +// table_init.wast:1880 +assert_trap(() => call($32, "test", [59])); + +// table_init.wast:1881 +assert_trap(() => call($32, "test", [60])); + +// table_init.wast:1882 +assert_trap(() => call($32, "test", [61])); + +// table_init.wast:1883 +assert_trap(() => call($32, "test", [62])); + +// table_init.wast:1884 +assert_trap(() => call($32, "test", [63])); + +// table_init.wast:1885 +assert_trap(() => call($32, "test", [64])); + +// table_init.wast:1886 +assert_trap(() => call($32, "test", [65])); + +// table_init.wast:1887 +assert_trap(() => call($32, "test", [66])); + +// table_init.wast:1888 +assert_trap(() => call($32, "test", [67])); + +// table_init.wast:1889 +assert_trap(() => call($32, "test", [68])); + +// table_init.wast:1890 +assert_trap(() => call($32, "test", [69])); + +// table_init.wast:1891 +assert_trap(() => call($32, "test", [70])); + +// table_init.wast:1892 +assert_trap(() => call($32, "test", [71])); + +// table_init.wast:1893 +assert_trap(() => call($32, "test", [72])); + +// table_init.wast:1894 +assert_trap(() => call($32, "test", [73])); + +// table_init.wast:1895 +assert_trap(() => call($32, "test", [74])); + +// table_init.wast:1896 +assert_trap(() => call($32, "test", [75])); + +// table_init.wast:1897 +assert_trap(() => call($32, "test", [76])); + +// table_init.wast:1898 +assert_trap(() => call($32, "test", [77])); + +// table_init.wast:1899 +assert_trap(() => call($32, "test", [78])); + +// table_init.wast:1900 +assert_trap(() => call($32, "test", [79])); + +// table_init.wast:1901 +assert_trap(() => call($32, "test", [80])); + +// table_init.wast:1902 +assert_trap(() => call($32, "test", [81])); + +// table_init.wast:1903 +assert_trap(() => call($32, "test", [82])); + +// table_init.wast:1904 +assert_trap(() => call($32, "test", [83])); + +// table_init.wast:1905 +assert_trap(() => call($32, "test", [84])); + +// table_init.wast:1906 +assert_trap(() => call($32, "test", [85])); + +// table_init.wast:1907 +assert_trap(() => call($32, "test", [86])); + +// table_init.wast:1908 +assert_trap(() => call($32, "test", [87])); + +// table_init.wast:1909 +assert_trap(() => call($32, "test", [88])); + +// table_init.wast:1910 +assert_trap(() => call($32, "test", [89])); + +// table_init.wast:1911 +assert_trap(() => call($32, "test", [90])); + +// table_init.wast:1912 +assert_trap(() => call($32, "test", [91])); + +// table_init.wast:1913 +assert_trap(() => call($32, "test", [92])); + +// table_init.wast:1914 +assert_trap(() => call($32, "test", [93])); + +// table_init.wast:1915 +assert_trap(() => call($32, "test", [94])); + +// table_init.wast:1916 +assert_trap(() => call($32, "test", [95])); + +// table_init.wast:1917 +assert_trap(() => call($32, "test", [96])); + +// table_init.wast:1918 +assert_trap(() => call($32, "test", [97])); + +// table_init.wast:1919 +assert_trap(() => call($32, "test", [98])); + +// table_init.wast:1920 +assert_trap(() => call($32, "test", [99])); + +// table_init.wast:1921 +assert_trap(() => call($32, "test", [100])); + +// table_init.wast:1922 +assert_trap(() => call($32, "test", [101])); + +// table_init.wast:1923 +assert_trap(() => call($32, "test", [102])); + +// table_init.wast:1924 +assert_trap(() => call($32, "test", [103])); + +// table_init.wast:1925 +assert_trap(() => call($32, "test", [104])); + +// table_init.wast:1926 +assert_trap(() => call($32, "test", [105])); + +// table_init.wast:1927 +assert_trap(() => call($32, "test", [106])); + +// table_init.wast:1928 +assert_trap(() => call($32, "test", [107])); + +// table_init.wast:1929 +assert_trap(() => call($32, "test", [108])); + +// table_init.wast:1930 +assert_trap(() => call($32, "test", [109])); + +// table_init.wast:1931 +assert_trap(() => call($32, "test", [110])); + +// table_init.wast:1932 +assert_trap(() => call($32, "test", [111])); + +// table_init.wast:1933 +assert_trap(() => call($32, "test", [112])); + +// table_init.wast:1934 +assert_trap(() => call($32, "test", [113])); + +// table_init.wast:1935 +assert_trap(() => call($32, "test", [114])); + +// table_init.wast:1936 +assert_trap(() => call($32, "test", [115])); + +// table_init.wast:1937 +assert_trap(() => call($32, "test", [116])); + +// table_init.wast:1938 +assert_trap(() => call($32, "test", [117])); + +// table_init.wast:1939 +assert_trap(() => call($32, "test", [118])); + +// table_init.wast:1940 +assert_trap(() => call($32, "test", [119])); + +// table_init.wast:1941 +assert_trap(() => call($32, "test", [120])); + +// table_init.wast:1942 +assert_trap(() => call($32, "test", [121])); + +// table_init.wast:1943 +assert_trap(() => call($32, "test", [122])); + +// table_init.wast:1944 +assert_trap(() => call($32, "test", [123])); + +// table_init.wast:1945 +assert_trap(() => call($32, "test", [124])); + +// table_init.wast:1946 +assert_trap(() => call($32, "test", [125])); + +// table_init.wast:1947 +assert_trap(() => call($32, "test", [126])); + +// table_init.wast:1948 +assert_trap(() => call($32, "test", [127])); + +// table_init.wast:1949 +assert_trap(() => call($32, "test", [128])); + +// table_init.wast:1950 +assert_trap(() => call($32, "test", [129])); + +// table_init.wast:1951 +assert_trap(() => call($32, "test", [130])); + +// table_init.wast:1952 +assert_trap(() => call($32, "test", [131])); + +// table_init.wast:1953 +assert_trap(() => call($32, "test", [132])); + +// table_init.wast:1954 +assert_trap(() => call($32, "test", [133])); + +// table_init.wast:1955 +assert_trap(() => call($32, "test", [134])); + +// table_init.wast:1956 +assert_trap(() => call($32, "test", [135])); + +// table_init.wast:1957 +assert_trap(() => call($32, "test", [136])); + +// table_init.wast:1958 +assert_trap(() => call($32, "test", [137])); + +// table_init.wast:1959 +assert_trap(() => call($32, "test", [138])); + +// table_init.wast:1960 +assert_trap(() => call($32, "test", [139])); + +// table_init.wast:1961 +assert_trap(() => call($32, "test", [140])); + +// table_init.wast:1962 +assert_trap(() => call($32, "test", [141])); + +// table_init.wast:1963 +assert_trap(() => call($32, "test", [142])); + +// table_init.wast:1964 +assert_trap(() => call($32, "test", [143])); + +// table_init.wast:1965 +assert_trap(() => call($32, "test", [144])); + +// table_init.wast:1966 +assert_trap(() => call($32, "test", [145])); + +// table_init.wast:1967 +assert_trap(() => call($32, "test", [146])); + +// table_init.wast:1968 +assert_trap(() => call($32, "test", [147])); + +// table_init.wast:1969 +assert_trap(() => call($32, "test", [148])); + +// table_init.wast:1970 +assert_trap(() => call($32, "test", [149])); + +// table_init.wast:1971 +assert_trap(() => call($32, "test", [150])); + +// table_init.wast:1972 +assert_trap(() => call($32, "test", [151])); + +// table_init.wast:1973 +assert_trap(() => call($32, "test", [152])); + +// table_init.wast:1974 +assert_trap(() => call($32, "test", [153])); + +// table_init.wast:1975 +assert_trap(() => call($32, "test", [154])); + +// table_init.wast:1976 +assert_trap(() => call($32, "test", [155])); + +// table_init.wast:1977 +assert_trap(() => call($32, "test", [156])); + +// table_init.wast:1978 +assert_trap(() => call($32, "test", [157])); + +// table_init.wast:1979 +assert_trap(() => call($32, "test", [158])); + +// table_init.wast:1980 +assert_trap(() => call($32, "test", [159])); + +// table_init.wast:1982 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x40\x40\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x00\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:2010 +assert_trap(() => call($33, "run", [48, -16])); + +// table_init.wast:2011 +assert_trap(() => call($33, "test", [0])); + +// table_init.wast:2012 +assert_trap(() => call($33, "test", [1])); + +// table_init.wast:2013 +assert_trap(() => call($33, "test", [2])); + +// table_init.wast:2014 +assert_trap(() => call($33, "test", [3])); + +// table_init.wast:2015 +assert_trap(() => call($33, "test", [4])); + +// table_init.wast:2016 +assert_trap(() => call($33, "test", [5])); + +// table_init.wast:2017 +assert_trap(() => call($33, "test", [6])); + +// table_init.wast:2018 +assert_trap(() => call($33, "test", [7])); + +// table_init.wast:2019 +assert_trap(() => call($33, "test", [8])); + +// table_init.wast:2020 +assert_trap(() => call($33, "test", [9])); + +// table_init.wast:2021 +assert_trap(() => call($33, "test", [10])); + +// table_init.wast:2022 +assert_trap(() => call($33, "test", [11])); + +// table_init.wast:2023 +assert_trap(() => call($33, "test", [12])); + +// table_init.wast:2024 +assert_trap(() => call($33, "test", [13])); + +// table_init.wast:2025 +assert_trap(() => call($33, "test", [14])); + +// table_init.wast:2026 +assert_trap(() => call($33, "test", [15])); + +// table_init.wast:2027 +assert_trap(() => call($33, "test", [16])); + +// table_init.wast:2028 +assert_trap(() => call($33, "test", [17])); + +// table_init.wast:2029 +assert_trap(() => call($33, "test", [18])); + +// table_init.wast:2030 +assert_trap(() => call($33, "test", [19])); + +// table_init.wast:2031 +assert_trap(() => call($33, "test", [20])); + +// table_init.wast:2032 +assert_trap(() => call($33, "test", [21])); + +// table_init.wast:2033 +assert_trap(() => call($33, "test", [22])); + +// table_init.wast:2034 +assert_trap(() => call($33, "test", [23])); + +// table_init.wast:2035 +assert_trap(() => call($33, "test", [24])); + +// table_init.wast:2036 +assert_trap(() => call($33, "test", [25])); + +// table_init.wast:2037 +assert_trap(() => call($33, "test", [26])); + +// table_init.wast:2038 +assert_trap(() => call($33, "test", [27])); + +// table_init.wast:2039 +assert_trap(() => call($33, "test", [28])); + +// table_init.wast:2040 +assert_trap(() => call($33, "test", [29])); + +// table_init.wast:2041 +assert_trap(() => call($33, "test", [30])); + +// table_init.wast:2042 +assert_trap(() => call($33, "test", [31])); + +// table_init.wast:2043 +assert_trap(() => call($33, "test", [32])); + +// table_init.wast:2044 +assert_trap(() => call($33, "test", [33])); + +// table_init.wast:2045 +assert_trap(() => call($33, "test", [34])); + +// table_init.wast:2046 +assert_trap(() => call($33, "test", [35])); + +// table_init.wast:2047 +assert_trap(() => call($33, "test", [36])); + +// table_init.wast:2048 +assert_trap(() => call($33, "test", [37])); + +// table_init.wast:2049 +assert_trap(() => call($33, "test", [38])); + +// table_init.wast:2050 +assert_trap(() => call($33, "test", [39])); + +// table_init.wast:2051 +assert_trap(() => call($33, "test", [40])); + +// table_init.wast:2052 +assert_trap(() => call($33, "test", [41])); + +// table_init.wast:2053 +assert_trap(() => call($33, "test", [42])); + +// table_init.wast:2054 +assert_trap(() => call($33, "test", [43])); + +// table_init.wast:2055 +assert_trap(() => call($33, "test", [44])); + +// table_init.wast:2056 +assert_trap(() => call($33, "test", [45])); + +// table_init.wast:2057 +assert_trap(() => call($33, "test", [46])); + +// table_init.wast:2058 +assert_trap(() => call($33, "test", [47])); + +// table_init.wast:2059 +assert_trap(() => call($33, "test", [48])); + +// table_init.wast:2060 +assert_trap(() => call($33, "test", [49])); + +// table_init.wast:2061 +assert_trap(() => call($33, "test", [50])); + +// table_init.wast:2062 +assert_trap(() => call($33, "test", [51])); + +// table_init.wast:2063 +assert_trap(() => call($33, "test", [52])); + +// table_init.wast:2064 +assert_trap(() => call($33, "test", [53])); + +// table_init.wast:2065 +assert_trap(() => call($33, "test", [54])); + +// table_init.wast:2066 +assert_trap(() => call($33, "test", [55])); + +// table_init.wast:2067 +assert_trap(() => call($33, "test", [56])); + +// table_init.wast:2068 +assert_trap(() => call($33, "test", [57])); + +// table_init.wast:2069 +assert_trap(() => call($33, "test", [58])); + +// table_init.wast:2070 +assert_trap(() => call($33, "test", [59])); + +// table_init.wast:2071 +assert_trap(() => call($33, "test", [60])); + +// table_init.wast:2072 +assert_trap(() => call($33, "test", [61])); + +// table_init.wast:2073 +assert_trap(() => call($33, "test", [62])); + +// table_init.wast:2074 +assert_trap(() => call($33, "test", [63])); + +// table_init.wast:2076 +let $34 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8f\x80\x80\x80\x00\x03\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7f\x7f\x00\x03\x93\x80\x80\x80\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x10\x10\x07\xe4\x80\x80\x80\x00\x12\x02\x66\x30\x00\x00\x02\x66\x31\x00\x01\x02\x66\x32\x00\x02\x02\x66\x33\x00\x03\x02\x66\x34\x00\x04\x02\x66\x35\x00\x05\x02\x66\x36\x00\x06\x02\x66\x37\x00\x07\x02\x66\x38\x00\x08\x02\x66\x39\x00\x09\x03\x66\x31\x30\x00\x0a\x03\x66\x31\x31\x00\x0b\x03\x66\x31\x32\x00\x0c\x03\x66\x31\x33\x00\x0d\x03\x66\x31\x34\x00\x0e\x03\x66\x31\x35\x00\x0f\x04\x74\x65\x73\x74\x00\x10\x03\x72\x75\x6e\x00\x11\x09\x94\x80\x80\x80\x00\x01\x01\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x0a\xae\x81\x80\x80\x00\x12\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x01\x0b\x84\x80\x80\x80\x00\x00\x41\x02\x0b\x84\x80\x80\x80\x00\x00\x41\x03\x0b\x84\x80\x80\x80\x00\x00\x41\x04\x0b\x84\x80\x80\x80\x00\x00\x41\x05\x0b\x84\x80\x80\x80\x00\x00\x41\x06\x0b\x84\x80\x80\x80\x00\x00\x41\x07\x0b\x84\x80\x80\x80\x00\x00\x41\x08\x0b\x84\x80\x80\x80\x00\x00\x41\x09\x0b\x84\x80\x80\x80\x00\x00\x41\x0a\x0b\x84\x80\x80\x80\x00\x00\x41\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x0c\x0b\x84\x80\x80\x80\x00\x00\x41\x0d\x0b\x84\x80\x80\x80\x00\x00\x41\x0e\x0b\x84\x80\x80\x80\x00\x00\x41\x0f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x41\x08\x20\x01\xfc\x0c\x00\x00\x0b"); + +// table_init.wast:2104 +assert_trap(() => call($34, "run", [0, -4])); + +// table_init.wast:2105 +assert_trap(() => call($34, "test", [0])); + +// table_init.wast:2106 +assert_trap(() => call($34, "test", [1])); + +// table_init.wast:2107 +assert_trap(() => call($34, "test", [2])); + +// table_init.wast:2108 +assert_trap(() => call($34, "test", [3])); + +// table_init.wast:2109 +assert_trap(() => call($34, "test", [4])); + +// table_init.wast:2110 +assert_trap(() => call($34, "test", [5])); + +// table_init.wast:2111 +assert_trap(() => call($34, "test", [6])); + +// table_init.wast:2112 +assert_trap(() => call($34, "test", [7])); + +// table_init.wast:2113 +assert_trap(() => call($34, "test", [8])); + +// table_init.wast:2114 +assert_trap(() => call($34, "test", [9])); + +// table_init.wast:2115 +assert_trap(() => call($34, "test", [10])); + +// table_init.wast:2116 +assert_trap(() => call($34, "test", [11])); + +// table_init.wast:2117 +assert_trap(() => call($34, "test", [12])); + +// table_init.wast:2118 +assert_trap(() => call($34, "test", [13])); + +// table_init.wast:2119 +assert_trap(() => call($34, "test", [14])); + +// table_init.wast:2120 +assert_trap(() => call($34, "test", [15])); + +// table_init.wast:2122 +let $35 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x09\xc4\x81\x80\x80\x00\x41\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x01\x00\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\xfc\x0c\x40\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_set.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_set.wast.js new file mode 100644 index 0000000000..77079824b5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_set.wast.js @@ -0,0 +1,78 @@ + +// table_set.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa2\x80\x80\x80\x00\x07\x60\x00\x00\x60\x01\x7f\x01\x6f\x60\x01\x7f\x01\x70\x60\x02\x7f\x6f\x00\x60\x02\x7f\x70\x00\x60\x02\x7f\x7f\x00\x60\x01\x7f\x01\x7f\x03\x88\x80\x80\x80\x00\x07\x00\x01\x02\x03\x04\x05\x06\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x01\x70\x00\x02\x07\xe2\x80\x80\x80\x00\x06\x0d\x67\x65\x74\x2d\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x01\x0b\x67\x65\x74\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x02\x0d\x73\x65\x74\x2d\x65\x78\x74\x65\x72\x6e\x72\x65\x66\x00\x03\x0b\x73\x65\x74\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x04\x10\x73\x65\x74\x2d\x66\x75\x6e\x63\x72\x65\x66\x2d\x66\x72\x6f\x6d\x00\x05\x0f\x69\x73\x5f\x6e\x75\x6c\x6c\x2d\x66\x75\x6e\x63\x72\x65\x66\x00\x06\x09\x89\x80\x80\x80\x00\x01\x02\x01\x41\x01\x0b\x00\x01\x00\x0a\xd4\x80\x80\x80\x00\x07\x82\x80\x80\x80\x00\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x25\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x25\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x20\x01\x26\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x20\x01\x26\x01\x0b\x8a\x80\x80\x80\x00\x00\x20\x00\x20\x01\x25\x01\x26\x01\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x10\x02\xd1\x70\x0b"); + +// table_set.wast:29 +assert_return(() => call($1, "get-externref", [0]), null); + +// table_set.wast:30 +assert_return(() => call($1, "set-externref", [0, externref(1)])); + +// table_set.wast:31 +assert_return(() => call($1, "get-externref", [0]), externref(1)); + +// table_set.wast:32 +assert_return(() => call($1, "set-externref", [0, null])); + +// table_set.wast:33 +assert_return(() => call($1, "get-externref", [0]), null); + +// table_set.wast:35 +assert_return(() => call($1, "get-funcref", [0]), null); + +// table_set.wast:36 +assert_return(() => call($1, "set-funcref-from", [0, 1])); + +// table_set.wast:37 +assert_return(() => call($1, "is_null-funcref", [0]), 0); + +// table_set.wast:38 +assert_return(() => call($1, "set-funcref", [0, null])); + +// table_set.wast:39 +assert_return(() => call($1, "get-funcref", [0]), null); + +// table_set.wast:41 +assert_trap(() => call($1, "set-externref", [2, null])); + +// table_set.wast:42 +assert_trap(() => call($1, "set-funcref", [3, null])); + +// table_set.wast:43 +assert_trap(() => call($1, "set-externref", [-1, null])); + +// table_set.wast:44 +assert_trap(() => call($1, "set-funcref", [-1, null])); + +// table_set.wast:46 +assert_trap(() => call($1, "set-externref", [2, externref(0)])); + +// table_set.wast:47 +assert_trap(() => call($1, "set-funcref-from", [3, 1])); + +// table_set.wast:48 +assert_trap(() => call($1, "set-externref", [-1, externref(0)])); + +// table_set.wast:49 +assert_trap(() => call($1, "set-funcref-from", [-1, 1])); + +// table_set.wast:54 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x26\x00\x0b"); + +// table_set.wast:63 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\xd0\x6f\x26\x00\x0b"); + +// table_set.wast:72 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x01\x26\x00\x0b"); + +// table_set.wast:81 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\xd0\x6f\x26\x00\x0b"); + +// table_set.wast:90 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x6f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x0a\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x01\x20\x00\x26\x00\x0b"); + +// table_set.wast:100 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x6f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x87\x80\x80\x80\x00\x02\x6f\x00\x01\x70\x00\x01\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x20\x00\x26\x01\x0b"); + +// table_set.wast:111 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x0a\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\xd0\x6f\x26\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/reference-types/table_size.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/table_size.wast.js new file mode 100644 index 0000000000..3320bb7ad4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/reference-types/table_size.wast.js @@ -0,0 +1,117 @@ + +// table_size.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x01\x7f\x60\x01\x7f\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x01\x01\x01\x01\x04\x8f\x80\x80\x80\x00\x04\x6f\x00\x00\x6f\x00\x01\x6f\x01\x00\x02\x6f\x01\x03\x08\x07\xd1\x80\x80\x80\x00\x08\x07\x73\x69\x7a\x65\x2d\x74\x30\x00\x00\x07\x73\x69\x7a\x65\x2d\x74\x31\x00\x01\x07\x73\x69\x7a\x65\x2d\x74\x32\x00\x02\x07\x73\x69\x7a\x65\x2d\x74\x33\x00\x03\x07\x67\x72\x6f\x77\x2d\x74\x30\x00\x04\x07\x67\x72\x6f\x77\x2d\x74\x31\x00\x05\x07\x67\x72\x6f\x77\x2d\x74\x32\x00\x06\x07\x67\x72\x6f\x77\x2d\x74\x33\x00\x07\x0a\xe5\x80\x80\x80\x00\x08\x85\x80\x80\x80\x00\x00\xfc\x10\x00\x0b\x85\x80\x80\x80\x00\x00\xfc\x10\x01\x0b\x85\x80\x80\x80\x00\x00\xfc\x10\x02\x0b\x85\x80\x80\x80\x00\x00\xfc\x10\x03\x0b\x8a\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x00\x1a\x0b\x8a\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x01\x1a\x0b\x8a\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x02\x1a\x0b\x8a\x80\x80\x80\x00\x00\xd0\x6f\x20\x00\xfc\x0f\x03\x1a\x0b"); + +// table_size.wast:26 +assert_return(() => call($1, "size-t0", []), 0); + +// table_size.wast:27 +assert_return(() => call($1, "grow-t0", [1])); + +// table_size.wast:28 +assert_return(() => call($1, "size-t0", []), 1); + +// table_size.wast:29 +assert_return(() => call($1, "grow-t0", [4])); + +// table_size.wast:30 +assert_return(() => call($1, "size-t0", []), 5); + +// table_size.wast:31 +assert_return(() => call($1, "grow-t0", [0])); + +// table_size.wast:32 +assert_return(() => call($1, "size-t0", []), 5); + +// table_size.wast:34 +assert_return(() => call($1, "size-t1", []), 1); + +// table_size.wast:35 +assert_return(() => call($1, "grow-t1", [1])); + +// table_size.wast:36 +assert_return(() => call($1, "size-t1", []), 2); + +// table_size.wast:37 +assert_return(() => call($1, "grow-t1", [4])); + +// table_size.wast:38 +assert_return(() => call($1, "size-t1", []), 6); + +// table_size.wast:39 +assert_return(() => call($1, "grow-t1", [0])); + +// table_size.wast:40 +assert_return(() => call($1, "size-t1", []), 6); + +// table_size.wast:42 +assert_return(() => call($1, "size-t2", []), 0); + +// table_size.wast:43 +assert_return(() => call($1, "grow-t2", [3])); + +// table_size.wast:44 +assert_return(() => call($1, "size-t2", []), 0); + +// table_size.wast:45 +assert_return(() => call($1, "grow-t2", [1])); + +// table_size.wast:46 +assert_return(() => call($1, "size-t2", []), 1); + +// table_size.wast:47 +assert_return(() => call($1, "grow-t2", [0])); + +// table_size.wast:48 +assert_return(() => call($1, "size-t2", []), 1); + +// table_size.wast:49 +assert_return(() => call($1, "grow-t2", [4])); + +// table_size.wast:50 +assert_return(() => call($1, "size-t2", []), 1); + +// table_size.wast:51 +assert_return(() => call($1, "grow-t2", [1])); + +// table_size.wast:52 +assert_return(() => call($1, "size-t2", []), 2); + +// table_size.wast:54 +assert_return(() => call($1, "size-t3", []), 3); + +// table_size.wast:55 +assert_return(() => call($1, "grow-t3", [1])); + +// table_size.wast:56 +assert_return(() => call($1, "size-t3", []), 4); + +// table_size.wast:57 +assert_return(() => call($1, "grow-t3", [3])); + +// table_size.wast:58 +assert_return(() => call($1, "size-t3", []), 7); + +// table_size.wast:59 +assert_return(() => call($1, "grow-t3", [0])); + +// table_size.wast:60 +assert_return(() => call($1, "size-t3", []), 7); + +// table_size.wast:61 +assert_return(() => call($1, "grow-t3", [2])); + +// table_size.wast:62 +assert_return(() => call($1, "size-t3", []), 7); + +// table_size.wast:63 +assert_return(() => call($1, "grow-t3", [1])); + +// table_size.wast:64 +assert_return(() => call($1, "size-t3", []), 8); + +// table_size.wast:69 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x10\x00\x0b"); + +// table_size.wast:78 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x6f\x00\x01\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\xfc\x10\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js b/js/src/jit-test/tests/wasm/spec/reference-types/unreached-invalid.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/unreached-invalid.wast.js rename to js/src/jit-test/tests/wasm/spec/reference-types/unreached-invalid.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/address.wast.js b/js/src/jit-test/tests/wasm/spec/spec/address.wast.js new file mode 100644 index 0000000000..59b286ac3c --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/address.wast.js @@ -0,0 +1,780 @@ + +// address.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x01\x7f\x00\x03\x9f\x80\x80\x80\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xcd\x82\x80\x80\x00\x1e\x08\x38\x75\x5f\x67\x6f\x6f\x64\x31\x00\x00\x08\x38\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x02\x08\x38\x75\x5f\x67\x6f\x6f\x64\x34\x00\x03\x08\x38\x75\x5f\x67\x6f\x6f\x64\x35\x00\x04\x08\x38\x73\x5f\x67\x6f\x6f\x64\x31\x00\x05\x08\x38\x73\x5f\x67\x6f\x6f\x64\x32\x00\x06\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x07\x08\x38\x73\x5f\x67\x6f\x6f\x64\x34\x00\x08\x08\x38\x73\x5f\x67\x6f\x6f\x64\x35\x00\x09\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x31\x00\x0a\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x32\x00\x0b\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x0c\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x34\x00\x0d\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x35\x00\x0e\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x31\x00\x0f\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x32\x00\x10\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x11\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x34\x00\x12\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x35\x00\x13\x08\x33\x32\x5f\x67\x6f\x6f\x64\x31\x00\x14\x08\x33\x32\x5f\x67\x6f\x6f\x64\x32\x00\x15\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x16\x08\x33\x32\x5f\x67\x6f\x6f\x64\x34\x00\x17\x08\x33\x32\x5f\x67\x6f\x6f\x64\x35\x00\x18\x06\x38\x75\x5f\x62\x61\x64\x00\x19\x06\x38\x73\x5f\x62\x61\x64\x00\x1a\x07\x31\x36\x75\x5f\x62\x61\x64\x00\x1b\x07\x31\x36\x73\x5f\x62\x61\x64\x00\x1c\x06\x33\x32\x5f\x62\x61\x64\x00\x1d\x0a\x82\x83\x80\x80\x00\x1e\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2d\x00\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2c\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2c\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2c\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2c\x00\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2c\x00\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2f\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2f\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2f\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2f\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2f\x01\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2e\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2e\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2e\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2e\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2e\x01\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x28\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x28\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x28\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x28\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x28\x02\x19\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2d\x00\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2c\x00\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2f\x01\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2e\x01\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x28\x02\xff\xff\xff\xff\x0f\x1a\x0b\x0b\xa0\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x1a\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a"); + +// address.wast:104 +assert_return(() => call($1, "8u_good1", [0]), 97); + +// address.wast:105 +assert_return(() => call($1, "8u_good2", [0]), 97); + +// address.wast:106 +assert_return(() => call($1, "8u_good3", [0]), 98); + +// address.wast:107 +assert_return(() => call($1, "8u_good4", [0]), 99); + +// address.wast:108 +assert_return(() => call($1, "8u_good5", [0]), 122); + +// address.wast:110 +assert_return(() => call($1, "8s_good1", [0]), 97); + +// address.wast:111 +assert_return(() => call($1, "8s_good2", [0]), 97); + +// address.wast:112 +assert_return(() => call($1, "8s_good3", [0]), 98); + +// address.wast:113 +assert_return(() => call($1, "8s_good4", [0]), 99); + +// address.wast:114 +assert_return(() => call($1, "8s_good5", [0]), 122); + +// address.wast:116 +assert_return(() => call($1, "16u_good1", [0]), 25_185); + +// address.wast:117 +assert_return(() => call($1, "16u_good2", [0]), 25_185); + +// address.wast:118 +assert_return(() => call($1, "16u_good3", [0]), 25_442); + +// address.wast:119 +assert_return(() => call($1, "16u_good4", [0]), 25_699); + +// address.wast:120 +assert_return(() => call($1, "16u_good5", [0]), 122); + +// address.wast:122 +assert_return(() => call($1, "16s_good1", [0]), 25_185); + +// address.wast:123 +assert_return(() => call($1, "16s_good2", [0]), 25_185); + +// address.wast:124 +assert_return(() => call($1, "16s_good3", [0]), 25_442); + +// address.wast:125 +assert_return(() => call($1, "16s_good4", [0]), 25_699); + +// address.wast:126 +assert_return(() => call($1, "16s_good5", [0]), 122); + +// address.wast:128 +assert_return(() => call($1, "32_good1", [0]), 1_684_234_849); + +// address.wast:129 +assert_return(() => call($1, "32_good2", [0]), 1_684_234_849); + +// address.wast:130 +assert_return(() => call($1, "32_good3", [0]), 1_701_077_858); + +// address.wast:131 +assert_return(() => call($1, "32_good4", [0]), 1_717_920_867); + +// address.wast:132 +assert_return(() => call($1, "32_good5", [0]), 122); + +// address.wast:134 +assert_return(() => call($1, "8u_good1", [65_507]), 0); + +// address.wast:135 +assert_return(() => call($1, "8u_good2", [65_507]), 0); + +// address.wast:136 +assert_return(() => call($1, "8u_good3", [65_507]), 0); + +// address.wast:137 +assert_return(() => call($1, "8u_good4", [65_507]), 0); + +// address.wast:138 +assert_return(() => call($1, "8u_good5", [65_507]), 0); + +// address.wast:140 +assert_return(() => call($1, "8s_good1", [65_507]), 0); + +// address.wast:141 +assert_return(() => call($1, "8s_good2", [65_507]), 0); + +// address.wast:142 +assert_return(() => call($1, "8s_good3", [65_507]), 0); + +// address.wast:143 +assert_return(() => call($1, "8s_good4", [65_507]), 0); + +// address.wast:144 +assert_return(() => call($1, "8s_good5", [65_507]), 0); + +// address.wast:146 +assert_return(() => call($1, "16u_good1", [65_507]), 0); + +// address.wast:147 +assert_return(() => call($1, "16u_good2", [65_507]), 0); + +// address.wast:148 +assert_return(() => call($1, "16u_good3", [65_507]), 0); + +// address.wast:149 +assert_return(() => call($1, "16u_good4", [65_507]), 0); + +// address.wast:150 +assert_return(() => call($1, "16u_good5", [65_507]), 0); + +// address.wast:152 +assert_return(() => call($1, "16s_good1", [65_507]), 0); + +// address.wast:153 +assert_return(() => call($1, "16s_good2", [65_507]), 0); + +// address.wast:154 +assert_return(() => call($1, "16s_good3", [65_507]), 0); + +// address.wast:155 +assert_return(() => call($1, "16s_good4", [65_507]), 0); + +// address.wast:156 +assert_return(() => call($1, "16s_good5", [65_507]), 0); + +// address.wast:158 +assert_return(() => call($1, "32_good1", [65_507]), 0); + +// address.wast:159 +assert_return(() => call($1, "32_good2", [65_507]), 0); + +// address.wast:160 +assert_return(() => call($1, "32_good3", [65_507]), 0); + +// address.wast:161 +assert_return(() => call($1, "32_good4", [65_507]), 0); + +// address.wast:162 +assert_return(() => call($1, "32_good5", [65_507]), 0); + +// address.wast:164 +assert_return(() => call($1, "8u_good1", [65_508]), 0); + +// address.wast:165 +assert_return(() => call($1, "8u_good2", [65_508]), 0); + +// address.wast:166 +assert_return(() => call($1, "8u_good3", [65_508]), 0); + +// address.wast:167 +assert_return(() => call($1, "8u_good4", [65_508]), 0); + +// address.wast:168 +assert_return(() => call($1, "8u_good5", [65_508]), 0); + +// address.wast:170 +assert_return(() => call($1, "8s_good1", [65_508]), 0); + +// address.wast:171 +assert_return(() => call($1, "8s_good2", [65_508]), 0); + +// address.wast:172 +assert_return(() => call($1, "8s_good3", [65_508]), 0); + +// address.wast:173 +assert_return(() => call($1, "8s_good4", [65_508]), 0); + +// address.wast:174 +assert_return(() => call($1, "8s_good5", [65_508]), 0); + +// address.wast:176 +assert_return(() => call($1, "16u_good1", [65_508]), 0); + +// address.wast:177 +assert_return(() => call($1, "16u_good2", [65_508]), 0); + +// address.wast:178 +assert_return(() => call($1, "16u_good3", [65_508]), 0); + +// address.wast:179 +assert_return(() => call($1, "16u_good4", [65_508]), 0); + +// address.wast:180 +assert_return(() => call($1, "16u_good5", [65_508]), 0); + +// address.wast:182 +assert_return(() => call($1, "16s_good1", [65_508]), 0); + +// address.wast:183 +assert_return(() => call($1, "16s_good2", [65_508]), 0); + +// address.wast:184 +assert_return(() => call($1, "16s_good3", [65_508]), 0); + +// address.wast:185 +assert_return(() => call($1, "16s_good4", [65_508]), 0); + +// address.wast:186 +assert_return(() => call($1, "16s_good5", [65_508]), 0); + +// address.wast:188 +assert_return(() => call($1, "32_good1", [65_508]), 0); + +// address.wast:189 +assert_return(() => call($1, "32_good2", [65_508]), 0); + +// address.wast:190 +assert_return(() => call($1, "32_good3", [65_508]), 0); + +// address.wast:191 +assert_return(() => call($1, "32_good4", [65_508]), 0); + +// address.wast:192 +assert_trap(() => call($1, "32_good5", [65_508])); + +// address.wast:194 +assert_trap(() => call($1, "8u_good3", [-1])); + +// address.wast:195 +assert_trap(() => call($1, "8s_good3", [-1])); + +// address.wast:196 +assert_trap(() => call($1, "16u_good3", [-1])); + +// address.wast:197 +assert_trap(() => call($1, "16s_good3", [-1])); + +// address.wast:198 +assert_trap(() => call($1, "32_good3", [-1])); + +// address.wast:199 +assert_trap(() => call($1, "32_good3", [-1])); + +// address.wast:201 +assert_trap(() => call($1, "8u_bad", [0])); + +// address.wast:202 +assert_trap(() => call($1, "8s_bad", [0])); + +// address.wast:203 +assert_trap(() => call($1, "16u_bad", [0])); + +// address.wast:204 +assert_trap(() => call($1, "16s_bad", [0])); + +// address.wast:205 +assert_trap(() => call($1, "32_bad", [0])); + +// address.wast:207 +assert_trap(() => call($1, "8u_bad", [1])); + +// address.wast:208 +assert_trap(() => call($1, "8s_bad", [1])); + +// address.wast:209 +assert_trap(() => call($1, "16u_bad", [1])); + +// address.wast:210 +assert_trap(() => call($1, "16s_bad", [1])); + +// address.wast:211 +assert_trap(() => call($1, "32_bad", [1])); + +// address.wast:213 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// address.wast:223 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7e\x60\x01\x7f\x00\x03\xab\x80\x80\x80\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xd9\x83\x80\x80\x00\x2a\x08\x38\x75\x5f\x67\x6f\x6f\x64\x31\x00\x00\x08\x38\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x02\x08\x38\x75\x5f\x67\x6f\x6f\x64\x34\x00\x03\x08\x38\x75\x5f\x67\x6f\x6f\x64\x35\x00\x04\x08\x38\x73\x5f\x67\x6f\x6f\x64\x31\x00\x05\x08\x38\x73\x5f\x67\x6f\x6f\x64\x32\x00\x06\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x07\x08\x38\x73\x5f\x67\x6f\x6f\x64\x34\x00\x08\x08\x38\x73\x5f\x67\x6f\x6f\x64\x35\x00\x09\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x31\x00\x0a\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x32\x00\x0b\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x0c\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x34\x00\x0d\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x35\x00\x0e\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x31\x00\x0f\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x32\x00\x10\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x11\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x34\x00\x12\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x35\x00\x13\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x31\x00\x14\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x32\x00\x15\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x33\x00\x16\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x34\x00\x17\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x35\x00\x18\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x31\x00\x19\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x32\x00\x1a\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x33\x00\x1b\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x34\x00\x1c\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x35\x00\x1d\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x1e\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x1f\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x20\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x21\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x22\x06\x38\x75\x5f\x62\x61\x64\x00\x23\x06\x38\x73\x5f\x62\x61\x64\x00\x24\x07\x31\x36\x75\x5f\x62\x61\x64\x00\x25\x07\x31\x36\x73\x5f\x62\x61\x64\x00\x26\x07\x33\x32\x75\x5f\x62\x61\x64\x00\x27\x07\x33\x32\x73\x5f\x62\x61\x64\x00\x28\x06\x36\x34\x5f\x62\x61\x64\x00\x29\x0a\x9c\x84\x80\x80\x00\x2a\x87\x80\x80\x80\x00\x00\x20\x00\x31\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x31\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x31\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x31\x00\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x31\x00\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x30\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x30\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x30\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x30\x00\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x30\x00\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x33\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x33\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x33\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x33\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x33\x01\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x32\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x32\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x32\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x32\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x32\x01\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x35\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x35\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x35\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x35\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x35\x02\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x34\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x34\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x34\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x34\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x34\x02\x19\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x29\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x29\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x29\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x29\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x29\x03\x19\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x31\x00\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x30\x00\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x33\x01\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x32\x01\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x35\x02\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x34\x02\xff\xff\xff\xff\x0f\x1a\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x29\x03\xff\xff\xff\xff\x0f\x1a\x0b\x0b\xa0\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x1a\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a"); + +// address.wast:362 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good1", [0]), int64("97")) + +// address.wast:363 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good2", [0]), int64("97")) + +// address.wast:364 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good3", [0]), int64("98")) + +// address.wast:365 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good4", [0]), int64("99")) + +// address.wast:366 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good5", [0]), int64("122")) + +// address.wast:368 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good1", [0]), int64("97")) + +// address.wast:369 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good2", [0]), int64("97")) + +// address.wast:370 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good3", [0]), int64("98")) + +// address.wast:371 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good4", [0]), int64("99")) + +// address.wast:372 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good5", [0]), int64("122")) + +// address.wast:374 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good1", [0]), int64("25_185")) + +// address.wast:375 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good2", [0]), int64("25_185")) + +// address.wast:376 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\xc6\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good3", [0]), int64("25_442")) + +// address.wast:377 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\xc8\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good4", [0]), int64("25_699")) + +// address.wast:378 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good5", [0]), int64("122")) + +// address.wast:380 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good1", [0]), int64("25_185")) + +// address.wast:381 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good2", [0]), int64("25_185")) + +// address.wast:382 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\xc6\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good3", [0]), int64("25_442")) + +// address.wast:383 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\xc8\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good4", [0]), int64("25_699")) + +// address.wast:384 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good5", [0]), int64("122")) + +// address.wast:386 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good1", [0]), int64("1_684_234_849")) + +// address.wast:387 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good2", [0]), int64("1_684_234_849")) + +// address.wast:388 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\xc6\x91\xab\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good3", [0]), int64("1_701_077_858")) + +// address.wast:389 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\xc8\x95\xb3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good4", [0]), int64("1_717_920_867")) + +// address.wast:390 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good5", [0]), int64("122")) + +// address.wast:392 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good1", [0]), int64("1_684_234_849")) + +// address.wast:393 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good2", [0]), int64("1_684_234_849")) + +// address.wast:394 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\xc6\x91\xab\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good3", [0]), int64("1_701_077_858")) + +// address.wast:395 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\xc8\x95\xb3\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good4", [0]), int64("1_717_920_867")) + +// address.wast:396 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good5", [0]), int64("122")) + +// address.wast:398 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\xd6\xcc\xd9\xb3\xe8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good1", [0]), int64("7_523_094_288_207_667_809")) + +// address.wast:399 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe1\xc4\x8d\xa3\xd6\xcc\xd9\xb3\xe8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good2", [0]), int64("7_523_094_288_207_667_809")) + +// address.wast:400 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe2\xc6\x91\xab\xe6\xec\x99\xb4\xe9\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good3", [0]), int64("7_595_434_461_045_744_482")) + +// address.wast:401 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xe3\xc8\x95\xb3\xf6\x8c\xda\xb4\xea\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good4", [0]), int64("7_667_774_633_883_821_155")) + +// address.wast:402 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\xfa\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good5", [0]), int64("122")) + +// address.wast:404 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good1", [65_503]), int64("0")) + +// address.wast:405 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good2", [65_503]), int64("0")) + +// address.wast:406 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good3", [65_503]), int64("0")) + +// address.wast:407 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good4", [65_503]), int64("0")) + +// address.wast:408 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good5", [65_503]), int64("0")) + +// address.wast:410 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good1", [65_503]), int64("0")) + +// address.wast:411 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good2", [65_503]), int64("0")) + +// address.wast:412 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good3", [65_503]), int64("0")) + +// address.wast:413 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good4", [65_503]), int64("0")) + +// address.wast:414 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good5", [65_503]), int64("0")) + +// address.wast:416 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good1", [65_503]), int64("0")) + +// address.wast:417 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good2", [65_503]), int64("0")) + +// address.wast:418 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good3", [65_503]), int64("0")) + +// address.wast:419 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good4", [65_503]), int64("0")) + +// address.wast:420 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good5", [65_503]), int64("0")) + +// address.wast:422 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good1", [65_503]), int64("0")) + +// address.wast:423 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good2", [65_503]), int64("0")) + +// address.wast:424 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good3", [65_503]), int64("0")) + +// address.wast:425 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good4", [65_503]), int64("0")) + +// address.wast:426 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good5", [65_503]), int64("0")) + +// address.wast:428 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good1", [65_503]), int64("0")) + +// address.wast:429 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good2", [65_503]), int64("0")) + +// address.wast:430 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good3", [65_503]), int64("0")) + +// address.wast:431 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good4", [65_503]), int64("0")) + +// address.wast:432 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good5", [65_503]), int64("0")) + +// address.wast:434 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good1", [65_503]), int64("0")) + +// address.wast:435 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good2", [65_503]), int64("0")) + +// address.wast:436 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good3", [65_503]), int64("0")) + +// address.wast:437 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good4", [65_503]), int64("0")) + +// address.wast:438 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good5", [65_503]), int64("0")) + +// address.wast:440 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good1", [65_503]), int64("0")) + +// address.wast:441 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good2", [65_503]), int64("0")) + +// address.wast:442 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good3", [65_503]), int64("0")) + +// address.wast:443 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good4", [65_503]), int64("0")) + +// address.wast:444 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xdf\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good5", [65_503]), int64("0")) + +// address.wast:446 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good1", [65_504]), int64("0")) + +// address.wast:447 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good2", [65_504]), int64("0")) + +// address.wast:448 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good3", [65_504]), int64("0")) + +// address.wast:449 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good4", [65_504]), int64("0")) + +// address.wast:450 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8u_good5", [65_504]), int64("0")) + +// address.wast:452 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good1", [65_504]), int64("0")) + +// address.wast:453 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good2", [65_504]), int64("0")) + +// address.wast:454 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good3", [65_504]), int64("0")) + +// address.wast:455 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good4", [65_504]), int64("0")) + +// address.wast:456 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "8s_good5", [65_504]), int64("0")) + +// address.wast:458 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good1", [65_504]), int64("0")) + +// address.wast:459 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good2", [65_504]), int64("0")) + +// address.wast:460 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good3", [65_504]), int64("0")) + +// address.wast:461 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good4", [65_504]), int64("0")) + +// address.wast:462 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16u_good5", [65_504]), int64("0")) + +// address.wast:464 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good1", [65_504]), int64("0")) + +// address.wast:465 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good2", [65_504]), int64("0")) + +// address.wast:466 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good3", [65_504]), int64("0")) + +// address.wast:467 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good4", [65_504]), int64("0")) + +// address.wast:468 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "16s_good5", [65_504]), int64("0")) + +// address.wast:470 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good1", [65_504]), int64("0")) + +// address.wast:471 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good2", [65_504]), int64("0")) + +// address.wast:472 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good3", [65_504]), int64("0")) + +// address.wast:473 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good4", [65_504]), int64("0")) + +// address.wast:474 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32u_good5", [65_504]), int64("0")) + +// address.wast:476 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good1", [65_504]), int64("0")) + +// address.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good2", [65_504]), int64("0")) + +// address.wast:478 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good3", [65_504]), int64("0")) + +// address.wast:479 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good4", [65_504]), int64("0")) + +// address.wast:480 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "32s_good5", [65_504]), int64("0")) + +// address.wast:482 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good1", [65_504]), int64("0")) + +// address.wast:483 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good2", [65_504]), int64("0")) + +// address.wast:484 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good3", [65_504]), int64("0")) + +// address.wast:485 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "64_good4", [65_504]), int64("0")) + +// address.wast:486 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\xe0\xff\x03\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "64_good5", [65_504])) + +// address.wast:488 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "8u_good3", [-1])) + +// address.wast:489 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x38\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "8s_good3", [-1])) + +// address.wast:490 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "16u_good3", [-1])) + +// address.wast:491 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x31\x36\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "16s_good3", [-1])) + +// address.wast:492 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x75\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "32u_good3", [-1])) + +// address.wast:493 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x32\x09\x33\x32\x73\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "32s_good3", [-1])) + +// address.wast:494 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_trap(() => call($2, "64_good3", [-1])) + +// address.wast:496 +assert_trap(() => call($2, "8u_bad", [0])); + +// address.wast:497 +assert_trap(() => call($2, "8s_bad", [0])); + +// address.wast:498 +assert_trap(() => call($2, "16u_bad", [0])); + +// address.wast:499 +assert_trap(() => call($2, "16s_bad", [0])); + +// address.wast:500 +assert_trap(() => call($2, "32u_bad", [0])); + +// address.wast:501 +assert_trap(() => call($2, "32s_bad", [0])); + +// address.wast:502 +assert_trap(() => call($2, "64_bad", [0])); + +// address.wast:504 +assert_trap(() => call($2, "8u_bad", [1])); + +// address.wast:505 +assert_trap(() => call($2, "8s_bad", [1])); + +// address.wast:506 +assert_trap(() => call($2, "16u_bad", [1])); + +// address.wast:507 +assert_trap(() => call($2, "16s_bad", [1])); + +// address.wast:508 +assert_trap(() => call($2, "32u_bad", [0])); + +// address.wast:509 +assert_trap(() => call($2, "32s_bad", [0])); + +// address.wast:510 +assert_trap(() => call($2, "64_bad", [1])); + +// address.wast:514 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7d\x60\x01\x7f\x00\x03\x87\x80\x80\x80\x00\x06\x00\x00\x00\x00\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xc1\x80\x80\x80\x00\x06\x08\x33\x32\x5f\x67\x6f\x6f\x64\x31\x00\x00\x08\x33\x32\x5f\x67\x6f\x6f\x64\x32\x00\x01\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x02\x08\x33\x32\x5f\x67\x6f\x6f\x64\x34\x00\x03\x08\x33\x32\x5f\x67\x6f\x6f\x64\x35\x00\x04\x06\x33\x32\x5f\x62\x61\x64\x00\x05\x0a\xce\x80\x80\x80\x00\x06\x87\x80\x80\x80\x00\x00\x20\x00\x2a\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2a\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2a\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2a\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2a\x02\x08\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2a\x02\xff\xff\xff\xff\x0f\x1a\x0b\x0b\x92\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x0c\x00\x00\x00\x00\x00\x00\xa0\x7f\x01\x00\xd0\x7f"); + +// address.wast:538 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good1", [0]), 0.) + +// address.wast:539 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good2", [0]), 0.) + +// address.wast:540 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good3", [0]), 0.) + +// address.wast:541 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good4", [0]), 0.) + +// address.wast:542 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x01\x00\xd0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good5", [0]), NaN) + +// address.wast:544 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf4\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good1", [65_524]), 0.) + +// address.wast:545 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf4\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good2", [65_524]), 0.) + +// address.wast:546 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf4\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good3", [65_524]), 0.) + +// address.wast:547 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf4\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good4", [65_524]), 0.) + +// address.wast:548 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf4\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good5", [65_524]), 0.) + +// address.wast:550 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf5\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good1", [65_525]), 0.) + +// address.wast:551 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf5\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good2", [65_525]), 0.) + +// address.wast:552 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf5\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good3", [65_525]), 0.) + +// address.wast:553 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x41\xf5\xff\x03\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "32_good4", [65_525]), 0.) + +// address.wast:554 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\xf5\xff\x03\x10\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_trap(() => call($3, "32_good5", [65_525])) + +// address.wast:556 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_trap(() => call($3, "32_good3", [-1])) + +// address.wast:557 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x33\x32\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_trap(() => call($3, "32_good3", [-1])) + +// address.wast:559 +assert_trap(() => call($3, "32_bad", [0])); + +// address.wast:560 +assert_trap(() => call($3, "32_bad", [1])); + +// address.wast:564 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7c\x60\x01\x7f\x00\x03\x87\x80\x80\x80\x00\x06\x00\x00\x00\x00\x00\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xc1\x80\x80\x80\x00\x06\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x00\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x02\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x03\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x04\x06\x36\x34\x5f\x62\x61\x64\x00\x05\x0a\xce\x80\x80\x80\x00\x06\x87\x80\x80\x80\x00\x00\x20\x00\x2b\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2b\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2b\x00\x01\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2b\x01\x02\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x2b\x03\x12\x0b\x8c\x80\x80\x80\x00\x00\x20\x00\x2b\x03\xff\xff\xff\xff\x0f\x1a\x0b\x0b\xa0\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\x7f\x01\x00\x00\x00\x00\x00\xfc\x7f"); + +// address.wast:588 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good1", [0]), 0.) + +// address.wast:589 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good2", [0]), 0.) + +// address.wast:590 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good3", [0]), 0.) + +// address.wast:591 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good4", [0]), 0.) + +// address.wast:592 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xfc\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good5", [0]), NaN) + +// address.wast:594 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe6\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good1", [65_510]), 0.) + +// address.wast:595 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe6\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good2", [65_510]), 0.) + +// address.wast:596 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe6\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good3", [65_510]), 0.) + +// address.wast:597 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe6\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good4", [65_510]), 0.) + +// address.wast:598 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe6\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good5", [65_510]), 0.) + +// address.wast:600 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe7\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good1", [65_511]), 0.) + +// address.wast:601 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe7\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good2", [65_511]), 0.) + +// address.wast:602 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe7\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good3", [65_511]), 0.) + +// address.wast:603 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\xe7\xff\x03\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "64_good4", [65_511]), 0.) + +// address.wast:604 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\xe7\xff\x03\x10\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_trap(() => call($4, "64_good5", [65_511])) + +// address.wast:606 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_trap(() => call($4, "64_good3", [-1])) + +// address.wast:607 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x36\x34\x5f\x67\x6f\x6f\x64\x33\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_trap(() => call($4, "64_good3", [-1])) + +// address.wast:609 +assert_trap(() => call($4, "64_bad", [0])); + +// address.wast:610 +assert_trap(() => call($4, "64_bad", [1])); diff --git a/js/src/jit-test/tests/wasm/spec/binary-leb128.wast.js b/js/src/jit-test/tests/wasm/spec/spec/binary-leb128.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/binary-leb128.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/binary-leb128.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/binary.wast.js b/js/src/jit-test/tests/wasm/spec/spec/binary.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/binary.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/binary.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/block.wast.js b/js/src/jit-test/tests/wasm/spec/spec/block.wast.js new file mode 100644 index 0000000000..2ea8ff4e21 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/block.wast.js @@ -0,0 +1,669 @@ + +// block.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xbd\x80\x80\x80\x00\x0b\x60\x02\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x60\x03\x7f\x7c\x7f\x03\x7f\x7c\x7f\x60\x00\x03\x7f\x7e\x7f\x60\x01\x7f\x01\x7f\x60\x00\x02\x7f\x7f\x60\x00\x02\x7d\x7d\x60\x00\x03\x7f\x7f\x7e\x60\x02\x7f\x7f\x02\x7f\x7f\x03\xb8\x80\x80\x80\x00\x37\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x01\x02\x02\x02\x02\x02\x02\x00\x02\x02\x02\x01\x01\x02\x06\x02\x02\x01\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x09\x02\x02\x02\x02\x02\x02\x02\x02\x02\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xd0\x86\x80\x80\x00\x34\x05\x65\x6d\x70\x74\x79\x00\x01\x08\x73\x69\x6e\x67\x75\x6c\x61\x72\x00\x02\x05\x6d\x75\x6c\x74\x69\x00\x03\x06\x6e\x65\x73\x74\x65\x64\x00\x04\x04\x64\x65\x65\x70\x00\x05\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x06\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x07\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x08\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x09\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x0a\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x0b\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x0c\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x0d\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x0e\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x0f\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x10\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x11\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x12\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x14\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x15\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x16\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x17\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x18\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x19\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x1b\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x1c\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1d\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x1e\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x1f\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x20\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x21\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x22\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x23\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x24\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x25\x12\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x26\x12\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x27\x13\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x28\x11\x61\x73\x2d\x6d\x69\x78\x65\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x29\x0a\x62\x72\x65\x61\x6b\x2d\x62\x61\x72\x65\x00\x2a\x0b\x62\x72\x65\x61\x6b\x2d\x76\x61\x6c\x75\x65\x00\x2b\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x2c\x0e\x62\x72\x65\x61\x6b\x2d\x72\x65\x70\x65\x61\x74\x65\x64\x00\x2d\x0b\x62\x72\x65\x61\x6b\x2d\x69\x6e\x6e\x65\x72\x00\x2e\x05\x70\x61\x72\x61\x6d\x00\x2f\x06\x70\x61\x72\x61\x6d\x73\x00\x30\x09\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x00\x31\x0b\x70\x61\x72\x61\x6d\x2d\x62\x72\x65\x61\x6b\x00\x32\x0c\x70\x61\x72\x61\x6d\x73\x2d\x62\x72\x65\x61\x6b\x00\x33\x0f\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x2d\x62\x72\x65\x61\x6b\x00\x34\x07\x65\x66\x66\x65\x63\x74\x73\x00\x35\x08\x74\x79\x70\x65\x2d\x75\x73\x65\x00\x36\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x13\x0a\xae\x8a\x80\x80\x00\x37\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x02\x40\x0b\x02\x40\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x40\x01\x0b\x02\x7f\x41\x07\x0b\x0b\xbe\x80\x80\x80\x00\x00\x02\x40\x10\x00\x10\x00\x10\x00\x10\x00\x0b\x02\x7f\x10\x00\x10\x00\x10\x00\x41\x07\x10\x00\x0b\x1a\x02\x05\x10\x00\x10\x00\x10\x00\x41\x08\x10\x00\x10\x00\x10\x00\x10\x00\x42\x07\x10\x00\x10\x00\x10\x00\x10\x00\x41\x09\x10\x00\x0b\x1a\x1a\x0b\x95\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x10\x00\x02\x40\x0b\x01\x0b\x02\x7f\x10\x00\x41\x09\x0b\x0b\x0b\xf9\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x02\x7f\x10\x00\x41\x96\x01\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x41\x02\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x02\x7f\x41\x01\x0b\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x03\x02\x7f\x41\x01\x0b\x1b\x0b\x8e\x80\x80\x80\x00\x00\x03\x7f\x02\x7f\x41\x01\x0b\x10\x00\x10\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x02\x7f\x41\x01\x0b\x10\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x10\x00\x02\x7f\x41\x01\x0b\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x04\x40\x10\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x02\x7f\x41\x01\x0b\x05\x41\x02\x0b\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x02\x05\x02\x7f\x41\x01\x0b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x01\x0b\x41\x02\x0d\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x02\x7f\x41\x01\x0b\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x01\x0b\x41\x02\x0e\x01\x00\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x02\x7f\x41\x01\x0b\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x01\x0b\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x02\x7f\x41\x01\x0b\x41\x00\x11\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x02\x7f\x41\x00\x0b\x11\x00\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x41\x01\x36\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x02\x7f\x41\x01\x0b\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x89\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x10\x1a\x0b\x88\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x0f\x0b\x88\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x1a\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x01\x0b\x0c\x00\x0b\x0b\x8d\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x01\x0b\x21\x00\x20\x00\x0b\x8b\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x01\x0b\x22\x00\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x24\x00\x23\x00\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0b\x28\x02\x00\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x0d\x0b\x68\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x03\x0b\x02\x7f\x10\x00\x41\x04\x0b\x6c\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x0d\x0b\x45\x0b\x97\x80\x80\x80\x00\x00\x02\x7d\x10\x00\x43\x00\x00\x40\x40\x0b\x02\x7d\x10\x00\x43\x00\x00\x40\x40\x0b\x5e\x0b\x8e\x80\x80\x80\x00\x00\x02\x07\x10\x00\x41\x03\x10\x00\x41\x04\x0b\x6c\x0b\x94\x80\x80\x80\x00\x00\x02\x08\x10\x00\x43\x00\x00\x40\x40\x10\x00\x43\x00\x00\x40\x40\x0b\x5e\x0b\x91\x80\x80\x80\x00\x00\x02\x07\x10\x00\x41\x03\x10\x00\x41\x04\x0b\x41\x05\x6a\x6c\x0b\xa6\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x00\x0b\x02\x40\x41\x01\x0d\x00\x00\x0b\x02\x40\x41\x00\x0e\x00\x00\x00\x0b\x02\x40\x41\x01\x0e\x02\x00\x00\x00\x00\x0b\x41\x13\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x12\x0c\x00\x41\x13\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x09\x41\x12\x41\x6e\x42\x12\x0c\x00\x41\x13\x41\x6d\x42\x13\x0b\x0b\xb1\x80\x80\x80\x00\x00\x02\x7f\x41\x12\x0c\x00\x41\x13\x0c\x00\x41\x14\x41\x00\x0d\x00\x1a\x41\x14\x41\x01\x0d\x00\x1a\x41\x15\x0c\x00\x41\x16\x41\x04\x0e\x00\x00\x41\x17\x41\x01\x0e\x02\x00\x00\x00\x41\x15\x0b\x0b\xc5\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x21\x00\x20\x00\x02\x7f\x02\x7f\x41\x01\x0c\x01\x0b\x0b\x6a\x21\x00\x20\x00\x02\x7f\x02\x40\x0c\x00\x0b\x41\x02\x0b\x6a\x21\x00\x20\x00\x02\x7f\x41\x04\x0c\x00\x68\x0b\x6a\x21\x00\x20\x00\x02\x7f\x02\x7f\x41\x08\x0c\x01\x0b\x68\x0b\x6a\x21\x00\x20\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x02\x06\x41\x02\x6a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x02\x00\x6a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x02\x0a\x0b\x6a\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x02\x06\x41\x02\x6a\x0c\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x02\x02\x00\x6a\x0c\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x02\x02\x0a\x0c\x00\x0b\x6a\x0b\xaf\x80\x80\x80\x00\x01\x01\x7f\x02\x40\x41\x01\x21\x00\x20\x00\x41\x03\x6c\x21\x00\x20\x00\x41\x05\x6b\x21\x00\x20\x00\x41\x07\x6c\x21\x00\x0c\x00\x20\x00\x41\xe4\x00\x6c\x21\x00\x0b\x20\x00\x41\x72\x46\x0b\xbd\x80\x80\x80\x00\x00\x02\x01\x0b\x02\x02\x41\x00\x0b\x02\x03\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x02\x04\x0b\x1a\x1a\x1a\x02\x02\x41\x00\x0b\x02\x03\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x02\x04\x0b\x1a\x1a\x1a\x0b"); + +// block.wast:353 +assert_return(() => call($1, "empty", [])); + +// block.wast:354 +assert_return(() => call($1, "singular", []), 7); + +// block.wast:355 +assert_return(() => call($1, "multi", []), 8); + +// block.wast:356 +assert_return(() => call($1, "nested", []), 9); + +// block.wast:357 +assert_return(() => call($1, "deep", []), 150); + +// block.wast:359 +assert_return(() => call($1, "as-select-first", []), 1); + +// block.wast:360 +assert_return(() => call($1, "as-select-mid", []), 2); + +// block.wast:361 +assert_return(() => call($1, "as-select-last", []), 2); + +// block.wast:363 +assert_return(() => call($1, "as-loop-first", []), 1); + +// block.wast:364 +assert_return(() => call($1, "as-loop-mid", []), 1); + +// block.wast:365 +assert_return(() => call($1, "as-loop-last", []), 1); + +// block.wast:367 +assert_return(() => call($1, "as-if-condition", [])); + +// block.wast:368 +assert_return(() => call($1, "as-if-then", []), 1); + +// block.wast:369 +assert_return(() => call($1, "as-if-else", []), 2); + +// block.wast:371 +assert_return(() => call($1, "as-br_if-first", []), 1); + +// block.wast:372 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// block.wast:374 +assert_return(() => call($1, "as-br_table-first", []), 1); + +// block.wast:375 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// block.wast:377 +assert_return(() => call($1, "as-call_indirect-first", []), 1); + +// block.wast:378 +assert_return(() => call($1, "as-call_indirect-mid", []), 2); + +// block.wast:379 +assert_return(() => call($1, "as-call_indirect-last", []), 1); + +// block.wast:381 +assert_return(() => call($1, "as-store-first", [])); + +// block.wast:382 +assert_return(() => call($1, "as-store-last", [])); + +// block.wast:384 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// block.wast:385 +assert_return(() => call($1, "as-call-value", []), 1); + +// block.wast:386 +assert_return(() => call($1, "as-return-value", []), 1); + +// block.wast:387 +assert_return(() => call($1, "as-drop-operand", [])); + +// block.wast:388 +assert_return(() => call($1, "as-br-value", []), 1); + +// block.wast:389 +assert_return(() => call($1, "as-local.set-value", []), 1); + +// block.wast:390 +assert_return(() => call($1, "as-local.tee-value", []), 1); + +// block.wast:391 +assert_return(() => call($1, "as-global.set-value", []), 1); + +// block.wast:392 +assert_return(() => call($1, "as-load-operand", []), 1); + +// block.wast:394 +assert_return(() => call($1, "as-unary-operand", []), 0); + +// block.wast:395 +assert_return(() => call($1, "as-binary-operand", []), 12); + +// block.wast:396 +assert_return(() => call($1, "as-test-operand", []), 0); + +// block.wast:397 +assert_return(() => call($1, "as-compare-operand", []), 0); + +// block.wast:398 +assert_return(() => call($1, "as-binary-operands", []), 12); + +// block.wast:399 +assert_return(() => call($1, "as-compare-operands", []), 0); + +// block.wast:400 +assert_return(() => call($1, "as-mixed-operands", []), 27); + +// block.wast:402 +assert_return(() => call($1, "break-bare", []), 19); + +// block.wast:403 +assert_return(() => call($1, "break-value", []), 18); + +// block.wast:404 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x03\x7f\x7f\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x12\x01\x51\x45\x0d\x00\x01\x41\x6e\x01\x46\x45\x0d\x00\x01\x41\x12\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-multi-value", []), 18, -18, int64("18")) + +// block.wast:407 +assert_return(() => call($1, "break-repeated", []), 18); + +// block.wast:408 +assert_return(() => call($1, "break-inner", []), 15); + +// block.wast:410 +assert_return(() => call($1, "param", []), 3); + +// block.wast:411 +assert_return(() => call($1, "params", []), 3); + +// block.wast:412 +assert_return(() => call($1, "params-id", []), 3); + +// block.wast:413 +assert_return(() => call($1, "param-break", []), 3); + +// block.wast:414 +assert_return(() => call($1, "params-break", []), 3); + +// block.wast:415 +assert_return(() => call($1, "params-id-break", []), 3); + +// block.wast:417 +assert_return(() => call($1, "effects", []), 1); + +// block.wast:419 +assert_return(() => call($1, "type-use", [])); + +// block.wast:421 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:428 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:435 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:442 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:449 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:456 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:463 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:467 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:474 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:481 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:488 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:496 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x00\x41\x00\x0b\x0b"); + +// block.wast:504 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x40\x0b\x0b"); + +// block.wast:508 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x40\x0b\x0b"); + +// block.wast:512 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x40\x0b\x0b"); + +// block.wast:516 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x40\x0b\x0b"); + +// block.wast:521 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0b\x0b"); + +// block.wast:527 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x40\x42\x01\x0b\x0b"); + +// block.wast:533 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:539 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:545 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x41\x01\x41\x02\x0b\x0b"); + +// block.wast:551 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x7f\x0b\x0b"); + +// block.wast:557 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x7e\x0b\x0b"); + +// block.wast:563 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x7d\x0b\x0b"); + +// block.wast:569 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x7c\x0b\x0b"); + +// block.wast:575 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x02\x00\x0b\x0b"); + +// block.wast:582 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x02\x7f\x0b\x1a\x0b\x0b"); + +// block.wast:591 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x03\x40\x02\x7f\x0b\x1a\x0b\x0b"); + +// block.wast:600 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x02\x7f\x0b\x1a\x0b\x0b"); + +// block.wast:610 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x7f\x01\x0b\x0b"); + +// block.wast:616 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x7e\x01\x0b\x0b"); + +// block.wast:622 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x7d\x01\x0b\x0b"); + +// block.wast:628 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x7c\x01\x0b\x0b"); + +// block.wast:634 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x00\x01\x0b\x0b"); + +// block.wast:640 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7f\x42\x00\x0b\x0b"); + +// block.wast:646 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7f\x43\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:652 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:658 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7e\x41\x00\x0b\x0b"); + +// block.wast:664 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7e\x43\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:670 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7e\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:676 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7d\x41\x00\x0b\x0b"); + +// block.wast:682 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7d\x42\x00\x0b\x0b"); + +// block.wast:688 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7d\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:694 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7c\x41\x00\x0b\x0b"); + +// block.wast:700 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7c\x42\x00\x0b\x0b"); + +// block.wast:706 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7c\x43\x00\x00\x00\x00\x0b\x0b"); + +// block.wast:712 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x00\x41\x00\x0b\x0b"); + +// block.wast:718 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x02\x00\x41\x02\x0b\x0b"); + +// block.wast:724 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x0b\x0b"); + +// block.wast:731 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7e\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:737 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7d\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:743 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7c\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:749 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:755 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7d\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:761 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7c\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:767 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:773 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7e\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:779 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7c\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:785 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:791 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7e\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:797 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7d\x00\x00\x00\x1b\x0b\x0b"); + +// block.wast:804 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x0b\x0b"); + +// block.wast:810 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7e\x0c\x00\x0b\x0b"); + +// block.wast:816 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7d\x0c\x00\x0b\x0b"); + +// block.wast:822 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x7c\x0c\x00\x0b\x0b"); + +// block.wast:828 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x00\x0c\x00\x0b\x0b"); + +// block.wast:835 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x41\x01\x0b\x0b"); + +// block.wast:841 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7e\x0c\x00\x42\x01\x0b\x0b"); + +// block.wast:847 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7d\x0c\x00\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:853 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7c\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:859 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x00\x0c\x00\x41\x01\x41\x02\x0b\x0b"); + +// block.wast:866 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7f\x01\x0c\x00\x41\x01\x0b\x0b"); + +// block.wast:872 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7e\x01\x0c\x00\x42\x01\x0b\x0b"); + +// block.wast:878 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7d\x01\x0c\x00\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:884 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7c\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:891 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x0c\x00\x41\x01\x0b\x0b"); + +// block.wast:897 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x43\x00\x00\x80\x3f\x0c\x00\x41\x01\x0b\x0b"); + +// block.wast:903 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x41\x01\x0b\x0b"); + +// block.wast:909 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x0c\x00\x42\x01\x0b\x0b"); + +// block.wast:915 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7e\x43\x00\x00\x80\x3f\x0c\x00\x42\x01\x0b\x0b"); + +// block.wast:921 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7e\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x42\x01\x0b\x0b"); + +// block.wast:927 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7d\x41\x01\x0c\x00\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:933 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7d\x42\x01\x0c\x00\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:939 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x7d\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x43\x00\x00\x80\x3f\x0b\x0b"); + +// block.wast:945 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:951 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7c\x42\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:957 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x7c\x43\x00\x00\x80\x3f\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// block.wast:963 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x00\x41\x00\x0c\x00\x41\x01\x41\x02\x0b\x0b"); + +// block.wast:969 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x01\x02\x00\x41\x00\x0c\x00\x41\x02\x0b\x0b"); + +// block.wast:976 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x01\x0c\x00\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:982 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7e\x01\x0c\x00\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:988 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7d\x01\x0c\x00\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:994 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x7c\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1000 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x00\x01\x0c\x00\x41\x01\x41\x02\x0c\x00\x0b\x0b"); + +// block.wast:1007 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x0c\x00\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1013 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7f\x43\x00\x00\x80\x3f\x0c\x00\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1019 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1025 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x0c\x00\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1031 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7e\x43\x00\x00\x80\x3f\x0c\x00\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1037 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x7e\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1043 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7d\x41\x01\x0c\x00\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1049 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7d\x42\x01\x0c\x00\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1055 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7d\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1061 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x7c\x41\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1067 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x7c\x42\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1073 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7c\x43\x00\x00\x80\x3f\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1079 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x00\x41\x00\x0c\x00\x41\x01\x41\x02\x0c\x00\x0b\x0b"); + +// block.wast:1086 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x41\x01\x0c\x01\x0b\x0c\x00\x0b\x0b"); + +// block.wast:1092 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7e\x02\x7e\x42\x01\x0c\x01\x0b\x0c\x00\x0b\x0b"); + +// block.wast:1098 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7d\x02\x7d\x43\x00\x00\x80\x3f\x0c\x01\x0b\x0c\x00\x0b\x0b"); + +// block.wast:1104 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x7c\x02\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x01\x0b\x0c\x00\x0b\x0b"); + +// block.wast:1110 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x01\x02\x01\x41\x01\x41\x02\x0c\x01\x0b\x0c\x00\x0b\x0b"); + +// block.wast:1117 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x0c\x01\x0b\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1123 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7e\x02\x40\x0c\x01\x0b\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1129 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7d\x02\x40\x0c\x01\x0b\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1135 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x7c\x02\x40\x0c\x01\x0b\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1141 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x00\x02\x40\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b\x0b"); + +// block.wast:1148 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x01\x0c\x01\x0b\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1154 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7e\x02\x7e\x01\x0c\x01\x0b\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1160 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7d\x02\x7d\x01\x0c\x01\x0b\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1166 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x7c\x02\x7c\x01\x0c\x01\x0b\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1172 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x00\x02\x00\x01\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b\x0b"); + +// block.wast:1179 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x42\x01\x0c\x01\x0b\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1187 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x43\x00\x00\x80\x3f\x0c\x01\x0b\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1195 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7f\x02\x7f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x01\x0b\x41\x01\x0c\x00\x0b\x0b"); + +// block.wast:1203 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7e\x02\x7e\x41\x01\x0c\x01\x0b\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1211 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x7e\x02\x7e\x43\x00\x00\x80\x3f\x0c\x01\x0b\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1219 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7e\x02\x7e\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x01\x0b\x42\x01\x0c\x00\x0b\x0b"); + +// block.wast:1227 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x7d\x02\x7d\x41\x01\x0c\x01\x0b\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1235 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x7d\x02\x7d\x42\x01\x0c\x01\x0b\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1243 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x7d\x02\x7d\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x01\x0b\x43\x00\x00\x80\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1251 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7c\x02\x7c\x41\x01\x0c\x01\x0b\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1259 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x7c\x02\x7c\x42\x01\x0c\x01\x0b\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1267 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x7c\x02\x7c\x43\x00\x00\x80\x3f\x0c\x01\x0b\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// block.wast:1275 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x00\x02\x00\x41\x00\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b\x0b"); + +// block.wast:1284 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0b\x68\x0b"); + +// block.wast:1290 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0b\x7a\x0b"); + +// block.wast:1296 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0b\x8e\x0b"); + +// block.wast:1302 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0b\x9c\x0b"); + +// block.wast:1308 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0b\x6a\x0b"); + +// block.wast:1315 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x00\x0b\x68\x0b"); + +// block.wast:1321 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x00\x0b\x7a\x0b"); + +// block.wast:1327 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x00\x0b\x8e\x0b"); + +// block.wast:1333 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x00\x0b\x9c\x0b"); + +// block.wast:1339 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x00\x0b\x6a\x0b"); + +// block.wast:1346 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x09\x0c\x00\x0b\x7a\x0b"); + +// block.wast:1352 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x10\x41\x0c\x00\x0b\x8e\x0b"); + +// block.wast:1358 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x22\x40\x0c\x00\x0b\x9c\x0b"); + +// block.wast:1364 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x09\x0c\x00\x0b\x68\x0b"); + +// block.wast:1370 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x10\x41\x0c\x00\x0b\x8e\x0b"); + +// block.wast:1376 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x22\x40\x0c\x00\x0b\x9c\x0b"); + +// block.wast:1382 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x09\x0c\x00\x0b\x68\x0b"); + +// block.wast:1388 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x09\x0c\x00\x0b\x7a\x0b"); + +// block.wast:1394 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x22\x40\x0c\x00\x0b\x9c\x0b"); + +// block.wast:1400 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x09\x0c\x00\x0b\x68\x0b"); + +// block.wast:1406 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x09\x0c\x00\x0b\x7a\x0b"); + +// block.wast:1412 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x10\x41\x0c\x00\x0b\x8e\x0b"); + +// block.wast:1418 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x42\x09\x41\x0a\x0c\x00\x0b\x6a\x0b"); + +// block.wast:1425 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x02\x01\x1a\x0b\x0b"); + +// block.wast:1431 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x01\x1a\x1a\x0b\x0b"); + +// block.wast:1437 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x02\x01\x1a\x0b\x0b"); + +// block.wast:1443 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x02\x01\x1a\x1a\x0b\x0b"); + +// block.wast:1449 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x02\x01\x1a\x0b\x0b\x0b"); + +// block.wast:1455 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x02\x01\x1a\x1a\x0b\x0b\x0b"); + +// block.wast:1461 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x02\x01\x1a\x0b\x0b\x0b"); + +// block.wast:1467 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x02\x01\x1a\x1a\x0b\x0b\x0b"); + +// block.wast:1474 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:1478 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:1484 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// block.wast:1488 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/br.wast.js b/js/src/jit-test/tests/wasm/spec/spec/br.wast.js new file mode 100644 index 0000000000..1b400840ec --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/br.wast.js @@ -0,0 +1,291 @@ + +// br.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xab\x80\x80\x80\x00\x09\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x00\x02\x7c\x7c\x60\x00\x02\x7f\x7e\x60\x02\x7f\x7f\x01\x7f\x03\xcb\x80\x80\x80\x00\x4a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x03\x04\x05\x06\x01\x01\x01\x02\x02\x02\x02\x02\x01\x02\x02\x01\x02\x02\x03\x07\x02\x08\x08\x08\x08\x02\x02\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x04\x03\x02\x02\x02\x02\x02\x02\x04\x02\x03\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\x92\x8a\x80\x80\x00\x48\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x01\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x02\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x03\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x04\x0c\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x69\x33\x32\x00\x05\x0c\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x69\x36\x34\x00\x06\x0c\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x66\x33\x32\x00\x07\x0c\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x66\x36\x34\x00\x08\x0e\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x09\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x0a\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x0b\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x0c\x12\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x0d\x0e\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x66\x69\x72\x73\x74\x00\x0e\x0c\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6d\x69\x64\x00\x0f\x0d\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6c\x61\x73\x74\x00\x10\x0e\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x61\x6c\x75\x65\x00\x11\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x12\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x13\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x14\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x15\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x63\x6f\x6e\x64\x00\x16\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x17\x13\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x18\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x69\x6e\x64\x65\x78\x00\x19\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x1a\x17\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x1b\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x1c\x10\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x73\x00\x1d\x0a\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x00\x1e\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x1f\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x20\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x21\x10\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x73\x65\x63\x6f\x6e\x64\x00\x22\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x63\x6f\x6e\x64\x00\x23\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x61\x6c\x6c\x00\x24\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x66\x69\x72\x73\x74\x00\x26\x0b\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6d\x69\x64\x00\x27\x0c\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6c\x61\x73\x74\x00\x28\x0b\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x61\x6c\x6c\x00\x29\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x75\x6e\x63\x00\x2a\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x2b\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x2c\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x2d\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x61\x6c\x6c\x00\x2e\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x2f\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x30\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x31\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x32\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x33\x10\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x34\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x76\x61\x6c\x75\x65\x00\x35\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x62\x6f\x74\x68\x00\x36\x11\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x37\x0f\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x76\x61\x6c\x75\x65\x00\x38\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x62\x6f\x74\x68\x00\x39\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x3a\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x3b\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x3c\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x62\x6f\x74\x68\x00\x3d\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x3e\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x3f\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x40\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x62\x6f\x74\x68\x00\x41\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x42\x13\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x73\x69\x7a\x65\x00\x43\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x61\x6c\x75\x65\x00\x44\x0f\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x45\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x46\x17\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x47\x15\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x48\x1b\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x49\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x25\x0a\x8d\x8b\x80\x80\x00\x4a\x82\x80\x80\x80\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x68\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x7a\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x8c\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x9a\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x6a\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x7c\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x92\x1a\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\xa0\x1a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0c\x00\x68\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7e\x42\x02\x0c\x00\x7a\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x40\x40\x0c\x00\x8c\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7c\x44\x00\x00\x00\x00\x00\x00\x10\x40\x0c\x00\x9a\x0b\x0b\xa3\x80\x80\x80\x00\x00\x02\x06\x44\x00\x00\x00\x00\x00\x00\x10\x40\x44\x00\x00\x00\x00\x00\x00\x14\x40\x0c\x00\xa0\x44\x00\x00\x00\x00\x00\x00\x18\x40\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x10\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x40\x10\x00\x0c\x00\x10\x00\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x40\x01\x10\x00\x0c\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x01\x10\x00\x41\x02\x0c\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x03\x0c\x01\x41\x02\x0b\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x10\x00\x41\x04\x0c\x01\x41\x02\x0b\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x01\x10\x00\x41\x05\x0c\x01\x0b\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x09\x0c\x00\x0c\x00\x0b\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x08\x0c\x00\x41\x01\x0d\x00\x1a\x41\x07\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x09\x0c\x00\x0d\x00\x1a\x41\x07\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x0e\x02\x00\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x0c\x00\x41\x01\x0e\x02\x00\x00\x00\x41\x07\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x06\x41\x0b\x0c\x00\x0e\x01\x00\x00\x41\x07\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7e\x42\x07\x0c\x00\x0f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x02\x02\x7e\x41\x01\x42\x07\x0c\x00\x0f\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x0c\x00\x04\x7f\x41\x00\x05\x41\x01\x0b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x41\x03\x0c\x01\x05\x20\x01\x0b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x20\x01\x05\x41\x04\x0c\x01\x0b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x05\x0c\x00\x20\x00\x20\x01\x1b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x41\x06\x0c\x00\x20\x01\x1b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x07\x0c\x00\x1b\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x08\x0c\x00\x1b\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x7f\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0c\x0c\x00\x41\x02\x41\x03\x10\x25\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x0d\x0c\x00\x41\x03\x10\x25\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x0e\x0c\x00\x10\x25\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x0f\x0c\x00\x10\x25\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x14\x0c\x00\x41\x01\x41\x02\x41\x03\x11\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x15\x0c\x00\x41\x02\x41\x03\x11\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x16\x0c\x00\x41\x03\x11\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x41\x02\x41\x17\x0c\x00\x11\x00\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x18\x0c\x00\x11\x00\x00\x0b\x0b\x8f\x80\x80\x80\x00\x01\x01\x7d\x02\x7f\x41\x11\x0c\x00\x21\x00\x41\x7f\x0b\x0b\x8d\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x01\x0c\x00\x22\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0c\x00\x24\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7d\x43\x9a\x99\xd9\x3f\x0c\x00\x2a\x02\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7e\x42\x1e\x0c\x00\x30\x00\x00\x0b\x0b\x97\x80\x80\x80\x00\x00\x02\x7f\x41\x1e\x0c\x00\x44\x00\x00\x00\x00\x00\x00\x1c\x40\x39\x03\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x1f\x0c\x00\x37\x03\x00\x41\x7f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x20\x0c\x00\x37\x03\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x20\x0c\x00\x41\x07\x3a\x00\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x21\x0c\x00\x3d\x01\x00\x41\x7f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x22\x0c\x00\x3d\x01\x00\x41\x7f\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7d\x43\x9a\x99\x59\x40\x0c\x00\x8c\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x03\x0c\x00\x41\x0a\x6a\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7e\x42\x0a\x42\x2d\x0c\x00\x7d\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x2e\x0c\x00\x6a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x2c\x0c\x00\x45\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x2b\x0c\x00\x44\x00\x00\x00\x00\x00\x00\x24\x40\x65\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x43\x00\x00\x20\x41\x41\x2a\x0c\x00\x5c\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x2c\x0c\x00\x65\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x29\x0c\x00\xa7\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x28\x0c\x00\x40\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x10\x00\x41\x04\x41\x08\x0c\x00\x6a\x0b\x6a\x0b\x9a\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x0c\x01\x0c\x00\x0b\x1a\x41\x10\x0b\x6a\x0b\x9f\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x0c\x01\x41\x01\x0d\x00\x1a\x41\x20\x0b\x1a\x41\x10\x0b\x6a\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x41\x08\x0c\x00\x0d\x00\x1a\x41\x10\x0b\x6a\x0b\x9d\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x04\x1a\x41\x08\x0c\x01\x41\x01\x0e\x00\x00\x0b\x1a\x41\x10\x0b\x6a\x0b\x96\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x41\x08\x0c\x00\x0e\x00\x00\x41\x10\x0b\x6a\x0b"); + +// br.wast:372 +assert_return(() => call($1, "type-i32", [])); + +// br.wast:373 +assert_return(() => call($1, "type-i64", [])); + +// br.wast:374 +assert_return(() => call($1, "type-f32", [])); + +// br.wast:375 +assert_return(() => call($1, "type-f64", [])); + +// br.wast:376 +assert_return(() => call($1, "type-i32-i32", [])); + +// br.wast:377 +assert_return(() => call($1, "type-i64-i64", [])); + +// br.wast:378 +assert_return(() => call($1, "type-f32-f32", [])); + +// br.wast:379 +assert_return(() => call($1, "type-f64-f64", [])); + +// br.wast:381 +assert_return(() => call($1, "type-i32-value", []), 1); + +// br.wast:382 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i64-value", []), int64("2")) + +// br.wast:383 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f32-value", []), 3.) + +// br.wast:384 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64-value", []), 4.) + +// br.wast:385 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7c\x7c\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x14\x40\xbd\x51\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64-f64-value", []), 4., 5.) + +// br.wast:387 +assert_return(() => call($1, "as-block-first", [])); + +// br.wast:388 +assert_return(() => call($1, "as-block-mid", [])); + +// br.wast:389 +assert_return(() => call($1, "as-block-last", [])); + +// br.wast:390 +assert_return(() => call($1, "as-block-value", []), 2); + +// br.wast:392 +assert_return(() => call($1, "as-loop-first", []), 3); + +// br.wast:393 +assert_return(() => call($1, "as-loop-mid", []), 4); + +// br.wast:394 +assert_return(() => call($1, "as-loop-last", []), 5); + +// br.wast:396 +assert_return(() => call($1, "as-br-value", []), 9); + +// br.wast:398 +assert_return(() => call($1, "as-br_if-cond", [])); + +// br.wast:399 +assert_return(() => call($1, "as-br_if-value", []), 8); + +// br.wast:400 +assert_return(() => call($1, "as-br_if-value-cond", []), 9); + +// br.wast:402 +assert_return(() => call($1, "as-br_table-index", [])); + +// br.wast:403 +assert_return(() => call($1, "as-br_table-value", []), 10); + +// br.wast:404 +assert_return(() => call($1, "as-br_table-value-index", []), 11); + +// br.wast:406 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-return-value", []), int64("7")) + +// br.wast:407 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x07\x01\x51\x45\x0d\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-return-values", []), 2, int64("7")) + +// br.wast:409 +assert_return(() => call($1, "as-if-cond", []), 2); + +// br.wast:410 +assert_return(() => call($1, "as-if-then", [1, 6]), 3); + +// br.wast:411 +assert_return(() => call($1, "as-if-then", [0, 6]), 6); + +// br.wast:412 +assert_return(() => call($1, "as-if-else", [0, 6]), 4); + +// br.wast:413 +assert_return(() => call($1, "as-if-else", [1, 6]), 6); + +// br.wast:415 +assert_return(() => call($1, "as-select-first", [0, 6]), 5); + +// br.wast:416 +assert_return(() => call($1, "as-select-first", [1, 6]), 5); + +// br.wast:417 +assert_return(() => call($1, "as-select-second", [0, 6]), 6); + +// br.wast:418 +assert_return(() => call($1, "as-select-second", [1, 6]), 6); + +// br.wast:419 +assert_return(() => call($1, "as-select-cond", []), 7); + +// br.wast:420 +assert_return(() => call($1, "as-select-all", []), 8); + +// br.wast:422 +assert_return(() => call($1, "as-call-first", []), 12); + +// br.wast:423 +assert_return(() => call($1, "as-call-mid", []), 13); + +// br.wast:424 +assert_return(() => call($1, "as-call-last", []), 14); + +// br.wast:425 +assert_return(() => call($1, "as-call-all", []), 15); + +// br.wast:427 +assert_return(() => call($1, "as-call_indirect-func", []), 20); + +// br.wast:428 +assert_return(() => call($1, "as-call_indirect-first", []), 21); + +// br.wast:429 +assert_return(() => call($1, "as-call_indirect-mid", []), 22); + +// br.wast:430 +assert_return(() => call($1, "as-call_indirect-last", []), 23); + +// br.wast:431 +assert_return(() => call($1, "as-call_indirect-all", []), 24); + +// br.wast:433 +assert_return(() => call($1, "as-local.set-value", []), 17); + +// br.wast:434 +assert_return(() => call($1, "as-local.tee-value", []), 1); + +// br.wast:435 +assert_return(() => call($1, "as-global.set-value", []), 1); + +// br.wast:437 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x9a\x99\xd9\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-load-address", []), 1.70000004768) + +// br.wast:438 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x1e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-loadN-address", []), int64("30")) + +// br.wast:440 +assert_return(() => call($1, "as-store-address", []), 30); + +// br.wast:441 +assert_return(() => call($1, "as-store-value", []), 31); + +// br.wast:442 +assert_return(() => call($1, "as-store-both", []), 32); + +// br.wast:443 +assert_return(() => call($1, "as-storeN-address", []), 32); + +// br.wast:444 +assert_return(() => call($1, "as-storeN-value", []), 33); + +// br.wast:445 +assert_return(() => call($1, "as-storeN-both", []), 34); + +// br.wast:447 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x9a\x99\x59\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 3.40000009537) + +// br.wast:449 +assert_return(() => call($1, "as-binary-left", []), 3); + +// br.wast:450 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x2d\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-binary-right", []), int64("45")) + +// br.wast:451 +assert_return(() => call($1, "as-binary-both", []), 46); + +// br.wast:453 +assert_return(() => call($1, "as-test-operand", []), 44); + +// br.wast:455 +assert_return(() => call($1, "as-compare-left", []), 43); + +// br.wast:456 +assert_return(() => call($1, "as-compare-right", []), 42); + +// br.wast:457 +assert_return(() => call($1, "as-compare-both", []), 44); + +// br.wast:459 +assert_return(() => call($1, "as-convert-operand", []), 41); + +// br.wast:461 +assert_return(() => call($1, "as-memory.grow-size", []), 40); + +// br.wast:463 +assert_return(() => call($1, "nested-block-value", []), 9); + +// br.wast:464 +assert_return(() => call($1, "nested-br-value", []), 9); + +// br.wast:465 +assert_return(() => call($1, "nested-br_if-value", []), 9); + +// br.wast:466 +assert_return(() => call($1, "nested-br_if-value-cond", []), 9); + +// br.wast:467 +assert_return(() => call($1, "nested-br_table-value", []), 9); + +// br.wast:468 +assert_return(() => call($1, "nested-br_table-value-index", []), 9); + +// br.wast:470 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x41\x01\x0b\x0b"); + +// br.wast:477 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7f\x01\x0c\x00\x41\x01\x0b\x0b"); + +// br.wast:483 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x02\x40\x0c\x01\x0b\x0b\x0b"); + +// br.wast:489 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x0c\x00\x41\x01\x0b\x0b"); + +// br.wast:496 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x02\x7f\x0c\x00\x0c\x00\x0b\x45\x1a\x0b"); + +// br.wast:505 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x02\x7f\x0c\x00\x41\x01\x0d\x00\x0b\x45\x1a\x0b"); + +// br.wast:514 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x02\x7f\x0c\x00\x0e\x00\x00\x0b\x45\x1a\x0b"); + +// br.wast:523 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x0f\x0b\x45\x1a\x0b"); + +// br.wast:534 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x41\x01\x41\x02\x1b\x0b\x45\x1a\x0b"); + +// br.wast:545 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x9a\x80\x80\x80\x00\x02\x8b\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x10\x01\x0b\x45\x1a\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// br.wast:557 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9d\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x41\x00\x11\x00\x00\x0b\x45\x1a\x0b"); + +// br.wast:573 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x0c\x00\x21\x00\x20\x00\x0b\x45\x1a\x0b"); + +// br.wast:585 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x0c\x00\x22\x00\x0b\x45\x1a\x0b"); + +// br.wast:597 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x24\x00\x23\x00\x0b\x45\x1a\x0b"); + +// br.wast:609 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x40\x00\x0b\x45\x1a\x0b"); + +// br.wast:621 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x28\x02\x00\x0b\x45\x1a\x0b"); + +// br.wast:633 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x0c\x00\x41\x00\x36\x02\x00\x0b\x45\x1a\x0b"); + +// br.wast:646 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x0c\x01\x0b"); + +// br.wast:650 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x02\x40\x0c\x05\x0b\x0b\x0b"); + +// br.wast:654 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x0c\x81\x80\x80\x80\x01\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/br_if.wast.js b/js/src/jit-test/tests/wasm/spec/spec/br_if.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/br_if.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/br_if.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/call.wast.js b/js/src/jit-test/tests/wasm/spec/spec/call.wast.js new file mode 100644 index 0000000000..ed75a1f2c4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/call.wast.js @@ -0,0 +1,273 @@ + +// call.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xe9\x81\x80\x80\x00\x19\x60\x02\x7f\x7f\x01\x7f\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x00\x02\x7f\x7e\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x60\x01\x7d\x01\x7d\x60\x01\x7c\x01\x7c\x60\x02\x7f\x7c\x02\x7f\x7c\x60\x02\x7f\x7f\x02\x7f\x7f\x60\x02\x7d\x7c\x02\x7c\x7d\x60\x02\x7c\x7f\x02\x7f\x7c\x60\x02\x7d\x7f\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x60\x02\x7c\x7d\x01\x7d\x60\x02\x7e\x7c\x01\x7c\x60\x00\x02\x7f\x7c\x60\x00\x02\x7f\x7f\x60\x00\x02\x7c\x7d\x60\x02\x7e\x7e\x01\x7e\x60\x01\x7e\x01\x7f\x60\x00\x00\x60\x64\x7d\x7f\x7f\x7c\x7d\x7d\x7d\x7c\x7d\x7f\x7f\x7d\x7c\x7e\x7e\x7f\x7e\x7e\x7d\x7e\x7e\x7e\x7f\x7d\x7d\x7d\x7c\x7d\x7f\x7e\x7d\x7c\x7c\x7d\x7f\x7d\x7d\x7c\x7e\x7c\x7f\x7e\x7d\x7c\x7f\x7f\x7f\x7e\x7c\x7f\x7e\x7e\x7c\x7c\x7c\x7c\x7c\x7c\x7f\x7d\x7c\x7c\x7f\x7e\x7d\x7d\x7d\x7f\x7c\x7c\x7c\x7c\x7c\x7d\x7e\x7e\x7f\x7f\x7f\x7d\x7c\x7f\x7e\x7d\x7d\x7d\x7f\x7f\x7d\x7c\x7e\x7d\x7c\x7d\x7d\x7d\x7f\x7d\x7e\x7f\x01\x7f\x03\xcf\x80\x80\x80\x00\x4e\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x01\x02\x03\x04\x05\x01\x02\x03\x04\x01\x02\x03\x04\x12\x13\x14\x12\x01\x01\x13\x07\x15\x07\x16\x16\x17\x17\x17\x01\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x17\x17\x01\x01\x17\x01\x01\x01\x01\x01\x06\x08\x03\x01\x01\x01\x01\x01\x02\x18\x06\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xca\x87\x80\x80\x00\x38\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x11\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x12\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x13\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x14\x0c\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x15\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x16\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x17\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x18\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x19\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x1a\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x1b\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x1c\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x1d\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x1e\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x69\x33\x32\x00\x1f\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x33\x32\x2d\x66\x36\x34\x00\x20\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x21\x16\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x61\x6c\x6c\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x22\x11\x61\x73\x2d\x6d\x69\x78\x65\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x23\x14\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x61\x6c\x6c\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x24\x03\x66\x61\x63\x00\x25\x07\x66\x61\x63\x2d\x61\x63\x63\x00\x26\x03\x66\x69\x62\x00\x27\x04\x65\x76\x65\x6e\x00\x28\x03\x6f\x64\x64\x00\x29\x07\x72\x75\x6e\x61\x77\x61\x79\x00\x2a\x0e\x6d\x75\x74\x75\x61\x6c\x2d\x72\x75\x6e\x61\x77\x61\x79\x00\x2b\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x2d\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x2e\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x2f\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x30\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x31\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x32\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x33\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x34\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x36\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x37\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x38\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x39\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x3a\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x3b\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x3c\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x3d\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x3e\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x3f\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x40\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x41\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x42\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x45\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x46\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x47\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x48\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x49\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x4a\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x4b\x1e\x72\x65\x74\x75\x72\x6e\x2d\x66\x72\x6f\x6d\x2d\x6c\x6f\x6e\x67\x2d\x61\x72\x67\x75\x6d\x65\x6e\x74\x2d\x6c\x69\x73\x74\x00\x4d\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x35\x0a\xad\x8c\x80\x80\x00\x4e\x85\x80\x80\x80\x00\x00\x41\xb2\x02\x0b\x85\x80\x80\x80\x00\x00\x42\xe4\x02\x0b\x87\x80\x80\x80\x00\x00\x43\x00\x20\x73\x45\x0b\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\xc8\xae\x40\x0b\x88\x80\x80\x80\x00\x00\x41\xb2\x02\x42\xe4\x02\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x20\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x01\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x01\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x01\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x10\x00\x0b\x84\x80\x80\x80\x00\x00\x10\x01\x0b\x84\x80\x80\x80\x00\x00\x10\x02\x0b\x84\x80\x80\x80\x00\x00\x10\x03\x0b\x84\x80\x80\x80\x00\x00\x10\x04\x0b\x86\x80\x80\x80\x00\x00\x41\x20\x10\x05\x0b\x87\x80\x80\x80\x00\x00\x42\xc0\x00\x10\x06\x0b\x89\x80\x80\x80\x00\x00\x43\xc3\xf5\xa8\x3f\x10\x07\x0b\x8d\x80\x80\x80\x00\x00\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\x10\x08\x0b\x8b\x80\x80\x80\x00\x00\x43\x66\x66\x00\x42\x41\x20\x10\x0d\x0b\x89\x80\x80\x80\x00\x00\x41\x20\x42\xc0\x00\x10\x0e\x0b\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x50\x40\x43\x00\x00\x00\x42\x10\x0f\x0b\x90\x80\x80\x80\x00\x00\x42\xc0\x00\x44\x66\x66\x66\x66\x66\x06\x50\x40\x10\x10\x0b\x8f\x80\x80\x80\x00\x00\x41\x20\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\x10\x09\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x41\x02\x10\x0a\x0b\x92\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x44\x00\x00\x00\x00\x00\x00\x00\x40\x10\x0b\x0b\x8f\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x02\x10\x0c\x0b\x89\x80\x80\x80\x00\x00\x41\x03\x41\x04\x10\x0a\x6a\x0b\x8c\x80\x80\x80\x00\x00\x41\x03\x41\x04\x10\x0a\x41\x05\x6a\x6c\x0b\x8a\x80\x80\x80\x00\x00\x41\x03\x41\x04\x10\x0a\x10\x0a\x0b\x95\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7e\x42\x01\x05\x20\x00\x20\x00\x42\x01\x7d\x10\x25\x7e\x0b\x0b\x97\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7e\x20\x01\x05\x20\x00\x42\x01\x7d\x20\x00\x20\x01\x7e\x10\x26\x0b\x0b\x9c\x80\x80\x80\x00\x00\x20\x00\x42\x01\x58\x04\x7e\x42\x01\x05\x20\x00\x42\x02\x7d\x10\x27\x20\x00\x42\x01\x7d\x10\x27\x7c\x0b\x0b\x92\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7f\x41\x2c\x05\x20\x00\x42\x01\x7d\x10\x29\x0b\x0b\x93\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7f\x41\xe3\x00\x05\x20\x00\x42\x01\x7d\x10\x28\x0b\x0b\x84\x80\x80\x80\x00\x00\x10\x2a\x0b\x84\x80\x80\x80\x00\x00\x10\x2c\x0b\x84\x80\x80\x80\x00\x00\x10\x2b\x0b\x89\x80\x80\x80\x00\x00\x10\x00\x41\x02\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x10\x00\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x41\x03\x10\x00\x1b\x0b\x8c\x80\x80\x80\x00\x00\x10\x00\x04\x7f\x41\x01\x05\x41\x02\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x02\x0d\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x10\x00\x0d\x00\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x02\x0e\x01\x00\x00\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x10\x00\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x10\x00\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x10\x00\x11\x00\x00\x0b\x0b\x89\x80\x80\x80\x00\x00\x10\x00\x41\x01\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x0a\x10\x00\x36\x02\x00\x0b\x86\x80\x80\x80\x00\x00\x10\x00\x40\x00\x0b\x85\x80\x80\x80\x00\x00\x10\x00\x0f\x0b\x85\x80\x80\x80\x00\x00\x10\x00\x1a\x0b\x89\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x0c\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x01\x7f\x10\x00\x21\x00\x20\x00\x0b\x88\x80\x80\x80\x00\x01\x01\x7f\x10\x00\x22\x00\x0b\x88\x80\x80\x80\x00\x00\x10\x00\x24\x00\x23\x00\x0b\x87\x80\x80\x80\x00\x00\x10\x00\x28\x02\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x00\x00\x10\x44\x91\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x10\x43\x41\x0a\x6a\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x10\x43\x6b\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x10\x43\x45\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x10\x43\x41\x0a\x4d\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x10\x43\x47\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x10\x43\xac\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x63\x0b\xdf\x83\x80\x80\x00\x00\x43\x00\x00\x00\x00\x41\x00\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x41\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x42\x00\x41\x00\x42\x00\x42\x00\x43\x00\x00\x00\x00\x42\x00\x42\x00\x42\x00\x41\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x42\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x41\x00\x41\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x42\x00\x42\x00\x41\x00\x41\x00\x41\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x41\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x41\x00\x43\x00\x00\x00\x00\x42\x00\x20\x00\x10\x4c\x0b"); + +// call.wast:285 +assert_return(() => call($1, "type-i32", []), 306); + +// call.wast:286 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i64", []), int64("356")) + +// call.wast:287 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x20\x73\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f32", []), 3890.) + +// call.wast:288 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64", []), 3940.) + +// call.wast:289 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7e\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x01\x41\xb2\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i32-i64", []), 306, int64("356")) + +// call.wast:291 +assert_return(() => call($1, "type-first-i32", []), 32); + +// call.wast:292 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-i64", []), int64("64")) + +// call.wast:293 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xc3\xf5\xa8\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-f32", []), 1.32000005245) + +// call.wast:294 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-f64", []), 1.64) + +// call.wast:296 +assert_return(() => call($1, "type-second-i32", []), 32); + +// call.wast:297 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-i64", []), int64("64")) + +// call.wast:298 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-f32", []), 32.) + +// call.wast:299 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x66\x66\x66\x66\x66\x06\x50\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-f64", []), 64.1) + +// call.wast:301 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\xbd\x51\x45\x0d\x00\x01\x41\x20\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-i32-f64", []), 32, 1.64) + +// call.wast:302 +assert_return(() => call($1, "type-all-i32-i32", []), 2, 1); + +// call.wast:303 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7c\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-f32-f64", []), 2., 1.) + +// call.wast:304 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-f64-i32", []), 2, 1.) + +// call.wast:306 +assert_return(() => call($1, "as-binary-all-operands", []), 7); + +// call.wast:307 +assert_return(() => call($1, "as-mixed-operands", []), 32); + +// call.wast:308 +assert_return(() => call($1, "as-call-all-operands", []), 3, 4); + +// call.wast:310 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x61\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac", [int64("0")]), int64("1")) + +// call.wast:311 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x61\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac", [int64("1")]), int64("1")) + +// call.wast:312 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x61\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac", [int64("5")]), int64("120")) + +// call.wast:313 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x61\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// call.wast:314 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x61\x63\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-acc", [int64("0"), int64("1")]), int64("1")) + +// call.wast:315 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x61\x63\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-acc", [int64("1"), int64("1")]), int64("1")) + +// call.wast:316 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x61\x63\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x01\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-acc", [int64("5"), int64("1")]), int64("120")) + +// call.wast:317 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x61\x63\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x19\x42\x01\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-acc", [int64("25"), int64("1")]), int64("7_034_535_277_573_963_776")) + +// call.wast:322 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x69\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib", [int64("0")]), int64("1")) + +// call.wast:323 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x69\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib", [int64("1")]), int64("1")) + +// call.wast:324 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x69\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib", [int64("2")]), int64("2")) + +// call.wast:325 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x69\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib", [int64("5")]), int64("8")) + +// call.wast:326 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x69\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x14\x10\x00\x01\x42\xc2\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib", [int64("20")]), int64("10_946")) + +// call.wast:328 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x65\x76\x65\x6e\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x41\x2c\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "even", [int64("0")]), 44) + +// call.wast:329 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x65\x76\x65\x6e\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x41\xe3\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "even", [int64("1")]), 99) + +// call.wast:330 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x65\x76\x65\x6e\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\xe4\x00\x10\x00\x01\x41\x2c\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "even", [int64("100")]), 44) + +// call.wast:331 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x65\x76\x65\x6e\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xcd\x00\x10\x00\x01\x41\xe3\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "even", [int64("77")]), 99) + +// call.wast:332 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6f\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x41\xe3\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "odd", [int64("0")]), 99) + +// call.wast:333 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6f\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x41\x2c\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "odd", [int64("1")]), 44) + +// call.wast:334 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6f\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xc8\x01\x10\x00\x01\x41\xe3\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "odd", [int64("200")]), 99) + +// call.wast:335 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6f\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\xcd\x00\x10\x00\x01\x41\x2c\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "odd", [int64("77")]), 44) + +// call.wast:337 +assert_exhaustion(() => call($1, "runaway", [])); + +// call.wast:338 +assert_exhaustion(() => call($1, "mutual-runaway", [])); + +// call.wast:340 +assert_return(() => call($1, "as-select-first", []), 306); + +// call.wast:341 +assert_return(() => call($1, "as-select-mid", []), 2); + +// call.wast:342 +assert_return(() => call($1, "as-select-last", []), 2); + +// call.wast:344 +assert_return(() => call($1, "as-if-condition", []), 1); + +// call.wast:346 +assert_return(() => call($1, "as-br_if-first", []), 306); + +// call.wast:347 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// call.wast:349 +assert_return(() => call($1, "as-br_table-first", []), 306); + +// call.wast:350 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// call.wast:352 +assert_return(() => call($1, "as-call_indirect-first", []), 306); + +// call.wast:353 +assert_return(() => call($1, "as-call_indirect-mid", []), 2); + +// call.wast:354 +assert_trap(() => call($1, "as-call_indirect-last", [])); + +// call.wast:356 +assert_return(() => call($1, "as-store-first", [])); + +// call.wast:357 +assert_return(() => call($1, "as-store-last", [])); + +// call.wast:359 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// call.wast:360 +assert_return(() => call($1, "as-return-value", []), 306); + +// call.wast:361 +assert_return(() => call($1, "as-drop-operand", [])); + +// call.wast:362 +assert_return(() => call($1, "as-br-value", []), 306); + +// call.wast:363 +assert_return(() => call($1, "as-local.set-value", []), 306); + +// call.wast:364 +assert_return(() => call($1, "as-local.tee-value", []), 306); + +// call.wast:365 +assert_return(() => call($1, "as-global.set-value", []), 306); + +// call.wast:366 +assert_return(() => call($1, "as-load-operand", []), 1); + +// call.wast:368 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 0.) + +// call.wast:369 +assert_return(() => call($1, "as-binary-left", []), 11); + +// call.wast:370 +assert_return(() => call($1, "as-binary-right", []), 9); + +// call.wast:371 +assert_return(() => call($1, "as-test-operand", []), 0); + +// call.wast:372 +assert_return(() => call($1, "as-compare-left", []), 1); + +// call.wast:373 +assert_return(() => call($1, "as-compare-right", []), 1); + +// call.wast:374 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-convert-operand", []), int64("1")) + +// call.wast:376 +assert_return(() => call($1, "return-from-long-argument-list", [42]), 42); + +// call.wast:380 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x0a\x92\x80\x80\x80\x00\x02\x85\x80\x80\x80\x00\x00\x10\x01\x45\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:387 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x94\x80\x80\x80\x00\x02\x85\x80\x80\x80\x00\x00\x10\x01\x45\x0b\x84\x80\x80\x80\x00\x00\x42\x01\x0b"); + +// call.wast:395 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x91\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:402 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7c\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x91\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:409 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x0a\x93\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x41\x01\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:416 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x0a\x9c\x80\x80\x80\x00\x02\x8f\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x01\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:424 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x94\x80\x80\x80\x00\x02\x87\x80\x80\x80\x00\x00\x01\x41\x01\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:431 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x94\x80\x80\x80\x00\x02\x87\x80\x80\x80\x00\x00\x41\x01\x01\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:438 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x9c\x80\x80\x80\x00\x02\x8f\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:445 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7c\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x9c\x80\x80\x80\x00\x02\x8f\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x01\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:453 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x94\x80\x80\x80\x00\x02\x87\x80\x80\x80\x00\x00\x02\x40\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:462 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x96\x80\x80\x80\x00\x02\x89\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:471 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x94\x80\x80\x80\x00\x02\x87\x80\x80\x80\x00\x00\x03\x40\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:480 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x96\x80\x80\x80\x00\x02\x89\x80\x80\x80\x00\x00\x03\x40\x41\x00\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:489 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x96\x80\x80\x80\x00\x02\x89\x80\x80\x80\x00\x00\x41\x00\x04\x40\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:498 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x98\x80\x80\x80\x00\x02\x8b\x80\x80\x80\x00\x00\x41\x00\x04\x40\x41\x00\x10\x01\x0b\x0b\x82\x80\x80\x80\x00\x00\x0b"); + +// call.wast:511 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x10\x01\x0b"); + +// call.wast:515 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x10\x94\x98\xdb\xe2\x03\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/call_indirect.wast.js b/js/src/jit-test/tests/wasm/spec/spec/call_indirect.wast.js new file mode 100644 index 0000000000..cfb178619f --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/call_indirect.wast.js @@ -0,0 +1,468 @@ + +// call_indirect.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x98\x81\x80\x80\x00\x1d\x60\x00\x00\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x00\x02\x7c\x7f\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x60\x01\x7d\x01\x7d\x60\x01\x7c\x01\x7c\x60\x02\x7f\x7c\x02\x7f\x7c\x60\x02\x7f\x7e\x02\x7e\x7f\x60\x02\x7d\x7f\x01\x7f\x60\x02\x7f\x7e\x01\x7e\x60\x02\x7c\x7d\x01\x7d\x60\x02\x7e\x7c\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x60\x01\x7d\x01\x7d\x60\x01\x7c\x01\x7c\x60\x04\x7e\x7c\x7f\x7e\x01\x7f\x60\x01\x7e\x01\x7f\x60\x04\x7e\x7c\x7f\x7e\x00\x60\x01\x7e\x00\x60\x00\x02\x7f\x7c\x60\x00\x02\x7e\x7f\x60\x01\x7f\x01\x7e\x60\x01\x7f\x01\x7d\x60\x01\x7f\x01\x7c\x03\xd1\x80\x80\x80\x00\x50\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0d\x0f\x0c\x0e\x10\x11\x12\x13\x00\x01\x02\x03\x04\x05\x02\x01\x02\x03\x04\x01\x02\x03\x04\x05\x18\x19\x0d\x1a\x06\x1b\x1c\x07\x07\x06\x08\x09\x06\x08\x09\x06\x06\x00\x00\x00\x01\x01\x01\x01\x02\x01\x03\x01\x00\x00\x01\x01\x00\x03\x04\x04\x04\x01\x03\x01\x01\x01\x01\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x20\x20\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x8d\x80\x80\x80\x00\x01\x7c\x01\x44\x00\x00\x00\x00\x00\x00\x24\x40\x0b\x07\xc4\x87\x80\x80\x00\x3b\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x14\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x15\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x16\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x17\x0c\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x18\x0a\x74\x79\x70\x65\x2d\x69\x6e\x64\x65\x78\x00\x19\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x1a\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x1b\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x1c\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x1d\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x1e\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x1f\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x20\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x21\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x22\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x23\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x24\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x25\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x26\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x33\x32\x00\x27\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x28\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x29\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x2a\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x2b\x07\x66\x61\x63\x2d\x69\x33\x32\x00\x2c\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x2d\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x2e\x07\x66\x69\x62\x2d\x69\x33\x32\x00\x2f\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x30\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x31\x04\x65\x76\x65\x6e\x00\x32\x03\x6f\x64\x64\x00\x33\x07\x72\x75\x6e\x61\x77\x61\x79\x00\x34\x0e\x6d\x75\x74\x75\x61\x6c\x2d\x72\x75\x6e\x61\x77\x61\x79\x00\x35\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x37\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x38\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x39\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x3a\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x3b\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x3c\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x3d\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x3e\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x3f\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x40\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x41\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x42\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x43\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x44\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x45\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x46\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x47\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x48\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x49\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x4a\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x4b\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x4c\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x4d\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x4e\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x4f\x09\xa6\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x20\x00\x01\x02\x03\x05\x06\x07\x08\x0d\x0b\x0e\x0c\x2a\x2b\x32\x33\x34\x35\x36\x0f\x10\x11\x12\x2c\x2d\x2e\x2f\x30\x31\x04\x09\x0a\x0a\xa1\x8c\x80\x80\x00\x50\x85\x80\x80\x80\x00\x00\x41\xb2\x02\x0b\x85\x80\x80\x80\x00\x00\x42\xe4\x02\x0b\x87\x80\x80\x80\x00\x00\x43\x00\x20\x73\x45\x0b\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\xc8\xae\x40\x0b\x8d\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\xc8\xae\x40\x41\x20\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x20\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x01\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\xdd\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x42\x00\x41\x00\x11\x17\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x41\x00\x11\x16\x00\x41\x00\x11\x00\x00\x41\x00\x11\x01\x00\x45\x1a\x41\x00\x11\x01\x00\x45\x1a\x42\x00\x41\x00\x11\x15\x00\x45\x1a\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x42\x00\x41\x00\x11\x14\x00\x45\x1a\x42\x00\x41\x00\x11\x07\x00\x50\x1a\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x01\x11\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x02\x11\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x03\x11\x04\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x1d\x11\x05\x00\x0b\x8a\x80\x80\x80\x00\x00\x42\xe4\x00\x41\x05\x11\x07\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x20\x41\x04\x11\x06\x00\x0b\x8a\x80\x80\x80\x00\x00\x42\xc0\x00\x41\x05\x11\x07\x00\x0b\x8c\x80\x80\x80\x00\x00\x43\xc3\xf5\xa8\x3f\x41\x06\x11\x08\x00\x0b\x90\x80\x80\x80\x00\x00\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\x41\x07\x11\x09\x00\x0b\x8e\x80\x80\x80\x00\x00\x43\x66\x66\x00\x42\x41\x20\x41\x08\x11\x0c\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x20\x42\xc0\x00\x41\x09\x11\x0d\x00\x0b\x95\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x50\x40\x43\x00\x00\x00\x42\x41\x0a\x11\x0e\x00\x0b\x93\x80\x80\x80\x00\x00\x42\xc0\x00\x44\x66\x66\x66\x66\x66\x06\x50\x40\x41\x0b\x11\x0f\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x1d\x11\x05\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x1e\x11\x0a\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x42\x02\x41\x1f\x11\x0b\x00\x0b\x89\x80\x80\x80\x00\x00\x20\x01\x20\x00\x11\x07\x00\x0b\x89\x80\x80\x80\x00\x00\x42\x09\x20\x00\x11\x11\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x09\x20\x00\x11\x10\x00\x0b\x8c\x80\x80\x80\x00\x00\x43\x00\x00\x10\x41\x20\x00\x11\x12\x00\x0b\x90\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x22\x40\x20\x00\x11\x13\x00\x0b\x98\x80\x80\x80\x00\x00\x20\x00\x50\x04\x7e\x42\x01\x05\x20\x00\x20\x00\x42\x01\x7d\x41\x0c\x11\x07\x00\x7e\x0b\x0b\xa2\x80\x80\x80\x00\x00\x20\x00\x42\x01\x58\x04\x7e\x42\x01\x05\x20\x00\x42\x02\x7d\x41\x0d\x11\x07\x00\x20\x00\x42\x01\x7d\x41\x0d\x11\x07\x00\x7c\x0b\x0b\x98\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\x01\x05\x20\x00\x20\x00\x41\x01\x6b\x41\x17\x11\x06\x00\x6c\x0b\x0b\xa3\x80\x80\x80\x00\x00\x20\x00\x43\x00\x00\x00\x00\x5b\x04\x7d\x43\x00\x00\x80\x3f\x05\x20\x00\x20\x00\x43\x00\x00\x80\x3f\x93\x41\x18\x11\x08\x00\x94\x0b\x0b\xaf\x80\x80\x80\x00\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x61\x04\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x05\x20\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xa1\x41\x19\x11\x09\x00\xa2\x0b\x0b\xa2\x80\x80\x80\x00\x00\x20\x00\x41\x01\x4d\x04\x7f\x41\x01\x05\x20\x00\x41\x02\x6b\x41\x1a\x11\x06\x00\x20\x00\x41\x01\x6b\x41\x1a\x11\x06\x00\x6a\x0b\x0b\xae\x80\x80\x80\x00\x00\x20\x00\x43\x00\x00\x80\x3f\x5f\x04\x7d\x43\x00\x00\x80\x3f\x05\x20\x00\x43\x00\x00\x00\x40\x93\x41\x1b\x11\x08\x00\x20\x00\x43\x00\x00\x80\x3f\x93\x41\x1b\x11\x08\x00\x92\x0b\x0b\xbe\x80\x80\x80\x00\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x65\x04\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x05\x20\x00\x44\x00\x00\x00\x00\x00\x00\x00\x40\xa1\x41\x1c\x11\x09\x00\x20\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xa1\x41\x1c\x11\x09\x00\xa0\x0b\x0b\x95\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\x2c\x05\x20\x00\x41\x01\x6b\x41\x0f\x11\x06\x00\x0b\x0b\x96\x80\x80\x80\x00\x00\x20\x00\x45\x04\x7f\x41\xe3\x00\x05\x20\x00\x41\x01\x6b\x41\x0e\x11\x06\x00\x0b\x0b\x87\x80\x80\x80\x00\x00\x41\x10\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x12\x11\x00\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x11\x11\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x41\x02\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x00\x11\x01\x00\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x03\x41\x00\x11\x01\x00\x1b\x0b\x8f\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x04\x7f\x41\x01\x05\x41\x02\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x11\x02\x00\x41\x02\x0d\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x11\x01\x00\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7d\x41\x02\x11\x03\x00\x41\x02\x0e\x01\x00\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x11\x01\x00\x0e\x01\x00\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x41\x01\x36\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x41\x03\x11\x04\x00\x39\x03\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x40\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x04\x11\x06\x00\x0f\x0b\x8a\x80\x80\x80\x00\x00\x42\x01\x41\x05\x11\x07\x00\x1a\x0b\x91\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x80\x3f\x41\x06\x11\x08\x00\x0c\x00\x0b\x0b\x96\x80\x80\x80\x00\x01\x01\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x21\x00\x20\x00\x0b\x94\x80\x80\x80\x00\x01\x01\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x22\x00\x0b\x94\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x07\x11\x09\x00\x24\x00\x23\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x28\x02\x00\x0b\x90\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x00\x00\x41\x06\x11\x08\x00\x91\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x41\x0a\x6a\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x04\x11\x06\x00\x6b\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x45\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x11\x06\x00\x41\x0a\x4d\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x04\x11\x06\x00\x47\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7e\x41\x01\x41\x04\x11\x06\x00\xac\x0b\x0b"); + +// call_indirect.wast:471 +assert_return(() => call($1, "type-i32", []), 306); + +// call_indirect.wast:472 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i64", []), int64("356")) + +// call_indirect.wast:473 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x20\x73\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f32", []), 3890.) + +// call_indirect.wast:474 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64", []), 3940.) + +// call_indirect.wast:475 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7c\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x20\x01\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64-i32", []), 3940., 32) + +// call_indirect.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x74\x79\x70\x65\x2d\x69\x6e\x64\x65\x78\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-index", []), int64("100")) + +// call_indirect.wast:479 +assert_return(() => call($1, "type-first-i32", []), 32); + +// call_indirect.wast:480 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-i64", []), int64("64")) + +// call_indirect.wast:481 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xc3\xf5\xa8\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-f32", []), 1.32000005245) + +// call_indirect.wast:482 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x3d\x0a\xd7\xa3\x70\x3d\xfa\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-first-f64", []), 1.64) + +// call_indirect.wast:484 +assert_return(() => call($1, "type-second-i32", []), 32); + +// call_indirect.wast:485 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-i64", []), int64("64")) + +// call_indirect.wast:486 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-f32", []), 32.) + +// call_indirect.wast:487 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x74\x79\x70\x65\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x66\x66\x66\x66\x66\x06\x50\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-second-f64", []), 64.1) + +// call_indirect.wast:489 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7c\x7f\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x66\x36\x34\x2d\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x20\x01\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\xc8\xae\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-f64-i32", []), 3940., 32) + +// call_indirect.wast:490 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-i32-f64", []), 1, 2.) + +// call_indirect.wast:491 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7e\x7f\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x74\x79\x70\x65\x2d\x61\x6c\x6c\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-all-i32-i64", []), int64("2"), 1) + +// call_indirect.wast:493 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x05\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch", [5, int64("2")]), int64("2")) + +// call_indirect.wast:494 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x05\x42\x05\x10\x00\x01\x42\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch", [5, int64("5")]), int64("5")) + +// call_indirect.wast:495 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x0c\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch", [12, int64("5")]), int64("120")) + +// call_indirect.wast:496 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x0d\x42\x05\x10\x00\x01\x42\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch", [13, int64("5")]), int64("8")) + +// call_indirect.wast:497 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x14\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch", [20, int64("2")]), int64("2")) + +// call_indirect.wast:498 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch", [0, int64("2")])) + +// call_indirect.wast:499 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x0f\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch", [15, int64("2")])) + +// call_indirect.wast:500 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x20\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch", [32, int64("2")])) + +// call_indirect.wast:501 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch", [-1, int64("2")])) + +// call_indirect.wast:502 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x64\x69\x73\x70\x61\x74\x63\x68\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\xe7\x84\xce\xc2\x04\x42\x02\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch", [1_213_432_423, int64("2")])) + +// call_indirect.wast:504 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x05\x10\x00\x01\x42\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [5]), int64("9")) + +// call_indirect.wast:505 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x41\x0c\x10\x00\x01\x42\x80\x93\x16\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [12]), int64("362_880")) + +// call_indirect.wast:506 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x0d\x10\x00\x01\x42\x37\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [13]), int64("55")) + +// call_indirect.wast:507 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x14\x10\x00\x01\x42\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-i64", [20]), int64("9")) + +// call_indirect.wast:508 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x0b\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-i64", [11])) + +// call_indirect.wast:509 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x16\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-i64", [22])) + +// call_indirect.wast:511 +assert_return(() => call($1, "dispatch-structural-i32", [4]), 9); + +// call_indirect.wast:512 +assert_return(() => call($1, "dispatch-structural-i32", [23]), 362_880); + +// call_indirect.wast:513 +assert_return(() => call($1, "dispatch-structural-i32", [26]), 55); + +// call_indirect.wast:514 +assert_return(() => call($1, "dispatch-structural-i32", [19]), 9); + +// call_indirect.wast:515 +assert_trap(() => call($1, "dispatch-structural-i32", [9])); + +// call_indirect.wast:516 +assert_trap(() => call($1, "dispatch-structural-i32", [21])); + +// call_indirect.wast:518 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x06\x10\x00\xbc\x43\x00\x00\x10\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [6]), 9.) + +// call_indirect.wast:519 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x18\x10\x00\xbc\x43\x00\x30\xb1\x48\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [24]), 362880.) + +// call_indirect.wast:520 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x1b\x10\x00\xbc\x43\x00\x00\x5c\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [27]), 55.) + +// call_indirect.wast:521 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x15\x10\x00\xbc\x43\x00\x00\x10\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f32", [21]), 9.) + +// call_indirect.wast:522 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x08\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f32", [8])) + +// call_indirect.wast:523 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x13\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f32", [19])) + +// call_indirect.wast:525 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x07\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [7]), 9.) + +// call_indirect.wast:526 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x19\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x26\x16\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [25]), 362880.) + +// call_indirect.wast:527 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x1c\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x80\x4b\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [28]), 55.) + +// call_indirect.wast:528 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x16\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "dispatch-structural-f64", [22]), 9.) + +// call_indirect.wast:529 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x0a\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f64", [10])) + +// call_indirect.wast:530 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x9e\x80\x80\x80\x00\x01\x02\x24\x31\x17\x64\x69\x73\x70\x61\x74\x63\x68\x2d\x73\x74\x72\x75\x63\x74\x75\x72\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x12\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "dispatch-structural-f64", [18])) + +// call_indirect.wast:532 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("0")]), int64("1")) + +// call_indirect.wast:533 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("1")]), int64("1")) + +// call_indirect.wast:534 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("5")]), int64("120")) + +// call_indirect.wast:535 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-i64", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// call_indirect.wast:537 +assert_return(() => call($1, "fac-i32", [0]), 1); + +// call_indirect.wast:538 +assert_return(() => call($1, "fac-i32", [1]), 1); + +// call_indirect.wast:539 +assert_return(() => call($1, "fac-i32", [5]), 120); + +// call_indirect.wast:540 +assert_return(() => call($1, "fac-i32", [10]), 3_628_800); + +// call_indirect.wast:542 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f32", [0.]), 1.) + +// call_indirect.wast:543 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f32", [1.]), 1.) + +// call_indirect.wast:544 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x40\x10\x00\xbc\x43\x00\x00\xf0\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f32", [5.]), 120.) + +// call_indirect.wast:545 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x20\x41\x10\x00\xbc\x43\x00\x7c\x5d\x4a\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f32", [10.]), 3628800.) + +// call_indirect.wast:547 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f64", [0.]), 1.) + +// call_indirect.wast:548 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f64", [1.]), 1.) + +// call_indirect.wast:549 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x14\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x5e\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f64", [5.]), 120.) + +// call_indirect.wast:550 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x24\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x80\xaf\x4b\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-f64", [10.]), 3628800.) + +// call_indirect.wast:552 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("0")]), int64("1")) + +// call_indirect.wast:553 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("1")]), int64("1")) + +// call_indirect.wast:554 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("2")]), int64("2")) + +// call_indirect.wast:555 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("5")]), int64("8")) + +// call_indirect.wast:556 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x14\x10\x00\x01\x42\xc2\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-i64", [int64("20")]), int64("10_946")) + +// call_indirect.wast:558 +assert_return(() => call($1, "fib-i32", [0]), 1); + +// call_indirect.wast:559 +assert_return(() => call($1, "fib-i32", [1]), 1); + +// call_indirect.wast:560 +assert_return(() => call($1, "fib-i32", [2]), 2); + +// call_indirect.wast:561 +assert_return(() => call($1, "fib-i32", [5]), 8); + +// call_indirect.wast:562 +assert_return(() => call($1, "fib-i32", [20]), 10_946); + +// call_indirect.wast:564 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f32", [0.]), 1.) + +// call_indirect.wast:565 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f32", [1.]), 1.) + +// call_indirect.wast:566 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f32", [2.]), 2.) + +// call_indirect.wast:567 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x40\x10\x00\xbc\x43\x00\x00\x00\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f32", [5.]), 8.) + +// call_indirect.wast:568 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x41\x10\x00\xbc\x43\x00\x08\x2b\x46\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f32", [20.]), 10946.) + +// call_indirect.wast:570 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f64", [0.]), 1.) + +// call_indirect.wast:571 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f64", [1.]), 1.) + +// call_indirect.wast:572 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f64", [2.]), 2.) + +// call_indirect.wast:573 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x14\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x20\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f64", [5.]), 8.) + +// call_indirect.wast:574 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7c\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x69\x62\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x34\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x61\xc5\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fib-f64", [20.]), 10946.) + +// call_indirect.wast:576 +assert_return(() => call($1, "even", [0]), 44); + +// call_indirect.wast:577 +assert_return(() => call($1, "even", [1]), 99); + +// call_indirect.wast:578 +assert_return(() => call($1, "even", [100]), 44); + +// call_indirect.wast:579 +assert_return(() => call($1, "even", [77]), 99); + +// call_indirect.wast:580 +assert_return(() => call($1, "odd", [0]), 99); + +// call_indirect.wast:581 +assert_return(() => call($1, "odd", [1]), 44); + +// call_indirect.wast:582 +assert_return(() => call($1, "odd", [200]), 99); + +// call_indirect.wast:583 +assert_return(() => call($1, "odd", [77]), 44); + +// call_indirect.wast:585 +assert_exhaustion(() => call($1, "runaway", [])); + +// call_indirect.wast:586 +assert_exhaustion(() => call($1, "mutual-runaway", [])); + +// call_indirect.wast:588 +assert_return(() => call($1, "as-select-first", []), 306); + +// call_indirect.wast:589 +assert_return(() => call($1, "as-select-mid", []), 2); + +// call_indirect.wast:590 +assert_return(() => call($1, "as-select-last", []), 2); + +// call_indirect.wast:592 +assert_return(() => call($1, "as-if-condition", []), 1); + +// call_indirect.wast:594 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe4\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-br_if-first", []), int64("356")) + +// call_indirect.wast:595 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// call_indirect.wast:597 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x20\x73\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-br_table-first", []), 3890.) + +// call_indirect.wast:598 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// call_indirect.wast:600 +assert_return(() => call($1, "as-store-first", [])); + +// call_indirect.wast:601 +assert_return(() => call($1, "as-store-last", [])); + +// call_indirect.wast:603 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// call_indirect.wast:604 +assert_return(() => call($1, "as-return-value", []), 1); + +// call_indirect.wast:605 +assert_return(() => call($1, "as-drop-operand", [])); + +// call_indirect.wast:606 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x92\x80\x80\x80\x00\x01\x02\x24\x31\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-br-value", []), 1.) + +// call_indirect.wast:607 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-local.set-value", []), 1.) + +// call_indirect.wast:608 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-local.tee-value", []), 1.) + +// call_indirect.wast:609 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-global.set-value", []), 1.) + +// call_indirect.wast:610 +assert_return(() => call($1, "as-load-operand", []), 1); + +// call_indirect.wast:612 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 0.) + +// call_indirect.wast:613 +assert_return(() => call($1, "as-binary-left", []), 11); + +// call_indirect.wast:614 +assert_return(() => call($1, "as-binary-right", []), 9); + +// call_indirect.wast:615 +assert_return(() => call($1, "as-test-operand", []), 0); + +// call_indirect.wast:616 +assert_return(() => call($1, "as-compare-left", []), 1); + +// call_indirect.wast:617 +assert_return(() => call($1, "as-compare-right", []), 1); + +// call_indirect.wast:618 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x73\x2d\x63\x6f\x6e\x76\x65\x72\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-convert-operand", []), int64("1")) + +// call_indirect.wast:622 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:634 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:646 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:658 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:670 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:682 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:692 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:699 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:709 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:719 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:729 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// call_indirect.wast:744 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:752 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x45\x0b"); + +// call_indirect.wast:760 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x01\x7e\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x45\x0b"); + +// call_indirect.wast:769 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:777 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7c\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:785 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:793 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x40\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:804 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x01\x01\x11\x00\x00\x0b"); + +// call_indirect.wast:812 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x42\x01\x11\x00\x00\x0b"); + +// call_indirect.wast:821 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x01\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:831 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:841 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7c\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:851 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7c\x7f\x00\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x01\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x00\x11\x00\x00\x0b"); + +// call_indirect.wast:862 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x97\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:875 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:888 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x97\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8a\x80\x80\x80\x00\x00\x03\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:901 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x99\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x03\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:914 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:930 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x00\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9d\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x41\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// call_indirect.wast:950 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x11\x01\x00\x0b"); + +// call_indirect.wast:957 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x11\x94\x98\xdb\xe2\x03\x00\x0b"); + +// call_indirect.wast:968 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x02\x02\x09\x88\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x02\x00\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/comments.wast.js b/js/src/jit-test/tests/wasm/spec/spec/comments.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/comments.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/comments.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/const.wast.js b/js/src/jit-test/tests/wasm/spec/spec/const.wast.js new file mode 100644 index 0000000000..0ee4c4c622 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/const.wast.js @@ -0,0 +1,2334 @@ + +// const.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x95\x9a\xef\x3a\x1a\x0b"); + +// const.wast:6 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\xdf\xf7\xbf\xd6\x79\x1a\x0b"); + +// const.wast:7 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:11 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:15 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:19 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:24 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x42\x95\x9a\xef\x3a\x1a\x0b"); + +// const.wast:25 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x42\xef\xf9\xbe\xef\x9a\xf1\xd9\x92\x01\x1a\x0b"); + +// const.wast:26 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:30 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:34 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:38 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:43 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xa3\x79\xeb\x4c\x1a\x0b"); + +// const.wast:44 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:45 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:46 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\x2f\x59\x2d\x1a\x0b"); + +// const.wast:47 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xa3\x79\xeb\x4c\x1a\x0b"); + +// const.wast:48 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:49 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:50 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\x2f\x59\x2d\x1a\x0b"); + +// const.wast:51 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xa3\x79\xeb\x4c\x1a\x0b"); + +// const.wast:52 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:53 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x7b\x4d\x7f\x6c\x1a\x0b"); + +// const.wast:54 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\x2f\x59\x2d\x1a\x0b"); + +// const.wast:55 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x91\x5b\x1a\x0b"); + +// const.wast:56 +let $18 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:57 +let $19 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:58 +let $20 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x52\x1a\x0b"); + +// const.wast:59 +let $21 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x91\x5b\x1a\x0b"); + +// const.wast:60 +let $22 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:61 +let $23 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:62 +let $24 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x52\x1a\x0b"); + +// const.wast:63 +let $25 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x91\x5b\x1a\x0b"); + +// const.wast:64 +let $26 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:65 +let $27 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x65\x1a\x0b"); + +// const.wast:66 +let $28 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xb4\xa2\x11\x52\x1a\x0b"); + +// const.wast:67 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:71 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:75 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:79 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:83 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:87 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:91 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:95 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:99 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:103 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:107 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:111 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:115 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:119 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:123 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:127 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:131 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:135 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:139 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:145 +let $29 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:146 +let $30 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:147 +let $31 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:148 +let $32 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x11\x43\x2b\xd6\xff\x25\xab\x3d\x1a\x0b"); + +// const.wast:149 +let $33 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:150 +let $34 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:151 +let $35 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:152 +let $36 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x11\x43\x2b\xd6\xff\x25\xab\x3d\x1a\x0b"); + +// const.wast:153 +let $37 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x58\xa4\x0c\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:154 +let $38 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xd5\xcb\x6b\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:155 +let $39 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xd5\xcb\x6b\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:156 +let $40 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x12\xec\x36\xd6\xff\x25\xab\x3d\x1a\x0b"); + +// const.wast:157 +let $41 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:158 +let $42 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:159 +let $43 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x58\xa4\x0c\x54\x34\x6f\x9d\x41\x1a\x0b"); + +// const.wast:160 +let $44 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:161 +let $45 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xfa\x16\x5e\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:162 +let $46 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xd5\xcb\x6b\x5b\xaf\xe9\x8f\x45\x1a\x0b"); + +// const.wast:164 +let $47 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:165 +let $48 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:166 +let $49 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:167 +let $50 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xc2\x43\x1a\x0b"); + +// const.wast:168 +let $51 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:169 +let $52 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:170 +let $53 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:171 +let $54 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xc2\x43\x1a\x0b"); + +// const.wast:172 +let $55 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:173 +let $56 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:174 +let $57 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:175 +let $58 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xc2\x43\x1a\x0b"); + +// const.wast:176 +let $59 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:177 +let $60 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:178 +let $61 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\xf2\x44\x1a\x0b"); + +// const.wast:179 +let $62 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:180 +let $63 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:181 +let $64 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xdf\xbc\x9a\x78\x56\x34\x22\x46\x1a\x0b"); + +// const.wast:184 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:188 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:192 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:196 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:200 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:204 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:208 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:212 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:216 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:220 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:224 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:228 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:232 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:236 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:240 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:244 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:248 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:252 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:256 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:264 +let $65 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x7f\x1a\x0b"); + +// const.wast:265 +let $66 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x80\x80\x80\x80\x78\x1a\x0b"); + +// const.wast:266 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:270 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:275 +let $67 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x7f\x1a\x0b"); + +// const.wast:276 +let $68 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x80\x80\x80\x80\x78\x1a\x0b"); + +// const.wast:277 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:281 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:286 +let $69 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x7f\x1a\x0b"); + +// const.wast:287 +let $70 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x1a\x0b"); + +// const.wast:288 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:292 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:297 +let $71 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x7f\x1a\x0b"); + +// const.wast:298 +let $72 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x1a\x0b"); + +// const.wast:299 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:303 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:308 +let $73 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x00\x00\x00\x7f\x1a\x0b"); + +// const.wast:309 +let $74 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x00\x00\x00\xff\x1a\x0b"); + +// const.wast:310 +let $75 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x1a\x0b"); + +// const.wast:311 +let $76 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x1a\x0b"); + +// const.wast:312 +let $77 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x1a\x0b"); + +// const.wast:313 +let $78 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x1a\x0b"); + +// const.wast:314 +let $79 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x1a\x0b"); + +// const.wast:315 +let $80 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x1a\x0b"); + +// const.wast:316 +let $81 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x1a\x0b"); + +// const.wast:317 +let $82 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x1a\x0b"); + +// const.wast:318 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:322 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:326 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:330 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:335 +let $83 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x99\x76\x96\x7e\x1a\x0b"); + +// const.wast:336 +let $84 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x99\x76\x96\xfe\x1a\x0b"); + +// const.wast:337 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:341 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:346 +let $85 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x1a\x0b"); + +// const.wast:347 +let $86 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x1a\x0b"); + +// const.wast:348 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:352 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:357 +let $87 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xe0\x7f\x1a\x0b"); + +// const.wast:358 +let $88 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xe0\xff\x1a\x0b"); + +// const.wast:359 +let $89 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x1a\x0b"); + +// const.wast:360 +let $90 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x1a\x0b"); + +// const.wast:361 +let $91 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x1a\x0b"); + +// const.wast:362 +let $92 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x1a\x0b"); + +// const.wast:363 +let $93 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x1a\x0b"); + +// const.wast:364 +let $94 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x1a\x0b"); + +// const.wast:365 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:369 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:373 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:377 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:382 +let $95 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xa0\xc8\xeb\x85\xf3\xcc\xe1\x7f\x1a\x0b"); + +// const.wast:383 +let $96 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xa0\xc8\xeb\x85\xf3\xcc\xe1\xff\x1a\x0b"); + +// const.wast:384 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:388 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:393 +let $97 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x1a\x0b"); + +// const.wast:394 +let $98 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x1a\x0b"); + +// const.wast:395 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:399 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:404 +let $99 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x01\x00\x80\x7f\x1a\x0b"); + +// const.wast:405 +let $100 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\xf0\x7f\x1a\x0b"); + +// const.wast:406 +let $101 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\xff\xff\xff\x7f\x1a\x0b"); + +// const.wast:407 +let $102 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xff\x7f\x1a\x0b"); + +// const.wast:409 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:413 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:418 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:422 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:427 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:431 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// const.wast:440 +let $103 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x26\x0b"); + +// const.wast:441 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$103", $103)), "run", [])); // assert_return(() => call($103, "f", []), 8.881784197e-16) + +// const.wast:442 +let $104 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xa6\x0b"); + +// const.wast:443 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$104", $104)), "run", [])); // assert_return(() => call($104, "f", []), -8.881784197e-16) + +// const.wast:444 +let $105 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:445 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$105", $105)), "run", [])); // assert_return(() => call($105, "f", []), 8.88178525579e-16) + +// const.wast:446 +let $106 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:447 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$106", $106)), "run", [])); // assert_return(() => call($106, "f", []), -8.88178525579e-16) + +// const.wast:448 +let $107 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:449 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$107", $107)), "run", [])); // assert_return(() => call($107, "f", []), 8.88178525579e-16) + +// const.wast:450 +let $108 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:451 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$108", $108)), "run", [])); // assert_return(() => call($108, "f", []), -8.88178525579e-16) + +// const.wast:452 +let $109 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:453 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x30\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$109", $109)), "run", [])); // assert_return(() => call($109, "f", []), 8.88178525579e-16) + +// const.wast:454 +let $110 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:455 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$110", $110)), "run", [])); // assert_return(() => call($110, "f", []), -8.88178525579e-16) + +// const.wast:456 +let $111 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:457 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$111", $111)), "run", [])); // assert_return(() => call($111, "f", []), 8.88178525579e-16) + +// const.wast:458 +let $112 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:459 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$112", $112)), "run", [])); // assert_return(() => call($112, "f", []), -8.88178525579e-16) + +// const.wast:460 +let $113 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:461 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$113", $113)), "run", [])); // assert_return(() => call($113, "f", []), 8.88178525579e-16) + +// const.wast:462 +let $114 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:463 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$114", $114)), "run", [])); // assert_return(() => call($114, "f", []), -8.88178525579e-16) + +// const.wast:464 +let $115 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:465 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$115", $115)), "run", [])); // assert_return(() => call($115, "f", []), 8.88178631458e-16) + +// const.wast:466 +let $116 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:467 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$116", $116)), "run", [])); // assert_return(() => call($116, "f", []), -8.88178631458e-16) + +// const.wast:468 +let $117 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:469 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$117", $117)), "run", [])); // assert_return(() => call($117, "f", []), 8.88178631458e-16) + +// const.wast:470 +let $118 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:471 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$118", $118)), "run", [])); // assert_return(() => call($118, "f", []), -8.88178631458e-16) + +// const.wast:472 +let $119 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:473 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x31\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$119", $119)), "run", [])); // assert_return(() => call($119, "f", []), 8.88178631458e-16) + +// const.wast:474 +let $120 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:475 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$120", $120)), "run", [])); // assert_return(() => call($120, "f", []), -8.88178631458e-16) + +// const.wast:476 +let $121 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$121", $121)), "run", [])); // assert_return(() => call($121, "f", []), 8.88178631458e-16) + +// const.wast:478 +let $122 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:479 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$122", $122)), "run", [])); // assert_return(() => call($122, "f", []), -8.88178631458e-16) + +// const.wast:480 +let $123 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:481 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$123", $123)), "run", [])); // assert_return(() => call($123, "f", []), 8.88178631458e-16) + +// const.wast:482 +let $124 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:483 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$124", $124)), "run", [])); // assert_return(() => call($124, "f", []), -8.88178631458e-16) + +// const.wast:484 +let $125 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:485 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$125", $125)), "run", [])); // assert_return(() => call($125, "f", []), 8.88178631458e-16) + +// const.wast:486 +let $126 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:487 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$126", $126)), "run", [])); // assert_return(() => call($126, "f", []), -8.88178631458e-16) + +// const.wast:488 +let $127 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:489 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$127", $127)), "run", [])); // assert_return(() => call($127, "f", []), 8.88178631458e-16) + +// const.wast:490 +let $128 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:491 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$128", $128)), "run", [])); // assert_return(() => call($128, "f", []), -8.88178631458e-16) + +// const.wast:492 +let $129 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\x26\x0b"); + +// const.wast:493 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x32\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$129", $129)), "run", [])); // assert_return(() => call($129, "f", []), 8.88178737337e-16) + +// const.wast:494 +let $130 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\xa6\x0b"); + +// const.wast:495 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$130", $130)), "run", [])); // assert_return(() => call($130, "f", []), -8.88178737337e-16) + +// const.wast:497 +let $131 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x26\x0b"); + +// const.wast:498 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$131", $131)), "run", [])); // assert_return(() => call($131, "f", []), 8.881784197e-16) + +// const.wast:499 +let $132 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xa6\x0b"); + +// const.wast:500 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$132", $132)), "run", [])); // assert_return(() => call($132, "f", []), -8.881784197e-16) + +// const.wast:501 +let $133 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:502 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$133", $133)), "run", [])); // assert_return(() => call($133, "f", []), 8.88178525579e-16) + +// const.wast:503 +let $134 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:504 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$134", $134)), "run", [])); // assert_return(() => call($134, "f", []), -8.88178525579e-16) + +// const.wast:505 +let $135 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:506 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$135", $135)), "run", [])); // assert_return(() => call($135, "f", []), 8.88178525579e-16) + +// const.wast:507 +let $136 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:508 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$136", $136)), "run", [])); // assert_return(() => call($136, "f", []), -8.88178525579e-16) + +// const.wast:509 +let $137 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:510 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$137", $137)), "run", [])); // assert_return(() => call($137, "f", []), 8.88178525579e-16) + +// const.wast:511 +let $138 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:512 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$138", $138)), "run", [])); // assert_return(() => call($138, "f", []), -8.88178525579e-16) + +// const.wast:513 +let $139 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:514 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x33\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$139", $139)), "run", [])); // assert_return(() => call($139, "f", []), 8.88178525579e-16) + +// const.wast:515 +let $140 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:516 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$140", $140)), "run", [])); // assert_return(() => call($140, "f", []), -8.88178525579e-16) + +// const.wast:517 +let $141 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:518 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$141", $141)), "run", [])); // assert_return(() => call($141, "f", []), 8.88178525579e-16) + +// const.wast:519 +let $142 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:520 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$142", $142)), "run", [])); // assert_return(() => call($142, "f", []), -8.88178525579e-16) + +// const.wast:521 +let $143 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:522 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$143", $143)), "run", [])); // assert_return(() => call($143, "f", []), 8.88178631458e-16) + +// const.wast:523 +let $144 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:524 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$144", $144)), "run", [])); // assert_return(() => call($144, "f", []), -8.88178631458e-16) + +// const.wast:525 +let $145 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:526 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$145", $145)), "run", [])); // assert_return(() => call($145, "f", []), 8.88178631458e-16) + +// const.wast:527 +let $146 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:528 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$146", $146)), "run", [])); // assert_return(() => call($146, "f", []), -8.88178631458e-16) + +// const.wast:529 +let $147 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:530 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$147", $147)), "run", [])); // assert_return(() => call($147, "f", []), 8.88178631458e-16) + +// const.wast:531 +let $148 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:532 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$148", $148)), "run", [])); // assert_return(() => call($148, "f", []), -8.88178631458e-16) + +// const.wast:533 +let $149 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:534 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x34\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$149", $149)), "run", [])); // assert_return(() => call($149, "f", []), 8.88178631458e-16) + +// const.wast:535 +let $150 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:536 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$150", $150)), "run", [])); // assert_return(() => call($150, "f", []), -8.88178631458e-16) + +// const.wast:537 +let $151 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:538 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$151", $151)), "run", [])); // assert_return(() => call($151, "f", []), 8.88178631458e-16) + +// const.wast:539 +let $152 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:540 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$152", $152)), "run", [])); // assert_return(() => call($152, "f", []), -8.88178631458e-16) + +// const.wast:541 +let $153 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\x26\x0b"); + +// const.wast:542 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$153", $153)), "run", [])); // assert_return(() => call($153, "f", []), 8.88178737337e-16) + +// const.wast:543 +let $154 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\xa6\x0b"); + +// const.wast:544 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$154", $154)), "run", [])); // assert_return(() => call($154, "f", []), -8.88178737337e-16) + +// const.wast:546 +let $155 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x26\x0b"); + +// const.wast:547 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$155", $155)), "run", [])); // assert_return(() => call($155, "f", []), 8.881784197e-16) + +// const.wast:548 +let $156 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xa6\x0b"); + +// const.wast:549 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$156", $156)), "run", [])); // assert_return(() => call($156, "f", []), -8.881784197e-16) + +// const.wast:550 +let $157 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:551 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$157", $157)), "run", [])); // assert_return(() => call($157, "f", []), 8.88178525579e-16) + +// const.wast:552 +let $158 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:553 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$158", $158)), "run", [])); // assert_return(() => call($158, "f", []), -8.88178525579e-16) + +// const.wast:554 +let $159 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x26\x0b"); + +// const.wast:555 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x35\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$159", $159)), "run", [])); // assert_return(() => call($159, "f", []), 8.88178525579e-16) + +// const.wast:556 +let $160 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xa6\x0b"); + +// const.wast:557 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$160", $160)), "run", [])); // assert_return(() => call($160, "f", []), -8.88178525579e-16) + +// const.wast:558 +let $161 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x26\x0b"); + +// const.wast:559 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x26\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$161", $161)), "run", [])); // assert_return(() => call($161, "f", []), 8.88178631458e-16) + +// const.wast:560 +let $162 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xa6\x0b"); + +// const.wast:561 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xa6\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$162", $162)), "run", [])); // assert_return(() => call($162, "f", []), -8.88178631458e-16) + +// const.wast:564 +let $163 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x58\x0b"); + +// const.wast:565 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$163", $163)), "run", [])); // assert_return(() => call($163, "f", []), 1.12589990684e+15) + +// const.wast:566 +let $164 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xd8\x0b"); + +// const.wast:567 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$164", $164)), "run", [])); // assert_return(() => call($164, "f", []), -1.12589990684e+15) + +// const.wast:568 +let $165 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:569 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$165", $165)), "run", [])); // assert_return(() => call($165, "f", []), 1.12590004106e+15) + +// const.wast:570 +let $166 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:571 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$166", $166)), "run", [])); // assert_return(() => call($166, "f", []), -1.12590004106e+15) + +// const.wast:572 +let $167 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:573 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$167", $167)), "run", [])); // assert_return(() => call($167, "f", []), 1.12590004106e+15) + +// const.wast:574 +let $168 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:575 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$168", $168)), "run", [])); // assert_return(() => call($168, "f", []), -1.12590004106e+15) + +// const.wast:576 +let $169 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:577 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x36\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$169", $169)), "run", [])); // assert_return(() => call($169, "f", []), 1.12590004106e+15) + +// const.wast:578 +let $170 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:579 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$170", $170)), "run", [])); // assert_return(() => call($170, "f", []), -1.12590004106e+15) + +// const.wast:580 +let $171 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:581 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$171", $171)), "run", [])); // assert_return(() => call($171, "f", []), 1.12590004106e+15) + +// const.wast:582 +let $172 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:583 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$172", $172)), "run", [])); // assert_return(() => call($172, "f", []), -1.12590004106e+15) + +// const.wast:584 +let $173 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:585 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$173", $173)), "run", [])); // assert_return(() => call($173, "f", []), 1.12590004106e+15) + +// const.wast:586 +let $174 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:587 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$174", $174)), "run", [])); // assert_return(() => call($174, "f", []), -1.12590004106e+15) + +// const.wast:588 +let $175 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:589 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$175", $175)), "run", [])); // assert_return(() => call($175, "f", []), 1.12590017528e+15) + +// const.wast:590 +let $176 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:591 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$176", $176)), "run", [])); // assert_return(() => call($176, "f", []), -1.12590017528e+15) + +// const.wast:592 +let $177 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:593 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$177", $177)), "run", [])); // assert_return(() => call($177, "f", []), 1.12590017528e+15) + +// const.wast:594 +let $178 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:595 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$178", $178)), "run", [])); // assert_return(() => call($178, "f", []), -1.12590017528e+15) + +// const.wast:596 +let $179 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:597 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x37\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$179", $179)), "run", [])); // assert_return(() => call($179, "f", []), 1.12590017528e+15) + +// const.wast:598 +let $180 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:599 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$180", $180)), "run", [])); // assert_return(() => call($180, "f", []), -1.12590017528e+15) + +// const.wast:600 +let $181 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:601 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$181", $181)), "run", [])); // assert_return(() => call($181, "f", []), 1.12590017528e+15) + +// const.wast:602 +let $182 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:603 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$182", $182)), "run", [])); // assert_return(() => call($182, "f", []), -1.12590017528e+15) + +// const.wast:604 +let $183 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:605 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$183", $183)), "run", [])); // assert_return(() => call($183, "f", []), 1.12590017528e+15) + +// const.wast:606 +let $184 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:607 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$184", $184)), "run", [])); // assert_return(() => call($184, "f", []), -1.12590017528e+15) + +// const.wast:608 +let $185 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:609 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$185", $185)), "run", [])); // assert_return(() => call($185, "f", []), 1.12590017528e+15) + +// const.wast:610 +let $186 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:611 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$186", $186)), "run", [])); // assert_return(() => call($186, "f", []), -1.12590017528e+15) + +// const.wast:612 +let $187 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:613 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$187", $187)), "run", [])); // assert_return(() => call($187, "f", []), 1.12590017528e+15) + +// const.wast:614 +let $188 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:615 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$188", $188)), "run", [])); // assert_return(() => call($188, "f", []), -1.12590017528e+15) + +// const.wast:616 +let $189 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\x58\x0b"); + +// const.wast:617 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x38\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$189", $189)), "run", [])); // assert_return(() => call($189, "f", []), 1.1259003095e+15) + +// const.wast:618 +let $190 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x80\xd8\x0b"); + +// const.wast:619 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$190", $190)), "run", [])); // assert_return(() => call($190, "f", []), -1.1259003095e+15) + +// const.wast:621 +let $191 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x58\x0b"); + +// const.wast:622 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$191", $191)), "run", [])); // assert_return(() => call($191, "f", []), 1.12589990684e+15) + +// const.wast:623 +let $192 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xd8\x0b"); + +// const.wast:624 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$192", $192)), "run", [])); // assert_return(() => call($192, "f", []), -1.12589990684e+15) + +// const.wast:625 +let $193 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:626 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$193", $193)), "run", [])); // assert_return(() => call($193, "f", []), 1.12590004106e+15) + +// const.wast:627 +let $194 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:628 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$194", $194)), "run", [])); // assert_return(() => call($194, "f", []), -1.12590004106e+15) + +// const.wast:629 +let $195 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:630 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$195", $195)), "run", [])); // assert_return(() => call($195, "f", []), 1.12590004106e+15) + +// const.wast:631 +let $196 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:632 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$196", $196)), "run", [])); // assert_return(() => call($196, "f", []), -1.12590004106e+15) + +// const.wast:633 +let $197 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:634 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$197", $197)), "run", [])); // assert_return(() => call($197, "f", []), 1.12590004106e+15) + +// const.wast:635 +let $198 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:636 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$198", $198)), "run", [])); // assert_return(() => call($198, "f", []), -1.12590004106e+15) + +// const.wast:637 +let $199 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:638 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x31\x39\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$199", $199)), "run", [])); // assert_return(() => call($199, "f", []), 1.12590004106e+15) + +// const.wast:639 +let $200 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:640 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$200", $200)), "run", [])); // assert_return(() => call($200, "f", []), -1.12590004106e+15) + +// const.wast:641 +let $201 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:642 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$201", $201)), "run", [])); // assert_return(() => call($201, "f", []), 1.12590004106e+15) + +// const.wast:643 +let $202 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:644 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$202", $202)), "run", [])); // assert_return(() => call($202, "f", []), -1.12590004106e+15) + +// const.wast:645 +let $203 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:646 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$203", $203)), "run", [])); // assert_return(() => call($203, "f", []), 1.12590017528e+15) + +// const.wast:647 +let $204 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:648 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$204", $204)), "run", [])); // assert_return(() => call($204, "f", []), -1.12590017528e+15) + +// const.wast:650 +let $205 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\x58\x0b"); + +// const.wast:651 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$205", $205)), "run", [])); // assert_return(() => call($205, "f", []), 1.12589990684e+15) + +// const.wast:652 +let $206 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x80\xd8\x0b"); + +// const.wast:653 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$206", $206)), "run", [])); // assert_return(() => call($206, "f", []), -1.12589990684e+15) + +// const.wast:654 +let $207 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:655 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$207", $207)), "run", [])); // assert_return(() => call($207, "f", []), 1.12590004106e+15) + +// const.wast:656 +let $208 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:657 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$208", $208)), "run", [])); // assert_return(() => call($208, "f", []), -1.12590004106e+15) + +// const.wast:658 +let $209 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\x58\x0b"); + +// const.wast:659 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x30\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$209", $209)), "run", [])); // assert_return(() => call($209, "f", []), 1.12590004106e+15) + +// const.wast:660 +let $210 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x80\xd8\x0b"); + +// const.wast:661 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$210", $210)), "run", [])); // assert_return(() => call($210, "f", []), -1.12590004106e+15) + +// const.wast:662 +let $211 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\x58\x0b"); + +// const.wast:663 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\x58\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$211", $211)), "run", [])); // assert_return(() => call($211, "f", []), 1.12590017528e+15) + +// const.wast:664 +let $212 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x80\xd8\x0b"); + +// const.wast:665 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x80\xd8\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$212", $212)), "run", [])); // assert_return(() => call($212, "f", []), -1.12590017528e+15) + +// const.wast:668 +let $213 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x0b"); + +// const.wast:669 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$213", $213)), "run", [])); // assert_return(() => call($213, "f", []), 0.) + +// const.wast:670 +let $214 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x00\x80\x0b"); + +// const.wast:671 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$214", $214)), "run", [])); // assert_return(() => call($214, "f", []), -0.) + +// const.wast:672 +let $215 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x00\x0b"); + +// const.wast:673 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$215", $215)), "run", [])); // assert_return(() => call($215, "f", []), 1.40129846432e-45) + +// const.wast:674 +let $216 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x80\x0b"); + +// const.wast:675 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$216", $216)), "run", [])); // assert_return(() => call($216, "f", []), -1.40129846432e-45) + +// const.wast:676 +let $217 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x00\x0b"); + +// const.wast:677 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$217", $217)), "run", [])); // assert_return(() => call($217, "f", []), 1.40129846432e-45) + +// const.wast:678 +let $218 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x80\x0b"); + +// const.wast:679 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$218", $218)), "run", [])); // assert_return(() => call($218, "f", []), -1.40129846432e-45) + +// const.wast:680 +let $219 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x00\x0b"); + +// const.wast:681 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x31\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$219", $219)), "run", [])); // assert_return(() => call($219, "f", []), 1.40129846432e-45) + +// const.wast:682 +let $220 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x80\x0b"); + +// const.wast:683 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$220", $220)), "run", [])); // assert_return(() => call($220, "f", []), -1.40129846432e-45) + +// const.wast:684 +let $221 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x00\x0b"); + +// const.wast:685 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$221", $221)), "run", [])); // assert_return(() => call($221, "f", []), 1.40129846432e-45) + +// const.wast:686 +let $222 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x80\x0b"); + +// const.wast:687 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$222", $222)), "run", [])); // assert_return(() => call($222, "f", []), -1.40129846432e-45) + +// const.wast:688 +let $223 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x00\x0b"); + +// const.wast:689 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$223", $223)), "run", [])); // assert_return(() => call($223, "f", []), 1.40129846432e-45) + +// const.wast:690 +let $224 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x01\x00\x00\x80\x0b"); + +// const.wast:691 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$224", $224)), "run", [])); // assert_return(() => call($224, "f", []), -1.40129846432e-45) + +// const.wast:692 +let $225 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:693 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$225", $225)), "run", [])); // assert_return(() => call($225, "f", []), 2.80259692865e-45) + +// const.wast:694 +let $226 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:695 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$226", $226)), "run", [])); // assert_return(() => call($226, "f", []), -2.80259692865e-45) + +// const.wast:696 +let $227 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:697 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$227", $227)), "run", [])); // assert_return(() => call($227, "f", []), 2.80259692865e-45) + +// const.wast:698 +let $228 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:699 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$228", $228)), "run", [])); // assert_return(() => call($228, "f", []), -2.80259692865e-45) + +// const.wast:700 +let $229 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:701 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x32\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$229", $229)), "run", [])); // assert_return(() => call($229, "f", []), 2.80259692865e-45) + +// const.wast:702 +let $230 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:703 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$230", $230)), "run", [])); // assert_return(() => call($230, "f", []), -2.80259692865e-45) + +// const.wast:704 +let $231 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:705 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$231", $231)), "run", [])); // assert_return(() => call($231, "f", []), 2.80259692865e-45) + +// const.wast:706 +let $232 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:707 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$232", $232)), "run", [])); // assert_return(() => call($232, "f", []), -2.80259692865e-45) + +// const.wast:708 +let $233 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:709 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$233", $233)), "run", [])); // assert_return(() => call($233, "f", []), 2.80259692865e-45) + +// const.wast:710 +let $234 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:711 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$234", $234)), "run", [])); // assert_return(() => call($234, "f", []), -2.80259692865e-45) + +// const.wast:712 +let $235 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:713 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$235", $235)), "run", [])); // assert_return(() => call($235, "f", []), 2.80259692865e-45) + +// const.wast:714 +let $236 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:715 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$236", $236)), "run", [])); // assert_return(() => call($236, "f", []), -2.80259692865e-45) + +// const.wast:716 +let $237 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x00\x0b"); + +// const.wast:717 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$237", $237)), "run", [])); // assert_return(() => call($237, "f", []), 2.80259692865e-45) + +// const.wast:718 +let $238 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x02\x00\x00\x80\x0b"); + +// const.wast:719 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x02\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$238", $238)), "run", [])); // assert_return(() => call($238, "f", []), -2.80259692865e-45) + +// const.wast:720 +let $239 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x00\x00\x0b"); + +// const.wast:721 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x33\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$239", $239)), "run", [])); // assert_return(() => call($239, "f", []), 4.20389539297e-45) + +// const.wast:722 +let $240 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x03\x00\x00\x80\x0b"); + +// const.wast:723 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x03\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$240", $240)), "run", [])); // assert_return(() => call($240, "f", []), -4.20389539297e-45) + +// const.wast:726 +let $241 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x0b"); + +// const.wast:727 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$241", $241)), "run", [])); // assert_return(() => call($241, "f", []), 3.40282346639e+38) + +// const.wast:728 +let $242 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x0b"); + +// const.wast:729 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$242", $242)), "run", [])); // assert_return(() => call($242, "f", []), -3.40282346639e+38) + +// const.wast:730 +let $243 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x0b"); + +// const.wast:731 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$243", $243)), "run", [])); // assert_return(() => call($243, "f", []), 3.40282346639e+38) + +// const.wast:732 +let $244 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x0b"); + +// const.wast:733 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$244", $244)), "run", [])); // assert_return(() => call($244, "f", []), -3.40282346639e+38) + +// const.wast:734 +let $245 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\x7f\x0b"); + +// const.wast:735 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$245", $245)), "run", [])); // assert_return(() => call($245, "f", []), 3.40282346639e+38) + +// const.wast:736 +let $246 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\xff\xff\x7f\xff\x0b"); + +// const.wast:737 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$246", $246)), "run", [])); // assert_return(() => call($246, "f", []), -3.40282346639e+38) + +// const.wast:740 +let $247 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:741 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$247", $247)), "run", [])); // assert_return(() => call($247, "f", []), 2.4099198651e-181) + +// const.wast:742 +let $248 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:743 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$248", $248)), "run", [])); // assert_return(() => call($248, "f", []), -2.4099198651e-181) + +// const.wast:744 +let $249 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:745 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x34\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$249", $249)), "run", [])); // assert_return(() => call($249, "f", []), 2.4099198651e-181) + +// const.wast:746 +let $250 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:747 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$250", $250)), "run", [])); // assert_return(() => call($250, "f", []), -2.4099198651e-181) + +// const.wast:748 +let $251 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:749 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$251", $251)), "run", [])); // assert_return(() => call($251, "f", []), 2.4099198651e-181) + +// const.wast:750 +let $252 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:751 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$252", $252)), "run", [])); // assert_return(() => call($252, "f", []), -2.4099198651e-181) + +// const.wast:752 +let $253 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:753 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$253", $253)), "run", [])); // assert_return(() => call($253, "f", []), 2.4099198651e-181) + +// const.wast:754 +let $254 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:755 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$254", $254)), "run", [])); // assert_return(() => call($254, "f", []), -2.4099198651e-181) + +// const.wast:756 +let $255 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:757 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$255", $255)), "run", [])); // assert_return(() => call($255, "f", []), 2.4099198651e-181) + +// const.wast:758 +let $256 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:759 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$256", $256)), "run", [])); // assert_return(() => call($256, "f", []), -2.4099198651e-181) + +// const.wast:760 +let $257 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:761 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$257", $257)), "run", [])); // assert_return(() => call($257, "f", []), 2.4099198651e-181) + +// const.wast:762 +let $258 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:763 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$258", $258)), "run", [])); // assert_return(() => call($258, "f", []), -2.4099198651e-181) + +// const.wast:764 +let $259 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:765 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x35\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$259", $259)), "run", [])); // assert_return(() => call($259, "f", []), 2.4099198651e-181) + +// const.wast:766 +let $260 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:767 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$260", $260)), "run", [])); // assert_return(() => call($260, "f", []), -2.4099198651e-181) + +// const.wast:768 +let $261 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:769 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$261", $261)), "run", [])); // assert_return(() => call($261, "f", []), 2.4099198651e-181) + +// const.wast:770 +let $262 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:771 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$262", $262)), "run", [])); // assert_return(() => call($262, "f", []), -2.4099198651e-181) + +// const.wast:772 +let $263 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:773 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$263", $263)), "run", [])); // assert_return(() => call($263, "f", []), 2.4099198651e-181) + +// const.wast:774 +let $264 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:775 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$264", $264)), "run", [])); // assert_return(() => call($264, "f", []), -2.4099198651e-181) + +// const.wast:776 +let $265 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:777 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$265", $265)), "run", [])); // assert_return(() => call($265, "f", []), 2.4099198651e-181) + +// const.wast:778 +let $266 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:779 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$266", $266)), "run", [])); // assert_return(() => call($266, "f", []), -2.4099198651e-181) + +// const.wast:780 +let $267 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:781 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$267", $267)), "run", [])); // assert_return(() => call($267, "f", []), 2.4099198651e-181) + +// const.wast:782 +let $268 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:783 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$268", $268)), "run", [])); // assert_return(() => call($268, "f", []), -2.4099198651e-181) + +// const.wast:784 +let $269 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:785 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x36\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$269", $269)), "run", [])); // assert_return(() => call($269, "f", []), 2.4099198651e-181) + +// const.wast:786 +let $270 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:787 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$270", $270)), "run", [])); // assert_return(() => call($270, "f", []), -2.4099198651e-181) + +// const.wast:788 +let $271 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:789 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$271", $271)), "run", [])); // assert_return(() => call($271, "f", []), 2.4099198651e-181) + +// const.wast:790 +let $272 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:791 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$272", $272)), "run", [])); // assert_return(() => call($272, "f", []), -2.4099198651e-181) + +// const.wast:793 +let $273 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:794 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$273", $273)), "run", [])); // assert_return(() => call($273, "f", []), 2.4099198651e-181) + +// const.wast:795 +let $274 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:796 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$274", $274)), "run", [])); // assert_return(() => call($274, "f", []), -2.4099198651e-181) + +// const.wast:797 +let $275 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:798 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$275", $275)), "run", [])); // assert_return(() => call($275, "f", []), 2.4099198651e-181) + +// const.wast:799 +let $276 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:800 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$276", $276)), "run", [])); // assert_return(() => call($276, "f", []), -2.4099198651e-181) + +// const.wast:801 +let $277 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:802 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$277", $277)), "run", [])); // assert_return(() => call($277, "f", []), 2.4099198651e-181) + +// const.wast:803 +let $278 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:804 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$278", $278)), "run", [])); // assert_return(() => call($278, "f", []), -2.4099198651e-181) + +// const.wast:805 +let $279 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:806 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x37\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$279", $279)), "run", [])); // assert_return(() => call($279, "f", []), 2.4099198651e-181) + +// const.wast:807 +let $280 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:808 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$280", $280)), "run", [])); // assert_return(() => call($280, "f", []), -2.4099198651e-181) + +// const.wast:809 +let $281 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:810 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$281", $281)), "run", [])); // assert_return(() => call($281, "f", []), 2.4099198651e-181) + +// const.wast:811 +let $282 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:812 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$282", $282)), "run", [])); // assert_return(() => call($282, "f", []), -2.4099198651e-181) + +// const.wast:813 +let $283 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:814 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$283", $283)), "run", [])); // assert_return(() => call($283, "f", []), 2.4099198651e-181) + +// const.wast:815 +let $284 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:816 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$284", $284)), "run", [])); // assert_return(() => call($284, "f", []), -2.4099198651e-181) + +// const.wast:817 +let $285 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:818 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$285", $285)), "run", [])); // assert_return(() => call($285, "f", []), 2.4099198651e-181) + +// const.wast:819 +let $286 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:820 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$286", $286)), "run", [])); // assert_return(() => call($286, "f", []), -2.4099198651e-181) + +// const.wast:821 +let $287 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:822 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$287", $287)), "run", [])); // assert_return(() => call($287, "f", []), 2.4099198651e-181) + +// const.wast:823 +let $288 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:824 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$288", $288)), "run", [])); // assert_return(() => call($288, "f", []), -2.4099198651e-181) + +// const.wast:825 +let $289 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:826 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x38\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$289", $289)), "run", [])); // assert_return(() => call($289, "f", []), 2.4099198651e-181) + +// const.wast:827 +let $290 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:828 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$290", $290)), "run", [])); // assert_return(() => call($290, "f", []), -2.4099198651e-181) + +// const.wast:829 +let $291 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:830 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$291", $291)), "run", [])); // assert_return(() => call($291, "f", []), 2.4099198651e-181) + +// const.wast:831 +let $292 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:832 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$292", $292)), "run", [])); // assert_return(() => call($292, "f", []), -2.4099198651e-181) + +// const.wast:833 +let $293 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:834 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$293", $293)), "run", [])); // assert_return(() => call($293, "f", []), 2.4099198651e-181) + +// const.wast:835 +let $294 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:836 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$294", $294)), "run", [])); // assert_return(() => call($294, "f", []), -2.4099198651e-181) + +// const.wast:837 +let $295 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:838 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$295", $295)), "run", [])); // assert_return(() => call($295, "f", []), 2.4099198651e-181) + +// const.wast:839 +let $296 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:840 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$296", $296)), "run", [])); // assert_return(() => call($296, "f", []), -2.4099198651e-181) + +// const.wast:841 +let $297 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\x1a\x0b"); + +// const.wast:842 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\x1a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$297", $297)), "run", [])); // assert_return(() => call($297, "f", []), 2.4099198651e-181) + +// const.wast:843 +let $298 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\x9a\x0b"); + +// const.wast:844 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\x9a\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$298", $298)), "run", [])); // assert_return(() => call($298, "f", []), -2.4099198651e-181) + +// const.wast:846 +let $299 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x60\x7e\x0b"); + +// const.wast:847 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x32\x39\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x60\x7e\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$299", $299)), "run", [])); // assert_return(() => call($299, "f", []), 5.35754303593e+300) + +// const.wast:848 +let $300 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x60\xfe\x0b"); + +// const.wast:849 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x60\xfe\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$300", $300)), "run", [])); // assert_return(() => call($300, "f", []), -5.35754303593e+300) + +// const.wast:850 +let $301 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x60\x7e\x0b"); + +// const.wast:851 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x60\x7e\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$301", $301)), "run", [])); // assert_return(() => call($301, "f", []), 5.35754303593e+300) + +// const.wast:852 +let $302 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x60\xfe\x0b"); + +// const.wast:853 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x60\xfe\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$302", $302)), "run", [])); // assert_return(() => call($302, "f", []), -5.35754303593e+300) + +// const.wast:854 +let $303 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x60\x7e\x0b"); + +// const.wast:855 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x60\x7e\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$303", $303)), "run", [])); // assert_return(() => call($303, "f", []), 5.35754303593e+300) + +// const.wast:856 +let $304 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x60\xfe\x0b"); + +// const.wast:857 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x60\xfe\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$304", $304)), "run", [])); // assert_return(() => call($304, "f", []), -5.35754303593e+300) + +// const.wast:858 +let $305 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x60\x7e\x0b"); + +// const.wast:859 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x60\x7e\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$305", $305)), "run", [])); // assert_return(() => call($305, "f", []), 5.35754303593e+300) + +// const.wast:860 +let $306 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x60\xfe\x0b"); + +// const.wast:861 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x60\xfe\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$306", $306)), "run", [])); // assert_return(() => call($306, "f", []), -5.35754303593e+300) + +// const.wast:864 +let $307 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:865 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$307", $307)), "run", [])); // assert_return(() => call($307, "f", []), 4.14951556888e+180) + +// const.wast:866 +let $308 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:867 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$308", $308)), "run", [])); // assert_return(() => call($308, "f", []), -4.14951556888e+180) + +// const.wast:868 +let $309 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:869 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x30\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$309", $309)), "run", [])); // assert_return(() => call($309, "f", []), 4.14951556888e+180) + +// const.wast:870 +let $310 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:871 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$310", $310)), "run", [])); // assert_return(() => call($310, "f", []), -4.14951556888e+180) + +// const.wast:872 +let $311 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:873 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$311", $311)), "run", [])); // assert_return(() => call($311, "f", []), 4.14951556888e+180) + +// const.wast:874 +let $312 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:875 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$312", $312)), "run", [])); // assert_return(() => call($312, "f", []), -4.14951556888e+180) + +// const.wast:876 +let $313 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:877 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$313", $313)), "run", [])); // assert_return(() => call($313, "f", []), 4.14951556888e+180) + +// const.wast:878 +let $314 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:879 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$314", $314)), "run", [])); // assert_return(() => call($314, "f", []), -4.14951556888e+180) + +// const.wast:880 +let $315 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:881 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$315", $315)), "run", [])); // assert_return(() => call($315, "f", []), 4.14951556888e+180) + +// const.wast:882 +let $316 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:883 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$316", $316)), "run", [])); // assert_return(() => call($316, "f", []), -4.14951556888e+180) + +// const.wast:884 +let $317 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:885 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$317", $317)), "run", [])); // assert_return(() => call($317, "f", []), 4.14951556888e+180) + +// const.wast:886 +let $318 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:887 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$318", $318)), "run", [])); // assert_return(() => call($318, "f", []), -4.14951556888e+180) + +// const.wast:888 +let $319 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:889 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x31\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$319", $319)), "run", [])); // assert_return(() => call($319, "f", []), 4.14951556888e+180) + +// const.wast:890 +let $320 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:891 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$320", $320)), "run", [])); // assert_return(() => call($320, "f", []), -4.14951556888e+180) + +// const.wast:892 +let $321 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:893 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$321", $321)), "run", [])); // assert_return(() => call($321, "f", []), 4.14951556888e+180) + +// const.wast:894 +let $322 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:895 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$322", $322)), "run", [])); // assert_return(() => call($322, "f", []), -4.14951556888e+180) + +// const.wast:896 +let $323 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:897 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$323", $323)), "run", [])); // assert_return(() => call($323, "f", []), 4.14951556888e+180) + +// const.wast:898 +let $324 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:899 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$324", $324)), "run", [])); // assert_return(() => call($324, "f", []), -4.14951556888e+180) + +// const.wast:900 +let $325 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:901 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$325", $325)), "run", [])); // assert_return(() => call($325, "f", []), 4.14951556888e+180) + +// const.wast:902 +let $326 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:903 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$326", $326)), "run", [])); // assert_return(() => call($326, "f", []), -4.14951556888e+180) + +// const.wast:904 +let $327 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:905 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$327", $327)), "run", [])); // assert_return(() => call($327, "f", []), 4.14951556888e+180) + +// const.wast:906 +let $328 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:907 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$328", $328)), "run", [])); // assert_return(() => call($328, "f", []), -4.14951556888e+180) + +// const.wast:908 +let $329 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:909 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x32\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$329", $329)), "run", [])); // assert_return(() => call($329, "f", []), 4.14951556888e+180) + +// const.wast:910 +let $330 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:911 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$330", $330)), "run", [])); // assert_return(() => call($330, "f", []), -4.14951556888e+180) + +// const.wast:912 +let $331 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:913 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$331", $331)), "run", [])); // assert_return(() => call($331, "f", []), 4.14951556888e+180) + +// const.wast:914 +let $332 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:915 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$332", $332)), "run", [])); // assert_return(() => call($332, "f", []), -4.14951556888e+180) + +// const.wast:916 +let $333 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\x65\x0b"); + +// const.wast:917 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\x65\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$333", $333)), "run", [])); // assert_return(() => call($333, "f", []), 4.14951556888e+180) + +// const.wast:918 +let $334 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x70\xe5\x0b"); + +// const.wast:919 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x70\xe5\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$334", $334)), "run", [])); // assert_return(() => call($334, "f", []), -4.14951556888e+180) + +// const.wast:921 +let $335 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:922 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$335", $335)), "run", [])); // assert_return(() => call($335, "f", []), 1.58456325029e+29) + +// const.wast:923 +let $336 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:924 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$336", $336)), "run", [])); // assert_return(() => call($336, "f", []), -1.58456325029e+29) + +// const.wast:925 +let $337 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:926 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$337", $337)), "run", [])); // assert_return(() => call($337, "f", []), 1.58456325029e+29) + +// const.wast:927 +let $338 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:928 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$338", $338)), "run", [])); // assert_return(() => call($338, "f", []), -1.58456325029e+29) + +// const.wast:929 +let $339 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:930 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x33\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$339", $339)), "run", [])); // assert_return(() => call($339, "f", []), 1.58456325029e+29) + +// const.wast:931 +let $340 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:932 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$340", $340)), "run", [])); // assert_return(() => call($340, "f", []), -1.58456325029e+29) + +// const.wast:933 +let $341 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:934 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$341", $341)), "run", [])); // assert_return(() => call($341, "f", []), 1.58456325029e+29) + +// const.wast:935 +let $342 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:936 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$342", $342)), "run", [])); // assert_return(() => call($342, "f", []), -1.58456325029e+29) + +// const.wast:937 +let $343 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:938 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$343", $343)), "run", [])); // assert_return(() => call($343, "f", []), 1.58456325029e+29) + +// const.wast:939 +let $344 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:940 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$344", $344)), "run", [])); // assert_return(() => call($344, "f", []), -1.58456325029e+29) + +// const.wast:941 +let $345 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:942 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$345", $345)), "run", [])); // assert_return(() => call($345, "f", []), 1.58456325029e+29) + +// const.wast:943 +let $346 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:944 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$346", $346)), "run", [])); // assert_return(() => call($346, "f", []), -1.58456325029e+29) + +// const.wast:945 +let $347 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:946 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$347", $347)), "run", [])); // assert_return(() => call($347, "f", []), 1.58456325029e+29) + +// const.wast:947 +let $348 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:948 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$348", $348)), "run", [])); // assert_return(() => call($348, "f", []), -1.58456325029e+29) + +// const.wast:949 +let $349 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:950 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x34\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$349", $349)), "run", [])); // assert_return(() => call($349, "f", []), 1.58456325029e+29) + +// const.wast:951 +let $350 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:952 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$350", $350)), "run", [])); // assert_return(() => call($350, "f", []), -1.58456325029e+29) + +// const.wast:953 +let $351 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:954 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$351", $351)), "run", [])); // assert_return(() => call($351, "f", []), 1.58456325029e+29) + +// const.wast:955 +let $352 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:956 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$352", $352)), "run", [])); // assert_return(() => call($352, "f", []), -1.58456325029e+29) + +// const.wast:957 +let $353 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:958 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$353", $353)), "run", [])); // assert_return(() => call($353, "f", []), 1.58456325029e+29) + +// const.wast:959 +let $354 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:960 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$354", $354)), "run", [])); // assert_return(() => call($354, "f", []), -1.58456325029e+29) + +// const.wast:961 +let $355 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:962 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$355", $355)), "run", [])); // assert_return(() => call($355, "f", []), 1.58456325029e+29) + +// const.wast:963 +let $356 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:964 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$356", $356)), "run", [])); // assert_return(() => call($356, "f", []), -1.58456325029e+29) + +// const.wast:965 +let $357 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:966 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$357", $357)), "run", [])); // assert_return(() => call($357, "f", []), 1.58456325029e+29) + +// const.wast:967 +let $358 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:968 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$358", $358)), "run", [])); // assert_return(() => call($358, "f", []), -1.58456325029e+29) + +// const.wast:969 +let $359 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:970 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x35\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$359", $359)), "run", [])); // assert_return(() => call($359, "f", []), 1.58456325029e+29) + +// const.wast:971 +let $360 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:972 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$360", $360)), "run", [])); // assert_return(() => call($360, "f", []), -1.58456325029e+29) + +// const.wast:973 +let $361 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x00\x46\x0b"); + +// const.wast:974 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x00\x46\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$361", $361)), "run", [])); // assert_return(() => call($361, "f", []), 1.58456325029e+29) + +// const.wast:975 +let $362 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x00\xc6\x0b"); + +// const.wast:976 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x00\xc6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$362", $362)), "run", [])); // assert_return(() => call($362, "f", []), -1.58456325029e+29) + +// const.wast:978 +let $363 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xb0\x43\x0b"); + +// const.wast:979 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xb0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$363", $363)), "run", [])); // assert_return(() => call($363, "f", []), 1.15292150461e+18) + +// const.wast:980 +let $364 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xb0\xc3\x0b"); + +// const.wast:981 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xb0\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$364", $364)), "run", [])); // assert_return(() => call($364, "f", []), -1.15292150461e+18) + +// const.wast:982 +let $365 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\xb0\x43\x0b"); + +// const.wast:983 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xb0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$365", $365)), "run", [])); // assert_return(() => call($365, "f", []), 1.15292150461e+18) + +// const.wast:984 +let $366 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\xb0\xc3\x0b"); + +// const.wast:985 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xb0\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$366", $366)), "run", [])); // assert_return(() => call($366, "f", []), -1.15292150461e+18) + +// const.wast:986 +let $367 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\xb0\x43\x0b"); + +// const.wast:987 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xb0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$367", $367)), "run", [])); // assert_return(() => call($367, "f", []), 1.15292150461e+18) + +// const.wast:988 +let $368 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\xb0\xc3\x0b"); + +// const.wast:989 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xb0\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$368", $368)), "run", [])); // assert_return(() => call($368, "f", []), -1.15292150461e+18) + +// const.wast:990 +let $369 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\xb0\x43\x0b"); + +// const.wast:991 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x36\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\xb0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$369", $369)), "run", [])); // assert_return(() => call($369, "f", []), 1.15292150461e+18) + +// const.wast:992 +let $370 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\xb0\xc3\x0b"); + +// const.wast:993 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\xb0\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$370", $370)), "run", [])); // assert_return(() => call($370, "f", []), -1.15292150461e+18) + +// const.wast:996 +let $371 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:997 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$371", $371)), "run", [])); // assert_return(() => call($371, "f", []), 0.) + +// const.wast:998 +let $372 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:999 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$372", $372)), "run", [])); // assert_return(() => call($372, "f", []), -0.) + +// const.wast:1000 +let $373 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1001 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$373", $373)), "run", [])); // assert_return(() => call($373, "f", []), 4.94065645841e-324) + +// const.wast:1002 +let $374 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1003 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$374", $374)), "run", [])); // assert_return(() => call($374, "f", []), -4.94065645841e-324) + +// const.wast:1004 +let $375 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1005 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$375", $375)), "run", [])); // assert_return(() => call($375, "f", []), 4.94065645841e-324) + +// const.wast:1006 +let $376 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1007 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$376", $376)), "run", [])); // assert_return(() => call($376, "f", []), -4.94065645841e-324) + +// const.wast:1008 +let $377 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1009 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$377", $377)), "run", [])); // assert_return(() => call($377, "f", []), 4.94065645841e-324) + +// const.wast:1010 +let $378 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1011 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$378", $378)), "run", [])); // assert_return(() => call($378, "f", []), -4.94065645841e-324) + +// const.wast:1012 +let $379 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1013 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x37\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$379", $379)), "run", [])); // assert_return(() => call($379, "f", []), 4.94065645841e-324) + +// const.wast:1014 +let $380 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1015 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$380", $380)), "run", [])); // assert_return(() => call($380, "f", []), -4.94065645841e-324) + +// const.wast:1016 +let $381 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1017 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$381", $381)), "run", [])); // assert_return(() => call($381, "f", []), 4.94065645841e-324) + +// const.wast:1018 +let $382 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x01\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1019 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$382", $382)), "run", [])); // assert_return(() => call($382, "f", []), -4.94065645841e-324) + +// const.wast:1020 +let $383 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1021 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$383", $383)), "run", [])); // assert_return(() => call($383, "f", []), 9.88131291682e-324) + +// const.wast:1022 +let $384 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1023 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$384", $384)), "run", [])); // assert_return(() => call($384, "f", []), -9.88131291682e-324) + +// const.wast:1024 +let $385 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1025 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$385", $385)), "run", [])); // assert_return(() => call($385, "f", []), 9.88131291682e-324) + +// const.wast:1026 +let $386 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1027 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$386", $386)), "run", [])); // assert_return(() => call($386, "f", []), -9.88131291682e-324) + +// const.wast:1028 +let $387 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1029 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$387", $387)), "run", [])); // assert_return(() => call($387, "f", []), 9.88131291682e-324) + +// const.wast:1030 +let $388 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1031 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$388", $388)), "run", [])); // assert_return(() => call($388, "f", []), -9.88131291682e-324) + +// const.wast:1032 +let $389 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1033 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x38\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$389", $389)), "run", [])); // assert_return(() => call($389, "f", []), 9.88131291682e-324) + +// const.wast:1034 +let $390 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1035 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$390", $390)), "run", [])); // assert_return(() => call($390, "f", []), -9.88131291682e-324) + +// const.wast:1036 +let $391 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1037 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$391", $391)), "run", [])); // assert_return(() => call($391, "f", []), 9.88131291682e-324) + +// const.wast:1038 +let $392 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1039 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$392", $392)), "run", [])); // assert_return(() => call($392, "f", []), -9.88131291682e-324) + +// const.wast:1040 +let $393 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1041 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x33\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$393", $393)), "run", [])); // assert_return(() => call($393, "f", []), 9.88131291682e-324) + +// const.wast:1042 +let $394 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1043 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x34\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$394", $394)), "run", [])); // assert_return(() => call($394, "f", []), -9.88131291682e-324) + +// const.wast:1044 +let $395 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x00\x0b"); + +// const.wast:1045 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x35\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$395", $395)), "run", [])); // assert_return(() => call($395, "f", []), 9.88131291682e-324) + +// const.wast:1046 +let $396 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x02\x00\x00\x00\x00\x00\x00\x80\x0b"); + +// const.wast:1047 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x36\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$396", $396)), "run", [])); // assert_return(() => call($396, "f", []), -9.88131291682e-324) + +// const.wast:1048 +let $397 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x10\x00\x0b"); + +// const.wast:1049 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x37\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x10\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$397", $397)), "run", [])); // assert_return(() => call($397, "f", []), 2.22507385851e-308) + +// const.wast:1050 +let $398 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\x03\x00\x00\x00\x00\x00\x10\x80\x0b"); + +// const.wast:1051 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x38\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x03\x00\x00\x00\x00\x00\x10\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$398", $398)), "run", [])); // assert_return(() => call($398, "f", []), -2.22507385851e-308) + +// const.wast:1054 +let $399 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x0b"); + +// const.wast:1055 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x33\x39\x39\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$399", $399)), "run", [])); // assert_return(() => call($399, "f", []), 1.79769313486e+308) + +// const.wast:1056 +let $400 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x0b"); + +// const.wast:1057 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x34\x30\x30\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$400", $400)), "run", [])); // assert_return(() => call($400, "f", []), -1.79769313486e+308) + +// const.wast:1058 +let $401 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x0b"); + +// const.wast:1059 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x34\x30\x31\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$401", $401)), "run", [])); // assert_return(() => call($401, "f", []), 1.79769313486e+308) + +// const.wast:1060 +let $402 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x07\x85\x80\x80\x80\x00\x01\x01\x66\x00\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x44\xff\xff\xff\xff\xff\xff\xef\xff\x0b"); + +// const.wast:1061 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8a\x80\x80\x80\x00\x01\x04\x24\x34\x30\x32\x01\x66\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$402", $402)), "run", [])); // assert_return(() => call($402, "f", []), -1.79769313486e+308) diff --git a/js/src/jit-test/tests/wasm/spec/spec/conversions.wast.js b/js/src/jit-test/tests/wasm/spec/spec/conversions.wast.js new file mode 100644 index 0000000000..583b7b324b --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/conversions.wast.js @@ -0,0 +1,1845 @@ + +// conversions.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xbd\x80\x80\x80\x00\x0c\x60\x01\x7f\x01\x7e\x60\x01\x7e\x01\x7f\x60\x01\x7d\x01\x7f\x60\x01\x7c\x01\x7f\x60\x01\x7d\x01\x7e\x60\x01\x7c\x01\x7e\x60\x01\x7f\x01\x7d\x60\x01\x7e\x01\x7d\x60\x01\x7f\x01\x7c\x60\x01\x7e\x01\x7c\x60\x01\x7d\x01\x7c\x60\x01\x7c\x01\x7d\x03\xa2\x80\x80\x80\x00\x21\x00\x00\x01\x02\x02\x03\x03\x04\x04\x05\x05\x02\x02\x03\x03\x04\x04\x05\x05\x06\x07\x08\x09\x06\x07\x08\x09\x0a\x0b\x06\x09\x02\x05\x07\x91\x85\x80\x80\x00\x21\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x00\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x02\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x03\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x04\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x05\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x06\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x07\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x08\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x09\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x0a\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x0b\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x0c\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x0d\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x0e\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x0f\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x10\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x11\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x12\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x13\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x14\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x15\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x16\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x17\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x18\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x19\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x1a\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x1b\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x1c\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x1d\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x1e\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x1f\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x20\x0a\xd3\x82\x80\x80\x00\x21\x85\x80\x80\x80\x00\x00\x20\x00\xac\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xad\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xa7\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xa8\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xa9\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xaa\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xab\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xae\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xaf\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb0\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb1\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x02\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x03\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x04\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x05\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x06\x0b\x86\x80\x80\x80\x00\x00\x20\x00\xfc\x07\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb2\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb4\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb7\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb9\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb3\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb5\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb8\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xba\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xbb\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xb6\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xbe\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xbf\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xbc\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xbd\x0b"); + +// conversions.wast:37 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [0]), int64("0")) + +// conversions.wast:38 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x90\xce\x00\x10\x00\x01\x42\x90\xce\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [10_000]), int64("10_000")) + +// conversions.wast:39 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\xf0\xb1\x7f\x10\x00\x01\x42\xf0\xb1\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [-10_000]), int64("-10_000")) + +// conversions.wast:40 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [-1]), int64("-1")) + +// conversions.wast:41 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\x01\x42\xff\xff\xff\xff\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [2_147_483_647]), int64("2_147_483_647")) + +// conversions.wast:42 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\x01\x42\x80\x80\x80\x80\x78\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_s", [-2_147_483_648]), int64("-2_147_483_648")) + +// conversions.wast:44 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [0]), int64("0")) + +// conversions.wast:45 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x90\xce\x00\x10\x00\x01\x42\x90\xce\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [10_000]), int64("10_000")) + +// conversions.wast:46 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\xf0\xb1\x7f\x10\x00\x01\x42\xf0\xb1\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [-10_000]), int64("4_294_957_296")) + +// conversions.wast:47 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [-1]), int64("4_294_967_295")) + +// conversions.wast:48 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\x01\x42\xff\xff\xff\xff\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [2_147_483_647]), int64("2_147_483_647")) + +// conversions.wast:49 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x69\x36\x34\x2e\x65\x78\x74\x65\x6e\x64\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\x01\x42\x80\x80\x80\x80\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.extend_i32_u", [-2_147_483_648]), int64("2_147_483_648")) + +// conversions.wast:51 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-1")]), -1) + +// conversions.wast:52 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xe0\xf2\x79\x10\x00\x01\x41\xe0\xf2\x79\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-100_000")]), -100_000) + +// conversions.wast:53 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x08\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("2_147_483_648")]), -2_147_483_648) + +// conversions.wast:54 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x77\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-2_147_483_649")]), 2_147_483_647) + +// conversions.wast:55 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x70\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-4_294_967_296")]), 0) + +// conversions.wast:56 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x6f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-4_294_967_297")]), -1) + +// conversions.wast:57 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x70\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("-4_294_967_295")]), 1) + +// conversions.wast:58 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("0")]), 0) + +// conversions.wast:59 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xf0\xbd\xf3\xd5\x89\xcf\x95\x9a\x12\x10\x00\x01\x41\xf0\xbd\xf3\xd5\x79\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("1_311_768_467_463_790_320")]), -1_698_898_192) + +// conversions.wast:60 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x0f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("4_294_967_295")]), -1) + +// conversions.wast:61 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x10\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("4_294_967_296")]), 0) + +// conversions.wast:62 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x93\x80\x80\x80\x00\x01\x02\x24\x31\x0c\x69\x33\x32\x2e\x77\x72\x61\x70\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x10\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.wrap_i64", [int64("4_294_967_297")]), 1) + +// conversions.wast:64 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [0.]), 0) + +// conversions.wast:65 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-0.]), 0) + +// conversions.wast:66 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [1.40129846432e-45]), 0) + +// conversions.wast:67 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-1.40129846432e-45]), 0) + +// conversions.wast:68 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [1.]), 1) + +// conversions.wast:69 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [1.10000002384]), 1) + +// conversions.wast:70 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [1.5]), 1) + +// conversions.wast:71 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-1.]), -1) + +// conversions.wast:72 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-1.10000002384]), -1) + +// conversions.wast:73 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-1.5]), -1) + +// conversions.wast:74 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-1.89999997616]), -1) + +// conversions.wast:75 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xc0\x10\x00\x01\x41\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-2.]), -2) + +// conversions.wast:76 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\xff\x4e\x10\x00\x01\x41\x80\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [2147483520.]), 2_147_483_520) + +// conversions.wast:77 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xcf\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_s", [-2147483648.]), -2_147_483_648) + +// conversions.wast:78 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x4f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [2147483648.])) + +// conversions.wast:79 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\xcf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [-2147483904.])) + +// conversions.wast:80 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [Infinity])) + +// conversions.wast:81 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [-Infinity])) + +// conversions.wast:82 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [NaN])) + +// conversions.wast:83 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [NaN])) + +// conversions.wast:84 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [-NaN])) + +// conversions.wast:85 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_s", [-NaN])) + +// conversions.wast:87 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [0.]), 0) + +// conversions.wast:88 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [-0.]), 0) + +// conversions.wast:89 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [1.40129846432e-45]), 0) + +// conversions.wast:90 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [-1.40129846432e-45]), 0) + +// conversions.wast:91 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [1.]), 1) + +// conversions.wast:92 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [1.10000002384]), 1) + +// conversions.wast:93 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [1.5]), 1) + +// conversions.wast:94 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [1.89999997616]), 1) + +// conversions.wast:95 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x10\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [2.]), 2) + +// conversions.wast:96 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x4f\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [2147483648.]), -2_147_483_648) + +// conversions.wast:97 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x4f\x10\x00\x01\x41\x80\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [4294967040.]), -256) + +// conversions.wast:98 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x66\x66\x66\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [-0.899999976158]), 0) + +// conversions.wast:99 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f32_u", [-0.999999940395]), 0) + +// conversions.wast:100 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [4294967296.])) + +// conversions.wast:101 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [-1.])) + +// conversions.wast:102 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [Infinity])) + +// conversions.wast:103 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [-Infinity])) + +// conversions.wast:104 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [NaN])) + +// conversions.wast:105 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [NaN])) + +// conversions.wast:106 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [-NaN])) + +// conversions.wast:107 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f32_u", [-NaN])) + +// conversions.wast:109 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [0.]), 0) + +// conversions.wast:110 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-0.]), 0) + +// conversions.wast:111 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [4.94065645841e-324]), 0) + +// conversions.wast:112 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-4.94065645841e-324]), 0) + +// conversions.wast:113 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [1.]), 1) + +// conversions.wast:114 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [1.1]), 1) + +// conversions.wast:115 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [1.5]), 1) + +// conversions.wast:116 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-1.]), -1) + +// conversions.wast:117 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-1.1]), -1) + +// conversions.wast:118 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-1.5]), -1) + +// conversions.wast:119 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-1.9]), -1) + +// conversions.wast:120 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\xc0\x10\x00\x01\x41\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-2.]), -2) + +// conversions.wast:121 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xc0\xff\xff\xff\xdf\x41\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [2147483647.]), 2_147_483_647) + +// conversions.wast:122 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\xc1\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_s", [-2147483648.]), -2_147_483_648) + +// conversions.wast:123 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x41\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [2147483648.])) + +// conversions.wast:124 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x20\x00\x00\x00\xe0\xc1\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [-2147483649.])) + +// conversions.wast:125 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [Infinity])) + +// conversions.wast:126 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [-Infinity])) + +// conversions.wast:127 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [NaN])) + +// conversions.wast:128 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [NaN])) + +// conversions.wast:129 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [-NaN])) + +// conversions.wast:130 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_s", [-NaN])) + +// conversions.wast:132 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [0.]), 0) + +// conversions.wast:133 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [-0.]), 0) + +// conversions.wast:134 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [4.94065645841e-324]), 0) + +// conversions.wast:135 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [-4.94065645841e-324]), 0) + +// conversions.wast:136 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [1.]), 1) + +// conversions.wast:137 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [1.1]), 1) + +// conversions.wast:138 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [1.5]), 1) + +// conversions.wast:139 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [1.9]), 1) + +// conversions.wast:140 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x10\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [2.]), 2) + +// conversions.wast:141 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x41\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [2147483648.]), -2_147_483_648) + +// conversions.wast:142 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xe0\xff\xff\xff\xef\x41\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [4294967295.]), -1) + +// conversions.wast:143 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xcd\xcc\xcc\xcc\xcc\xcc\xec\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [-0.9]), 0) + +// conversions.wast:144 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [-1.]), 0) + +// conversions.wast:145 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x84\xd7\x97\x41\x10\x00\x01\x41\x80\xc2\xd7\x2f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_f64_u", [100000000.]), 100_000_000) + +// conversions.wast:146 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [4294967296.])) + +// conversions.wast:147 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [-1.])) + +// conversions.wast:148 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x80\xe0\x37\x79\xc3\x41\x43\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [1e+16])) + +// conversions.wast:149 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\xea\x8c\xa0\x39\x59\x3e\x29\x46\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [1e+30])) + +// conversions.wast:150 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [9.22337203685e+18])) + +// conversions.wast:151 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [Infinity])) + +// conversions.wast:152 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [-Infinity])) + +// conversions.wast:153 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [NaN])) + +// conversions.wast:154 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [NaN])) + +// conversions.wast:155 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [-NaN])) + +// conversions.wast:156 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i32.trunc_f64_u", [-NaN])) + +// conversions.wast:158 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [0.]), int64("0")) + +// conversions.wast:159 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-0.]), int64("0")) + +// conversions.wast:160 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [1.40129846432e-45]), int64("0")) + +// conversions.wast:161 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-1.40129846432e-45]), int64("0")) + +// conversions.wast:162 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [1.]), int64("1")) + +// conversions.wast:163 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [1.10000002384]), int64("1")) + +// conversions.wast:164 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [1.5]), int64("1")) + +// conversions.wast:165 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-1.]), int64("-1")) + +// conversions.wast:166 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-1.10000002384]), int64("-1")) + +// conversions.wast:167 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-1.5]), int64("-1")) + +// conversions.wast:168 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-1.89999997616]), int64("-1")) + +// conversions.wast:169 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xc0\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-2.]), int64("-2")) + +// conversions.wast:170 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:171 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xcf\x10\x00\x01\x42\x80\x80\x80\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-4294967296.]), int64("-4_294_967_296")) + +// conversions.wast:172 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\xff\x5e\x10\x00\x01\x42\x80\x80\x80\x80\x80\xf0\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [9.2233714871e+18]), int64("9_223_371_487_098_961_920")) + +// conversions.wast:173 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xdf\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_s", [-9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:174 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x5f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [9.22337203685e+18])) + +// conversions.wast:175 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\xdf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [-9.22337313637e+18])) + +// conversions.wast:176 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [Infinity])) + +// conversions.wast:177 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [-Infinity])) + +// conversions.wast:178 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [NaN])) + +// conversions.wast:179 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [NaN])) + +// conversions.wast:180 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [-NaN])) + +// conversions.wast:181 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_s", [-NaN])) + +// conversions.wast:183 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [0.]), int64("0")) + +// conversions.wast:184 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [-0.]), int64("0")) + +// conversions.wast:185 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [1.40129846432e-45]), int64("0")) + +// conversions.wast:186 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [-1.40129846432e-45]), int64("0")) + +// conversions.wast:187 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [1.]), int64("1")) + +// conversions.wast:188 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [1.10000002384]), int64("1")) + +// conversions.wast:189 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [1.5]), int64("1")) + +// conversions.wast:190 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:191 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x5f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x60\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [1.84467429742e+19]), int64("-1_099_511_627_776")) + +// conversions.wast:192 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x66\x66\x66\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [-0.899999976158]), int64("0")) + +// conversions.wast:193 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f32_u", [-0.999999940395]), int64("0")) + +// conversions.wast:194 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x5f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [1.84467440737e+19])) + +// conversions.wast:195 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [-1.])) + +// conversions.wast:196 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [Infinity])) + +// conversions.wast:197 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [-Infinity])) + +// conversions.wast:198 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [NaN])) + +// conversions.wast:199 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [NaN])) + +// conversions.wast:200 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [-NaN])) + +// conversions.wast:201 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f32_u", [-NaN])) + +// conversions.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [0.]), int64("0")) + +// conversions.wast:204 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-0.]), int64("0")) + +// conversions.wast:205 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [4.94065645841e-324]), int64("0")) + +// conversions.wast:206 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-4.94065645841e-324]), int64("0")) + +// conversions.wast:207 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [1.]), int64("1")) + +// conversions.wast:208 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [1.1]), int64("1")) + +// conversions.wast:209 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [1.5]), int64("1")) + +// conversions.wast:210 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-1.]), int64("-1")) + +// conversions.wast:211 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-1.1]), int64("-1")) + +// conversions.wast:212 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-1.5]), int64("-1")) + +// conversions.wast:213 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-1.9]), int64("-1")) + +// conversions.wast:214 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\xc0\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-2.]), int64("-2")) + +// conversions.wast:215 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:216 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xc1\x10\x00\x01\x42\x80\x80\x80\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-4294967296.]), int64("-4_294_967_296")) + +// conversions.wast:217 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xdf\x43\x10\x00\x01\x42\x80\xf8\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [9.22337203685e+18]), int64("9_223_372_036_854_774_784")) + +// conversions.wast:218 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\xc3\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_s", [-9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:219 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [9.22337203685e+18])) + +// conversions.wast:220 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\xe0\xc3\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [-9.22337203685e+18])) + +// conversions.wast:221 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [Infinity])) + +// conversions.wast:222 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [-Infinity])) + +// conversions.wast:223 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [NaN])) + +// conversions.wast:224 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [NaN])) + +// conversions.wast:225 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [-NaN])) + +// conversions.wast:226 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_s", [-NaN])) + +// conversions.wast:228 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [0.]), int64("0")) + +// conversions.wast:229 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [-0.]), int64("0")) + +// conversions.wast:230 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [4.94065645841e-324]), int64("0")) + +// conversions.wast:231 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [-4.94065645841e-324]), int64("0")) + +// conversions.wast:232 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [1.]), int64("1")) + +// conversions.wast:233 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [1.1]), int64("1")) + +// conversions.wast:234 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [1.5]), int64("1")) + +// conversions.wast:235 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xe0\xff\xff\xff\xef\x41\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [4294967295.]), int64("4_294_967_295")) + +// conversions.wast:236 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:237 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\x43\x10\x00\x01\x42\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [1.84467440737e+19]), int64("-2_048")) + +// conversions.wast:238 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xcd\xcc\xcc\xcc\xcc\xcc\xec\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [-0.9]), int64("0")) + +// conversions.wast:239 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [-1.]), int64("0")) + +// conversions.wast:240 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x84\xd7\x97\x41\x10\x00\x01\x42\x80\xc2\xd7\x2f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [100000000.]), int64("100_000_000")) + +// conversions.wast:241 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x80\xe0\x37\x79\xc3\x41\x43\x10\x00\x01\x42\x80\x80\x84\xfe\xa6\xde\xe1\x11\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [1e+16]), int64("10_000_000_000_000_000")) + +// conversions.wast:242 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_f64_u", [9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:243 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x43\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [1.84467440737e+19])) + +// conversions.wast:244 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [-1.])) + +// conversions.wast:245 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [Infinity])) + +// conversions.wast:246 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [-Infinity])) + +// conversions.wast:247 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [NaN])) + +// conversions.wast:248 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [NaN])) + +// conversions.wast:249 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [-NaN])) + +// conversions.wast:250 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "i64.trunc_f64_u", [-NaN])) + +// conversions.wast:252 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [1]), 1.) + +// conversions.wast:253 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\xbc\x43\x00\x00\x80\xbf\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [-1]), -1.) + +// conversions.wast:254 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [0]), 0.) + +// conversions.wast:255 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\xbc\x43\x00\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [2_147_483_647]), 2147483648.) + +// conversions.wast:256 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\xbc\x43\x00\x00\x00\xcf\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [-2_147_483_648]), -2147483648.) + +// conversions.wast:257 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\xd2\x85\xd8\xcc\x04\x10\x00\xbc\x43\x06\x2c\x93\x4e\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [1_234_567_890]), 1234567936.) + +// conversions.wast:261 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [0.]), 0) + +// conversions.wast:262 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-0.]), 0) + +// conversions.wast:263 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [1.40129846432e-45]), 0) + +// conversions.wast:264 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-1.40129846432e-45]), 0) + +// conversions.wast:265 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [1.]), 1) + +// conversions.wast:266 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [1.10000002384]), 1) + +// conversions.wast:267 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [1.5]), 1) + +// conversions.wast:268 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-1.]), -1) + +// conversions.wast:269 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-1.10000002384]), -1) + +// conversions.wast:270 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-1.5]), -1) + +// conversions.wast:271 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-1.89999997616]), -1) + +// conversions.wast:272 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xc0\x10\x00\x01\x41\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-2.]), -2) + +// conversions.wast:273 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\xff\x4e\x10\x00\x01\x41\x80\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [2147483520.]), 2_147_483_520) + +// conversions.wast:274 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xcf\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-2147483648.]), -2_147_483_648) + +// conversions.wast:275 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x4f\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [2147483648.]), 2_147_483_647) + +// conversions.wast:276 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\xcf\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-2147483904.]), -2_147_483_648) + +// conversions.wast:277 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [Infinity]), 2_147_483_647) + +// conversions.wast:278 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-Infinity]), -2_147_483_648) + +// conversions.wast:279 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [NaN]), 0) + +// conversions.wast:280 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [NaN]), 0) + +// conversions.wast:281 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-NaN]), 0) + +// conversions.wast:282 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_s", [-NaN]), 0) + +// conversions.wast:284 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [0.]), 0) + +// conversions.wast:285 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-0.]), 0) + +// conversions.wast:286 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [1.40129846432e-45]), 0) + +// conversions.wast:287 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-1.40129846432e-45]), 0) + +// conversions.wast:288 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [1.]), 1) + +// conversions.wast:289 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [1.10000002384]), 1) + +// conversions.wast:290 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [1.5]), 1) + +// conversions.wast:291 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [1.89999997616]), 1) + +// conversions.wast:292 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x10\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [2.]), 2) + +// conversions.wast:293 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x4f\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [2147483648.]), -2_147_483_648) + +// conversions.wast:294 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x4f\x10\x00\x01\x41\x80\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [4294967040.]), -256) + +// conversions.wast:295 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x66\x66\x66\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-0.899999976158]), 0) + +// conversions.wast:296 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-0.999999940395]), 0) + +// conversions.wast:297 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [4294967296.]), -1) + +// conversions.wast:298 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-1.]), 0) + +// conversions.wast:299 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [Infinity]), -1) + +// conversions.wast:300 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-Infinity]), 0) + +// conversions.wast:301 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [NaN]), 0) + +// conversions.wast:302 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [NaN]), 0) + +// conversions.wast:303 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-NaN]), 0) + +// conversions.wast:304 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f32_u", [-NaN]), 0) + +// conversions.wast:306 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [0.]), 0) + +// conversions.wast:307 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-0.]), 0) + +// conversions.wast:308 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [4.94065645841e-324]), 0) + +// conversions.wast:309 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-4.94065645841e-324]), 0) + +// conversions.wast:310 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [1.]), 1) + +// conversions.wast:311 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [1.1]), 1) + +// conversions.wast:312 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [1.5]), 1) + +// conversions.wast:313 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-1.]), -1) + +// conversions.wast:314 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-1.1]), -1) + +// conversions.wast:315 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-1.5]), -1) + +// conversions.wast:316 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\xbf\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-1.9]), -1) + +// conversions.wast:317 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\xc0\x10\x00\x01\x41\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-2.]), -2) + +// conversions.wast:318 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xc0\xff\xff\xff\xdf\x41\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [2147483647.]), 2_147_483_647) + +// conversions.wast:319 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\xc1\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-2147483648.]), -2_147_483_648) + +// conversions.wast:320 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x41\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [2147483648.]), 2_147_483_647) + +// conversions.wast:321 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x20\x00\x00\x00\xe0\xc1\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-2147483649.]), -2_147_483_648) + +// conversions.wast:322 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x01\x41\xff\xff\xff\xff\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [Infinity]), 2_147_483_647) + +// conversions.wast:323 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-Infinity]), -2_147_483_648) + +// conversions.wast:324 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [NaN]), 0) + +// conversions.wast:325 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [NaN]), 0) + +// conversions.wast:326 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-NaN]), 0) + +// conversions.wast:327 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_s", [-NaN]), 0) + +// conversions.wast:329 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [0.]), 0) + +// conversions.wast:330 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-0.]), 0) + +// conversions.wast:331 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [4.94065645841e-324]), 0) + +// conversions.wast:332 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-4.94065645841e-324]), 0) + +// conversions.wast:333 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1.]), 1) + +// conversions.wast:334 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1.1]), 1) + +// conversions.wast:335 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1.5]), 1) + +// conversions.wast:336 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\x3f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1.9]), 1) + +// conversions.wast:337 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x10\x00\x01\x41\x02\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [2.]), 2) + +// conversions.wast:338 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x41\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [2147483648.]), -2_147_483_648) + +// conversions.wast:339 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xe0\xff\xff\xff\xef\x41\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [4294967295.]), -1) + +// conversions.wast:340 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xcd\xcc\xcc\xcc\xcc\xcc\xec\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-0.9]), 0) + +// conversions.wast:341 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-1.]), 0) + +// conversions.wast:342 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x84\xd7\x97\x41\x10\x00\x01\x41\x80\xc2\xd7\x2f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [100000000.]), 100_000_000) + +// conversions.wast:343 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [4294967296.]), -1) + +// conversions.wast:344 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-1.]), 0) + +// conversions.wast:345 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x80\xe0\x37\x79\xc3\x41\x43\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1e+16]), -1) + +// conversions.wast:346 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xea\x8c\xa0\x39\x59\x3e\x29\x46\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [1e+30]), -1) + +// conversions.wast:347 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [9.22337203685e+18]), -1) + +// conversions.wast:348 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [Infinity]), -1) + +// conversions.wast:349 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-Infinity]), 0) + +// conversions.wast:350 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [NaN]), 0) + +// conversions.wast:351 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [NaN]), 0) + +// conversions.wast:352 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-NaN]), 0) + +// conversions.wast:353 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.trunc_sat_f64_u", [-NaN]), 0) + +// conversions.wast:355 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [0.]), int64("0")) + +// conversions.wast:356 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-0.]), int64("0")) + +// conversions.wast:357 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [1.40129846432e-45]), int64("0")) + +// conversions.wast:358 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-1.40129846432e-45]), int64("0")) + +// conversions.wast:359 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [1.]), int64("1")) + +// conversions.wast:360 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [1.10000002384]), int64("1")) + +// conversions.wast:361 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [1.5]), int64("1")) + +// conversions.wast:362 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-1.]), int64("-1")) + +// conversions.wast:363 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-1.10000002384]), int64("-1")) + +// conversions.wast:364 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-1.5]), int64("-1")) + +// conversions.wast:365 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x33\x33\xf3\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-1.89999997616]), int64("-1")) + +// conversions.wast:366 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xc0\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-2.]), int64("-2")) + +// conversions.wast:367 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:368 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xcf\x10\x00\x01\x42\x80\x80\x80\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-4294967296.]), int64("-4_294_967_296")) + +// conversions.wast:369 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\xff\x5e\x10\x00\x01\x42\x80\x80\x80\x80\x80\xf0\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [9.2233714871e+18]), int64("9_223_371_487_098_961_920")) + +// conversions.wast:370 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\xdf\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:371 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x5f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [9.22337203685e+18]), int64("9_223_372_036_854_775_807")) + +// conversions.wast:372 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\xdf\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-9.22337313637e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:373 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [Infinity]), int64("9_223_372_036_854_775_807")) + +// conversions.wast:374 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-Infinity]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:375 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [NaN]), int64("0")) + +// conversions.wast:376 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [NaN]), int64("0")) + +// conversions.wast:377 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-NaN]), int64("0")) + +// conversions.wast:378 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_s", [-NaN]), int64("0")) + +// conversions.wast:380 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [0.]), int64("0")) + +// conversions.wast:381 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-0.]), int64("0")) + +// conversions.wast:382 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.40129846432e-45]), int64("0")) + +// conversions.wast:383 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-1.40129846432e-45]), int64("0")) + +// conversions.wast:384 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.]), int64("1")) + +// conversions.wast:385 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xcd\xcc\x8c\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.10000002384]), int64("1")) + +// conversions.wast:386 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.5]), int64("1")) + +// conversions.wast:387 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x4f\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:388 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x5f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x60\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.84467429742e+19]), int64("-1_099_511_627_776")) + +// conversions.wast:389 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x66\x66\x66\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-0.899999976158]), int64("0")) + +// conversions.wast:390 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-0.999999940395]), int64("0")) + +// conversions.wast:391 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x5f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [1.84467440737e+19]), int64("-1")) + +// conversions.wast:392 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-1.]), int64("0")) + +// conversions.wast:393 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [Infinity]), int64("-1")) + +// conversions.wast:394 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-Infinity]), int64("0")) + +// conversions.wast:395 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [NaN]), int64("0")) + +// conversions.wast:396 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [NaN]), int64("0")) + +// conversions.wast:397 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-NaN]), int64("0")) + +// conversions.wast:398 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f32_u", [-NaN]), int64("0")) + +// conversions.wast:400 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [0.]), int64("0")) + +// conversions.wast:401 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-0.]), int64("0")) + +// conversions.wast:402 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [4.94065645841e-324]), int64("0")) + +// conversions.wast:403 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-4.94065645841e-324]), int64("0")) + +// conversions.wast:404 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [1.]), int64("1")) + +// conversions.wast:405 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [1.1]), int64("1")) + +// conversions.wast:406 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [1.5]), int64("1")) + +// conversions.wast:407 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-1.]), int64("-1")) + +// conversions.wast:408 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-1.1]), int64("-1")) + +// conversions.wast:409 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-1.5]), int64("-1")) + +// conversions.wast:410 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x66\x66\x66\x66\x66\x66\xfe\xbf\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-1.9]), int64("-1")) + +// conversions.wast:411 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\xc0\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-2.]), int64("-2")) + +// conversions.wast:412 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:413 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xc1\x10\x00\x01\x42\x80\x80\x80\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-4294967296.]), int64("-4_294_967_296")) + +// conversions.wast:414 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xdf\x43\x10\x00\x01\x42\x80\xf8\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [9.22337203685e+18]), int64("9_223_372_036_854_774_784")) + +// conversions.wast:415 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\xc3\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:416 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [9.22337203685e+18]), int64("9_223_372_036_854_775_807")) + +// conversions.wast:417 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\xe0\xc3\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:418 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [Infinity]), int64("9_223_372_036_854_775_807")) + +// conversions.wast:419 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-Infinity]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:420 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [NaN]), int64("0")) + +// conversions.wast:421 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [NaN]), int64("0")) + +// conversions.wast:422 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-NaN]), int64("0")) + +// conversions.wast:423 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_s", [-NaN]), int64("0")) + +// conversions.wast:425 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [0.]), int64("0")) + +// conversions.wast:426 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-0.]), int64("0")) + +// conversions.wast:427 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [4.94065645841e-324]), int64("0")) + +// conversions.wast:428 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-4.94065645841e-324]), int64("0")) + +// conversions.wast:429 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1.]), int64("1")) + +// conversions.wast:430 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x9a\x99\x99\x99\x99\x99\xf1\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1.1]), int64("1")) + +// conversions.wast:431 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1.5]), int64("1")) + +// conversions.wast:432 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\xe0\xff\xff\xff\xef\x41\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [4294967295.]), int64("4_294_967_295")) + +// conversions.wast:433 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x41\x10\x00\x01\x42\x80\x80\x80\x80\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [4294967296.]), int64("4_294_967_296")) + +// conversions.wast:434 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\x43\x10\x00\x01\x42\x80\x70\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1.84467440737e+19]), int64("-2_048")) + +// conversions.wast:435 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xcd\xcc\xcc\xcc\xcc\xcc\xec\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-0.9]), int64("0")) + +// conversions.wast:436 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-1.]), int64("0")) + +// conversions.wast:437 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x84\xd7\x97\x41\x10\x00\x01\x42\x80\xc2\xd7\x2f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [100000000.]), int64("100_000_000")) + +// conversions.wast:438 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x80\xe0\x37\x79\xc3\x41\x43\x10\x00\x01\x42\x80\x80\x84\xfe\xa6\xde\xe1\x11\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1e+16]), int64("10_000_000_000_000_000")) + +// conversions.wast:439 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xe0\x43\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [9.22337203685e+18]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:440 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x43\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [1.84467440737e+19]), int64("-1")) + +// conversions.wast:441 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-1.]), int64("0")) + +// conversions.wast:442 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [Infinity]), int64("-1")) + +// conversions.wast:443 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-Infinity]), int64("0")) + +// conversions.wast:444 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [NaN]), int64("0")) + +// conversions.wast:445 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [NaN]), int64("0")) + +// conversions.wast:446 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-NaN]), int64("0")) + +// conversions.wast:447 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x74\x72\x75\x6e\x63\x5f\x73\x61\x74\x5f\x66\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.trunc_sat_f64_u", [-NaN]), int64("0")) + +// conversions.wast:450 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x81\x80\x80\x08\x10\x00\xbc\x43\x00\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [16_777_217]), 16777216.) + +// conversions.wast:451 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\x77\x10\x00\xbc\x43\x00\x00\x80\xcb\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [-16_777_217]), -16777216.) + +// conversions.wast:452 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x83\x80\x80\x08\x10\x00\xbc\x43\x02\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [16_777_219]), 16777220.) + +// conversions.wast:453 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\xfd\xff\xff\x77\x10\x00\xbc\x43\x02\x00\x80\xcb\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_s", [-16_777_219]), -16777220.) + +// conversions.wast:455 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("1")]), 1.) + +// conversions.wast:456 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\xbc\x43\x00\x00\x80\xbf\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-1")]), -1.) + +// conversions.wast:457 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("0")]), 0.) + +// conversions.wast:458 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\xbc\x43\x00\x00\x00\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("9_223_372_036_854_775_807")]), 9.22337203685e+18) + +// conversions.wast:459 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbc\x43\x00\x00\x00\xdf\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-9_223_372_036_854_775_808")]), -9.22337203685e+18) + +// conversions.wast:460 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\x83\xc9\xa8\xbb\x9e\xb7\xc7\x00\x10\x00\xbc\x43\xf4\xdc\x8e\x57\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("314_159_265_358_979")]), 3.1415927518e+14) + +// conversions.wast:462 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x08\x10\x00\xbc\x43\x00\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("16_777_217")]), 16777216.) + +// conversions.wast:463 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\x77\x10\x00\xbc\x43\x00\x00\x80\xcb\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-16_777_217")]), -16777216.) + +// conversions.wast:464 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\x83\x80\x80\x08\x10\x00\xbc\x43\x02\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("16_777_219")]), 16777220.) + +// conversions.wast:465 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\xfd\xff\xff\x77\x10\x00\xbc\x43\x02\x00\x80\xcb\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-16_777_219")]), -16777220.) + +// conversions.wast:467 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\xe8\xff\xff\xff\x00\x10\x00\xbc\x43\xff\xff\xff\x5e\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("9_223_371_212_221_054_977")]), 9.2233714871e+18) + +// conversions.wast:468 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x88\x80\x80\x80\x7f\x10\x00\xbc\x43\xff\xff\xff\xde\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-9_223_371_761_976_868_863")]), -9.2233714871e+18) + +// conversions.wast:469 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x82\x80\x80\x10\x10\x00\xbc\x43\x01\x00\x00\x5a\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("9_007_199_791_611_905")]), 9.00720032848e+15) + +// conversions.wast:470 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xfd\xff\xff\x6f\x10\x00\xbc\x43\x01\x00\x00\xda\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_s", [int64("-9_007_199_791_611_905")]), -9.00720032848e+15) + +// conversions.wast:472 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [1]), 1.) + +// conversions.wast:473 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [-1]), -1.) + +// conversions.wast:474 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [0]), 0.) + +// conversions.wast:475 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\xbd\x44\x00\x00\xc0\xff\xff\xff\xdf\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [2_147_483_647]), 2147483647.) + +// conversions.wast:476 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\xc1\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [-2_147_483_648]), -2147483648.) + +// conversions.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\xb1\xd1\xf9\xd6\x03\x10\x00\xbd\x44\x00\x00\x80\x58\x34\x6f\xcd\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_s", [987_654_321]), 987654321.) + +// conversions.wast:479 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("1")]), 1.) + +// conversions.wast:480 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("-1")]), -1.) + +// conversions.wast:481 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("0")]), 0.) + +// conversions.wast:482 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("9_223_372_036_854_775_807")]), 9.22337203685e+18) + +// conversions.wast:483 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("-9_223_372_036_854_775_808")]), -9.22337203685e+18) + +// conversions.wast:484 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x8e\xad\xae\xba\xd3\xd3\xa5\x08\x10\x00\xbd\x44\x8e\x96\x4b\x37\x9d\x96\x30\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("4_669_201_609_102_990")]), 4.6692016091e+15) + +// conversions.wast:486 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x10\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x40\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("9_007_199_254_740_993")]), 9.00719925474e+15) + +// conversions.wast:487 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\x6f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x40\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("-9_007_199_254_740_993")]), -9.00719925474e+15) + +// conversions.wast:488 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x83\x80\x80\x80\x80\x80\x80\x10\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x40\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("9_007_199_254_740_995")]), 9.00719925474e+15) + +// conversions.wast:489 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\xfd\xff\xff\xff\xff\xff\xff\x6f\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x40\xc3\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_s", [int64("-9_007_199_254_740_995")]), -9.00719925474e+15) + +// conversions.wast:491 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [1]), 1.) + +// conversions.wast:492 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [0]), 0.) + +// conversions.wast:493 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\xbc\x43\x00\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [2_147_483_647]), 2147483648.) + +// conversions.wast:494 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\xbc\x43\x00\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-2_147_483_648]), 2147483648.) + +// conversions.wast:495 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\xf8\xac\xd1\x91\x01\x10\x00\xbc\x43\xb4\xa2\x91\x4d\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [305_419_896]), 305419904.) + +// conversions.wast:496 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\xbc\x43\x00\x00\x80\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-1]), 4294967296.) + +// conversions.wast:497 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x81\x80\x80\x78\x10\x00\xbc\x43\x00\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-2_147_483_520]), 2147483648.) + +// conversions.wast:498 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x81\x81\x80\x80\x78\x10\x00\xbc\x43\x01\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-2_147_483_519]), 2147483904.) + +// conversions.wast:499 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x82\x81\x80\x80\x78\x10\x00\xbc\x43\x01\x00\x00\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-2_147_483_518]), 2147483904.) + +// conversions.wast:500 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x80\x7d\x10\x00\xbc\x43\xfe\xff\x7f\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-384]), 4294966784.) + +// conversions.wast:501 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x81\x7d\x10\x00\xbc\x43\xff\xff\x7f\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-383]), 4294967040.) + +// conversions.wast:502 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x41\x82\x7d\x10\x00\xbc\x43\xff\xff\x7f\x4f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [-382]), 4294967040.) + +// conversions.wast:504 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x81\x80\x80\x08\x10\x00\xbc\x43\x00\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [16_777_217]), 16777216.) + +// conversions.wast:505 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x83\x80\x80\x08\x10\x00\xbc\x43\x02\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i32_u", [16_777_219]), 16777220.) + +// conversions.wast:507 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("1")]), 1.) + +// conversions.wast:508 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("0")]), 0.) + +// conversions.wast:509 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\xbc\x43\x00\x00\x00\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("9_223_372_036_854_775_807")]), 9.22337203685e+18) + +// conversions.wast:510 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbc\x43\x00\x00\x00\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("-9_223_372_036_854_775_808")]), 9.22337203685e+18) + +// conversions.wast:511 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\xbc\x43\x00\x00\x80\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("-1")]), 1.84467440737e+19) + +// conversions.wast:513 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x08\x10\x00\xbc\x43\x00\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("16_777_217")]), 16777216.) + +// conversions.wast:514 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x42\x83\x80\x80\x08\x10\x00\xbc\x43\x02\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("16_777_219")]), 16777220.) + +// conversions.wast:516 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x82\x80\x80\x10\x10\x00\xbc\x43\x01\x00\x00\x5a\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("9_007_199_791_611_905")]), 9.00720032848e+15) + +// conversions.wast:517 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xf7\xff\xff\xff\x00\x10\x00\xbc\x43\xff\xff\xff\x5e\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("9_223_371_761_976_868_863")]), 9.2233714871e+18) + +// conversions.wast:518 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x90\x80\x80\x80\x7f\x10\x00\xbc\x43\x01\x00\x00\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("-9_223_371_487_098_961_919")]), 9.22337313637e+18) + +// conversions.wast:519 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7d\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x33\x32\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x50\x10\x00\xbc\x43\xff\xff\x7f\x5f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.convert_i64_u", [int64("-1_649_267_441_663")]), 1.84467429742e+19) + +// conversions.wast:521 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_u", [1]), 1.) + +// conversions.wast:522 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_u", [0]), 0.) + +// conversions.wast:523 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\xff\xff\xff\xff\x07\x10\x00\xbd\x44\x00\x00\xc0\xff\xff\xff\xdf\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_u", [2_147_483_647]), 2147483647.) + +// conversions.wast:524 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_u", [-2_147_483_648]), 2147483648.) + +// conversions.wast:525 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\xbd\x44\x00\x00\xe0\xff\xff\xff\xef\x41\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i32_u", [-1]), 4294967295.) + +// conversions.wast:527 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("1")]), 1.) + +// conversions.wast:528 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("0")]), 0.) + +// conversions.wast:529 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("9_223_372_036_854_775_807")]), 9.22337203685e+18) + +// conversions.wast:530 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-9_223_372_036_854_775_808")]), 9.22337203685e+18) + +// conversions.wast:531 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-1")]), 1.84467440737e+19) + +// conversions.wast:532 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x88\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-9_223_372_036_854_774_784")]), 9.22337203685e+18) + +// conversions.wast:533 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x81\x88\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-9_223_372_036_854_774_783")]), 9.22337203685e+18) + +// conversions.wast:534 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x82\x88\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xe0\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-9_223_372_036_854_774_782")]), 9.22337203685e+18) + +// conversions.wast:535 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x68\x10\x00\xbd\x44\xfe\xff\xff\xff\xff\xff\xef\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-3_072")]), 1.84467440737e+19) + +// conversions.wast:536 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x81\x68\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-3_071")]), 1.84467440737e+19) + +// conversions.wast:537 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x82\x68\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xef\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("-3_070")]), 1.84467440737e+19) + +// conversions.wast:539 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x10\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x40\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("9_007_199_254_740_993")]), 9.00719925474e+15) + +// conversions.wast:540 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x66\x36\x34\x2e\x63\x6f\x6e\x76\x65\x72\x74\x5f\x69\x36\x34\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x83\x80\x80\x80\x80\x80\x80\x10\x10\x00\xbd\x44\x02\x00\x00\x00\x00\x00\x40\x43\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.convert_i64_u", [int64("9_007_199_254_740_995")]), 9.00719925474e+15) + +// conversions.wast:542 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [0.]), 0.) + +// conversions.wast:543 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-0.]), -0.) + +// conversions.wast:544 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xa0\x36\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [1.40129846432e-45]), 1.40129846432e-45) + +// conversions.wast:545 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xa0\xb6\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-1.40129846432e-45]), -1.40129846432e-45) + +// conversions.wast:546 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [1.]), 1.) + +// conversions.wast:547 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xbf\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-1.]), -1.) + +// conversions.wast:548 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xff\x10\x00\xbd\x44\x00\x00\x00\xe0\xff\xff\xef\xc7\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-3.40282346639e+38]), -3.40282346639e+38) + +// conversions.wast:549 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x7f\x10\x00\xbd\x44\x00\x00\x00\xe0\xff\xff\xef\x47\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [3.40282346639e+38]), 3.40282346639e+38) + +// conversions.wast:551 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x04\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x80\x38\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [1.50463276905e-36]), 1.50463276905e-36) + +// conversions.wast:553 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x3f\xc3\x47\x7e\x10\x00\xbd\x44\x00\x00\x00\xe0\x67\xf8\xc8\x47\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [6.63825367101e+37]), 6.63825367101e+37) + +// conversions.wast:554 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [Infinity]), Infinity) + +// conversions.wast:555 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-Infinity]), -Infinity) + +// conversions.wast:556 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\xbd\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [NaN]), nan:canonical) + +// conversions.wast:557 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\xbd\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [NaN]), nan:arithmetic) + +// conversions.wast:558 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\xbd\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-NaN]), nan:canonical) + +// conversions.wast:559 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x66\x36\x34\x2e\x70\x72\x6f\x6d\x6f\x74\x65\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\xbd\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x83\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.promote_f32", [-NaN]), nan:arithmetic) + +// conversions.wast:561 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [0.]), 0.) + +// conversions.wast:562 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-0.]), -0.) + +// conversions.wast:563 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [4.94065645841e-324]), 0.) + +// conversions.wast:564 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-4.94065645841e-324]), -0.) + +// conversions.wast:565 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.]), 1.) + +// conversions.wast:566 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xbf\x10\x00\xbc\x43\x00\x00\x80\xbf\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-1.]), -1.) + +// conversions.wast:567 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xe0\xff\xff\x0f\x38\x10\x00\xbc\x43\x00\x00\x80\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.17549428076e-38]), 1.17549435082e-38) + +// conversions.wast:568 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xe0\xff\xff\x0f\xb8\x10\x00\xbc\x43\x00\x00\x80\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-1.17549428076e-38]), -1.17549435082e-38) + +// conversions.wast:569 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xdf\xff\xff\x0f\x38\x10\x00\xbc\x43\xff\xff\x7f\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.17549428076e-38]), 1.17549421069e-38) + +// conversions.wast:570 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xdf\xff\xff\x0f\xb8\x10\x00\xbc\x43\xff\xff\x7f\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-1.17549428076e-38]), -1.17549421069e-38) + +// conversions.wast:571 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xa0\x36\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.40129846432e-45]), 1.40129846432e-45) + +// conversions.wast:572 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xa0\xb6\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-1.40129846432e-45]), -1.40129846432e-45) + +// conversions.wast:573 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xd0\xff\xff\xef\x47\x10\x00\xbc\x43\xfe\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [3.40282336497e+38]), 3.40282326356e+38) + +// conversions.wast:574 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xd0\xff\xff\xef\xc7\x10\x00\xbc\x43\xfe\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-3.40282336497e+38]), -3.40282326356e+38) + +// conversions.wast:575 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\xd0\xff\xff\xef\x47\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [3.40282336497e+38]), 3.40282346639e+38) + +// conversions.wast:576 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\xd0\xff\xff\xef\xc7\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-3.40282336497e+38]), -3.40282346639e+38) + +// conversions.wast:577 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xe0\xff\xff\xef\x47\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [3.40282346639e+38]), 3.40282346639e+38) + +// conversions.wast:578 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xe0\xff\xff\xef\xc7\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-3.40282346639e+38]), -3.40282346639e+38) + +// conversions.wast:579 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xef\xff\xff\xef\x47\x10\x00\xbc\x43\xff\xff\x7f\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [3.4028235678e+38]), 3.40282346639e+38) + +// conversions.wast:580 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xef\xff\xff\xef\xc7\x10\x00\xbc\x43\xff\xff\x7f\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-3.4028235678e+38]), -3.40282346639e+38) + +// conversions.wast:581 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xf0\xff\xff\xef\x47\x10\x00\xbc\x43\x00\x00\x80\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [3.4028235678e+38]), Infinity) + +// conversions.wast:582 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xf0\xff\xff\xef\xc7\x10\x00\xbc\x43\x00\x00\x80\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-3.4028235678e+38]), -Infinity) + +// conversions.wast:583 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x80\x38\x10\x00\xbc\x43\x00\x00\x00\x04\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.50463276905e-36]), 1.50463276905e-36) + +// conversions.wast:584 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\xe0\x67\xf8\xc8\x47\x10\x00\xbc\x43\x3f\xc3\x47\x7e\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [6.63825367101e+37]), 6.63825367101e+37) + +// conversions.wast:585 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\xbc\x43\x00\x00\x80\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [Infinity]), Infinity) + +// conversions.wast:586 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\xbc\x43\x00\x00\x80\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-Infinity]), -Infinity) + +// conversions.wast:587 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.]), 1.) + +// conversions.wast:588 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.]), 1.) + +// conversions.wast:589 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x10\x00\x00\xf0\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.0000000596]), 1.) + +// conversions.wast:590 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x10\x00\x00\xf0\x3f\x10\x00\xbc\x43\x01\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.0000000596]), 1.00000011921) + +// conversions.wast:591 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\x2f\x00\x00\xf0\x3f\x10\x00\xbc\x43\x01\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.00000017881]), 1.00000011921) + +// conversions.wast:592 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x30\x00\x00\xf0\x3f\x10\x00\xbc\x43\x02\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.00000017881]), 1.00000023842) + +// conversions.wast:593 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x50\x00\x00\xf0\x3f\x10\x00\xbc\x43\x02\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.00000029802]), 1.00000023842) + +// conversions.wast:594 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x10\x00\x00\x70\x41\x10\x00\xbc\x43\x00\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [16777217.]), 16777216.) + +// conversions.wast:595 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x10\x00\x00\x70\x41\x10\x00\xbc\x43\x01\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [16777217.]), 16777218.) + +// conversions.wast:596 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\x2f\x00\x00\x70\x41\x10\x00\xbc\x43\x01\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [16777219.]), 16777218.) + +// conversions.wast:597 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x30\x00\x00\x70\x41\x10\x00\xbc\x43\x02\x00\x80\x4b\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [16777219.]), 16777220.) + +// conversions.wast:598 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x70\x4c\x02\xf7\xe4\xea\xb4\x46\x10\x00\xbc\x43\x28\x57\xa7\x75\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [4.24258443299e+32]), 4.24258454169e+32) + +// conversions.wast:599 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x85\x86\x35\x1e\xe7\x12\xea\x38\x10\x00\xbc\x43\x39\x97\x50\x07\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.56926210784e-34]), 1.56926211427e-34) + +// conversions.wast:600 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xff\x21\xd5\x54\x83\xb9\x0c\x38\x10\x00\xbc\x43\x0d\xe6\x72\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [1.05517736886e-38]), 1.05517732325e-38) + +// conversions.wast:601 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x62\xb5\xcf\x30\x2b\x97\x06\xc0\x10\x00\xbc\x43\x5a\xb9\x34\xc0\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-2.82381284841]), -2.82381296158) + +// conversions.wast:602 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\xc4\xd4\x19\x48\xbe\xed\xfb\xc6\x10\x00\xbc\x43\xf2\x6d\xdf\xf7\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-9.0633763701e+33]), -9.0633762134e+33) + +// conversions.wast:603 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xaa\x80\x80\x80\x00\x01\xa4\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\xbc\x41\xff\xff\xff\xff\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [NaN]), nan:canonical) + +// conversions.wast:604 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xaa\x80\x80\x80\x00\x01\xa4\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\xbc\x41\x80\x80\x80\xfe\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [NaN]), nan:arithmetic) + +// conversions.wast:605 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xaa\x80\x80\x80\x00\x01\xa4\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\xbc\x41\xff\xff\xff\xff\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-NaN]), nan:canonical) + +// conversions.wast:606 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xaa\x80\x80\x80\x00\x01\xa4\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\xbc\x41\x80\x80\x80\xfe\x07\x71\x41\x80\x80\x80\xfe\x07\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-NaN]), nan:arithmetic) + +// conversions.wast:607 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x10\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [2.22507385851e-308]), 0.) + +// conversions.wast:608 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x10\x80\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-2.22507385851e-308]), -0.) + +// conversions.wast:609 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x90\x36\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [7.00649232162e-46]), 0.) + +// conversions.wast:610 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x90\xb6\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-7.00649232162e-46]), -0.) + +// conversions.wast:611 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x90\x36\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [7.00649232162e-46]), 1.40129846432e-45) + +// conversions.wast:612 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x33\x32\x2e\x64\x65\x6d\x6f\x74\x65\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x90\xb6\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.demote_f64", [-7.00649232162e-46]), -1.40129846432e-45) + +// conversions.wast:614 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [0]), 0.) + +// conversions.wast:615 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x80\x78\x10\x00\xbc\x43\x00\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-2_147_483_648]), -0.) + +// conversions.wast:616 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\xbc\x43\x01\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [1]), 1.40129846432e-45) + +// conversions.wast:617 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x41\x7f\x10\x00\xbc\x43\xff\xff\xff\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-1]), -NaN) + +// conversions.wast:618 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x95\x9a\xef\x3a\x10\x00\xbc\x43\x15\xcd\x5b\x07\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [123_456_789]), 1.65359970134e-34) + +// conversions.wast:619 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x81\x80\x80\x80\x78\x10\x00\xbc\x43\x01\x00\x00\x80\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-2_147_483_647]), -1.40129846432e-45) + +// conversions.wast:620 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\xfc\x07\x10\x00\xbc\x43\x00\x00\x80\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [2_139_095_040]), Infinity) + +// conversions.wast:621 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x7c\x10\x00\xbc\x43\x00\x00\x80\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-8_388_608]), -Infinity) + +// conversions.wast:622 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\xfe\x07\x10\x00\xbc\x43\x00\x00\xc0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [2_143_289_344]), NaN) + +// conversions.wast:623 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x7e\x10\x00\xbc\x43\x00\x00\xc0\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-4_194_304]), -NaN) + +// conversions.wast:624 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\xfd\x07\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [2_141_192_192]), NaN) + +// conversions.wast:625 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7d\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x41\x80\x80\x80\x7d\x10\x00\xbc\x43\x00\x00\xa0\xff\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.reinterpret_i32", [-6_291_456]), -NaN) + +// conversions.wast:627 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("0")]), 0.) + +// conversions.wast:628 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("1")]), 4.94065645841e-324) + +// conversions.wast:629 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\xbd\x44\xff\xff\xff\xff\xff\xff\xff\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-1")]), -NaN) + +// conversions.wast:630 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-9_223_372_036_854_775_808")]), -0.) + +// conversions.wast:631 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\xd2\x85\xd8\xcc\x04\x10\x00\xbd\x44\xd2\x02\x96\x49\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("1_234_567_890")]), 6.09957581908e-315) + +// conversions.wast:632 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\x00\x80\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-9_223_372_036_854_775_807")]), -4.94065645841e-324) + +// conversions.wast:633 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\xf8\xff\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("9_218_868_437_227_405_312")]), Infinity) + +// conversions.wast:634 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x78\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-4_503_599_627_370_496")]), -Infinity) + +// conversions.wast:635 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("9_221_120_237_041_090_560")]), NaN) + +// conversions.wast:636 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x7c\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf8\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-2_251_799_813_685_248")]), -NaN) + +// conversions.wast:637 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("9_219_994_337_134_247_936")]), NaN) + +// conversions.wast:638 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7c\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x66\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x7a\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\xff\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f64.reinterpret_i64", [int64("-3_377_699_720_527_872")]), -NaN) + +// conversions.wast:640 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [0.]), 0) + +// conversions.wast:641 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x80\x10\x00\x01\x41\x80\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-0.]), -2_147_483_648) + +// conversions.wast:642 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [1.40129846432e-45]), 1) + +// conversions.wast:643 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\xff\xff\x10\x00\x01\x41\x7f\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-NaN]), -1) + +// conversions.wast:644 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x01\x00\x00\x80\x10\x00\x01\x41\x81\x80\x80\x80\x78\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-1.40129846432e-45]), -2_147_483_647) + +// conversions.wast:645 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x10\x00\x01\x41\x80\x80\x80\xfc\x03\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [1.]), 1_065_353_216) + +// conversions.wast:646 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\xda\x0f\x49\x40\x10\x00\x01\x41\xda\x9f\xa4\x82\x04\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [3.14159250259]), 1_078_530_010) + +// conversions.wast:647 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\x7f\x10\x00\x01\x41\xff\xff\xff\xfb\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [3.40282346639e+38]), 2_139_095_039) + +// conversions.wast:648 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\xff\xff\x7f\xff\x10\x00\x01\x41\xff\xff\xff\x7b\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-3.40282346639e+38]), -8_388_609) + +// conversions.wast:649 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x7f\x10\x00\x01\x41\x80\x80\x80\xfc\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [Infinity]), 2_139_095_040) + +// conversions.wast:650 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\xff\x10\x00\x01\x41\x80\x80\x80\x7c\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-Infinity]), -8_388_608) + +// conversions.wast:651 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\x7f\x10\x00\x01\x41\x80\x80\x80\xfe\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [NaN]), 2_143_289_344) + +// conversions.wast:652 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xc0\xff\x10\x00\x01\x41\x80\x80\x80\x7e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-NaN]), -4_194_304) + +// conversions.wast:653 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\x7f\x10\x00\x01\x41\x80\x80\x80\xfd\x07\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [NaN]), 2_141_192_192) + +// conversions.wast:654 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x01\x7f\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x33\x32\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xa0\xff\x10\x00\x01\x41\x80\x80\x80\x7d\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i32.reinterpret_f32", [-NaN]), -6_291_456) + +// conversions.wast:656 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [0.]), int64("0")) + +// conversions.wast:657 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-0.]), int64("-9_223_372_036_854_775_808")) + +// conversions.wast:658 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [4.94065645841e-324]), int64("1")) + +// conversions.wast:659 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xff\xff\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-NaN]), int64("-1")) + +// conversions.wast:660 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x01\x00\x00\x00\x00\x00\x00\x80\x10\x00\x01\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-4.94065645841e-324]), int64("-9_223_372_036_854_775_807")) + +// conversions.wast:661 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa8\x80\x80\x80\x00\x01\xa2\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xf8\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [1.]), int64("4_607_182_418_800_017_408")) + +// conversions.wast:662 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x11\x2d\x44\x54\xfb\x21\x09\x40\x10\x00\x01\x42\x91\xda\x90\xa2\xb5\xbf\xc8\x84\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [3.14159265359]), int64("4_614_256_656_552_045_841")) + +// conversions.wast:663 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xf7\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [1.79769313486e+308]), int64("9_218_868_437_227_405_311")) + +// conversions.wast:664 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\xff\xff\xff\xff\xff\xff\xef\xff\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\x77\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-1.79769313486e+308]), int64("-4_503_599_627_370_497")) + +// conversions.wast:665 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xf8\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [Infinity]), int64("9_218_868_437_227_405_312")) + +// conversions.wast:666 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf0\xff\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x78\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-Infinity]), int64("-4_503_599_627_370_496")) + +// conversions.wast:667 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfc\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [NaN]), int64("9_221_120_237_041_090_560")) + +// conversions.wast:668 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf8\xff\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x7c\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-NaN]), int64("-2_251_799_813_685_248")) + +// conversions.wast:669 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [NaN]), int64("9_219_994_337_134_247_936")) + +// conversions.wast:670 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x01\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x69\x36\x34\x2e\x72\x65\x69\x6e\x74\x65\x72\x70\x72\x65\x74\x5f\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\xf4\xff\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x7a\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "i64.reinterpret_f64", [-NaN]), int64("-3_377_699_720_527_872")) + +// conversions.wast:674 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\xa7\x0b"); + +// conversions.wast:675 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xa8\x0b"); + +// conversions.wast:676 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xa9\x0b"); + +// conversions.wast:677 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xaa\x0b"); + +// conversions.wast:678 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xab\x0b"); + +// conversions.wast:679 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xbc\x0b"); + +// conversions.wast:680 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\xac\x0b"); + +// conversions.wast:681 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\xad\x0b"); + +// conversions.wast:682 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xae\x0b"); + +// conversions.wast:683 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xaf\x0b"); + +// conversions.wast:684 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb0\x0b"); + +// conversions.wast:685 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb1\x0b"); + +// conversions.wast:686 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xbd\x0b"); + +// conversions.wast:687 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xb2\x0b"); + +// conversions.wast:688 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xb3\x0b"); + +// conversions.wast:689 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb4\x0b"); + +// conversions.wast:690 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb5\x0b"); + +// conversions.wast:691 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb6\x0b"); + +// conversions.wast:692 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xbe\x0b"); + +// conversions.wast:693 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xb7\x0b"); + +// conversions.wast:694 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\xb8\x0b"); + +// conversions.wast:695 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xb9\x0b"); + +// conversions.wast:696 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xba\x0b"); + +// conversions.wast:697 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xbb\x0b"); + +// conversions.wast:698 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\xbf\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/custom.wast.js b/js/src/jit-test/tests/wasm/spec/spec/custom.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/custom.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/custom.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/directives.txt b/js/src/jit-test/tests/wasm/spec/spec/directives.txt new file mode 100644 index 0000000000..ef444e9a95 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemoryIsSupported(); include:wasm-testharness.js; local-include:harness/sync_index.js \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/endianness.wast.js b/js/src/jit-test/tests/wasm/spec/spec/endianness.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/endianness.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/endianness.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f32.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f32.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f32.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f32.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f32_bitwise.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f32_bitwise.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f32_bitwise.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f32_bitwise.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f32_cmp.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f32_cmp.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f32_cmp.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f32_cmp.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f64.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f64.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f64.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f64.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f64_bitwise.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f64_bitwise.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f64_bitwise.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f64_bitwise.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/f64_cmp.wast.js b/js/src/jit-test/tests/wasm/spec/spec/f64_cmp.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/f64_cmp.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/f64_cmp.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/fac.wast.js b/js/src/jit-test/tests/wasm/spec/spec/fac.wast.js new file mode 100644 index 0000000000..8244bcc09e --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/fac.wast.js @@ -0,0 +1,24 @@ + +// fac.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9a\x80\x80\x80\x00\x04\x60\x01\x7e\x01\x7e\x60\x01\x7e\x02\x7e\x7e\x60\x02\x7e\x7e\x03\x7e\x7e\x7e\x60\x02\x7e\x7e\x01\x7e\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x00\x07\xcb\x80\x80\x80\x00\x06\x07\x66\x61\x63\x2d\x72\x65\x63\x00\x00\x0d\x66\x61\x63\x2d\x72\x65\x63\x2d\x6e\x61\x6d\x65\x64\x00\x01\x08\x66\x61\x63\x2d\x69\x74\x65\x72\x00\x02\x0e\x66\x61\x63\x2d\x69\x74\x65\x72\x2d\x6e\x61\x6d\x65\x64\x00\x03\x07\x66\x61\x63\x2d\x6f\x70\x74\x00\x04\x07\x66\x61\x63\x2d\x73\x73\x61\x00\x07\x0a\x8b\x82\x80\x80\x00\x08\x97\x80\x80\x80\x00\x00\x20\x00\x42\x00\x51\x04\x7e\x42\x01\x05\x20\x00\x20\x00\x42\x01\x7d\x10\x00\x7e\x0b\x0b\x97\x80\x80\x80\x00\x00\x20\x00\x42\x00\x51\x04\x7e\x42\x01\x05\x20\x00\x20\x00\x42\x01\x7d\x10\x01\x7e\x0b\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xac\x80\x80\x80\x00\x01\x01\x7e\x42\x01\x21\x01\x02\x40\x20\x00\x42\x02\x53\x0d\x00\x03\x40\x20\x01\x20\x00\x7e\x21\x01\x20\x00\x42\x7f\x7c\x21\x00\x20\x00\x42\x01\x55\x0d\x00\x0b\x0b\x20\x01\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x20\x00\x0b\x88\x80\x80\x80\x00\x00\x20\x00\x20\x01\x20\x00\x0b\x9c\x80\x80\x80\x00\x00\x42\x01\x20\x00\x03\x03\x10\x06\x10\x06\x7e\x10\x06\x42\x01\x7d\x10\x05\x42\x00\x56\x0d\x00\x1a\x0f\x0b\x0b"); + +// fac.wast:102 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x72\x65\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-rec", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:103 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x61\x63\x2d\x69\x74\x65\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-iter", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:104 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x02\x24\x31\x0d\x66\x61\x63\x2d\x72\x65\x63\x2d\x6e\x61\x6d\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-rec-named", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:105 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x66\x61\x63\x2d\x69\x74\x65\x72\x2d\x6e\x61\x6d\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-iter-named", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:106 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x6f\x70\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-opt", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:107 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x73\x73\x61\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-ssa", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// fac.wast:109 +assert_exhaustion(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x66\x61\x63\x2d\x72\x65\x63\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x04\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_exhaustion(() => call($1, "fac-rec", [int64("1_073_741_824")])) diff --git a/js/src/jit-test/tests/wasm/spec/float_exprs.wast.js b/js/src/jit-test/tests/wasm/spec/spec/float_exprs.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/float_exprs.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/float_exprs.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/float_literals.wast.js b/js/src/jit-test/tests/wasm/spec/spec/float_literals.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/float_literals.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/float_literals.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/float_memory.wast.js b/js/src/jit-test/tests/wasm/spec/spec/float_memory.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/float_memory.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/float_memory.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/float_misc.wast.js b/js/src/jit-test/tests/wasm/spec/spec/float_misc.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/float_misc.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/float_misc.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/forward.wast.js b/js/src/jit-test/tests/wasm/spec/spec/forward.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/forward.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/forward.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/func.wast.js b/js/src/jit-test/tests/wasm/spec/spec/func.wast.js similarity index 52% rename from js/src/jit-test/tests/wasm/spec/func.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/func.wast.js index 9e3c1f0942..898dafacc9 100644 --- a/js/src/jit-test/tests/wasm/spec/func.wast.js +++ b/js/src/jit-test/tests/wasm/spec/spec/func.wast.js @@ -1,369 +1,501 @@ // func.wast:3 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xe7\x80\x80\x80\x00\x13\x60\x00\x00\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x60\x03\x7f\x7c\x7f\x01\x7f\x60\x00\x00\x60\x03\x7f\x7c\x7e\x00\x60\x02\x7f\x7c\x00\x60\x05\x7f\x7d\x7e\x7f\x7c\x00\x60\x04\x7f\x7d\x7e\x7f\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x02\x7f\x7f\x01\x7f\x60\x02\x7e\x7e\x01\x7e\x60\x02\x7d\x7d\x01\x7d\x60\x02\x7c\x7c\x01\x7c\x60\x06\x7d\x7f\x7e\x7f\x7c\x7f\x01\x7c\x60\x01\x7f\x01\x7f\x03\xd0\x80\x80\x80\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x06\x07\x08\x02\x01\x02\x03\x04\x02\x03\x04\x00\x05\x09\x00\x02\x0a\x0b\x0c\x02\x0a\x0b\x0c\x0c\x0d\x0e\x0f\x10\x0d\x0e\x0f\x10\x11\x00\x00\x02\x0a\x0b\x0c\x00\x02\x00\x02\x0a\x0b\x0c\x02\x00\x02\x0a\x0b\x0c\x02\x03\x12\x03\x12\x03\x12\x02\x0a\x0b\x0c\x07\x88\x87\x80\x80\x00\x39\x01\x66\x00\x02\x01\x67\x00\x04\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x31\x00\x14\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x32\x00\x15\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x33\x00\x16\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x34\x00\x17\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x35\x00\x18\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x36\x00\x19\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x37\x00\x1a\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x1f\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x20\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x21\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x22\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x23\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x24\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x25\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x26\x0b\x6c\x6f\x63\x61\x6c\x2d\x6d\x69\x78\x65\x64\x00\x27\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x28\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x29\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x2a\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x2b\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x2c\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x2d\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x2e\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x2f\x0b\x70\x61\x72\x61\x6d\x2d\x6d\x69\x78\x65\x64\x00\x30\x05\x65\x6d\x70\x74\x79\x00\x31\x0a\x76\x61\x6c\x75\x65\x2d\x76\x6f\x69\x64\x00\x32\x09\x76\x61\x6c\x75\x65\x2d\x69\x33\x32\x00\x33\x09\x76\x61\x6c\x75\x65\x2d\x69\x36\x34\x00\x34\x09\x76\x61\x6c\x75\x65\x2d\x66\x33\x32\x00\x35\x09\x76\x61\x6c\x75\x65\x2d\x66\x36\x34\x00\x36\x10\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x6f\x69\x64\x00\x37\x0f\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x38\x0c\x72\x65\x74\x75\x72\x6e\x2d\x65\x6d\x70\x74\x79\x00\x39\x0a\x72\x65\x74\x75\x72\x6e\x2d\x69\x33\x32\x00\x3a\x0a\x72\x65\x74\x75\x72\x6e\x2d\x69\x36\x34\x00\x3b\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x33\x32\x00\x3c\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x36\x34\x00\x3d\x10\x72\x65\x74\x75\x72\x6e\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x3e\x0b\x62\x72\x65\x61\x6b\x2d\x65\x6d\x70\x74\x79\x00\x3f\x09\x62\x72\x65\x61\x6b\x2d\x69\x33\x32\x00\x40\x09\x62\x72\x65\x61\x6b\x2d\x69\x36\x34\x00\x41\x09\x62\x72\x65\x61\x6b\x2d\x66\x33\x32\x00\x42\x09\x62\x72\x65\x61\x6b\x2d\x66\x36\x34\x00\x43\x0f\x62\x72\x65\x61\x6b\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x44\x11\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x65\x6d\x70\x74\x79\x00\x45\x0f\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x6e\x75\x6d\x00\x46\x14\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x65\x6d\x70\x74\x79\x00\x47\x12\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x00\x48\x1b\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x65\x73\x74\x65\x64\x2d\x65\x6d\x70\x74\x79\x00\x49\x19\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x65\x73\x74\x65\x64\x2d\x6e\x75\x6d\x00\x4a\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x69\x33\x32\x00\x4b\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x69\x36\x34\x00\x4c\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x33\x32\x00\x4d\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x36\x34\x00\x4e\x0a\x8f\x87\x80\x80\x00\x4f\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x01\x01\x7f\x0b\x84\x80\x80\x80\x00\x01\x01\x7f\x0b\x88\x80\x80\x80\x00\x03\x01\x7f\x01\x7c\x01\x7e\x0b\x86\x80\x80\x80\x00\x02\x01\x7f\x01\x7c\x0b\x8c\x80\x80\x80\x00\x05\x01\x7f\x01\x7d\x01\x7e\x01\x7f\x01\x7c\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x83\x80\x80\x80\x00\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x90\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x00\x00\x0b\x90\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7f\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7d\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7c\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7f\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7e\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7d\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7c\x20\x01\x0b\xa8\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x20\x00\x8c\x1a\x20\x01\x45\x1a\x20\x02\x50\x1a\x20\x03\x45\x1a\x20\x04\x9a\x1a\x20\x05\x45\x1a\x20\x04\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x9c\x80\x80\x80\x00\x00\x20\x00\x8c\x1a\x20\x01\x45\x1a\x20\x02\x50\x1a\x20\x03\x45\x1a\x20\x04\x9a\x1a\x20\x05\x45\x1a\x20\x04\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x10\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xcd\x00\x0b\x85\x80\x80\x80\x00\x00\x42\xe1\x3c\x0b\x87\x80\x80\x80\x00\x00\x43\x66\x66\x9b\x42\x0b\x8b\x80\x80\x80\x00\x00\x44\xe1\x7a\x14\xae\x47\x71\x53\x40\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x10\x00\x10\x00\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0b\x83\x80\x80\x80\x00\x00\x0f\x0b\x86\x80\x80\x80\x00\x00\x41\xce\x00\x0f\x0b\x86\x80\x80\x80\x00\x00\x42\xc6\x3d\x0f\x0b\x88\x80\x80\x80\x00\x00\x43\x66\x66\x9d\x42\x0f\x0b\x8c\x80\x80\x80\x00\x00\x44\x52\xb8\x1e\x85\xeb\xb1\x53\x40\x0f\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0f\x0b\x84\x80\x80\x80\x00\x00\x0c\x00\x0b\x87\x80\x80\x80\x00\x00\x41\xcf\x00\x0c\x00\x0b\x87\x80\x80\x80\x00\x00\x42\xab\x3e\x0c\x00\x0b\x89\x80\x80\x80\x00\x00\x43\xcd\xcc\x9f\x42\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x44\xc3\xf5\x28\x5c\x8f\xf2\x53\x40\x0c\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0c\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x0d\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x32\x20\x00\x0d\x00\x1a\x41\x33\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x0e\x02\x00\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x32\x20\x00\x0e\x01\x00\x00\x41\x33\x0b\x8c\x80\x80\x80\x00\x00\x02\x40\x20\x00\x0e\x02\x00\x01\x00\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x32\x20\x00\x0e\x02\x00\x01\x00\x41\x33\x0b\x41\x02\x6a\x0b\x86\x80\x80\x80\x00\x01\x01\x7f\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7e\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7d\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7c\x20\x00\x0b"); +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xbc\x81\x80\x80\x00\x1c\x60\x00\x00\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x60\x03\x7f\x7c\x7f\x01\x7f\x60\x00\x00\x60\x03\x7f\x7c\x7e\x00\x60\x02\x7f\x7c\x00\x60\x05\x7f\x7d\x7e\x7f\x7c\x00\x60\x00\x03\x7f\x7c\x7d\x60\x00\x02\x7f\x7c\x60\x00\x05\x7f\x7d\x7e\x7f\x7c\x60\x04\x7f\x7d\x7e\x7f\x03\x7f\x7e\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x02\x7f\x7f\x01\x7f\x60\x02\x7e\x7e\x01\x7e\x60\x02\x7d\x7d\x01\x7d\x60\x02\x7c\x7c\x01\x7c\x60\x06\x7d\x7f\x7e\x7f\x7c\x7f\x01\x7c\x60\x00\x03\x7f\x7f\x7f\x60\x00\x02\x7f\x7e\x60\x01\x7f\x01\x7f\x60\x01\x7f\x02\x7f\x7e\x60\x01\x7f\x02\x7f\x7f\x60\x00\x02\x7f\x7f\x60\x11\x7f\x7e\x7d\x7d\x7f\x7c\x7d\x7f\x7f\x7f\x7d\x7c\x7c\x7c\x7f\x7f\x7d\x10\x7c\x7d\x7f\x7f\x7f\x7e\x7d\x7f\x7f\x7d\x7c\x7c\x7f\x7d\x7f\x7c\x03\xe2\x80\x80\x80\x00\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x06\x07\x08\x00\x00\x02\x09\x0a\x0b\x01\x02\x03\x04\x02\x03\x04\x00\x05\x0c\x00\x02\x0d\x0e\x0f\x02\x0d\x0e\x0f\x0f\x10\x11\x12\x13\x10\x11\x12\x13\x14\x00\x00\x02\x0d\x0e\x0f\x0a\x15\x00\x02\x16\x00\x02\x0d\x0e\x0f\x0a\x15\x02\x16\x00\x02\x0d\x0e\x0f\x0a\x15\x02\x16\x03\x17\x18\x03\x17\x18\x03\x17\x19\x1b\x02\x0d\x0e\x0f\x07\x94\x89\x80\x80\x00\x46\x01\x66\x00\x02\x01\x67\x00\x04\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x31\x00\x19\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x32\x00\x1a\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x33\x00\x1b\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x34\x00\x1c\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x35\x00\x1d\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x36\x00\x1e\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x37\x00\x1f\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x24\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x25\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x26\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x27\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x28\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x29\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x2a\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x2b\x0b\x6c\x6f\x63\x61\x6c\x2d\x6d\x69\x78\x65\x64\x00\x2c\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x69\x33\x32\x00\x2d\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x2e\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x2f\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x30\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x33\x32\x00\x31\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x32\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x33\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x34\x0b\x70\x61\x72\x61\x6d\x2d\x6d\x69\x78\x65\x64\x00\x35\x05\x65\x6d\x70\x74\x79\x00\x36\x0a\x76\x61\x6c\x75\x65\x2d\x76\x6f\x69\x64\x00\x37\x09\x76\x61\x6c\x75\x65\x2d\x69\x33\x32\x00\x38\x09\x76\x61\x6c\x75\x65\x2d\x69\x36\x34\x00\x39\x09\x76\x61\x6c\x75\x65\x2d\x66\x33\x32\x00\x3a\x09\x76\x61\x6c\x75\x65\x2d\x66\x36\x34\x00\x3b\x0d\x76\x61\x6c\x75\x65\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x3c\x11\x76\x61\x6c\x75\x65\x2d\x69\x33\x32\x2d\x69\x33\x32\x2d\x69\x33\x32\x00\x3d\x10\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x6f\x69\x64\x00\x3e\x0f\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x3f\x13\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x40\x0c\x72\x65\x74\x75\x72\x6e\x2d\x65\x6d\x70\x74\x79\x00\x41\x0a\x72\x65\x74\x75\x72\x6e\x2d\x69\x33\x32\x00\x42\x0a\x72\x65\x74\x75\x72\x6e\x2d\x69\x36\x34\x00\x43\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x33\x32\x00\x44\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x36\x34\x00\x45\x0e\x72\x65\x74\x75\x72\x6e\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x46\x12\x72\x65\x74\x75\x72\x6e\x2d\x69\x33\x32\x2d\x69\x33\x32\x2d\x69\x33\x32\x00\x47\x10\x72\x65\x74\x75\x72\x6e\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x48\x14\x72\x65\x74\x75\x72\x6e\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x49\x0b\x62\x72\x65\x61\x6b\x2d\x65\x6d\x70\x74\x79\x00\x4a\x09\x62\x72\x65\x61\x6b\x2d\x69\x33\x32\x00\x4b\x09\x62\x72\x65\x61\x6b\x2d\x69\x36\x34\x00\x4c\x09\x62\x72\x65\x61\x6b\x2d\x66\x33\x32\x00\x4d\x09\x62\x72\x65\x61\x6b\x2d\x66\x36\x34\x00\x4e\x0d\x62\x72\x65\x61\x6b\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x4f\x11\x62\x72\x65\x61\x6b\x2d\x69\x33\x32\x2d\x69\x33\x32\x2d\x69\x33\x32\x00\x50\x0f\x62\x72\x65\x61\x6b\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x00\x51\x13\x62\x72\x65\x61\x6b\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x52\x11\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x65\x6d\x70\x74\x79\x00\x53\x0f\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x6e\x75\x6d\x00\x54\x13\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x55\x14\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x65\x6d\x70\x74\x79\x00\x56\x12\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x00\x57\x16\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x58\x1b\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x65\x73\x74\x65\x64\x2d\x65\x6d\x70\x74\x79\x00\x59\x19\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x65\x73\x74\x65\x64\x2d\x6e\x75\x6d\x00\x5a\x1d\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x65\x73\x74\x65\x64\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x5b\x09\x6c\x61\x72\x67\x65\x2d\x73\x69\x67\x00\x5c\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x69\x33\x32\x00\x5d\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x69\x36\x34\x00\x5e\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x33\x32\x00\x5f\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x36\x34\x00\x60\x0a\xbb\x89\x80\x80\x00\x61\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x01\x01\x7f\x0b\x84\x80\x80\x80\x00\x01\x01\x7f\x0b\x88\x80\x80\x80\x00\x03\x01\x7f\x01\x7c\x01\x7e\x0b\x86\x80\x80\x80\x00\x02\x01\x7f\x01\x7c\x0b\x8c\x80\x80\x80\x00\x05\x01\x7f\x01\x7d\x01\x7e\x01\x7f\x01\x7c\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x83\x80\x80\x80\x00\x00\x00\x0b\x83\x80\x80\x80\x00\x00\x00\x0b\x83\x80\x80\x80\x00\x00\x00\x0b\x83\x80\x80\x80\x00\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x41\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x90\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x00\x00\x0b\x90\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7f\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7d\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7c\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x02\x7f\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7e\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7d\x20\x01\x0b\x86\x80\x80\x80\x00\x01\x02\x7c\x20\x01\x0b\xa8\x80\x80\x80\x00\x06\x01\x7d\x01\x7f\x01\x7e\x01\x7f\x01\x7c\x01\x7f\x20\x00\x8c\x1a\x20\x01\x45\x1a\x20\x02\x50\x1a\x20\x03\x45\x1a\x20\x04\x9a\x1a\x20\x05\x45\x1a\x20\x04\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x01\x0b\x9c\x80\x80\x80\x00\x00\x20\x00\x8c\x1a\x20\x01\x45\x1a\x20\x02\x50\x1a\x20\x03\x45\x1a\x20\x04\x9a\x1a\x20\x05\x45\x1a\x20\x04\x0b\x82\x80\x80\x80\x00\x00\x0b\x84\x80\x80\x80\x00\x00\x10\x00\x0b\x85\x80\x80\x80\x00\x00\x41\xcd\x00\x0b\x85\x80\x80\x80\x00\x00\x42\xe1\x3c\x0b\x87\x80\x80\x80\x00\x00\x43\x66\x66\x9b\x42\x0b\x8b\x80\x80\x80\x00\x00\x44\xe1\x7a\x14\xae\x47\x71\x53\x40\x0b\x8e\x80\x80\x80\x00\x00\x41\xcd\x00\x44\x00\x00\x00\x00\x00\x00\x1c\x40\x0b\x88\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x03\x0b\x89\x80\x80\x80\x00\x00\x02\x40\x10\x00\x10\x00\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0b\x8b\x80\x80\x80\x00\x00\x02\x16\x10\x00\x41\x01\x42\x02\x0b\x0b\x83\x80\x80\x80\x00\x00\x0f\x0b\x86\x80\x80\x80\x00\x00\x41\xce\x00\x0f\x0b\x86\x80\x80\x80\x00\x00\x42\xc6\x3d\x0f\x0b\x88\x80\x80\x80\x00\x00\x43\x66\x66\x9d\x42\x0f\x0b\x8c\x80\x80\x80\x00\x00\x44\x52\xb8\x1e\x85\xeb\xb1\x53\x40\x0f\x0b\x8f\x80\x80\x80\x00\x00\x41\xce\x00\x44\x52\xb8\x1e\x85\xeb\xb1\x53\x40\x0f\x0b\x89\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x03\x0f\x0b\x8b\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0f\x0b\x8c\x80\x80\x80\x00\x00\x02\x16\x10\x00\x41\x01\x42\x02\x0b\x0f\x0b\x84\x80\x80\x80\x00\x00\x0c\x00\x0b\x87\x80\x80\x80\x00\x00\x41\xcf\x00\x0c\x00\x0b\x87\x80\x80\x80\x00\x00\x42\xab\x3e\x0c\x00\x0b\x89\x80\x80\x80\x00\x00\x43\xcd\xcc\x9f\x42\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x44\xc3\xf5\x28\x5c\x8f\xf2\x53\x40\x0c\x00\x0b\x90\x80\x80\x80\x00\x00\x41\xcf\x00\x44\xc3\xf5\x28\x5c\x8f\xf2\x53\x40\x0c\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x41\x03\x0c\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\xcd\x00\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x16\x10\x00\x41\x01\x42\x02\x0b\x0c\x00\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x0d\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x32\x20\x00\x0d\x00\x1a\x41\x33\x0b\x90\x80\x80\x80\x00\x00\x41\x32\x42\x33\x20\x00\x0d\x00\x1a\x1a\x41\x33\x42\x34\x0b\x89\x80\x80\x80\x00\x00\x20\x00\x0e\x02\x00\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x32\x20\x00\x0e\x01\x00\x00\x41\x33\x0b\x90\x80\x80\x80\x00\x00\x41\x32\x42\x33\x20\x00\x0e\x01\x00\x00\x41\x33\x42\x34\x0b\x8c\x80\x80\x80\x00\x00\x02\x40\x20\x00\x0e\x02\x00\x01\x00\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x32\x20\x00\x0e\x02\x00\x01\x00\x41\x33\x0b\x41\x02\x6a\x0b\x97\x80\x80\x80\x00\x00\x02\x1a\x41\x32\x41\x33\x20\x00\x0e\x02\x00\x01\x00\x41\x33\x41\x7d\x0b\x6a\x41\x34\x0b\xa2\x80\x80\x80\x00\x00\x20\x05\x20\x02\x20\x00\x20\x08\x20\x07\x20\x01\x20\x03\x20\x09\x20\x04\x20\x06\x20\x0d\x20\x0b\x20\x0f\x20\x10\x20\x0e\x20\x0c\x0b\x86\x80\x80\x80\x00\x01\x01\x7f\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7e\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7d\x20\x00\x0b\x86\x80\x80\x80\x00\x01\x01\x7c\x20\x00\x0b"); -// func.wast:171 +// func.wast:241 assert_return(() => call($1, "type-use-1", [])); -// func.wast:172 +// func.wast:242 assert_return(() => call($1, "type-use-2", []), 0); -// func.wast:173 +// func.wast:243 assert_return(() => call($1, "type-use-3", [1])); -// func.wast:174 +// func.wast:244 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7c\x7f\x01\x7f\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-use-4", [1, 1., 1]), 0) -// func.wast:178 +// func.wast:248 assert_return(() => call($1, "type-use-5", []), 0); -// func.wast:179 +// func.wast:249 assert_return(() => call($1, "type-use-6", [1])); -// func.wast:180 +// func.wast:250 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7f\x7c\x7f\x01\x7f\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x74\x79\x70\x65\x2d\x75\x73\x65\x2d\x37\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-use-7", [1, 1., 1]), 0) -// func.wast:185 +// func.wast:255 assert_return(() => call($1, "local-first-i32", []), 0); -// func.wast:186 +// func.wast:256 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-first-i64", []), int64("0")) -// func.wast:187 +// func.wast:257 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-first-f32", []), 0.) -// func.wast:188 +// func.wast:258 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x6c\x6f\x63\x61\x6c\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-first-f64", []), 0.) -// func.wast:189 +// func.wast:259 assert_return(() => call($1, "local-second-i32", []), 0); -// func.wast:190 +// func.wast:260 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-second-i64", []), int64("0")) -// func.wast:191 +// func.wast:261 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-second-f32", []), 0.) -// func.wast:192 +// func.wast:262 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x6c\x6f\x63\x61\x6c\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-second-f64", []), 0.) -// func.wast:193 +// func.wast:263 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x92\x80\x80\x80\x00\x01\x02\x24\x31\x0b\x6c\x6f\x63\x61\x6c\x2d\x6d\x69\x78\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "local-mixed", []), 0.) -// func.wast:195 +// func.wast:265 assert_return(() => call($1, "param-first-i32", [2, 3]), 2); -// func.wast:198 +// func.wast:268 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x03\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-first-i64", [int64("2"), int64("3")]), int64("2")) -// func.wast:201 +// func.wast:271 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\x40\x40\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-first-f32", [2., 3.]), 2.) -// func.wast:204 +// func.wast:274 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7c\x7c\x01\x7c\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x70\x61\x72\x61\x6d\x2d\x66\x69\x72\x73\x74\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\x08\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-first-f64", [2., 3.]), 2.) -// func.wast:207 +// func.wast:277 assert_return(() => call($1, "param-second-i32", [2, 3]), 3); -// func.wast:210 +// func.wast:280 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x02\x42\x03\x10\x00\x01\x42\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-second-i64", [int64("2"), int64("3")]), int64("3")) -// func.wast:213 +// func.wast:283 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\x40\x40\x10\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-second-f32", [2., 3.]), 3.) -// func.wast:216 +// func.wast:286 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7c\x7c\x01\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x70\x61\x72\x61\x6d\x2d\x73\x65\x63\x6f\x6e\x64\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb0\x80\x80\x80\x00\x01\xaa\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x40\x44\x00\x00\x00\x00\x00\x00\x08\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x08\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-second-f64", [2., 3.]), 3.) -// func.wast:220 +// func.wast:290 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x02\x60\x00\x00\x60\x06\x7d\x7f\x7e\x7f\x7c\x7f\x01\x7c\x02\x92\x80\x80\x80\x00\x01\x02\x24\x31\x0b\x70\x61\x72\x61\x6d\x2d\x6d\x69\x78\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb4\x80\x80\x80\x00\x01\xae\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x41\x02\x42\x03\x41\x04\x44\x00\x00\x00\x00\x00\x00\x16\x40\x41\x06\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x16\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "param-mixed", [1., 2, int64("3"), 4, 5.5, 6]), 5.5) -// func.wast:228 +// func.wast:298 assert_return(() => call($1, "empty", [])); -// func.wast:229 +// func.wast:299 assert_return(() => call($1, "value-void", [])); -// func.wast:230 +// func.wast:300 assert_return(() => call($1, "value-i32", []), 77); -// func.wast:231 +// func.wast:301 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x76\x61\x6c\x75\x65\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xe1\x3c\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "value-i64", []), int64("7_777")) -// func.wast:232 +// func.wast:302 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x76\x61\x6c\x75\x65\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x66\x66\x9b\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "value-f32", []), 77.6999969482) -// func.wast:233 +// func.wast:303 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x76\x61\x6c\x75\x65\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xe1\x7a\x14\xae\x47\x71\x53\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "value-f64", []), 77.77) -// func.wast:234 +// func.wast:304 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x94\x80\x80\x80\x00\x01\x02\x24\x31\x0d\x76\x61\x6c\x75\x65\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x1c\x40\xbd\x51\x45\x0d\x00\x01\x41\xcd\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "value-i32-f64", []), 77, 7.) + +// func.wast:305 +assert_return(() => call($1, "value-i32-i32-i32", []), 1, 2, 3); + +// func.wast:308 assert_return(() => call($1, "value-block-void", [])); -// func.wast:235 +// func.wast:309 assert_return(() => call($1, "value-block-i32", []), 77); -// func.wast:237 +// func.wast:310 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x76\x61\x6c\x75\x65\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "value-block-i32-i64", []), 1, int64("2")) + +// func.wast:312 assert_return(() => call($1, "return-empty", [])); -// func.wast:238 +// func.wast:313 assert_return(() => call($1, "return-i32", []), 78); -// func.wast:239 +// func.wast:314 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x72\x65\x74\x75\x72\x6e\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xc6\x3d\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "return-i64", []), int64("7_878")) -// func.wast:240 +// func.wast:315 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x66\x66\x9d\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "return-f32", []), 78.6999969482) -// func.wast:241 +// func.wast:316 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x72\x65\x74\x75\x72\x6e\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x52\xb8\x1e\x85\xeb\xb1\x53\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "return-f64", []), 78.78) -// func.wast:242 +// func.wast:317 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x72\x65\x74\x75\x72\x6e\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x52\xb8\x1e\x85\xeb\xb1\x53\x40\xbd\x51\x45\x0d\x00\x01\x41\xce\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "return-i32-f64", []), 78, 78.78) + +// func.wast:318 +assert_return(() => call($1, "return-i32-i32-i32", []), 1, 2, 3); + +// func.wast:321 assert_return(() => call($1, "return-block-i32", []), 77); -// func.wast:244 +// func.wast:322 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7e\x02\x9b\x80\x80\x80\x00\x01\x02\x24\x31\x14\x72\x65\x74\x75\x72\x6e\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "return-block-i32-i64", []), 1, int64("2")) + +// func.wast:324 assert_return(() => call($1, "break-empty", [])); -// func.wast:245 +// func.wast:325 assert_return(() => call($1, "break-i32", []), 79); -// func.wast:246 +// func.wast:326 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x62\x72\x65\x61\x6b\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\xab\x3e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-i64", []), int64("7_979")) -// func.wast:247 +// func.wast:327 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x62\x72\x65\x61\x6b\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\xcd\xcc\x9f\x42\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-f32", []), 79.9000015259) -// func.wast:248 +// func.wast:328 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x62\x72\x65\x61\x6b\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xc3\xf5\x28\x5c\x8f\xf2\x53\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-f64", []), 79.79) -// func.wast:249 +// func.wast:329 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7c\x02\x94\x80\x80\x80\x00\x01\x02\x24\x31\x0d\x62\x72\x65\x61\x6b\x2d\x69\x33\x32\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\xc3\xf5\x28\x5c\x8f\xf2\x53\x40\xbd\x51\x45\x0d\x00\x01\x41\xcf\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-i32-f64", []), 79, 79.79) + +// func.wast:330 +assert_return(() => call($1, "break-i32-i32-i32", []), 1, 2, 3); + +// func.wast:333 assert_return(() => call($1, "break-block-i32", []), 77); -// func.wast:251 +// func.wast:334 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x02\x7f\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x62\x72\x65\x61\x6b\x2d\x62\x6c\x6f\x63\x6b\x2d\x69\x33\x32\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9f\x80\x80\x80\x00\x01\x99\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-block-i32-i64", []), 1, int64("2")) + +// func.wast:336 assert_return(() => call($1, "break-br_if-empty", [0])); -// func.wast:252 +// func.wast:337 assert_return(() => call($1, "break-br_if-empty", [2])); -// func.wast:253 +// func.wast:338 assert_return(() => call($1, "break-br_if-num", [0]), 51); -// func.wast:254 +// func.wast:339 assert_return(() => call($1, "break-br_if-num", [1]), 50); -// func.wast:256 +// func.wast:340 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\x34\x01\x51\x45\x0d\x00\x01\x41\x33\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_if-num-num", [0]), 51, int64("52")) + +// func.wast:343 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9a\x80\x80\x80\x00\x01\x02\x24\x31\x13\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x69\x66\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\x01\x42\x33\x01\x51\x45\x0d\x00\x01\x41\x32\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_if-num-num", [1]), 50, int64("51")) + +// func.wast:347 assert_return(() => call($1, "break-br_table-empty", [0])); -// func.wast:257 +// func.wast:348 assert_return(() => call($1, "break-br_table-empty", [1])); -// func.wast:258 +// func.wast:349 assert_return(() => call($1, "break-br_table-empty", [5])); -// func.wast:259 +// func.wast:350 assert_return(() => call($1, "break-br_table-empty", [-1])); -// func.wast:260 +// func.wast:351 assert_return(() => call($1, "break-br_table-num", [0]), 50); -// func.wast:261 +// func.wast:352 assert_return(() => call($1, "break-br_table-num", [1]), 50); -// func.wast:262 +// func.wast:353 assert_return(() => call($1, "break-br_table-num", [10]), 50); -// func.wast:263 +// func.wast:354 assert_return(() => call($1, "break-br_table-num", [-100]), 50); -// func.wast:264 +// func.wast:355 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9d\x80\x80\x80\x00\x01\x02\x24\x31\x16\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\x33\x01\x51\x45\x0d\x00\x01\x41\x32\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_table-num-num", [0]), 50, int64("51")) + +// func.wast:358 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9d\x80\x80\x80\x00\x01\x02\x24\x31\x16\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\x01\x42\x33\x01\x51\x45\x0d\x00\x01\x41\x32\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_table-num-num", [1]), 50, int64("51")) + +// func.wast:361 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9d\x80\x80\x80\x00\x01\x02\x24\x31\x16\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x41\x0a\x10\x00\x01\x42\x33\x01\x51\x45\x0d\x00\x01\x41\x32\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_table-num-num", [10]), 50, int64("51")) + +// func.wast:364 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x02\x7f\x7e\x02\x9d\x80\x80\x80\x00\x01\x02\x24\x31\x16\x62\x72\x65\x61\x6b\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6e\x75\x6d\x2d\x6e\x75\x6d\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x41\x9c\x7f\x10\x00\x01\x42\x33\x01\x51\x45\x0d\x00\x01\x41\x32\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-br_table-num-num", [-100]), 50, int64("51")) + +// func.wast:367 assert_return(() => call($1, "break-br_table-nested-empty", [0])); -// func.wast:265 +// func.wast:368 assert_return(() => call($1, "break-br_table-nested-empty", [1])); -// func.wast:266 +// func.wast:369 assert_return(() => call($1, "break-br_table-nested-empty", [3])); -// func.wast:267 +// func.wast:370 assert_return(() => call($1, "break-br_table-nested-empty", [-2])); -// func.wast:268 +// func.wast:371 assert_return(() => call($1, "break-br_table-nested-num", [0]), 52); -// func.wast:271 +// func.wast:374 assert_return(() => call($1, "break-br_table-nested-num", [1]), 50); -// func.wast:274 +// func.wast:377 assert_return(() => call($1, "break-br_table-nested-num", [2]), 52); -// func.wast:277 +// func.wast:380 assert_return(() => call($1, "break-br_table-nested-num", [-3]), 52); -// func.wast:281 +// func.wast:383 +assert_return(() => call($1, "break-br_table-nested-num-num", [0]), 101, 52); + +// func.wast:387 +assert_return(() => call($1, "break-br_table-nested-num-num", [1]), 50, 51); + +// func.wast:391 +assert_return(() => call($1, "break-br_table-nested-num-num", [2]), 101, 52); + +// func.wast:395 +assert_return(() => call($1, "break-br_table-nested-num-num", [-3]), 101, 52); + +// func.wast:400 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa8\x80\x80\x80\x00\x02\x60\x00\x00\x60\x11\x7f\x7e\x7d\x7d\x7f\x7c\x7d\x7f\x7f\x7f\x7d\x7c\x7c\x7c\x7f\x7f\x7d\x10\x7c\x7d\x7f\x7f\x7f\x7e\x7d\x7f\x7f\x7d\x7c\x7c\x7f\x7d\x7f\x7c\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x6c\x61\x72\x67\x65\x2d\x73\x69\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x84\x82\x80\x80\x00\x01\xfe\x81\x80\x80\x00\x00\x02\x40\x41\x00\x42\x01\x43\x00\x00\x00\x40\x43\x00\x00\x40\x40\x41\x04\x44\x00\x00\x00\x00\x00\x00\x14\x40\x43\x00\x00\xc0\x40\x41\x07\x41\x08\x41\x09\x43\x00\x00\x20\x41\x44\x00\x00\x00\x00\x00\x00\x26\x40\x44\x00\x00\x00\x00\x00\x00\x28\x40\x44\x00\x00\x00\x00\x00\x00\x2a\x40\x41\x0e\x41\x0f\x43\x00\x00\x80\x41\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x28\x40\xbd\x51\x45\x0d\x00\x01\x41\x0e\x01\x46\x45\x0d\x00\xbc\x43\x00\x00\x80\x41\xbc\x46\x45\x0d\x00\x01\x41\x0f\x01\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x26\x40\xbd\x51\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x2a\x40\xbd\x51\x45\x0d\x00\xbc\x43\x00\x00\xc0\x40\xbc\x46\x45\x0d\x00\x01\x41\x04\x01\x46\x45\x0d\x00\x01\x41\x09\x01\x46\x45\x0d\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x01\x41\x07\x01\x46\x45\x0d\x00\x01\x41\x08\x01\x46\x45\x0d\x00\x01\x41\x00\x01\x46\x45\x0d\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x14\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "large-sig", [0, int64("1"), 2., 3., 4, 5., 6., 7, 8, 9, 10., 11., 12., 13., 14, 15, 16.]), 5., 2., 0, 8, 7, int64("1"), 3., 9, 4, 6., 13., 11., 15, 16., 14, 12.) + +// func.wast:414 assert_return(() => call($1, "init-local-i32", []), 0); -// func.wast:282 +// func.wast:415 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x69\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "init-local-i64", []), int64("0")) -// func.wast:283 +// func.wast:416 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x33\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "init-local-f32", []), 0.) -// func.wast:284 +// func.wast:417 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x69\x6e\x69\x74\x2d\x6c\x6f\x63\x61\x6c\x2d\x66\x36\x34\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "init-local-f64", []), 0.) -// func.wast:289 +// func.wast:422 let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x01\x7f\x00\x60\x00\x01\x7c\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x01\x00\x00\x01\x02\x0a\xbd\x80\x80\x80\x00\x05\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x10\x02\x10\x03\x1a\x0b"); -// func.wast:302 +// func.wast:435 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x00\x60\x00\x01\x7c\x03\x85\x80\x80\x80\x00\x04\x01\x00\x01\x02\x0a\xaf\x80\x80\x80\x00\x04\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8b\x80\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x82\x80\x80\x80\x00\x00\x0b"); -// func.wast:315 +// func.wast:448 let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9d\x80\x80\x80\x00\x04\x60\x00\x00\x60\x00\x00\x60\x08\x7e\x7e\x7c\x7e\x7c\x7e\x7d\x7f\x00\x60\x08\x7c\x7e\x7c\x7e\x7c\x7e\x7d\x7f\x00\x03\x8c\x80\x80\x80\x00\x0b\x00\x03\x00\x03\x03\x02\x02\x00\x00\x00\x00\x04\x85\x80\x80\x80\x00\x01\x70\x01\x07\x07\x07\xf7\x80\x80\x80\x00\x04\x19\x73\x69\x67\x6e\x61\x74\x75\x72\x65\x2d\x65\x78\x70\x6c\x69\x63\x69\x74\x2d\x72\x65\x75\x73\x65\x64\x00\x07\x19\x73\x69\x67\x6e\x61\x74\x75\x72\x65\x2d\x69\x6d\x70\x6c\x69\x63\x69\x74\x2d\x72\x65\x75\x73\x65\x64\x00\x08\x1c\x73\x69\x67\x6e\x61\x74\x75\x72\x65\x2d\x65\x78\x70\x6c\x69\x63\x69\x74\x2d\x64\x75\x70\x6c\x69\x63\x61\x74\x65\x00\x09\x1c\x73\x69\x67\x6e\x61\x74\x75\x72\x65\x2d\x69\x6d\x70\x6c\x69\x63\x69\x74\x2d\x64\x75\x70\x6c\x69\x63\x61\x74\x65\x00\x0a\x09\x8d\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x07\x04\x02\x01\x04\x00\x05\x06\x0a\xb0\x82\x80\x80\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x11\x00\x00\x41\x04\x11\x00\x00\x0b\x89\x81\x80\x80\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x41\x00\x41\x00\x11\x03\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x41\x00\x41\x02\x11\x03\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x41\x00\x41\x03\x11\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x01\x11\x01\x00\x0b\xce\x80\x80\x80\x00\x00\x42\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x41\x00\x41\x05\x11\x02\x00\x42\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x43\x00\x00\x00\x00\x41\x00\x41\x06\x11\x02\x00\x0b"); -// func.wast:378 +// func.wast:511 assert_return(() => call($3, "signature-explicit-reused", [])); -// func.wast:379 +// func.wast:512 assert_return(() => call($3, "signature-implicit-reused", [])); -// func.wast:380 +// func.wast:513 assert_return(() => call($3, "signature-explicit-duplicate", [])); -// func.wast:381 +// func.wast:514 assert_return(() => call($3, "signature-implicit-duplicate", [])); -// func.wast:386 +// func.wast:519 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:393 +// func.wast:526 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:400 +// func.wast:533 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:407 +// func.wast:540 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:414 +// func.wast:547 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:421 +// func.wast:554 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:428 +// func.wast:561 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:435 +// func.wast:568 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:442 +// func.wast:575 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:449 +// func.wast:582 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:460 +// func.wast:593 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x01\x01\x7f\x20\x00\x0b"); -// func.wast:464 +// func.wast:597 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x01\x01\x7d\x20\x00\x45\x0b"); -// func.wast:468 +// func.wast:601 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x02\x01\x7c\x01\x7e\x20\x01\x9a\x0b"); -// func.wast:476 +// func.wast:609 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x01\x7f\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); -// func.wast:480 +// func.wast:613 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x01\x7d\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x20\x00\x45\x0b"); -// func.wast:484 +// func.wast:617 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x02\x7c\x7e\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x20\x01\x9a\x0b"); -// func.wast:492 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x00\x0b"); - -// func.wast:496 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x00\x0b"); - -// func.wast:505 +// func.wast:625 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); -// func.wast:509 +// func.wast:629 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); -// func.wast:513 +// func.wast:633 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); -// func.wast:517 +// func.wast:637 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); -// func.wast:522 +// func.wast:641 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7c\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b"); + +// func.wast:646 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x01\x0b"); -// func.wast:528 +// func.wast:652 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x01\x0b"); + +// func.wast:658 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x41\x00\x0b"); -// func.wast:534 +// func.wast:664 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x42\x00\x0b"); + +// func.wast:670 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x0b"); -// func.wast:541 +// func.wast:676 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7d\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x0b"); + +// func.wast:682 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x43\x00\x00\x00\x00\x0b"); + +// func.wast:689 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x0f\x0b"); -// func.wast:547 +// func.wast:695 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x89\x80\x80\x80\x00\x01\x83\x80\x80\x80\x00\x00\x0f\x0b"); + +// func.wast:701 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x01\x0f\x0b"); -// func.wast:553 +// func.wast:707 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x01\x0f\x0b"); + +// func.wast:713 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x0f\x0b"); -// func.wast:560 +// func.wast:719 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7e\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x0f\x0b"); + +// func.wast:726 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x0f\x41\x01\x0b"); -// func.wast:566 +// func.wast:732 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x0f\x41\x01\x41\x02\x0b"); + +// func.wast:738 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x01\x0f\x41\x02\x0b"); + +// func.wast:744 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x01\x0f\x41\x01\x0b"); -// func.wast:572 +// func.wast:750 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x01\x0f\x41\x01\x0b"); + +// func.wast:756 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x42\x01\x0f\x41\x01\x0b"); -// func.wast:578 +// func.wast:762 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x42\x01\x0f\x41\x01\x41\x02\x0b"); + +// func.wast:768 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x42\x01\x0f\x41\x01\x0f\x0b"); -// func.wast:585 +// func.wast:774 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x0f\x41\x01\x41\x02\x0f\x0b"); + +// func.wast:781 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x0c\x00\x0b"); -// func.wast:591 +// func.wast:787 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x0c\x00\x0b"); + +// func.wast:793 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x0c\x00\x0b"); -// func.wast:597 +// func.wast:799 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x0c\x00\x0b"); + +// func.wast:805 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x0c\x00\x41\x01\x0b"); -// func.wast:603 +// func.wast:811 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x0c\x00\x41\x01\x41\x02\x0b"); + +// func.wast:817 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x42\x01\x0c\x00\x41\x01\x0b"); -// func.wast:609 +// func.wast:823 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x0c\x00\x41\x01\x41\x02\x0b"); + +// func.wast:829 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x01\x0c\x00\x41\x01\x0c\x00\x0b"); -// func.wast:616 +// func.wast:836 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x0c\x01\x0b\x41\x01\x0c\x00\x0b"); -// func.wast:622 +// func.wast:842 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b"); + +// func.wast:848 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x01\x0b\x41\x01\x0c\x00\x0b"); -// func.wast:628 +// func.wast:854 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x01\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b"); + +// func.wast:860 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x01\x0c\x01\x0b\x41\x01\x0c\x00\x0b"); -// func.wast:638 +// func.wast:866 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0c\x01\x0b\x41\x01\x41\x02\x0c\x00\x0b"); + +// func.wast:876 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:642 +// func.wast:880 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:646 +// func.wast:884 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:650 +// func.wast:888 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:654 +// func.wast:892 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); -// func.wast:658 +// func.wast:896 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:903 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:907 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:911 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:916 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:918 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// func.wast:920 assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/func_ptrs.wast.js b/js/src/jit-test/tests/wasm/spec/spec/func_ptrs.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/func_ptrs.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/func_ptrs.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/globals.wast.js b/js/src/jit-test/tests/wasm/spec/spec/global.wast.js similarity index 91% rename from js/src/jit-test/tests/wasm/spec/globals.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/global.wast.js index 5ce082d2c9..26581a9cdc 100644 --- a/js/src/jit-test/tests/wasm/spec/globals.wast.js +++ b/js/src/jit-test/tests/wasm/spec/spec/global.wast.js @@ -1,234 +1,243 @@ -// globals.wast:3 +// global.wast:3 let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xaf\x80\x80\x80\x00\x0b\x60\x02\x7f\x7f\x01\x7f\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x01\x7f\x00\x60\x01\x7e\x00\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x01\x7d\x00\x60\x01\x7c\x00\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\xae\x80\x80\x80\x00\x2d\x01\x02\x01\x02\x03\x04\x05\x06\x05\x06\x07\x08\x09\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x09\x09\x01\x01\x0a\x01\x01\x09\x01\x0a\x0a\x01\x01\x01\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\xbd\x80\x80\x80\x00\x08\x7f\x00\x41\x7e\x0b\x7d\x00\x43\x00\x00\x40\xc0\x0b\x7c\x00\x44\x00\x00\x00\x00\x00\x00\x10\xc0\x0b\x7e\x00\x42\x7b\x0b\x7f\x01\x41\x74\x0b\x7d\x01\x43\x00\x00\x50\xc1\x0b\x7c\x01\x44\x00\x00\x00\x00\x00\x00\x2c\xc0\x0b\x7e\x01\x42\x71\x0b\x07\x85\x85\x80\x80\x00\x2a\x05\x67\x65\x74\x2d\x61\x00\x00\x05\x67\x65\x74\x2d\x62\x00\x01\x05\x67\x65\x74\x2d\x78\x00\x02\x05\x67\x65\x74\x2d\x79\x00\x03\x05\x73\x65\x74\x2d\x78\x00\x04\x05\x73\x65\x74\x2d\x79\x00\x05\x05\x67\x65\x74\x2d\x31\x00\x06\x05\x67\x65\x74\x2d\x32\x00\x07\x05\x67\x65\x74\x2d\x35\x00\x08\x05\x67\x65\x74\x2d\x36\x00\x09\x05\x73\x65\x74\x2d\x35\x00\x0a\x05\x73\x65\x74\x2d\x36\x00\x0b\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x0d\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x0e\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x0f\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x10\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x11\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x12\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x13\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x14\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x15\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x16\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x17\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x18\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x19\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x1b\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x1c\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x1d\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x1e\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x1f\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x20\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x21\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x23\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x24\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x25\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x26\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x27\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x28\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x29\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2a\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2b\x12\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x2c\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x1a\x0a\xc9\x84\x80\x80\x00\x2d\x84\x80\x80\x80\x00\x00\x23\x00\x0b\x84\x80\x80\x80\x00\x00\x23\x03\x0b\x84\x80\x80\x80\x00\x00\x23\x04\x0b\x84\x80\x80\x80\x00\x00\x23\x07\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x04\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x07\x0b\x84\x80\x80\x80\x00\x00\x23\x01\x0b\x84\x80\x80\x80\x00\x00\x23\x02\x0b\x84\x80\x80\x80\x00\x00\x23\x05\x0b\x84\x80\x80\x80\x00\x00\x23\x06\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x05\x0b\x86\x80\x80\x80\x00\x00\x20\x00\x24\x06\x0b\x82\x80\x80\x80\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x23\x04\x41\x02\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x23\x04\x41\x03\x1b\x0b\x89\x80\x80\x80\x00\x00\x41\x02\x41\x03\x23\x04\x1b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x23\x04\x10\x0c\x10\x0c\x0b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x10\x0c\x23\x04\x10\x0c\x0b\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x10\x0c\x10\x0c\x23\x04\x0b\x0b\x90\x80\x80\x80\x00\x00\x23\x04\x04\x7f\x10\x0c\x41\x02\x05\x10\x0c\x41\x03\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x23\x04\x05\x41\x02\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x41\x02\x05\x23\x04\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x0d\x00\x41\x03\x0f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x0d\x00\x41\x03\x0f\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x0e\x01\x00\x00\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x23\x04\x41\x00\x11\x00\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x23\x04\x11\x00\x00\x0b\x0b\x89\x80\x80\x80\x00\x00\x23\x04\x41\x01\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x23\x04\x36\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x23\x04\x28\x02\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x10\x22\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x0f\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x1a\x0b\x89\x80\x80\x80\x00\x00\x02\x7f\x23\x04\x0c\x00\x0b\x0b\x88\x80\x80\x80\x00\x00\x23\x04\x21\x00\x20\x00\x0b\x86\x80\x80\x80\x00\x00\x23\x04\x22\x00\x0b\x88\x80\x80\x80\x00\x00\x23\x04\x24\x04\x23\x04\x0b\x85\x80\x80\x80\x00\x00\x23\x04\x45\x0b\x87\x80\x80\x80\x00\x00\x23\x04\x23\x04\x6c\x0b\x87\x80\x80\x80\x00\x00\x23\x00\x41\x01\x4b\x0b"); -// globals.wast:181 +// global.wast:181 assert_return(() => call($1, "get-a", []), -2); -// globals.wast:182 +// global.wast:182 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x7b\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-b", []), int64("-5")) -// globals.wast:183 +// global.wast:183 assert_return(() => call($1, "get-x", []), -12); -// globals.wast:184 +// global.wast:184 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x71\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-y", []), int64("-15")) -// globals.wast:186 +// global.wast:186 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x31\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x40\xc0\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-1", []), -3.) -// globals.wast:187 +// global.wast:187 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x32\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\xc0\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-2", []), -4.) -// globals.wast:188 +// global.wast:188 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x50\xc1\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-5", []), -13.) -// globals.wast:189 +// global.wast:189 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x36\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x2c\xc0\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-6", []), -14.) -// globals.wast:191 +// global.wast:191 assert_return(() => call($1, "set-x", [6])); -// globals.wast:192 +// global.wast:192 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x00\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x65\x74\x2d\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x42\x07\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "set-y", [int64("7")])) -// globals.wast:193 +// global.wast:193 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7d\x00\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x65\x74\x2d\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x41\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "set-5", [8.])) -// globals.wast:194 +// global.wast:194 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7c\x00\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x65\x74\x2d\x36\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x22\x40\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "set-6", [9.])) -// globals.wast:196 +// global.wast:196 assert_return(() => call($1, "get-x", []), 6); -// globals.wast:197 +// global.wast:197 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-y", []), int64("7")) -// globals.wast:198 +// global.wast:198 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x35\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-5", []), 8.) -// globals.wast:199 +// global.wast:199 run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x67\x65\x74\x2d\x36\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x22\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "get-6", []), 9.) -// globals.wast:201 +// global.wast:201 assert_return(() => call($1, "as-select-first", []), 6); -// globals.wast:202 +// global.wast:202 assert_return(() => call($1, "as-select-mid", []), 2); -// globals.wast:203 +// global.wast:203 assert_return(() => call($1, "as-select-last", []), 2); -// globals.wast:205 +// global.wast:205 assert_return(() => call($1, "as-loop-first", []), 6); -// globals.wast:206 +// global.wast:206 assert_return(() => call($1, "as-loop-mid", []), 6); -// globals.wast:207 +// global.wast:207 assert_return(() => call($1, "as-loop-last", []), 6); -// globals.wast:209 +// global.wast:209 assert_return(() => call($1, "as-if-condition", []), 2); -// globals.wast:210 +// global.wast:210 assert_return(() => call($1, "as-if-then", []), 6); -// globals.wast:211 +// global.wast:211 assert_return(() => call($1, "as-if-else", []), 6); -// globals.wast:213 +// global.wast:213 assert_return(() => call($1, "as-br_if-first", []), 6); -// globals.wast:214 +// global.wast:214 assert_return(() => call($1, "as-br_if-last", []), 2); -// globals.wast:216 +// global.wast:216 assert_return(() => call($1, "as-br_table-first", []), 6); -// globals.wast:217 +// global.wast:217 assert_return(() => call($1, "as-br_table-last", []), 2); -// globals.wast:219 +// global.wast:219 assert_return(() => call($1, "as-call_indirect-first", []), 6); -// globals.wast:220 +// global.wast:220 assert_return(() => call($1, "as-call_indirect-mid", []), 2); -// globals.wast:221 +// global.wast:221 assert_trap(() => call($1, "as-call_indirect-last", [])); -// globals.wast:223 +// global.wast:223 assert_return(() => call($1, "as-store-first", [])); -// globals.wast:224 +// global.wast:224 assert_return(() => call($1, "as-store-last", [])); -// globals.wast:225 +// global.wast:225 assert_return(() => call($1, "as-load-operand", []), 1); -// globals.wast:226 +// global.wast:226 assert_return(() => call($1, "as-memory.grow-value", []), 1); -// globals.wast:228 +// global.wast:228 assert_return(() => call($1, "as-call-value", []), 6); -// globals.wast:230 +// global.wast:230 assert_return(() => call($1, "as-return-value", []), 6); -// globals.wast:231 +// global.wast:231 assert_return(() => call($1, "as-drop-operand", [])); -// globals.wast:232 +// global.wast:232 assert_return(() => call($1, "as-br-value", []), 6); -// globals.wast:234 +// global.wast:234 assert_return(() => call($1, "as-local.set-value", [1]), 6); -// globals.wast:235 +// global.wast:235 assert_return(() => call($1, "as-local.tee-value", [1]), 6); -// globals.wast:236 +// global.wast:236 assert_return(() => call($1, "as-global.set-value", []), 6); -// globals.wast:238 +// global.wast:238 assert_return(() => call($1, "as-unary-operand", []), 0); -// globals.wast:239 +// global.wast:239 assert_return(() => call($1, "as-binary-operand", []), 36); -// globals.wast:240 +// global.wast:240 assert_return(() => call($1, "as-compare-operand", []), 1); -// globals.wast:242 +// global.wast:242 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x00\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x43\x00\x00\x80\x3f\x24\x00\x0b"); -// globals.wast:248 +// global.wast:248 let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x01\x43\x00\x00\x00\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x61\x03\x00"); -// globals.wast:249 +// global.wast:249 let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7d\x01\x43\x00\x00\x00\x00\x0b\x07\x85\x80\x80\x80\x00\x01\x01\x61\x03\x00"); -// globals.wast:251 +// global.wast:251 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8a\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x00\x00\x8c\x0b"); -// globals.wast:256 +// global.wast:256 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7d\x00\x20\x00\x0b"); -// globals.wast:261 +// global.wast:261 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8a\x80\x80\x80\x00\x01\x7d\x00\x43\x00\x00\x80\x3f\x8c\x0b"); -// globals.wast:266 +// global.wast:266 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x87\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x01\x0b"); -// globals.wast:271 +// global.wast:271 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x85\x80\x80\x80\x00\x01\x7f\x00\x01\x0b"); -// globals.wast:276 +// global.wast:276 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x89\x80\x80\x80\x00\x01\x7f\x00\x43\x00\x00\x00\x00\x0b"); -// globals.wast:281 +// global.wast:281 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x88\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x41\x00\x0b"); -// globals.wast:286 +// global.wast:286 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x84\x80\x80\x80\x00\x01\x7f\x00\x0b"); -// globals.wast:291 +// global.wast:291 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x00\x23\x00\x0b"); -// globals.wast:296 +// global.wast:296 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x8b\x80\x80\x80\x00\x02\x7f\x00\x23\x01\x0b\x7f\x00\x41\x00\x0b"); -// globals.wast:301 +// global.wast:301 let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x00"); -// globals.wast:304 +// global.wast:304 assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\x02"); -// globals.wast:317 +// global.wast:317 assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x98\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x0a\x67\x6c\x6f\x62\x61\x6c\x5f\x69\x33\x32\x03\x7f\xff"); -// globals.wast:331 +// global.wast:331 let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x00\x41\x00\x0b"); -// globals.wast:334 +// global.wast:334 assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x02\x41\x00\x0b"); -// globals.wast:346 +// global.wast:346 assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x86\x80\x80\x80\x00\x01\x7f\xff\x41\x00\x0b"); -// globals.wast:360 +// global.wast:360 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x24\x00\x0b"); -// globals.wast:369 +// global.wast:369 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0b\x0b"); -// globals.wast:379 +// global.wast:379 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x03\x40\x24\x00\x0b\x0b"); -// globals.wast:389 +// global.wast:389 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x24\x00\x0b\x0b"); -// globals.wast:399 +// global.wast:399 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x24\x00\x0b\x0b"); -// globals.wast:409 +// global.wast:409 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0c\x00\x0b\x0b"); -// globals.wast:419 +// global.wast:419 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0d\x00\x0b\x0b"); -// globals.wast:429 +// global.wast:429 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x02\x40\x24\x00\x0e\x00\x00\x0b\x0b"); -// globals.wast:439 +// global.wast:439 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x24\x00\x0f\x0b"); -// globals.wast:448 +// global.wast:448 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x24\x00\x41\x01\x41\x02\x1b\x0b"); -// globals.wast:457 +// global.wast:457 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x95\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x24\x00\x10\x01\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); -// globals.wast:467 +// global.wast:467 assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x24\x00\x41\x00\x11\x00\x00\x0b\x0b"); + +// global.wast:486 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// global.wast:490 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// global.wast:494 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/harness/async_index.js b/js/src/jit-test/tests/wasm/spec/spec/harness/async_index.js new file mode 100644 index 0000000000..038d6859cd --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/harness/async_index.js @@ -0,0 +1,388 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +"use strict"; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + }; +})(); + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch (e) { + assert_true( + e instanceof err, + `expected ${err.name}, observed ${e.constructor.name}` + ); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error."); +} + +/****************************************************************************** + ***************************** WAST HARNESS ************************************ + ******************************************************************************/ + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +// Default imports. +var registry = {}; + +// All tests run asynchronously and return their results as promises. To ensure +// that all tests execute in the correct order, we chain the promises together +// so that a test is only executed when all previous tests have finished their +// execution. +let chain = Promise.resolve(); + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === "undefined") return; + + chain = chain.then(_ => { + let spectest = { + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({ + initial: 10, + maximum: 20, + element: "anyfunc" + }), + memory: new WebAssembly.Memory({ initial: 1, maximum: 2 }) + }; + let handler = { + get(target, prop) { + return prop in target ? target[prop] : {}; + } + }; + registry = new Proxy({ spectest }, handler); + }); + + // This function is called at the end of every generated js test file. By + // adding the chain as a promise_test here we make sure that the WPT harness + // waits for all tests in the chain to finish. + promise_test(_ => chain, testNum() + "Reinitialize the default imports"); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + const test = valid + ? "Test that WebAssembly compilation succeeds" + : "Test that WebAssembly compilation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + let buffer = binary(bytes); + let validated = WebAssembly.validate(buffer); + + uniqueTest(_ => { + assert_equals(valid, validated); + }, test); + + chain = chain.then(_ => WebAssembly.compile(buffer)).then( + module => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return module; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `WebAssembly.compile failed unexpectedly with ${error} at {loc}` + ); + }, test); + } + ); + return chain; +} + +function assert_invalid(bytes) { + module(bytes, EXPECT_INVALID); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports, valid = true) { + const test = valid + ? "Test that WebAssembly instantiation succeeds" + : "Test that WebAssembly instantiation fails"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([imports, chain]) + .then(values => { + let imports = values[0] ? values[0] : registry; + return WebAssembly.instantiate(binary(bytes), imports); + }) + .then( + pair => { + uniqueTest(_ => { + assert_true(valid, loc); + }, test); + return pair.instance; + }, + error => { + uniqueTest(_ => { + assert_true( + !valid, + `unexpected instantiation error, observed ${error} ${loc}` + ); + }, test); + return error; + } + ); + return chain; +} + +function exports(name, instance) { + return instance.then(inst => { + return { [name]: inst.exports }; + }); +} + +function call(instance, name, args) { + return Promise.all([instance, chain]).then(values => { + return values[0].exports[name](...args); + }); +} + +function run(action) { + const test = "Run a WebAssembly test without special assertions"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + _ => { + uniqueTest(_ => {}, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, "run"); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_trap(action) { + const test = "Test that a WebAssembly code traps"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([chain, action()]) + .then( + result => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof WebAssembly.RuntimeError, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_return(action, ...expected) { + const test = "Test that a WebAssembly code returns a specific result"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + values => { + uniqueTest(_ => { + let actual = values[0]; + if (actual === undefined) { + actual = []; + } else if (!Array.isArray(actual)) { + actual = [actual]; + } + if (actual.length !== expected.length) { + throw new Error(expected.length + " value(s) expected, got " + actual.length); + } + + for (let i = 0; i < actual.length; ++i) { + assert_equals(actual[i], expected[i], loc); + } + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + false, + `unexpected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +let StackOverflow; +try { + (function f() { + 1 + f(); + })(); +} catch (e) { + StackOverflow = e.constructor; +} + +function assert_exhaustion(action) { + const test = "Test that a WebAssembly code exhauts the stack space"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([action(), chain]) + .then( + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + }, + error => { + uniqueTest(_ => { + assert_true( + error instanceof StackOverflow, + `expected runtime error, observed ${error} ${loc}` + ); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_unlinkable(bytes) { + const test = "Test that a WebAssembly module is unlinkable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.LinkError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function assert_uninstantiable(bytes) { + const test = "Test that a WebAssembly module is uninstantiable"; + const loc = new Error().stack.toString().replace("Error", ""); + instance(bytes, registry, EXPECT_INVALID) + .then( + result => { + uniqueTest(_ => { + assert_true( + result instanceof WebAssembly.RuntimeError, + `expected link error, observed ${result} ${loc}` + ); + }, test); + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function register(name, instance) { + const test = + "Test that the exports of a WebAssembly module can be registered"; + const loc = new Error().stack.toString().replace("Error", ""); + let stack = new Error(); + chain = Promise.all([instance, chain]) + .then( + values => { + registry[name] = values[0].exports; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ) + // Clear all exceptions, so that subsequent tests get executed. + .catch(_ => {}); +} + +function get(instance, name) { + const test = "Test that an export of a WebAssembly instance can be acquired"; + const loc = new Error().stack.toString().replace("Error", ""); + chain = Promise.all([instance, chain]).then( + values => { + let v = values[0].exports[name]; + return (v instanceof WebAssembly.Global) ? v.value : v; + }, + _ => { + uniqueTest(_ => { + assert_true(false, loc); + }, test); + } + ); + return chain; +} + diff --git a/js/src/jit-test/tests/wasm/spec/spec/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/spec/harness/directives.txt new file mode 100644 index 0000000000..d41243abbb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/harness/directives.txt @@ -0,0 +1 @@ +|jit-test| skip-if: true \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/spec/harness/sync_index.js b/js/src/jit-test/tests/wasm/spec/spec/harness/sync_index.js new file mode 100644 index 0000000000..fd4e72326a --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/harness/sync_index.js @@ -0,0 +1,349 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +'use strict'; + +let testNum = (function() { + let count = 1; + return function() { + return `#${count++} `; + } +})(); + +// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since +// it is not aware of the WebAssembly error types (yet), implement our own +// version. +function assertThrows(func, err) { + let caught = false; + try { + func(); + } catch(e) { + assert_true(e instanceof err, `expected ${err.name}, observed ${e.constructor.name}`); + caught = true; + } + assert_true(caught, testNum() + "assertThrows must catch any error.") +} + +/****************************************************************************** +***************************** WAST HARNESS ************************************ +******************************************************************************/ + +// For assertions internal to our test harness. +function _assert(x) { + if (!x) { + throw new Error(`Assertion failure: ${x}`); + } +} + +// A simple sum type that can either be a valid Value or an Error. +function Result(type, maybeValue) { + this.value = maybeValue; + this.type = type; +}; + +Result.VALUE = 'VALUE'; +Result.ERROR = 'ERROR'; + +function ValueResult(val) { return new Result(Result.VALUE, val); } +function ErrorResult(err) { return new Result(Result.ERROR, err); } + +Result.prototype.isError = function() { return this.type === Result.ERROR; } + +const EXPECT_INVALID = false; + +/* DATA **********************************************************************/ + +let $$; + +// Default imports. +var registry = {}; + +// Resets the registry between two different WPT tests. +function reinitializeRegistry() { + if (typeof WebAssembly === 'undefined') + return; + + let spectest = { + print: console.log.bind(console), + print_i32: console.log.bind(console), + print_i32_f32: console.log.bind(console), + print_f64_f64: console.log.bind(console), + print_f32: console.log.bind(console), + print_f64: console.log.bind(console), + global_i32: 666, + global_f32: 666, + global_f64: 666, + table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}), + memory: new WebAssembly.Memory({initial: 1, maximum: 2}) + }; + let handler = { + get(target, prop) { + return (prop in target) ? target[prop] : {}; + } + }; + registry = new Proxy({spectest}, handler); +} + +reinitializeRegistry(); + +/* WAST POLYFILL *************************************************************/ + +function binary(bytes) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { + view[i] = bytes.charCodeAt(i); + } + return buffer; +} + +/** + * Returns a compiled module, or throws if there was an error at compilation. + */ +function module(bytes, valid = true) { + let buffer = binary(bytes); + let validated; + + try { + validated = WebAssembly.validate(buffer); + } catch (e) { + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + + if (validated !== valid) { + // Try to get a more precise error message from the WebAssembly.CompileError. + try { + new WebAssembly.Module(buffer); + } catch (e) { + if (e instanceof WebAssembly.CompileError) + throw new WebAssembly.CompileError(`WebAssembly.validate error: ${e.toString()}${e.stack}\n`); + else + throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); + } + throw new Error(`WebAssembly.validate was expected to fail, but didn't`); + } + + let module; + try { + module = new WebAssembly.Module(buffer); + } catch(e) { + if (valid) + throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}'); + throw e; + } + + return module; +} + +function uniqueTest(func, desc) { + test(func, testNum() + desc); +} + +function assert_invalid(bytes) { + uniqueTest(() => { + try { + module(bytes, /* valid */ false); + throw new Error('did not fail'); + } catch(e) { + assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:"); + } + }, "A wast module that should be invalid or malformed."); +} + +const assert_malformed = assert_invalid; + +function instance(bytes, imports = registry, valid = true) { + if (imports instanceof Result) { + if (imports.isError()) + return imports; + imports = imports.value; + } + + let err = null; + + let m, i; + try { + let m = module(bytes); + i = new WebAssembly.Instance(m, imports); + } catch(e) { + err = e; + } + + if (valid) { + uniqueTest(() => { + let instantiated = err === null; + assert_true(instantiated, err); + }, "module successfully instantiated"); + } + + return err !== null ? ErrorResult(err) : ValueResult(i); +} + +function register(name, instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return; + + registry[name] = instance.value.exports; +} + +function call(instance, name, args) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let err = null; + let result; + try { + result = instance.value.exports[name](...args); + } catch(e) { + err = e; + } + + return err !== null ? ErrorResult(err) : ValueResult(result); +}; + +function get(instance, name) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + let v = instance.value.exports[name]; + return ValueResult((v instanceof WebAssembly.Global) ? v.value : v); +} + +function exports(name, instance) { + _assert(instance instanceof Result); + + if (instance.isError()) + return instance; + + return ValueResult({ [name]: instance.value.exports }); +} + +function run(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + if (result.isError()) + throw result.value; + }, "A wast test that runs without any special assertion."); +} + +function assert_unlinkable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.LinkError, `expected link error, observed ${e}:`); + } + }, "A wast module that is unlinkable."); +} + +function assert_uninstantiable(bytes) { + let result = instance(bytes, registry, EXPECT_INVALID); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that is uninstantiable."); +} + +function assert_trap(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); + } + }, "A wast module that must trap at runtime."); +} + +let StackOverflow; +try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor } + +function assert_exhaustion(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(result.isError(), 'expected error result'); + if (result.isError()) { + let e = result.value; + assert_true(e instanceof StackOverflow, `expected stack overflow error, observed ${e}:`); + } + }, "A wast module that must exhaust the stack space."); +} + +function assert_return(action, ...expected) { + let result = action(); + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), `expected success result, got: ${result.value}.`); + + let actual = result.value; + if (actual === undefined) { + actual = []; + } else if (!Array.isArray(actual)) { + actual = [actual]; + } + if (actual.length !== expected.length) { + throw new Error(expected.length + " value(s) expected, got " + actual.length); + } + + for (let i = 0; i < actual.length; ++i) { + if (expected[i] instanceof Result) { + if (expected[i].isError()) + return; + expected[i] = expected[i].value; + } + assert_equals(actual[i], expected[i]); + } + }, "A wast module that must return a particular value."); +}; + +function assert_return_nan(action) { + let result = action(); + + _assert(result instanceof Result); + + uniqueTest(() => { + assert_true(!result.isError(), 'expected success result'); + if (!result.isError()) { + assert_true(Number.isNaN(result.value), `expected NaN, observed ${result.value}.`); + }; + }, "A wast module that must return NaN."); +} diff --git a/js/src/jit-test/tests/wasm/spec/spec/i32.wast.js b/js/src/jit-test/tests/wasm/spec/spec/i32.wast.js new file mode 100644 index 0000000000..00efd5c4c4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/i32.wast.js @@ -0,0 +1,1374 @@ + +// i32.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x02\x7f\x7f\x01\x7f\x60\x01\x7f\x01\x7f\x03\xa0\x80\x80\x80\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xde\x81\x80\x80\x00\x1f\x03\x61\x64\x64\x00\x00\x03\x73\x75\x62\x00\x01\x03\x6d\x75\x6c\x00\x02\x05\x64\x69\x76\x5f\x73\x00\x03\x05\x64\x69\x76\x5f\x75\x00\x04\x05\x72\x65\x6d\x5f\x73\x00\x05\x05\x72\x65\x6d\x5f\x75\x00\x06\x03\x61\x6e\x64\x00\x07\x02\x6f\x72\x00\x08\x03\x78\x6f\x72\x00\x09\x03\x73\x68\x6c\x00\x0a\x05\x73\x68\x72\x5f\x73\x00\x0b\x05\x73\x68\x72\x5f\x75\x00\x0c\x04\x72\x6f\x74\x6c\x00\x0d\x04\x72\x6f\x74\x72\x00\x0e\x03\x63\x6c\x7a\x00\x0f\x03\x63\x74\x7a\x00\x10\x06\x70\x6f\x70\x63\x6e\x74\x00\x11\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x12\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x13\x03\x65\x71\x7a\x00\x14\x02\x65\x71\x00\x15\x02\x6e\x65\x00\x16\x04\x6c\x74\x5f\x73\x00\x17\x04\x6c\x74\x5f\x75\x00\x18\x04\x6c\x65\x5f\x73\x00\x19\x04\x6c\x65\x5f\x75\x00\x1a\x04\x67\x74\x5f\x73\x00\x1b\x04\x67\x74\x5f\x75\x00\x1c\x04\x67\x65\x5f\x73\x00\x1d\x04\x67\x65\x5f\x75\x00\x1e\x0a\xe9\x82\x80\x80\x00\x1f\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6a\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6b\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6c\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6d\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6e\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x6f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x70\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x71\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x72\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x73\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x74\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x75\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x76\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x77\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x78\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x67\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x68\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x69\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xc0\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xc1\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x45\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x46\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x47\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x48\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x49\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4c\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4d\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4a\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4b\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4e\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x4f\x0b"); + +// i32.wast:37 +assert_return(() => call($1, "add", [1, 1]), 2); + +// i32.wast:38 +assert_return(() => call($1, "add", [1, 0]), 1); + +// i32.wast:39 +assert_return(() => call($1, "add", [-1, -1]), -2); + +// i32.wast:40 +assert_return(() => call($1, "add", [-1, 1]), 0); + +// i32.wast:41 +assert_return(() => call($1, "add", [2_147_483_647, 1]), -2_147_483_648); + +// i32.wast:42 +assert_return(() => call($1, "add", [-2_147_483_648, -1]), 2_147_483_647); + +// i32.wast:43 +assert_return(() => call($1, "add", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:44 +assert_return(() => call($1, "add", [1_073_741_823, 1]), 1_073_741_824); + +// i32.wast:46 +assert_return(() => call($1, "sub", [1, 1]), 0); + +// i32.wast:47 +assert_return(() => call($1, "sub", [1, 0]), 1); + +// i32.wast:48 +assert_return(() => call($1, "sub", [-1, -1]), 0); + +// i32.wast:49 +assert_return(() => call($1, "sub", [2_147_483_647, -1]), -2_147_483_648); + +// i32.wast:50 +assert_return(() => call($1, "sub", [-2_147_483_648, 1]), 2_147_483_647); + +// i32.wast:51 +assert_return(() => call($1, "sub", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:52 +assert_return(() => call($1, "sub", [1_073_741_823, -1]), 1_073_741_824); + +// i32.wast:54 +assert_return(() => call($1, "mul", [1, 1]), 1); + +// i32.wast:55 +assert_return(() => call($1, "mul", [1, 0]), 0); + +// i32.wast:56 +assert_return(() => call($1, "mul", [-1, -1]), 1); + +// i32.wast:57 +assert_return(() => call($1, "mul", [268_435_456, 4_096]), 0); + +// i32.wast:58 +assert_return(() => call($1, "mul", [-2_147_483_648, 0]), 0); + +// i32.wast:59 +assert_return(() => call($1, "mul", [-2_147_483_648, -1]), -2_147_483_648); + +// i32.wast:60 +assert_return(() => call($1, "mul", [2_147_483_647, -1]), -2_147_483_647); + +// i32.wast:61 +assert_return(() => call($1, "mul", [19_088_743, 1_985_229_328]), 898_528_368); + +// i32.wast:62 +assert_return(() => call($1, "mul", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:64 +assert_trap(() => call($1, "div_s", [1, 0])); + +// i32.wast:65 +assert_trap(() => call($1, "div_s", [0, 0])); + +// i32.wast:66 +assert_trap(() => call($1, "div_s", [-2_147_483_648, -1])); + +// i32.wast:67 +assert_trap(() => call($1, "div_s", [-2_147_483_648, 0])); + +// i32.wast:68 +assert_return(() => call($1, "div_s", [1, 1]), 1); + +// i32.wast:69 +assert_return(() => call($1, "div_s", [0, 1]), 0); + +// i32.wast:70 +assert_return(() => call($1, "div_s", [0, -1]), 0); + +// i32.wast:71 +assert_return(() => call($1, "div_s", [-1, -1]), 1); + +// i32.wast:72 +assert_return(() => call($1, "div_s", [-2_147_483_648, 2]), -1_073_741_824); + +// i32.wast:73 +assert_return(() => call($1, "div_s", [-2_147_483_647, 1_000]), -2_147_483); + +// i32.wast:74 +assert_return(() => call($1, "div_s", [5, 2]), 2); + +// i32.wast:75 +assert_return(() => call($1, "div_s", [-5, 2]), -2); + +// i32.wast:76 +assert_return(() => call($1, "div_s", [5, -2]), -2); + +// i32.wast:77 +assert_return(() => call($1, "div_s", [-5, -2]), 2); + +// i32.wast:78 +assert_return(() => call($1, "div_s", [7, 3]), 2); + +// i32.wast:79 +assert_return(() => call($1, "div_s", [-7, 3]), -2); + +// i32.wast:80 +assert_return(() => call($1, "div_s", [7, -3]), -2); + +// i32.wast:81 +assert_return(() => call($1, "div_s", [-7, -3]), 2); + +// i32.wast:82 +assert_return(() => call($1, "div_s", [11, 5]), 2); + +// i32.wast:83 +assert_return(() => call($1, "div_s", [17, 7]), 2); + +// i32.wast:85 +assert_trap(() => call($1, "div_u", [1, 0])); + +// i32.wast:86 +assert_trap(() => call($1, "div_u", [0, 0])); + +// i32.wast:87 +assert_return(() => call($1, "div_u", [1, 1]), 1); + +// i32.wast:88 +assert_return(() => call($1, "div_u", [0, 1]), 0); + +// i32.wast:89 +assert_return(() => call($1, "div_u", [-1, -1]), 1); + +// i32.wast:90 +assert_return(() => call($1, "div_u", [-2_147_483_648, -1]), 0); + +// i32.wast:91 +assert_return(() => call($1, "div_u", [-2_147_483_648, 2]), 1_073_741_824); + +// i32.wast:92 +assert_return(() => call($1, "div_u", [-1_880_092_688, 65_537]), 36_847); + +// i32.wast:93 +assert_return(() => call($1, "div_u", [-2_147_483_647, 1_000]), 2_147_483); + +// i32.wast:94 +assert_return(() => call($1, "div_u", [5, 2]), 2); + +// i32.wast:95 +assert_return(() => call($1, "div_u", [-5, 2]), 2_147_483_645); + +// i32.wast:96 +assert_return(() => call($1, "div_u", [5, -2]), 0); + +// i32.wast:97 +assert_return(() => call($1, "div_u", [-5, -2]), 0); + +// i32.wast:98 +assert_return(() => call($1, "div_u", [7, 3]), 2); + +// i32.wast:99 +assert_return(() => call($1, "div_u", [11, 5]), 2); + +// i32.wast:100 +assert_return(() => call($1, "div_u", [17, 7]), 2); + +// i32.wast:102 +assert_trap(() => call($1, "rem_s", [1, 0])); + +// i32.wast:103 +assert_trap(() => call($1, "rem_s", [0, 0])); + +// i32.wast:104 +assert_return(() => call($1, "rem_s", [2_147_483_647, -1]), 0); + +// i32.wast:105 +assert_return(() => call($1, "rem_s", [1, 1]), 0); + +// i32.wast:106 +assert_return(() => call($1, "rem_s", [0, 1]), 0); + +// i32.wast:107 +assert_return(() => call($1, "rem_s", [0, -1]), 0); + +// i32.wast:108 +assert_return(() => call($1, "rem_s", [-1, -1]), 0); + +// i32.wast:109 +assert_return(() => call($1, "rem_s", [-2_147_483_648, -1]), 0); + +// i32.wast:110 +assert_return(() => call($1, "rem_s", [-2_147_483_648, 2]), 0); + +// i32.wast:111 +assert_return(() => call($1, "rem_s", [-2_147_483_647, 1_000]), -647); + +// i32.wast:112 +assert_return(() => call($1, "rem_s", [5, 2]), 1); + +// i32.wast:113 +assert_return(() => call($1, "rem_s", [-5, 2]), -1); + +// i32.wast:114 +assert_return(() => call($1, "rem_s", [5, -2]), 1); + +// i32.wast:115 +assert_return(() => call($1, "rem_s", [-5, -2]), -1); + +// i32.wast:116 +assert_return(() => call($1, "rem_s", [7, 3]), 1); + +// i32.wast:117 +assert_return(() => call($1, "rem_s", [-7, 3]), -1); + +// i32.wast:118 +assert_return(() => call($1, "rem_s", [7, -3]), 1); + +// i32.wast:119 +assert_return(() => call($1, "rem_s", [-7, -3]), -1); + +// i32.wast:120 +assert_return(() => call($1, "rem_s", [11, 5]), 1); + +// i32.wast:121 +assert_return(() => call($1, "rem_s", [17, 7]), 3); + +// i32.wast:123 +assert_trap(() => call($1, "rem_u", [1, 0])); + +// i32.wast:124 +assert_trap(() => call($1, "rem_u", [0, 0])); + +// i32.wast:125 +assert_return(() => call($1, "rem_u", [1, 1]), 0); + +// i32.wast:126 +assert_return(() => call($1, "rem_u", [0, 1]), 0); + +// i32.wast:127 +assert_return(() => call($1, "rem_u", [-1, -1]), 0); + +// i32.wast:128 +assert_return(() => call($1, "rem_u", [-2_147_483_648, -1]), -2_147_483_648); + +// i32.wast:129 +assert_return(() => call($1, "rem_u", [-2_147_483_648, 2]), 0); + +// i32.wast:130 +assert_return(() => call($1, "rem_u", [-1_880_092_688, 65_537]), 32_769); + +// i32.wast:131 +assert_return(() => call($1, "rem_u", [-2_147_483_647, 1_000]), 649); + +// i32.wast:132 +assert_return(() => call($1, "rem_u", [5, 2]), 1); + +// i32.wast:133 +assert_return(() => call($1, "rem_u", [-5, 2]), 1); + +// i32.wast:134 +assert_return(() => call($1, "rem_u", [5, -2]), 5); + +// i32.wast:135 +assert_return(() => call($1, "rem_u", [-5, -2]), -5); + +// i32.wast:136 +assert_return(() => call($1, "rem_u", [7, 3]), 1); + +// i32.wast:137 +assert_return(() => call($1, "rem_u", [11, 5]), 1); + +// i32.wast:138 +assert_return(() => call($1, "rem_u", [17, 7]), 3); + +// i32.wast:140 +assert_return(() => call($1, "and", [1, 0]), 0); + +// i32.wast:141 +assert_return(() => call($1, "and", [0, 1]), 0); + +// i32.wast:142 +assert_return(() => call($1, "and", [1, 1]), 1); + +// i32.wast:143 +assert_return(() => call($1, "and", [0, 0]), 0); + +// i32.wast:144 +assert_return(() => call($1, "and", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:145 +assert_return(() => call($1, "and", [2_147_483_647, -1]), 2_147_483_647); + +// i32.wast:146 +assert_return(() => call($1, "and", [-252_641_281, -3_856]), -252_645_136); + +// i32.wast:147 +assert_return(() => call($1, "and", [-1, -1]), -1); + +// i32.wast:149 +assert_return(() => call($1, "or", [1, 0]), 1); + +// i32.wast:150 +assert_return(() => call($1, "or", [0, 1]), 1); + +// i32.wast:151 +assert_return(() => call($1, "or", [1, 1]), 1); + +// i32.wast:152 +assert_return(() => call($1, "or", [0, 0]), 0); + +// i32.wast:153 +assert_return(() => call($1, "or", [2_147_483_647, -2_147_483_648]), -1); + +// i32.wast:154 +assert_return(() => call($1, "or", [-2_147_483_648, 0]), -2_147_483_648); + +// i32.wast:155 +assert_return(() => call($1, "or", [-252_641_281, -3_856]), -1); + +// i32.wast:156 +assert_return(() => call($1, "or", [-1, -1]), -1); + +// i32.wast:158 +assert_return(() => call($1, "xor", [1, 0]), 1); + +// i32.wast:159 +assert_return(() => call($1, "xor", [0, 1]), 1); + +// i32.wast:160 +assert_return(() => call($1, "xor", [1, 1]), 0); + +// i32.wast:161 +assert_return(() => call($1, "xor", [0, 0]), 0); + +// i32.wast:162 +assert_return(() => call($1, "xor", [2_147_483_647, -2_147_483_648]), -1); + +// i32.wast:163 +assert_return(() => call($1, "xor", [-2_147_483_648, 0]), -2_147_483_648); + +// i32.wast:164 +assert_return(() => call($1, "xor", [-1, -2_147_483_648]), 2_147_483_647); + +// i32.wast:165 +assert_return(() => call($1, "xor", [-1, 2_147_483_647]), -2_147_483_648); + +// i32.wast:166 +assert_return(() => call($1, "xor", [-252_641_281, -3_856]), 252_645_135); + +// i32.wast:167 +assert_return(() => call($1, "xor", [-1, -1]), 0); + +// i32.wast:169 +assert_return(() => call($1, "shl", [1, 1]), 2); + +// i32.wast:170 +assert_return(() => call($1, "shl", [1, 0]), 1); + +// i32.wast:171 +assert_return(() => call($1, "shl", [2_147_483_647, 1]), -2); + +// i32.wast:172 +assert_return(() => call($1, "shl", [-1, 1]), -2); + +// i32.wast:173 +assert_return(() => call($1, "shl", [-2_147_483_648, 1]), 0); + +// i32.wast:174 +assert_return(() => call($1, "shl", [1_073_741_824, 1]), -2_147_483_648); + +// i32.wast:175 +assert_return(() => call($1, "shl", [1, 31]), -2_147_483_648); + +// i32.wast:176 +assert_return(() => call($1, "shl", [1, 32]), 1); + +// i32.wast:177 +assert_return(() => call($1, "shl", [1, 33]), 2); + +// i32.wast:178 +assert_return(() => call($1, "shl", [1, -1]), -2_147_483_648); + +// i32.wast:179 +assert_return(() => call($1, "shl", [1, 2_147_483_647]), -2_147_483_648); + +// i32.wast:181 +assert_return(() => call($1, "shr_s", [1, 1]), 0); + +// i32.wast:182 +assert_return(() => call($1, "shr_s", [1, 0]), 1); + +// i32.wast:183 +assert_return(() => call($1, "shr_s", [-1, 1]), -1); + +// i32.wast:184 +assert_return(() => call($1, "shr_s", [2_147_483_647, 1]), 1_073_741_823); + +// i32.wast:185 +assert_return(() => call($1, "shr_s", [-2_147_483_648, 1]), -1_073_741_824); + +// i32.wast:186 +assert_return(() => call($1, "shr_s", [1_073_741_824, 1]), 536_870_912); + +// i32.wast:187 +assert_return(() => call($1, "shr_s", [1, 32]), 1); + +// i32.wast:188 +assert_return(() => call($1, "shr_s", [1, 33]), 0); + +// i32.wast:189 +assert_return(() => call($1, "shr_s", [1, -1]), 0); + +// i32.wast:190 +assert_return(() => call($1, "shr_s", [1, 2_147_483_647]), 0); + +// i32.wast:191 +assert_return(() => call($1, "shr_s", [1, -2_147_483_648]), 1); + +// i32.wast:192 +assert_return(() => call($1, "shr_s", [-2_147_483_648, 31]), -1); + +// i32.wast:193 +assert_return(() => call($1, "shr_s", [-1, 32]), -1); + +// i32.wast:194 +assert_return(() => call($1, "shr_s", [-1, 33]), -1); + +// i32.wast:195 +assert_return(() => call($1, "shr_s", [-1, -1]), -1); + +// i32.wast:196 +assert_return(() => call($1, "shr_s", [-1, 2_147_483_647]), -1); + +// i32.wast:197 +assert_return(() => call($1, "shr_s", [-1, -2_147_483_648]), -1); + +// i32.wast:199 +assert_return(() => call($1, "shr_u", [1, 1]), 0); + +// i32.wast:200 +assert_return(() => call($1, "shr_u", [1, 0]), 1); + +// i32.wast:201 +assert_return(() => call($1, "shr_u", [-1, 1]), 2_147_483_647); + +// i32.wast:202 +assert_return(() => call($1, "shr_u", [2_147_483_647, 1]), 1_073_741_823); + +// i32.wast:203 +assert_return(() => call($1, "shr_u", [-2_147_483_648, 1]), 1_073_741_824); + +// i32.wast:204 +assert_return(() => call($1, "shr_u", [1_073_741_824, 1]), 536_870_912); + +// i32.wast:205 +assert_return(() => call($1, "shr_u", [1, 32]), 1); + +// i32.wast:206 +assert_return(() => call($1, "shr_u", [1, 33]), 0); + +// i32.wast:207 +assert_return(() => call($1, "shr_u", [1, -1]), 0); + +// i32.wast:208 +assert_return(() => call($1, "shr_u", [1, 2_147_483_647]), 0); + +// i32.wast:209 +assert_return(() => call($1, "shr_u", [1, -2_147_483_648]), 1); + +// i32.wast:210 +assert_return(() => call($1, "shr_u", [-2_147_483_648, 31]), 1); + +// i32.wast:211 +assert_return(() => call($1, "shr_u", [-1, 32]), -1); + +// i32.wast:212 +assert_return(() => call($1, "shr_u", [-1, 33]), 2_147_483_647); + +// i32.wast:213 +assert_return(() => call($1, "shr_u", [-1, -1]), 1); + +// i32.wast:214 +assert_return(() => call($1, "shr_u", [-1, 2_147_483_647]), 1); + +// i32.wast:215 +assert_return(() => call($1, "shr_u", [-1, -2_147_483_648]), -1); + +// i32.wast:217 +assert_return(() => call($1, "rotl", [1, 1]), 2); + +// i32.wast:218 +assert_return(() => call($1, "rotl", [1, 0]), 1); + +// i32.wast:219 +assert_return(() => call($1, "rotl", [-1, 1]), -1); + +// i32.wast:220 +assert_return(() => call($1, "rotl", [1, 32]), 1); + +// i32.wast:221 +assert_return(() => call($1, "rotl", [-1_412_589_450, 1]), 1_469_788_397); + +// i32.wast:222 +assert_return(() => call($1, "rotl", [-33_498_112, 4]), -535_969_777); + +// i32.wast:223 +assert_return(() => call($1, "rotl", [-1_329_474_845, 5]), 406_477_942); + +// i32.wast:224 +assert_return(() => call($1, "rotl", [32_768, 37]), 1_048_576); + +// i32.wast:225 +assert_return(() => call($1, "rotl", [-1_329_474_845, 65_285]), 406_477_942); + +// i32.wast:226 +assert_return(() => call($1, "rotl", [1_989_852_383, -19]), 1_469_837_011); + +// i32.wast:227 +assert_return(() => call($1, "rotl", [1_989_852_383, -2_147_483_635]), 1_469_837_011); + +// i32.wast:228 +assert_return(() => call($1, "rotl", [1, 31]), -2_147_483_648); + +// i32.wast:229 +assert_return(() => call($1, "rotl", [-2_147_483_648, 1]), 1); + +// i32.wast:231 +assert_return(() => call($1, "rotr", [1, 1]), -2_147_483_648); + +// i32.wast:232 +assert_return(() => call($1, "rotr", [1, 0]), 1); + +// i32.wast:233 +assert_return(() => call($1, "rotr", [-1, 1]), -1); + +// i32.wast:234 +assert_return(() => call($1, "rotr", [1, 32]), 1); + +// i32.wast:235 +assert_return(() => call($1, "rotr", [-16_724_992, 1]), 2_139_121_152); + +// i32.wast:236 +assert_return(() => call($1, "rotr", [524_288, 4]), 32_768); + +// i32.wast:237 +assert_return(() => call($1, "rotr", [-1_329_474_845, 5]), 495_324_823); + +// i32.wast:238 +assert_return(() => call($1, "rotr", [32_768, 37]), 1_024); + +// i32.wast:239 +assert_return(() => call($1, "rotr", [-1_329_474_845, 65_285]), 495_324_823); + +// i32.wast:240 +assert_return(() => call($1, "rotr", [1_989_852_383, -19]), -419_711_787); + +// i32.wast:241 +assert_return(() => call($1, "rotr", [1_989_852_383, -2_147_483_635]), -419_711_787); + +// i32.wast:242 +assert_return(() => call($1, "rotr", [1, 31]), 2); + +// i32.wast:243 +assert_return(() => call($1, "rotr", [-2_147_483_648, 31]), 1); + +// i32.wast:245 +assert_return(() => call($1, "clz", [-1]), 0); + +// i32.wast:246 +assert_return(() => call($1, "clz", [0]), 32); + +// i32.wast:247 +assert_return(() => call($1, "clz", [32_768]), 16); + +// i32.wast:248 +assert_return(() => call($1, "clz", [255]), 24); + +// i32.wast:249 +assert_return(() => call($1, "clz", [-2_147_483_648]), 0); + +// i32.wast:250 +assert_return(() => call($1, "clz", [1]), 31); + +// i32.wast:251 +assert_return(() => call($1, "clz", [2]), 30); + +// i32.wast:252 +assert_return(() => call($1, "clz", [2_147_483_647]), 1); + +// i32.wast:254 +assert_return(() => call($1, "ctz", [-1]), 0); + +// i32.wast:255 +assert_return(() => call($1, "ctz", [0]), 32); + +// i32.wast:256 +assert_return(() => call($1, "ctz", [32_768]), 15); + +// i32.wast:257 +assert_return(() => call($1, "ctz", [65_536]), 16); + +// i32.wast:258 +assert_return(() => call($1, "ctz", [-2_147_483_648]), 31); + +// i32.wast:259 +assert_return(() => call($1, "ctz", [2_147_483_647]), 0); + +// i32.wast:261 +assert_return(() => call($1, "popcnt", [-1]), 32); + +// i32.wast:262 +assert_return(() => call($1, "popcnt", [0]), 0); + +// i32.wast:263 +assert_return(() => call($1, "popcnt", [32_768]), 1); + +// i32.wast:264 +assert_return(() => call($1, "popcnt", [-2_147_450_880]), 2); + +// i32.wast:265 +assert_return(() => call($1, "popcnt", [2_147_483_647]), 31); + +// i32.wast:266 +assert_return(() => call($1, "popcnt", [-1_431_655_766]), 16); + +// i32.wast:267 +assert_return(() => call($1, "popcnt", [1_431_655_765]), 16); + +// i32.wast:268 +assert_return(() => call($1, "popcnt", [-559_038_737]), 24); + +// i32.wast:270 +assert_return(() => call($1, "extend8_s", [0]), 0); + +// i32.wast:271 +assert_return(() => call($1, "extend8_s", [127]), 127); + +// i32.wast:272 +assert_return(() => call($1, "extend8_s", [128]), -128); + +// i32.wast:273 +assert_return(() => call($1, "extend8_s", [255]), -1); + +// i32.wast:274 +assert_return(() => call($1, "extend8_s", [19_088_640]), 0); + +// i32.wast:275 +assert_return(() => call($1, "extend8_s", [-19_088_768]), -128); + +// i32.wast:276 +assert_return(() => call($1, "extend8_s", [-1]), -1); + +// i32.wast:278 +assert_return(() => call($1, "extend16_s", [0]), 0); + +// i32.wast:279 +assert_return(() => call($1, "extend16_s", [32_767]), 32_767); + +// i32.wast:280 +assert_return(() => call($1, "extend16_s", [32_768]), -32_768); + +// i32.wast:281 +assert_return(() => call($1, "extend16_s", [65_535]), -1); + +// i32.wast:282 +assert_return(() => call($1, "extend16_s", [19_070_976]), 0); + +// i32.wast:283 +assert_return(() => call($1, "extend16_s", [-19_103_744]), -32_768); + +// i32.wast:284 +assert_return(() => call($1, "extend16_s", [-1]), -1); + +// i32.wast:286 +assert_return(() => call($1, "eqz", [0]), 1); + +// i32.wast:287 +assert_return(() => call($1, "eqz", [1]), 0); + +// i32.wast:288 +assert_return(() => call($1, "eqz", [-2_147_483_648]), 0); + +// i32.wast:289 +assert_return(() => call($1, "eqz", [2_147_483_647]), 0); + +// i32.wast:290 +assert_return(() => call($1, "eqz", [-1]), 0); + +// i32.wast:292 +assert_return(() => call($1, "eq", [0, 0]), 1); + +// i32.wast:293 +assert_return(() => call($1, "eq", [1, 1]), 1); + +// i32.wast:294 +assert_return(() => call($1, "eq", [-1, 1]), 0); + +// i32.wast:295 +assert_return(() => call($1, "eq", [-2_147_483_648, -2_147_483_648]), 1); + +// i32.wast:296 +assert_return(() => call($1, "eq", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:297 +assert_return(() => call($1, "eq", [-1, -1]), 1); + +// i32.wast:298 +assert_return(() => call($1, "eq", [1, 0]), 0); + +// i32.wast:299 +assert_return(() => call($1, "eq", [0, 1]), 0); + +// i32.wast:300 +assert_return(() => call($1, "eq", [-2_147_483_648, 0]), 0); + +// i32.wast:301 +assert_return(() => call($1, "eq", [0, -2_147_483_648]), 0); + +// i32.wast:302 +assert_return(() => call($1, "eq", [-2_147_483_648, -1]), 0); + +// i32.wast:303 +assert_return(() => call($1, "eq", [-1, -2_147_483_648]), 0); + +// i32.wast:304 +assert_return(() => call($1, "eq", [-2_147_483_648, 2_147_483_647]), 0); + +// i32.wast:305 +assert_return(() => call($1, "eq", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:307 +assert_return(() => call($1, "ne", [0, 0]), 0); + +// i32.wast:308 +assert_return(() => call($1, "ne", [1, 1]), 0); + +// i32.wast:309 +assert_return(() => call($1, "ne", [-1, 1]), 1); + +// i32.wast:310 +assert_return(() => call($1, "ne", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:311 +assert_return(() => call($1, "ne", [2_147_483_647, 2_147_483_647]), 0); + +// i32.wast:312 +assert_return(() => call($1, "ne", [-1, -1]), 0); + +// i32.wast:313 +assert_return(() => call($1, "ne", [1, 0]), 1); + +// i32.wast:314 +assert_return(() => call($1, "ne", [0, 1]), 1); + +// i32.wast:315 +assert_return(() => call($1, "ne", [-2_147_483_648, 0]), 1); + +// i32.wast:316 +assert_return(() => call($1, "ne", [0, -2_147_483_648]), 1); + +// i32.wast:317 +assert_return(() => call($1, "ne", [-2_147_483_648, -1]), 1); + +// i32.wast:318 +assert_return(() => call($1, "ne", [-1, -2_147_483_648]), 1); + +// i32.wast:319 +assert_return(() => call($1, "ne", [-2_147_483_648, 2_147_483_647]), 1); + +// i32.wast:320 +assert_return(() => call($1, "ne", [2_147_483_647, -2_147_483_648]), 1); + +// i32.wast:322 +assert_return(() => call($1, "lt_s", [0, 0]), 0); + +// i32.wast:323 +assert_return(() => call($1, "lt_s", [1, 1]), 0); + +// i32.wast:324 +assert_return(() => call($1, "lt_s", [-1, 1]), 1); + +// i32.wast:325 +assert_return(() => call($1, "lt_s", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:326 +assert_return(() => call($1, "lt_s", [2_147_483_647, 2_147_483_647]), 0); + +// i32.wast:327 +assert_return(() => call($1, "lt_s", [-1, -1]), 0); + +// i32.wast:328 +assert_return(() => call($1, "lt_s", [1, 0]), 0); + +// i32.wast:329 +assert_return(() => call($1, "lt_s", [0, 1]), 1); + +// i32.wast:330 +assert_return(() => call($1, "lt_s", [-2_147_483_648, 0]), 1); + +// i32.wast:331 +assert_return(() => call($1, "lt_s", [0, -2_147_483_648]), 0); + +// i32.wast:332 +assert_return(() => call($1, "lt_s", [-2_147_483_648, -1]), 1); + +// i32.wast:333 +assert_return(() => call($1, "lt_s", [-1, -2_147_483_648]), 0); + +// i32.wast:334 +assert_return(() => call($1, "lt_s", [-2_147_483_648, 2_147_483_647]), 1); + +// i32.wast:335 +assert_return(() => call($1, "lt_s", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:337 +assert_return(() => call($1, "lt_u", [0, 0]), 0); + +// i32.wast:338 +assert_return(() => call($1, "lt_u", [1, 1]), 0); + +// i32.wast:339 +assert_return(() => call($1, "lt_u", [-1, 1]), 0); + +// i32.wast:340 +assert_return(() => call($1, "lt_u", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:341 +assert_return(() => call($1, "lt_u", [2_147_483_647, 2_147_483_647]), 0); + +// i32.wast:342 +assert_return(() => call($1, "lt_u", [-1, -1]), 0); + +// i32.wast:343 +assert_return(() => call($1, "lt_u", [1, 0]), 0); + +// i32.wast:344 +assert_return(() => call($1, "lt_u", [0, 1]), 1); + +// i32.wast:345 +assert_return(() => call($1, "lt_u", [-2_147_483_648, 0]), 0); + +// i32.wast:346 +assert_return(() => call($1, "lt_u", [0, -2_147_483_648]), 1); + +// i32.wast:347 +assert_return(() => call($1, "lt_u", [-2_147_483_648, -1]), 1); + +// i32.wast:348 +assert_return(() => call($1, "lt_u", [-1, -2_147_483_648]), 0); + +// i32.wast:349 +assert_return(() => call($1, "lt_u", [-2_147_483_648, 2_147_483_647]), 0); + +// i32.wast:350 +assert_return(() => call($1, "lt_u", [2_147_483_647, -2_147_483_648]), 1); + +// i32.wast:352 +assert_return(() => call($1, "le_s", [0, 0]), 1); + +// i32.wast:353 +assert_return(() => call($1, "le_s", [1, 1]), 1); + +// i32.wast:354 +assert_return(() => call($1, "le_s", [-1, 1]), 1); + +// i32.wast:355 +assert_return(() => call($1, "le_s", [-2_147_483_648, -2_147_483_648]), 1); + +// i32.wast:356 +assert_return(() => call($1, "le_s", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:357 +assert_return(() => call($1, "le_s", [-1, -1]), 1); + +// i32.wast:358 +assert_return(() => call($1, "le_s", [1, 0]), 0); + +// i32.wast:359 +assert_return(() => call($1, "le_s", [0, 1]), 1); + +// i32.wast:360 +assert_return(() => call($1, "le_s", [-2_147_483_648, 0]), 1); + +// i32.wast:361 +assert_return(() => call($1, "le_s", [0, -2_147_483_648]), 0); + +// i32.wast:362 +assert_return(() => call($1, "le_s", [-2_147_483_648, -1]), 1); + +// i32.wast:363 +assert_return(() => call($1, "le_s", [-1, -2_147_483_648]), 0); + +// i32.wast:364 +assert_return(() => call($1, "le_s", [-2_147_483_648, 2_147_483_647]), 1); + +// i32.wast:365 +assert_return(() => call($1, "le_s", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:367 +assert_return(() => call($1, "le_u", [0, 0]), 1); + +// i32.wast:368 +assert_return(() => call($1, "le_u", [1, 1]), 1); + +// i32.wast:369 +assert_return(() => call($1, "le_u", [-1, 1]), 0); + +// i32.wast:370 +assert_return(() => call($1, "le_u", [-2_147_483_648, -2_147_483_648]), 1); + +// i32.wast:371 +assert_return(() => call($1, "le_u", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:372 +assert_return(() => call($1, "le_u", [-1, -1]), 1); + +// i32.wast:373 +assert_return(() => call($1, "le_u", [1, 0]), 0); + +// i32.wast:374 +assert_return(() => call($1, "le_u", [0, 1]), 1); + +// i32.wast:375 +assert_return(() => call($1, "le_u", [-2_147_483_648, 0]), 0); + +// i32.wast:376 +assert_return(() => call($1, "le_u", [0, -2_147_483_648]), 1); + +// i32.wast:377 +assert_return(() => call($1, "le_u", [-2_147_483_648, -1]), 1); + +// i32.wast:378 +assert_return(() => call($1, "le_u", [-1, -2_147_483_648]), 0); + +// i32.wast:379 +assert_return(() => call($1, "le_u", [-2_147_483_648, 2_147_483_647]), 0); + +// i32.wast:380 +assert_return(() => call($1, "le_u", [2_147_483_647, -2_147_483_648]), 1); + +// i32.wast:382 +assert_return(() => call($1, "gt_s", [0, 0]), 0); + +// i32.wast:383 +assert_return(() => call($1, "gt_s", [1, 1]), 0); + +// i32.wast:384 +assert_return(() => call($1, "gt_s", [-1, 1]), 0); + +// i32.wast:385 +assert_return(() => call($1, "gt_s", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:386 +assert_return(() => call($1, "gt_s", [2_147_483_647, 2_147_483_647]), 0); + +// i32.wast:387 +assert_return(() => call($1, "gt_s", [-1, -1]), 0); + +// i32.wast:388 +assert_return(() => call($1, "gt_s", [1, 0]), 1); + +// i32.wast:389 +assert_return(() => call($1, "gt_s", [0, 1]), 0); + +// i32.wast:390 +assert_return(() => call($1, "gt_s", [-2_147_483_648, 0]), 0); + +// i32.wast:391 +assert_return(() => call($1, "gt_s", [0, -2_147_483_648]), 1); + +// i32.wast:392 +assert_return(() => call($1, "gt_s", [-2_147_483_648, -1]), 0); + +// i32.wast:393 +assert_return(() => call($1, "gt_s", [-1, -2_147_483_648]), 1); + +// i32.wast:394 +assert_return(() => call($1, "gt_s", [-2_147_483_648, 2_147_483_647]), 0); + +// i32.wast:395 +assert_return(() => call($1, "gt_s", [2_147_483_647, -2_147_483_648]), 1); + +// i32.wast:397 +assert_return(() => call($1, "gt_u", [0, 0]), 0); + +// i32.wast:398 +assert_return(() => call($1, "gt_u", [1, 1]), 0); + +// i32.wast:399 +assert_return(() => call($1, "gt_u", [-1, 1]), 1); + +// i32.wast:400 +assert_return(() => call($1, "gt_u", [-2_147_483_648, -2_147_483_648]), 0); + +// i32.wast:401 +assert_return(() => call($1, "gt_u", [2_147_483_647, 2_147_483_647]), 0); + +// i32.wast:402 +assert_return(() => call($1, "gt_u", [-1, -1]), 0); + +// i32.wast:403 +assert_return(() => call($1, "gt_u", [1, 0]), 1); + +// i32.wast:404 +assert_return(() => call($1, "gt_u", [0, 1]), 0); + +// i32.wast:405 +assert_return(() => call($1, "gt_u", [-2_147_483_648, 0]), 1); + +// i32.wast:406 +assert_return(() => call($1, "gt_u", [0, -2_147_483_648]), 0); + +// i32.wast:407 +assert_return(() => call($1, "gt_u", [-2_147_483_648, -1]), 0); + +// i32.wast:408 +assert_return(() => call($1, "gt_u", [-1, -2_147_483_648]), 1); + +// i32.wast:409 +assert_return(() => call($1, "gt_u", [-2_147_483_648, 2_147_483_647]), 1); + +// i32.wast:410 +assert_return(() => call($1, "gt_u", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:412 +assert_return(() => call($1, "ge_s", [0, 0]), 1); + +// i32.wast:413 +assert_return(() => call($1, "ge_s", [1, 1]), 1); + +// i32.wast:414 +assert_return(() => call($1, "ge_s", [-1, 1]), 0); + +// i32.wast:415 +assert_return(() => call($1, "ge_s", [-2_147_483_648, -2_147_483_648]), 1); + +// i32.wast:416 +assert_return(() => call($1, "ge_s", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:417 +assert_return(() => call($1, "ge_s", [-1, -1]), 1); + +// i32.wast:418 +assert_return(() => call($1, "ge_s", [1, 0]), 1); + +// i32.wast:419 +assert_return(() => call($1, "ge_s", [0, 1]), 0); + +// i32.wast:420 +assert_return(() => call($1, "ge_s", [-2_147_483_648, 0]), 0); + +// i32.wast:421 +assert_return(() => call($1, "ge_s", [0, -2_147_483_648]), 1); + +// i32.wast:422 +assert_return(() => call($1, "ge_s", [-2_147_483_648, -1]), 0); + +// i32.wast:423 +assert_return(() => call($1, "ge_s", [-1, -2_147_483_648]), 1); + +// i32.wast:424 +assert_return(() => call($1, "ge_s", [-2_147_483_648, 2_147_483_647]), 0); + +// i32.wast:425 +assert_return(() => call($1, "ge_s", [2_147_483_647, -2_147_483_648]), 1); + +// i32.wast:427 +assert_return(() => call($1, "ge_u", [0, 0]), 1); + +// i32.wast:428 +assert_return(() => call($1, "ge_u", [1, 1]), 1); + +// i32.wast:429 +assert_return(() => call($1, "ge_u", [-1, 1]), 1); + +// i32.wast:430 +assert_return(() => call($1, "ge_u", [-2_147_483_648, -2_147_483_648]), 1); + +// i32.wast:431 +assert_return(() => call($1, "ge_u", [2_147_483_647, 2_147_483_647]), 1); + +// i32.wast:432 +assert_return(() => call($1, "ge_u", [-1, -1]), 1); + +// i32.wast:433 +assert_return(() => call($1, "ge_u", [1, 0]), 1); + +// i32.wast:434 +assert_return(() => call($1, "ge_u", [0, 1]), 0); + +// i32.wast:435 +assert_return(() => call($1, "ge_u", [-2_147_483_648, 0]), 1); + +// i32.wast:436 +assert_return(() => call($1, "ge_u", [0, -2_147_483_648]), 0); + +// i32.wast:437 +assert_return(() => call($1, "ge_u", [-2_147_483_648, -1]), 0); + +// i32.wast:438 +assert_return(() => call($1, "ge_u", [-1, -2_147_483_648]), 1); + +// i32.wast:439 +assert_return(() => call($1, "ge_u", [-2_147_483_648, 2_147_483_647]), 1); + +// i32.wast:440 +assert_return(() => call($1, "ge_u", [2_147_483_647, -2_147_483_648]), 0); + +// i32.wast:443 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x45\x1a\x0b"); + +// i32.wast:451 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x02\x40\x45\x1a\x0b\x0b"); + +// i32.wast:460 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x03\x40\x45\x1a\x0b\x0b"); + +// i32.wast:469 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x45\x1a\x0b\x0b"); + +// i32.wast:478 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x45\x0b\x1a\x0b"); + +// i32.wast:487 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x45\x0c\x00\x1a\x0b\x0b"); + +// i32.wast:496 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x02\x40\x45\x41\x01\x0d\x00\x1a\x0b\x0b"); + +// i32.wast:505 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x02\x40\x45\x0e\x00\x00\x1a\x0b\x0b"); + +// i32.wast:514 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x45\x0f\x1a\x0b"); + +// i32.wast:522 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x45\x41\x01\x41\x02\x1b\x1a\x0b"); + +// i32.wast:530 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x45\x10\x01\x1a\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// i32.wast:539 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x45\x41\x00\x11\x00\x00\x1a\x0b\x0b"); + +// i32.wast:555 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x01\x01\x7f\x45\x21\x00\x20\x00\x1a\x0b"); + +// i32.wast:564 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x01\x01\x7f\x45\x22\x00\x1a\x0b"); + +// i32.wast:573 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x45\x24\x00\x23\x00\x1a\x0b"); + +// i32.wast:582 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x45\x40\x00\x1a\x0b"); + +// i32.wast:591 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x45\x28\x02\x00\x1a\x0b"); + +// i32.wast:600 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x45\x41\x01\x36\x02\x00\x0b"); + +// i32.wast:610 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x6a\x1a\x0b"); + +// i32.wast:618 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x00\x6a\x1a\x0b"); + +// i32.wast:626 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x02\x40\x6a\x1a\x0b\x0b"); + +// i32.wast:635 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x41\x00\x6a\x1a\x0b\x0b"); + +// i32.wast:644 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x41\x00\x03\x40\x6a\x1a\x0b\x0b"); + +// i32.wast:653 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x03\x40\x41\x00\x6a\x1a\x0b\x0b"); + +// i32.wast:662 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x6a\x04\x40\x1a\x0b\x0b"); + +// i32.wast:671 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x04\x40\x6a\x05\x1a\x0b\x0b"); + +// i32.wast:680 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x6a\x41\x00\x0b\x1a\x1a\x0b"); + +// i32.wast:690 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x6a\x0b\x1a\x0b"); + +// i32.wast:700 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x02\x40\x6a\x0c\x00\x1a\x0b\x0b"); + +// i32.wast:709 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x02\x40\x41\x00\x6a\x0c\x00\x1a\x0b\x0b"); + +// i32.wast:718 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x41\x00\x02\x40\x6a\x41\x01\x0d\x00\x1a\x0b\x0b"); + +// i32.wast:727 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x02\x40\x41\x00\x6a\x41\x01\x0d\x00\x1a\x0b\x0b"); + +// i32.wast:736 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x00\x02\x40\x6a\x0e\x00\x00\x1a\x0b\x0b"); + +// i32.wast:745 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x02\x40\x41\x00\x6a\x0e\x00\x00\x1a\x0b\x0b"); + +// i32.wast:754 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x6a\x0f\x1a\x0b"); + +// i32.wast:762 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x6a\x0f\x1a\x0b"); + +// i32.wast:770 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x6a\x41\x01\x41\x02\x1b\x1a\x0b"); + +// i32.wast:778 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x6a\x41\x01\x41\x02\x1b\x1a\x0b"); + +// i32.wast:786 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x95\x80\x80\x80\x00\x02\x86\x80\x80\x80\x00\x00\x6a\x10\x01\x1a\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// i32.wast:795 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x97\x80\x80\x80\x00\x02\x88\x80\x80\x80\x00\x00\x41\x00\x6a\x10\x01\x1a\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// i32.wast:804 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9b\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x6a\x41\x00\x11\x00\x00\x1a\x0b\x0b"); + +// i32.wast:820 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9d\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x6a\x41\x00\x11\x00\x00\x1a\x0b\x0b"); + +// i32.wast:836 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x01\x01\x7f\x6a\x21\x00\x20\x00\x1a\x0b"); + +// i32.wast:845 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x6a\x21\x00\x20\x00\x1a\x0b"); + +// i32.wast:854 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x01\x01\x7f\x6a\x22\x00\x1a\x0b"); + +// i32.wast:863 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x6a\x22\x00\x1a\x0b"); + +// i32.wast:872 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x6a\x24\x00\x23\x00\x1a\x0b"); + +// i32.wast:881 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x6a\x24\x00\x23\x00\x1a\x0b"); + +// i32.wast:890 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x6a\x40\x00\x1a\x0b"); + +// i32.wast:899 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x6a\x40\x00\x1a\x0b"); + +// i32.wast:908 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x6a\x28\x02\x00\x1a\x0b"); + +// i32.wast:917 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x6a\x28\x02\x00\x1a\x0b"); + +// i32.wast:926 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x6a\x41\x01\x36\x02\x00\x0b"); + +// i32.wast:935 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x6a\x41\x00\x36\x02\x00\x0b"); + +// i32.wast:948 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6a\x0b"); + +// i32.wast:949 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x71\x0b"); + +// i32.wast:950 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6d\x0b"); + +// i32.wast:951 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6e\x0b"); + +// i32.wast:952 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6c\x0b"); + +// i32.wast:953 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x72\x0b"); + +// i32.wast:954 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6f\x0b"); + +// i32.wast:955 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x70\x0b"); + +// i32.wast:956 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x77\x0b"); + +// i32.wast:957 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x78\x0b"); + +// i32.wast:958 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x74\x0b"); + +// i32.wast:959 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x75\x0b"); + +// i32.wast:960 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x76\x0b"); + +// i32.wast:961 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x6b\x0b"); + +// i32.wast:962 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x73\x0b"); + +// i32.wast:963 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x45\x0b"); + +// i32.wast:964 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x67\x0b"); + +// i32.wast:965 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x68\x0b"); + +// i32.wast:966 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x42\x00\x69\x0b"); + +// i32.wast:967 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x46\x0b"); + +// i32.wast:968 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4e\x0b"); + +// i32.wast:969 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4f\x0b"); + +// i32.wast:970 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4a\x0b"); + +// i32.wast:971 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4b\x0b"); + +// i32.wast:972 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4c\x0b"); + +// i32.wast:973 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x4d\x0b"); + +// i32.wast:974 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x48\x0b"); + +// i32.wast:975 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x49\x0b"); + +// i32.wast:976 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x42\x00\x43\x00\x00\x00\x00\x47\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/i64.wast.js b/js/src/jit-test/tests/wasm/spec/spec/i64.wast.js new file mode 100644 index 0000000000..1f4a20e59f --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/i64.wast.js @@ -0,0 +1,1242 @@ + +// i64.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x97\x80\x80\x80\x00\x04\x60\x02\x7e\x7e\x01\x7e\x60\x01\x7e\x01\x7e\x60\x01\x7e\x01\x7f\x60\x02\x7e\x7e\x01\x7f\x03\xa1\x80\x80\x80\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x07\xeb\x81\x80\x80\x00\x20\x03\x61\x64\x64\x00\x00\x03\x73\x75\x62\x00\x01\x03\x6d\x75\x6c\x00\x02\x05\x64\x69\x76\x5f\x73\x00\x03\x05\x64\x69\x76\x5f\x75\x00\x04\x05\x72\x65\x6d\x5f\x73\x00\x05\x05\x72\x65\x6d\x5f\x75\x00\x06\x03\x61\x6e\x64\x00\x07\x02\x6f\x72\x00\x08\x03\x78\x6f\x72\x00\x09\x03\x73\x68\x6c\x00\x0a\x05\x73\x68\x72\x5f\x73\x00\x0b\x05\x73\x68\x72\x5f\x75\x00\x0c\x04\x72\x6f\x74\x6c\x00\x0d\x04\x72\x6f\x74\x72\x00\x0e\x03\x63\x6c\x7a\x00\x0f\x03\x63\x74\x7a\x00\x10\x06\x70\x6f\x70\x63\x6e\x74\x00\x11\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x12\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x13\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x14\x03\x65\x71\x7a\x00\x15\x02\x65\x71\x00\x16\x02\x6e\x65\x00\x17\x04\x6c\x74\x5f\x73\x00\x18\x04\x6c\x74\x5f\x75\x00\x19\x04\x6c\x65\x5f\x73\x00\x1a\x04\x6c\x65\x5f\x75\x00\x1b\x04\x67\x74\x5f\x73\x00\x1c\x04\x67\x74\x5f\x75\x00\x1d\x04\x67\x65\x5f\x73\x00\x1e\x04\x67\x65\x5f\x75\x00\x1f\x0a\xf3\x82\x80\x80\x00\x20\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x7c\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x7d\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x7e\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x7f\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x80\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x81\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x82\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x83\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x84\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x85\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x86\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x87\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x88\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x89\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x8a\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x79\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x7a\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x7b\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xc2\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xc3\x0b\x85\x80\x80\x80\x00\x00\x20\x00\xc4\x0b\x85\x80\x80\x80\x00\x00\x20\x00\x50\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x51\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x52\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x53\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x54\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x57\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x58\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x55\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x56\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x59\x0b\x87\x80\x80\x80\x00\x00\x20\x00\x20\x01\x5a\x0b"); + +// i64.wast:38 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("1"), int64("1")]), int64("2")) + +// i64.wast:39 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:40 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("-1"), int64("-1")]), int64("-2")) + +// i64.wast:41 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("-1"), int64("1")]), int64("0")) + +// i64.wast:42 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("9_223_372_036_854_775_807"), int64("1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:43 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("-9_223_372_036_854_775_808"), int64("-1")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:44 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), int64("0")) + +// i64.wast:45 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x64\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x03\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x04\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add", [int64("1_073_741_823"), int64("1")]), int64("1_073_741_824")) + +// i64.wast:47 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:48 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:49 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("-1"), int64("-1")]), int64("0")) + +// i64.wast:50 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("9_223_372_036_854_775_807"), int64("-1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:51 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x01\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("-9_223_372_036_854_775_808"), int64("1")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:52 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), int64("0")) + +// i64.wast:53 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x75\x62\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x03\x42\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x04\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "sub", [int64("1_073_741_823"), int64("-1")]), int64("1_073_741_824")) + +// i64.wast:55 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("1"), int64("1")]), int64("1")) + +// i64.wast:56 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("1"), int64("0")]), int64("0")) + +// i64.wast:57 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("-1"), int64("-1")]), int64("1")) + +// i64.wast:58 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x10\x42\x80\x20\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("1_152_921_504_606_846_976"), int64("4_096")]), int64("0")) + +// i64.wast:59 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("-9_223_372_036_854_775_808"), int64("0")]), int64("0")) + +// i64.wast:60 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("-9_223_372_036_854_775_808"), int64("-1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:61 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x7f\x10\x00\x01\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("9_223_372_036_854_775_807"), int64("-1")]), int64("-9_223_372_036_854_775_807")) + +// i64.wast:62 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb3\x80\x80\x80\x00\x01\xad\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xaf\xcd\xf8\xac\xd1\x91\x01\x42\x90\xe4\xd0\xb2\x87\xd3\xae\xee\x7e\x10\x00\x01\x42\xf0\x99\x86\xab\xfe\x91\xb6\x9b\x22\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("81_985_529_216_486_895"), int64("-81_985_529_216_486_896")]), int64("2_465_395_958_572_223_728")) + +// i64.wast:63 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x6d\x75\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "mul", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), int64("1")) + +// i64.wast:65 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_s", [int64("1"), int64("0")])) + +// i64.wast:66 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_s", [int64("0"), int64("0")])) + +// i64.wast:67 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_s", [int64("-9_223_372_036_854_775_808"), int64("-1")])) + +// i64.wast:68 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_s", [int64("-9_223_372_036_854_775_808"), int64("0")])) + +// i64.wast:69 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("1"), int64("1")]), int64("1")) + +// i64.wast:70 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("0"), int64("1")]), int64("0")) + +// i64.wast:71 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("0"), int64("-1")]), int64("0")) + +// i64.wast:72 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-1"), int64("-1")]), int64("1")) + +// i64.wast:73 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x02\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x40\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-9_223_372_036_854_775_808"), int64("2")]), int64("-4_611_686_018_427_387_904")) + +// i64.wast:74 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xe8\x07\x10\x00\x01\x42\x89\xd8\xf2\xd0\xc5\xec\xce\x6f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-9_223_372_036_854_775_807"), int64("1_000")]), int64("-9_223_372_036_854_775")) + +// i64.wast:75 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("5"), int64("2")]), int64("2")) + +// i64.wast:76 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x02\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-5"), int64("2")]), int64("-2")) + +// i64.wast:77 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x7e\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("5"), int64("-2")]), int64("-2")) + +// i64.wast:78 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x7e\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-5"), int64("-2")]), int64("2")) + +// i64.wast:79 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x03\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("7"), int64("3")]), int64("2")) + +// i64.wast:80 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x79\x42\x03\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-7"), int64("3")]), int64("-2")) + +// i64.wast:81 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x7d\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("7"), int64("-3")]), int64("-2")) + +// i64.wast:82 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x79\x42\x7d\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("-7"), int64("-3")]), int64("2")) + +// i64.wast:83 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x0b\x42\x05\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("11"), int64("5")]), int64("2")) + +// i64.wast:84 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x11\x42\x07\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_s", [int64("17"), int64("7")]), int64("2")) + +// i64.wast:86 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_u", [int64("1"), int64("0")])) + +// i64.wast:87 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "div_u", [int64("0"), int64("0")])) + +// i64.wast:88 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("1"), int64("1")]), int64("1")) + +// i64.wast:89 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("0"), int64("1")]), int64("0")) + +// i64.wast:90 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-1"), int64("-1")]), int64("1")) + +// i64.wast:91 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), int64("0")) + +// i64.wast:92 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x02\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-9_223_372_036_854_775_808"), int64("2")]), int64("4_611_686_018_427_387_904")) + +// i64.wast:93 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\xf0\x9f\xc0\xff\x80\xfe\x83\xf8\x8f\x7f\x42\x81\x80\x80\x80\x10\x10\x00\x01\x42\xef\x9f\xc0\xff\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-8_074_936_608_141_340_688"), int64("4_294_967_297")]), int64("2_414_874_607")) + +// i64.wast:94 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xe8\x07\x10\x00\x01\x42\xf7\xa7\x8d\xaf\xba\x93\xb1\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-9_223_372_036_854_775_807"), int64("1_000")]), int64("9_223_372_036_854_775")) + +// i64.wast:95 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("5"), int64("2")]), int64("2")) + +// i64.wast:96 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x02\x10\x00\x01\x42\xfd\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-5"), int64("2")]), int64("9_223_372_036_854_775_805")) + +// i64.wast:97 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x7e\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("5"), int64("-2")]), int64("0")) + +// i64.wast:98 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x7e\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("-5"), int64("-2")]), int64("0")) + +// i64.wast:99 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x03\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("7"), int64("3")]), int64("2")) + +// i64.wast:100 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x0b\x42\x05\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("11"), int64("5")]), int64("2")) + +// i64.wast:101 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x64\x69\x76\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x11\x42\x07\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "div_u", [int64("17"), int64("7")]), int64("2")) + +// i64.wast:103 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "rem_s", [int64("1"), int64("0")])) + +// i64.wast:104 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "rem_s", [int64("0"), int64("0")])) + +// i64.wast:105 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("9_223_372_036_854_775_807"), int64("-1")]), int64("0")) + +// i64.wast:106 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:107 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("0"), int64("1")]), int64("0")) + +// i64.wast:108 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("0"), int64("-1")]), int64("0")) + +// i64.wast:109 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-1"), int64("-1")]), int64("0")) + +// i64.wast:110 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-9_223_372_036_854_775_808"), int64("-1")]), int64("0")) + +// i64.wast:111 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x02\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-9_223_372_036_854_775_808"), int64("2")]), int64("0")) + +// i64.wast:112 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xe8\x07\x10\x00\x01\x42\xd9\x79\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-9_223_372_036_854_775_807"), int64("1_000")]), int64("-807")) + +// i64.wast:113 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x02\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("5"), int64("2")]), int64("1")) + +// i64.wast:114 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x02\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-5"), int64("2")]), int64("-1")) + +// i64.wast:115 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x7e\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("5"), int64("-2")]), int64("1")) + +// i64.wast:116 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x7e\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-5"), int64("-2")]), int64("-1")) + +// i64.wast:117 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x03\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("7"), int64("3")]), int64("1")) + +// i64.wast:118 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x79\x42\x03\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-7"), int64("3")]), int64("-1")) + +// i64.wast:119 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x7d\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("7"), int64("-3")]), int64("1")) + +// i64.wast:120 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x79\x42\x7d\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("-7"), int64("-3")]), int64("-1")) + +// i64.wast:121 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x0b\x42\x05\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("11"), int64("5")]), int64("1")) + +// i64.wast:122 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x11\x42\x07\x10\x00\x01\x42\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_s", [int64("17"), int64("7")]), int64("3")) + +// i64.wast:124 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "rem_u", [int64("1"), int64("0")])) + +// i64.wast:125 +assert_trap(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_trap(() => call($1, "rem_u", [int64("0"), int64("0")])) + +// i64.wast:126 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:127 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("0"), int64("1")]), int64("0")) + +// i64.wast:128 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-1"), int64("-1")]), int64("0")) + +// i64.wast:129 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:130 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x02\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-9_223_372_036_854_775_808"), int64("2")]), int64("0")) + +// i64.wast:131 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\xf0\x9f\xc0\xff\x80\xfe\x83\xf8\x8f\x7f\x42\x81\x80\x80\x80\x10\x10\x00\x01\x42\x81\x80\x80\x80\x08\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-8_074_936_608_141_340_688"), int64("4_294_967_297")]), int64("2_147_483_649")) + +// i64.wast:132 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa6\x80\x80\x80\x00\x01\xa0\x80\x80\x80\x00\x00\x02\x40\x42\x81\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xe8\x07\x10\x00\x01\x42\xa9\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-9_223_372_036_854_775_807"), int64("1_000")]), int64("809")) + +// i64.wast:133 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x02\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("5"), int64("2")]), int64("1")) + +// i64.wast:134 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x02\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-5"), int64("2")]), int64("1")) + +// i64.wast:135 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x05\x42\x7e\x10\x00\x01\x42\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("5"), int64("-2")]), int64("5")) + +// i64.wast:136 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7b\x42\x7e\x10\x00\x01\x42\x7b\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("-5"), int64("-2")]), int64("-5")) + +// i64.wast:137 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x07\x42\x03\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("7"), int64("3")]), int64("1")) + +// i64.wast:138 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x0b\x42\x05\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("11"), int64("5")]), int64("1")) + +// i64.wast:139 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x72\x65\x6d\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x11\x42\x07\x10\x00\x01\x42\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rem_u", [int64("17"), int64("7")]), int64("3")) + +// i64.wast:141 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("1"), int64("0")]), int64("0")) + +// i64.wast:142 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("0"), int64("1")]), int64("0")) + +// i64.wast:143 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("1"), int64("1")]), int64("1")) + +// i64.wast:144 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("0"), int64("0")]), int64("0")) + +// i64.wast:145 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), int64("0")) + +// i64.wast:146 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("9_223_372_036_854_775_807"), int64("-1")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:147 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xc3\x87\x0f\x42\xf0\xe1\xff\xff\x0f\x10\x00\x01\x42\xf0\xe1\xc3\x87\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("4_042_326_015"), int64("4_294_963_440")]), int64("4_042_322_160")) + +// i64.wast:148 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "and", [int64("-1"), int64("-1")]), int64("-1")) + +// i64.wast:150 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:151 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("0"), int64("1")]), int64("1")) + +// i64.wast:152 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("1"), int64("1")]), int64("1")) + +// i64.wast:153 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("0"), int64("0")]), int64("0")) + +// i64.wast:154 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), int64("-1")) + +// i64.wast:155 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("-9_223_372_036_854_775_808"), int64("0")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:156 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xc3\x87\x0f\x42\xf0\xe1\xff\xff\x0f\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("4_042_326_015"), int64("4_294_963_440")]), int64("4_294_967_295")) + +// i64.wast:157 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "or", [int64("-1"), int64("-1")]), int64("-1")) + +// i64.wast:159 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:160 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("0"), int64("1")]), int64("1")) + +// i64.wast:161 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:162 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("0"), int64("0")]), int64("0")) + +// i64.wast:163 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), int64("-1")) + +// i64.wast:164 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("-9_223_372_036_854_775_808"), int64("0")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:165 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("-1"), int64("-9_223_372_036_854_775_808")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:166 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("-1"), int64("9_223_372_036_854_775_807")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:167 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xc3\x87\x0f\x42\xf0\xe1\xff\xff\x0f\x10\x00\x01\x42\x8f\x9e\xbc\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("4_042_326_015"), int64("4_294_963_440")]), int64("252_645_135")) + +// i64.wast:168 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x78\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "xor", [int64("-1"), int64("-1")]), int64("0")) + +// i64.wast:170 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("1")]), int64("2")) + +// i64.wast:171 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:172 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x01\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("9_223_372_036_854_775_807"), int64("1")]), int64("-2")) + +// i64.wast:173 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("-1"), int64("1")]), int64("-2")) + +// i64.wast:174 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("-9_223_372_036_854_775_808"), int64("1")]), int64("0")) + +// i64.wast:175 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\xc0\x00\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("4_611_686_018_427_387_904"), int64("1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:176 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x3f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("63")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:177 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc0\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("64")]), int64("1")) + +// i64.wast:178 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc1\x00\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("65")]), int64("2")) + +// i64.wast:179 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x7f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("-1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:180 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x73\x68\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shl", [int64("1"), int64("9_223_372_036_854_775_807")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:182 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:183 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:184 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("1")]), int64("-1")) + +// i64.wast:185 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x01\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("9_223_372_036_854_775_807"), int64("1")]), int64("4_611_686_018_427_387_903")) + +// i64.wast:186 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x40\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-9_223_372_036_854_775_808"), int64("1")]), int64("-4_611_686_018_427_387_904")) + +// i64.wast:187 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\xc0\x00\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x20\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("4_611_686_018_427_387_904"), int64("1")]), int64("2_305_843_009_213_693_952")) + +// i64.wast:188 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc0\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("64")]), int64("1")) + +// i64.wast:189 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc1\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("65")]), int64("0")) + +// i64.wast:190 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("-1")]), int64("0")) + +// i64.wast:191 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("9_223_372_036_854_775_807")]), int64("0")) + +// i64.wast:192 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("1"), int64("-9_223_372_036_854_775_808")]), int64("1")) + +// i64.wast:193 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x3f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-9_223_372_036_854_775_808"), int64("63")]), int64("-1")) + +// i64.wast:194 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xc0\x00\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("64")]), int64("-1")) + +// i64.wast:195 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xc1\x00\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("65")]), int64("-1")) + +// i64.wast:196 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("-1")]), int64("-1")) + +// i64.wast:197 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("9_223_372_036_854_775_807")]), int64("-1")) + +// i64.wast:198 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_s", [int64("-1"), int64("-9_223_372_036_854_775_808")]), int64("-1")) + +// i64.wast:200 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("1")]), int64("0")) + +// i64.wast:201 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:202 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("1")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x01\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("9_223_372_036_854_775_807"), int64("1")]), int64("4_611_686_018_427_387_903")) + +// i64.wast:204 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-9_223_372_036_854_775_808"), int64("1")]), int64("4_611_686_018_427_387_904")) + +// i64.wast:205 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\xc0\x00\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x20\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("4_611_686_018_427_387_904"), int64("1")]), int64("2_305_843_009_213_693_952")) + +// i64.wast:206 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc0\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("64")]), int64("1")) + +// i64.wast:207 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc1\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("65")]), int64("0")) + +// i64.wast:208 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("-1")]), int64("0")) + +// i64.wast:209 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("9_223_372_036_854_775_807")]), int64("0")) + +// i64.wast:210 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("1"), int64("-9_223_372_036_854_775_808")]), int64("1")) + +// i64.wast:211 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-9_223_372_036_854_775_808"), int64("63")]), int64("1")) + +// i64.wast:212 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xc0\x00\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("64")]), int64("-1")) + +// i64.wast:213 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xc1\x00\x10\x00\x01\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("65")]), int64("9_223_372_036_854_775_807")) + +// i64.wast:214 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("-1")]), int64("1")) + +// i64.wast:215 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("9_223_372_036_854_775_807")]), int64("1")) + +// i64.wast:216 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x73\x68\x72\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "shr_u", [int64("-1"), int64("-9_223_372_036_854_775_808")]), int64("-1")) + +// i64.wast:218 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("1"), int64("1")]), int64("2")) + +// i64.wast:219 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:220 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-1"), int64("1")]), int64("-1")) + +// i64.wast:221 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc0\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("1"), int64("64")]), int64("1")) + +// i64.wast:222 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xce\x95\x9a\x92\xe0\x8e\xe6\xe6\xab\x7f\x42\x01\x10\x00\x01\x42\x9d\xab\xb4\xa4\xc0\x9d\xcc\xcd\xd7\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_067_025_490_386_449_714"), int64("1")]), int64("6_312_693_092_936_652_189")) + +// i64.wast:223 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xab\x80\x80\x80\x00\x01\xa5\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\xe0\x8d\x80\x80\x80\x7e\x42\x04\x10\x00\x01\x42\x8f\x80\x80\x80\xdc\x81\x80\x80\x60\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-144_115_184_384_868_352"), int64("4")]), int64("-2_305_842_950_157_893_617")) + +// i64.wast:224 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xc6\xc4\xe6\xab\x7f\x42\x35\x10\x00\x01\x42\xcf\xd5\xf7\xb4\xa4\xb4\xde\x9a\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_067_173_104_435_169_271"), int64("53")]), int64("87_109_505_680_009_935")) + +// i64.wast:225 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x9c\x81\x9e\xab\xef\xe9\xc8\xe8\xab\x7f\x42\x3f\x10\x00\x01\x42\xce\x80\xcf\xd5\xf7\xb4\xa4\xf4\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_066_028_401_059_725_156"), int64("63")]), int64("6_190_357_836_324_913_230")) + +// i64.wast:226 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xc6\xc4\xe6\xab\x7f\x42\xf5\x01\x10\x00\x01\x42\xcf\xd5\xf7\xb4\xa4\xb4\xde\x9a\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_067_173_104_435_169_271"), int64("245")]), int64("87_109_505_680_009_935")) + +// i64.wast:227 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xac\x80\x80\x80\x00\x01\xa6\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xd2\xdc\xe6\xab\x7f\x42\x6d\x10\x00\x01\x42\xea\xbb\xca\xf2\x9a\xaf\xcd\x80\x4f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_067_067_139_002_042_359"), int64("-19")]), int64("-3_530_481_836_149_793_302")) + +// i64.wast:228 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb6\x80\x80\x80\x00\x01\xb0\x80\x80\x80\x00\x00\x02\x40\x42\x9c\x81\x9e\xab\xef\xe9\xc8\xe8\xab\x7f\x42\xbf\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\xce\x80\xcf\xd5\xf7\xb4\xa4\xf4\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-6_066_028_401_059_725_156"), int64("-9_223_372_036_854_775_745")]), int64("6_190_357_836_324_913_230")) + +// i64.wast:229 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x3f\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("1"), int64("63")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:230 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x6c\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotl", [int64("-9_223_372_036_854_775_808"), int64("1")]), int64("1")) + +// i64.wast:232 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("1"), int64("1")]), int64("-9_223_372_036_854_775_808")) + +// i64.wast:233 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("1"), int64("0")]), int64("1")) + +// i64.wast:234 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-1"), int64("1")]), int64("-1")) + +// i64.wast:235 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9c\x80\x80\x80\x00\x01\x96\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\xc0\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("1"), int64("64")]), int64("1")) + +// i64.wast:236 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xce\x95\x9a\x92\xe0\x8e\xe6\xe6\xab\x7f\x42\x01\x10\x00\x01\x42\xe7\x8a\x8d\x89\xb0\x87\xb3\xf3\xd5\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_067_025_490_386_449_714"), int64("1")]), int64("6_189_859_291_661_550_951")) + +// i64.wast:237 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xab\x80\x80\x80\x00\x01\xa5\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\xe0\x8d\x80\x80\x80\x7e\x42\x04\x10\x00\x01\x42\x80\x80\x80\xee\x80\x80\x80\xf0\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-144_115_184_384_868_352"), int64("4")]), int64("1_143_914_305_582_792_704")) + +// i64.wast:238 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xc6\xc4\xe6\xab\x7f\x42\x35\x10\x00\x01\x42\xde\x9a\x81\x9e\xab\xef\xe9\xc8\xe8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_067_173_104_435_169_271"), int64("53")]), int64("7_534_987_797_011_123_550")) + +// i64.wast:239 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x9c\x81\x9e\xab\xef\xe9\xc8\xe8\xab\x7f\x42\x3f\x10\x00\x01\x42\xb9\x82\xbc\xd6\xde\xd3\x91\xd1\xd7\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_066_028_401_059_725_156"), int64("63")]), int64("6_314_687_271_590_101_305")) + +// i64.wast:240 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xae\x80\x80\x80\x00\x01\xa8\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xc6\xc4\xe6\xab\x7f\x42\xf5\x01\x10\x00\x01\x42\xde\x9a\x81\x9e\xab\xef\xe9\xc8\xe8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_067_173_104_435_169_271"), int64("245")]), int64("7_534_987_797_011_123_550")) + +// i64.wast:241 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x89\xf0\xd9\xfa\xce\xd2\xdc\xe6\xab\x7f\x42\x6d\x10\x00\x01\x42\xeb\xbc\xb5\x82\xbc\xd6\xde\xd3\x94\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_067_067_139_002_042_359"), int64("-19")]), int64("-7_735_078_922_541_506_965")) + +// i64.wast:242 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb6\x80\x80\x80\x00\x01\xb0\x80\x80\x80\x00\x00\x02\x40\x42\x9c\x81\x9e\xab\xef\xe9\xc8\xe8\xab\x7f\x42\xbf\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\xb9\x82\xbc\xd6\xde\xd3\x91\xd1\xd7\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-6_066_028_401_059_725_156"), int64("-9_223_372_036_854_775_745")]), int64("6_314_687_271_590_101_305")) + +// i64.wast:243 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x3f\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("1"), int64("63")]), int64("2")) + +// i64.wast:244 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x72\x6f\x74\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x3f\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "rotr", [int64("-9_223_372_036_854_775_808"), int64("63")]), int64("1")) + +// i64.wast:246 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("-1")]), int64("0")) + +// i64.wast:247 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("0")]), int64("64")) + +// i64.wast:248 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x02\x10\x00\x01\x42\x30\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("32_768")]), int64("48")) + +// i64.wast:249 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\xff\x01\x10\x00\x01\x42\x38\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("255")]), int64("56")) + +// i64.wast:250 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("-9_223_372_036_854_775_808")]), int64("0")) + +// i64.wast:251 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("1")]), int64("63")) + +// i64.wast:252 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x3e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("2")]), int64("62")) + +// i64.wast:253 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x6c\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "clz", [int64("9_223_372_036_854_775_807")]), int64("1")) + +// i64.wast:255 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("-1")]), int64("0")) + +// i64.wast:256 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("0")]), int64("64")) + +// i64.wast:257 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x02\x10\x00\x01\x42\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("32_768")]), int64("15")) + +// i64.wast:258 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x04\x10\x00\x01\x42\x10\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("65_536")]), int64("16")) + +// i64.wast:259 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("-9_223_372_036_854_775_808")]), int64("63")) + +// i64.wast:260 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x63\x74\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ctz", [int64("9_223_372_036_854_775_807")]), int64("0")) + +// i64.wast:262 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xc0\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("-1")]), int64("64")) + +// i64.wast:263 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("0")]), int64("0")) + +// i64.wast:264 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x02\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("32_768")]), int64("1")) + +// i64.wast:265 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x82\x80\x88\x80\xa0\x80\x80\x7f\x10\x00\x01\x42\x04\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("-9_223_231_297_218_904_064")]), int64("4")) + +// i64.wast:266 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x42\x3f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("9_223_372_036_854_775_807")]), int64("63")) + +// i64.wast:267 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xd5\xaa\xd5\xaa\xa5\xd5\xaa\xd5\xaa\x7f\x10\x00\x01\x42\x20\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("-6_148_914_692_668_172_971")]), int64("32")) + +// i64.wast:268 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xaa\xd5\xaa\xd5\x9a\xb3\xe6\xcc\x99\x7f\x10\x00\x01\x42\x20\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("-7_378_697_629_197_489_494")]), int64("32")) + +// i64.wast:269 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8d\x80\x80\x80\x00\x01\x02\x24\x31\x06\x70\x6f\x70\x63\x6e\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xef\xfd\xb6\xf5\xfd\xdd\xef\xd6\x5e\x10\x00\x01\x42\x30\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "popcnt", [int64("-2_401_053_088_876_216_593")]), int64("48")) + +// i64.wast:271 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("0")]), int64("0")) + +// i64.wast:272 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xff\x00\x10\x00\x01\x42\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("127")]), int64("127")) + +// i64.wast:273 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x80\x01\x10\x00\x01\x42\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("128")]), int64("-128")) + +// i64.wast:274 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\xff\x01\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("255")]), int64("-1")) + +// i64.wast:275 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x9a\xaf\xcd\xf8\xac\xd1\x91\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("81_985_529_216_486_656")]), int64("0")) + +// i64.wast:276 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x80\xe5\xd0\xb2\x87\xd3\xae\xee\x7e\x10\x00\x01\x42\x80\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("-81_985_529_216_486_784")]), int64("-128")) + +// i64.wast:277 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x65\x78\x74\x65\x6e\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend8_s", [int64("-1")]), int64("-1")) + +// i64.wast:279 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("0")]), int64("0")) + +// i64.wast:280 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\x01\x10\x00\x01\x42\xff\xff\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("32_767")]), int64("32_767")) + +// i64.wast:281 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x02\x10\x00\x01\x42\x80\x80\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("32_768")]), int64("-32_768")) + +// i64.wast:282 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\x03\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("65_535")]), int64("-1")) + +// i64.wast:283 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\xf0\xd5\x89\xcf\x95\x9a\x12\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("1_311_768_467_463_733_248")]), int64("0")) + +// i64.wast:284 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\xd2\xb2\x87\xd3\xae\xee\x7e\x10\x00\x01\x42\x80\x80\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("-81_985_529_216_466_944")]), int64("-32_768")) + +// i64.wast:285 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend16_s", [int64("-1")]), int64("-1")) + +// i64.wast:287 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("0")]), int64("0")) + +// i64.wast:288 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\x01\x10\x00\x01\x42\xff\xff\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("32_767")]), int64("32_767")) + +// i64.wast:289 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x02\x10\x00\x01\x42\x80\x80\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("32_768")]), int64("32_768")) + +// i64.wast:290 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\x03\x10\x00\x01\x42\xff\xff\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("65_535")]), int64("65_535")) + +// i64.wast:291 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x07\x10\x00\x01\x42\xff\xff\xff\xff\x07\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("2_147_483_647")]), int64("2_147_483_647")) + +// i64.wast:292 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x08\x10\x00\x01\x42\x80\x80\x80\x80\x78\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("2_147_483_648")]), int64("-2_147_483_648")) + +// i64.wast:293 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\x0f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("4_294_967_295")]), int64("-1")) + +// i64.wast:294 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\xf0\xac\xd1\x91\x01\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("81_985_526_906_748_928")]), int64("0")) + +// i64.wast:295 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x88\xd3\xae\xee\x7e\x10\x00\x01\x42\x80\x80\x80\x80\x78\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("-81_985_529_054_232_576")]), int64("-2_147_483_648")) + +// i64.wast:296 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x91\x80\x80\x80\x00\x01\x02\x24\x31\x0a\x65\x78\x74\x65\x6e\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "extend32_s", [int64("-1")]), int64("-1")) + +// i64.wast:298 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x65\x71\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eqz", [int64("0")]), 1) + +// i64.wast:299 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x65\x71\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eqz", [int64("1")]), 0) + +// i64.wast:300 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x65\x71\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eqz", [int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:301 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x65\x71\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eqz", [int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:302 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7f\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x65\x71\x7a\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eqz", [int64("-1")]), 0) + +// i64.wast:304 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("0"), int64("0")]), 1) + +// i64.wast:305 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("1"), int64("1")]), 1) + +// i64.wast:306 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-1"), int64("1")]), 0) + +// i64.wast:307 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:308 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:309 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-1"), int64("-1")]), 1) + +// i64.wast:310 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("1"), int64("0")]), 0) + +// i64.wast:311 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("0"), int64("1")]), 0) + +// i64.wast:312 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-9_223_372_036_854_775_808"), int64("0")]), 0) + +// i64.wast:313 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("0"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:314 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 0) + +// i64.wast:315 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:316 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:317 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x65\x71\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "eq", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:319 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("0"), int64("0")]), 0) + +// i64.wast:320 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("1"), int64("1")]), 0) + +// i64.wast:321 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-1"), int64("1")]), 1) + +// i64.wast:322 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:323 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:324 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-1"), int64("-1")]), 0) + +// i64.wast:325 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("1"), int64("0")]), 1) + +// i64.wast:326 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("0"), int64("1")]), 1) + +// i64.wast:327 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-9_223_372_036_854_775_808"), int64("0")]), 1) + +// i64.wast:328 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("0"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:329 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 1) + +// i64.wast:330 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:331 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:332 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x89\x80\x80\x80\x00\x01\x02\x24\x31\x02\x6e\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ne", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:334 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("0"), int64("0")]), 0) + +// i64.wast:335 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("1"), int64("1")]), 0) + +// i64.wast:336 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-1"), int64("1")]), 1) + +// i64.wast:337 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:338 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:339 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-1"), int64("-1")]), 0) + +// i64.wast:340 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("1"), int64("0")]), 0) + +// i64.wast:341 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("0"), int64("1")]), 1) + +// i64.wast:342 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-9_223_372_036_854_775_808"), int64("0")]), 1) + +// i64.wast:343 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("0"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:344 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 1) + +// i64.wast:345 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:346 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:347 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_s", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:349 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("0"), int64("0")]), 0) + +// i64.wast:350 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("1"), int64("1")]), 0) + +// i64.wast:351 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-1"), int64("1")]), 0) + +// i64.wast:352 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:353 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:354 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-1"), int64("-1")]), 0) + +// i64.wast:355 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("1"), int64("0")]), 0) + +// i64.wast:356 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("0"), int64("1")]), 1) + +// i64.wast:357 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-9_223_372_036_854_775_808"), int64("0")]), 0) + +// i64.wast:358 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("0"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:359 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 1) + +// i64.wast:360 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:361 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:362 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "lt_u", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:364 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("0"), int64("0")]), 1) + +// i64.wast:365 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("1"), int64("1")]), 1) + +// i64.wast:366 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-1"), int64("1")]), 1) + +// i64.wast:367 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:368 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:369 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-1"), int64("-1")]), 1) + +// i64.wast:370 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("1"), int64("0")]), 0) + +// i64.wast:371 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("0"), int64("1")]), 1) + +// i64.wast:372 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-9_223_372_036_854_775_808"), int64("0")]), 1) + +// i64.wast:373 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("0"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:374 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 1) + +// i64.wast:375 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:376 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:377 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_s", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:379 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("0"), int64("0")]), 1) + +// i64.wast:380 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("1"), int64("1")]), 1) + +// i64.wast:381 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-1"), int64("1")]), 0) + +// i64.wast:382 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:383 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:384 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-1"), int64("-1")]), 1) + +// i64.wast:385 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("1"), int64("0")]), 0) + +// i64.wast:386 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("0"), int64("1")]), 1) + +// i64.wast:387 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-9_223_372_036_854_775_808"), int64("0")]), 0) + +// i64.wast:388 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("0"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:389 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 1) + +// i64.wast:390 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:391 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:392 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x6c\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "le_u", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:394 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("0"), int64("0")]), 0) + +// i64.wast:395 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("1"), int64("1")]), 0) + +// i64.wast:396 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-1"), int64("1")]), 0) + +// i64.wast:397 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:398 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:399 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-1"), int64("-1")]), 0) + +// i64.wast:400 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("1"), int64("0")]), 1) + +// i64.wast:401 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("0"), int64("1")]), 0) + +// i64.wast:402 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-9_223_372_036_854_775_808"), int64("0")]), 0) + +// i64.wast:403 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("0"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:404 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 0) + +// i64.wast:405 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:406 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:407 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_s", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:409 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("0"), int64("0")]), 0) + +// i64.wast:410 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("1"), int64("1")]), 0) + +// i64.wast:411 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-1"), int64("1")]), 1) + +// i64.wast:412 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:413 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:414 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-1"), int64("-1")]), 0) + +// i64.wast:415 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("1"), int64("0")]), 1) + +// i64.wast:416 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("0"), int64("1")]), 0) + +// i64.wast:417 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-9_223_372_036_854_775_808"), int64("0")]), 1) + +// i64.wast:418 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("0"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:419 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 0) + +// i64.wast:420 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:421 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:422 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x74\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "gt_u", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:424 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("0"), int64("0")]), 1) + +// i64.wast:425 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("1"), int64("1")]), 1) + +// i64.wast:426 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-1"), int64("1")]), 0) + +// i64.wast:427 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:428 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:429 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-1"), int64("-1")]), 1) + +// i64.wast:430 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("1"), int64("0")]), 1) + +// i64.wast:431 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("0"), int64("1")]), 0) + +// i64.wast:432 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-9_223_372_036_854_775_808"), int64("0")]), 0) + +// i64.wast:433 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("0"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:434 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 0) + +// i64.wast:435 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:436 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 0) + +// i64.wast:437 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_s", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:439 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("0"), int64("0")]), 1) + +// i64.wast:440 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("1"), int64("1")]), 1) + +// i64.wast:441 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-1"), int64("1")]), 1) + +// i64.wast:442 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:443 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("9_223_372_036_854_775_807"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:444 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-1"), int64("-1")]), 1) + +// i64.wast:445 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x01\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("1"), int64("0")]), 1) + +// i64.wast:446 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x01\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("0"), int64("1")]), 0) + +// i64.wast:447 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-9_223_372_036_854_775_808"), int64("0")]), 1) + +// i64.wast:448 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("0"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:449 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-9_223_372_036_854_775_808"), int64("-1")]), 0) + +// i64.wast:450 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-1"), int64("-9_223_372_036_854_775_808")]), 1) + +// i64.wast:451 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("-9_223_372_036_854_775_808"), int64("9_223_372_036_854_775_807")]), 1) + +// i64.wast:452 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7f\x02\x8b\x80\x80\x80\x00\x01\x02\x24\x31\x04\x67\x65\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "ge_u", [int64("9_223_372_036_854_775_807"), int64("-9_223_372_036_854_775_808")]), 0) + +// i64.wast:457 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x7c\x0b"); + +// i64.wast:458 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x83\x0b"); + +// i64.wast:459 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x7f\x0b"); + +// i64.wast:460 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x80\x0b"); + +// i64.wast:461 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x7e\x0b"); + +// i64.wast:462 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x84\x0b"); + +// i64.wast:463 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x81\x0b"); + +// i64.wast:464 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x82\x0b"); + +// i64.wast:465 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x89\x0b"); + +// i64.wast:466 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x8a\x0b"); + +// i64.wast:467 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x86\x0b"); + +// i64.wast:468 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x87\x0b"); + +// i64.wast:469 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x88\x0b"); + +// i64.wast:470 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x7d\x0b"); + +// i64.wast:471 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x85\x0b"); + +// i64.wast:472 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\x50\x0b"); + +// i64.wast:473 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\x79\x0b"); + +// i64.wast:474 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\x7a\x0b"); + +// i64.wast:475 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x41\x00\x7b\x0b"); + +// i64.wast:476 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x51\x0b"); + +// i64.wast:477 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x59\x0b"); + +// i64.wast:478 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x5a\x0b"); + +// i64.wast:479 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x55\x0b"); + +// i64.wast:480 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x56\x0b"); + +// i64.wast:481 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x57\x0b"); + +// i64.wast:482 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x58\x0b"); + +// i64.wast:483 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x53\x0b"); + +// i64.wast:484 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x54\x0b"); + +// i64.wast:485 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x52\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/if.wast.js b/js/src/jit-test/tests/wasm/spec/spec/if.wast.js new file mode 100644 index 0000000000..2f991f8269 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/if.wast.js @@ -0,0 +1,717 @@ + +// if.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xdd\x80\x80\x80\x00\x10\x60\x02\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x60\x03\x7f\x7c\x7f\x03\x7f\x7c\x7f\x60\x01\x7f\x01\x7f\x60\x01\x7f\x02\x7f\x7f\x60\x00\x03\x7f\x7e\x7f\x60\x00\x02\x7f\x7f\x60\x00\x02\x7d\x7d\x60\x01\x7f\x03\x7f\x7f\x7e\x60\x00\x03\x7f\x7f\x7e\x60\x02\x7f\x7f\x02\x7f\x7f\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x60\x02\x7e\x7e\x01\x7e\x60\x01\x7e\x01\x7e\x03\xb5\x80\x80\x80\x00\x34\x01\x03\x05\x06\x00\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x00\x05\x05\x05\x03\x03\x05\x05\x05\x05\x03\x05\x05\x05\x05\x05\x05\x00\x05\x00\x05\x05\x05\x02\x05\x0a\x05\x05\x05\x05\x05\x05\x05\x0d\x0e\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xb9\x86\x80\x80\x00\x31\x05\x65\x6d\x70\x74\x79\x00\x01\x08\x73\x69\x6e\x67\x75\x6c\x61\x72\x00\x02\x05\x6d\x75\x6c\x74\x69\x00\x03\x06\x6e\x65\x73\x74\x65\x64\x00\x04\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x05\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x06\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x07\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x08\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x09\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x0a\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x0b\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x0c\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x0d\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x0e\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x0f\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x11\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x12\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x13\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x14\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x15\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x16\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x18\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x19\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1a\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x1b\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x1c\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x1d\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x1e\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1f\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x20\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x21\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x22\x12\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x23\x12\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x24\x13\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x25\x11\x61\x73\x2d\x6d\x69\x78\x65\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x26\x0a\x62\x72\x65\x61\x6b\x2d\x62\x61\x72\x65\x00\x27\x0b\x62\x72\x65\x61\x6b\x2d\x76\x61\x6c\x75\x65\x00\x28\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x29\x05\x70\x61\x72\x61\x6d\x00\x2a\x06\x70\x61\x72\x61\x6d\x73\x00\x2b\x09\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x00\x2c\x0b\x70\x61\x72\x61\x6d\x2d\x62\x72\x65\x61\x6b\x00\x2d\x0c\x70\x61\x72\x61\x6d\x73\x2d\x62\x72\x65\x61\x6b\x00\x2e\x0f\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x2d\x62\x72\x65\x61\x6b\x00\x2f\x07\x65\x66\x66\x65\x63\x74\x73\x00\x30\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x32\x08\x74\x79\x70\x65\x2d\x75\x73\x65\x00\x33\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x10\x0a\x88\x8d\x80\x80\x00\x34\x82\x80\x80\x80\x00\x00\x0b\x96\x80\x80\x80\x00\x00\x20\x00\x04\x40\x0b\x20\x00\x04\x40\x0b\x20\x00\x04\x40\x0b\x20\x00\x04\x40\x0b\x0b\x9a\x80\x80\x80\x00\x00\x20\x00\x04\x40\x01\x0b\x20\x00\x04\x40\x01\x05\x01\x0b\x20\x00\x04\x7f\x41\x07\x05\x41\x08\x0b\x0b\xe7\x80\x80\x80\x00\x00\x20\x00\x04\x40\x10\x00\x10\x00\x10\x00\x0b\x20\x00\x04\x40\x05\x10\x00\x10\x00\x10\x00\x0b\x20\x00\x04\x7f\x10\x00\x10\x00\x41\x08\x10\x00\x05\x10\x00\x10\x00\x41\x09\x10\x00\x0b\x20\x00\x04\x07\x10\x00\x10\x00\x41\x01\x10\x00\x10\x00\x10\x00\x42\x02\x10\x00\x10\x00\x10\x00\x41\x03\x10\x00\x05\x10\x00\x10\x00\x41\x7f\x10\x00\x10\x00\x10\x00\x42\x7e\x10\x00\x10\x00\x10\x00\x41\x7d\x10\x00\x0b\x1a\x1a\x0b\xd2\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x20\x01\x04\x40\x10\x00\x02\x40\x0b\x01\x0b\x20\x01\x04\x40\x05\x10\x00\x02\x40\x0b\x01\x0b\x20\x01\x04\x7f\x10\x00\x41\x09\x05\x10\x00\x41\x0a\x0b\x05\x20\x01\x04\x40\x10\x00\x02\x40\x0b\x01\x0b\x20\x01\x04\x40\x05\x10\x00\x02\x40\x0b\x01\x0b\x20\x01\x04\x7f\x10\x00\x41\x0a\x05\x10\x00\x41\x0b\x0b\x0b\x0b\x95\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x02\x41\x03\x1b\x0b\x95\x80\x80\x80\x00\x00\x41\x02\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x03\x1b\x0b\x95\x80\x80\x80\x00\x00\x41\x02\x41\x03\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x1b\x0b\x97\x80\x80\x80\x00\x00\x03\x7f\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x10\x00\x10\x00\x0b\x0b\x97\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x10\x00\x0b\x0b\x97\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x10\x00\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x0b\x0b\x98\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x04\x7f\x10\x00\x41\x02\x05\x10\x00\x41\x03\x0b\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x02\x0d\x00\x41\x03\x0f\x0b\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x0d\x00\x41\x03\x0f\x0b\x0b\x99\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x02\x0e\x01\x00\x00\x0b\x0b\x99\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x00\x11\x00\x00\x0b\x0b\x9a\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x00\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x11\x00\x00\x0b\x0b\x95\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x41\x02\x36\x02\x00\x0b\x95\x80\x80\x80\x00\x00\x41\x02\x20\x00\x04\x7f\x10\x00\x41\x01\x05\x10\x00\x41\x00\x0b\x36\x02\x00\x0b\x8e\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x10\x17\x0b\x8d\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x0f\x0b\x8d\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x1a\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x0c\x00\x0b\x0b\x92\x80\x80\x80\x00\x01\x01\x7f\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x21\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x22\x00\x0b\x90\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x01\x05\x41\x00\x0b\x24\x00\x23\x00\x0b\x8f\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x0b\x05\x41\x0a\x0b\x28\x02\x00\x0b\x91\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x10\x00\x41\x0d\x05\x10\x00\x41\x73\x0b\x68\x0b\x9f\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x10\x00\x41\x03\x05\x10\x00\x41\x7d\x0b\x20\x01\x04\x7f\x10\x00\x41\x04\x05\x10\x00\x41\x7b\x0b\x6c\x0b\x91\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x10\x00\x41\x0d\x05\x10\x00\x41\x00\x0b\x45\x0b\xab\x80\x80\x80\x00\x00\x20\x00\x04\x7d\x10\x00\x43\x00\x00\x40\x40\x05\x10\x00\x43\x00\x00\x40\xc0\x0b\x20\x01\x04\x7d\x10\x00\x43\x00\x00\x80\x40\x05\x10\x00\x43\x00\x00\x80\xc0\x0b\x5e\x0b\x99\x80\x80\x80\x00\x00\x20\x00\x04\x08\x10\x00\x41\x03\x10\x00\x41\x04\x05\x10\x00\x41\x03\x10\x00\x41\x7c\x0b\x6c\x0b\xa5\x80\x80\x80\x00\x00\x20\x00\x04\x09\x10\x00\x43\x00\x00\x40\x40\x10\x00\x43\x00\x00\x40\x40\x05\x10\x00\x43\x00\x00\x00\xc0\x10\x00\x43\x00\x00\x40\xc0\x0b\x5e\x0b\x9c\x80\x80\x80\x00\x00\x20\x00\x04\x08\x10\x00\x41\x03\x10\x00\x41\x04\x05\x10\x00\x41\x7d\x10\x00\x41\x7c\x0b\x41\x05\x6a\x6c\x0b\xe7\x80\x80\x80\x00\x00\x41\x01\x04\x40\x0c\x00\x00\x0b\x41\x01\x04\x40\x0c\x00\x00\x05\x00\x0b\x41\x00\x04\x40\x00\x05\x0c\x00\x00\x0b\x41\x01\x04\x40\x41\x01\x0d\x00\x00\x0b\x41\x01\x04\x40\x41\x01\x0d\x00\x00\x05\x00\x0b\x41\x00\x04\x40\x00\x05\x41\x01\x0d\x00\x00\x0b\x41\x01\x04\x40\x41\x00\x0e\x00\x00\x00\x0b\x41\x01\x04\x40\x41\x00\x0e\x00\x00\x00\x05\x00\x0b\x41\x00\x04\x40\x00\x05\x41\x00\x0e\x00\x00\x00\x0b\x41\x13\x0b\x94\x80\x80\x80\x00\x00\x20\x00\x04\x7f\x41\x12\x0c\x00\x41\x13\x05\x41\x15\x0c\x00\x41\x14\x0b\x0b\xa4\x80\x80\x80\x00\x00\x20\x00\x04\x0b\x41\x12\x41\x6e\x42\x12\x0c\x00\x41\x13\x41\x6d\x42\x13\x05\x41\x6e\x41\x12\x42\x6e\x0c\x00\x41\x6d\x41\x13\x42\x6d\x0b\x0b\x90\x80\x80\x80\x00\x00\x41\x01\x20\x00\x04\x05\x41\x02\x6a\x05\x41\x7e\x6a\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x04\x00\x6a\x05\x6b\x0b\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x04\x0c\x0b\x6a\x0b\x94\x80\x80\x80\x00\x00\x41\x01\x20\x00\x04\x05\x41\x02\x6a\x0c\x00\x05\x41\x7e\x6a\x0c\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x04\x00\x6a\x0c\x00\x05\x6b\x0c\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x41\x01\x41\x02\x20\x00\x04\x0c\x0c\x00\x0b\x6a\x0b\xd1\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x01\x21\x01\x20\x00\x0b\x04\x40\x20\x01\x41\x03\x6c\x21\x01\x20\x01\x41\x05\x6b\x21\x01\x20\x01\x41\x07\x6c\x21\x01\x0c\x00\x20\x01\x41\xe4\x00\x6c\x21\x01\x05\x20\x01\x41\x05\x6c\x21\x01\x20\x01\x41\x07\x6b\x21\x01\x20\x01\x41\x03\x6c\x21\x01\x0c\x00\x20\x01\x41\xe8\x07\x6c\x21\x01\x0b\x20\x01\x0b\x97\x80\x80\x80\x00\x01\x01\x7e\x20\x00\x20\x01\x7c\x20\x02\xad\x7c\x21\x03\x20\x03\x20\x03\x20\x00\x54\x0f\x0b\x90\x80\x80\x80\x00\x00\x20\x00\x20\x01\x41\x00\x10\x31\x04\x0f\x1a\x42\x7f\x0b\x0b\xd5\x80\x80\x80\x00\x00\x41\x01\x04\x01\x0b\x41\x01\x04\x02\x41\x00\x05\x41\x02\x0b\x41\x01\x04\x03\x1a\x05\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x41\x01\x04\x04\x0b\x1a\x1a\x1a\x41\x01\x04\x02\x41\x00\x05\x41\x02\x0b\x41\x01\x04\x03\x1a\x05\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x41\x01\x04\x04\x0b\x1a\x1a\x1a\x0b"); + +// if.wast:529 +assert_return(() => call($1, "empty", [0])); + +// if.wast:530 +assert_return(() => call($1, "empty", [1])); + +// if.wast:531 +assert_return(() => call($1, "empty", [100])); + +// if.wast:532 +assert_return(() => call($1, "empty", [-2])); + +// if.wast:534 +assert_return(() => call($1, "singular", [0]), 8); + +// if.wast:535 +assert_return(() => call($1, "singular", [1]), 7); + +// if.wast:536 +assert_return(() => call($1, "singular", [10]), 7); + +// if.wast:537 +assert_return(() => call($1, "singular", [-10]), 7); + +// if.wast:539 +assert_return(() => call($1, "multi", [0]), 9, -1); + +// if.wast:540 +assert_return(() => call($1, "multi", [1]), 8, 1); + +// if.wast:541 +assert_return(() => call($1, "multi", [13]), 8, 1); + +// if.wast:542 +assert_return(() => call($1, "multi", [-5]), 8, 1); + +// if.wast:544 +assert_return(() => call($1, "nested", [0, 0]), 11); + +// if.wast:545 +assert_return(() => call($1, "nested", [1, 0]), 10); + +// if.wast:546 +assert_return(() => call($1, "nested", [0, 1]), 10); + +// if.wast:547 +assert_return(() => call($1, "nested", [3, 2]), 9); + +// if.wast:548 +assert_return(() => call($1, "nested", [0, -100]), 10); + +// if.wast:549 +assert_return(() => call($1, "nested", [10, 10]), 9); + +// if.wast:550 +assert_return(() => call($1, "nested", [0, -1]), 10); + +// if.wast:551 +assert_return(() => call($1, "nested", [-111, -2]), 9); + +// if.wast:553 +assert_return(() => call($1, "as-select-first", [0]), 0); + +// if.wast:554 +assert_return(() => call($1, "as-select-first", [1]), 1); + +// if.wast:555 +assert_return(() => call($1, "as-select-mid", [0]), 2); + +// if.wast:556 +assert_return(() => call($1, "as-select-mid", [1]), 2); + +// if.wast:557 +assert_return(() => call($1, "as-select-last", [0]), 3); + +// if.wast:558 +assert_return(() => call($1, "as-select-last", [1]), 2); + +// if.wast:560 +assert_return(() => call($1, "as-loop-first", [0]), 0); + +// if.wast:561 +assert_return(() => call($1, "as-loop-first", [1]), 1); + +// if.wast:562 +assert_return(() => call($1, "as-loop-mid", [0]), 0); + +// if.wast:563 +assert_return(() => call($1, "as-loop-mid", [1]), 1); + +// if.wast:564 +assert_return(() => call($1, "as-loop-last", [0]), 0); + +// if.wast:565 +assert_return(() => call($1, "as-loop-last", [1]), 1); + +// if.wast:567 +assert_return(() => call($1, "as-if-condition", [0]), 3); + +// if.wast:568 +assert_return(() => call($1, "as-if-condition", [1]), 2); + +// if.wast:570 +assert_return(() => call($1, "as-br_if-first", [0]), 0); + +// if.wast:571 +assert_return(() => call($1, "as-br_if-first", [1]), 1); + +// if.wast:572 +assert_return(() => call($1, "as-br_if-last", [0]), 3); + +// if.wast:573 +assert_return(() => call($1, "as-br_if-last", [1]), 2); + +// if.wast:575 +assert_return(() => call($1, "as-br_table-first", [0]), 0); + +// if.wast:576 +assert_return(() => call($1, "as-br_table-first", [1]), 1); + +// if.wast:577 +assert_return(() => call($1, "as-br_table-last", [0]), 2); + +// if.wast:578 +assert_return(() => call($1, "as-br_table-last", [1]), 2); + +// if.wast:580 +assert_return(() => call($1, "as-call_indirect-first", [0]), 0); + +// if.wast:581 +assert_return(() => call($1, "as-call_indirect-first", [1]), 1); + +// if.wast:582 +assert_return(() => call($1, "as-call_indirect-mid", [0]), 2); + +// if.wast:583 +assert_return(() => call($1, "as-call_indirect-mid", [1]), 2); + +// if.wast:584 +assert_return(() => call($1, "as-call_indirect-last", [0]), 2); + +// if.wast:585 +assert_trap(() => call($1, "as-call_indirect-last", [1])); + +// if.wast:587 +assert_return(() => call($1, "as-store-first", [0])); + +// if.wast:588 +assert_return(() => call($1, "as-store-first", [1])); + +// if.wast:589 +assert_return(() => call($1, "as-store-last", [0])); + +// if.wast:590 +assert_return(() => call($1, "as-store-last", [1])); + +// if.wast:592 +assert_return(() => call($1, "as-memory.grow-value", [0]), 1); + +// if.wast:593 +assert_return(() => call($1, "as-memory.grow-value", [1]), 1); + +// if.wast:595 +assert_return(() => call($1, "as-call-value", [0]), 0); + +// if.wast:596 +assert_return(() => call($1, "as-call-value", [1]), 1); + +// if.wast:598 +assert_return(() => call($1, "as-return-value", [0]), 0); + +// if.wast:599 +assert_return(() => call($1, "as-return-value", [1]), 1); + +// if.wast:601 +assert_return(() => call($1, "as-drop-operand", [0])); + +// if.wast:602 +assert_return(() => call($1, "as-drop-operand", [1])); + +// if.wast:604 +assert_return(() => call($1, "as-br-value", [0]), 0); + +// if.wast:605 +assert_return(() => call($1, "as-br-value", [1]), 1); + +// if.wast:607 +assert_return(() => call($1, "as-local.set-value", [0]), 0); + +// if.wast:608 +assert_return(() => call($1, "as-local.set-value", [1]), 1); + +// if.wast:610 +assert_return(() => call($1, "as-local.tee-value", [0]), 0); + +// if.wast:611 +assert_return(() => call($1, "as-local.tee-value", [1]), 1); + +// if.wast:613 +assert_return(() => call($1, "as-global.set-value", [0]), 0); + +// if.wast:614 +assert_return(() => call($1, "as-global.set-value", [1]), 1); + +// if.wast:616 +assert_return(() => call($1, "as-load-operand", [0]), 0); + +// if.wast:617 +assert_return(() => call($1, "as-load-operand", [1]), 0); + +// if.wast:619 +assert_return(() => call($1, "as-unary-operand", [0]), 0); + +// if.wast:620 +assert_return(() => call($1, "as-unary-operand", [1]), 0); + +// if.wast:621 +assert_return(() => call($1, "as-unary-operand", [-1]), 0); + +// if.wast:623 +assert_return(() => call($1, "as-binary-operand", [0, 0]), 15); + +// if.wast:624 +assert_return(() => call($1, "as-binary-operand", [0, 1]), -12); + +// if.wast:625 +assert_return(() => call($1, "as-binary-operand", [1, 0]), -15); + +// if.wast:626 +assert_return(() => call($1, "as-binary-operand", [1, 1]), 12); + +// if.wast:628 +assert_return(() => call($1, "as-test-operand", [0]), 1); + +// if.wast:629 +assert_return(() => call($1, "as-test-operand", [1]), 0); + +// if.wast:631 +assert_return(() => call($1, "as-compare-operand", [0, 0]), 1); + +// if.wast:632 +assert_return(() => call($1, "as-compare-operand", [0, 1]), 0); + +// if.wast:633 +assert_return(() => call($1, "as-compare-operand", [1, 0]), 1); + +// if.wast:634 +assert_return(() => call($1, "as-compare-operand", [1, 1]), 0); + +// if.wast:636 +assert_return(() => call($1, "as-binary-operands", [0]), -12); + +// if.wast:637 +assert_return(() => call($1, "as-binary-operands", [1]), 12); + +// if.wast:639 +assert_return(() => call($1, "as-compare-operands", [0]), 1); + +// if.wast:640 +assert_return(() => call($1, "as-compare-operands", [1]), 0); + +// if.wast:642 +assert_return(() => call($1, "as-mixed-operands", [0]), -3); + +// if.wast:643 +assert_return(() => call($1, "as-mixed-operands", [1]), 27); + +// if.wast:645 +assert_return(() => call($1, "break-bare", []), 19); + +// if.wast:646 +assert_return(() => call($1, "break-value", [1]), 18); + +// if.wast:647 +assert_return(() => call($1, "break-value", [0]), 21); + +// if.wast:648 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x03\x7f\x7f\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x41\x00\x10\x00\x01\x42\x6e\x01\x51\x45\x0d\x00\x01\x41\x12\x01\x46\x45\x0d\x00\x01\x41\x6e\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-multi-value", [0]), -18, 18, int64("-18")) + +// if.wast:651 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8b\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x03\x7f\x7f\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa9\x80\x80\x80\x00\x01\xa3\x80\x80\x80\x00\x00\x02\x40\x41\x01\x10\x00\x01\x42\x12\x01\x51\x45\x0d\x00\x01\x41\x6e\x01\x46\x45\x0d\x00\x01\x41\x12\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-multi-value", [1]), 18, -18, int64("18")) + +// if.wast:655 +assert_return(() => call($1, "param", [0]), -1); + +// if.wast:656 +assert_return(() => call($1, "param", [1]), 3); + +// if.wast:657 +assert_return(() => call($1, "params", [0]), -1); + +// if.wast:658 +assert_return(() => call($1, "params", [1]), 3); + +// if.wast:659 +assert_return(() => call($1, "params-id", [0]), 3); + +// if.wast:660 +assert_return(() => call($1, "params-id", [1]), 3); + +// if.wast:661 +assert_return(() => call($1, "param-break", [0]), -1); + +// if.wast:662 +assert_return(() => call($1, "param-break", [1]), 3); + +// if.wast:663 +assert_return(() => call($1, "params-break", [0]), -1); + +// if.wast:664 +assert_return(() => call($1, "params-break", [1]), 3); + +// if.wast:665 +assert_return(() => call($1, "params-id-break", [0]), 3); + +// if.wast:666 +assert_return(() => call($1, "params-id-break", [1]), 3); + +// if.wast:668 +assert_return(() => call($1, "effects", [1]), -14); + +// if.wast:669 +assert_return(() => call($1, "effects", [0]), -6); + +// if.wast:671 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x41\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("0"), int64("0"), 0]), int64("0"), 0) + +// if.wast:675 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa8\x80\x80\x80\x00\x01\xa2\x80\x80\x80\x00\x00\x02\x40\x42\xe4\x00\x42\xfc\x00\x41\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x01\x42\xe0\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("100"), int64("124"), 0]), int64("224"), 0) + +// if.wast:679 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x00\x41\x00\x10\x00\x01\x41\x00\x01\x46\x45\x0d\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-1"), int64("0"), 0]), int64("-1"), 0) + +// if.wast:683 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x41\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-1"), int64("1"), 0]), int64("0"), 1) + +// if.wast:687 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x41\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x7e\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-1"), int64("-1"), 0]), int64("-2"), 1) + +// if.wast:691 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x00\x41\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-1"), int64("0"), 1]), int64("0"), 1) + +// if.wast:695 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x41\x01\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-1"), int64("1"), 1]), int64("1"), 1) + +// if.wast:699 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x02\x60\x00\x00\x60\x03\x7e\x7e\x7f\x02\x7e\x7f\x02\x99\x80\x80\x80\x00\x01\x02\x24\x31\x12\x61\x64\x64\x36\x34\x5f\x75\x5f\x77\x69\x74\x68\x5f\x63\x61\x72\x72\x79\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xb7\x80\x80\x80\x00\x01\xb1\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x41\x00\x10\x00\x01\x41\x01\x01\x46\x45\x0d\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_with_carry", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808"), 0]), int64("0"), 1) + +// if.wast:704 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x00\x42\x00\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("0"), int64("0")]), int64("0")) + +// if.wast:707 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xce\x09\x42\x17\x10\x00\x01\x42\xe5\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("1_230"), int64("23")]), int64("1_253")) + +// if.wast:710 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x00\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("-1"), int64("0")]), int64("-1")) + +// if.wast:713 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x01\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("-1"), int64("1")]), int64("-1")) + +// if.wast:716 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("-1"), int64("-1")]), int64("-1")) + +// if.wast:719 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7e\x7e\x01\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x61\x64\x64\x36\x34\x5f\x75\x5f\x73\x61\x74\x75\x72\x61\x74\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xad\x80\x80\x80\x00\x01\xa7\x80\x80\x80\x00\x00\x02\x40\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x42\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "add64_u_saturated", [int64("-9_223_372_036_854_775_808"), int64("-9_223_372_036_854_775_808")]), int64("-1")) + +// if.wast:723 +assert_return(() => call($1, "type-use", [])); + +// if.wast:725 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:734 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:743 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:752 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:761 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:770 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:777 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:785 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:795 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:805 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:815 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:825 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x41\x00\x04\x00\x0b\x0b"); + +// if.wast:833 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:837 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:841 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:845 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:850 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:854 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:858 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:862 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x04\x40\x0b\x0b"); + +// if.wast:867 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x0b\x0b"); + +// if.wast:873 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x0b\x0b"); + +// if.wast:879 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x04\x40\x05\x41\x01\x0b\x0b"); + +// if.wast:885 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:892 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x41\x02\x0b\x0b"); + +// if.wast:898 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x41\x02\x0b\x0b"); + +// if.wast:904 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x40\x05\x41\x01\x41\x02\x0b\x0b"); + +// if.wast:910 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x40\x41\x01\x41\x02\x05\x41\x02\x41\x01\x0b\x0b"); + +// if.wast:917 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x05\x41\x00\x0b\x0b"); + +// if.wast:923 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x00\x0b\x0b"); + +// if.wast:929 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x0b\x0b"); + +// if.wast:936 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x00\x05\x41\x00\x41\x02\x0b\x0b"); + +// if.wast:942 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x00\x41\x01\x0b\x0b"); + +// if.wast:948 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x01\x04\x00\x0b\x0b"); + +// if.wast:955 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x0b\x0b"); + +// if.wast:961 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:968 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x01\x05\x41\x00\x0b\x0b"); + +// if.wast:974 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x00\x05\x01\x0b\x0b"); + +// if.wast:980 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x01\x05\x01\x0b\x0b"); + +// if.wast:987 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x01\x04\x00\x01\x05\x41\x00\x41\x00\x0b\x0b"); + +// if.wast:993 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x00\x41\x00\x05\x01\x0b\x0b"); + +// if.wast:999 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x04\x00\x01\x05\x01\x0b\x0b"); + +// if.wast:1006 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x42\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1012 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x42\x01\x0b\x0b"); + +// if.wast:1018 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x42\x01\x05\x42\x01\x0b\x0b"); + +// if.wast:1025 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1031 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1037 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1044 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x00\x41\x01\x04\x00\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1051 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1058 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x41\x01\x04\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1066 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1072 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1078 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1085 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x42\x01\x05\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0b\x0b"); + +// if.wast:1091 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1098 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x04\x7e\x00\x00\x00\x1b\x05\x42\x00\x0b\x0b"); + +// if.wast:1108 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7e\x42\x00\x05\x00\x00\x00\x1b\x0b\x0b"); + +// if.wast:1118 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x7e\x00\x00\x00\x1b\x05\x00\x00\x00\x1b\x0b\x0b"); + +// if.wast:1129 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x0c\x00\x05\x41\x01\x0b\x0b"); + +// if.wast:1135 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x0c\x00\x0b\x0b"); + +// if.wast:1141 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x00\x0c\x00\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1147 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x0c\x00\x0b\x0b"); + +// if.wast:1154 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x0c\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1163 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x0c\x00\x41\x01\x0b\x0b"); + +// if.wast:1172 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x04\x00\x0c\x00\x41\x01\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1181 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x0c\x00\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1191 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x01\x0c\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1200 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x01\x0c\x00\x41\x01\x0b\x0b"); + +// if.wast:1209 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x04\x00\x01\x0c\x00\x41\x01\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1218 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x01\x0c\x00\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1228 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x42\x01\x0c\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1237 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x01\x05\x42\x01\x0c\x00\x41\x01\x0b\x0b"); + +// if.wast:1246 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x41\x01\x04\x00\x42\x01\x0c\x00\x41\x01\x41\x01\x05\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1255 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x41\x01\x04\x00\x41\x01\x41\x01\x05\x42\x01\x0c\x00\x41\x01\x41\x01\x0b\x0b"); + +// if.wast:1264 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x41\x01\x04\x00\x42\x01\x0c\x00\x41\x01\x05\x41\x01\x0b\x0b"); + +// if.wast:1274 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x01\x41\x01\x04\x00\x41\x01\x05\x42\x01\x0c\x00\x41\x01\x0b\x0b"); + +// if.wast:1285 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x04\x40\x0b\x0b"); + +// if.wast:1293 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x02\x40\x04\x40\x0b\x0b\x0b"); + +// if.wast:1302 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x03\x40\x04\x40\x0b\x0b\x0b"); + +// if.wast:1311 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x04\x40\x0b\x0b\x0b"); + +// if.wast:1320 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x7f\x41\x00\x05\x04\x40\x0b\x41\x00\x0b\x1a\x0b"); + +// if.wast:1330 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x02\x40\x04\x40\x0b\x0c\x00\x1a\x0b\x0b"); + +// if.wast:1339 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x02\x40\x04\x40\x0b\x41\x01\x0d\x00\x1a\x0b\x0b"); + +// if.wast:1348 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x02\x40\x04\x40\x0b\x0e\x00\x00\x1a\x0b\x0b"); + +// if.wast:1357 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x04\x40\x0b\x0f\x1a\x0b"); + +// if.wast:1365 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x04\x40\x0b\x41\x01\x41\x02\x1b\x1a\x0b"); + +// if.wast:1373 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x01\x7f\x03\x83\x80\x80\x80\x00\x02\x00\x01\x0a\x97\x80\x80\x80\x00\x02\x88\x80\x80\x80\x00\x00\x04\x40\x0b\x10\x01\x1a\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b"); + +// if.wast:1382 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x01\x7f\x01\x7f\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x00\x0a\x9d\x80\x80\x80\x00\x02\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x04\x40\x0b\x41\x00\x11\x00\x00\x1a\x0b\x0b"); + +// if.wast:1398 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x01\x01\x7f\x04\x40\x0b\x21\x00\x20\x00\x1a\x0b"); + +// if.wast:1407 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x01\x01\x7f\x04\x40\x0b\x22\x00\x1a\x0b"); + +// if.wast:1416 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x04\x40\x0b\x24\x00\x23\x00\x1a\x0b"); + +// if.wast:1425 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x04\x40\x0b\x40\x00\x1a\x0b"); + +// if.wast:1434 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x04\x40\x0b\x28\x02\x00\x1a\x0b"); + +// if.wast:1443 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x04\x40\x0b\x41\x01\x36\x02\x00\x0b"); + +// if.wast:1453 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x01\x04\x01\x1a\x0b\x0b"); + +// if.wast:1459 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x04\x01\x1a\x1a\x0b\x0b"); + +// if.wast:1465 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x41\x01\x04\x01\x1a\x0b\x0b"); + +// if.wast:1471 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x41\x01\x04\x01\x1a\x1a\x0b\x0b"); + +// if.wast:1477 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x01\x04\x01\x1a\x0b\x0b\x0b"); + +// if.wast:1483 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x01\x04\x01\x1a\x1a\x0b\x0b\x0b"); + +// if.wast:1489 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x41\x01\x04\x01\x1a\x0b\x0b\x0b"); + +// if.wast:1495 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x41\x01\x04\x01\x1a\x1a\x0b\x0b\x0b"); + +// if.wast:1502 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1506 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1511 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1515 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1519 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1523 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1527 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1531 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1535 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1539 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1543 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// if.wast:1547 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/inline-module.wast.js b/js/src/jit-test/tests/wasm/spec/spec/inline-module.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/inline-module.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/inline-module.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/int_exprs.wast.js b/js/src/jit-test/tests/wasm/spec/spec/int_exprs.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/int_exprs.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/int_exprs.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/int_literals.wast.js b/js/src/jit-test/tests/wasm/spec/spec/int_literals.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/int_literals.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/int_literals.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/labels.wast.js b/js/src/jit-test/tests/wasm/spec/spec/labels.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/labels.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/labels.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/left-to-right.wast.js b/js/src/jit-test/tests/wasm/spec/spec/left-to-right.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/left-to-right.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/left-to-right.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/load.wast.js b/js/src/jit-test/tests/wasm/spec/spec/load.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/load.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/load.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/local_get.wast.js b/js/src/jit-test/tests/wasm/spec/spec/local_get.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/local_get.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/local_get.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/local_set.wast.js b/js/src/jit-test/tests/wasm/spec/spec/local_set.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/local_set.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/local_set.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/local_tee.wast.js b/js/src/jit-test/tests/wasm/spec/spec/local_tee.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/local_tee.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/local_tee.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/loop.wast.js b/js/src/jit-test/tests/wasm/spec/spec/loop.wast.js new file mode 100644 index 0000000000..0b8bf57324 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/loop.wast.js @@ -0,0 +1,360 @@ + +// loop.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xce\x80\x80\x80\x00\x0e\x60\x02\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x60\x03\x7f\x7c\x7f\x03\x7f\x7c\x7f\x60\x00\x03\x7f\x7e\x7f\x60\x01\x7f\x01\x7f\x60\x00\x02\x7f\x7f\x60\x00\x02\x7d\x7d\x60\x00\x03\x7f\x7f\x7e\x60\x03\x7f\x7f\x7e\x00\x60\x02\x7f\x7f\x02\x7f\x7f\x60\x01\x7e\x01\x7e\x60\x02\x7d\x7d\x01\x7d\x03\xb9\x80\x80\x80\x00\x38\x01\x01\x02\x02\x02\x02\x02\x02\x02\x01\x02\x02\x02\x02\x02\x02\x00\x02\x02\x02\x01\x01\x02\x06\x02\x02\x01\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x09\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x0c\x0c\x0d\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x07\xc8\x86\x80\x80\x00\x35\x05\x65\x6d\x70\x74\x79\x00\x01\x08\x73\x69\x6e\x67\x75\x6c\x61\x72\x00\x02\x05\x6d\x75\x6c\x74\x69\x00\x03\x06\x6e\x65\x73\x74\x65\x64\x00\x04\x04\x64\x65\x65\x70\x00\x05\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x06\x0d\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6d\x69\x64\x00\x07\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x08\x0f\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x69\x74\x69\x6f\x6e\x00\x09\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x0a\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x0b\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x66\x69\x72\x73\x74\x00\x0c\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x6c\x61\x73\x74\x00\x0d\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x66\x69\x72\x73\x74\x00\x0e\x10\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x6c\x61\x73\x74\x00\x0f\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x11\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x12\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x13\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x66\x69\x72\x73\x74\x00\x14\x0d\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x6c\x61\x73\x74\x00\x15\x14\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x76\x61\x6c\x75\x65\x00\x16\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x76\x61\x6c\x75\x65\x00\x18\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x19\x0f\x61\x73\x2d\x64\x72\x6f\x70\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1a\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x1b\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x1c\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x1d\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x1e\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x1f\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x20\x11\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x21\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x22\x12\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x23\x12\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x24\x13\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x25\x11\x61\x73\x2d\x6d\x69\x78\x65\x64\x2d\x6f\x70\x65\x72\x61\x6e\x64\x73\x00\x26\x0a\x62\x72\x65\x61\x6b\x2d\x62\x61\x72\x65\x00\x27\x0b\x62\x72\x65\x61\x6b\x2d\x76\x61\x6c\x75\x65\x00\x28\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x29\x0e\x62\x72\x65\x61\x6b\x2d\x72\x65\x70\x65\x61\x74\x65\x64\x00\x2a\x0b\x62\x72\x65\x61\x6b\x2d\x69\x6e\x6e\x65\x72\x00\x2b\x0a\x63\x6f\x6e\x74\x2d\x69\x6e\x6e\x65\x72\x00\x2c\x05\x70\x61\x72\x61\x6d\x00\x2d\x06\x70\x61\x72\x61\x6d\x73\x00\x2e\x09\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x00\x2f\x0b\x70\x61\x72\x61\x6d\x2d\x62\x72\x65\x61\x6b\x00\x30\x0c\x70\x61\x72\x61\x6d\x73\x2d\x62\x72\x65\x61\x6b\x00\x31\x0f\x70\x61\x72\x61\x6d\x73\x2d\x69\x64\x2d\x62\x72\x65\x61\x6b\x00\x32\x07\x65\x66\x66\x65\x63\x74\x73\x00\x33\x05\x77\x68\x69\x6c\x65\x00\x34\x03\x66\x6f\x72\x00\x35\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x36\x08\x74\x79\x70\x65\x2d\x75\x73\x65\x00\x37\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x10\x0a\xe3\x8c\x80\x80\x00\x38\x82\x80\x80\x80\x00\x00\x0b\x88\x80\x80\x80\x00\x00\x03\x40\x0b\x03\x40\x0b\x0b\x8b\x80\x80\x80\x00\x00\x03\x40\x01\x0b\x03\x7f\x41\x07\x0b\x0b\xbc\x80\x80\x80\x00\x00\x03\x40\x10\x00\x10\x00\x10\x00\x10\x00\x0b\x03\x7f\x10\x00\x10\x00\x41\x08\x10\x00\x0b\x1a\x03\x05\x10\x00\x10\x00\x10\x00\x41\x08\x10\x00\x10\x00\x10\x00\x10\x00\x42\x07\x10\x00\x10\x00\x10\x00\x10\x00\x41\x09\x10\x00\x0b\x1a\x1a\x0b\x95\x80\x80\x80\x00\x00\x03\x7f\x03\x40\x10\x00\x02\x40\x0b\x01\x0b\x03\x7f\x10\x00\x41\x09\x0b\x0b\x0b\xff\x80\x80\x80\x00\x00\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x02\x7f\x10\x00\x41\x96\x01\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x8c\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x41\x02\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x03\x7f\x41\x01\x0b\x41\x03\x1b\x0b\x8c\x80\x80\x80\x00\x00\x41\x02\x41\x03\x03\x7f\x41\x01\x0b\x1b\x0b\x8c\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x04\x40\x10\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x03\x7f\x41\x01\x0b\x05\x41\x02\x0b\x0b\x8f\x80\x80\x80\x00\x00\x41\x01\x04\x7f\x41\x02\x05\x03\x7f\x41\x01\x0b\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x01\x0b\x41\x02\x0d\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x03\x7f\x41\x01\x0b\x0d\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x01\x0b\x41\x02\x0e\x01\x00\x00\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x03\x7f\x41\x01\x0b\x0e\x01\x00\x00\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x01\x0b\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x03\x7f\x41\x01\x0b\x41\x00\x11\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x03\x7f\x41\x00\x0b\x11\x00\x00\x0b\x0b\x8c\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x41\x01\x36\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x0a\x03\x7f\x41\x01\x0b\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x40\x00\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x89\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x10\x17\x0b\x88\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x0f\x0b\x88\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x1a\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x01\x0b\x0c\x00\x0b\x0b\x8d\x80\x80\x80\x00\x01\x01\x7f\x03\x7f\x41\x01\x0b\x21\x00\x20\x00\x0b\x8b\x80\x80\x80\x00\x01\x01\x7f\x03\x7f\x41\x01\x0b\x22\x00\x0b\x8b\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x24\x00\x23\x00\x0b\x8a\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0b\x28\x02\x00\x0b\x8a\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x41\x0d\x0b\x68\x0b\x91\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x41\x03\x0b\x03\x7f\x10\x00\x41\x04\x0b\x6c\x0b\x8a\x80\x80\x80\x00\x00\x03\x7f\x10\x00\x41\x0d\x0b\x45\x0b\x97\x80\x80\x80\x00\x00\x03\x7d\x10\x00\x43\x00\x00\x40\x40\x0b\x03\x7d\x10\x00\x43\x00\x00\x40\x40\x0b\x5e\x0b\x8e\x80\x80\x80\x00\x00\x03\x07\x10\x00\x41\x03\x10\x00\x41\x04\x0b\x6c\x0b\x94\x80\x80\x80\x00\x00\x03\x08\x10\x00\x43\x00\x00\x40\x40\x10\x00\x43\x00\x00\x40\x40\x0b\x5e\x0b\x91\x80\x80\x80\x00\x00\x03\x07\x10\x00\x41\x03\x10\x00\x41\x04\x0b\x41\x05\x6a\x6c\x0b\xb4\x80\x80\x80\x00\x00\x02\x40\x03\x40\x0c\x01\x0c\x00\x00\x0b\x0b\x02\x40\x03\x40\x41\x01\x0d\x01\x00\x0b\x0b\x02\x40\x03\x40\x41\x00\x0e\x00\x01\x00\x0b\x0b\x02\x40\x03\x40\x41\x01\x0e\x02\x01\x01\x01\x00\x0b\x0b\x41\x13\x0b\x97\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x03\x03\x02\x40\x41\x12\x0c\x02\x0b\x41\x14\x0c\x00\x0b\x41\x13\x0b\x0b\xa7\x80\x80\x80\x00\x00\x02\x09\x41\x00\x41\x00\x42\x00\x03\x0a\x02\x40\x41\x12\x41\x6e\x42\x12\x0c\x02\x0b\x41\x14\x41\x6c\x42\x14\x0c\x00\x0b\x41\x13\x41\x6d\x42\x13\x0b\x0b\xb4\x80\x80\x80\x00\x00\x02\x7f\x03\x7f\x41\x12\x0c\x01\x41\x13\x0c\x01\x41\x14\x41\x00\x0d\x01\x1a\x41\x14\x41\x01\x0d\x01\x1a\x41\x15\x0c\x01\x41\x16\x41\x00\x0e\x00\x01\x41\x17\x41\x01\x0e\x02\x01\x01\x01\x41\x15\x0b\x0b\x0b\xe6\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x21\x00\x20\x00\x02\x7f\x03\x7f\x02\x7f\x41\x01\x0c\x02\x0b\x0b\x0b\x6a\x21\x00\x20\x00\x02\x7f\x03\x7f\x03\x7f\x41\x02\x0c\x02\x0b\x0b\x0b\x6a\x21\x00\x20\x00\x02\x7f\x03\x7f\x02\x7f\x03\x7f\x41\x04\x0c\x01\x0b\x0b\x0b\x0b\x6a\x21\x00\x20\x00\x02\x7f\x03\x7f\x41\x08\x0c\x01\x68\x0b\x0b\x6a\x21\x00\x20\x00\x02\x7f\x03\x7f\x03\x7f\x41\x10\x0c\x02\x0b\x68\x0b\x0b\x6a\x21\x00\x20\x00\x0b\xb0\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x21\x00\x20\x00\x03\x7f\x03\x7f\x0c\x01\x0b\x0b\x6a\x21\x00\x20\x00\x03\x7f\x0c\x00\x68\x0b\x6a\x21\x00\x20\x00\x03\x7f\x03\x7f\x0c\x01\x0b\x68\x0b\x6a\x21\x00\x20\x00\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x03\x06\x41\x02\x6a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x03\x00\x6a\x0b\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x41\x02\x03\x0b\x0b\x6a\x0b\x95\x80\x80\x80\x00\x01\x01\x7f\x41\x01\x03\x06\x41\x04\x6a\x22\x00\x20\x00\x41\x0a\x49\x0d\x00\x0b\x0b\x98\x80\x80\x80\x00\x01\x01\x7f\x41\x01\x41\x02\x03\x00\x6a\x22\x00\x41\x03\x20\x00\x41\x0a\x49\x0d\x00\x1a\x0b\x0b\x9e\x80\x80\x80\x00\x01\x01\x7f\x41\x00\x21\x00\x41\x01\x41\x02\x03\x0b\x20\x00\x41\x01\x6a\x21\x00\x20\x00\x41\x0a\x49\x0d\x00\x0b\x6a\x0b\xb2\x80\x80\x80\x00\x01\x01\x7f\x02\x40\x03\x40\x41\x01\x21\x00\x20\x00\x41\x03\x6c\x21\x00\x20\x00\x41\x05\x6b\x21\x00\x20\x00\x41\x07\x6c\x21\x00\x0c\x01\x20\x00\x41\xe4\x00\x6c\x21\x00\x0b\x0b\x20\x00\x41\x72\x46\x0b\xa5\x80\x80\x80\x00\x01\x01\x7e\x42\x01\x21\x01\x02\x40\x03\x40\x20\x00\x50\x0d\x01\x20\x00\x20\x01\x7e\x21\x01\x20\x00\x42\x01\x7d\x21\x00\x0c\x00\x0b\x0b\x20\x01\x0b\xab\x80\x80\x80\x00\x01\x02\x7e\x42\x01\x21\x01\x42\x02\x21\x02\x02\x40\x03\x40\x20\x02\x20\x00\x56\x0d\x01\x20\x01\x20\x02\x7e\x21\x01\x20\x02\x42\x01\x7c\x21\x02\x0c\x00\x0b\x0b\x20\x01\x0b\xda\x80\x80\x80\x00\x01\x02\x7d\x02\x40\x03\x40\x20\x00\x43\x00\x00\x00\x00\x5b\x0d\x01\x20\x01\x21\x02\x02\x40\x03\x40\x20\x02\x43\x00\x00\x00\x00\x5b\x0d\x01\x20\x02\x43\x00\x00\x00\x00\x5d\x0d\x03\x20\x03\x20\x02\x92\x21\x03\x20\x02\x43\x00\x00\x00\x40\x93\x21\x02\x0c\x00\x0b\x0b\x20\x03\x20\x00\x95\x21\x03\x20\x00\x43\x00\x00\x80\x3f\x93\x21\x00\x0c\x00\x0b\x0b\x20\x03\x0b\xbd\x80\x80\x80\x00\x00\x03\x01\x0b\x03\x02\x41\x00\x0b\x03\x03\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x03\x04\x0b\x1a\x1a\x1a\x03\x02\x41\x00\x0b\x03\x03\x1a\x0b\x41\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x03\x04\x0b\x1a\x1a\x1a\x0b"); + +// loop.wast:430 +assert_return(() => call($1, "empty", [])); + +// loop.wast:431 +assert_return(() => call($1, "singular", []), 7); + +// loop.wast:432 +assert_return(() => call($1, "multi", []), 8); + +// loop.wast:433 +assert_return(() => call($1, "nested", []), 9); + +// loop.wast:434 +assert_return(() => call($1, "deep", []), 150); + +// loop.wast:436 +assert_return(() => call($1, "as-select-first", []), 1); + +// loop.wast:437 +assert_return(() => call($1, "as-select-mid", []), 2); + +// loop.wast:438 +assert_return(() => call($1, "as-select-last", []), 2); + +// loop.wast:440 +assert_return(() => call($1, "as-if-condition", [])); + +// loop.wast:441 +assert_return(() => call($1, "as-if-then", []), 1); + +// loop.wast:442 +assert_return(() => call($1, "as-if-else", []), 2); + +// loop.wast:444 +assert_return(() => call($1, "as-br_if-first", []), 1); + +// loop.wast:445 +assert_return(() => call($1, "as-br_if-last", []), 2); + +// loop.wast:447 +assert_return(() => call($1, "as-br_table-first", []), 1); + +// loop.wast:448 +assert_return(() => call($1, "as-br_table-last", []), 2); + +// loop.wast:450 +assert_return(() => call($1, "as-call_indirect-first", []), 1); + +// loop.wast:451 +assert_return(() => call($1, "as-call_indirect-mid", []), 2); + +// loop.wast:452 +assert_return(() => call($1, "as-call_indirect-last", []), 1); + +// loop.wast:454 +assert_return(() => call($1, "as-store-first", [])); + +// loop.wast:455 +assert_return(() => call($1, "as-store-last", [])); + +// loop.wast:457 +assert_return(() => call($1, "as-memory.grow-value", []), 1); + +// loop.wast:458 +assert_return(() => call($1, "as-call-value", []), 1); + +// loop.wast:459 +assert_return(() => call($1, "as-return-value", []), 1); + +// loop.wast:460 +assert_return(() => call($1, "as-drop-operand", [])); + +// loop.wast:461 +assert_return(() => call($1, "as-br-value", []), 1); + +// loop.wast:462 +assert_return(() => call($1, "as-local.set-value", []), 1); + +// loop.wast:463 +assert_return(() => call($1, "as-local.tee-value", []), 1); + +// loop.wast:464 +assert_return(() => call($1, "as-global.set-value", []), 1); + +// loop.wast:465 +assert_return(() => call($1, "as-load-operand", []), 1); + +// loop.wast:467 +assert_return(() => call($1, "as-unary-operand", []), 0); + +// loop.wast:468 +assert_return(() => call($1, "as-binary-operand", []), 12); + +// loop.wast:469 +assert_return(() => call($1, "as-test-operand", []), 0); + +// loop.wast:470 +assert_return(() => call($1, "as-compare-operand", []), 0); + +// loop.wast:471 +assert_return(() => call($1, "as-binary-operands", []), 12); + +// loop.wast:472 +assert_return(() => call($1, "as-compare-operands", []), 0); + +// loop.wast:473 +assert_return(() => call($1, "as-mixed-operands", []), 27); + +// loop.wast:475 +assert_return(() => call($1, "break-bare", []), 19); + +// loop.wast:476 +assert_return(() => call($1, "break-value", []), 18); + +// loop.wast:477 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x03\x7f\x7f\x7e\x02\x98\x80\x80\x80\x00\x01\x02\x24\x31\x11\x62\x72\x65\x61\x6b\x2d\x6d\x75\x6c\x74\x69\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa7\x80\x80\x80\x00\x01\xa1\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x12\x01\x51\x45\x0d\x00\x01\x41\x6e\x01\x46\x45\x0d\x00\x01\x41\x12\x01\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "break-multi-value", []), 18, -18, int64("18")) + +// loop.wast:480 +assert_return(() => call($1, "break-repeated", []), 18); + +// loop.wast:481 +assert_return(() => call($1, "break-inner", []), 31); + +// loop.wast:483 +assert_return(() => call($1, "param", []), 3); + +// loop.wast:484 +assert_return(() => call($1, "params", []), 3); + +// loop.wast:485 +assert_return(() => call($1, "params-id", []), 3); + +// loop.wast:486 +assert_return(() => call($1, "param-break", []), 13); + +// loop.wast:487 +assert_return(() => call($1, "params-break", []), 12); + +// loop.wast:488 +assert_return(() => call($1, "params-id-break", []), 3); + +// loop.wast:490 +assert_return(() => call($1, "effects", []), 1); + +// loop.wast:492 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("0")]), int64("1")) + +// loop.wast:493 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("1")]), int64("1")) + +// loop.wast:494 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("2")]), int64("2")) + +// loop.wast:495 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x03\x10\x00\x01\x42\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("3")]), int64("6")) + +// loop.wast:496 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("5")]), int64("120")) + +// loop.wast:497 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8c\x80\x80\x80\x00\x01\x02\x24\x31\x05\x77\x68\x69\x6c\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x14\x10\x00\x01\x42\x80\x80\xd0\x95\xc8\xef\xd9\xe1\x21\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "while", [int64("20")]), int64("2_432_902_008_176_640_000")) + +// loop.wast:499 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x00\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("0")]), int64("1")) + +// loop.wast:500 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x01\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("1")]), int64("1")) + +// loop.wast:501 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x02\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("2")]), int64("2")) + +// loop.wast:502 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x03\x10\x00\x01\x42\x06\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("3")]), int64("6")) + +// loop.wast:503 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x05\x10\x00\x01\x42\xf8\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("5")]), int64("120")) + +// loop.wast:504 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8a\x80\x80\x80\x00\x01\x02\x24\x31\x03\x66\x6f\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\x14\x10\x00\x01\x42\x80\x80\xd0\x95\xc8\xef\xd9\xe1\x21\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "for", [int64("20")]), int64("2_432_902_008_176_640_000")) + +// loop.wast:506 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x43\x00\x00\xe0\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [0., 7.]), 0.) + +// loop.wast:507 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xe0\x40\x43\x00\x00\x00\x00\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [7., 0.]), 0.) + +// loop.wast:508 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 1.]), 1.) + +// loop.wast:509 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x00\x40\x10\x00\xbc\x43\x00\x00\x00\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 2.]), 2.) + +// loop.wast:510 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x40\x40\x10\x00\xbc\x43\x00\x00\x80\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 3.]), 4.) + +// loop.wast:511 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\x80\x40\x10\x00\xbc\x43\x00\x00\xc0\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 4.]), 6.) + +// loop.wast:512 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\xc8\x42\x10\x00\xbc\x43\x00\x60\x1f\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 100.]), 2550.) + +// loop.wast:513 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x43\x00\x00\xca\x42\x10\x00\xbc\x43\x00\x90\x22\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [1., 101.]), 2601.) + +// loop.wast:514 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [2., 1.]), 1.) + +// loop.wast:515 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x40\x40\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [3., 1.]), 1.) + +// loop.wast:516 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x20\x41\x43\x00\x00\x80\x3f\x10\x00\xbc\x43\x00\x00\x80\x3f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [10., 1.]), 1.) + +// loop.wast:517 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\x00\x40\x10\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [2., 2.]), 3.) + +// loop.wast:518 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x40\x43\x00\x00\x40\x40\x10\x00\xbc\x43\x00\x00\x80\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [2., 3.]), 4.) + +// loop.wast:519 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xe0\x40\x43\x00\x00\x80\x40\x10\x00\xbc\x43\xcf\xf3\x24\x41\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [7., 4.]), 10.3095235825) + +// loop.wast:520 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xe0\x40\x43\x00\x00\xc8\x42\x10\x00\xbc\x43\x62\xec\x88\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [7., 100.]), 4381.54785156) + +// loop.wast:521 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8a\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7d\x01\x7d\x02\x8e\x80\x80\x80\x00\x01\x02\x24\x31\x07\x6e\x65\x73\x74\x69\x6e\x67\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa4\x80\x80\x80\x00\x01\x9e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\xe0\x40\x43\x00\x00\xca\x42\x10\x00\xbc\x43\x00\x90\x22\x45\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "nesting", [7., 101.]), 2601.) + +// loop.wast:523 +assert_return(() => call($1, "type-use", [])); + +// loop.wast:525 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:532 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:539 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:546 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:553 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:560 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:567 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:571 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:578 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:585 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:592 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:600 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x03\x00\x41\x00\x0b\x0b"); + +// loop.wast:608 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x40\x0b\x0b"); + +// loop.wast:612 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x40\x0b\x0b"); + +// loop.wast:616 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7d\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x40\x0b\x0b"); + +// loop.wast:620 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7c\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x40\x0b\x0b"); + +// loop.wast:625 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x03\x40\x41\x01\x0b\x0b"); + +// loop.wast:631 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x41\x01\x41\x02\x0b\x0b"); + +// loop.wast:637 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x7f\x0b\x0b"); + +// loop.wast:643 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x03\x00\x0b\x0b"); + +// loop.wast:649 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x03\x7f\x01\x0b\x0b"); + +// loop.wast:655 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x03\x00\x01\x0b\x0b"); + +// loop.wast:661 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x03\x7f\x43\x00\x00\x00\x00\x0b\x0b"); + +// loop.wast:667 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x03\x00\x41\x00\x0b\x0b"); + +// loop.wast:673 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x01\x03\x00\x41\x02\x0b\x0b"); + +// loop.wast:679 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x41\x02\x0b\x0b"); + +// loop.wast:685 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x7e\x00\x00\x00\x1b\x0b\x0b"); + +// loop.wast:692 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x02\x40\x03\x7f\x0b\x1a\x0b\x0b"); + +// loop.wast:701 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x03\x40\x03\x7f\x0b\x1a\x0b\x0b"); + +// loop.wast:710 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x00\x04\x40\x03\x7f\x0b\x1a\x0b\x0b"); + +// loop.wast:720 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x03\x01\x1a\x0b\x0b"); + +// loop.wast:726 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x03\x01\x1a\x1a\x0b\x0b"); + +// loop.wast:732 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x03\x01\x1a\x0b\x0b"); + +// loop.wast:738 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x43\x00\x00\x00\x00\x03\x01\x1a\x1a\x0b\x0b"); + +// loop.wast:744 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x03\x01\x1a\x0b\x0b\x0b"); + +// loop.wast:750 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7f\x7c\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x03\x01\x1a\x1a\x0b\x0b\x0b"); + +// loop.wast:756 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x03\x01\x1a\x0b\x0b\x0b"); + +// loop.wast:762 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x02\x7d\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x03\x01\x1a\x1a\x0b\x0b\x0b"); + +// loop.wast:769 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:773 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:778 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// loop.wast:782 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/spec/memory.wast.js b/js/src/jit-test/tests/wasm/spec/spec/memory.wast.js new file mode 100644 index 0000000000..71802472b5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/memory.wast.js @@ -0,0 +1,237 @@ + +// memory.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00"); + +// memory.wast:4 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x01"); + +// memory.wast:5 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00"); + +// memory.wast:6 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x01"); + +// memory.wast:7 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x01\x01\x80\x02"); + +// memory.wast:8 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x80\x80\x04"); + +// memory.wast:10 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x02\x00\x00\x00\x00"); + +// memory.wast:11 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00"); + +// memory.wast:13 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:14 +assert_return(() => call($7, "memsize", []), 0); + +// memory.wast:15 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:16 +assert_return(() => call($8, "memsize", []), 0); + +// memory.wast:17 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); + +// memory.wast:18 +assert_return(() => call($9, "memsize", []), 1); + +// memory.wast:20 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:21 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:22 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); + +// memory.wast:24 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2a\x02\x00\x1a\x0b"); + +// memory.wast:28 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x38\x02\x00\x0b"); + +// memory.wast:32 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2c\x00\x00\x1a\x0b"); + +// memory.wast:36 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x41\x00\x3a\x00\x00\x0b"); + +// memory.wast:40 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x3f\x00\x1a\x0b"); + +// memory.wast:44 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x1a\x0b"); + +// memory.wast:50 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x00"); + +// memory.wast:54 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x00\x81\x80\x04"); + +// memory.wast:58 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\x80\x80\x80\x80\x08"); + +// memory.wast:62 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\xff\xff\xff\xff\x0f"); + +// memory.wast:66 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x81\x80\x04"); + +// memory.wast:70 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\x80\x80\x80\x80\x08"); + +// memory.wast:74 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\xff\xff\xff\xff\x0f"); + +// memory.wast:79 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// memory.wast:83 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// memory.wast:87 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// memory.wast:92 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x93\x80\x80\x80\x00\x04\x60\x00\x01\x7f\x60\x00\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x03\x8d\x80\x80\x80\x00\x0c\x00\x01\x02\x02\x02\x02\x03\x03\x03\x03\x03\x03\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xa1\x81\x80\x80\x00\x0c\x04\x64\x61\x74\x61\x00\x00\x04\x63\x61\x73\x74\x00\x01\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x02\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x03\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x04\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x05\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x06\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x07\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x08\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x09\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x0a\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x0b\x0a\xcf\x82\x80\x80\x00\x0c\xce\x80\x80\x80\x00\x00\x41\x00\x2d\x00\x00\x41\xc1\x00\x46\x41\x03\x2d\x00\x00\x41\xa7\x01\x46\x71\x41\x06\x2d\x00\x00\x41\x00\x46\x41\x13\x2d\x00\x00\x41\x00\x46\x71\x71\x41\x14\x2d\x00\x00\x41\xd7\x00\x46\x41\x17\x2d\x00\x00\x41\xcd\x00\x46\x71\x41\x18\x2d\x00\x00\x41\x00\x46\x41\xff\x07\x2d\x00\x00\x41\x00\x46\x71\x71\x71\x0b\xb8\x80\x80\x80\x00\x00\x41\x08\x42\xc7\x9f\x7f\x37\x03\x00\x41\x08\x2b\x03\x00\x42\xc7\x9f\x7f\xbf\x61\x04\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0b\x41\x09\x42\x00\x37\x00\x00\x41\x0f\x41\xc5\x80\x01\x3b\x00\x00\x41\x09\x2b\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2c\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2d\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2e\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2f\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x30\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x31\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x32\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x33\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x34\x02\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x35\x02\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x05\x41\x42\x43\xa7\x44\x00\x41\x14\x0b\x04\x57\x41\x53\x4d"); + +// memory.wast:180 +assert_return(() => call($10, "data", []), 1); + +// memory.wast:181 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8c\x80\x80\x80\x00\x01\x03\x24\x31\x30\x04\x63\x61\x73\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x45\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "cast", []), 42.) + +// memory.wast:183 +assert_return(() => call($10, "i32_load8_s", [-1]), -1); + +// memory.wast:184 +assert_return(() => call($10, "i32_load8_u", [-1]), 255); + +// memory.wast:185 +assert_return(() => call($10, "i32_load16_s", [-1]), -1); + +// memory.wast:186 +assert_return(() => call($10, "i32_load16_u", [-1]), 65_535); + +// memory.wast:188 +assert_return(() => call($10, "i32_load8_s", [100]), 100); + +// memory.wast:189 +assert_return(() => call($10, "i32_load8_u", [200]), 200); + +// memory.wast:190 +assert_return(() => call($10, "i32_load16_s", [20_000]), 20_000); + +// memory.wast:191 +assert_return(() => call($10, "i32_load16_u", [40_000]), 40_000); + +// memory.wast:193 +assert_return(() => call($10, "i32_load8_s", [-19_110_589]), 67); + +// memory.wast:194 +assert_return(() => call($10, "i32_load8_s", [878_104_047]), -17); + +// memory.wast:195 +assert_return(() => call($10, "i32_load8_u", [-19_110_589]), 67); + +// memory.wast:196 +assert_return(() => call($10, "i32_load8_u", [878_104_047]), 239); + +// memory.wast:197 +assert_return(() => call($10, "i32_load16_s", [-19_110_589]), 25_923); + +// memory.wast:198 +assert_return(() => call($10, "i32_load16_s", [878_104_047]), -12_817); + +// memory.wast:199 +assert_return(() => call($10, "i32_load16_u", [-19_110_589]), 25_923); + +// memory.wast:200 +assert_return(() => call($10, "i32_load16_u", [878_104_047]), 52_719); + +// memory.wast:202 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("-1")]), int64("-1")) + +// memory.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("-1")]), int64("255")) + +// memory.wast:204 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("-1")]), int64("-1")) + +// memory.wast:205 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("-1")]), int64("65_535")) + +// memory.wast:206 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("-1")]), int64("-1")) + +// memory.wast:207 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("-1")]), int64("4_294_967_295")) + +// memory.wast:209 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xe4\x00\x10\x00\x01\x42\xe4\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("100")]), int64("100")) + +// memory.wast:210 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xc8\x01\x10\x00\x01\x42\xc8\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("200")]), int64("200")) + +// memory.wast:211 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("20_000")]), int64("20_000")) + +// memory.wast:212 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("40_000")]), int64("40_000")) + +// memory.wast:213 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("20_000")]), int64("20_000")) + +// memory.wast:214 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("40_000")]), int64("40_000")) + +// memory.wast:216 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("-81_985_529_755_441_853")]), int64("67")) + +// memory.wast:217 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\x6f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("3_771_275_841_602_506_223")]), int64("-17")) + +// memory.wast:218 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("-81_985_529_755_441_853")]), int64("67")) + +// memory.wast:219 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("3_771_275_841_602_506_223")]), int64("239")) + +// memory.wast:220 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("-81_985_529_755_441_853")]), int64("25_923")) + +// memory.wast:221 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("3_771_275_841_602_506_223")]), int64("-12_817")) + +// memory.wast:222 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("-81_985_529_755_441_853")]), int64("25_923")) + +// memory.wast:223 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("3_771_275_841_602_506_223")]), int64("52_719")) + +// memory.wast:224 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) + +// memory.wast:225 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x79\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("3_771_275_841_602_506_223")]), int64("-1_732_588_049")) + +// memory.wast:226 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) + +// memory.wast:227 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("3_771_275_841_602_506_223")]), int64("2_562_379_247")) + +// memory.wast:231 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// memory.wast:235 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// memory.wast:239 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/memory_grow.wast.js b/js/src/jit-test/tests/wasm/spec/spec/memory_grow.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/memory_grow.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/memory_grow.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/memory_redundancy.wast.js b/js/src/jit-test/tests/wasm/spec/spec/memory_redundancy.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/memory_redundancy.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/memory_redundancy.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/memory_size.wast.js b/js/src/jit-test/tests/wasm/spec/spec/memory_size.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/memory_size.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/memory_size.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/nop.wast.js b/js/src/jit-test/tests/wasm/spec/spec/nop.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/nop.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/nop.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/return.wast.js b/js/src/jit-test/tests/wasm/spec/spec/return.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/return.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/return.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/select.wast.js b/js/src/jit-test/tests/wasm/spec/spec/select.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/select.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/select.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/skip-stack-guard-page.wast.js b/js/src/jit-test/tests/wasm/spec/spec/skip-stack-guard-page.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/skip-stack-guard-page.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/skip-stack-guard-page.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/stack.wast.js b/js/src/jit-test/tests/wasm/spec/spec/stack.wast.js new file mode 100644 index 0000000000..1deaec4f59 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/stack.wast.js @@ -0,0 +1,21 @@ + +// stack.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8d\x80\x80\x80\x00\x03\x60\x01\x7e\x01\x7e\x60\x00\x01\x7f\x60\x00\x00\x03\x89\x80\x80\x80\x00\x08\x00\x00\x00\x00\x00\x01\x02\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x00\x0b\x07\xd7\x80\x80\x80\x00\x06\x08\x66\x61\x63\x2d\x65\x78\x70\x72\x00\x00\x09\x66\x61\x63\x2d\x73\x74\x61\x63\x6b\x00\x01\x0d\x66\x61\x63\x2d\x73\x74\x61\x63\x6b\x2d\x72\x61\x77\x00\x02\x09\x66\x61\x63\x2d\x6d\x69\x78\x65\x64\x00\x03\x0d\x66\x61\x63\x2d\x6d\x69\x78\x65\x64\x2d\x72\x61\x77\x00\x04\x10\x6e\x6f\x74\x2d\x71\x75\x69\x74\x65\x2d\x61\x2d\x74\x72\x65\x65\x00\x07\x0a\xaf\x82\x80\x80\x00\x08\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\xaf\x80\x80\x80\x00\x01\x02\x7e\x20\x00\x21\x01\x42\x01\x21\x02\x02\x40\x03\x40\x20\x01\x42\x00\x51\x04\x40\x0c\x02\x05\x20\x01\x20\x02\x7e\x21\x02\x20\x01\x42\x01\x7d\x21\x01\x0b\x0c\x00\x0b\x0b\x20\x02\x0b\x8d\x80\x80\x80\x00\x01\x01\x7f\x41\x01\x23\x00\x6a\x24\x00\x23\x00\x0b\x85\x80\x80\x80\x00\x00\x10\x05\x1a\x0b\x89\x80\x80\x80\x00\x00\x10\x05\x10\x05\x10\x06\x6a\x0b"); + +// stack.wast:146 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x61\x63\x2d\x65\x78\x70\x72\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-expr", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// stack.wast:147 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x66\x61\x63\x2d\x73\x74\x61\x63\x6b\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-stack", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// stack.wast:148 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x90\x80\x80\x80\x00\x01\x02\x24\x31\x09\x66\x61\x63\x2d\x6d\x69\x78\x65\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\x19\x10\x00\x01\x42\x80\x80\x80\xde\x87\x92\xec\xcf\xe1\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "fac-mixed", [int64("25")]), int64("7_034_535_277_573_963_776")) + +// stack.wast:150 +assert_return(() => call($1, "not-quite-a-tree", []), 3); + +// stack.wast:151 +assert_return(() => call($1, "not-quite-a-tree", []), 9); + +// stack.wast:156 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x00\x60\x00\x01\x7f\x60\x01\x7f\x00\x03\x82\x80\x80\x80\x00\x01\x00\x04\x84\x80\x80\x80\x00\x01\x70\x00\x01\x0a\xb7\x83\x80\x80\x00\x01\xb1\x83\x80\x80\x00\x00\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x02\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x03\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x41\x00\x04\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x41\x00\x04\x40\x41\x00\x41\x00\x11\x02\x00\x05\x41\x00\x41\x00\x11\x02\x00\x0b\x02\x7f\x41\x00\x11\x01\x00\x0b\x1a\x03\x7f\x41\x00\x11\x01\x00\x0b\x1a\x41\x00\x04\x7f\x41\x00\x11\x01\x00\x05\x41\x00\x11\x01\x00\x0b\x1a\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x02\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x03\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x41\x00\x04\x40\x41\x00\x41\x00\x11\x02\x00\x0b\x41\x00\x04\x40\x41\x00\x41\x00\x11\x02\x00\x05\x41\x00\x41\x00\x11\x02\x00\x0b\x02\x7f\x41\x00\x11\x01\x00\x0b\x1a\x03\x7f\x41\x00\x11\x01\x00\x0b\x1a\x41\x00\x04\x7f\x41\x00\x11\x01\x00\x05\x41\x00\x11\x01\x00\x0b\x1a\x02\x40\x41\x00\x11\x00\x00\x0b\x03\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x0b\x41\x00\x04\x40\x41\x00\x11\x00\x00\x05\x41\x00\x11\x00\x00\x0b\x41\x00\x11\x00\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/start.wast.js b/js/src/jit-test/tests/wasm/spec/spec/start.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/start.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/start.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/store.wast.js b/js/src/jit-test/tests/wasm/spec/spec/store.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/store.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/store.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/switch.wast.js b/js/src/jit-test/tests/wasm/spec/spec/switch.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/switch.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/switch.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/token.wast.js b/js/src/jit-test/tests/wasm/spec/spec/token.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/token.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/token.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/traps.wast.js b/js/src/jit-test/tests/wasm/spec/spec/traps.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/traps.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/traps.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/type.wast.js b/js/src/jit-test/tests/wasm/spec/spec/type.wast.js new file mode 100644 index 0000000000..19e70b379e --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/type.wast.js @@ -0,0 +1,9 @@ + +// type.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x81\x80\x80\x00\x17\x60\x00\x00\x60\x00\x00\x60\x01\x7f\x00\x60\x01\x7f\x00\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7d\x7c\x00\x60\x00\x02\x7e\x7d\x60\x02\x7f\x7e\x02\x7d\x7c\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x00\x02\x7e\x7d\x60\x02\x7f\x7e\x02\x7d\x7c\x60\x02\x7f\x7e\x02\x7d\x7c\x60\x06\x7d\x7c\x7f\x7c\x7f\x7f\x00\x60\x00\x05\x7e\x7e\x7d\x7d\x7f\x60\x04\x7f\x7f\x7e\x7f\x04\x7d\x7c\x7c\x7f\x60\x03\x7d\x7c\x7f\x00\x60\x00\x03\x7e\x7e\x7d\x60\x05\x7f\x7f\x7e\x7f\x7f\x04\x7d\x7c\x7c\x7f"); + +// type.wast:43 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// type.wast:47 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/unreachable.wast.js b/js/src/jit-test/tests/wasm/spec/spec/unreachable.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/unreachable.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/unreachable.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/spec/unreached-invalid.wast.js b/js/src/jit-test/tests/wasm/spec/spec/unreached-invalid.wast.js new file mode 100644 index 0000000000..2aec2cedc9 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/spec/unreached-invalid.wast.js @@ -0,0 +1,333 @@ + +// unreached-invalid.wast:3 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x20\x00\x1a\x0b"); + +// unreached-invalid.wast:7 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x23\x00\x1a\x0b"); + +// unreached-invalid.wast:11 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x00\x10\x01\x0b"); + +// unreached-invalid.wast:15 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x00\x0c\x01\x0b"); + +// unreached-invalid.wast:20 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x00\x41\x00\x50\x1a\x0b"); + +// unreached-invalid.wast:26 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x00\x42\x00\x41\x00\x1b\x0b"); + +// unreached-invalid.wast:32 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x00\x42\x00\x41\x00\x1b\x41\x00\x41\x00\x1b\x0b"); + +// unreached-invalid.wast:41 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x00\x41\x00\x0b"); + +// unreached-invalid.wast:45 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x00\x45\x0b"); + +// unreached-invalid.wast:49 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x41\x00\x6a\x0b"); + +// unreached-invalid.wast:55 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x00\x1b\x0b"); + +// unreached-invalid.wast:59 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x41\x00\x1b\x0b"); + +// unreached-invalid.wast:63 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x00\x41\x00\x41\x00\x1b\x0b"); + +// unreached-invalid.wast:70 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x02\x40\x01\x45\x1a\x0b\x0b\x0b"); + +// unreached-invalid.wast:76 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x43\x00\x00\x80\x3f\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:82 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x02\x40\x41\x01\x5b\x1a\x0b\x0b\x0b"); + +// unreached-invalid.wast:88 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:94 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x0c\x00\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:100 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0c\x00\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:106 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x03\x40\x0c\x01\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:112 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0c\x01\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:118 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x0c\x00\x41\x01\x0b"); + +// unreached-invalid.wast:124 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x01\x0c\x00\x43\x00\x00\x00\x00\x0b"); + +// unreached-invalid.wast:131 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x0f\x02\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:137 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x0f\x43\x00\x00\x80\x3f\x45\x1a\x0b"); + +// unreached-invalid.wast:143 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x0f\x02\x40\x41\x01\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:149 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x0f\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b"); + +// unreached-invalid.wast:155 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x0f\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:161 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x00\x0f\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:167 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x03\x40\x0f\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:173 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x03\x7f\x41\x01\x0f\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:179 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x0f\x41\x01\x0b"); + +// unreached-invalid.wast:185 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x0f\x43\x00\x00\x00\x00\x0b"); + +// unreached-invalid.wast:192 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x00\x02\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:198 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x00\x03\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:204 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x00\x03\x7f\x01\x45\x0b\x0b"); + +// unreached-invalid.wast:210 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x00\x43\x00\x00\x80\x3f\x45\x1a\x0b"); + +// unreached-invalid.wast:216 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x00\x02\x40\x41\x01\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:222 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x00\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b"); + +// unreached-invalid.wast:228 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x00\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:234 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x00\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:240 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x03\x40\x00\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:246 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x7f\x00\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:252 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x00\x41\x01\x0b"); + +// unreached-invalid.wast:258 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x00\x43\x00\x00\x00\x00\x0b"); + +// unreached-invalid.wast:264 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x00\x41\x00\x04\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:270 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x00\x41\x00\x04\x40\x01\x05\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:276 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x40\x00\x05\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:283 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x02\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:289 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x43\x00\x00\x80\x3f\x45\x1a\x0b"); + +// unreached-invalid.wast:295 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x02\x40\x41\x01\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:301 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b"); + +// unreached-invalid.wast:307 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x02\x40\x00\x0b\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:313 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x02\x40\x00\x0b\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:320 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x03\x40\x02\x40\x00\x0b\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:326 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x03\x7f\x02\x40\x00\x0b\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:333 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x41\x01\x0b"); + +// unreached-invalid.wast:339 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x00\x0b\x43\x00\x00\x00\x00\x0b"); + +// unreached-invalid.wast:347 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x02\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:353 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x43\x00\x00\x80\x3f\x45\x1a\x0b"); + +// unreached-invalid.wast:359 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x02\x40\x41\x01\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:365 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b"); + +// unreached-invalid.wast:371 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x03\x40\x0c\x00\x0b\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:377 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x03\x40\x0c\x00\x0b\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:383 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x03\x40\x03\x40\x0c\x00\x0b\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:389 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x03\x7f\x03\x40\x0c\x00\x0b\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:395 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x41\x01\x0b"); + +// unreached-invalid.wast:401 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x03\x40\x0c\x00\x0b\x43\x00\x00\x00\x00\x0b"); + +// unreached-invalid.wast:408 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x00\x04\x40\x01\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:414 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x41\x00\x04\x40\x43\x00\x00\x80\x3f\x45\x1a\x0b\x0b"); + +// unreached-invalid.wast:420 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x41\x00\x04\x40\x41\x01\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:426 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x41\x00\x04\x40\x41\x01\x43\x00\x00\x00\x00\x5b\x1a\x0b\x0b"); + +// unreached-invalid.wast:432 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x04\x40\x41\x01\x0b\x0b"); + +// unreached-invalid.wast:438 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x43\x00\x00\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:444 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x40\x02\x40\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:450 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x02\x7f\x43\x00\x00\x00\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:456 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x04\x40\x03\x40\x41\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:462 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x00\x04\x7f\x03\x7f\x43\x00\x00\x00\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:469 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x41\x01\x0f\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0f\x0b"); + +// unreached-invalid.wast:476 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0c\x00\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x0c\x00\x0b\x0b"); + +// unreached-invalid.wast:483 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x00\x43\x00\x00\x00\x00\x0d\x00\x0b\x0b"); + +// unreached-invalid.wast:489 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x00\x41\x00\x41\x00\x0d\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:497 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x7f\x02\x7d\x00\x41\x00\x41\x00\x0d\x01\x0b\x1a\x41\x00\x0b\x0b"); + +// unreached-invalid.wast:506 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x00\x41\x00\x41\x00\x0d\x00\x41\x00\x0b\x0b"); + +// unreached-invalid.wast:514 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x40\x00\x43\x00\x00\x80\x3f\x0e\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:520 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x7f\x00\x43\x00\x00\x00\x00\x41\x01\x0e\x00\x00\x0b\x0b"); + +// unreached-invalid.wast:526 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x00\x0b\x1a\x0b\x0b"); + +// unreached-invalid.wast:538 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x7c\x02\x7d\x00\x41\x01\x0e\x02\x00\x01\x01\x0b\x1a\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x1a\x0b"); + +// unreached-invalid.wast:553 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:559 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:565 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:571 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x00\x0b\x0b\x41\x09\x0b"); + +// unreached-invalid.wast:578 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0c\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:584 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:590 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x42\x00\x02\x40\x41\x00\x0c\x01\x0b\x0b\x0b"); + +// unreached-invalid.wast:597 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x03\x02\x40\x0c\x02\x0b\x0b\x0b\x0b"); + +// unreached-invalid.wast:603 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); + +// unreached-invalid.wast:609 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x7f\x02\x7e\x42\x00\x02\x40\x41\x00\x0c\x02\x0b\x0b\x0b\x0b"); + +// unreached-invalid.wast:617 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x0c\x01\x0b\x0b\x41\x09\x0b"); + +// unreached-invalid.wast:624 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x0f\x0b\x0b\x0b"); + +// unreached-invalid.wast:630 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); + +// unreached-invalid.wast:636 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7e\x42\x00\x02\x40\x41\x00\x0f\x0b\x0b\x0b"); + +// unreached-invalid.wast:642 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x41\x03\x02\x40\x42\x01\x41\x00\x0f\x0b\x0b\x41\x09\x0b"); + +// unreached-invalid.wast:650 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x40\x41\x03\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:656 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:662 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x03\x7e\x42\x00\x02\x40\x00\x0b\x0b\x0b"); + +// unreached-invalid.wast:669 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x03\x40\x01\x0c\x00\x0b\x0b"); + +// unreached-invalid.wast:675 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x03\x40\x41\x00\x0c\x00\x0b\x0b"); + +// unreached-invalid.wast:682 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x01\x01\x7f\x00\x22\x00\x0b"); + +// unreached-invalid.wast:689 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x95\x80\x80\x80\x00\x01\x8f\x80\x80\x80\x00\x00\x02\x7f\x02\x40\x00\x41\x00\x0d\x01\x0b\x41\x00\x0b\x0b"); + +// unreached-invalid.wast:700 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7e\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x00\x0d\x00\xad\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/unwind.wast.js b/js/src/jit-test/tests/wasm/spec/spec/unwind.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/unwind.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/unwind.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/utf8-import-field.wast.js b/js/src/jit-test/tests/wasm/spec/spec/utf8-import-field.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/utf8-import-field.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/utf8-import-field.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/utf8-import-module.wast.js b/js/src/jit-test/tests/wasm/spec/spec/utf8-import-module.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/utf8-import-module.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/utf8-import-module.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/utf8-invalid-encoding.wast.js b/js/src/jit-test/tests/wasm/spec/spec/utf8-invalid-encoding.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/utf8-invalid-encoding.wast.js rename to js/src/jit-test/tests/wasm/spec/spec/utf8-invalid-encoding.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/address.wast.js b/js/src/jit-test/tests/wasm/spec/threads/address.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/address.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/address.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/binary.wast.js b/js/src/jit-test/tests/wasm/spec/threads/binary.wast.js new file mode 100644 index 0000000000..6c09003c15 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/binary.wast.js @@ -0,0 +1,254 @@ + +// binary.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:2 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:3 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M1 = $3; + +// binary.wast:4 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00"); +let $M2 = $4; + +// binary.wast:6 +assert_malformed(""); + +// binary.wast:7 +assert_malformed("\x01"); + +// binary.wast:8 +assert_malformed("\x00\x61\x73"); + +// binary.wast:9 +assert_malformed("\x61\x73\x6d\x00"); + +// binary.wast:10 +assert_malformed("\x6d\x73\x61\x00"); + +// binary.wast:11 +assert_malformed("\x6d\x73\x61\x00\x01\x00\x00\x00"); + +// binary.wast:12 +assert_malformed("\x6d\x73\x61\x00\x00\x00\x00\x01"); + +// binary.wast:13 +assert_malformed("\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// binary.wast:14 +assert_malformed("\x77\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:15 +assert_malformed("\x7f\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:16 +assert_malformed("\x80\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:17 +assert_malformed("\x82\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:18 +assert_malformed("\xff\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:21 +assert_malformed("\x00\x00\x00\x01\x6d\x73\x61\x00"); + +// binary.wast:24 +assert_malformed("\x61\x00\x6d\x73\x00\x01\x00\x00"); + +// binary.wast:25 +assert_malformed("\x73\x6d\x00\x61\x00\x00\x01\x00"); + +// binary.wast:28 +assert_malformed("\x00\x41\x53\x4d\x01\x00\x00\x00"); + +// binary.wast:31 +assert_malformed("\x00\x81\xa2\x94\x01\x00\x00\x00"); + +// binary.wast:34 +assert_malformed("\xef\xbb\xbf\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// binary.wast:37 +assert_malformed("\x00\x61\x73\x6d"); + +// binary.wast:38 +assert_malformed("\x00\x61\x73\x6d\x01"); + +// binary.wast:39 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00"); + +// binary.wast:40 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x00"); + +// binary.wast:41 +assert_malformed("\x00\x61\x73\x6d\x0d\x00\x00\x00"); + +// binary.wast:42 +assert_malformed("\x00\x61\x73\x6d\x0e\x00\x00\x00"); + +// binary.wast:43 +assert_malformed("\x00\x61\x73\x6d\x00\x01\x00\x00"); + +// binary.wast:44 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x01\x00"); + +// binary.wast:45 +assert_malformed("\x00\x61\x73\x6d\x00\x00\x00\x01"); + +// binary.wast:49 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x09\x01\x07\x00\x41\x00\x11\x00\x01\x0b"); + +// binary.wast:68 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0a\x01\x07\x00\x41\x00\x11\x00\x80\x00\x0b"); + +// binary.wast:87 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0b\x01\x08\x00\x41\x00\x11\x00\x80\x80\x00\x0b"); + +// binary.wast:105 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0c\x01\x09\x00\x41\x00\x11\x00\x80\x80\x80\x00\x0b"); + +// binary.wast:123 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x00\x0a\x0d\x01\x0a\x00\x41\x00\x11\x00\x80\x80\x80\x80\x00\x0b"); + +// binary.wast:142 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x41\x00\x40\x01\x1a\x0b"); + +// binary.wast:162 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x41\x00\x40\x80\x00\x1a\x0b"); + +// binary.wast:182 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x41\x00\x40\x80\x80\x00\x1a\x0b"); + +// binary.wast:201 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0c\x01\x0a\x00\x41\x00\x40\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:220 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0d\x01\x0b\x00\x41\x00\x40\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:240 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x07\x01\x05\x00\x3f\x01\x1a\x0b"); + +// binary.wast:259 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x08\x01\x06\x00\x3f\x80\x00\x1a\x0b"); + +// binary.wast:278 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x09\x01\x07\x00\x3f\x80\x80\x00\x1a\x0b"); + +// binary.wast:296 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0a\x01\x08\x00\x3f\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:314 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x05\x03\x01\x00\x00\x0a\x0b\x01\x09\x00\x3f\x80\x80\x80\x80\x00\x1a\x0b"); + +// binary.wast:333 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0c\x01\x0a\x02\xff\xff\xff\xff\x0f\x7f\x02\x7e\x0b"); + +// binary.wast:350 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x0a\x01\x08\x03\x00\x7f\x00\x7e\x02\x7d\x0b"); + +// binary.wast:365 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00"); + +// binary.wast:375 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:384 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:395 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:406 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x03\x01\x00"); + +// binary.wast:412 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x0a\x01\x00"); + +// binary.wast:418 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x01\x00"); + +// binary.wast:424 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x02\x60\x00\x00"); + +// binary.wast:435 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x00\x00\x60\x00\x00"); + +// binary.wast:446 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x01\x00"); + +// binary.wast:454 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x02\x16\x02\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00"); + +// binary.wast:473 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x09\x02\x60\x01\x7f\x00\x60\x01\x7d\x00\x02\x2b\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x69\x33\x32\x00\x00\x08\x73\x70\x65\x63\x74\x65\x73\x74\x09\x70\x72\x69\x6e\x74\x5f\x66\x33\x32\x00\x01"); + +// binary.wast:498 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x00"); + +// binary.wast:504 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x04\x01\x01"); + +// binary.wast:514 +let $11 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x00"); + +// binary.wast:520 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x01\x01"); + +// binary.wast:530 +let $12 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x01\x00"); + +// binary.wast:536 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x06\x02\x7f\x00\x41\x00\x0b"); + +// binary.wast:547 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x06\x0b\x01\x7f\x00\x41\x00\x0b\x7f\x00\x41\x00\x0b"); + +// binary.wast:558 +let $13 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x01\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:570 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x06\x02\x02\x66\x31\x00\x00\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:591 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x03\x02\x00\x00\x07\x0b\x01\x02\x66\x31\x00\x00\x02\x66\x32\x00\x01\x0a\x07\x02\x02\x00\x0b\x02\x00\x0b"); + +// binary.wast:612 +let $14 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:625 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x07\x02\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:643 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x04\x04\x01\x70\x00\x01\x09\x0d\x01\x00\x41\x00\x0b\x01\x00\x00\x41\x00\x0b\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:661 +let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x01\x00"); + +// binary.wast:669 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x07\x02\x00\x41\x00\x0b\x01\x61"); + +// binary.wast:682 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0d\x01\x00\x41\x00\x0b\x01\x61\x00\x41\x01\x0b\x01\x62"); + +// binary.wast:695 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x03\x0b\x07\x61\x62\x63\x64\x65\x66"); + +// binary.wast:709 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x03\x01\x00\x01\x0b\x0c\x01\x00\x41\x00\x0b\x05\x61\x62\x63\x64\x65\x66"); + +// binary.wast:723 +let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x11\x01\x0f\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x00\x02\x0b\x0b\x0b"); + +// binary.wast:740 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x10\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x02\x00\x02\x0b\x0b\x0b"); + +// binary.wast:762 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x0a\x12\x01\x11\x00\x02\x40\x41\x01\x04\x40\x41\x01\x0e\x01\x00\x01\x02\x0b\x0b\x0b"); + +// binary.wast:784 +let $17 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); + +// binary.wast:797 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/block.wast.js b/js/src/jit-test/tests/wasm/spec/threads/block.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/block.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/block.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/br.wast.js b/js/src/jit-test/tests/wasm/spec/threads/br.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/br.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/br.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/br_if.wast.js b/js/src/jit-test/tests/wasm/spec/threads/br_if.wast.js new file mode 100644 index 0000000000..a97f8bd9c4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/br_if.wast.js @@ -0,0 +1,354 @@ + +// br_if.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa9\x80\x80\x80\x00\x09\x60\x03\x7f\x7f\x7f\x01\x7f\x60\x00\x00\x60\x00\x01\x7f\x60\x00\x01\x7e\x60\x00\x01\x7d\x60\x00\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7f\x00\x60\x02\x7f\x7f\x00\x03\xc0\x80\x80\x80\x00\x3f\x01\x01\x01\x01\x01\x02\x03\x04\x05\x06\x06\x07\x06\x06\x06\x06\x06\x07\x02\x01\x02\x06\x01\x02\x02\x03\x06\x08\x08\x06\x06\x02\x00\x02\x02\x02\x00\x02\x02\x02\x02\x06\x06\x06\x02\x02\x02\x02\x02\x02\x05\x02\x02\x02\x02\x02\x02\x06\x06\x06\x06\x06\x06\x04\x85\x80\x80\x80\x00\x01\x70\x01\x01\x01\x05\x83\x80\x80\x80\x00\x01\x00\x01\x06\x86\x80\x80\x80\x00\x01\x7f\x01\x41\x0a\x0b\x07\xd1\x88\x80\x80\x00\x3c\x08\x74\x79\x70\x65\x2d\x69\x33\x32\x00\x01\x08\x74\x79\x70\x65\x2d\x69\x36\x34\x00\x02\x08\x74\x79\x70\x65\x2d\x66\x33\x32\x00\x03\x08\x74\x79\x70\x65\x2d\x66\x36\x34\x00\x04\x0e\x74\x79\x70\x65\x2d\x69\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x05\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x06\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x07\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x08\x0e\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x66\x69\x72\x73\x74\x00\x09\x0c\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6d\x69\x64\x00\x0a\x0d\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6c\x61\x73\x74\x00\x0b\x14\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x66\x69\x72\x73\x74\x2d\x76\x61\x6c\x75\x65\x00\x0c\x12\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6d\x69\x64\x2d\x76\x61\x6c\x75\x65\x00\x0d\x13\x61\x73\x2d\x62\x6c\x6f\x63\x6b\x2d\x6c\x61\x73\x74\x2d\x76\x61\x6c\x75\x65\x00\x0e\x0d\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x66\x69\x72\x73\x74\x00\x0f\x0b\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6d\x69\x64\x00\x10\x0c\x61\x73\x2d\x6c\x6f\x6f\x70\x2d\x6c\x61\x73\x74\x00\x11\x0b\x61\x73\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x12\x0d\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x63\x6f\x6e\x64\x00\x13\x0e\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x14\x13\x61\x73\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x15\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x69\x6e\x64\x65\x78\x00\x16\x11\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x17\x17\x61\x73\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x18\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x19\x0a\x61\x73\x2d\x69\x66\x2d\x63\x6f\x6e\x64\x00\x1a\x0a\x61\x73\x2d\x69\x66\x2d\x74\x68\x65\x6e\x00\x1b\x0a\x61\x73\x2d\x69\x66\x2d\x65\x6c\x73\x65\x00\x1c\x0f\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x1d\x10\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x73\x65\x63\x6f\x6e\x64\x00\x1e\x0e\x61\x73\x2d\x73\x65\x6c\x65\x63\x74\x2d\x63\x6f\x6e\x64\x00\x1f\x0d\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x66\x69\x72\x73\x74\x00\x21\x0b\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6d\x69\x64\x00\x22\x0c\x61\x73\x2d\x63\x61\x6c\x6c\x2d\x6c\x61\x73\x74\x00\x23\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x75\x6e\x63\x00\x25\x16\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x66\x69\x72\x73\x74\x00\x26\x14\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6d\x69\x64\x00\x27\x15\x61\x73\x2d\x63\x61\x6c\x6c\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x2d\x6c\x61\x73\x74\x00\x28\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x29\x12\x61\x73\x2d\x6c\x6f\x63\x61\x6c\x2e\x74\x65\x65\x2d\x76\x61\x6c\x75\x65\x00\x2a\x13\x61\x73\x2d\x67\x6c\x6f\x62\x61\x6c\x2e\x73\x65\x74\x2d\x76\x61\x6c\x75\x65\x00\x2b\x0f\x61\x73\x2d\x6c\x6f\x61\x64\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x2c\x10\x61\x73\x2d\x6c\x6f\x61\x64\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x2d\x10\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x2e\x0e\x61\x73\x2d\x73\x74\x6f\x72\x65\x2d\x76\x61\x6c\x75\x65\x00\x2f\x11\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x61\x64\x64\x72\x65\x73\x73\x00\x30\x0f\x61\x73\x2d\x73\x74\x6f\x72\x65\x4e\x2d\x76\x61\x6c\x75\x65\x00\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x32\x0e\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x6c\x65\x66\x74\x00\x33\x0f\x61\x73\x2d\x62\x69\x6e\x61\x72\x79\x2d\x72\x69\x67\x68\x74\x00\x34\x0f\x61\x73\x2d\x74\x65\x73\x74\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x35\x0f\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x6c\x65\x66\x74\x00\x36\x10\x61\x73\x2d\x63\x6f\x6d\x70\x61\x72\x65\x2d\x72\x69\x67\x68\x74\x00\x37\x13\x61\x73\x2d\x6d\x65\x6d\x6f\x72\x79\x2e\x67\x72\x6f\x77\x2d\x73\x69\x7a\x65\x00\x38\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x6c\x6f\x63\x6b\x2d\x76\x61\x6c\x75\x65\x00\x39\x0f\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x2d\x76\x61\x6c\x75\x65\x00\x3a\x12\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x00\x3b\x17\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x69\x66\x2d\x76\x61\x6c\x75\x65\x2d\x63\x6f\x6e\x64\x00\x3c\x15\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x00\x3d\x1b\x6e\x65\x73\x74\x65\x64\x2d\x62\x72\x5f\x74\x61\x62\x6c\x65\x2d\x76\x61\x6c\x75\x65\x2d\x69\x6e\x64\x65\x78\x00\x3e\x09\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x24\x0a\xd6\x8a\x80\x80\x00\x3f\x82\x80\x80\x80\x00\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x01\x0d\x00\x68\x1a\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x42\x00\x41\x01\x0d\x00\x7a\x1a\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x00\x00\x41\x01\x0d\x00\x8c\x1a\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x41\x01\x0d\x00\x9a\x1a\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0d\x00\x68\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7e\x42\x02\x41\x01\x0d\x00\x7a\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7d\x43\x00\x00\x40\x40\x41\x01\x0d\x00\x8c\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7c\x44\x00\x00\x00\x00\x00\x00\x10\x40\x41\x01\x0d\x00\x9a\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x40\x20\x00\x0d\x00\x41\x02\x0f\x0b\x41\x03\x0b\x90\x80\x80\x80\x00\x00\x02\x40\x10\x00\x20\x00\x0d\x00\x41\x02\x0f\x0b\x41\x03\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x10\x00\x10\x00\x20\x00\x0d\x00\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x20\x00\x0d\x00\x1a\x41\x0b\x0f\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x41\x14\x20\x00\x0d\x00\x1a\x41\x15\x0f\x0b\x0b\x8f\x80\x80\x80\x00\x00\x02\x7f\x10\x00\x10\x00\x41\x0b\x20\x00\x0d\x00\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x40\x03\x40\x20\x00\x0d\x01\x41\x02\x0f\x0b\x0b\x41\x03\x0b\x93\x80\x80\x80\x00\x00\x02\x40\x03\x40\x10\x00\x20\x00\x0d\x01\x41\x02\x0f\x0b\x0b\x41\x04\x0b\x8b\x80\x80\x80\x00\x00\x03\x40\x10\x00\x20\x00\x0d\x01\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x0d\x00\x0c\x00\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x40\x41\x01\x41\x01\x0d\x00\x0d\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x0d\x00\x41\x03\x0d\x00\x1a\x41\x04\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x01\x20\x00\x0d\x00\x0d\x00\x1a\x41\x04\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x40\x41\x01\x41\x02\x0d\x00\x0e\x02\x00\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x0d\x00\x41\x03\x0e\x02\x00\x00\x00\x41\x04\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x01\x41\x03\x0d\x00\x0e\x01\x00\x00\x41\x04\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7e\x42\x01\x41\x02\x0d\x00\x0f\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x20\x00\x0d\x00\x04\x7f\x41\x02\x05\x41\x03\x0b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x40\x20\x00\x04\x40\x20\x01\x0d\x01\x05\x10\x00\x0b\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x40\x20\x00\x04\x40\x10\x00\x05\x20\x01\x0d\x01\x0b\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x03\x41\x0a\x0d\x00\x41\x02\x20\x00\x1b\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x03\x41\x0a\x0d\x00\x20\x00\x1b\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x03\x41\x0a\x0d\x00\x1b\x0b\x0b\x84\x80\x80\x80\x00\x00\x41\x7f\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x0c\x41\x01\x0d\x00\x41\x02\x41\x03\x10\x20\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x0d\x41\x01\x0d\x00\x41\x03\x10\x20\x0b\x0b\x91\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x0e\x41\x01\x0d\x00\x10\x20\x0b\x0b\x84\x80\x80\x80\x00\x00\x20\x00\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x04\x41\x0a\x0d\x00\x41\x01\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x04\x41\x0a\x0d\x00\x41\x02\x41\x00\x11\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x04\x41\x0a\x0d\x00\x41\x00\x11\x00\x00\x0b\x0b\x94\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x02\x41\x03\x41\x04\x41\x0a\x0d\x00\x11\x00\x00\x0b\x0b\x91\x80\x80\x80\x00\x01\x01\x7f\x02\x7f\x41\x11\x20\x00\x0d\x00\x21\x00\x41\x7f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x20\x00\x0d\x00\x22\x00\x41\x7f\x0f\x0b\x0b\x90\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x20\x00\x0d\x00\x24\x00\x41\x7f\x0f\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0d\x00\x28\x02\x00\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x1e\x41\x01\x0d\x00\x2c\x00\x00\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x1e\x41\x01\x0d\x00\x41\x07\x36\x02\x00\x41\x7f\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x1f\x41\x01\x0d\x00\x36\x02\x00\x41\x7f\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x20\x41\x01\x0d\x00\x41\x07\x3a\x00\x00\x41\x7f\x0b\x0b\x92\x80\x80\x80\x00\x00\x02\x7f\x41\x02\x41\x21\x41\x01\x0d\x00\x3b\x01\x00\x41\x7f\x0b\x0b\x93\x80\x80\x80\x00\x00\x02\x7c\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\x41\x01\x0d\x00\x9a\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0d\x00\x41\x0a\x6a\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x01\x0d\x00\x6b\x0b\x0b\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x41\x01\x0d\x00\x45\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0d\x00\x41\x0a\x4d\x0b\x0b\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x0a\x41\x01\x41\x2a\x0d\x00\x47\x0b\x0b\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x41\x01\x0d\x00\x40\x00\x0b\x0b\x9a\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x10\x0b\x6a\x0b\x6a\x0b\x9b\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x04\x0b\x0c\x00\x41\x10\x0b\x6a\x0b\x9e\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x04\x0b\x41\x01\x0d\x00\x1a\x41\x10\x0b\x6a\x0b\x9e\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x01\x0b\x0d\x00\x1a\x41\x10\x0b\x6a\x0b\x9e\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x04\x0b\x41\x01\x0e\x00\x00\x41\x10\x0b\x6a\x0b\x9e\x80\x80\x80\x00\x00\x41\x01\x02\x7f\x41\x02\x1a\x41\x04\x02\x7f\x41\x08\x20\x00\x0d\x01\x1a\x41\x01\x0b\x0e\x00\x00\x41\x10\x0b\x6a\x0b"); + +// br_if.wast:372 +assert_return(() => call($1, "type-i32", [])); + +// br_if.wast:373 +assert_return(() => call($1, "type-i64", [])); + +// br_if.wast:374 +assert_return(() => call($1, "type-f32", [])); + +// br_if.wast:375 +assert_return(() => call($1, "type-f64", [])); + +// br_if.wast:377 +assert_return(() => call($1, "type-i32-value", []), 1); + +// br_if.wast:378 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x69\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-i64-value", []), int64("2")) + +// br_if.wast:379 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x33\x32\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x40\x40\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f32-value", []), 3.) + +// br_if.wast:380 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x95\x80\x80\x80\x00\x01\x02\x24\x31\x0e\x74\x79\x70\x65\x2d\x66\x36\x34\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x10\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "type-f64-value", []), 4.) + +// br_if.wast:382 +assert_return(() => call($1, "as-block-first", [0]), 2); + +// br_if.wast:383 +assert_return(() => call($1, "as-block-first", [1]), 3); + +// br_if.wast:384 +assert_return(() => call($1, "as-block-mid", [0]), 2); + +// br_if.wast:385 +assert_return(() => call($1, "as-block-mid", [1]), 3); + +// br_if.wast:386 +assert_return(() => call($1, "as-block-last", [0])); + +// br_if.wast:387 +assert_return(() => call($1, "as-block-last", [1])); + +// br_if.wast:389 +assert_return(() => call($1, "as-block-first-value", [0]), 11); + +// br_if.wast:390 +assert_return(() => call($1, "as-block-first-value", [1]), 10); + +// br_if.wast:391 +assert_return(() => call($1, "as-block-mid-value", [0]), 21); + +// br_if.wast:392 +assert_return(() => call($1, "as-block-mid-value", [1]), 20); + +// br_if.wast:393 +assert_return(() => call($1, "as-block-last-value", [0]), 11); + +// br_if.wast:394 +assert_return(() => call($1, "as-block-last-value", [1]), 11); + +// br_if.wast:396 +assert_return(() => call($1, "as-loop-first", [0]), 2); + +// br_if.wast:397 +assert_return(() => call($1, "as-loop-first", [1]), 3); + +// br_if.wast:398 +assert_return(() => call($1, "as-loop-mid", [0]), 2); + +// br_if.wast:399 +assert_return(() => call($1, "as-loop-mid", [1]), 4); + +// br_if.wast:400 +assert_return(() => call($1, "as-loop-last", [0])); + +// br_if.wast:401 +assert_return(() => call($1, "as-loop-last", [1])); + +// br_if.wast:403 +assert_return(() => call($1, "as-br-value", []), 1); + +// br_if.wast:405 +assert_return(() => call($1, "as-br_if-cond", [])); + +// br_if.wast:406 +assert_return(() => call($1, "as-br_if-value", []), 1); + +// br_if.wast:407 +assert_return(() => call($1, "as-br_if-value-cond", [0]), 2); + +// br_if.wast:408 +assert_return(() => call($1, "as-br_if-value-cond", [1]), 1); + +// br_if.wast:410 +assert_return(() => call($1, "as-br_table-index", [])); + +// br_if.wast:411 +assert_return(() => call($1, "as-br_table-value", []), 1); + +// br_if.wast:412 +assert_return(() => call($1, "as-br_table-value-index", []), 1); + +// br_if.wast:414 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x96\x80\x80\x80\x00\x01\x02\x24\x31\x0f\x61\x73\x2d\x72\x65\x74\x75\x72\x6e\x2d\x76\x61\x6c\x75\x65\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-return-value", []), int64("1")) + +// br_if.wast:416 +assert_return(() => call($1, "as-if-cond", [0]), 2); + +// br_if.wast:417 +assert_return(() => call($1, "as-if-cond", [1]), 1); + +// br_if.wast:418 +assert_return(() => call($1, "as-if-then", [0, 0])); + +// br_if.wast:419 +assert_return(() => call($1, "as-if-then", [4, 0])); + +// br_if.wast:420 +assert_return(() => call($1, "as-if-then", [0, 1])); + +// br_if.wast:421 +assert_return(() => call($1, "as-if-then", [4, 1])); + +// br_if.wast:422 +assert_return(() => call($1, "as-if-else", [0, 0])); + +// br_if.wast:423 +assert_return(() => call($1, "as-if-else", [3, 0])); + +// br_if.wast:424 +assert_return(() => call($1, "as-if-else", [0, 1])); + +// br_if.wast:425 +assert_return(() => call($1, "as-if-else", [3, 1])); + +// br_if.wast:427 +assert_return(() => call($1, "as-select-first", [0]), 3); + +// br_if.wast:428 +assert_return(() => call($1, "as-select-first", [1]), 3); + +// br_if.wast:429 +assert_return(() => call($1, "as-select-second", [0]), 3); + +// br_if.wast:430 +assert_return(() => call($1, "as-select-second", [1]), 3); + +// br_if.wast:431 +assert_return(() => call($1, "as-select-cond", []), 3); + +// br_if.wast:433 +assert_return(() => call($1, "as-call-first", []), 12); + +// br_if.wast:434 +assert_return(() => call($1, "as-call-mid", []), 13); + +// br_if.wast:435 +assert_return(() => call($1, "as-call-last", []), 14); + +// br_if.wast:437 +assert_return(() => call($1, "as-call_indirect-func", []), 4); + +// br_if.wast:438 +assert_return(() => call($1, "as-call_indirect-first", []), 4); + +// br_if.wast:439 +assert_return(() => call($1, "as-call_indirect-mid", []), 4); + +// br_if.wast:440 +assert_return(() => call($1, "as-call_indirect-last", []), 4); + +// br_if.wast:442 +assert_return(() => call($1, "as-local.set-value", [0]), -1); + +// br_if.wast:443 +assert_return(() => call($1, "as-local.set-value", [1]), 17); + +// br_if.wast:445 +assert_return(() => call($1, "as-local.tee-value", [0]), -1); + +// br_if.wast:446 +assert_return(() => call($1, "as-local.tee-value", [1]), 1); + +// br_if.wast:448 +assert_return(() => call($1, "as-global.set-value", [0]), -1); + +// br_if.wast:449 +assert_return(() => call($1, "as-global.set-value", [1]), 1); + +// br_if.wast:451 +assert_return(() => call($1, "as-load-address", []), 1); + +// br_if.wast:452 +assert_return(() => call($1, "as-loadN-address", []), 30); + +// br_if.wast:454 +assert_return(() => call($1, "as-store-address", []), 30); + +// br_if.wast:455 +assert_return(() => call($1, "as-store-value", []), 31); + +// br_if.wast:456 +assert_return(() => call($1, "as-storeN-address", []), 32); + +// br_if.wast:457 +assert_return(() => call($1, "as-storeN-value", []), 33); + +// br_if.wast:459 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x97\x80\x80\x80\x00\x01\x02\x24\x31\x10\x61\x73\x2d\x75\x6e\x61\x72\x79\x2d\x6f\x70\x65\x72\x61\x6e\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf0\x3f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "as-unary-operand", []), 1.) + +// br_if.wast:460 +assert_return(() => call($1, "as-binary-left", []), 1); + +// br_if.wast:461 +assert_return(() => call($1, "as-binary-right", []), 1); + +// br_if.wast:462 +assert_return(() => call($1, "as-test-operand", []), 0); + +// br_if.wast:463 +assert_return(() => call($1, "as-compare-left", []), 1); + +// br_if.wast:464 +assert_return(() => call($1, "as-compare-right", []), 1); + +// br_if.wast:465 +assert_return(() => call($1, "as-memory.grow-size", []), 1); + +// br_if.wast:467 +assert_return(() => call($1, "nested-block-value", [0]), 21); + +// br_if.wast:468 +assert_return(() => call($1, "nested-block-value", [1]), 9); + +// br_if.wast:469 +assert_return(() => call($1, "nested-br-value", [0]), 5); + +// br_if.wast:470 +assert_return(() => call($1, "nested-br-value", [1]), 9); + +// br_if.wast:471 +assert_return(() => call($1, "nested-br_if-value", [0]), 5); + +// br_if.wast:472 +assert_return(() => call($1, "nested-br_if-value", [1]), 9); + +// br_if.wast:473 +assert_return(() => call($1, "nested-br_if-value-cond", [0]), 5); + +// br_if.wast:474 +assert_return(() => call($1, "nested-br_if-value-cond", [1]), 9); + +// br_if.wast:475 +assert_return(() => call($1, "nested-br_table-value", [0]), 5); + +// br_if.wast:476 +assert_return(() => call($1, "nested-br_table-value", [1]), 9); + +// br_if.wast:477 +assert_return(() => call($1, "nested-br_table-value-index", [0]), 5); + +// br_if.wast:478 +assert_return(() => call($1, "nested-br_table-value-index", [1]), 9); + +// br_if.wast:480 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0d\x00\x68\x0b\x0b"); + +// br_if.wast:484 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0d\x00\x7a\x0b\x0b"); + +// br_if.wast:488 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0d\x00\x8c\x0b\x0b"); + +// br_if.wast:492 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x0d\x00\x9a\x0b\x0b"); + +// br_if.wast:497 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x01\x0d\x00\x68\x0b\x0b"); + +// br_if.wast:501 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x01\x0d\x00\x7a\x0b\x0b"); + +// br_if.wast:505 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x40\x43\x00\x00\x80\x3f\x0d\x00\x8c\x0b\x0b"); + +// br_if.wast:509 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x40\x42\x01\x0d\x00\x9a\x0b\x0b"); + +// br_if.wast:514 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:520 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:526 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x0d\x00\x0b\x0b"); + +// br_if.wast:532 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x91\x80\x80\x80\x00\x01\x8b\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x01\x0d\x00\x0b\x0b"); + +// br_if.wast:539 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x01\x41\x00\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:545 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x01\x41\x01\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:551 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x41\x00\x0d\x00\x1a\x41\x01\x0b\x0b"); + +// br_if.wast:559 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x42\x01\x41\x00\x0d\x00\x1a\x41\x01\x0b\x0b"); + +// br_if.wast:568 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x02\x40\x0d\x00\x0b\x0b"); + +// br_if.wast:574 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x40\x01\x0d\x00\x0b\x0b"); + +// br_if.wast:580 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x40\x42\x00\x0d\x00\x0b\x0b"); + +// br_if.wast:586 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x01\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:592 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x94\x80\x80\x80\x00\x01\x8e\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x02\x40\x41\x01\x0d\x01\x0b\x0b\x0b"); + +// br_if.wast:598 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x93\x80\x80\x80\x00\x01\x8d\x80\x80\x80\x00\x00\x02\x7f\x41\x00\x42\x00\x0d\x00\x41\x01\x0b\x0b"); + +// br_if.wast:605 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x96\x80\x80\x80\x00\x01\x90\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x04\x7f\x0d\x00\x0b\x0b\x45\x1a\x0b"); + +// br_if.wast:617 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x98\x80\x80\x80\x00\x01\x92\x80\x80\x80\x00\x00\x02\x40\x41\x00\x41\x00\x04\x7f\x41\x01\x0d\x00\x0b\x0b\x45\x1a\x0b"); + +// br_if.wast:629 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x02\x7f\x0d\x00\x0f\x0b\x45\x1a\x0b"); + +// br_if.wast:640 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x7f\x41\x01\x0d\x00\x0f\x0b\x45\x1a\x0b"); + +// br_if.wast:653 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8c\x80\x80\x80\x00\x01\x86\x80\x80\x80\x00\x00\x41\x01\x0d\x01\x0b"); + +// br_if.wast:657 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x02\x40\x02\x40\x41\x01\x0d\x05\x0b\x0b\x0b"); + +// br_if.wast:661 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x90\x80\x80\x80\x00\x01\x8a\x80\x80\x80\x00\x00\x41\x01\x0d\x81\x80\x80\x80\x01\x0b"); diff --git a/js/src/jit-test/tests/wasm/spec/break-drop.wast.js b/js/src/jit-test/tests/wasm/spec/threads/break-drop.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/break-drop.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/break-drop.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/call.wast.js b/js/src/jit-test/tests/wasm/spec/threads/call.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/call.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/call.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/call_indirect.wast.js b/js/src/jit-test/tests/wasm/spec/threads/call_indirect.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/call_indirect.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/call_indirect.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/const.wast.js b/js/src/jit-test/tests/wasm/spec/threads/const.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/const.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/const.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/conversions.wast.js b/js/src/jit-test/tests/wasm/spec/threads/conversions.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/conversions.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/conversions.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/custom.wast.js b/js/src/jit-test/tests/wasm/spec/threads/custom.wast.js new file mode 100644 index 0000000000..35531a06bf --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/custom.wast.js @@ -0,0 +1,30 @@ + +// custom.wast:1 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x20\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x11\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x00\x10\x00\x74\x68\x69\x73\x20\x69\x73\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x01\x00\x00\x24\x10\x00\x00\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x00\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\xef\xbb\xbf\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\xe2\x8c\xa3\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x1f\x16\x6d\x6f\x64\x75\x6c\x65\x20\x77\x69\x74\x68\x69\x6e\x20\x61\x20\x6d\x6f\x64\x75\x6c\x65\x00\x61\x73\x6d\x01\x00\x00\x00"); + +// custom.wast:14 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x01\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x02\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x03\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x04\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x05\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x06\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x07\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x09\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0a\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x0b\x01\x00\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64\x00\x0e\x06\x63\x75\x73\x74\x6f\x6d\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:50 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x1a\x06\x63\x75\x73\x74\x6f\x6d\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x07\x0a\x01\x06\x61\x64\x64\x54\x77\x6f\x00\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:60 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00"); + +// custom.wast:68 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00"); + +// custom.wast:76 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x00\x00\x05\x01\x00\x07\x00\x00"); + +// custom.wast:84 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x26\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:92 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x00\x24\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:101 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x07\x01\x60\x02\x7f\x7f\x01\x7f\x00\x25\x10\x61\x20\x63\x75\x73\x74\x6f\x6d\x20\x73\x65\x63\x74\x69\x6f\x6e\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64\x03\x02\x01\x00\x0a\x09\x01\x07\x00\x20\x00\x20\x01\x6a\x0b\x00\x1b\x07\x63\x75\x73\x74\x6f\x6d\x32\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x70\x61\x79\x6c\x6f\x61\x64"); + +// custom.wast:114 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x00\x61\x73\x6d\x01\x00\x00\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/threads/directives.txt b/js/src/jit-test/tests/wasm/spec/threads/directives.txt new file mode 100644 index 0000000000..0f72ff4191 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=ion; test-also=--wasm-compiler=baseline; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemoryIsSupported(); include:wasm-testharness.js; local-include:harness/sync_index.js; skip-if: !wasmThreadsSupported() \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/fac.wast.js b/js/src/jit-test/tests/wasm/spec/threads/fac.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/fac.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/fac.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/float_memory.wast.js b/js/src/jit-test/tests/wasm/spec/threads/float_memory.wast.js new file mode 100644 index 0000000000..33c3b1d9cd --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/float_memory.wast.js @@ -0,0 +1,270 @@ + +// float_memory.wast:5 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7d\x60\x00\x01\x7f\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xca\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x00\x2a\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x28\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\xa0\x7f\x38\x02\x00\x0b\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x80\x80\x80\xfd\x07\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x41\x00\x36\x02\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x04\x00\x00\xa0\x7f"); + +// float_memory.wast:15 +assert_return(() => call($1, "i32.load", []), 2_141_192_192); + +// float_memory.wast:16 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.load", []), NaN) + +// float_memory.wast:17 +run(() => call($1, "reset", [])); + +// float_memory.wast:18 +assert_return(() => call($1, "i32.load", []), 0); + +// float_memory.wast:19 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.load", []), 0.) + +// float_memory.wast:20 +run(() => call($1, "f32.store", [])); + +// float_memory.wast:21 +assert_return(() => call($1, "i32.load", []), 2_141_192_192); + +// float_memory.wast:22 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.load", []), NaN) + +// float_memory.wast:23 +run(() => call($1, "reset", [])); + +// float_memory.wast:24 +assert_return(() => call($1, "i32.load", []), 0); + +// float_memory.wast:25 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.load", []), 0.) + +// float_memory.wast:26 +run(() => call($1, "i32.store", [])); + +// float_memory.wast:27 +assert_return(() => call($1, "i32.load", []), 2_141_192_192); + +// float_memory.wast:28 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x31\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$1", $1)), "run", [])); // assert_return(() => call($1, "f32.load", []), NaN) + +// float_memory.wast:30 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7c\x60\x00\x01\x7e\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xd3\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x00\x2b\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x29\x03\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x00\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x39\x03\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x00\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x37\x03\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x42\x00\x37\x03\x00\x0b\x0b\x8e\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x08\x00\x00\x00\x00\x00\x00\xf4\x7f"); + +// float_memory.wast:40 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:41 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "f64.load", []), NaN) + +// float_memory.wast:42 +run(() => call($2, "reset", [])); + +// float_memory.wast:43 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "i64.load", []), int64("0")) + +// float_memory.wast:44 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "f64.load", []), 0.) + +// float_memory.wast:45 +run(() => call($2, "f64.store", [])); + +// float_memory.wast:46 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:47 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "f64.load", []), NaN) + +// float_memory.wast:48 +run(() => call($2, "reset", [])); + +// float_memory.wast:49 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "i64.load", []), int64("0")) + +// float_memory.wast:50 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "f64.load", []), 0.) + +// float_memory.wast:51 +run(() => call($2, "i64.store", [])); + +// float_memory.wast:52 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:53 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x32\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$2", $2)), "run", [])); // assert_return(() => call($2, "f64.load", []), NaN) + +// float_memory.wast:57 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7d\x60\x00\x01\x7f\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xca\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x01\x2a\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x01\x28\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x01\x43\x00\x00\xa0\x7f\x38\x02\x00\x0b\x8d\x80\x80\x80\x00\x00\x41\x01\x41\x80\x80\x80\xfd\x07\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x01\x41\x00\x36\x02\x00\x0b\x0b\x8b\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x05\x00\x00\x00\xa0\x7f"); + +// float_memory.wast:67 +assert_return(() => call($3, "i32.load", []), 2_141_192_192); + +// float_memory.wast:68 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "f32.load", []), NaN) + +// float_memory.wast:69 +run(() => call($3, "reset", [])); + +// float_memory.wast:70 +assert_return(() => call($3, "i32.load", []), 0); + +// float_memory.wast:71 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "f32.load", []), 0.) + +// float_memory.wast:72 +run(() => call($3, "f32.store", [])); + +// float_memory.wast:73 +assert_return(() => call($3, "i32.load", []), 2_141_192_192); + +// float_memory.wast:74 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "f32.load", []), NaN) + +// float_memory.wast:75 +run(() => call($3, "reset", [])); + +// float_memory.wast:76 +assert_return(() => call($3, "i32.load", []), 0); + +// float_memory.wast:77 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "f32.load", []), 0.) + +// float_memory.wast:78 +run(() => call($3, "i32.store", [])); + +// float_memory.wast:79 +assert_return(() => call($3, "i32.load", []), 2_141_192_192); + +// float_memory.wast:80 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x33\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\xa0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$3", $3)), "run", [])); // assert_return(() => call($3, "f32.load", []), NaN) + +// float_memory.wast:82 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7c\x60\x00\x01\x7e\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xd3\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x01\x2b\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x01\x29\x03\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x01\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\x39\x03\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x37\x03\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x01\x42\x00\x37\x03\x00\x0b\x0b\x8f\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x09\x00\x00\x00\x00\x00\x00\x00\xf4\x7f"); + +// float_memory.wast:92 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:93 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "f64.load", []), NaN) + +// float_memory.wast:94 +run(() => call($4, "reset", [])); + +// float_memory.wast:95 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "i64.load", []), int64("0")) + +// float_memory.wast:96 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "f64.load", []), 0.) + +// float_memory.wast:97 +run(() => call($4, "f64.store", [])); + +// float_memory.wast:98 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:99 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "f64.load", []), NaN) + +// float_memory.wast:100 +run(() => call($4, "reset", [])); + +// float_memory.wast:101 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "i64.load", []), int64("0")) + +// float_memory.wast:102 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "f64.load", []), 0.) + +// float_memory.wast:103 +run(() => call($4, "i64.store", [])); + +// float_memory.wast:104 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x80\x80\x80\x80\x80\x80\x80\xfa\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "i64.load", []), int64("9_219_994_337_134_247_936")) + +// float_memory.wast:105 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x34\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\xf4\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$4", $4)), "run", [])); // assert_return(() => call($4, "f64.load", []), NaN) + +// float_memory.wast:109 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7d\x60\x00\x01\x7f\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x33\x32\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xca\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x00\x2a\x02\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x28\x02\x00\x0b\x8c\x80\x80\x80\x00\x00\x41\x00\x43\x01\x00\xd0\x7f\x38\x02\x00\x0b\x8d\x80\x80\x80\x00\x00\x41\x00\x41\x81\x80\xc0\xfe\x07\x36\x02\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x41\x00\x36\x02\x00\x0b\x0b\x8a\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x04\x01\x00\xd0\x7f"); + +// float_memory.wast:119 +assert_return(() => call($5, "i32.load", []), 2_144_337_921); + +// float_memory.wast:120 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x35\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\xd0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$5", $5)), "run", [])); // assert_return(() => call($5, "f32.load", []), NaN) + +// float_memory.wast:121 +run(() => call($5, "reset", [])); + +// float_memory.wast:122 +assert_return(() => call($5, "i32.load", []), 0); + +// float_memory.wast:123 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x35\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$5", $5)), "run", [])); // assert_return(() => call($5, "f32.load", []), 0.) + +// float_memory.wast:124 +run(() => call($5, "f32.store", [])); + +// float_memory.wast:125 +assert_return(() => call($5, "i32.load", []), 2_144_337_921); + +// float_memory.wast:126 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x35\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\xd0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$5", $5)), "run", [])); // assert_return(() => call($5, "f32.load", []), NaN) + +// float_memory.wast:127 +run(() => call($5, "reset", [])); + +// float_memory.wast:128 +assert_return(() => call($5, "i32.load", []), 0); + +// float_memory.wast:129 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x35\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x00\x00\x00\x00\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$5", $5)), "run", [])); // assert_return(() => call($5, "f32.load", []), 0.) + +// float_memory.wast:130 +run(() => call($5, "i32.store", [])); + +// float_memory.wast:131 +assert_return(() => call($5, "i32.load", []), 2_144_337_921); + +// float_memory.wast:132 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7d\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x35\x08\x66\x33\x32\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbc\x43\x01\x00\xd0\x7f\xbc\x46\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$5", $5)), "run", [])); // assert_return(() => call($5, "f32.load", []), NaN) + +// float_memory.wast:134 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8c\x80\x80\x80\x00\x03\x60\x00\x01\x7c\x60\x00\x01\x7e\x60\x00\x00\x03\x86\x80\x80\x80\x00\x05\x00\x01\x02\x02\x02\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\xb7\x80\x80\x80\x00\x05\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x00\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x09\x66\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x02\x09\x69\x36\x34\x2e\x73\x74\x6f\x72\x65\x00\x03\x05\x72\x65\x73\x65\x74\x00\x04\x0a\xd3\x80\x80\x80\x00\x05\x87\x80\x80\x80\x00\x00\x41\x00\x2b\x03\x00\x0b\x87\x80\x80\x80\x00\x00\x41\x00\x29\x03\x00\x0b\x90\x80\x80\x80\x00\x00\x41\x00\x44\x01\x00\x00\x00\x00\x00\xfc\x7f\x39\x03\x00\x0b\x92\x80\x80\x80\x00\x00\x41\x00\x42\x81\x80\x80\x80\x80\x80\x80\xfe\xff\x00\x37\x03\x00\x0b\x89\x80\x80\x80\x00\x00\x41\x00\x42\x00\x37\x03\x00\x0b\x0b\x8e\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x08\x01\x00\x00\x00\x00\x00\xfc\x7f"); + +// float_memory.wast:144 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x81\x80\x80\x80\x80\x80\x80\xfe\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "i64.load", []), int64("9_222_246_136_947_933_185")) + +// float_memory.wast:145 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xfc\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "f64.load", []), NaN) + +// float_memory.wast:146 +run(() => call($6, "reset", [])); + +// float_memory.wast:147 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "i64.load", []), int64("0")) + +// float_memory.wast:148 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "f64.load", []), 0.) + +// float_memory.wast:149 +run(() => call($6, "f64.store", [])); + +// float_memory.wast:150 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x81\x80\x80\x80\x80\x80\x80\xfe\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "i64.load", []), int64("9_222_246_136_947_933_185")) + +// float_memory.wast:151 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xfc\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "f64.load", []), NaN) + +// float_memory.wast:152 +run(() => call($6, "reset", [])); + +// float_memory.wast:153 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x97\x80\x80\x80\x00\x01\x91\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "i64.load", []), int64("0")) + +// float_memory.wast:154 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "f64.load", []), 0.) + +// float_memory.wast:155 +run(() => call($6, "i64.store", [])); + +// float_memory.wast:156 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7e\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x69\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa0\x80\x80\x80\x00\x01\x9a\x80\x80\x80\x00\x00\x02\x40\x10\x00\x01\x42\x81\x80\x80\x80\x80\x80\x80\xfe\xff\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "i64.load", []), int64("9_222_246_136_947_933_185")) + +// float_memory.wast:157 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8f\x80\x80\x80\x00\x01\x02\x24\x36\x08\x66\x36\x34\x2e\x6c\x6f\x61\x64\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x01\x00\x00\x00\x00\x00\xfc\x7f\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$6", $6)), "run", [])); // assert_return(() => call($6, "f64.load", []), NaN) diff --git a/js/src/jit-test/tests/wasm/spec/harness/async_index.js b/js/src/jit-test/tests/wasm/spec/threads/harness/async_index.js similarity index 98% rename from js/src/jit-test/tests/wasm/spec/harness/async_index.js rename to js/src/jit-test/tests/wasm/spec/threads/harness/async_index.js index e7659b8378..cc252f50ea 100644 --- a/js/src/jit-test/tests/wasm/spec/harness/async_index.js +++ b/js/src/jit-test/tests/wasm/spec/threads/harness/async_index.js @@ -322,8 +322,8 @@ function assert_uninstantiable(bytes) { result => { uniqueTest(_ => { assert_true( - result instanceof WebAssembly.LinkError || result instanceof WebAssembly.RuntimeError, - `expected link or runtime error, observed ${result} ${loc}` + result instanceof WebAssembly.RuntimeError, + `expected link error, observed ${result} ${loc}` ); }, test); }, diff --git a/js/src/jit-test/tests/wasm/spec/threads/harness/directives.txt b/js/src/jit-test/tests/wasm/spec/threads/harness/directives.txt new file mode 100644 index 0000000000..d41243abbb --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/harness/directives.txt @@ -0,0 +1 @@ +|jit-test| skip-if: true \ No newline at end of file diff --git a/js/src/jit-test/tests/wasm/spec/harness/sync_index.js b/js/src/jit-test/tests/wasm/spec/threads/harness/sync_index.js similarity index 98% rename from js/src/jit-test/tests/wasm/spec/harness/sync_index.js rename to js/src/jit-test/tests/wasm/spec/threads/harness/sync_index.js index 67f6a84f67..bd57cc4818 100644 --- a/js/src/jit-test/tests/wasm/spec/harness/sync_index.js +++ b/js/src/jit-test/tests/wasm/spec/threads/harness/sync_index.js @@ -270,7 +270,7 @@ function assert_uninstantiable(bytes) { assert_true(result.isError(), 'expected error result'); if (result.isError()) { let e = result.value; - assert_true(e instanceof WebAssembly.LinkError || e instanceof WebAssembly.RuntimeError, `expected link or runtime error, observed ${e}:`); + assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); } }, "A wast module that is uninstantiable."); } diff --git a/js/src/jit-test/tests/wasm/spec/i32.wast.js b/js/src/jit-test/tests/wasm/spec/threads/i32.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/i32.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/i32.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/i64.wast.js b/js/src/jit-test/tests/wasm/spec/threads/i64.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/i64.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/i64.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/if.wast.js b/js/src/jit-test/tests/wasm/spec/threads/if.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/if.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/if.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/loop.wast.js b/js/src/jit-test/tests/wasm/spec/threads/loop.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/loop.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/loop.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/memory.wast.js b/js/src/jit-test/tests/wasm/spec/threads/memory.wast.js new file mode 100644 index 0000000000..68ece569f6 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/memory.wast.js @@ -0,0 +1,222 @@ + +// memory.wast:3 +let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00"); + +// memory.wast:4 +let $2 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x01"); + +// memory.wast:5 +let $3 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x01\x01\x80\x02"); + +// memory.wast:6 +let $4 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x80\x80\x04"); + +// memory.wast:7 +let $5 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x03\x00\x00"); + +// memory.wast:8 +let $6 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x03\x01\x02"); + +// memory.wast:10 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x83\x80\x80\x80\x00\x01\x02\x01"); + +// memory.wast:12 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x02\x00\x00\x00\x00"); + +// memory.wast:13 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x94\x80\x80\x80\x00\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x06\x6d\x65\x6d\x6f\x72\x79\x02\x00\x00\x05\x83\x80\x80\x80\x00\x01\x00\x00"); + +// memory.wast:15 +let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:16 +assert_return(() => call($7, "memsize", []), 0); + +// memory.wast:17 +let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x00\x00\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:18 +assert_return(() => call($8, "memsize", []), 0); + +// memory.wast:19 +let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x85\x80\x80\x80\x00\x01\x60\x00\x01\x7f\x03\x82\x80\x80\x80\x00\x01\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x01\x07\x8b\x80\x80\x80\x00\x01\x07\x6d\x65\x6d\x73\x69\x7a\x65\x00\x00\x0a\x8a\x80\x80\x80\x00\x01\x84\x80\x80\x80\x00\x00\x3f\x00\x0b\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); + +// memory.wast:20 +assert_return(() => call($9, "memsize", []), 1); + +// memory.wast:22 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:23 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x86\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x00"); + +// memory.wast:24 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x0b\x87\x80\x80\x80\x00\x01\x00\x41\x00\x0b\x01\x78"); + +// memory.wast:26 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2a\x02\x00\x1a\x0b"); + +// memory.wast:30 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x92\x80\x80\x80\x00\x01\x8c\x80\x80\x80\x00\x00\x41\x00\x43\x00\x00\x00\x00\x38\x02\x00\x0b"); + +// memory.wast:34 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x41\x00\x2c\x00\x00\x1a\x0b"); + +// memory.wast:38 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x41\x00\x41\x00\x3a\x00\x00\x0b"); + +// memory.wast:42 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8b\x80\x80\x80\x00\x01\x85\x80\x80\x80\x00\x00\x3f\x00\x1a\x0b"); + +// memory.wast:46 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8d\x80\x80\x80\x00\x01\x87\x80\x80\x80\x00\x00\x41\x00\x40\x00\x1a\x0b"); + +// memory.wast:52 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x84\x80\x80\x80\x00\x01\x01\x01\x00"); + +// memory.wast:56 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x85\x80\x80\x80\x00\x01\x00\x81\x80\x04"); + +// memory.wast:60 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\x80\x80\x80\x80\x08"); + +// memory.wast:64 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x87\x80\x80\x80\x00\x01\x00\xff\xff\xff\xff\x0f"); + +// memory.wast:68 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x86\x80\x80\x80\x00\x01\x01\x00\x81\x80\x04"); + +// memory.wast:72 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\x80\x80\x80\x80\x08"); + +// memory.wast:76 +assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x88\x80\x80\x80\x00\x01\x01\x00\xff\xff\xff\xff\x0f"); + +// memory.wast:81 +let $10 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x93\x80\x80\x80\x00\x04\x60\x00\x01\x7f\x60\x00\x01\x7c\x60\x01\x7f\x01\x7f\x60\x01\x7e\x01\x7e\x03\x8d\x80\x80\x80\x00\x0c\x00\x01\x02\x02\x02\x02\x03\x03\x03\x03\x03\x03\x05\x83\x80\x80\x80\x00\x01\x00\x01\x07\xa1\x81\x80\x80\x00\x0c\x04\x64\x61\x74\x61\x00\x00\x04\x63\x61\x73\x74\x00\x01\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x02\x0b\x69\x33\x32\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x03\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x04\x0c\x69\x33\x32\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x05\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x06\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x07\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x08\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x09\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x0a\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x0b\x0a\xcf\x82\x80\x80\x00\x0c\xce\x80\x80\x80\x00\x00\x41\x00\x2d\x00\x00\x41\xc1\x00\x46\x41\x03\x2d\x00\x00\x41\xa7\x01\x46\x71\x41\x06\x2d\x00\x00\x41\x00\x46\x41\x13\x2d\x00\x00\x41\x00\x46\x71\x71\x41\x14\x2d\x00\x00\x41\xd7\x00\x46\x41\x17\x2d\x00\x00\x41\xcd\x00\x46\x71\x41\x18\x2d\x00\x00\x41\x00\x46\x41\xff\x07\x2d\x00\x00\x41\x00\x46\x71\x71\x71\x0b\xb8\x80\x80\x80\x00\x00\x41\x08\x42\xc7\x9f\x7f\x37\x03\x00\x41\x08\x2b\x03\x00\x42\xc7\x9f\x7f\xbf\x61\x04\x40\x44\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0b\x41\x09\x42\x00\x37\x00\x00\x41\x0f\x41\xc5\x80\x01\x3b\x00\x00\x41\x09\x2b\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2c\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3a\x00\x00\x41\x08\x2d\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2e\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3b\x01\x00\x41\x08\x2f\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x30\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3c\x00\x00\x41\x08\x31\x00\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x32\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3d\x01\x00\x41\x08\x33\x01\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x34\x02\x00\x0b\x8e\x80\x80\x80\x00\x00\x41\x08\x20\x00\x3e\x02\x00\x41\x08\x35\x02\x00\x0b\x0b\x94\x80\x80\x80\x00\x02\x00\x41\x00\x0b\x05\x41\x42\x43\xa7\x44\x00\x41\x14\x0b\x04\x57\x41\x53\x4d"); + +// memory.wast:169 +assert_return(() => call($10, "data", []), 1); + +// memory.wast:170 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x88\x80\x80\x80\x00\x02\x60\x00\x00\x60\x00\x01\x7c\x02\x8c\x80\x80\x80\x00\x01\x03\x24\x31\x30\x04\x63\x61\x73\x74\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9e\x80\x80\x80\x00\x01\x98\x80\x80\x80\x00\x00\x02\x40\x10\x00\xbd\x44\x00\x00\x00\x00\x00\x00\x45\x40\xbd\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "cast", []), 42.) + +// memory.wast:172 +assert_return(() => call($10, "i32_load8_s", [-1]), -1); + +// memory.wast:173 +assert_return(() => call($10, "i32_load8_u", [-1]), 255); + +// memory.wast:174 +assert_return(() => call($10, "i32_load16_s", [-1]), -1); + +// memory.wast:175 +assert_return(() => call($10, "i32_load16_u", [-1]), 65_535); + +// memory.wast:177 +assert_return(() => call($10, "i32_load8_s", [100]), 100); + +// memory.wast:178 +assert_return(() => call($10, "i32_load8_u", [200]), 200); + +// memory.wast:179 +assert_return(() => call($10, "i32_load16_s", [20_000]), 20_000); + +// memory.wast:180 +assert_return(() => call($10, "i32_load16_u", [40_000]), 40_000); + +// memory.wast:182 +assert_return(() => call($10, "i32_load8_s", [-19_110_589]), 67); + +// memory.wast:183 +assert_return(() => call($10, "i32_load8_s", [878_104_047]), -17); + +// memory.wast:184 +assert_return(() => call($10, "i32_load8_u", [-19_110_589]), 67); + +// memory.wast:185 +assert_return(() => call($10, "i32_load8_u", [878_104_047]), 239); + +// memory.wast:186 +assert_return(() => call($10, "i32_load16_s", [-19_110_589]), 25_923); + +// memory.wast:187 +assert_return(() => call($10, "i32_load16_s", [878_104_047]), -12_817); + +// memory.wast:188 +assert_return(() => call($10, "i32_load16_u", [-19_110_589]), 25_923); + +// memory.wast:189 +assert_return(() => call($10, "i32_load16_u", [878_104_047]), 52_719); + +// memory.wast:191 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("-1")]), int64("-1")) + +// memory.wast:192 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9a\x80\x80\x80\x00\x01\x94\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("-1")]), int64("255")) + +// memory.wast:193 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("-1")]), int64("-1")) + +// memory.wast:194 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("-1")]), int64("65_535")) + +// memory.wast:195 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x99\x80\x80\x80\x00\x01\x93\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("-1")]), int64("-1")) + +// memory.wast:196 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\x7f\x10\x00\x01\x42\xff\xff\xff\xff\x0f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("-1")]), int64("4_294_967_295")) + +// memory.wast:198 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xe4\x00\x10\x00\x01\x42\xe4\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("100")]), int64("100")) + +// memory.wast:199 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9b\x80\x80\x80\x00\x01\x95\x80\x80\x80\x00\x00\x02\x40\x42\xc8\x01\x10\x00\x01\x42\xc8\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("200")]), int64("200")) + +// memory.wast:200 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("20_000")]), int64("20_000")) + +// memory.wast:201 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("40_000")]), int64("40_000")) + +// memory.wast:202 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xa0\x9c\x01\x10\x00\x01\x42\xa0\x9c\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("20_000")]), int64("20_000")) + +// memory.wast:203 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\x9d\x80\x80\x80\x00\x01\x97\x80\x80\x80\x00\x00\x02\x40\x42\xc0\xb8\x02\x10\x00\x01\x42\xc0\xb8\x02\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("40_000")]), int64("40_000")) + +// memory.wast:205 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("-81_985_529_755_441_853")]), int64("67")) + +// memory.wast:206 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa1\x80\x80\x80\x00\x01\x9b\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\x6f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_s", [int64("3_771_275_841_602_506_223")]), int64("-17")) + +// memory.wast:207 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\x00\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("-81_985_529_755_441_853")]), int64("67")) + +// memory.wast:208 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x93\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0b\x69\x36\x34\x5f\x6c\x6f\x61\x64\x38\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa2\x80\x80\x80\x00\x01\x9c\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load8_u", [int64("3_771_275_841_602_506_223")]), int64("239")) + +// memory.wast:209 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("-81_985_529_755_441_853")]), int64("25_923")) + +// memory.wast:210 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x7f\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_s", [int64("3_771_275_841_602_506_223")]), int64("-12_817")) + +// memory.wast:211 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\x01\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("-81_985_529_755_441_853")]), int64("25_923")) + +// memory.wast:212 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x31\x36\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa3\x80\x80\x80\x00\x01\x9d\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\x03\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load16_u", [int64("3_771_275_841_602_506_223")]), int64("52_719")) + +// memory.wast:213 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) + +// memory.wast:214 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x73\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x79\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_s", [int64("3_771_275_841_602_506_223")]), int64("-1_732_588_049")) + +// memory.wast:215 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xc3\xca\xd1\xb1\x85\xd3\xae\xee\x7e\x10\x00\x01\x42\xc3\xca\xd1\xb1\x05\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("-81_985_529_755_441_853")]), int64("1_446_274_371")) + +// memory.wast:216 +run(() => call(instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x60\x00\x00\x60\x01\x7e\x01\x7e\x02\x94\x80\x80\x80\x00\x01\x03\x24\x31\x30\x0c\x69\x36\x34\x5f\x6c\x6f\x61\x64\x33\x32\x5f\x75\x00\x01\x03\x82\x80\x80\x80\x00\x01\x00\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x01\x0a\xa5\x80\x80\x80\x00\x01\x9f\x80\x80\x80\x00\x00\x02\x40\x42\xef\x9b\xeb\xc5\xd9\xec\x90\xab\x34\x10\x00\x01\x42\xef\x9b\xeb\xc5\x09\x01\x51\x45\x0d\x00\x0f\x0b\x00\x0b", exports("$10", $10)), "run", [])); // assert_return(() => call($10, "i64_load32_u", [int64("3_771_275_841_602_506_223")]), int64("2_562_379_247")) diff --git a/js/src/jit-test/tests/wasm/spec/stack.wast.js b/js/src/jit-test/tests/wasm/spec/threads/stack.wast.js similarity index 100% rename from js/src/jit-test/tests/wasm/spec/stack.wast.js rename to js/src/jit-test/tests/wasm/spec/threads/stack.wast.js diff --git a/js/src/jit-test/tests/wasm/spec/threads/utf8-import-field.wast.js b/js/src/jit-test/tests/wasm/spec/threads/utf8-import-field.wast.js new file mode 100644 index 0000000000..0ece6b792c --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/utf8-import-field.wast.js @@ -0,0 +1,528 @@ + +// utf8-import-field.wast:6 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:21 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\x8f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:36 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:51 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\x9f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:66 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:81 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:98 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xc2\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:113 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xc2\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:128 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc2\x2e\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:145 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:160 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc0\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:175 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc1\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:190 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc1\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:205 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc2\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:220 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc2\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:235 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc2\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:250 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xc2\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:265 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xdf\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:280 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xdf\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:295 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xdf\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:310 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xdf\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:327 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xe1\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:342 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xe1\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:357 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x80\x2e\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:372 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xe1\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:387 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xe1\x2e\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:404 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x00\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:419 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x7f\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:434 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:449 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x80\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:464 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x9f\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:479 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\x9f\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:494 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xc0\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:509 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xfd\xa0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:524 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:539 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:554 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:569 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:584 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:599 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:614 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:629 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:644 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:659 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:674 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xa0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:689 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xa0\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:704 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xbf\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:719 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xbf\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:734 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:749 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:764 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:779 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:794 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:809 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:824 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:839 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:854 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:869 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:886 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xa0\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:901 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xa0\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:916 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xa0\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:931 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe0\xa0\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:946 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:961 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:976 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:991 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xe1\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1006 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1021 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1036 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1051 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xec\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1066 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1081 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1096 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1111 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xed\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1126 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1141 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1156 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1171 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xee\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1186 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1201 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1216 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1231 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xef\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1248 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xf1\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1263 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xf1\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1278 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1293 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xf1\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1308 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xf1\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1323 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xf1\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1338 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xf1\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1355 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x00\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1370 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x7f\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1385 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1400 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x80\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1415 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x8f\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1430 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x8f\xbf\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1445 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\xc0\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1460 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\xfd\x90\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1475 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x00\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1490 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x7f\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1505 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\xc0\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1520 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\xfd\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1535 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x00\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1550 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x7f\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1565 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\xc0\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1580 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\xfd\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1595 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x00\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1610 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x7f\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1625 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x90\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1640 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\xbf\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1655 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\xc0\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1670 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\xfd\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1685 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf5\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1700 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf7\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1715 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf7\xbf\xbf\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1732 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x00\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1747 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x7f\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1762 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\xc0\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1777 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\xfd\x90\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1792 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1807 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1822 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1837 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1852 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1867 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1882 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1897 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1912 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x00\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1927 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x7f\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1942 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\xc0\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1957 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\xfd\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1974 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x90\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:1989 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x90\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2004 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x90\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2019 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf0\x90\x90\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2034 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2049 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2064 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2079 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf1\x80\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2094 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2109 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2124 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2139 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf3\x80\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2154 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x80\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2169 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x80\x7f\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2184 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x80\xc0\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2199 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf4\x80\x80\xfd\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2216 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x06\xf8\x80\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2231 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf8\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2246 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xf8\x80\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2261 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xf8\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2276 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xf8\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2291 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xf8\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2306 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xf8\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2321 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xf8\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2336 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xf8\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2353 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xf8\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2368 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xfb\xbf\xbf\xbf\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2385 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x11\x01\x07\xfc\x80\x80\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2400 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xfc\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2415 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x06\xfc\x80\x80\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2430 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xfc\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2445 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x05\xfc\x80\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2460 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xfc\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2475 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xfc\x80\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2490 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xfc\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2505 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x03\xfc\x80\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2520 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xfc\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2535 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xfc\x23\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2552 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x06\xfc\x80\x80\x80\x80\x80\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2567 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x06\xfd\xbf\xbf\xbf\xbf\xbf\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2584 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xfe\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2599 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x01\xff\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2614 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xfe\xff\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2629 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x00\x00\xfe\xff\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2644 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x02\xff\xfe\x04\x74\x65\x73\x74\x03\x7f\x00"); + +// utf8-import-field.wast:2659 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\xff\xfe\x00\x00\x04\x74\x65\x73\x74\x03\x7f\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/threads/utf8-import-module.wast.js b/js/src/jit-test/tests/wasm/spec/threads/utf8-import-module.wast.js new file mode 100644 index 0000000000..4e3a15b132 --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/utf8-import-module.wast.js @@ -0,0 +1,528 @@ + +// utf8-import-module.wast:6 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\x80\x03\x7f\x00"); + +// utf8-import-module.wast:21 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\x8f\x03\x7f\x00"); + +// utf8-import-module.wast:36 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\x90\x03\x7f\x00"); + +// utf8-import-module.wast:51 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\x9f\x03\x7f\x00"); + +// utf8-import-module.wast:66 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:81 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:98 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xc2\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:113 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xc2\x03\x7f\x00"); + +// utf8-import-module.wast:128 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc2\x2e\x03\x7f\x00"); + +// utf8-import-module.wast:145 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:160 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc0\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:175 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc1\x80\x03\x7f\x00"); + +// utf8-import-module.wast:190 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc1\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:205 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc2\x00\x03\x7f\x00"); + +// utf8-import-module.wast:220 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc2\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:235 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc2\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:250 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xc2\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:265 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xdf\x00\x03\x7f\x00"); + +// utf8-import-module.wast:280 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xdf\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:295 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xdf\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:310 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xdf\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:327 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xe1\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:342 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xe1\x80\x03\x7f\x00"); + +// utf8-import-module.wast:357 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x80\x2e\x03\x7f\x00"); + +// utf8-import-module.wast:372 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xe1\x03\x7f\x00"); + +// utf8-import-module.wast:387 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xe1\x2e\x03\x7f\x00"); + +// utf8-import-module.wast:404 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x00\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:419 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x7f\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:434 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:449 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x80\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:464 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x9f\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:479 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\x9f\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:494 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xc0\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:509 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xfd\xa0\x03\x7f\x00"); + +// utf8-import-module.wast:524 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:539 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:554 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:569 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:584 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:599 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:614 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:629 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:644 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:659 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:674 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xa0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:689 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xa0\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:704 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xbf\x80\x03\x7f\x00"); + +// utf8-import-module.wast:719 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xbf\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:734 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:749 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:764 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:779 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:794 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:809 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:824 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:839 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:854 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:869 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:886 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xa0\x00\x03\x7f\x00"); + +// utf8-import-module.wast:901 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xa0\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:916 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xa0\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:931 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe0\xa0\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:946 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:961 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:976 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:991 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xe1\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:1006 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:1021 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:1036 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:1051 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xec\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:1066 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:1081 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:1096 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:1111 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xed\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:1126 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:1141 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:1156 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:1171 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xee\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:1186 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:1201 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:1216 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:1231 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xef\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:1248 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xf1\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1263 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xf1\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1278 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:1293 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xf1\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1308 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xf1\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:1323 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xf1\x03\x7f\x00"); + +// utf8-import-module.wast:1338 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xf1\x23\x03\x7f\x00"); + +// utf8-import-module.wast:1355 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x00\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1370 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x7f\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1385 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1400 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x80\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1415 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x8f\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1430 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x8f\xbf\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:1445 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\xc0\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1460 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\xfd\x90\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1475 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x00\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1490 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x7f\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1505 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\xc0\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1520 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\xfd\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1535 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x00\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1550 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x7f\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1565 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\xc0\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1580 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\xfd\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1595 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x00\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1610 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x7f\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1625 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x90\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1640 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\xbf\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1655 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\xc0\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1670 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\xfd\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1685 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf5\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1700 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf7\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1715 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf7\xbf\xbf\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:1732 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x00\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1747 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x7f\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1762 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\xc0\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1777 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\xfd\x90\x03\x7f\x00"); + +// utf8-import-module.wast:1792 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1807 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1822 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1837 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1852 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1867 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1882 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1897 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1912 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x00\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1927 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x7f\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1942 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\xc0\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1957 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\xfd\x80\x03\x7f\x00"); + +// utf8-import-module.wast:1974 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x90\x00\x03\x7f\x00"); + +// utf8-import-module.wast:1989 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x90\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:2004 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x90\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:2019 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf0\x90\x90\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:2034 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:2049 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:2064 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:2079 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf1\x80\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:2094 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:2109 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:2124 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:2139 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf3\x80\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:2154 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x80\x00\x03\x7f\x00"); + +// utf8-import-module.wast:2169 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x80\x7f\x03\x7f\x00"); + +// utf8-import-module.wast:2184 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x80\xc0\x03\x7f\x00"); + +// utf8-import-module.wast:2199 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf4\x80\x80\xfd\x03\x7f\x00"); + +// utf8-import-module.wast:2216 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x04\x74\x65\x73\x74\x06\xf8\x80\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2231 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf8\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2246 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xf8\x80\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2261 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xf8\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2276 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xf8\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2291 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xf8\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2306 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xf8\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2321 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xf8\x03\x7f\x00"); + +// utf8-import-module.wast:2336 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xf8\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2353 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xf8\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2368 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xfb\xbf\xbf\xbf\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:2385 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x11\x01\x04\x74\x65\x73\x74\x07\xfc\x80\x80\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2400 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xfc\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2415 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x04\x74\x65\x73\x74\x06\xfc\x80\x80\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2430 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xfc\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2445 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0f\x01\x04\x74\x65\x73\x74\x05\xfc\x80\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2460 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xfc\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2475 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xfc\x80\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2490 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xfc\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2505 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0d\x01\x04\x74\x65\x73\x74\x03\xfc\x80\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2520 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xfc\x03\x7f\x00"); + +// utf8-import-module.wast:2535 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xfc\x23\x03\x7f\x00"); + +// utf8-import-module.wast:2552 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x04\x74\x65\x73\x74\x06\xfc\x80\x80\x80\x80\x80\x03\x7f\x00"); + +// utf8-import-module.wast:2567 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x10\x01\x04\x74\x65\x73\x74\x06\xfd\xbf\xbf\xbf\xbf\xbf\x03\x7f\x00"); + +// utf8-import-module.wast:2584 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xfe\x03\x7f\x00"); + +// utf8-import-module.wast:2599 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0b\x01\x04\x74\x65\x73\x74\x01\xff\x03\x7f\x00"); + +// utf8-import-module.wast:2614 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xfe\xff\x03\x7f\x00"); + +// utf8-import-module.wast:2629 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\x00\x00\xfe\xff\x03\x7f\x00"); + +// utf8-import-module.wast:2644 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0c\x01\x04\x74\x65\x73\x74\x02\xff\xfe\x03\x7f\x00"); + +// utf8-import-module.wast:2659 +assert_malformed("\x00\x61\x73\x6d\x01\x00\x00\x00\x02\x0e\x01\x04\x74\x65\x73\x74\x04\xff\xfe\x00\x00\x03\x7f\x00"); diff --git a/js/src/jit-test/tests/wasm/spec/threads/utf8-invalid-encoding.wast.js b/js/src/jit-test/tests/wasm/spec/threads/utf8-invalid-encoding.wast.js new file mode 100644 index 0000000000..5614de4cdf --- /dev/null +++ b/js/src/jit-test/tests/wasm/spec/threads/utf8-invalid-encoding.wast.js @@ -0,0 +1,528 @@ + +// utf8-invalid-encoding.wast:1 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:2 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:3 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:4 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:5 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:6 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:7 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:8 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:9 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:10 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:11 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:12 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:13 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:14 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:15 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:16 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:17 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:18 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:19 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:20 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:21 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:22 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:23 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:24 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:25 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:26 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:27 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:28 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:29 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:30 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:31 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:32 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:33 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:34 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:35 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:36 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:37 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:38 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:39 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:40 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:41 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:42 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:43 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:44 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:45 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:46 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:47 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:48 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:49 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:50 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:51 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:52 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:53 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:54 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:55 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:56 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:57 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:58 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:59 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:60 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:61 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:62 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:63 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:64 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:65 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:66 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:67 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:68 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:69 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:70 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:71 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:72 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:73 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:74 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:75 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:76 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:77 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:78 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:79 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:80 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:81 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:82 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:83 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:84 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:85 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:86 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:87 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:88 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:89 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:90 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:91 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:92 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:93 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:94 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:95 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:96 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:97 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:98 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:99 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:100 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:101 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:102 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:103 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:104 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:105 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:106 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:107 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:108 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:109 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:110 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:111 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:112 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:113 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:114 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:115 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:116 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:117 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:118 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:119 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:120 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:121 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:122 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:123 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:124 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:125 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:126 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:127 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:128 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:129 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:130 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:131 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:132 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:133 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:134 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:135 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:136 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:137 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:138 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:139 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:140 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:141 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:142 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:143 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:144 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:145 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:146 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:147 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:148 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:149 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:150 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:151 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:152 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:153 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:154 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:155 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:156 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:157 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:158 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:159 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:160 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:161 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:162 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:163 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:164 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:165 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:166 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:167 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:168 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:169 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:170 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:171 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:172 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:173 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:174 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:175 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); + +// utf8-invalid-encoding.wast:176 +assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); diff --git a/js/src/jit-test/tests/wasm/spec/type.wast.js b/js/src/jit-test/tests/wasm/spec/type.wast.js deleted file mode 100644 index 9184b46010..0000000000 --- a/js/src/jit-test/tests/wasm/spec/type.wast.js +++ /dev/null @@ -1,23 +0,0 @@ - -// type.wast:3 -let $1 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xc5\x80\x80\x80\x00\x0e\x60\x00\x00\x60\x00\x00\x60\x01\x7f\x00\x60\x01\x7f\x00\x60\x00\x01\x7f\x60\x01\x7f\x01\x7f\x60\x01\x7f\x01\x7f\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x02\x7d\x7c\x00\x60\x06\x7d\x7c\x7f\x7c\x7f\x7f\x00\x60\x03\x7d\x7c\x7f\x00"); - -// type.wast:43 -assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); - -// type.wast:47 -assert_malformed("\x3c\x6d\x61\x6c\x66\x6f\x72\x6d\x65\x64\x20\x71\x75\x6f\x74\x65\x3e"); - -// These last two tests check that function types returning more than 2 -// results are invalid, but with multi-value of course that's no longer -// the case. Until the feature fully lands and we can import from -// upstream, skip these tests. -if (wasmMultiValueEnabled()) { - quit(); -} - -// type.wast:52 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f"); - -// type.wast:56 -assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x86\x80\x80\x80\x00\x01\x60\x00\x02\x7f\x7f"); diff --git a/js/src/jit-test/tests/wasm/streaming.js b/js/src/jit-test/tests/wasm/streaming.js index 44defaf4fc..fc2d95cd4a 100644 --- a/js/src/jit-test/tests/wasm/streaming.js +++ b/js/src/jit-test/tests/wasm/streaming.js @@ -68,22 +68,25 @@ text += ` (func (export "run") (result i32) call 100)\n`; text += `)`; var code = wasmTextToBinary(text); -assertEq(code.length > 1000, true); -for ([delayMillis, chunkSize] of [[0, 10], [1, 10], [0, 100], [1, 100], [0, 1000], [1, 1000], [10, 1000]]) { - setBufferStreamParams(delayMillis, chunkSize); - testBoth(code, 'run', 5050); -} +// fuzzing-safe disables setBufferStreamParams +if (typeof setBufferStreamParams == 'function') { + assertEq(code.length > 1000, true); + for ([delayMillis, chunkSize] of [[0, 10], [1, 10], [0, 100], [1, 100], [0, 1000], [1, 1000], [10, 1000]]) { + setBufferStreamParams(delayMillis, chunkSize); + testBoth(code, 'run', 5050); + } -setBufferStreamParams(1, 100); -var arr = []; -for (var i = 0; i < 10; i++) - arr.push(WebAssembly.instantiateStreaming(code)); -var results; -Promise.all(arr).then(r => results = r); -drainJobQueue(); -assertEq(results.length === 10, true); -for (var i = 0; i < 10; i++) - assertEq(results[i].instance.exports.run(), 5050); + setBufferStreamParams(1, 100); + var arr = []; + for (var i = 0; i < 10; i++) + arr.push(WebAssembly.instantiateStreaming(code)); + var results; + Promise.all(arr).then(r => results = r); + drainJobQueue(); + assertEq(results.length === 10, true); + for (var i = 0; i < 10; i++) + assertEq(results[i].instance.exports.run(), 5050); +} // No code section, but data section: var code = wasmTextToBinary('(module (memory (import "js" "mem") 1) (data (i32.const 0) "a"))'); diff --git a/js/src/jit-test/tests/wasm/tables.js b/js/src/jit-test/tests/wasm/tables.js index 9539f1cd20..db96e9009e 100644 --- a/js/src/jit-test/tests/wasm/tables.js +++ b/js/src/jit-test/tests/wasm/tables.js @@ -8,11 +8,7 @@ const RuntimeError = WebAssembly.RuntimeError; const badFuncRefError = /can only pass WebAssembly exported functions to funcref/; function assertSegmentFitError(f) { - if (wasmBulkMemSupported()) { - assertErrorMessage(f, RuntimeError, /out of bounds/); - } else { - assertErrorMessage(f, LinkError, /segment does not fit/); - } + assertErrorMessage(f, RuntimeError, /out of bounds/); } var callee = i => `(func $f${i} (result i32) (i32.const ${i}))`; diff --git a/js/src/jit-test/tests/wasm/unsupported/README.md b/js/src/jit-test/tests/wasm/unsupported/README.md new file mode 100644 index 0000000000..9687e7a9b6 --- /dev/null +++ b/js/src/jit-test/tests/wasm/unsupported/README.md @@ -0,0 +1 @@ +DO NOT ADD A directives.txt FILE IN THIS DIRECTORY. THE TEST CASE MUST RUN WITH MINIMAL PRELIMINARIES. diff --git a/js/src/jit-test/tests/wasm/unsupported/requires-armv7.js b/js/src/jit-test/tests/wasm/unsupported/requires-armv7.js new file mode 100644 index 0000000000..88acfe502f --- /dev/null +++ b/js/src/jit-test/tests/wasm/unsupported/requires-armv7.js @@ -0,0 +1,5 @@ +// |jit-test| skip-if: !getBuildConfiguration().arm; --arm-hwcap=vfp + +// Wasm should be unavailable in this configuration: floating point without +// armv7, and armv7 is required for atomics and unaligned accesses. +assertEq(typeof WebAssembly, "undefined"); diff --git a/js/src/jit-test/tests/wasm/unsupported/requires-floatingpoint.js b/js/src/jit-test/tests/wasm/unsupported/requires-floatingpoint.js new file mode 100644 index 0000000000..40744ab130 --- /dev/null +++ b/js/src/jit-test/tests/wasm/unsupported/requires-floatingpoint.js @@ -0,0 +1,4 @@ +// |jit-test| skip-if: !getBuildConfiguration().arm; --arm-hwcap=armv7 + +// Wasm should be unavailable in this configuration: armv7 without floating point. +assertEq(typeof WebAssembly, "undefined"); diff --git a/js/src/jit-test/tests/xdr/bug1108603.js b/js/src/jit-test/tests/xdr/bug1108603.js deleted file mode 100644 index 54ba21e79a..0000000000 --- a/js/src/jit-test/tests/xdr/bug1108603.js +++ /dev/null @@ -1,9 +0,0 @@ -var caught = false; -try { - evaluate(cacheEntry(""), {saveBytecode: {value: true}, global: this}); - [[0]]; -} catch (err) { - caught = true; - assertEq(err.message, "compartment cannot save singleton anymore."); -} -assertEq(caught, true); \ No newline at end of file diff --git a/js/src/jit-test/tests/xdr/module-exports.js b/js/src/jit-test/tests/xdr/module-exports.js index c2c1263384..f597ba49c0 100644 --- a/js/src/jit-test/tests/xdr/module-exports.js +++ b/js/src/jit-test/tests/xdr/module-exports.js @@ -1,4 +1,3 @@ -load(libdir + "dummyModuleResolveHook.js"); const count = 10; let s = ""; @@ -6,11 +5,11 @@ for (let i = 0; i < count; i++) s += "export let e" + i + " = " + (i * i) + ";\n"; let og = parseModule(s); let bc = codeModule(og); -let a = moduleRepo['a'] = decodeModule(bc); +let a = registerModule('a', decodeModule(bc)); og = parseModule("import * as ns from 'a'"); bc = codeModule(og); -let b = moduleRepo['b'] = decodeModule(bc); +let b = registerModule('b', decodeModule(bc)); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/xdr/module-imports.js b/js/src/jit-test/tests/xdr/module-imports.js index 70ea6cd902..1ecf3ce29e 100644 --- a/js/src/jit-test/tests/xdr/module-imports.js +++ b/js/src/jit-test/tests/xdr/module-imports.js @@ -1,10 +1,8 @@ -load(libdir + "dummyModuleResolveHook.js"); - const count = 10; let og = parseModule("export let a = 1;"); let bc = codeModule(og); -let a = moduleRepo['a'] = decodeModule(bc); +let a = registerModule('a', decodeModule(bc)); let s = ""; for (let i = 0; i < count; i++) { @@ -14,7 +12,7 @@ for (let i = 0; i < count; i++) { og = parseModule(s); bc = codeModule(og); -let b = moduleRepo['b'] = decodeModule(bc); +let b = registerModule('b', decodeModule(bc)); b.declarationInstantiation(); b.evaluation(); diff --git a/js/src/jit-test/tests/xdr/module-oom.js b/js/src/jit-test/tests/xdr/module-oom.js index c0d08671e0..46e6b67525 100644 --- a/js/src/jit-test/tests/xdr/module-oom.js +++ b/js/src/jit-test/tests/xdr/module-oom.js @@ -2,8 +2,6 @@ // OOM tests for xdr module parsing. -load(libdir + "dummyModuleResolveHook.js"); - const sa = `export default 20; export let a = 22; @@ -20,9 +18,9 @@ const sb = oomTest(() => { let og = parseModule(sa); let bc = codeModule(og); - let a = moduleRepo['a'] = decodeModule(bc); + let a = registerModule('a', decodeModule(bc)); og = parseModule(sb); bc = codeModule(og); - let b = moduleRepo['b'] = decodeModule(bc); + let b = registerModule('b', decodeModule(bc)); }); diff --git a/js/src/jit-test/tests/xdr/module.js b/js/src/jit-test/tests/xdr/module.js index 3eef5909ba..c763ef21f8 100644 --- a/js/src/jit-test/tests/xdr/module.js +++ b/js/src/jit-test/tests/xdr/module.js @@ -1,6 +1,5 @@ load(libdir + "asserts.js"); -load(libdir + "dummyModuleResolveHook.js"); function parseAndEvaluate(source) { let og = parseModule(source); @@ -40,7 +39,7 @@ og = parseModule(`var x = 1; export default 2; export function f(x) { return x + 1; }`); bc = codeModule(og); -a = moduleRepo['a'] = decodeModule(bc); +a = registerModule('a', decodeModule(bc)); // Check we can evaluate top level definitions. parseAndEvaluate("var foo = 1;"); diff --git a/js/src/jit-test/tests/xdr/private-fields.js b/js/src/jit-test/tests/xdr/private-fields.js new file mode 100644 index 0000000000..dfea2b6a62 --- /dev/null +++ b/js/src/jit-test/tests/xdr/private-fields.js @@ -0,0 +1,10 @@ +// |jit-test| --enable-private-fields; +load(libdir + 'bytecode-cache.js'); + +function test() { + class A { + #x; + } +}; + +evalWithCache(test.toString(), {assertEqBytecode: true, assertEqResult: true}); diff --git a/js/src/jit-test/tests/xdr/runonce.js b/js/src/jit-test/tests/xdr/runonce.js new file mode 100644 index 0000000000..0ae79b9edb --- /dev/null +++ b/js/src/jit-test/tests/xdr/runonce.js @@ -0,0 +1,13 @@ +load(libdir + "asserts.js") + +// JS::EncodeScript cannot be use for run-once scripts. +evaluate(cacheEntry(""), { saveBytecode: true }); +evaluate(cacheEntry(""), { saveBytecode: true, isRunOnce: false }) +assertErrorMessage(() => { + evaluate(cacheEntry(""), { saveBytecode: true, isRunOnce: true }) +}, Error, "run-once script are not supported by XDR"); + +// Incremental XDR doesn't have any of these restrictions. +evaluate(cacheEntry(""), { saveIncrementalBytecode: true }); +evaluate(cacheEntry(""), { saveIncrementalBytecode: true, isRunOnce: false }); +evaluate(cacheEntry(""), { saveIncrementalBytecode: true, isRunOnce: true }); diff --git a/js/src/jit/AliasAnalysis.cpp b/js/src/jit/AliasAnalysis.cpp index d964427f2e..6b0135d214 100644 --- a/js/src/jit/AliasAnalysis.cpp +++ b/js/src/jit/AliasAnalysis.cpp @@ -109,9 +109,12 @@ static inline const MDefinition* GetObject(const MDefinition* ins) { case MDefinition::Opcode::LoadUnboxedScalar: case MDefinition::Opcode::LoadDataViewElement: case MDefinition::Opcode::StoreElement: + case MDefinition::Opcode::StoreHoleValueElement: case MDefinition::Opcode::StoreUnboxedScalar: case MDefinition::Opcode::StoreDataViewElement: case MDefinition::Opcode::SetInitializedLength: + case MDefinition::Opcode::AddAndStoreSlot: + case MDefinition::Opcode::AllocateAndStoreSlot: case MDefinition::Opcode::ArrayLength: case MDefinition::Opcode::SetArrayLength: case MDefinition::Opcode::Slots: @@ -133,6 +136,8 @@ static inline const MDefinition* GetObject(const MDefinition* ins) { case MDefinition::Opcode::GuardReceiverPolymorphic: case MDefinition::Opcode::GuardObjectGroup: case MDefinition::Opcode::GuardObjectIdentity: + case MDefinition::Opcode::GuardProto: + case MDefinition::Opcode::GuardNullProto: case MDefinition::Opcode::LoadDynamicSlot: case MDefinition::Opcode::StoreDynamicSlot: case MDefinition::Opcode::InArray: @@ -145,6 +150,13 @@ static inline const MDefinition* GetObject(const MDefinition* ins) { case MDefinition::Opcode::HomeObjectSuperBase: case MDefinition::Opcode::ObjectStaticProto: case MDefinition::Opcode::GuardNoDenseElements: + case MDefinition::Opcode::GuardElementNotHole: + case MDefinition::Opcode::GuardArrayIsPacked: + case MDefinition::Opcode::GuardFunctionFlags: + case MDefinition::Opcode::GuardFunctionKind: + case MDefinition::Opcode::ArgumentsObjectLength: + case MDefinition::Opcode::FunctionLength: + case MDefinition::Opcode::FunctionName: object = ins->getOperand(0); break; case MDefinition::Opcode::GetPropertyCache: @@ -156,10 +168,20 @@ static inline const MDefinition* GetObject(const MDefinition* ins) { case MDefinition::Opcode::ThrowRuntimeLexicalError: case MDefinition::Opcode::GetArgumentsObjectArg: case MDefinition::Opcode::SetArgumentsObjectArg: + case MDefinition::Opcode::LoadArgumentsObjectArg: case MDefinition::Opcode::CreateThis: + case MDefinition::Opcode::NewArrayDynamicLength: + case MDefinition::Opcode::NewTypedArrayDynamicLength: + case MDefinition::Opcode::CheckObjCoercible: + case MDefinition::Opcode::ToObject: + case MDefinition::Opcode::MegamorphicLoadSlot: + case MDefinition::Opcode::MegamorphicLoadSlotByValue: + case MDefinition::Opcode::MegamorphicStoreSlot: + case MDefinition::Opcode::MegamorphicHasProp: case MDefinition::Opcode::CompareExchangeTypedArrayElement: case MDefinition::Opcode::AtomicExchangeTypedArrayElement: case MDefinition::Opcode::AtomicTypedArrayElementBinop: + case MDefinition::Opcode::LoadWrapperTarget: case MDefinition::Opcode::AsmJSLoadHeap: case MDefinition::Opcode::AsmJSStoreHeap: case MDefinition::Opcode::WasmHeapBase: diff --git a/js/src/jit/AlignmentMaskAnalysis.cpp b/js/src/jit/AlignmentMaskAnalysis.cpp index f16de65347..2108e948cf 100644 --- a/js/src/jit/AlignmentMaskAnalysis.cpp +++ b/js/src/jit/AlignmentMaskAnalysis.cpp @@ -43,7 +43,7 @@ static void AnalyzeAsmHeapAddress(MDefinition* ptr, MIRGraph& graph) { MDefinition* lhs = ptr->toBitAnd()->getOperand(0); MDefinition* rhs = ptr->toBitAnd()->getOperand(1); if (lhs->isConstant()) { - mozilla::Swap(lhs, rhs); + std::swap(lhs, rhs); } if (!lhs->isAdd() || !rhs->isConstant()) { return; @@ -52,7 +52,7 @@ static void AnalyzeAsmHeapAddress(MDefinition* ptr, MIRGraph& graph) { MDefinition* op0 = lhs->toAdd()->getOperand(0); MDefinition* op1 = lhs->toAdd()->getOperand(1); if (op0->isConstant()) { - mozilla::Swap(op0, op1); + std::swap(op0, op1); } if (!op1->isConstant()) { return; diff --git a/js/src/jit/AtomicOperations.h b/js/src/jit/AtomicOperations.h index 4e871c2b1a..4360643eed 100644 --- a/js/src/jit/AtomicOperations.h +++ b/js/src/jit/AtomicOperations.h @@ -301,7 +301,7 @@ class AtomicOperations { }; inline bool AtomicOperations::isLockfreeJS(int32_t size) { - // Keep this in sync with visitAtomicIsLockFree() in jit/CodeGenerator.cpp. + // Keep this in sync with atomicIsLockFreeJS() in jit/MacroAssembler.cpp. switch (size) { case 1: diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index df2522f553..d714abba13 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -673,6 +673,14 @@ bool BacktrackingAllocator::buildLivenessInfo() { } } + // * For non-call instructions, temps cover both the input and output, + // so temps never alias uses (even at-start uses) or defs. + // * For call instructions, temps only cover the input (the output is + // used for the force-spill ranges added above). This means temps + // still don't alias uses but they can alias the (fixed) defs. For now + // we conservatively require temps to have a fixed register for call + // instructions to prevent a footgun. + MOZ_ASSERT_IF(ins->isCall(), temp->policy() == LDefinition::FIXED); CodePosition to = ins->isCall() ? outputOf(*ins) : outputOf(*ins).next(); @@ -696,18 +704,6 @@ bool BacktrackingAllocator::buildLivenessInfo() { use->usedAtStart()); #ifdef DEBUG - // Don't allow at-start call uses if there are temps of the same kind, - // so that we don't assign the same register. Only allow this when the - // use and temp are fixed registers, as they can't alias. - if (ins->isCall() && use->usedAtStart()) { - for (size_t i = 0; i < ins->numTemps(); i++) { - MOZ_ASSERT_IF( - !ins->getTemp(i)->isBogusTemp(), - vreg(ins->getTemp(i)).type() != vreg(use).type() || - (use->isFixedRegister() && ins->getTemp(i)->isFixed())); - } - } - // If there are both useRegisterAtStart(x) and useRegister(y) // uses, we may assign the same register to both operands // (bug 772830). Don't allow this for now. diff --git a/js/src/jit/Bailouts.cpp b/js/src/jit/Bailouts.cpp index b295bd63be..cfb6d2020d 100644 --- a/js/src/jit/Bailouts.cpp +++ b/js/src/jit/Bailouts.cpp @@ -36,6 +36,7 @@ static_assert(!(FAKE_EXITFP_FOR_BAILOUT_ADDR & wasm::ExitOrJitEntryFPTag), bool jit::Bailout(BailoutStack* sp, BaselineBailoutInfo** bailoutInfo) { JSContext* cx = TlsContext.get(); MOZ_ASSERT(bailoutInfo); + MOZ_ASSERT(!cx->hasIonReturnOverride()); // We don't have an exit frame. MOZ_ASSERT(IsInRange(FAKE_EXITFP_FOR_BAILOUT, 0, 0x1000) && @@ -61,8 +62,7 @@ bool jit::Bailout(BailoutStack* sp, BaselineBailoutInfo** bailoutInfo) { *bailoutInfo = nullptr; bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frame, - false, bailoutInfo, - /* excInfo = */ nullptr); + bailoutInfo, /*exceptionInfo=*/nullptr); MOZ_ASSERT_IF(success, *bailoutInfo != nullptr); if (!success) { @@ -137,9 +137,8 @@ bool jit::InvalidationBailout(InvalidationBailoutStack* sp, MOZ_ASSERT(IsBaselineJitEnabled(cx)); *bailoutInfo = nullptr; - bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frame, true, - bailoutInfo, - /* excInfo = */ nullptr); + bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frame, + bailoutInfo, /*exceptionInfo=*/nullptr); MOZ_ASSERT_IF(success, *bailoutInfo != nullptr); if (!success) { @@ -219,14 +218,15 @@ bool jit::ExceptionHandlerBailout(JSContext* cx, BaselineBailoutInfo* bailoutInfo = nullptr; bool success = BailoutIonToBaseline(cx, bailoutData.activation(), frameView, - true, &bailoutInfo, &excInfo); + &bailoutInfo, &excInfo); if (success) { MOZ_ASSERT(bailoutInfo); // Overwrite the kind so HandleException after the bailout returns // false, jumping directly to the exception tail. if (excInfo.propagatingIonExceptionForDebugMode()) { - bailoutInfo->bailoutKind = mozilla::Some(Bailout_IonExceptionDebugMode); + bailoutInfo->bailoutKind = + mozilla::Some(BailoutKind::IonExceptionDebugMode); } rfe->kind = ResumeFromException::RESUME_BAILOUT; @@ -281,7 +281,7 @@ void jit::CheckFrequentBailouts(JSContext* cx, JSScript* script, // which should prevent this from happening again. Also note that // the first execution bailout can be related to an inlined script, // so there is no need to penalize the caller. - if (bailoutKind != Bailout_FirstExecution && + if (bailoutKind != BailoutKind::FirstExecution && !script->hadFrequentBailouts()) { script->setHadFrequentBailouts(); } diff --git a/js/src/jit/Bailouts.h b/js/src/jit/Bailouts.h index 64a2221965..4e1789db36 100644 --- a/js/src/jit/Bailouts.h +++ b/js/src/jit/Bailouts.h @@ -24,17 +24,17 @@ namespace jit { // [SMDOC] IonMonkey Bailouts // -// A "bailout" is the process of recovering a baseline frame from an IonFrame. -// Bailouts are implemented in js::jit::BailoutIonToBaseline, which has the -// following callers: +// A "bailout" is the process of recovering a baseline interpreter frame from an +// IonFrame. Bailouts are implemented in js::jit::BailoutIonToBaseline, which +// has the following callers: // // * js::jit::Bailout - This is used when a guard fails in the Ion code // itself; for example, an LGuardShape fails or an LAddI overflows. See // callers of CodeGenerator::bailoutFrom() for more examples. // -// * js::jit::ExceptionHandlerBailout - Something called from Ion code -// failed. Ion doesn't implement `catch`; it handles all exceptions by -// bailing out. +// * js::jit::ExceptionHandlerBailout - Ion doesn't implement `catch` or +// `finally`. If an exception is thrown and would be caught by an Ion frame, +// we bail out instead. // // * js::jit::InvalidationBailout - We returned to Ion code that was // invalidated while it was on the stack. See "OSI" below. Ion code can be @@ -49,13 +49,13 @@ namespace jit { // Ion. There's no IC fallback case coming to save us; we've got a broken // assumption baked into the code we're running. So we jump to an out-of-line // code path that's responsible for abandoning Ion execution and resuming in -// baseline: the bailout path. +// the baseline interpreter: the bailout path. // // We were in the midst of optimized Ion code, so bits of program state may be // in registers or spilled to the native stack; values may be unboxed; some // objects may have been optimized away; thanks to inlining, whole call frames // may be missing. The bailout path must put all these pieces back together -// into the structure the baseline code expects. +// into the structure the baseline interpreter expects. // // The data structure that makes this possible is called a *snapshot*. // Snapshots are created during Ion codegen and associated with the IonScript; @@ -70,10 +70,7 @@ namespace jit { // 2. Spill all registers. // 3. Call js::jit::Bailout to reconstruct the baseline frame(s). // 4. memmove() those to the right place on the native stack. -// 5. Jump to baseline code. -// -// (This last step requires baseline JIT code to have an entry point at each pc -// where an eventual Ion guard may be inserted.) +// 5. Jump into the baseline interpreter. // // When C++ code invalidates Ion code, we do on-stack invalidation, or OSI, to // arrange for every affected Ion frame on the stack to bail out as soon as diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index bc9e5387eb..a8be16f75c 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -4,6 +4,7 @@ #include "mozilla/ScopeExit.h" +#include "builtin/ModuleObject.h" #include "debugger/DebugAPI.h" #include "jit/arm/Simulator-arm.h" #include "jit/BaselineFrame.h" @@ -17,6 +18,7 @@ #include "jit/mips64/Simulator-mips64.h" #include "jit/Recover.h" #include "jit/RematerializedFrame.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimitWithStackPointerDontReport, js::ReportOverRecursed #include "js/Utility.h" #include "util/Memory.h" #include "vm/ArgumentsObject.h" @@ -29,6 +31,8 @@ using namespace js; using namespace js::jit; +using mozilla::Maybe; + // BaselineStackBuilder may reallocate its buffer if the current one is too // small. To avoid dangling pointers, BufferPointer represents a pointer into // this buffer as a pointer to the header and a fixed offset. @@ -82,27 +86,41 @@ class BufferPointer { * The lowest region of the allocated memory contains a BaselineBailoutInfo * structure that points to the start and end of the written data. */ -struct BaselineStackBuilder { +class MOZ_STACK_CLASS BaselineStackBuilder { JSContext* cx_; - const JSJitFrameIter& iter_; JitFrameLayout* frame_ = nullptr; + SnapshotIterator& iter_; + RootedValueVector outermostFrameFormals_; - size_t bufferTotal_ = 0; + size_t bufferTotal_ = 1024; size_t bufferAvail_ = 0; size_t bufferUsed_ = 0; size_t framePushed_ = 0; UniquePtr header_; - BaselineStackBuilder(JSContext* cx, const JSJitFrameIter& iter, - size_t initialSize) - : cx_(cx), - iter_(iter), - frame_(static_cast(iter.current())), - bufferTotal_(initialSize) { - MOZ_ASSERT(bufferTotal_ >= sizeof(BaselineBailoutInfo)); - MOZ_ASSERT(iter.isBailoutJS()); - } + JSScript* script_; + JSFunction* fun_; + const ExceptionBailoutInfo* excInfo_; + ICScript* icScript_; + + jsbytecode* pc_ = nullptr; + JSOp op_ = JSOp::Nop; + uint32_t exprStackSlots_ = 0; + void* prevFramePtr_ = nullptr; + Maybe> blFrame_; + + size_t frameNo_ = 0; + JSFunction* nextCallee_ = nullptr; + + // The baseline frames we will reconstruct on the heap are not + // rooted, so GC must be suppressed. + gc::AutoSuppressGC suppress_; + + public: + BaselineStackBuilder(JSContext* cx, const JSJitFrameIter& frameIter, + SnapshotIterator& iter, + const ExceptionBailoutInfo* excInfo); MOZ_MUST_USE bool init() { MOZ_ASSERT(!header_); @@ -121,6 +139,87 @@ struct BaselineStackBuilder { return true; } + MOZ_MUST_USE bool buildOneFrame(); + bool done(); + void nextFrame(); + + JSScript* script() const { return script_; } + size_t frameNo() const { return frameNo_; } + bool isOutermostFrame() const { return frameNo_ == 0; } + MutableHandleValueVector outermostFrameFormals() { + return &outermostFrameFormals_; + } + + inline JitFrameLayout* startFrame() { return frame_; } + + BaselineBailoutInfo* info() { + MOZ_ASSERT(header_); + return header_.get(); + } + + BaselineBailoutInfo* takeBuffer() { + MOZ_ASSERT(header_); + return header_.release(); + } + + private: + MOZ_MUST_USE bool initFrame(); + MOZ_MUST_USE bool buildBaselineFrame(); + MOZ_MUST_USE bool buildArguments(); + MOZ_MUST_USE bool buildFixedSlots(); + MOZ_MUST_USE bool fixUpCallerArgs(MutableHandleValueVector savedCallerArgs, + bool* fixedUp); + MOZ_MUST_USE bool buildExpressionStack(); + MOZ_MUST_USE bool finishLastFrame(); + + MOZ_MUST_USE bool prepareForNextFrame(HandleValueVector savedCallerArgs); + MOZ_MUST_USE bool finishOuterFrame(uint32_t frameSize); + MOZ_MUST_USE bool buildStubFrame(uint32_t frameSize, + HandleValueVector savedCallerArgs); + MOZ_MUST_USE bool buildRectifierFrame(uint32_t actualArgc, + size_t endOfBaselineStubArgs); + +#ifdef DEBUG + MOZ_MUST_USE bool validateFrame(); +#endif + +#ifdef DEBUG + bool envChainSlotCanBeOptimized(); +#endif + + bool hasLiveStackValueAtDepth(uint32_t stackSlotIndex); + bool isPrologueBailout(); + jsbytecode* getResumePC(); + void* getStubReturnAddress(); + + uint32_t exprStackSlots() const { return exprStackSlots_; } + + // Returns true if we're bailing out to a catch or finally block in this frame + bool catchingException() const { + return excInfo_ && excInfo_->catchingException() && + excInfo_->frameNo() == frameNo_; + } + + // Returns true if we're bailing out in place for debug mode + bool propagatingIonExceptionForDebugMode() const { + return excInfo_ && excInfo_->propagatingIonExceptionForDebugMode(); + } + + void* prevFramePtr() const { return prevFramePtr_; } + BufferPointer& blFrame() { return blFrame_.ref(); } + + void setNextCallee(JSFunction* nextCallee); + JSFunction* nextCallee() const { return nextCallee_; } + + jsbytecode* pc() const { return pc_; } + bool resumeAfter() const { + return !catchingException() && iter_.resumeAfter(); + } + + bool needToSaveCallerArgs() const { + return op_ == JSOp::FunApply || IsIonInlinableGetterOrSetterOp(op_); + } + MOZ_MUST_USE bool enlarge() { MOZ_ASSERT(header_ != nullptr); if (bufferTotal_ & mozilla::tl::MulOverflowMask<2>::value) { @@ -162,16 +261,6 @@ struct BaselineStackBuilder { return true; } - BaselineBailoutInfo* info() { - MOZ_ASSERT(header_); - return header_.get(); - } - - BaselineBailoutInfo* takeBuffer() { - MOZ_ASSERT(header_); - return header_.release(); - } - void resetFramePushed() { framePushed_ = 0; } size_t framePushed() const { return framePushed_; } @@ -267,17 +356,6 @@ struct BaselineStackBuilder { return true; } - Value popValue() { - MOZ_ASSERT(bufferUsed_ >= sizeof(Value)); - MOZ_ASSERT(framePushed_ >= sizeof(Value)); - bufferAvail_ += sizeof(Value); - bufferUsed_ -= sizeof(Value); - framePushed_ -= sizeof(Value); - Value result = *((Value*)header_->copyStackBottom); - header_->copyStackBottom += sizeof(Value); - return result; - } - void setResumeFramePtr(void* resumeFramePtr) { header_->resumeFramePtr = resumeFramePtr; } @@ -312,13 +390,10 @@ struct BaselineStackBuilder { return reinterpret_cast(frame_) + (offset - bufferUsed_); } - inline JitFrameLayout* startFrame() { return frame_; } - BufferPointer topFrameAddress() { return pointerAtStackOffset(0); } - // // This method should only be called when the builder is in a state where it // is starting to construct the stack frame for the next callee. This means // that the lowest value on the constructed stack is the return address for @@ -406,6 +481,22 @@ struct BaselineStackBuilder { } }; +BaselineStackBuilder::BaselineStackBuilder(JSContext* cx, + const JSJitFrameIter& frameIter, + SnapshotIterator& iter, + const ExceptionBailoutInfo* excInfo) + : cx_(cx), + frame_(static_cast(frameIter.current())), + iter_(iter), + outermostFrameFormals_(cx), + script_(frameIter.script()), + fun_(frameIter.maybeCallee()), + excInfo_(excInfo), + icScript_(script_->jitScript()->icScript()), + suppress_(cx) { + MOZ_ASSERT(bufferTotal_ >= sizeof(BaselineBailoutInfo)); +} + #ifdef DEBUG static inline bool IsInlinableFallback(ICFallbackStub* icEntry) { return icEntry->isCall_Fallback() || icEntry->isGetProp_Fallback() || @@ -413,576 +504,421 @@ static inline bool IsInlinableFallback(ICFallbackStub* icEntry) { } #endif -static inline void* GetStubReturnAddress(JSContext* cx, JSOp op) { - const BaselineICFallbackCode& code = - cx->runtime()->jitRuntime()->baselineICFallbackCode(); - - if (IsGetPropOp(op)) { - return code.bailoutReturnAddr(BailoutReturnKind::GetProp); - } - if (IsSetPropOp(op)) { - return code.bailoutReturnAddr(BailoutReturnKind::SetProp); - } - if (IsGetElemOp(op)) { - return code.bailoutReturnAddr(BailoutReturnKind::GetElem); - } - - // This should be a call op of some kind, now. - MOZ_ASSERT(IsInvokeOp(op) && !IsSpreadOp(op)); - if (IsConstructOp(op)) { - return code.bailoutReturnAddr(BailoutReturnKind::New); +bool BaselineStackBuilder::initFrame() { + // If we are catching an exception, we are bailing out to a catch or + // finally block and this is the frame where we will resume. Usually the + // expression stack should be empty in this case but there can be + // iterators on the stack. + if (catchingException()) { + exprStackSlots_ = excInfo_->numExprSlots(); + } else { + uint32_t totalFrameSlots = iter_.numAllocations(); + uint32_t fixedSlots = script_->nfixed(); + uint32_t argSlots = CountArgSlots(script_, fun_); + exprStackSlots_ = totalFrameSlots - fixedSlots - argSlots; } - return code.bailoutReturnAddr(BailoutReturnKind::Call); -} - -static inline jsbytecode* GetNextNonLoopHeadPc(jsbytecode* pc, - jsbytecode** skippedLoopHead) { - JSOp op = JSOp(*pc); - switch (op) { - case JSOp::Goto: - return pc + GET_JUMP_OFFSET(pc); - case JSOp::LoopHead: - *skippedLoopHead = pc; - return GetNextPc(pc); + resetFramePushed(); - case JSOp::Nop: - return GetNextPc(pc); + JitSpew(JitSpew_BaselineBailouts, " Unpacking %s:%u:%u", + script_->filename(), script_->lineno(), script_->column()); + JitSpew(JitSpew_BaselineBailouts, " [BASELINE-JS FRAME]"); - default: - return pc; + // Calculate and write the previous frame pointer value. + // Record the virtual stack offset at this location. Later on, if we end up + // writing out a BaselineStub frame for the next callee, we'll need to save + // the address. + void* prevFramePtr = calculatePrevFramePtr(); + if (!writePtr(prevFramePtr, "PrevFramePtr")) { + return false; } -} + prevFramePtr_ = virtualPointerAtStackOffset(0); -// Returns the pc to resume execution at in Baseline after a bailout. -static jsbytecode* GetResumePC(JSScript* script, jsbytecode* pc, - bool resumeAfter) { - if (resumeAfter) { - return GetNextPc(pc); - } + // Get the pc. If we are handling an exception, resume at the pc of the + // catch or finally block. + pc_ = catchingException() ? excInfo_->resumePC() + : script_->offsetToPC(iter_.pcOffset()); + op_ = JSOp(*pc_); - // If we are resuming at a LoopHead op, resume at the next op to avoid - // a bailout -> enter Ion -> bailout loop with --ion-eager. + // When pgo is enabled, increment the counter of the block in which we + // resume, as Ion does not keep track of the code coverage. // - // The algorithm below is the "tortoise and the hare" algorithm. See bug - // 994444 for more explanation. - jsbytecode* skippedLoopHead = nullptr; - jsbytecode* fasterPc = pc; - while (true) { - pc = GetNextNonLoopHeadPc(pc, &skippedLoopHead); - fasterPc = GetNextNonLoopHeadPc(fasterPc, &skippedLoopHead); - fasterPc = GetNextNonLoopHeadPc(fasterPc, &skippedLoopHead); - if (fasterPc == pc) { - break; - } + // We need to do that when pgo is enabled, as after a specific number of + // FirstExecution bailouts, we invalidate and recompile the script with + // IonMonkey. Failing to increment the counter of the current basic block + // might lead to repeated bailouts and invalidations. + if (!JitOptions.disablePgo && script_->hasScriptCounts()) { + script_->incHitCount(pc_); } - return pc; + return true; } -static bool HasLiveStackValueAtDepth(HandleScript script, jsbytecode* pc, - uint32_t stackSlotIndex, - uint32_t stackDepth) { - // Return true iff stackSlotIndex is a stack value that's part of an active - // iterator loop instead of a normal expression stack slot. - - MOZ_ASSERT(stackSlotIndex < stackDepth); - - for (TryNoteIterAllNoGC tni(script, pc); !tni.done(); ++tni) { - const TryNote& tn = **tni; - - switch (tn.kind()) { - case TryNoteKind::ForIn: - case TryNoteKind::ForOf: - case TryNoteKind::Destructuring: - MOZ_ASSERT(tn.stackDepth <= stackDepth); - if (stackSlotIndex < tn.stackDepth) { - return true; - } - break; +void BaselineStackBuilder::setNextCallee(JSFunction* nextCallee) { + nextCallee_ = nextCallee; - default: - break; - } + if (JitOptions.warpBuilder) { + // Update icScript_ to point to the icScript of nextCallee + const uint32_t pcOff = script_->pcToOffset(pc_); + icScript_ = icScript_->findInlinedChild(pcOff); } - - return false; -} - -static bool IsPrologueBailout(const SnapshotIterator& iter, - const ExceptionBailoutInfo* excInfo) { - // If we are propagating an exception for debug mode, we will not resume - // into baseline code, but instead into HandleExceptionBaseline (i.e., - // never before the prologue). - return iter.pcOffset() == 0 && !iter.resumeAfter() && - (!excInfo || !excInfo->propagatingIonExceptionForDebugMode()); } -/* clang-format off */ -// For every inline frame, we write out the following data: -// -// | ... | -// +---------------+ -// | Descr(???) | --- Descr size here is (PREV_FRAME_SIZE) -// +---------------+ -// | ReturnAddr | -// -- +===============+ --- OVERWRITE STARTS HERE (START_STACK_ADDR) -// | | PrevFramePtr | -// | +-> +---------------+ -// | | | Baseline | -// | | | Frame | -// | | +---------------+ -// | | | Fixed0 | -// | | +---------------+ -// +--< | | ... | -// | | | +---------------+ -// | | | | FixedF | -// | | | +---------------+ -// | | | | Stack0 | -// | | | +---------------+ -// | | | | ... | -// | | | +---------------+ -// | | | | StackS | -// | -- | +---------------+ --- IF NOT LAST INLINE FRAME, -// +------------| Descr(BLJS) | --- CALLING INFO STARTS HERE -// | +---------------+ -// | | ReturnAddr | <-- return into main jitcode after IC -// -- | +===============+ -// | | | StubPtr | -// | | +---------------+ -// | +---| FramePtr | -// | +---------------+ --- The inlined frame might OSR in Ion -// | | Padding? | --- Thus the return address should be aligned. -// | +---------------+ -// +--< | ArgA | -// | | +---------------+ -// | | | ... | -// | | +---------------+ -// | | | Arg0 | -// | | +---------------+ -// | | | ThisV | -// | -- +---------------+ -// | | ActualArgC | -// | +---------------+ -// | | CalleeToken | -// | +---------------+ -// +------------| Descr(BLStub) | -// +---------------+ -// | ReturnAddr | <-- return into ICCall_Scripted IC -// -- +===============+ --- IF CALLEE FORMAL ARGS > ActualArgC -// | | Padding? | -// | +---------------+ -// | | UndefinedU | -// | +---------------+ -// | | ... | -// | +---------------+ -// | | Undefined0 | -// +--< +---------------+ -// | | | ArgA | -// | | +---------------+ -// | | | ... | -// | | +---------------+ -// | | | Arg0 | -// | | +---------------+ -// | | | ThisV | -// | -- +---------------+ -// | | ActualArgC | -// | +---------------+ -// | | CalleeToken | -// | +---------------+ -// +------------| Descr(Rect) | -// +---------------+ -// | ReturnAddr | <-- return into ArgumentsRectifier after call -// +===============+ -/* clang-format on */ -static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun, - HandleScript script, SnapshotIterator& iter, - bool invalidate, BaselineStackBuilder& builder, - MutableHandleValueVector startFrameFormals, - MutableHandleFunction nextCallee, - const ExceptionBailoutInfo* excInfo) { - // The Baseline frames we will reconstruct on the heap are not rooted, so GC - // must be suppressed here. - MOZ_ASSERT(cx->suppressGC); - - MOZ_ASSERT(script->hasBaselineScript()); - - // Are we catching an exception? - bool catchingException = excInfo && excInfo->catchingException(); - - // If we are catching an exception, we are bailing out to a catch or - // finally block and this is the frame where we will resume. Usually the - // expression stack should be empty in this case but there can be - // iterators on the stack. - uint32_t exprStackSlots; - if (catchingException) { - exprStackSlots = excInfo->numExprSlots(); - } else { - exprStackSlots = - iter.numAllocations() - (script->nfixed() + CountArgSlots(script, fun)); +bool BaselineStackBuilder::done() { + if (!iter_.moreFrames()) { + MOZ_ASSERT(!nextCallee_); + return true; } + return catchingException(); +} - builder.resetFramePushed(); - - // Build first baseline frame: - // +===============+ - // | PrevFramePtr | - // +---------------+ - // | Baseline | - // | Frame | - // +---------------+ - // | Fixed0 | - // +---------------+ - // | ... | - // +---------------+ - // | FixedF | - // +---------------+ - // | Stack0 | - // +---------------+ - // | ... | - // +---------------+ - // | StackS | - // +---------------+ --- IF NOT LAST INLINE FRAME, - // | Descr(BLJS) | --- CALLING INFO STARTS HERE - // +---------------+ - // | ReturnAddr | <-- return into main jitcode after IC - // +===============+ +void BaselineStackBuilder::nextFrame() { + MOZ_ASSERT(nextCallee_); + fun_ = nextCallee_; + script_ = fun_->nonLazyScript(); + nextCallee_ = nullptr; - JitSpew(JitSpew_BaselineBailouts, " Unpacking %s:%u:%u", - script->filename(), script->lineno(), script->column()); - JitSpew(JitSpew_BaselineBailouts, " [BASELINE-JS FRAME]"); + // Scripts with an IonScript must also have a BaselineScript. + MOZ_ASSERT(script_->hasBaselineScript()); - // Calculate and write the previous frame pointer value. - // Record the virtual stack offset at this location. Later on, if we end up - // writing out a BaselineStub frame for the next callee, we'll need to save - // the address. - void* prevFramePtr = builder.calculatePrevFramePtr(); - if (!builder.writePtr(prevFramePtr, "PrevFramePtr")) { - return false; - } - prevFramePtr = builder.virtualPointerAtStackOffset(0); + frameNo_++; + iter_.nextInstruction(); +} - // Write struct BaselineFrame. - if (!builder.subtract(BaselineFrame::Size(), "BaselineFrame")) { +// Build the BaselineFrame struct +bool BaselineStackBuilder::buildBaselineFrame() { + if (!subtract(BaselineFrame::Size(), "BaselineFrame")) { return false; } - BufferPointer blFrame = - builder.pointerAtStackOffset(0); + blFrame_.reset(); + blFrame_.emplace(pointerAtStackOffset(0)); uint32_t flags = BaselineFrame::RUNNING_IN_INTERPRETER; // If we are bailing to a script whose execution is observed, mark the // baseline frame as a debuggee frame. This is to cover the case where we // don't rematerialize the Ion frame via the Debugger. - if (script->isDebuggee()) { + if (script_->isDebuggee()) { flags |= BaselineFrame::DEBUGGEE; } - // Initialize BaselineFrame's envChain and argsObj JSObject* envChain = nullptr; Value returnValue = UndefinedValue(); ArgumentsObject* argsObj = nullptr; - BailoutKind bailoutKind = iter.bailoutKind(); - if (bailoutKind == Bailout_ArgumentCheck) { - // Skip the (unused) envChain, because it could be bogus (we can fail before - // the env chain slot is set) and use the function's initial environment. - // This will be fixed up later if needed in |FinishBailoutToBaseline|, which - // calls |EnsureHasEnvironmentObjects|. + + BailoutKind bailoutKind = iter_.bailoutKind(); + if (bailoutKind == BailoutKind::ArgumentCheck) { + // We may fail before the envChain slot is set. Skip it and use + // the function's initial environment. This will be fixed up + // later if needed in |FinishBailoutToBaseline|, which calls + // |EnsureHasEnvironmentObjects|. JitSpew(JitSpew_BaselineBailouts, - " Bailout_ArgumentCheck! (using function's environment)"); - iter.skip(); - envChain = fun->environment(); + " BailoutKind::ArgumentCheck! Using function's environment"); + envChain = fun_->environment(); + + // Skip envChain. + iter_.skip(); - // skip |return value| - iter.skip(); + // Skip return value. + iter_.skip(); // Scripts with |argumentsHasVarBinding| have an extra slot. - if (script->argumentsHasVarBinding()) { - JitSpew( - JitSpew_BaselineBailouts, - " Bailout_ArgumentCheck for script with argumentsHasVarBinding!" - "Using empty arguments object"); - iter.skip(); + // Skip argsObj if present. + if (script_->argumentsHasVarBinding()) { + JitSpew(JitSpew_BaselineBailouts, + " BailoutKind::ArgumentCheck for script with " + "argumentsHasVarBinding! " + "Using empty arguments object"); + iter_.skip(); } } else { - Value v = iter.read(); - if (v.isObject()) { - envChain = &v.toObject(); - - // If Ion has updated env slot from UndefinedValue, it will be the - // complete initial environment, so we can set the HAS_INITIAL_ENV - // flag if needed. - if (fun && fun->needsFunctionEnvironmentObjects()) { - MOZ_ASSERT(fun->nonLazyScript()->initialEnvironmentShape()); - MOZ_ASSERT(!fun->needsExtraBodyVarEnvironment()); + // Get |envChain|. + Value envChainSlot = iter_.read(); + if (envChainSlot.isObject()) { + // The env slot has been updated from UndefinedValue. It must be the + // complete initial environment. + envChain = &envChainSlot.toObject(); + + // Set the HAS_INITIAL_ENV flag if needed. + if (fun_ && fun_->needsFunctionEnvironmentObjects()) { + MOZ_ASSERT(fun_->nonLazyScript()->initialEnvironmentShape()); + MOZ_ASSERT(!fun_->needsExtraBodyVarEnvironment()); flags |= BaselineFrame::HAS_INITIAL_ENV; } } else { - MOZ_ASSERT(v.isUndefined() || v.isMagic(JS_OPTIMIZED_OUT)); - -#ifdef DEBUG - // The |envChain| slot must not be optimized out if the currently - // active scope requires any EnvironmentObjects beyond what is - // available at body scope. This checks that scope chain does not - // require any such EnvironmentObjects. - // See also: |CompileInfo::isObservableFrameSlot| - jsbytecode* pc = script->offsetToPC(iter.pcOffset()); - Scope* scopeIter = script->innermostScope(pc); - while (scopeIter != script->bodyScope()) { - MOZ_ASSERT(scopeIter); - MOZ_ASSERT(!scopeIter->hasEnvironment()); - scopeIter = scopeIter->enclosing(); - } -#endif - - // Get env chain from function or script. - if (fun) { - envChain = fun->environment(); - } else if (script->module()) { - envChain = script->module()->environment(); + MOZ_ASSERT(envChainSlot.isUndefined() || + envChainSlot.isMagic(JS_OPTIMIZED_OUT)); + MOZ_ASSERT(envChainSlotCanBeOptimized()); + + // The env slot has been optimized out. + // Get it from the function or script. + if (fun_) { + envChain = fun_->environment(); + } else if (script_->module()) { + envChain = script_->module()->environment(); } else { // For global scripts without a non-syntactic env the env - // chain is the script's global lexical environment (Ion does + // chain is the script's global lexical environment. (We do // not compile scripts with a non-syntactic global scope). // Also note that it's invalid to resume into the prologue in // this case because the prologue expects the env chain in R1 // for eval and global scripts. - MOZ_ASSERT(!script->isForEval()); - MOZ_ASSERT(!script->hasNonSyntacticScope()); - envChain = &(script->global().lexicalEnvironment()); + MOZ_ASSERT(!script_->isForEval()); + MOZ_ASSERT(!script_->hasNonSyntacticScope()); + envChain = &(script_->global().lexicalEnvironment()); } } - if (script->noScriptRval()) { + // Get |returnValue| if present. + if (script_->noScriptRval()) { // Don't use the return value (likely a JS_OPTIMIZED_OUT MagicValue) to // not confuse Baseline. - iter.skip(); + iter_.skip(); } else { - // Make sure to add HAS_RVAL to |flags| and not blFrame->flags because - // blFrame->setFlags(flags) below clobbers all frame flags. + returnValue = iter_.read(); flags |= BaselineFrame::HAS_RVAL; - returnValue = iter.read(); } - // If script maybe has an arguments object, the third slot will hold it. - if (script->argumentsHasVarBinding()) { - v = iter.read(); - MOZ_ASSERT(v.isObject() || v.isUndefined() || - v.isMagic(JS_OPTIMIZED_OUT)); - if (v.isObject()) { - argsObj = &v.toObject().as(); + // Get |argsObj| if present. + if (script_->argumentsHasVarBinding()) { + Value maybeArgsObj = iter_.read(); + MOZ_ASSERT(maybeArgsObj.isObject() || maybeArgsObj.isUndefined() || + maybeArgsObj.isMagic(JS_OPTIMIZED_OUT)); + if (maybeArgsObj.isObject()) { + argsObj = &maybeArgsObj.toObject().as(); } } } - MOZ_ASSERT(envChain); + // Write |envChain|. JitSpew(JitSpew_BaselineBailouts, " EnvChain=%p", envChain); - blFrame->setEnvironmentChain(envChain); + blFrame()->setEnvironmentChain(envChain); + + // Write |returnValue|. JitSpew(JitSpew_BaselineBailouts, " ReturnValue=%016" PRIx64, *((uint64_t*)&returnValue)); - blFrame->setReturnValue(returnValue); + blFrame()->setReturnValue(returnValue); + + // Note: we do not need to initialize the scratchValue field in BaselineFrame. + + // Write |flags|. + blFrame()->setFlags(flags); - // Do not need to initialize scratchValue field in BaselineFrame. - blFrame->setFlags(flags); + // Write |icScript|. + if (JitOptions.warpBuilder) { + JitSpew(JitSpew_BaselineBailouts, " ICScript=%p", icScript_); + blFrame()->setICScript(icScript_); + } // initArgsObjUnchecked modifies the frame's flags, so call it after setFlags. if (argsObj) { - blFrame->initArgsObjUnchecked(*argsObj); + blFrame()->initArgsObjUnchecked(*argsObj); } + return true; +} - if (fun) { - // The unpacked thisv and arguments should overwrite the pushed args present - // in the calling frame. - Value thisv = iter.read(); - JitSpew(JitSpew_BaselineBailouts, " Is function!"); - JitSpew(JitSpew_BaselineBailouts, " thisv=%016" PRIx64, - *((uint64_t*)&thisv)); +// Overwrite the pushed args present in the calling frame with +// the unpacked |thisv| and argument values. +bool BaselineStackBuilder::buildArguments() { + Value thisv = iter_.read(); + JitSpew(JitSpew_BaselineBailouts, " Is function!"); + JitSpew(JitSpew_BaselineBailouts, " thisv=%016" PRIx64, + *((uint64_t*)&thisv)); - size_t thisvOffset = builder.framePushed() + JitFrameLayout::offsetOfThis(); - builder.valuePointerAtStackOffset(thisvOffset).set(thisv); + size_t thisvOffset = framePushed() + JitFrameLayout::offsetOfThis(); + valuePointerAtStackOffset(thisvOffset).set(thisv); - MOZ_ASSERT(iter.numAllocations() >= CountArgSlots(script, fun)); - JitSpew(JitSpew_BaselineBailouts, - " frame slots %u, nargs %zu, nfixed %zu", - iter.numAllocations(), fun->nargs(), script->nfixed()); - - bool argsObjAliasesFormals = script->argsObjAliasesFormals(); - if (frameNo == 0 && !argsObjAliasesFormals) { - // This is the first (outermost) frame and we don't have an - // arguments object aliasing the formals. Store the formals in a - // Vector until we are done. Due to UCE and phi elimination, we - // could store an UndefinedValue() here for formals we think are - // unused, but locals may still reference the original argument slot - // (MParameter/LArgument) and expect the original Value. - MOZ_ASSERT(startFrameFormals.empty()); - if (!startFrameFormals.resize(fun->nargs())) { - return false; - } + MOZ_ASSERT(iter_.numAllocations() >= CountArgSlots(script_, fun_)); + JitSpew(JitSpew_BaselineBailouts, + " frame slots %u, nargs %zu, nfixed %zu", iter_.numAllocations(), + fun_->nargs(), script_->nfixed()); + + bool shouldStoreOutermostFormals = + isOutermostFrame() && !script_->argsObjAliasesFormals(); + if (shouldStoreOutermostFormals) { + // This is the first (outermost) frame and we don't have an + // arguments object aliasing the formals. Due to UCE and phi + // elimination, we could store an UndefinedValue() here for + // formals we think are unused, but locals may still reference the + // original argument slot (MParameter/LArgument) and expect the + // original Value. To avoid this problem, store the formals in a + // Vector until we are done. + MOZ_ASSERT(outermostFrameFormals().empty()); + if (!outermostFrameFormals().resize(fun_->nargs())) { + return false; } + } - for (uint32_t i = 0; i < fun->nargs(); i++) { - Value arg = iter.read(); - JitSpew(JitSpew_BaselineBailouts, " arg %d = %016" PRIx64, (int)i, - *((uint64_t*)&arg)); - if (frameNo > 0) { - size_t argOffset = - builder.framePushed() + JitFrameLayout::offsetOfActualArg(i); - builder.valuePointerAtStackOffset(argOffset).set(arg); - } else if (argsObjAliasesFormals) { - // When the arguments object aliases the formal arguments, then - // JSOp::SetArg mutates the argument object. In such cases, the - // list of arguments reported by the snapshot are only aliases - // of argument object slots which are optimized to only store - // differences compared to arguments which are on the stack. - } else { - startFrameFormals[i].set(arg); - } + for (uint32_t i = 0; i < fun_->nargs(); i++) { + Value arg = iter_.read(); + JitSpew(JitSpew_BaselineBailouts, " arg %d = %016" PRIx64, (int)i, + *((uint64_t*)&arg)); + if (!isOutermostFrame()) { + size_t argOffset = framePushed() + JitFrameLayout::offsetOfActualArg(i); + valuePointerAtStackOffset(argOffset).set(arg); + } else if (shouldStoreOutermostFormals) { + outermostFrameFormals()[i].set(arg); + } else { + // When the arguments object aliases the formal arguments, then + // JSOp::SetArg mutates the argument object. In such cases, the + // list of arguments reported by the snapshot are only aliases + // of argument object slots which are optimized to only store + // differences compared to arguments which are on the stack. } } + return true; +} - for (uint32_t i = 0; i < script->nfixed(); i++) { - Value slot = iter.read(); - if (!builder.writeValue(slot, "FixedValue")) { +bool BaselineStackBuilder::buildFixedSlots() { + for (uint32_t i = 0; i < script_->nfixed(); i++) { + Value slot = iter_.read(); + if (!writeValue(slot, "FixedValue")) { return false; } } + return true; +} - // Get the pc. If we are handling an exception, resume at the pc of the - // catch or finally block. - jsbytecode* const pc = catchingException - ? excInfo->resumePC() - : script->offsetToPC(iter.pcOffset()); - const bool resumeAfter = catchingException ? false : iter.resumeAfter(); +// The caller side of inlined JSOp::FunCall, JSOp::FunApply, and +// accessors must look like the function wasn't inlined. +bool BaselineStackBuilder::fixUpCallerArgs( + MutableHandleValueVector savedCallerArgs, bool* fixedUp) { + MOZ_ASSERT(!*fixedUp); - // When pgo is enabled, increment the counter of the block in which we - // resume, as Ion does not keep track of the code coverage. - // - // We need to do that when pgo is enabled, as after a specific number of - // FirstExecution bailouts, we invalidate and recompile the script with - // IonMonkey. Failing to increment the counter of the current basic block - // might lead to repeated bailouts and invalidations. - if (!JitOptions.disablePgo && script->hasScriptCounts()) { - script->incHitCount(pc); - } + // Inlining of SpreadCall-like frames not currently supported. + MOZ_ASSERT(!IsSpreadOp(op_)); - const JSOp op = JSOp(*pc); + if (op_ != JSOp::FunCall && !needToSaveCallerArgs()) { + return true; + } - // Inlining of SpreadCall-like frames not currently supported. - MOZ_ASSERT_IF(IsSpreadOp(op), !iter.moreFrames()); - - // Fixup inlined JSOp::FunCall, JSOp::FunApply, and accessors on the caller - // side. On the caller side this must represent like the function wasn't - // inlined. - uint32_t pushedSlots = 0; - RootedValueVector savedCallerArgs(cx); - bool needToSaveArgs = - op == JSOp::FunApply || IsIonInlinableGetterOrSetterOp(op); - if (iter.moreFrames() && (op == JSOp::FunCall || needToSaveArgs)) { - uint32_t inlined_args = 0; - if (op == JSOp::FunCall) { - inlined_args = 2 + GET_ARGC(pc) - 1; - } else if (op == JSOp::FunApply) { - inlined_args = 2 + blFrame->numActualArgs(); - } else { - MOZ_ASSERT(IsIonInlinableGetterOrSetterOp(op)); - inlined_args = 2 + IsSetPropOp(op); + // Calculate how many arguments are consumed by the inlined call. + // All calls pass |callee| and |this|. + uint32_t inlinedArgs = 2; + if (op_ == JSOp::FunCall) { + // The first argument to an inlined FunCall becomes |this|, + // if it exists. The rest are passed normally. + inlinedArgs += GET_ARGC(pc_) > 0 ? GET_ARGC(pc_) - 1 : 0; + } else if (op_ == JSOp::FunApply) { + // We currently only support FunApplyArgs. The number of arguments + // passed to the inlined function is the number of arguments to the + // current frame. + inlinedArgs += blFrame()->numActualArgs(); + } else { + MOZ_ASSERT(IsIonInlinableGetterOrSetterOp(op_)); + // Setters are passed one argument. Getters are passed none. + if (IsSetPropOp(op_)) { + inlinedArgs++; } + } - MOZ_ASSERT(exprStackSlots >= inlined_args); - pushedSlots = exprStackSlots - inlined_args; + // Calculate how many values are live on the stack across the call, + // and push them. + MOZ_ASSERT(inlinedArgs <= exprStackSlots()); + uint32_t liveStackSlots = exprStackSlots() - inlinedArgs; - JitSpew(JitSpew_BaselineBailouts, - " pushing %u expression stack slots before fixup", - pushedSlots); - for (uint32_t i = 0; i < pushedSlots; i++) { - Value v = iter.read(); - if (!builder.writeValue(v, "StackValue")) { - return false; - } + JitSpew(JitSpew_BaselineBailouts, + " pushing %u expression stack slots before fixup", + liveStackSlots); + for (uint32_t i = 0; i < liveStackSlots; i++) { + Value v = iter_.read(); + if (!writeValue(v, "StackValue")) { + return false; } + } - if (op == JSOp::FunCall) { - // When funcall got inlined and the native js_fun_call was bypassed, - // the stack state is incorrect. To restore correctly it must look like - // js_fun_call was actually called. This means transforming the stack - // from |target, this, args| to |js_fun_call, target, this, args| - // The js_fun_call is never read, so just pushing undefined now. - JitSpew(JitSpew_BaselineBailouts, - " pushing undefined to fixup funcall"); - if (!builder.writeValue(UndefinedValue(), "StackValue")) { - return false; - } + // When we inline JSOp::FunCall or JSOp::FunApply, we bypass the + // native and inline the target directly. When rebuilding the stack, + // we need to fill in the right number of slots to make it look like + // the js_native was actually called. + if (op_ == JSOp::FunCall) { + // We must transform the stack from |target, this, args| to + // |js_fun_call, target, this, args|. The value of |js_fun_call| + // will never be observed, so we push |undefined| for it, followed + // by the remaining arguments. + JitSpew(JitSpew_BaselineBailouts, + " pushing undefined to fixup funcall"); + if (!writeValue(UndefinedValue(), "StackValue")) { + return false; } - - if (needToSaveArgs) { - // When an accessor is inlined, the whole thing is a lie. There - // should never have been a call there. Fix the caller's stack to - // forget it ever happened. - - // When funapply gets inlined we take all arguments out of the - // arguments array. So the stack state is incorrect. To restore - // correctly it must look like js_fun_apply was actually called. - // This means transforming the stack from |target, this, arg1, ...| - // to |js_fun_apply, target, this, argObject|. - // Since the information is never read, we can just push undefined - // for all values. - if (op == JSOp::FunApply) { - JitSpew(JitSpew_BaselineBailouts, - " pushing 4x undefined to fixup funapply"); - if (!builder.writeValue(UndefinedValue(), "StackValue")) { - return false; - } - if (!builder.writeValue(UndefinedValue(), "StackValue")) { - return false; - } - if (!builder.writeValue(UndefinedValue(), "StackValue")) { - return false; - } - if (!builder.writeValue(UndefinedValue(), "StackValue")) { + if (GET_ARGC(pc_) > 0) { + JitSpew(JitSpew_BaselineBailouts, + " pushing %u expression stack slots", inlinedArgs); + for (uint32_t i = 0; i < inlinedArgs; i++) { + Value arg = iter_.read(); + if (!writeValue(arg, "StackValue")) { return false; } } - // Save the actual arguments. They are needed on the callee side - // as the arguments. Else we can't recover them. - if (!savedCallerArgs.resize(inlined_args)) { + } else { + // When we inline FunCall with no arguments, we push an extra + // |undefined| value for |this|. That value should not appear + // in the rebuilt baseline frame. + JitSpew(JitSpew_BaselineBailouts, " pushing target of funcall"); + Value target = iter_.read(); + if (!writeValue(target, "StackValue")) { return false; } - for (uint32_t i = 0; i < inlined_args; i++) { - savedCallerArgs[i].set(iter.read()); - } + // Skip |this|. + iter_.skip(); + } + } else if (op_ == JSOp::FunApply) { + // We currently only support FunApplyArgs. We must transform the + // stack from |target, this, arg1, ...| to |js_fun_apply, target, + // this, argObject|. These values will never be observed, so we + // can just push |undefined|. + JitSpew(JitSpew_BaselineBailouts, + " pushing 4x undefined to fixup funapply"); + if (!writeValue(UndefinedValue(), "StackValue") || + !writeValue(UndefinedValue(), "StackValue") || + !writeValue(UndefinedValue(), "StackValue") || + !writeValue(UndefinedValue(), "StackValue")) { + return false; + } + } - if (IsSetPropOp(op)) { - // We would love to just save all the arguments and leave them - // in the stub frame pushed below, but we will lose the inital - // argument which the function was called with, which we must - // leave on the stack. It's pushed as the result of the SetProp. - Value initialArg = savedCallerArgs[inlined_args - 1]; - JitSpew(JitSpew_BaselineBailouts, - " pushing setter's initial argument"); - if (!builder.writeValue(initialArg, "StackValue")) { - return false; - } + if (needToSaveCallerArgs()) { + // Save the actual arguments. They are needed to rebuild the callee frame. + if (!savedCallerArgs.resize(inlinedArgs)) { + return false; + } + for (uint32_t i = 0; i < inlinedArgs; i++) { + savedCallerArgs[i].set(iter_.read()); + } + + if (IsSetPropOp(op_)) { + // The RHS argument to SetProp remains on the stack after the + // operation and is observable, so we have to fill it in. + Value initialArg = savedCallerArgs[inlinedArgs - 1]; + JitSpew(JitSpew_BaselineBailouts, + " pushing setter's initial argument"); + if (!writeValue(initialArg, "StackValue")) { + return false; } - pushedSlots = exprStackSlots; } } + *fixedUp = true; + return true; +} + +bool BaselineStackBuilder::buildExpressionStack() { JitSpew(JitSpew_BaselineBailouts, " pushing %u expression stack slots", - exprStackSlots - pushedSlots); - for (uint32_t i = pushedSlots; i < exprStackSlots; i++) { + exprStackSlots()); + for (uint32_t i = 0; i < exprStackSlots(); i++) { Value v; - if (!iter.moreFrames() && i == exprStackSlots - 1 && - cx->hasIonReturnOverride()) { + if (!iter_.moreFrames() && i == exprStackSlots() - 1 && + cx_->hasIonReturnOverride()) { // If coming from an invalidation bailout, and this is the topmost // value, and a value override has been specified, don't read from the // iterator. Otherwise, we risk using a garbage value. - MOZ_ASSERT(invalidate); - iter.skip(); + // TODO(post-Warp): Remove value overrides and AutoDetectInvalidation. + iter_.skip(); JitSpew(JitSpew_BaselineBailouts, " [Return Override]"); - v = cx->takeIonReturnOverride(); - } else if (excInfo && excInfo->propagatingIonExceptionForDebugMode()) { + v = cx_->takeIonReturnOverride(); + } else if (propagatingIonExceptionForDebugMode()) { // If we are in the middle of propagating an exception from Ion by // bailing to baseline due to debug mode, we might not have all // the stack if we are at the newest frame. @@ -992,167 +928,63 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun, // possible nothing was pushed before we threw. We can't drop // iterators, however, so read them out. They will be closed by // HandleExceptionBaseline. - MOZ_ASSERT(cx->realm()->isDebuggee() || cx->isPropagatingForcedReturn()); - if (iter.moreFrames() || - HasLiveStackValueAtDepth(script, pc, i, exprStackSlots)) { - v = iter.read(); + MOZ_ASSERT(cx_->realm()->isDebuggee() || + cx_->isPropagatingForcedReturn()); + if (iter_.moreFrames() || hasLiveStackValueAtDepth(i)) { + v = iter_.read(); } else { - iter.skip(); + iter_.skip(); v = MagicValue(JS_OPTIMIZED_OUT); } } else { - v = iter.read(); + v = iter_.read(); } - if (!builder.writeValue(v, "StackValue")) { + if (!writeValue(v, "StackValue")) { return false; } } - // BaselineFrame::frameSize is the size of everything pushed since - // the builder.resetFramePushed() call. - const uint32_t frameSize = builder.framePushed(); -#ifdef DEBUG - blFrame->setDebugFrameSize(frameSize); -#endif - JitSpew(JitSpew_BaselineBailouts, " FrameSize=%u", frameSize); - - // debugNumValueSlots() is based on the frame size, do some sanity checks. - MOZ_ASSERT(blFrame->debugNumValueSlots() >= script->nfixed()); - MOZ_ASSERT(blFrame->debugNumValueSlots() <= script->nslots()); + return true; +} - const uint32_t pcOff = script->pcToOffset(pc); - JitScript* jitScript = script->jitScript(); +bool BaselineStackBuilder::prepareForNextFrame( + HandleValueVector savedCallerArgs) { + const uint32_t frameSize = framePushed(); -#ifdef DEBUG - uint32_t expectedDepth; - bool reachablePC; - if (!ReconstructStackDepth(cx, script, resumeAfter ? GetNextPc(pc) : pc, - &expectedDepth, &reachablePC)) { + // Write out descriptor and return address for the baseline frame. + // The icEntry in question MUST have an inlinable fallback stub. + if (!finishOuterFrame(frameSize)) { return false; } - if (reachablePC) { - if (op != JSOp::FunApply || !iter.moreFrames() || resumeAfter) { - if (op == JSOp::FunCall) { - // For fun.call(this, ...); the reconstructStackDepth will - // include the this. When inlining that is not included. - // So the exprStackSlots will be one less. - MOZ_ASSERT(expectedDepth - exprStackSlots <= 1); - } else if (iter.moreFrames() && IsIonInlinableGetterOrSetterOp(op)) { - // Accessors coming out of ion are inlined via a complete - // lie perpetrated by the compiler internally. Ion just rearranges - // the stack, and pretends that it looked like a call all along. - // This means that the depth is actually one *more* than expected - // by the interpreter, as there is now a JSFunction, |this| and [arg], - // rather than the expected |this| and [arg]. - // If the inlined accessor is a getelem operation, the numbers do match, - // but that's just because getelem expects one more item on the stack. - // Note that none of that was pushed, but it's still reflected - // in exprStackSlots. - MOZ_ASSERT(exprStackSlots - expectedDepth == (IsGetElemOp(op) ? 0 : 1)); - } else { - // For fun.apply({}, arguments) the reconstructStackDepth will - // have stackdepth 4, but it could be that we inlined the - // funapply. In that case exprStackSlots, will have the real - // arguments in the slots and not be 4. - MOZ_ASSERT(exprStackSlots == expectedDepth); - } - } - } -#endif + return buildStubFrame(frameSize, savedCallerArgs); +} -#ifdef JS_JITSPEW - JitSpew(JitSpew_BaselineBailouts, - " Resuming %s pc offset %d (op %s) (line %u) of %s:%u:%u", - resumeAfter ? "after" : "at", (int)pcOff, CodeName(op), - PCToLineNumber(script, pc), script->filename(), script->lineno(), - script->column()); - JitSpew(JitSpew_BaselineBailouts, " Bailout kind: %s", - BailoutKindString(bailoutKind)); -#endif +bool BaselineStackBuilder::finishOuterFrame(uint32_t frameSize) { + // . . + // | Descr(BLJS) | + // +---------------+ + // | ReturnAddr | + // +===============+ const BaselineInterpreter& baselineInterp = - cx->runtime()->jitRuntime()->baselineInterpreter(); - - // If this was the last inline frame, or we are bailing out to a catch or - // finally block in this frame, then unpacking is almost done. - if (!iter.moreFrames() || catchingException) { - builder.setResumeFramePtr(prevFramePtr); - builder.setFrameSizeOfInnerMostFrame(frameSize); - - // Compute the native address (within the Baseline Interpreter) that we will - // resume at and initialize the frame's interpreter fields. - uint8_t* resumeAddr; - if (IsPrologueBailout(iter, excInfo)) { - JitSpew(JitSpew_BaselineBailouts, " Resuming into prologue."); - MOZ_ASSERT(pc == script->code()); - blFrame->setInterpreterFieldsForPrologue(script); - resumeAddr = baselineInterp.bailoutPrologueEntryAddr(); - } else if (excInfo && excInfo->propagatingIonExceptionForDebugMode()) { - // When propagating an exception for debug mode, set the - // resume pc to the throwing pc, so that Debugger hooks report - // the correct pc offset of the throwing op instead of its - // successor. - jsbytecode* throwPC = script->offsetToPC(iter.pcOffset()); - blFrame->setInterpreterFields(script, throwPC); - resumeAddr = baselineInterp.interpretOpAddr().value; - } else { - // If the opcode is monitored we should monitor the top stack value when - // we finish the bailout in FinishBailoutToBaseline. - if (resumeAfter && BytecodeOpHasTypeSet(op)) { - builder.setMonitorPC(pc); - } - jsbytecode* resumePC = GetResumePC(script, pc, resumeAfter); - blFrame->setInterpreterFields(script, resumePC); - resumeAddr = baselineInterp.interpretOpAddr().value; - } - builder.setResumeAddr(resumeAddr); - JitSpew(JitSpew_BaselineBailouts, " Set resumeAddr=%p", resumeAddr); - - if (cx->runtime()->geckoProfiler().enabled()) { - // Register bailout with profiler. - const char* filename = script->filename(); - if (filename == nullptr) { - filename = ""; - } - unsigned len = strlen(filename) + 200; - UniqueChars buf(js_pod_malloc(len)); - if (buf == nullptr) { - ReportOutOfMemory(cx); - return false; - } - snprintf(buf.get(), len, "%s %s %s on line %u of %s:%u", - BailoutKindString(bailoutKind), resumeAfter ? "after" : "at", - CodeName(op), PCToLineNumber(script, pc), filename, - script->lineno()); - cx->runtime()->geckoProfiler().markEvent(buf.get()); - } - - return true; - } + cx_->runtime()->jitRuntime()->baselineInterpreter(); - // This is an outer frame for an inlined getter/setter/call. - - blFrame->setInterpreterFields(script, pc); + blFrame()->setInterpreterFields(script_, pc_); // Write out descriptor of BaselineJS frame. size_t baselineFrameDescr = MakeFrameDescriptor( - (uint32_t)builder.framePushed(), FrameType::BaselineJS, - BaselineStubFrameLayout::Size()); - if (!builder.writeWord(baselineFrameDescr, "Descriptor")) { + frameSize, FrameType::BaselineJS, BaselineStubFrameLayout::Size()); + if (!writeWord(baselineFrameDescr, "Descriptor")) { return false; } - // Calculate and write out return address. - // The icEntry in question MUST have an inlinable fallback stub. - ICEntry& icEntry = jitScript->icEntryFromPCOffset(pcOff); - MOZ_ASSERT(IsInlinableFallback(icEntry.fallbackStub())); - - uint8_t* retAddr = baselineInterp.retAddrForIC(JSOp(*pc)); - if (!builder.writePtr(retAddr, "ReturnAddr")) { - return false; - } + uint8_t* retAddr = baselineInterp.retAddrForIC(op_); + return writePtr(retAddr, "ReturnAddr"); +} +bool BaselineStackBuilder::buildStubFrame(uint32_t frameSize, + HandleValueVector savedCallerArgs) { // Build baseline stub frame: // +===============+ // | StubPtr | @@ -1180,96 +1012,118 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun, JitSpew(JitSpew_BaselineBailouts, " [BASELINE-STUB FRAME]"); - size_t startOfBaselineStubFrame = builder.framePushed(); + size_t startOfBaselineStubFrame = framePushed(); // Write stub pointer. + uint32_t pcOff = script_->pcToOffset(pc_); + ICEntry& icEntry = script_->jitScript()->icEntryFromPCOffset(pcOff); MOZ_ASSERT(IsInlinableFallback(icEntry.fallbackStub())); - if (!builder.writePtr(icEntry.fallbackStub(), "StubPtr")) { + if (!writePtr(icEntry.fallbackStub(), "StubPtr")) { return false; } // Write previous frame pointer (saved earlier). - if (!builder.writePtr(prevFramePtr, "PrevFramePtr")) { + if (!writePtr(prevFramePtr(), "PrevFramePtr")) { return false; } - prevFramePtr = builder.virtualPointerAtStackOffset(0); + prevFramePtr_ = virtualPointerAtStackOffset(0); - // Write out actual arguments (and thisv), copied from unpacked stack of - // BaselineJS frame. Arguments are reversed on the BaselineJS frame's stack + // Write out the arguments, copied from the baseline frame. The order + // of the arguments is reversed relative to the baseline frame's stack // values. - MOZ_ASSERT(IsIonInlinableOp(op)); - bool pushedNewTarget = IsConstructPC(pc); + MOZ_ASSERT(IsIonInlinableOp(op_)); + bool pushedNewTarget = IsConstructPC(pc_); unsigned actualArgc; Value callee; - if (needToSaveArgs) { + if (needToSaveCallerArgs()) { // For FunApply or an accessor, the arguments are not on the stack anymore, // but they are copied in a vector and are written here. - if (op == JSOp::FunApply) { - actualArgc = blFrame->numActualArgs(); + if (op_ == JSOp::FunApply) { + actualArgc = blFrame()->numActualArgs(); } else { - actualArgc = IsSetPropOp(op); + actualArgc = IsSetPropOp(op_); } callee = savedCallerArgs[0]; // Align the stack based on the number of arguments. size_t afterFrameSize = (actualArgc + 1) * sizeof(Value) + JitFrameLayout::Size(); - if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, - "Padding")) { + if (!maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding")) { return false; } // Push arguments. - MOZ_ASSERT(actualArgc + 2 <= exprStackSlots); + MOZ_ASSERT(actualArgc + 2 <= exprStackSlots()); MOZ_ASSERT(savedCallerArgs.length() == actualArgc + 2); for (unsigned i = 0; i < actualArgc + 1; i++) { size_t arg = savedCallerArgs.length() - (i + 1); - if (!builder.writeValue(savedCallerArgs[arg], "ArgVal")) { + if (!writeValue(savedCallerArgs[arg], "ArgVal")) { return false; } } + } else if (op_ == JSOp::FunCall && GET_ARGC(pc_) == 0) { + // When calling FunCall with 0 arguments, we push |undefined| + // for this. See BaselineCacheIRCompiler::pushFunCallArguments. + MOZ_ASSERT(!pushedNewTarget); + actualArgc = 0; + // Align the stack based on pushing |this| and 0 arguments. + size_t afterFrameSize = sizeof(Value) + JitFrameLayout::Size(); + if (!maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding")) { + return false; + } + // Push an undefined value for |this|. + if (!writeValue(UndefinedValue(), "ThisValue")) { + return false; + } + size_t calleeSlot = blFrame()->numValueSlots(frameSize) - 1; + callee = *blFrame()->valueSlot(calleeSlot); + } else { - actualArgc = GET_ARGC(pc); - if (op == JSOp::FunCall) { + actualArgc = GET_ARGC(pc_); + if (op_ == JSOp::FunCall) { + // See BaselineCacheIRCompiler::pushFunCallArguments. MOZ_ASSERT(actualArgc > 0); actualArgc--; } + // In addition to the formal arguments, we must also push |this|. + // When calling a constructor, we must also push |newTarget|. + uint32_t numArguments = actualArgc + 1 + pushedNewTarget; + // Align the stack based on the number of arguments. - size_t afterFrameSize = (actualArgc + 1 + pushedNewTarget) * sizeof(Value) + - JitFrameLayout::Size(); - if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, - "Padding")) { + size_t afterFrameSize = + numArguments * sizeof(Value) + JitFrameLayout::Size(); + if (!maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding")) { return false; } // Copy the arguments and |this| from the BaselineFrame, in reverse order. - size_t valueSlot = blFrame->numValueSlots(frameSize) - 1; - size_t calleeSlot = valueSlot - actualArgc - 1 - pushedNewTarget; + size_t valueSlot = blFrame()->numValueSlots(frameSize) - 1; + size_t calleeSlot = valueSlot - numArguments; for (size_t i = valueSlot; i > calleeSlot; i--) { - Value v = *blFrame->valueSlot(i); - if (!builder.writeValue(v, "ArgVal")) { + Value v = *blFrame()->valueSlot(i); + if (!writeValue(v, "ArgVal")) { return false; } } - callee = *blFrame->valueSlot(calleeSlot); + callee = *blFrame()->valueSlot(calleeSlot); } // In case these arguments need to be copied on the stack again for a // rectifier frame, save the framePushed values here for later use. - size_t endOfBaselineStubArgs = builder.framePushed(); + size_t endOfBaselineStubArgs = framePushed(); // Calculate frame size for descriptor. size_t baselineStubFrameSize = - builder.framePushed() - startOfBaselineStubFrame; + endOfBaselineStubArgs - startOfBaselineStubFrame; size_t baselineStubFrameDescr = MakeFrameDescriptor((uint32_t)baselineStubFrameSize, FrameType::BaselineStub, JitFrameLayout::Size()); // Push actual argc - if (!builder.writeWord(actualArgc, "ActualArgc")) { + if (!writeWord(actualArgc, "ActualArgc")) { return false; } @@ -1278,41 +1132,45 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun, callee.asRawBits()); JSFunction* calleeFun = &callee.toObject().as(); - if (!builder.writePtr(CalleeToToken(calleeFun, pushedNewTarget), - "CalleeToken")) { + if (!writePtr(CalleeToToken(calleeFun, pushedNewTarget), "CalleeToken")) { return false; } - nextCallee.set(calleeFun); + setNextCallee(calleeFun); // Push BaselineStub frame descriptor - if (!builder.writeWord(baselineStubFrameDescr, "Descriptor")) { + if (!writeWord(baselineStubFrameDescr, "Descriptor")) { return false; } // Ensure we have a TypeMonitor fallback stub so we don't crash in JIT code // when we try to enter it. See callers of offsetOfFallbackMonitorStub. - if (BytecodeOpHasTypeSet(JSOp(*pc))) { + if (BytecodeOpHasTypeSet(op_) && IsTypeInferenceEnabled()) { ICFallbackStub* fallbackStub = icEntry.fallbackStub(); if (!fallbackStub->toMonitoredFallbackStub()->getFallbackMonitorStub( - cx, script)) { + cx_, script_)) { return false; } } // Push return address into ICCall_Scripted stub, immediately after the call. - void* baselineCallReturnAddr = GetStubReturnAddress(cx, op); + void* baselineCallReturnAddr = getStubReturnAddress(); MOZ_ASSERT(baselineCallReturnAddr); - if (!builder.writePtr(baselineCallReturnAddr, "ReturnAddr")) { + if (!writePtr(baselineCallReturnAddr, "ReturnAddr")) { return false; } - MOZ_ASSERT(builder.framePushed() % JitStackAlignment == 0); + MOZ_ASSERT(framePushed() % JitStackAlignment == 0); - // If actualArgc >= fun->nargs, then we are done. Otherwise, we need to push - // on a reconstructed rectifier frame. - if (actualArgc >= calleeFun->nargs()) { - return true; + // Build a rectifier frame if necessary + if (actualArgc < calleeFun->nargs() && + !buildRectifierFrame(actualArgc, endOfBaselineStubArgs)) { + return false; } + return true; +} + +bool BaselineStackBuilder::buildRectifierFrame(uint32_t actualArgc, + size_t endOfBaselineStubArgs) { // Push a reconstructed rectifier frame. // +===============+ // | Padding? | @@ -1341,94 +1199,406 @@ static bool InitFromBailout(JSContext* cx, size_t frameNo, HandleFunction fun, // +===============+ JitSpew(JitSpew_BaselineBailouts, " [RECTIFIER FRAME]"); + bool pushedNewTarget = IsConstructPC(pc_); - size_t startOfRectifierFrame = builder.framePushed(); + size_t startOfRectifierFrame = framePushed(); // On x86-only, the frame pointer is saved again in the rectifier frame. #if defined(JS_CODEGEN_X86) - if (!builder.writePtr(prevFramePtr, "PrevFramePtr-X86Only")) { + if (!writePtr(prevFramePtr(), "PrevFramePtr-X86Only")) { return false; } // Follow the same logic as in JitRuntime::generateArgumentsRectifier. - prevFramePtr = builder.virtualPointerAtStackOffset(0); - if (!builder.writePtr(prevFramePtr, "Padding-X86Only")) { + prevFramePtr_ = virtualPointerAtStackOffset(0); + if (!writePtr(prevFramePtr(), "Padding-X86Only")) { return false; } #endif // Align the stack based on the number of arguments. size_t afterFrameSize = - (calleeFun->nargs() + 1 + pushedNewTarget) * sizeof(Value) + + (nextCallee()->nargs() + 1 + pushedNewTarget) * sizeof(Value) + RectifierFrameLayout::Size(); - if (!builder.maybeWritePadding(JitStackAlignment, afterFrameSize, - "Padding")) { + if (!maybeWritePadding(JitStackAlignment, afterFrameSize, "Padding")) { return false; } // Copy new.target, if necessary. if (pushedNewTarget) { - size_t newTargetOffset = (builder.framePushed() - endOfBaselineStubArgs) + + size_t newTargetOffset = (framePushed() - endOfBaselineStubArgs) + (actualArgc + 1) * sizeof(Value); - Value newTargetValue = *builder.valuePointerAtStackOffset(newTargetOffset); - if (!builder.writeValue(newTargetValue, "CopiedNewTarget")) { + Value newTargetValue = *valuePointerAtStackOffset(newTargetOffset); + if (!writeValue(newTargetValue, "CopiedNewTarget")) { return false; } } // Push undefined for missing arguments. - for (unsigned i = 0; i < (calleeFun->nargs() - actualArgc); i++) { - if (!builder.writeValue(UndefinedValue(), "FillerVal")) { + for (unsigned i = 0; i < (nextCallee()->nargs() - actualArgc); i++) { + if (!writeValue(UndefinedValue(), "FillerVal")) { return false; } } // Copy arguments + thisv from BaselineStub frame. - if (!builder.subtract((actualArgc + 1) * sizeof(Value), "CopiedArgs")) { + if (!subtract((actualArgc + 1) * sizeof(Value), "CopiedArgs")) { return false; } - BufferPointer stubArgsEnd = builder.pointerAtStackOffset( - builder.framePushed() - endOfBaselineStubArgs); + BufferPointer stubArgsEnd = + pointerAtStackOffset(framePushed() - endOfBaselineStubArgs); JitSpew(JitSpew_BaselineBailouts, " MemCpy from %p", stubArgsEnd.get()); - memcpy(builder.pointerAtStackOffset(0).get(), stubArgsEnd.get(), + memcpy(pointerAtStackOffset(0).get(), stubArgsEnd.get(), (actualArgc + 1) * sizeof(Value)); // Calculate frame size for descriptor. - size_t rectifierFrameSize = builder.framePushed() - startOfRectifierFrame; + size_t rectifierFrameSize = framePushed() - startOfRectifierFrame; size_t rectifierFrameDescr = MakeFrameDescriptor((uint32_t)rectifierFrameSize, FrameType::Rectifier, JitFrameLayout::Size()); // Push actualArgc - if (!builder.writeWord(actualArgc, "ActualArgc")) { + if (!writeWord(actualArgc, "ActualArgc")) { return false; } // Push calleeToken again. - if (!builder.writePtr(CalleeToToken(calleeFun, pushedNewTarget), - "CalleeToken")) { + if (!writePtr(CalleeToToken(nextCallee(), pushedNewTarget), "CalleeToken")) { return false; } // Push rectifier frame descriptor - if (!builder.writeWord(rectifierFrameDescr, "Descriptor")) { + if (!writeWord(rectifierFrameDescr, "Descriptor")) { return false; } // Push return address into the ArgumentsRectifier code, immediately after the // ioncode call. void* rectReturnAddr = - cx->runtime()->jitRuntime()->getArgumentsRectifierReturnAddr().value; + cx_->runtime()->jitRuntime()->getArgumentsRectifierReturnAddr().value; MOZ_ASSERT(rectReturnAddr); - if (!builder.writePtr(rectReturnAddr, "ReturnAddr")) { + if (!writePtr(rectReturnAddr, "ReturnAddr")) { + return false; + } + MOZ_ASSERT(framePushed() % JitStackAlignment == 0); + + return true; +} + +bool BaselineStackBuilder::finishLastFrame() { + const BaselineInterpreter& baselineInterp = + cx_->runtime()->jitRuntime()->baselineInterpreter(); + + setResumeFramePtr(prevFramePtr()); + setFrameSizeOfInnerMostFrame(framePushed()); + + // Compute the native address (within the Baseline Interpreter) that we will + // resume at and initialize the frame's interpreter fields. + uint8_t* resumeAddr; + if (isPrologueBailout()) { + JitSpew(JitSpew_BaselineBailouts, " Resuming into prologue."); + MOZ_ASSERT(pc_ == script_->code()); + blFrame()->setInterpreterFieldsForPrologue(script_); + resumeAddr = baselineInterp.bailoutPrologueEntryAddr(); + } else if (propagatingIonExceptionForDebugMode()) { + // When propagating an exception for debug mode, set the + // resume pc to the throwing pc, so that Debugger hooks report + // the correct pc offset of the throwing op instead of its + // successor. + jsbytecode* throwPC = script_->offsetToPC(iter_.pcOffset()); + blFrame()->setInterpreterFields(script_, throwPC); + resumeAddr = baselineInterp.interpretOpAddr().value; + } else { + // If the opcode is monitored we should monitor the top stack value when + // we finish the bailout in FinishBailoutToBaseline. + if (resumeAfter() && BytecodeOpHasTypeSet(op_)) { + setMonitorPC(pc_); + } + jsbytecode* resumePC = getResumePC(); + blFrame()->setInterpreterFields(script_, resumePC); + resumeAddr = baselineInterp.interpretOpAddr().value; + } + setResumeAddr(resumeAddr); + JitSpew(JitSpew_BaselineBailouts, " Set resumeAddr=%p", resumeAddr); + + if (cx_->runtime()->geckoProfiler().enabled()) { + // Register bailout with profiler. + const char* filename = script_->filename(); + if (filename == nullptr) { + filename = ""; + } + unsigned len = strlen(filename) + 200; + UniqueChars buf(js_pod_malloc(len)); + if (buf == nullptr) { + ReportOutOfMemory(cx_); + return false; + } + snprintf(buf.get(), len, "%s %s %s on line %u of %s:%u", + BailoutKindString(iter_.bailoutKind()), + resumeAfter() ? "after" : "at", CodeName(op_), + PCToLineNumber(script_, pc_), filename, script_->lineno()); + cx_->runtime()->geckoProfiler().markEvent(buf.get()); + } + + return true; +} + +#ifdef DEBUG +// The |envChain| slot must not be optimized out if the currently +// active scope requires any EnvironmentObjects beyond what is +// available at body scope. This checks that scope chain does not +// require any such EnvironmentObjects. +// See also: |CompileInfo::isObservableFrameSlot| +bool BaselineStackBuilder::envChainSlotCanBeOptimized() { + jsbytecode* pc = script_->offsetToPC(iter_.pcOffset()); + Scope* scopeIter = script_->innermostScope(pc); + while (scopeIter != script_->bodyScope()) { + if (!scopeIter || scopeIter->hasEnvironment()) { + return false; + } + scopeIter = scopeIter->enclosing(); + } + return true; +} + +bool BaselineStackBuilder::validateFrame() { + const uint32_t frameSize = framePushed(); + blFrame()->setDebugFrameSize(frameSize); + JitSpew(JitSpew_BaselineBailouts, " FrameSize=%u", frameSize); + + // debugNumValueSlots() is based on the frame size, do some sanity checks. + MOZ_ASSERT(blFrame()->debugNumValueSlots() >= script_->nfixed()); + MOZ_ASSERT(blFrame()->debugNumValueSlots() <= script_->nslots()); + + uint32_t expectedDepth; + bool reachablePC; + jsbytecode* pcForStackDepth = resumeAfter() ? GetNextPc(pc_) : pc_; + if (!ReconstructStackDepth(cx_, script_, pcForStackDepth, &expectedDepth, + &reachablePC)) { return false; } - MOZ_ASSERT(builder.framePushed() % JitStackAlignment == 0); + if (!reachablePC) { + return true; + } + // For FunApplyArgs, the reconstructed stack depth will be 4, but we + // may have inlined the funapply. In that case, exprStackSlots will + // have the real arguments in the slots, and the stack depth may not + // be 4. Don't assert. + if (op_ == JSOp::FunApply && iter_.moreFrames() && !resumeAfter()) { + return true; + } + if (op_ == JSOp::FunCall) { + // For fun.call(this, ...); the reconstructed stack depth will + // include the this. When inlining that is not included. + // So the exprStackSlots will be one less. + MOZ_ASSERT(expectedDepth - exprStackSlots() <= 1); + } else if (iter_.moreFrames() && IsIonInlinableGetterOrSetterOp(op_)) { + // Accessors coming out of ion are inlined via a complete + // lie perpetrated by the compiler internally. Ion just rearranges + // the stack, and pretends that it looked like a call all along. + // This means that the depth is actually one *more* than expected + // by the interpreter, as there is now a JSFunction, |this| and [arg], + // rather than the expected |this| and [arg]. + // If the inlined accessor is a getelem operation, the numbers do match, + // but that's just because getelem expects one more item on the stack. + // Note that none of that was pushed, but it's still reflected + // in exprStackSlots. + MOZ_ASSERT(exprStackSlots() - expectedDepth == (IsGetElemOp(op_) ? 0 : 1)); + } else { + MOZ_ASSERT(exprStackSlots() == expectedDepth); + } return true; } +#endif + +void* BaselineStackBuilder::getStubReturnAddress() { + const BaselineICFallbackCode& code = + cx_->runtime()->jitRuntime()->baselineICFallbackCode(); + + if (IsGetPropOp(op_)) { + return code.bailoutReturnAddr(BailoutReturnKind::GetProp); + } + if (IsSetPropOp(op_)) { + return code.bailoutReturnAddr(BailoutReturnKind::SetProp); + } + if (IsGetElemOp(op_)) { + return code.bailoutReturnAddr(BailoutReturnKind::GetElem); + } + + // This should be a call op of some kind, now. + MOZ_ASSERT(IsInvokeOp(op_) && !IsSpreadOp(op_)); + if (IsConstructOp(op_)) { + return code.bailoutReturnAddr(BailoutReturnKind::New); + } + return code.bailoutReturnAddr(BailoutReturnKind::Call); +} + +static inline jsbytecode* GetNextNonLoopHeadPc(jsbytecode* pc, + jsbytecode** skippedLoopHead) { + JSOp op = JSOp(*pc); + switch (op) { + case JSOp::Goto: + return pc + GET_JUMP_OFFSET(pc); + + case JSOp::LoopHead: + *skippedLoopHead = pc; + return GetNextPc(pc); + + case JSOp::Nop: + return GetNextPc(pc); + + default: + return pc; + } +} + +// Returns the pc to resume execution at in Baseline after a bailout. +jsbytecode* BaselineStackBuilder::getResumePC() { + if (resumeAfter()) { + return GetNextPc(pc_); + } + + // If we are resuming at a LoopHead op, resume at the next op to avoid + // a bailout -> enter Ion -> bailout loop with --ion-eager. + // + // The algorithm below is the "tortoise and the hare" algorithm. See bug + // 994444 for more explanation. + jsbytecode* skippedLoopHead = nullptr; + jsbytecode* slowerPc = pc_; + jsbytecode* fasterPc = pc_; + while (true) { + slowerPc = GetNextNonLoopHeadPc(slowerPc, &skippedLoopHead); + fasterPc = GetNextNonLoopHeadPc(fasterPc, &skippedLoopHead); + fasterPc = GetNextNonLoopHeadPc(fasterPc, &skippedLoopHead); + if (fasterPc == slowerPc) { + break; + } + } + + return slowerPc; +} + +bool BaselineStackBuilder::hasLiveStackValueAtDepth(uint32_t stackSlotIndex) { + // Return true iff stackSlotIndex is a stack value that's part of an active + // iterator loop instead of a normal expression stack slot. + + MOZ_ASSERT(stackSlotIndex < exprStackSlots()); + + for (TryNoteIterAllNoGC tni(script_, pc_); !tni.done(); ++tni) { + const TryNote& tn = **tni; + + switch (tn.kind()) { + case TryNoteKind::ForIn: + case TryNoteKind::ForOf: + case TryNoteKind::Destructuring: + MOZ_ASSERT(tn.stackDepth <= exprStackSlots()); + if (stackSlotIndex < tn.stackDepth) { + return true; + } + break; + + default: + break; + } + } + + return false; +} + +bool BaselineStackBuilder::isPrologueBailout() { + // If we are propagating an exception for debug mode, we will not resume + // into baseline code, but instead into HandleExceptionBaseline (i.e., + // never before the prologue). + return iter_.pcOffset() == 0 && !iter_.resumeAfter() && + !propagatingIonExceptionForDebugMode(); +} + +// Build a baseline stack frame. +bool BaselineStackBuilder::buildOneFrame() { + // Build a baseline frame: + // +===============+ + // | PrevFramePtr | <-- initFrame() + // +---------------+ + // | Baseline | <-- buildBaselineFrame() + // | Frame | + // +---------------+ + // | Fixed0 | <-- buildFixedSlots() + // +---------------+ + // | ... | + // +---------------+ + // | FixedF | + // +---------------+ + // | Stack0 | <-- buildExpressionStack() -or- fixupCallerArgs() + // +---------------+ + // | ... | + // +---------------+ If we are building the frame in which we will + // | StackS | <-- resume, we stop here. + // +---------------+ finishLastFrame() sets up the interpreter fields. + // . . + // . . + // . . <-- If there are additional frames inlined into this + // | Descr(BLJS) | one, we finish this frame. We generate a stub + // +---------------+ frame (and maybe also a rectifier frame) between + // | ReturnAddr | this frame and the inlined frame. + // +===============+ See: prepareForNextFrame() + + if (!initFrame()) { + return false; + } + + if (!buildBaselineFrame()) { + return false; + } + + if (fun_ && !buildArguments()) { + return false; + } + + if (!buildFixedSlots()) { + return false; + } + + bool fixedUp = false; + RootedValueVector savedCallerArgs(cx_); + if (iter_.moreFrames() && !fixUpCallerArgs(&savedCallerArgs, &fixedUp)) { + return false; + } + + if (!fixedUp && !buildExpressionStack()) { + return false; + } + +#ifdef DEBUG + if (!validateFrame()) { + return false; + } +#endif + +#ifdef JS_JITSPEW + const uint32_t pcOff = script_->pcToOffset(pc()); + JitSpew(JitSpew_BaselineBailouts, + " Resuming %s pc offset %d (op %s) (line %u) of %s:%u:%u", + resumeAfter() ? "after" : "at", (int)pcOff, CodeName(op_), + PCToLineNumber(script_, pc()), script_->filename(), script_->lineno(), + script_->column()); + JitSpew(JitSpew_BaselineBailouts, " Bailout kind: %s", + BailoutKindString(iter_.bailoutKind())); +#endif + + // If this was the last inline frame, or we are bailing out to a catch or + // finally block in this frame, then unpacking is almost done. + if (done()) { + return finishLastFrame(); + } + + // Otherwise, this is an outer frame for an inlined call or + // accessor. We will be building an inner frame. Before that, + // we must create a stub frame, and potentially a rectifier frame. + return prepareForNextFrame(savedCallerArgs); +} bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, - const JSJitFrameIter& iter, bool invalidate, + const JSJitFrameIter& iter, BaselineBailoutInfo** bailoutInfo, const ExceptionBailoutInfo* excInfo) { MOZ_ASSERT(bailoutInfo != nullptr); @@ -1495,23 +1665,13 @@ bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, iter.script()->filename(), iter.script()->lineno(), iter.script()->column(), (void*)iter.ionScript(), (int)prevFrameType); - bool catchingException; - bool propagatingExceptionForDebugMode; if (excInfo) { - catchingException = excInfo->catchingException(); - propagatingExceptionForDebugMode = - excInfo->propagatingIonExceptionForDebugMode(); - - if (catchingException) { + if (excInfo->catchingException()) { JitSpew(JitSpew_BaselineBailouts, "Resuming in catch or finally block"); } - - if (propagatingExceptionForDebugMode) { + if (excInfo->propagatingIonExceptionForDebugMode()) { JitSpew(JitSpew_BaselineBailouts, "Resuming in-place for debug mode"); } - } else { - catchingException = false; - propagatingExceptionForDebugMode = false; } JitSpew(JitSpew_BaselineBailouts, @@ -1523,14 +1683,6 @@ bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, } iter.script()->updateJitCodeRaw(cx->runtime()); - // Allocate buffer to hold stack replacement data. - BaselineStackBuilder builder(cx, iter, 1024); - if (!builder.init()) { - return false; - } - JitSpew(JitSpew_BaselineBailouts, " Incoming frame ptr = %p", - builder.startFrame()); - // Under a bailout, there is no need to invalidate the frame after // evaluating the recover instruction, as the invalidation is only needed in // cases where the frame is introspected ahead of the bailout. @@ -1550,11 +1702,17 @@ bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, snapIter.spewBailingFrom(); #endif - RootedFunction callee(cx, iter.maybeCallee()); - RootedScript scr(cx, iter.script()); - if (callee) { + BaselineStackBuilder builder(cx, iter, snapIter, excInfo); + if (!builder.init()) { + return false; + } + + JitSpew(JitSpew_BaselineBailouts, " Incoming frame ptr = %p", + builder.startFrame()); + if (iter.maybeCallee()) { JitSpew(JitSpew_BaselineBailouts, " Callee function (%s:%u:%u)", - scr->filename(), scr->lineno(), scr->column()); + iter.script()->filename(), iter.script()->lineno(), + iter.script()->column()); } else { JitSpew(JitSpew_BaselineBailouts, " No callee!"); } @@ -1566,72 +1724,43 @@ bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, } JitSpew(JitSpew_BaselineBailouts, " Restoring frames:"); - size_t frameNo = 0; - - // Reconstruct baseline frames using the builder. - RootedFunction fun(cx, callee); - RootedValueVector startFrameFormals(cx); - - gc::AutoSuppressGC suppress(cx); while (true) { // Skip recover instructions as they are already recovered by // |initInstructionResults|. snapIter.settleOnFrame(); - if (frameNo > 0) { + if (!builder.isOutermostFrame()) { // TraceLogger doesn't create entries for inlined frames. But we // see them in Baseline. Here we create the start events of those // entries. So they correspond to what we will see in Baseline. - TraceLoggerEvent scriptEvent(TraceLogger_Scripts, scr); + TraceLoggerEvent scriptEvent(TraceLogger_Scripts, builder.script()); TraceLogStartEvent(logger, scriptEvent); TraceLogStartEvent(logger, TraceLogger_Baseline); } - JitSpew(JitSpew_BaselineBailouts, " FrameNo %zu", frameNo); + JitSpew(JitSpew_BaselineBailouts, " FrameNo %zu", builder.frameNo()); - // If we are bailing out to a catch or finally block in this frame, - // pass excInfo to InitFromBailout and don't unpack any other frames. - bool handleException = (catchingException && excInfo->frameNo() == frameNo); - - // We also need to pass excInfo if we're bailing out in place for - // debug mode. - bool passExcInfo = handleException || propagatingExceptionForDebugMode; - - RootedFunction nextCallee(cx, nullptr); - if (!InitFromBailout(cx, frameNo, fun, scr, snapIter, invalidate, builder, - &startFrameFormals, &nextCallee, - passExcInfo ? excInfo : nullptr)) { + if (!builder.buildOneFrame()) { MOZ_ASSERT(cx->isExceptionPending()); return false; } - if (!snapIter.moreFrames()) { - MOZ_ASSERT(!nextCallee); - break; - } - - if (handleException) { + if (builder.done()) { break; } - MOZ_ASSERT(nextCallee); - fun = nextCallee; - scr = fun->nonLazyScript(); - - frameNo++; - - snapIter.nextInstruction(); + builder.nextFrame(); } JitSpew(JitSpew_BaselineBailouts, " Done restoring frames"); BailoutKind bailoutKind = snapIter.bailoutKind(); - if (!startFrameFormals.empty()) { + if (!builder.outermostFrameFormals().empty()) { // Set the first frame's formals, see the comment in InitFromBailout. Value* argv = builder.startFrame()->argv() + 1; // +1 to skip |this|. - mozilla::PodCopy(argv, startFrameFormals.begin(), - startFrameFormals.length()); + mozilla::PodCopy(argv, builder.outermostFrameFormals().begin(), + builder.outermostFrameFormals().length()); } // Do stack check. @@ -1657,7 +1786,7 @@ bool jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, // Take the reconstructed baseline stack so it doesn't get freed when builder // destructs. info = builder.takeBuffer(); - info->numFrames = frameNo + 1; + info->numFrames = builder.frameNo() + 1; info->bailoutKind.emplace(bailoutKind); *bailoutInfo = info; guardRemoveRematerializedFramesFromDebugger.release(); @@ -1704,6 +1833,11 @@ static void HandleBoundsCheckFailure(JSContext* cx, HandleScript outerScript, static void HandleShapeGuardFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { + if (JitOptions.warpBuilder) { + // Warp handles this by invalidating when the IC stub changes. + return; + } + JitSpew(JitSpew_IonBailouts, "Shape guard failure %s:%u:%u, inlined into %s:%u:%u", innerScript->filename(), innerScript->lineno(), innerScript->column(), @@ -1720,6 +1854,11 @@ static void HandleShapeGuardFailure(JSContext* cx, HandleScript outerScript, static void HandleBaselineInfoBailout(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { + if (JitOptions.warpBuilder) { + // Warp handles this by invalidating when the IC stub changes. + return; + } + JitSpew(JitSpew_IonBailouts, "Baseline info failure %s:%u:%u, inlined into %s:%u:%u", innerScript->filename(), innerScript->lineno(), innerScript->column(), @@ -1972,64 +2111,90 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfoArg) { switch (bailoutKind) { // Normal bailouts. - case Bailout_Inevitable: - case Bailout_DuringVMCall: - case Bailout_TooManyArguments: - case Bailout_DynamicNameNotFound: - case Bailout_StringArgumentsEval: - case Bailout_Overflow: - case Bailout_Round: - case Bailout_NonPrimitiveInput: - case Bailout_PrecisionLoss: - case Bailout_TypeBarrierO: - case Bailout_TypeBarrierV: - case Bailout_ValueGuard: - case Bailout_NullOrUndefinedGuard: - case Bailout_MonitorTypes: - case Bailout_Hole: - case Bailout_NoDenseElementsGuard: - case Bailout_NegativeIndex: - case Bailout_NonInt32Input: - case Bailout_NonNumericInput: - case Bailout_NonBooleanInput: - case Bailout_NonObjectInput: - case Bailout_NonStringInput: - case Bailout_NonSymbolInput: - case Bailout_NonBigIntInput: - case Bailout_Debugger: - case Bailout_SpecificAtomGuard: - case Bailout_SpecificSymbolGuard: + case BailoutKind::Inevitable: + case BailoutKind::DuringVMCall: + case BailoutKind::TooManyArguments: + case BailoutKind::DynamicNameNotFound: + case BailoutKind::Overflow: + case BailoutKind::Round: + case BailoutKind::NonPrimitiveInput: + case BailoutKind::PrecisionLoss: + case BailoutKind::TypeBarrierO: + case BailoutKind::TypeBarrierV: + case BailoutKind::ValueGuard: + case BailoutKind::NullOrUndefinedGuard: + case BailoutKind::Hole: + case BailoutKind::NoDenseElementsGuard: + case BailoutKind::NegativeIndex: + case BailoutKind::NonInt32Input: + case BailoutKind::NonNumericInput: + case BailoutKind::NonBooleanInput: + case BailoutKind::NonObjectInput: + case BailoutKind::NonStringInput: + case BailoutKind::NonSymbolInput: + case BailoutKind::NonBigIntInput: + case BailoutKind::Debugger: + case BailoutKind::SpecificAtomGuard: + case BailoutKind::SpecificSymbolGuard: + case BailoutKind::StringToIndexGuard: + case BailoutKind::StringToInt32Guard: + case BailoutKind::StringToDoubleGuard: + case BailoutKind::NonInt32ArrayLength: + case BailoutKind::FunctionLength: + case BailoutKind::FunctionName: + case BailoutKind::InvalidCodePoint: + case BailoutKind::ProtoGuard: + case BailoutKind::ProxyGuard: + case BailoutKind::NotProxyGuard: + case BailoutKind::NotDOMProxyGuard: + case BailoutKind::NotArrayBufferMaybeSharedGuard: + case BailoutKind::TypedArrayGuard: + case BailoutKind::MegamorphicAccess: + case BailoutKind::ArgumentsObjectAccess: + case BailoutKind::ArrayPopShift: + case BailoutKind::ArraySlice: + case BailoutKind::TagNotEqualGuard: + case BailoutKind::FunctionFlagsGuard: + case BailoutKind::FunctionKindGuard: + case BailoutKind::FunctionScriptGuard: + case BailoutKind::PackedArrayGuard: // Do nothing. break; - case Bailout_FirstExecution: + case BailoutKind::FirstExecution: // Do not return directly, as this was not frequent in the first place, // thus rely on the check for frequent bailouts to recompile the current // script. break; // Invalid assumption based on baseline code. - case Bailout_OverflowInvalidate: + case BailoutKind::OverflowInvalidate: outerScript->setHadOverflowBailout(); [[fallthrough]]; - case Bailout_DoubleOutput: - case Bailout_ObjectIdentityOrTypeGuard: + case BailoutKind::DoubleOutput: + case BailoutKind::ObjectIdentityOrTypeGuard: HandleBaselineInfoBailout(cx, outerScript, innerScript); break; - case Bailout_ArgumentCheck: + case BailoutKind::NotOptimizedArgumentsGuard: + // Optimized-arguments escaped to a slow path. Disable the optimization to + // prevent bailout loops. + JSScript::argumentsOptimizationFailed(cx, innerScript); + break; + + case BailoutKind::ArgumentCheck: // Do nothing, bailout will resume before the argument monitor ICs. break; - case Bailout_BoundsCheck: + case BailoutKind::BoundsCheck: HandleBoundsCheckFailure(cx, outerScript, innerScript); break; - case Bailout_ShapeGuard: + case BailoutKind::ShapeGuard: HandleShapeGuardFailure(cx, outerScript, innerScript); break; - case Bailout_UninitializedLexical: + case BailoutKind::UninitializedLexical: HandleLexicalCheckFailure(cx, outerScript, innerScript); break; - case Bailout_IonExceptionDebugMode: + case BailoutKind::IonExceptionDebugMode: // Return false to resume in HandleException with reconstructed // baseline frame. return false; diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index 731d44a6a1..7b83c8f4de 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -8,8 +8,11 @@ #include "jit/Linker.h" #include "jit/SharedICHelpers.h" #include "jit/VMFunctions.h" +#include "js/experimental/JitInfo.h" // JSJitInfo +#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration #include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" +#include "util/Unicode.h" #include "jit/MacroAssembler-inl.h" #include "jit/SharedICHelpers-inl.h" @@ -22,6 +25,8 @@ using namespace js::jit; using mozilla::Maybe; +using JS::ExpandoAndGeneration; + namespace js { namespace jit { @@ -356,6 +361,24 @@ bool BaselineCacheIRCompiler::emitGuardSpecificFunction( return emitGuardSpecificObject(objId, expectedOffset); } +bool BaselineCacheIRCompiler::emitGuardFunctionScript( + ObjOperandId funId, uint32_t expectedOffset, uint32_t nargsAndFlagsOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register fun = allocator.useRegister(masm, funId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + Address addr(stubAddress(expectedOffset)); + masm.loadPtr(Address(fun, JSFunction::offsetOfBaseScript()), scratch); + masm.branchPtr(Assembler::NotEqual, addr, scratch, failure->label()); + return true; +} + bool BaselineCacheIRCompiler::emitGuardSpecificAtom(StringOperandId strId, uint32_t expectedOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -493,8 +516,12 @@ bool BaselineCacheIRCompiler::emitGuardHasGetterSetter(ObjOperandId objId, return true; } -bool BaselineCacheIRCompiler::emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm) { +bool BaselineCacheIRCompiler::emitCallScriptedGetterResult( + ValOperandId receiverId, uint32_t getterOffset, bool sameRealm, + uint32_t nargsAndFlagsOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); Address getterAddr(stubAddress(getterOffset)); AutoScratchRegister code(allocator, masm); @@ -551,27 +578,12 @@ bool BaselineCacheIRCompiler::emitCallScriptedGetterResultShared( return true; } -bool BaselineCacheIRCompiler::emitCallScriptedGetterResult( - ObjOperandId objId, uint32_t getterOffset, bool sameRealm) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register obj = allocator.useRegister(masm, objId); - - return emitCallScriptedGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - sameRealm); -} - -bool BaselineCacheIRCompiler::emitCallScriptedGetterByValueResult( - ValOperandId valId, uint32_t getterOffset, bool sameRealm) { +bool BaselineCacheIRCompiler::emitCallNativeGetterResult( + ValOperandId receiverId, uint32_t getterOffset, bool sameRealm, + uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - ValueOperand val = allocator.useValueRegister(masm, valId); - return emitCallScriptedGetterResultShared(val, getterOffset, sameRealm); -} - -template -bool BaselineCacheIRCompiler::emitCallNativeGetterResultShared( - T receiver, uint32_t getterOffset, const CallVM& emitCallVM) { + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); Address getterAddr(stubAddress(getterOffset)); AutoScratchRegister scratch(allocator, masm); @@ -587,38 +599,44 @@ bool BaselineCacheIRCompiler::emitCallNativeGetterResultShared( masm.Push(receiver); masm.Push(scratch); - emitCallVM(); + using Fn = + bool (*)(JSContext*, HandleFunction, HandleValue, MutableHandleValue); + callVM(masm); stubFrame.leave(masm); return true; } -bool BaselineCacheIRCompiler::emitCallNativeGetterResult( - ObjOperandId objId, uint32_t getterOffset) { +bool BaselineCacheIRCompiler::emitCallDOMGetterResult(ObjOperandId objId, + uint32_t jitInfoOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); + Address jitInfoAddr(stubAddress(jitInfoOffset)); - return emitCallNativeGetterResultShared(obj, getterOffset, [this]() { - using Fn = - bool (*)(JSContext*, HandleFunction, HandleObject, MutableHandleValue); - callVM(masm); - }); -} + AutoScratchRegister scratch(allocator, masm); -bool BaselineCacheIRCompiler::emitCallNativeGetterByValueResult( - ValOperandId valId, uint32_t getterOffset) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - ValueOperand val = allocator.useValueRegister(masm, valId); + allocator.discardStack(masm); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); - return emitCallNativeGetterResultShared(val, getterOffset, [this]() { - using Fn = - bool (*)(JSContext*, HandleFunction, HandleValue, MutableHandleValue); - callVM(masm); - }); + // Load the JSJitInfo in the scratch register. + masm.loadPtr(jitInfoAddr, scratch); + + masm.Push(obj); + masm.Push(scratch); + + using Fn = + bool (*)(JSContext*, const JSJitInfo*, HandleObject, MutableHandleValue); + callVM(masm); + + stubFrame.leave(masm); + return true; } -bool BaselineCacheIRCompiler::emitCallProxyGetResult(ObjOperandId objId, - uint32_t idOffset) { +bool BaselineCacheIRCompiler::emitProxyGetResult(ObjOperandId objId, + uint32_t idOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); Address idAddr(stubAddress(idOffset)); @@ -705,6 +723,26 @@ bool BaselineCacheIRCompiler::emitLoadFrameArgumentResult( return true; } +bool BaselineCacheIRCompiler::emitFrameIsConstructingResult() { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register outputScratch = output.valueReg().scratchReg(); + + // Load the CalleeToken. + Address tokenAddr(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken()); + masm.loadPtr(tokenAddr, outputScratch); + + // The low bit indicates whether this call is constructing, just clear the + // other bits. + static_assert(CalleeToken_Function == 0x0); + static_assert(CalleeToken_FunctionConstructing == 0x1); + masm.andPtr(Imm32(0x1), outputScratch); + + masm.tagValue(JSVAL_TYPE_BOOLEAN, outputScratch, output.valueReg()); + return true; +} + bool BaselineCacheIRCompiler::emitLoadEnvironmentFixedSlotResult( ObjOperandId objId, uint32_t offsetOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -1174,6 +1212,34 @@ bool BaselineCacheIRCompiler::emitStoreDenseElement(ObjOperandId objId, return true; } +static void EmitAssertExtensibleElements(MacroAssembler& masm, + Register elementsReg) { +#ifdef DEBUG + // Preceding shape guards ensure the object elements are extensible. + Address elementsFlags(elementsReg, ObjectElements::offsetOfFlags()); + Label ok; + masm.branchTest32(Assembler::Zero, elementsFlags, + Imm32(ObjectElements::Flags::NOT_EXTENSIBLE), + &ok); + masm.assumeUnreachable("Unexpected non-extensible elements"); + masm.bind(&ok); +#endif +} + +static void EmitAssertWritableArrayLengthElements(MacroAssembler& masm, + Register elementsReg) { +#ifdef DEBUG + // Preceding shape guards ensure the array length is writable. + Address elementsFlags(elementsReg, ObjectElements::offsetOfFlags()); + Label ok; + masm.branchTest32(Assembler::Zero, elementsFlags, + Imm32(ObjectElements::Flags::NONWRITABLE_ARRAY_LENGTH), + &ok); + masm.assumeUnreachable("Unexpected non-writable array length elements"); + masm.bind(&ok); +#endif +} + bool BaselineCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, Int32OperandId indexId, ValOperandId rhsId, @@ -1196,6 +1262,11 @@ bool BaselineCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, // Load obj->elements in scratch. masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + EmitAssertExtensibleElements(masm, scratch); + if (handleAdd) { + EmitAssertWritableArrayLengthElements(masm, scratch); + } + BaseObjectElementIndex element(scratch, index); Address initLength(scratch, ObjectElements::offsetOfInitializedLength()); Address elementsFlags(scratch, ObjectElements::offsetOfFlags()); @@ -1229,12 +1300,7 @@ bool BaselineCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, masm.spectreBoundsCheck32(index, capacity, spectreTemp, &allocElement); masm.jump(&capacityOk); - // Check for non-writable array length. We only have to do this if - // index >= capacity. masm.bind(&allocElement); - masm.branchTest32(Assembler::NonZero, elementsFlags, - Imm32(ObjectElements::NONWRITABLE_ARRAY_LENGTH), - failure->label()); LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); @@ -1344,6 +1410,9 @@ bool BaselineCacheIRCompiler::emitArrayPush(ObjOperandId objId, // Load obj->elements in scratch. masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + EmitAssertExtensibleElements(masm, scratch); + EmitAssertWritableArrayLengthElements(masm, scratch); + Address elementsInitLength(scratch, ObjectElements::offsetOfInitializedLength()); Address elementsLength(scratch, ObjectElements::offsetOfLength()); @@ -1369,12 +1438,7 @@ bool BaselineCacheIRCompiler::emitArrayPush(ObjOperandId objId, masm.spectreBoundsCheck32(scratchLength, capacity, InvalidReg, &allocElement); masm.jump(&capacityOk); - // Check for non-writable array length. We only have to do this if - // index >= capacity. masm.bind(&allocElement); - masm.branchTest32(Assembler::NonZero, elementsFlags, - Imm32(ObjectElements::NONWRITABLE_ARRAY_LENGTH), - failure->label()); LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); save.takeUnchecked(scratch); @@ -1441,6 +1505,117 @@ bool BaselineCacheIRCompiler::emitArrayPush(ObjOperandId objId, return true; } +bool BaselineCacheIRCompiler::emitArrayJoinResult(ObjOperandId objId, + StringOperandId sepId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register sep = allocator.useRegister(masm, sepId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + allocator.discardStack(masm); + + // Load obj->elements in scratch. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); + Address lengthAddr(scratch, ObjectElements::offsetOfLength()); + + // If array length is 0, return empty string. + Label finished; + + { + Label arrayNotEmpty; + masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(0), &arrayNotEmpty); + masm.movePtr(ImmGCPtr(cx_->names().empty), scratch); + masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg()); + masm.jump(&finished); + masm.bind(&arrayNotEmpty); + } + + Label vmCall; + + // Otherwise, handle array length 1 case. + masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(1), &vmCall); + + // But only if initializedLength is also 1. + Address initLength(scratch, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::NotEqual, initLength, Imm32(1), &vmCall); + + // And only if elem0 is a string. + Address elementAddr(scratch, 0); + masm.branchTestString(Assembler::NotEqual, elementAddr, &vmCall); + + // Store the value. + masm.loadValue(elementAddr, output.valueReg()); + masm.jump(&finished); + + // Otherwise call into the VM. + { + masm.bind(&vmCall); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + masm.Push(sep); + masm.Push(obj); + + using Fn = JSString* (*)(JSContext*, HandleObject, HandleString); + callVM(masm); + + stubFrame.leave(masm); + + masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg()); + } + + masm.bind(&finished); + + return true; +} + +bool BaselineCacheIRCompiler::emitPackedArraySliceResult( + uint32_t templateObjectOffset, ObjOperandId arrayId, Int32OperandId beginId, + Int32OperandId endId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output); + AutoScratchRegisterMaybeOutputType scratch2(allocator, masm, output); + + Register array = allocator.useRegister(masm, arrayId); + Register begin = allocator.useRegister(masm, beginId); + Register end = allocator.useRegister(masm, endId); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.branchArrayIsNotPacked(array, scratch1, scratch2, failure->label()); + + allocator.discardStack(masm); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch1); + + // Don't attempt to pre-allocate the object, instead always use the slow + // path. + ImmPtr result(nullptr); + + masm.Push(result); + masm.Push(end); + masm.Push(begin); + masm.Push(array); + + using Fn = + JSObject* (*)(JSContext*, HandleObject, int32_t, int32_t, HandleObject); + callVM(masm); + + stubFrame.leave(masm); + + masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, output.valueReg()); + return true; +} + bool BaselineCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -1454,9 +1629,7 @@ bool BaselineCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) { Label isNotArray; // Primitives are never Arrays. - masm.branchTestObject(Assembler::NotEqual, val, &isNotArray); - - masm.unboxObject(val, scratch1); + masm.fallibleUnboxObject(val, scratch1, &isNotArray); Label isArray; masm.branchTestObjClass(Assembler::Equal, scratch1, &ArrayObject::class_, @@ -1491,15 +1664,123 @@ bool BaselineCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) { return true; } -bool BaselineCacheIRCompiler::emitStringFromCharCodeResult( - Int32OperandId codeId) { +bool BaselineCacheIRCompiler::emitIsTypedArrayResult(ObjOperandId objId, + bool isPossiblyWrapped) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); + + allocator.discardStack(masm); + + Label notTypedArray, isProxy, done; + masm.loadObjClassUnsafe(obj, scratch); + masm.branchIfClassIsNotTypedArray(scratch, ¬TypedArray); + masm.moveValue(BooleanValue(true), output.valueReg()); + masm.jump(&done); + + masm.bind(¬TypedArray); + if (isPossiblyWrapped) { + masm.branchTestClassIsProxy(true, scratch, &isProxy); + } + masm.moveValue(BooleanValue(false), output.valueReg()); + + if (isPossiblyWrapped) { + masm.jump(&done); + + masm.bind(&isProxy); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + masm.Push(obj); + + using Fn = bool (*)(JSContext*, JSObject*, bool*); + callVM(masm); + + stubFrame.leave(masm); + + masm.tagValue(JSVAL_TYPE_BOOLEAN, ReturnReg, output.valueReg()); + } + + masm.bind(&done); + return true; +} + +bool BaselineCacheIRCompiler::emitLoadStringCharResult(StringOperandId strId, + Int32OperandId indexId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + Register str = allocator.useRegister(masm, strId); + Register index = allocator.useRegister(masm, indexId); + AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check, load string char. + masm.spectreBoundsCheck32(index, Address(str, JSString::offsetOfLength()), + scratch1, failure->label()); + masm.loadStringChar(str, index, scratch1, scratch2, failure->label()); + + allocator.discardStack(masm); + + // Load StaticString for this char. For larger code units perform a VM call. + Label vmCall; + masm.boundsCheck32PowerOfTwo(scratch1, StaticStrings::UNIT_STATIC_LIMIT, + &vmCall); + masm.movePtr(ImmPtr(&cx_->staticStrings().unitStaticTable), scratch2); + masm.loadPtr(BaseIndex(scratch2, scratch1, ScalePointer), scratch2); + + Label done; + masm.jump(&done); + + { + masm.bind(&vmCall); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch2); + + masm.Push(scratch1); + + using Fn = JSLinearString* (*)(JSContext*, int32_t); + callVM(masm); + stubFrame.leave(masm); + + masm.storeCallPointerResult(scratch2); + } + + masm.bind(&done); + masm.tagValue(JSVAL_TYPE_STRING, scratch2, output.valueReg()); + return true; +} + +bool BaselineCacheIRCompiler::emitStringFromCodeResult(Int32OperandId codeId, + StringCode stringCode) { AutoOutputRegister output(*this); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); Register code = allocator.useRegister(masm, codeId); + FailurePath* failure = nullptr; + if (stringCode == StringCode::CodePoint) { + if (!addFailurePath(&failure)) { + return false; + } + } + + if (stringCode == StringCode::CodePoint) { + // Note: This condition must match tryAttachStringFromCodePoint to prevent + // failure loops. + masm.branch32(Assembler::Above, code, Imm32(unicode::NonBMPMax), + failure->label()); + } + allocator.discardStack(masm); // We pre-allocate atoms for the first UNIT_STATIC_LIMIT characters. @@ -1520,8 +1801,13 @@ bool BaselineCacheIRCompiler::emitStringFromCharCodeResult( masm.Push(code); - using Fn = JSLinearString* (*)(JSContext*, int32_t); - callVM(masm); + if (stringCode == StringCode::CodeUnit) { + using Fn = JSLinearString* (*)(JSContext*, int32_t); + callVM(masm); + } else { + using Fn = JSString* (*)(JSContext*, int32_t); + callVM(masm); + } stubFrame.leave(masm); masm.mov(ReturnReg, scratch); @@ -1532,6 +1818,20 @@ bool BaselineCacheIRCompiler::emitStringFromCharCodeResult( return true; } +bool BaselineCacheIRCompiler::emitStringFromCharCodeResult( + Int32OperandId codeId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitStringFromCodeResult(codeId, StringCode::CodeUnit); +} + +bool BaselineCacheIRCompiler::emitStringFromCodePointResult( + Int32OperandId codeId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitStringFromCodeResult(codeId, StringCode::CodePoint); +} + bool BaselineCacheIRCompiler::emitMathRandomResult(uint32_t rngOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -1550,6 +1850,53 @@ bool BaselineCacheIRCompiler::emitMathRandomResult(uint32_t rngOffset) { return true; } +bool BaselineCacheIRCompiler::emitReflectGetPrototypeOfResult( + ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + Register obj = allocator.useRegister(masm, objId); + + allocator.discardStack(masm); + + MOZ_ASSERT(uintptr_t(TaggedProto::LazyProto) == 1); + + masm.loadObjProto(obj, scratch); + + Label hasProto; + masm.branchPtr(Assembler::Above, scratch, ImmWord(1), &hasProto); + + // Call into the VM for lazy prototypes. + Label slow, done; + masm.branchPtr(Assembler::Equal, scratch, ImmWord(1), &slow); + + masm.moveValue(NullValue(), output.valueReg()); + masm.jump(&done); + + masm.bind(&hasProto); + masm.tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg()); + masm.jump(&done); + + { + masm.bind(&slow); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + masm.Push(obj); + + using Fn = bool (*)(JSContext*, HandleObject, MutableHandleValue); + callVM(masm); + + stubFrame.leave(masm); + } + + masm.bind(&done); + return true; +} + bool BaselineCacheIRCompiler::emitHasClassResult(ObjOperandId objId, uint32_t claspOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -1565,11 +1912,11 @@ bool BaselineCacheIRCompiler::emitHasClassResult(ObjOperandId objId, return true; } -bool BaselineCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, - uint32_t setterOffset, - ValOperandId rhsId) { +bool BaselineCacheIRCompiler::emitCallNativeSetter( + ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId, + bool sameRealm, uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register obj = allocator.useRegister(masm, objId); + Register receiver = allocator.useRegister(masm, receiverId); Address setterAddr(stubAddress(setterOffset)); ValueOperand val = allocator.useValueRegister(masm, rhsId); @@ -1584,7 +1931,7 @@ bool BaselineCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, masm.loadPtr(setterAddr, scratch); masm.Push(val); - masm.Push(obj); + masm.Push(receiver); masm.Push(scratch); using Fn = bool (*)(JSContext*, HandleFunction, HandleObject, HandleValue); @@ -1594,15 +1941,14 @@ bool BaselineCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, return true; } -bool BaselineCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId, - uint32_t setterOffset, - ValOperandId rhsId, - bool sameRealm) { +bool BaselineCacheIRCompiler::emitCallScriptedSetter( + ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId, + bool sameRealm, uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoScratchRegister scratch1(allocator, masm); AutoScratchRegister scratch2(allocator, masm); - Register obj = allocator.useRegister(masm, objId); + Register receiver = allocator.useRegister(masm, receiverId); Address setterAddr(stubAddress(setterOffset)); ValueOperand val = allocator.useValueRegister(masm, rhsId); @@ -1622,10 +1968,10 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId, // JitStackAlignment. masm.alignJitStackBasedOnNArgs(1); - // Setter is called with 1 argument, and |obj| as thisv. Note that we use + // Setter is called with 1 argument, and |receiver| as thisv. Note that we use // Push, not push, so that callJit will align the stack properly on ARM. masm.Push(val); - masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); + masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(receiver))); // Now that the object register is no longer needed, use it as second // scratch. @@ -1665,6 +2011,35 @@ bool BaselineCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId, return true; } +bool BaselineCacheIRCompiler::emitCallDOMSetter(ObjOperandId objId, + uint32_t jitInfoOffset, + ValOperandId rhsId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); + ValueOperand val = allocator.useValueRegister(masm, rhsId); + Address jitInfoAddr(stubAddress(jitInfoOffset)); + + AutoScratchRegister scratch(allocator, masm); + + allocator.discardStack(masm); + + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + // Load the JSJitInfo in the scratch register. + masm.loadPtr(jitInfoAddr, scratch); + + masm.Push(val); + masm.Push(obj); + masm.Push(scratch); + + using Fn = bool (*)(JSContext*, const JSJitInfo*, HandleObject, HandleValue); + callVM(masm); + + stubFrame.leave(masm); + return true; +} + bool BaselineCacheIRCompiler::emitCallSetArrayLength(ObjOperandId objId, bool strict, ValOperandId rhsId) { @@ -1690,10 +2065,9 @@ bool BaselineCacheIRCompiler::emitCallSetArrayLength(ObjOperandId objId, return true; } -bool BaselineCacheIRCompiler::emitCallProxySet(ObjOperandId objId, - uint32_t idOffset, - ValOperandId rhsId, - bool strict) { +bool BaselineCacheIRCompiler::emitProxySet(ObjOperandId objId, + uint32_t idOffset, + ValOperandId rhsId, bool strict) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); ValueOperand val = allocator.useValueRegister(masm, rhsId); @@ -1721,10 +2095,10 @@ bool BaselineCacheIRCompiler::emitCallProxySet(ObjOperandId objId, return true; } -bool BaselineCacheIRCompiler::emitCallProxySetByValue(ObjOperandId objId, - ValOperandId idId, - ValOperandId rhsId, - bool strict) { +bool BaselineCacheIRCompiler::emitProxySetByValue(ObjOperandId objId, + ValOperandId idId, + ValOperandId rhsId, + bool strict) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); ValueOperand idVal = allocator.useValueRegister(masm, idId); @@ -2005,6 +2379,7 @@ bool BaselineCacheIRCompiler::init(CacheKind kind) { case CacheKind::TypeOf: case CacheKind::ToPropertyKey: case CacheKind::GetIterator: + case CacheKind::OptimizeSpreadCall: case CacheKind::ToBool: case CacheKind::UnaryArith: MOZ_ASSERT(numInputs == 1); @@ -2016,6 +2391,7 @@ bool BaselineCacheIRCompiler::init(CacheKind kind) { case CacheKind::SetProp: case CacheKind::In: case CacheKind::HasOwn: + case CacheKind::CheckPrivateField: case CacheKind::InstanceOf: case CacheKind::BinaryArith: MOZ_ASSERT(numInputs == 2); @@ -2084,7 +2460,7 @@ static void ResetEnteredCounts(ICFallbackStub* stub) { ICStub* js::jit::AttachBaselineCacheIRStub( JSContext* cx, const CacheIRWriter& writer, CacheKind kind, - BaselineCacheIRStubKind stubKind, JSScript* outerScript, + BaselineCacheIRStubKind stubKind, JSScript* outerScript, ICScript* icScript, ICFallbackStub* stub, bool* attached) { // We shouldn't GC or report OOM (or any other exception) here. AutoAssertNoPendingException aanpe(cx); @@ -2118,6 +2494,11 @@ ICStub* js::jit::AttachBaselineCacheIRStub( JitZone* jitZone = cx->zone()->jitZone(); + // The script to invalidate if we are modifying a transpiled IC. + JSScript* invalidationScript = icScript->isInlined() + ? icScript->inliningRoot()->owningScript() + : outerScript; + // Check if we already have JitCode for this stub. CacheIRStubInfo* stubInfo; CacheIRStubKey::Lookup lookup(kind, ICStubEngine::Baseline, @@ -2213,6 +2594,7 @@ ICStub* js::jit::AttachBaselineCacheIRStub( // attach. Just return nullptr, the caller should do nothing in this // case. if (updated) { + stub->maybeInvalidateWarp(cx, invalidationScript); *attached = true; } else { JitSpew(JitSpew_BaselineICFallback, @@ -2227,8 +2609,8 @@ ICStub* js::jit::AttachBaselineCacheIRStub( size_t bytesNeeded = stubInfo->stubDataOffset() + stubInfo->stubDataSize(); - ICStubSpace* stubSpace = - ICStubCompiler::StubSpaceForStub(stubInfo->makesGCCalls(), outerScript); + ICStubSpace* stubSpace = ICStubCompiler::StubSpaceForStub( + stubInfo->makesGCCalls(), outerScript, icScript); void* newStubMem = stubSpace->alloc(bytesNeeded); if (!newStubMem) { return nullptr; @@ -2238,6 +2620,20 @@ ICStub* js::jit::AttachBaselineCacheIRStub( // about the chain much easier. ResetEnteredCounts(stub); + stub->maybeInvalidateWarp(cx, invalidationScript); + + switch (stub->trialInliningState()) { + case TrialInliningState::Initial: + case TrialInliningState::Candidate: + stub->setTrialInliningState(writer.trialInliningState()); + break; + case TrialInliningState::Inlined: + stub->setTrialInliningState(TrialInliningState::Failure); + break; + case TrialInliningState::Failure: + break; + } + switch (stubKind) { case BaselineCacheIRStubKind::Regular: { auto newStub = new (newStubMem) ICCacheIR_Regular(code, stubInfo); @@ -2281,17 +2677,13 @@ ICStub* js::jit::AttachBaselineCacheIRStub( MOZ_CRASH("Invalid kind"); } -uint8_t* ICCacheIR_Regular::stubDataStart() { +template +uint8_t* ICCacheIR_Trait::stubDataStart() { return reinterpret_cast(this) + stubInfo_->stubDataOffset(); } -uint8_t* ICCacheIR_Monitored::stubDataStart() { - return reinterpret_cast(this) + stubInfo_->stubDataOffset(); -} - -uint8_t* ICCacheIR_Updated::stubDataStart() { - return reinterpret_cast(this) + stubInfo_->stubDataOffset(); -} +template uint8_t* ICCacheIR_Trait::stubDataStart(); +template uint8_t* ICCacheIR_Trait::stubDataStart(); bool BaselineCacheIRCompiler::emitCallStringObjectConcatResult( ValOperandId lhsId, ValOperandId rhsId) { @@ -2324,10 +2716,6 @@ bool BaselineCacheIRCompiler::emitCallStringObjectConcatResult( // blowing the stack limit. bool BaselineCacheIRCompiler::updateArgc(CallFlags flags, Register argcReg, Register scratch) { - static_assert(CacheIRCompiler::MAX_ARGS_ARRAY_LENGTH <= ARGS_LENGTH_MAX, - "maximum arguments length for optimized stub should be <= " - "ARGS_LENGTH_MAX"); - CallFlags::ArgFormat format = flags.getArgFormat(); switch (format) { case CallFlags::Standard: @@ -2337,16 +2725,6 @@ bool BaselineCacheIRCompiler::updateArgc(CallFlags flags, Register argcReg, // fun_call has no extra guards, and argc will be corrected in // pushFunCallArguments. return true; - case CallFlags::FunApplyArray: { - // GuardFunApply array already guarded argc while checking for - // holes in the array, so we don't need to guard again here. We - // do still need to update argc. - BaselineFrameSlot slot(0); - masm.unboxObject(allocator.addressOf(masm, slot), argcReg); - masm.loadPtr(Address(argcReg, NativeObject::offsetOfElements()), argcReg); - masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg); - return true; - } default: break; } @@ -2359,7 +2737,8 @@ bool BaselineCacheIRCompiler::updateArgc(CallFlags flags, Register argcReg, // Load callee argc into scratch. switch (flags.getArgFormat()) { - case CallFlags::Spread: { + case CallFlags::Spread: + case CallFlags::FunApplyArray: { // Load the length of the elements. BaselineFrameSlot slot(flags.isConstructing()); masm.unboxObject(allocator.addressOf(masm, slot), scratch); @@ -2377,8 +2756,7 @@ bool BaselineCacheIRCompiler::updateArgc(CallFlags flags, Register argcReg, } // Ensure that callee argc does not exceed the limit. - masm.branch32(Assembler::Above, scratch, - Imm32(CacheIRCompiler::MAX_ARGS_ARRAY_LENGTH), + masm.branch32(Assembler::Above, scratch, Imm32(JIT_ARGS_LENGTH_MAX), failure->label()); // We're past the final guard. Update argc with the new value. @@ -2387,91 +2765,6 @@ bool BaselineCacheIRCompiler::updateArgc(CallFlags flags, Register argcReg, return true; } -bool BaselineCacheIRCompiler::emitGuardFunApply(Int32OperandId argcId, - CallFlags flags) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register argcReg = allocator.useRegister(masm, argcId); - AutoScratchRegister scratch(allocator, masm); - AutoScratchRegister scratch2(allocator, masm); - - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } - - // Ensure argc == 2 - masm.branch32(Assembler::NotEqual, argcReg, Imm32(2), failure->label()); - - // Stack layout is (bottom to top): - // Callee (fun_apply) - // ThisValue (target) - // Arg0 (new this) - // Arg1 (argument array) - - Address argsAddr = allocator.addressOf(masm, BaselineFrameSlot(0)); - switch (flags.getArgFormat()) { - case CallFlags::FunApplyArgs: { - // Ensure that args is magic |arguments|. - masm.branchTestMagic(Assembler::NotEqual, argsAddr, failure->label()); - - // Ensure that this frame doesn't have an arguments object. - Address flagAddr(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()); - masm.branchTest32(Assembler::NonZero, flagAddr, - Imm32(BaselineFrame::HAS_ARGS_OBJ), failure->label()); - } break; - case CallFlags::FunApplyArray: { - // Ensure that args is an array object. - masm.branchTestObject(Assembler::NotEqual, argsAddr, failure->label()); - masm.unboxObject(argsAddr, scratch); - const JSClass* clasp = &ArrayObject::class_; - masm.branchTestObjClass(Assembler::NotEqual, scratch, clasp, scratch2, - scratch, failure->label()); - - // Get the array elements and length - Register elementsReg = scratch; - masm.loadPtr(Address(scratch, NativeObject::offsetOfElements()), - elementsReg); - Register calleeArgcReg = scratch2; - masm.load32(Address(elementsReg, ObjectElements::offsetOfLength()), - calleeArgcReg); - - // Ensure that callee argc does not exceed the limit. Note that - // we do this earlier for FunApplyArray than for FunApplyArgs, - // because we don't want to loop over every element of the array - // looking for holes if we already know it is too long. - masm.branch32(Assembler::Above, calleeArgcReg, - Imm32(CacheIRCompiler::MAX_ARGS_ARRAY_LENGTH), - failure->label()); - - // Ensure that length == initializedLength - Address initLenAddr(elementsReg, - ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::NotEqual, initLenAddr, calleeArgcReg, - failure->label()); - - // Ensure no holes. Loop through array and verify no elements are magic. - Register start = elementsReg; - Register end = scratch2; - BaseValueIndex endAddr(elementsReg, calleeArgcReg); - masm.computeEffectiveAddress(endAddr, end); - - Label loop; - Label endLoop; - masm.bind(&loop); - masm.branchPtr(Assembler::AboveOrEqual, start, end, &endLoop); - masm.branchTestMagic(Assembler::Equal, Address(start, 0), - failure->label()); - masm.addPtr(Imm32(sizeof(Value)), start); - masm.jump(&loop); - masm.bind(&endLoop); - } break; - default: - MOZ_CRASH("Invalid arg format"); - break; - } - return true; -} - void BaselineCacheIRCompiler::pushArguments(Register argcReg, Register calleeReg, Register scratch, Register scratch2, @@ -2855,6 +3148,28 @@ void BaselineCacheIRCompiler::loadStackObject(ArgumentKind kind, } } +template +void BaselineCacheIRCompiler::storeThis(const T& newThis, Register argcReg, + CallFlags flags) { + switch (flags.getArgFormat()) { + case CallFlags::Standard: { + BaseValueIndex thisAddress(masm.getStackPointer(), + argcReg, // Arguments + 1 * sizeof(Value) + // NewTarget + STUB_FRAME_SIZE); // Stub frame + masm.storeValue(newThis, thisAddress); + } break; + case CallFlags::Spread: { + Address thisAddress(masm.getStackPointer(), + 2 * sizeof(Value) + // Arg array, NewTarget + STUB_FRAME_SIZE); // Stub frame + masm.storeValue(newThis, thisAddress); + } break; + default: + MOZ_CRASH("Invalid arg format for scripted constructor"); + } +} + /* * Scripted constructors require a |this| object to be created prior to the * call. When this function is called, the stack looks like (bottom->top): @@ -2870,11 +3185,19 @@ void BaselineCacheIRCompiler::createThis(Register argcReg, Register calleeReg, Register scratch, CallFlags flags) { MOZ_ASSERT(flags.isConstructing()); + if (flags.needsUninitializedThis()) { + storeThis(MagicValue(JS_UNINITIALIZED_LEXICAL), argcReg, flags); + return; + } + size_t depth = STUB_FRAME_SIZE; - // Save argc before call. - masm.push(argcReg); - depth += sizeof(size_t); + // Save live registers that don't have to be traced. + LiveGeneralRegisterSet liveNonGCRegs; + liveNonGCRegs.add(argcReg); + liveNonGCRegs.add(ICStubReg); + masm.PushRegsInMask(liveNonGCRegs); + depth += sizeof(uintptr_t) * liveNonGCRegs.set().size(); // CreateThis takes two arguments: callee, and newTarget. @@ -2901,33 +3224,16 @@ void BaselineCacheIRCompiler::createThis(Register argcReg, Register calleeReg, masm.bind(&createdThisOK); #endif - // Restore argc - masm.pop(argcReg); + // Restore saved registers. + masm.PopRegsInMask(liveNonGCRegs); // Save |this| value back into pushed arguments on stack. - switch (flags.getArgFormat()) { - case CallFlags::Standard: { - BaseValueIndex thisAddress(masm.getStackPointer(), - argcReg, // Arguments - 1 * sizeof(Value) + // NewTarget - STUB_FRAME_SIZE); // Stub frame - masm.storeValue(JSReturnOperand, thisAddress); - } break; - case CallFlags::Spread: { - Address thisAddress(masm.getStackPointer(), - 2 * sizeof(Value) + // Arg array, NewTarget - STUB_FRAME_SIZE); // Stub frame - masm.storeValue(JSReturnOperand, thisAddress); - } break; - default: - MOZ_CRASH("Invalid arg format for scripted constructor"); - } - - // Restore the stub register from the baseline stub frame. - Address stubRegAddress(masm.getStackPointer(), STUB_FRAME_SAVED_STUB_OFFSET); - masm.loadPtr(stubRegAddress, ICStubReg); + MOZ_ASSERT(!liveNonGCRegs.aliases(JSReturnOperand)); + storeThis(JSReturnOperand, argcReg, flags); - // Restore calleeReg. + // Restore calleeReg. CreateThisFromIC may trigger a GC, so we reload the + // callee from the stub frame (which is traced) instead of spilling it to + // the stack. depth = STUB_FRAME_SIZE; loadStackObject(ArgumentKind::Callee, flags, depth, argcReg, calleeReg); } @@ -3036,3 +3342,111 @@ bool BaselineCacheIRCompiler::emitCallScriptedFunction(ObjOperandId calleeId, return true; } + +bool BaselineCacheIRCompiler::emitCallInlinedFunction(ObjOperandId calleeId, + Int32OperandId argcId, + uint32_t icScriptOffset, + CallFlags flags) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoScratchRegisterMaybeOutputType scratch2(allocator, masm, output); + AutoScratchRegister codeReg(allocator, masm); + + Register calleeReg = allocator.useRegister(masm, calleeId); + Register argcReg = allocator.useRegister(masm, argcId); + + bool isConstructing = flags.isConstructing(); + bool isSameRealm = flags.isSameRealm(); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.loadBaselineJitCodeRaw(calleeReg, codeReg, failure->label()); + + if (!updateArgc(flags, argcReg, scratch)) { + return false; + } + + allocator.discardStack(masm); + + // Push a stub frame so that we can perform a non-tail call. + // Note that this leaves the return address in TailCallReg. + AutoStubFrame stubFrame(*this); + stubFrame.enter(masm, scratch); + + if (!isSameRealm) { + masm.switchToObjectRealm(calleeReg, scratch); + } + + Label baselineScriptDiscarded; + if (isConstructing) { + createThis(argcReg, calleeReg, scratch, flags); + + // CreateThisFromIC may trigger a GC and discard the BaselineScript. + // We have already called discardStack, so we can't use a FailurePath. + // Instead, we skip storing the ICScript in the JSContext and use a + // normal non-inlined call. + masm.loadBaselineJitCodeRaw(calleeReg, codeReg, &baselineScriptDiscarded); + } + + // Store icScript in the context. + Address icScriptAddr(stubAddress(icScriptOffset)); + masm.loadPtr(icScriptAddr, scratch); + masm.loadJSContext(scratch2); + masm.storePtr(scratch, + Address(scratch2, JSContext::offsetOfInlinedICScript())); + + if (isConstructing) { + Label skip; + masm.jump(&skip); + masm.bind(&baselineScriptDiscarded); + masm.loadJitCodeRaw(calleeReg, codeReg); + masm.bind(&skip); + } + + pushArguments(argcReg, calleeReg, scratch, scratch2, flags, + /*isJitCall =*/true); + + EmitBaselineCreateStubFrameDescriptor(masm, scratch, JitFrameLayout::Size()); + + // Note that we use Push, not push, so that callJit will align the stack + // properly on ARM. + masm.Push(argcReg); + masm.PushCalleeToken(calleeReg, isConstructing); + masm.Push(scratch); + + // Handle arguments underflow. + // TODO: This is a tricky problem for spread calls, where we don't + // know the number of arguments statically. We may need a second + // copy of the arguments rectifier. + Label noUnderflow; + masm.load16ZeroExtend(Address(calleeReg, JSFunction::offsetOfNargs()), + calleeReg); + masm.branch32(Assembler::AboveOrEqual, argcReg, calleeReg, &noUnderflow); + + // Call the trial-inlining arguments rectifier. + ArgumentsRectifierKind kind = ArgumentsRectifierKind::TrialInlining; + TrampolinePtr argumentsRectifier = + cx_->runtime()->jitRuntime()->getArgumentsRectifier(kind); + masm.movePtr(argumentsRectifier, codeReg); + + masm.bind(&noUnderflow); + masm.callJit(codeReg); + + // If this is a constructing call, and the callee returns a non-object, + // replace it with the |this| object passed in. + if (isConstructing) { + updateReturnValue(); + } + + stubFrame.leave(masm, true); + + if (!isSameRealm) { + masm.switchToBaselineFrameRealm(codeReg); + } + + return true; +} diff --git a/js/src/jit/BaselineCacheIRCompiler.h b/js/src/jit/BaselineCacheIRCompiler.h index 665c7858a4..81c29f9dda 100644 --- a/js/src/jit/BaselineCacheIRCompiler.h +++ b/js/src/jit/BaselineCacheIRCompiler.h @@ -22,8 +22,8 @@ enum class BaselineCacheIRStubKind { Regular, Monitored, Updated }; ICStub* AttachBaselineCacheIRStub(JSContext* cx, const CacheIRWriter& writer, CacheKind kind, BaselineCacheIRStubKind stubKind, - JSScript* outerScript, ICFallbackStub* stub, - bool* attached); + JSScript* outerScript, ICScript* icScript, + ICFallbackStub* stub, bool* attached); // BaselineCacheIRCompiler compiles CacheIR to BaselineIC native code. class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler { @@ -64,6 +64,8 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler { Register scratch2, bool isJitCall); void createThis(Register argcReg, Register calleeReg, Register scratch, CallFlags flags); + template + void storeThis(const T& newThis, Register argcReg, CallFlags flags); void updateReturnValue(); enum class NativeCallType { Native, ClassHook }; @@ -72,13 +74,8 @@ class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler { mozilla::Maybe ignoresReturnValue, mozilla::Maybe targetOffset); - MOZ_MUST_USE bool emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm); - - template - MOZ_MUST_USE bool emitCallNativeGetterResultShared(T receiver, - uint32_t getterOffset, - const CallVM& emitCallVM); + enum class StringCode { CodeUnit, CodePoint }; + bool emitStringFromCodeResult(Int32OperandId codeId, StringCode stringCode); public: friend class AutoStubFrame; diff --git a/js/src/jit/BaselineCodeGen.cpp b/js/src/jit/BaselineCodeGen.cpp index c534f919e3..5b72d54994 100644 --- a/js/src/jit/BaselineCodeGen.cpp +++ b/js/src/jit/BaselineCodeGen.cpp @@ -17,10 +17,12 @@ # include "jit/PerfSpewer.h" #endif #include "jit/SharedICHelpers.h" +#include "jit/TrialInlining.h" #include "jit/VMFunctions.h" #include "js/UniquePtr.h" #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" +#include "vm/BuiltinObjectKind.h" #include "vm/EnvironmentObject.h" #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/Interpreter.h" @@ -454,6 +456,10 @@ void BaselineInterpreterCodeGen::emitInitializeLocals() { // void PostWriteBarrier(JSRuntime* rt, JSObject* obj); template bool BaselineCodeGen::emitOutOfLinePostBarrierSlot() { + if (!postBarrierSlot_.used()) { + return true; + } + masm.bind(&postBarrierSlot_); Register objReg = R2.scratchReg(); @@ -494,16 +500,28 @@ bool BaselineCompilerCodeGen::emitNextIC() { // We don't use every ICEntry and we can skip unreachable ops, so we have // to loop until we find an ICEntry for the current pc. const ICEntry* entry; + uint32_t entryIndex; do { entry = &script->jitScript()->icEntry(handler.icEntryIndex()); + entryIndex = handler.icEntryIndex(); handler.moveToNextICEntry(); } while (entry->pcOffset() < pcOffset); MOZ_RELEASE_ASSERT(entry->pcOffset() == pcOffset); MOZ_ASSERT_IF(!entry->isForPrologue(), BytecodeOpHasIC(JSOp(*handler.pc()))); + // Load stub pointer into ICStubReg. + if (JitOptions.warpBuilder) { + masm.loadPtr(frame.addressOfICScript(), ICStubReg); + size_t firstStubOffset = ICScript::offsetOfFirstStub(entryIndex); + masm.loadPtr(Address(ICStubReg, firstStubOffset), ICStubReg); + } else { + masm.loadPtr(AbsoluteAddress(entry).offset(ICEntry::offsetOfFirstStub()), + ICStubReg); + } + CodeOffset returnOffset; - EmitCallIC(masm, entry, &returnOffset); + EmitCallIC(masm, &returnOffset); RetAddrEntry::Kind kind = entry->isForPrologue() ? RetAddrEntry::Kind::PrologueIC @@ -837,6 +855,8 @@ static gc::Cell* GetScriptGCThing(JSScript* script, jsbytecode* pc, return script->getAtom(pc); case ScriptGCThingType::RegExp: return script->getRegExp(pc); + case ScriptGCThingType::Object: + return script->getObject(pc); case ScriptGCThingType::Function: return script->getFunction(pc); case ScriptGCThingType::Scope: @@ -882,6 +902,7 @@ void BaselineInterpreterCodeGen::loadScriptGCThing(ScriptGCThingType type, masm.xorPtr(Imm32(2), dest); break; case ScriptGCThingType::RegExp: + case ScriptGCThingType::Object: case ScriptGCThingType::Function: // No-op because GCCellPtr tag bits are zero for objects. static_assert(uintptr_t(TraceKind::Object) == 0, @@ -1017,15 +1038,41 @@ bool BaselineCodeGen::emitDebugPrologue() { template <> void BaselineCompilerCodeGen::emitInitFrameFields(Register nonFunctionEnv) { + Register scratch = R0.scratchReg(); + Register scratch2 = R2.scratchReg(); + MOZ_ASSERT(nonFunctionEnv != scratch && nonFunctionEnv != scratch2); + masm.store32(Imm32(0), frame.addressOfFlags()); if (handler.function()) { - Register scratch = R0.scratchReg(); masm.loadFunctionFromCalleeToken(frame.addressOfCalleeToken(), scratch); masm.loadPtr(Address(scratch, JSFunction::offsetOfEnvironment()), scratch); masm.storePtr(scratch, frame.addressOfEnvironmentChain()); } else { masm.storePtr(nonFunctionEnv, frame.addressOfEnvironmentChain()); } + + if (!JitOptions.warpBuilder) { + // Trial inlining only supported in Warp. + return; + } + + // If cx->inlinedICScript contains an inlined ICScript (passed from + // the caller), take that ICScript and store it in the frame, then + // overwrite cx->inlinedICScript with nullptr. + Label notInlined, done; + masm.movePtr(ImmPtr(cx->addressOfInlinedICScript()), scratch); + Address inlinedAddr(scratch, 0); + masm.branchPtr(Assembler::Equal, inlinedAddr, ImmWord(0), ¬Inlined); + masm.loadPtr(inlinedAddr, scratch2); + masm.storePtr(scratch2, frame.addressOfICScript()); + masm.storePtr(ImmPtr(nullptr), inlinedAddr); + masm.jump(&done); + + // Otherwise, store this script's default ICSCript in the frame. + masm.bind(¬Inlined); + masm.storePtr(ImmPtr(handler.script()->jitScript()->icScript()), + frame.addressOfICScript()); + masm.bind(&done); } template <> @@ -1062,11 +1109,22 @@ void BaselineInterpreterCodeGen::emitInitFrameFields(Register nonFunctionEnv) { masm.bind(&done); masm.storePtr(scratch1, frame.addressOfInterpreterScript()); - // Initialize interpreterICEntry. - masm.loadJitScript(scratch1, scratch2); - masm.computeEffectiveAddress( - Address(scratch2, JitScript::offsetOfICEntries()), scratch2); - masm.storePtr(scratch2, frame.addressOfInterpreterICEntry()); + if (JitOptions.warpBuilder) { + // Initialize icScript and interpreterICEntry + masm.loadJitScript(scratch1, scratch2); + masm.computeEffectiveAddress( + Address(scratch2, JitScript::offsetOfICScript()), scratch2); + masm.storePtr(scratch2, frame.addressOfICScript()); + masm.computeEffectiveAddress( + Address(scratch2, ICScript::offsetOfICEntries()), scratch2); + masm.storePtr(scratch2, frame.addressOfInterpreterICEntry()); + } else { + // Initialize interpreterICEntry + masm.loadJitScript(scratch1, scratch2); + masm.computeEffectiveAddress( + Address(scratch2, JitScript::offsetOfICEntries()), scratch2); + masm.storePtr(scratch2, frame.addressOfInterpreterICEntry()); + } // Initialize interpreterPC. masm.loadPtr(Address(scratch1, JSScript::offsetOfSharedData()), scratch1); @@ -1179,19 +1237,51 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() { Register scriptReg = R2.scratchReg(); Register countReg = R0.scratchReg(); - // Load the JitScript* in scriptReg. - masm.movePtr(ImmPtr(script->jitScript()), scriptReg); + uint32_t warmUpCountOffset; + if (JitOptions.warpBuilder) { + // Load the ICScript* in scriptReg. + masm.loadPtr(frame.addressOfICScript(), scriptReg); + warmUpCountOffset = ICScript::offsetOfWarmUpCount(); + } else { + // Load the JitScript* in scriptReg. + masm.movePtr(ImmPtr(script->jitScript()), scriptReg); + warmUpCountOffset = JitScript::offsetOfWarmUpCount(); + } // Bump warm-up counter. - Address warmUpCounterAddr(scriptReg, JitScript::offsetOfWarmUpCount()); + Address warmUpCounterAddr(scriptReg, warmUpCountOffset); masm.load32(warmUpCounterAddr, countReg); masm.add32(Imm32(1), countReg); masm.store32(countReg, warmUpCounterAddr); + if (JitOptions.warpBuilder && !JitOptions.disableInlining) { + // Consider trial inlining. + // Note: unlike other warmup thresholds, where we try to enter a + // higher tier whenever we are higher than a given warmup count, + // trial inlining triggers once when reaching the threshold. + Label noTrialInlining; + masm.branch32(Assembler::NotEqual, countReg, + Imm32(JitOptions.trialInliningWarmUpThreshold), + &noTrialInlining); + prepareVMCall(); + + masm.PushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); + + using Fn = bool (*)(JSContext*, BaselineFrame*); + if (!callVMNonOp()) { + return false; + } + // Reload registers potentially clobbered by the call. + masm.loadPtr(frame.addressOfICScript(), scriptReg); + masm.load32(warmUpCounterAddr, countReg); + masm.bind(&noTrialInlining); + } + if (JSOp(*pc) == JSOp::LoopHead) { - // If this is a loop inside a catch or finally block, increment the warmup - // counter but don't attempt OSR (Ion only compiles the try block). - if (handler.analysis().info(pc).loopHeadInCatchOrFinally) { + // If this is a loop where we can't OSR (for example because it's inside a + // catch or finally block), increment the warmup counter but don't attempt + // OSR (Ion/Warp only compiles the try block). + if (!handler.analysis().info(pc).loopHeadCanOsr) { return true; } } @@ -1203,9 +1293,23 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() { uint32_t warmUpThreshold = info->compilerWarmUpThreshold(script, pc); masm.branch32(Assembler::LessThan, countReg, Imm32(warmUpThreshold), &done); + if (JitOptions.warpBuilder) { + // Don't trigger Ion compilations from trial-inlined scripts. + Address depthAddr(scriptReg, ICScript::offsetOfDepth()); + masm.branch32(Assembler::NotEqual, depthAddr, Imm32(0), &done); + + // Load the IonScript* in scriptReg. We can load this from the ICScript* + // because it must be an outer ICScript embedded in the JitScript. + constexpr int32_t offset = -int32_t(JitScript::offsetOfICScript()) + + int32_t(JitScript::offsetOfIonScript()); + masm.loadPtr(Address(scriptReg, offset), scriptReg); + } else { + // Load the IonScript* in scriptReg. + masm.loadPtr(Address(scriptReg, JitScript::offsetOfIonScript()), scriptReg); + } + // Do nothing if Ion is already compiling this script off-thread or if Ion has // been disabled for this script. - masm.loadPtr(Address(scriptReg, JitScript::offsetOfIonScript()), scriptReg); masm.branchPtr(Assembler::Equal, scriptReg, ImmPtr(IonCompilingScriptPtr), &done); masm.branchPtr(Assembler::Equal, scriptReg, ImmPtr(IonDisabledScriptPtr), @@ -1293,10 +1397,8 @@ bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() { masm.PushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); - const RetAddrEntry::Kind kind = RetAddrEntry::Kind::WarmupCounter; - using Fn = bool (*)(JSContext*, BaselineFrame*); - if (!callVM(kind)) { + if (!callVMNonOp()) { return false; } } @@ -2434,38 +2536,18 @@ bool BaselineInterpreterCodeGen::emit_Symbol() { return true; } -JSObject* BaselineCompilerHandler::maybeNoCloneSingletonObject() { - Realm* realm = script()->realm(); - if (realm->creationOptions().cloneSingletons()) { - return nullptr; - } - - realm->behaviors().setSingletonsAsValues(); - return script()->getObject(pc()); +template <> +bool BaselineCompilerCodeGen::emit_Object() { + frame.push(ObjectValue(*handler.script()->getObject(handler.pc()))); + return true; } -template -bool BaselineCodeGen::emit_Object() { - // If we know we don't have to clone the object literal, just push it - // directly. Note that the interpreter always does the VM call; that's fine - // because this op is only used in run-once code. - if (JSObject* obj = handler.maybeNoCloneSingletonObject()) { - frame.push(ObjectValue(*obj)); - return true; - } - - prepareVMCall(); - - pushBytecodePCArg(); - pushScriptArg(); - - using Fn = JSObject* (*)(JSContext*, HandleScript, jsbytecode*); - if (!callVM()) { - return false; - } - - // Box and push return value. - masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0); +template <> +bool BaselineInterpreterCodeGen::emit_Object() { + Register scratch1 = R0.scratchReg(); + Register scratch2 = R1.scratchReg(); + loadScriptGCThing(ScriptGCThingType::Object, scratch1, scratch2); + masm.tagValue(JSVAL_TYPE_OBJECT, scratch1, R0); frame.push(R0); return true; } @@ -2912,6 +2994,11 @@ bool BaselineCodeGen::emit_InitHiddenElem() { return emit_InitElem(); } +template +bool BaselineCodeGen::emit_InitLockedElem() { + return emit_InitElem(); +} + template bool BaselineCodeGen::emit_MutateProto() { // Keep values on the stack for the decompiler. @@ -3130,6 +3217,21 @@ bool BaselineCodeGen::emit_HasOwn() { return true; } +template +bool BaselineCodeGen::emit_CheckPrivateField() { + // Keep key and val on the stack. + frame.syncStack(0); + masm.loadValue(frame.addressOfStackValue(-2), R0); + masm.loadValue(frame.addressOfStackValue(-1), R1); + + if (!emitNextIC()) { + return false; + } + + frame.push(R0); + return true; +} + template <> bool BaselineCompilerCodeGen::tryOptimizeGetGlobalName() { PropertyName* name = handler.script()->getName(handler.pc()); @@ -3190,32 +3292,12 @@ bool BaselineCompilerCodeGen::tryOptimizeBindGlobalName() { return false; } - // We can bind name to the global lexical scope if the binding already - // exists, is initialized, and is writable (i.e., an initialized - // 'let') at compile time. + RootedGlobalObject global(cx, &script->global()); RootedPropertyName name(cx, script->getName(handler.pc())); - Rooted env(cx, - &script->global().lexicalEnvironment()); - if (Shape* shape = env->lookup(cx, name)) { - if (shape->writable() && - !env->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL)) { - frame.push(ObjectValue(*env)); - return true; - } - return false; - } - - if (Shape* shape = script->global().lookup(cx, name)) { - // If the property does not currently exist on the global lexical - // scope, we can bind name to the global object if the property - // exists on the global and is non-configurable, as then it cannot - // be shadowed. - if (!shape->configurable()) { - frame.push(ObjectValue(script->global())); - return true; - } + if (JSObject* binding = MaybeOptimizeBindGlobalName(cx, global, name)) { + frame.push(ObjectValue(*binding)); + return true; } - return false; } @@ -4504,15 +4586,10 @@ bool BaselineCodeGen::emit_OptimizeSpreadCall() { frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(-1), R0); - prepareVMCall(); - pushArg(R0); - - using Fn = bool (*)(JSContext*, HandleValue, bool*); - if (!callVM()) { + if (!emitNextIC()) { return false; } - masm.boxNonDouble(JSVAL_TYPE_BOOLEAN, ReturnReg, R0); frame.push(R0); return true; } @@ -5810,11 +5887,22 @@ bool BaselineCodeGen::emitEnterGeneratorCode(Register script, static_assert(BaselineDisabledScript == 0x1, "Comparison below requires specific sentinel encoding"); + if (JitOptions.warpBuilder) { + // Initialize the icScript slot in the baseline frame. + masm.loadJitScript(script, scratch); + masm.computeEffectiveAddress( + Address(scratch, JitScript::offsetOfICScript()), scratch); + Address icScriptAddr(BaselineFrameReg, + BaselineFrame::reverseOffsetOfICScript()); + masm.storePtr(scratch, icScriptAddr); + } + Label noBaselineScript; masm.loadJitScript(script, scratch); masm.loadPtr(Address(scratch, JitScript::offsetOfBaselineScript()), scratch); masm.branchPtr(Assembler::BelowOrEqual, scratch, ImmPtr(BaselineDisabledScriptPtr), &noBaselineScript); + masm.load32(Address(scratch, BaselineScript::offsetOfResumeEntriesOffset()), script); masm.addPtr(scratch, script); @@ -5966,8 +6054,7 @@ bool BaselineCodeGen::emit_Resume() { // Store the arguments object if there is one. Label noArgsObj; Address argsObjSlot(genObj, AbstractGeneratorObject::offsetOfArgsObjSlot()); - masm.branchTestUndefined(Assembler::Equal, argsObjSlot, &noArgsObj); - masm.unboxObject(argsObjSlot, scratch2); + masm.fallibleUnboxObject(argsObjSlot, scratch2, &noArgsObj); { masm.storePtr(scratch2, frame.addressOfArgsObj()); masm.or32(Imm32(BaselineFrame::HAS_ARGS_OBJ), frame.addressOfFlags()); @@ -5978,10 +6065,8 @@ bool BaselineCodeGen::emit_Resume() { Label noExprStack; Address exprStackSlot(genObj, AbstractGeneratorObject::offsetOfExpressionStackSlot()); - masm.branchTestNull(Assembler::Equal, exprStackSlot, &noExprStack); + masm.fallibleUnboxObject(exprStackSlot, scratch2, &noExprStack); { - masm.unboxObject(exprStackSlot, scratch2); - Register initLength = regs.takeAny(); masm.loadPtr(Address(scratch2, NativeObject::offsetOfElements()), scratch2); masm.load32(Address(scratch2, ObjectElements::offsetOfInitializedLength()), @@ -6167,11 +6252,18 @@ bool BaselineInterpreterCodeGen::emit_JumpTarget() { masm.lshiftPtr(Imm32(shift), scratch1); // Compute ICEntry* and store to frame->interpreterICEntry. - loadScript(scratch2); - masm.loadJitScript(scratch2, scratch2); - masm.computeEffectiveAddress( - BaseIndex(scratch2, scratch1, TimesOne, JitScript::offsetOfICEntries()), - scratch2); + if (JitOptions.warpBuilder) { + masm.loadPtr(frame.addressOfICScript(), scratch2); + masm.computeEffectiveAddress( + BaseIndex(scratch2, scratch1, TimesOne, ICScript::offsetOfICEntries()), + scratch2); + } else { + loadScript(scratch2); + masm.loadJitScript(scratch2, scratch2); + masm.computeEffectiveAddress( + BaseIndex(scratch2, scratch1, TimesOne, JitScript::offsetOfICEntries()), + scratch2); + } masm.storePtr(scratch2, frame.addressOfInterpreterICEntry()); return true; } @@ -6215,22 +6307,25 @@ bool BaselineCodeGen::emit_InitHomeObject() { } template <> -bool BaselineCompilerCodeGen::emit_FunctionProto() { - // The function prototype is a constant for a given global. - JSObject* funProto = FunctionProtoOperation(cx); - if (!funProto) { +bool BaselineCompilerCodeGen::emit_BuiltinObject() { + // Built-in objects are constants for a given global. + auto kind = BuiltinObjectKind(GET_UINT8(handler.pc())); + JSObject* builtin = BuiltinObjectOperation(cx, kind); + if (!builtin) { return false; } - frame.push(ObjectValue(*funProto)); + frame.push(ObjectValue(*builtin)); return true; } template <> -bool BaselineInterpreterCodeGen::emit_FunctionProto() { +bool BaselineInterpreterCodeGen::emit_BuiltinObject() { prepareVMCall(); - using Fn = JSObject* (*)(JSContext*); - if (!callVM()) { + pushUint8BytecodeOperandArg(R0.scratchReg()); + + using Fn = JSObject* (*)(JSContext*, BuiltinObjectKind); + if (!callVM()) { return false; } diff --git a/js/src/jit/BaselineCodeGen.h b/js/src/jit/BaselineCodeGen.h index dc20de7267..bba81cc6db 100644 --- a/js/src/jit/BaselineCodeGen.h +++ b/js/src/jit/BaselineCodeGen.h @@ -16,7 +16,7 @@ namespace js { namespace jit { -enum class ScriptGCThingType { Atom, RegExp, Function, Scope, BigInt }; +enum class ScriptGCThingType { Atom, RegExp, Object, Function, Scope, BigInt }; // Base class for BaselineCompiler and BaselineInterpreterGenerator. The Handler // template is a class storing fields/methods that are interpreter or compiler @@ -354,8 +354,6 @@ class BaselineCompilerHandler { static constexpr size_t NumSlotsLimit = 128; return script()->nslots() > NumSlotsLimit; } - - JSObject* maybeNoCloneSingletonObject(); }; using BaselineCompilerCodeGen = BaselineCodeGen; @@ -470,8 +468,6 @@ class BaselineInterpreterHandler { // The interpreter doesn't know the number of slots statically so we always // include them. bool mustIncludeSlotsInStackCheck() const { return true; } - - JSObject* maybeNoCloneSingletonObject() { return nullptr; } }; using BaselineInterpreterCodeGen = BaselineCodeGen; diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 75b730068f..54b7722853 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -176,8 +176,6 @@ static const char* RetAddrEntryKindToString(RetAddrEntry::Kind kind) { return "prologue IC"; case RetAddrEntry::Kind::CallVM: return "callVM"; - case RetAddrEntry::Kind::WarmupCounter: - return "warmup counter"; case RetAddrEntry::Kind::StackCheck: return "stack check"; case RetAddrEntry::Kind::InterruptCheck: @@ -223,18 +221,17 @@ static void PatchBaselineFramesForDebugMode( // A. From a non-prologue IC (fallback stub or "can call" stub). // B. From a VM call. // C. From inside the interrupt handler via the prologue stack check. - // D. From the warmup counter in the prologue. // // On to Off: // - All the ways above. - // E. From the debug trap handler. - // F. From the debug prologue. - // G. From the debug epilogue. - // H. From a JSOp::AfterYield instruction. + // D. From the debug trap handler. + // E. From the debug prologue. + // F. From the debug epilogue. + // G. From a JSOp::AfterYield instruction. // // In general, we patch the return address from VM calls and ICs to the // corresponding entry in the recompiled BaselineScript. For entries that are - // not present in the recompiled script (cases F to I above) we switch the + // not present in the recompiled script (cases D to G above) we switch the // frame to interpreter mode and resume in the Baseline Interpreter. // // Specifics on what needs to be done are documented below. @@ -285,9 +282,8 @@ static void PatchBaselineFramesForDebugMode( case RetAddrEntry::Kind::IC: case RetAddrEntry::Kind::CallVM: case RetAddrEntry::Kind::InterruptCheck: - case RetAddrEntry::Kind::WarmupCounter: case RetAddrEntry::Kind::StackCheck: { - // Cases A, B, C, D above. + // Cases A, B, C above. // // For the baseline frame here, we resume right after the CallVM or // IC returns. @@ -302,7 +298,6 @@ static void PatchBaselineFramesForDebugMode( case RetAddrEntry::Kind::InterruptCheck: retAddrEntry = &bl->retAddrEntryFromPCOffset(pcOffset, kind); break; - case RetAddrEntry::Kind::WarmupCounter: case RetAddrEntry::Kind::StackCheck: retAddrEntry = &bl->prologueRetAddrEntry(kind); break; @@ -318,7 +313,7 @@ static void PatchBaselineFramesForDebugMode( case RetAddrEntry::Kind::DebugEpilogue: case RetAddrEntry::Kind::DebugTrap: case RetAddrEntry::Kind::DebugAfterYield: { - // Cases E, F, G, H above. + // Cases D, E, F, G above. // // Resume in the Baseline Interpreter because these callVMs are not // present in the new BaselineScript if we recompiled without debug diff --git a/js/src/jit/BaselineFrame-inl.h b/js/src/jit/BaselineFrame-inl.h index 3dae9a33ab..a25f4968db 100644 --- a/js/src/jit/BaselineFrame-inl.h +++ b/js/src/jit/BaselineFrame-inl.h @@ -7,7 +7,6 @@ #include "jit/BaselineFrame.h" -#include "vm/EnvironmentObject.h" #include "vm/JSContext.h" #include "vm/Realm.h" @@ -87,6 +86,20 @@ inline CallObject& BaselineFrame::callObj() const { return obj->as(); } +inline ICScript* BaselineFrame::icScript() const { + if (JitOptions.warpBuilder) { + return icScript_; + } + return script()->jitScript()->icScript(); +} + +inline JSScript* BaselineFrame::invalidationScript() const { + if (!icScript()->isInlined()) { + return script(); + } + return icScript()->inliningRoot()->owningScript(); +} + inline void BaselineFrame::unsetIsDebuggee() { MOZ_ASSERT(!script()->isDebuggee()); flags_ &= ~DEBUGGEE; diff --git a/js/src/jit/BaselineFrame.cpp b/js/src/jit/BaselineFrame.cpp index 0b31b15fd4..08d4e0ca2f 100644 --- a/js/src/jit/BaselineFrame.cpp +++ b/js/src/jit/BaselineFrame.cpp @@ -108,18 +108,24 @@ bool BaselineFrame::pushVarEnvironment(JSContext* cx, HandleScope scope) { void BaselineFrame::setInterpreterFields(JSScript* script, jsbytecode* pc) { uint32_t pcOffset = script->pcToOffset(pc); - JitScript* jitScript = script->jitScript(); interpreterScript_ = script; interpreterPC_ = pc; - interpreterICEntry_ = jitScript->interpreterICEntryFromPCOffset(pcOffset); + if (JitOptions.warpBuilder) { + MOZ_ASSERT(icScript_); + interpreterICEntry_ = icScript_->interpreterICEntryFromPCOffset(pcOffset); + } else { + JitScript* jitScript = script->jitScript(); + interpreterICEntry_ = jitScript->interpreterICEntryFromPCOffset(pcOffset); + } } void BaselineFrame::setInterpreterFieldsForPrologue(JSScript* script) { - JitScript* jitScript = script->jitScript(); interpreterScript_ = script; interpreterPC_ = script->code(); - if (jitScript->numICEntries() > 0) { - interpreterICEntry_ = &jitScript->icEntry(0); + ICScript* icScript = + JitOptions.warpBuilder ? icScript_ : script->jitScript()->icScript(); + if (icScript->numICEntries() > 0) { + interpreterICEntry_ = &icScript->icEntry(0); } else { // If the script does not have any ICEntries (possible for non-function // scripts) the interpreterICEntry_ field won't be used. Just set it to @@ -146,6 +152,10 @@ bool BaselineFrame::initForOsr(InterpreterFrame* fp, uint32_t numStackValues) { setReturnValue(fp->returnValue()); } + if (JitOptions.warpBuilder) { + icScript_ = fp->script()->jitScript()->icScript(); + } + JSContext* cx = fp->script()->runtimeFromMainThread()->mainContextFromOwnThread(); diff --git a/js/src/jit/BaselineFrame.h b/js/src/jit/BaselineFrame.h index 58de7324ab..85804a0267 100644 --- a/js/src/jit/BaselineFrame.h +++ b/js/src/jit/BaselineFrame.h @@ -58,6 +58,7 @@ class BaselineFrame { ICEntry* interpreterICEntry_; JSObject* envChain_; // Environment chain (always initialized). + ICScript* icScript_; // IC script (initialized if Warp is enabled). ArgumentsObject* argsObj_; // If HAS_ARGS_OBJ, the arguments object. // We need to split the Value into 2 fields of 32 bits, otherwise the C++ @@ -79,6 +80,10 @@ class BaselineFrame { #endif uint32_t loReturnValue_; // If HAS_RVAL, the frame's return value. uint32_t hiReturnValue_; +#if JS_BITS_PER_WORD == 32 + // Ensure frame is 8-byte aligned, see static_assert below. + uint32_t padding_; +#endif public: // Distance between the frame pointer and the frame header (return address). @@ -94,7 +99,6 @@ class BaselineFrame { JSObject* environmentChain() const { return envChain_; } void setEnvironmentChain(JSObject* envChain) { envChain_ = envChain; } - inline JSObject** addressOfEnvironmentChain() { return &envChain_; } template inline void pushOnEnvironmentChain(SpecificEnvironment& env); @@ -216,7 +220,6 @@ class BaselineFrame { flags_ &= ~RUNNING_IN_INTERPRETER; interpreterScript_ = nullptr; interpreterPC_ = nullptr; - interpreterICEntry_ = nullptr; } void initInterpFieldsForGeneratorThrowOrReturn(JSScript* script, @@ -283,6 +286,14 @@ class BaselineFrame { // argument type check ICs). void setInterpreterFieldsForPrologue(JSScript* script); + ICScript* icScript() const; + void setICScript(ICScript* icScript) { + MOZ_ASSERT(JitOptions.warpBuilder); + icScript_ = icScript; + } + + JSScript* invalidationScript() const; + bool hasReturnValue() const { return flags_ & HAS_RVAL; } MutableHandleValue returnValue() { if (!hasReturnValue()) { @@ -413,6 +424,9 @@ class BaselineFrame { static int reverseOffsetOfInterpreterICEntry() { return -int(Size()) + offsetof(BaselineFrame, interpreterICEntry_); } + static int reverseOffsetOfICScript() { + return -int(Size()) + offsetof(BaselineFrame, icScript_); + } static int reverseOffsetOfLocal(size_t index) { return -int(Size()) - (index + 1) * sizeof(Value); } diff --git a/js/src/jit/BaselineFrameInfo.h b/js/src/jit/BaselineFrameInfo.h index e2f8056306..81ada9107f 100644 --- a/js/src/jit/BaselineFrameInfo.h +++ b/js/src/jit/BaselineFrameInfo.h @@ -12,13 +12,13 @@ #include "jit/BaselineFrame.h" #include "jit/BaselineJIT.h" #include "jit/FixedList.h" -#include "jit/MacroAssembler.h" #include "jit/SharedICRegisters.h" namespace js { namespace jit { struct BytecodeInfo; +class MacroAssembler; // [SMDOC] Baseline FrameInfo overview. // @@ -194,6 +194,9 @@ class FrameInfo { return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfEnvironmentChain()); } + Address addressOfICScript() const { + return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfICScript()); + } Address addressOfFlags() const { return Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()); } diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index d6fae2f754..93471836d9 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -164,7 +164,7 @@ class MOZ_RAII FallbackStubAllocator { // Helper method called by lambda expressions `addIC` and `addPrologueIC` in // `JitScript::initICEntriesAndBytecodeTypeMap`. -static bool AddICImpl(JSContext* cx, JitScript* jitScript, uint32_t offset, +static bool AddICImpl(JSContext* cx, ICScript* icScript, uint32_t offset, ICStub* stub, uint32_t& icEntryIndex) { if (!stub) { MOZ_ASSERT(cx->isExceptionPending()); @@ -173,7 +173,7 @@ static bool AddICImpl(JSContext* cx, JitScript* jitScript, uint32_t offset, } // Initialize the ICEntry. - ICEntry& entryRef = jitScript->icEntry(icEntryIndex); + ICEntry& entryRef = icScript->icEntry(icEntryIndex); icEntryIndex++; new (&entryRef) ICEntry(stub, offset); @@ -187,14 +187,13 @@ static bool AddICImpl(JSContext* cx, JitScript* jitScript, uint32_t offset, return true; } -bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, - JSScript* script) { +bool ICScript::initICEntries(JSContext* cx, JSScript* script) { MOZ_ASSERT(cx->realm()->jitRealm()); MOZ_ASSERT(jit::IsBaselineInterpreterEnabled()); MOZ_ASSERT(numICEntries() == script->numICEntries()); - FallbackStubAllocator alloc(cx, fallbackStubSpace_); + FallbackStubAllocator alloc(cx, *fallbackStubSpace()); // Index of the next ICEntry to initialize. uint32_t icEntryIndex = 0; @@ -233,22 +232,9 @@ bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, } } - // Index of the next bytecode type map entry to initialize. - uint32_t typeMapIndex = 0; - uint32_t* const typeMap = - IsTypeInferenceEnabled() ? bytecodeTypeMap() : nullptr; - // For JOF_IC ops: initialize ICEntries and fallback stubs. - // For JOF_TYPESET ops: initialize bytecode type map entries. for (BytecodeLocation loc : js::AllBytecodesIterable(script)) { JSOp op = loc.getOp(); - // Note: if the script is very large there will be more JOF_TYPESET ops - // than bytecode type sets. See JSScript::MaxBytecodeTypeSets. - if (BytecodeOpHasTypeSet(op) && typeMap && - typeMapIndex < JSScript::MaxBytecodeTypeSets) { - typeMap[typeMapIndex] = loc.bytecodeToOffset(script); - typeMapIndex++; - } // Assert the frontend stored the correct IC index in jump target ops. MOZ_ASSERT_IF(BytecodeIsJumpTarget(op), loc.icIndex() == icEntryIndex); @@ -337,6 +323,7 @@ bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, } case JSOp::InitElem: case JSOp::InitHiddenElem: + case JSOp::InitLockedElem: case JSOp::InitElemArray: case JSOp::InitElemInc: case JSOp::SetElem: @@ -409,6 +396,14 @@ bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, } break; } + case JSOp::CheckPrivateField: { + ICStub* stub = alloc.newStub( + Kind::CheckPrivateField); + if (!addIC(loc, stub)) { + return false; + } + break; + } case JSOp::GetName: case JSOp::GetGName: { ICStub* stub = alloc.newStub(Kind::GetName); @@ -511,6 +506,14 @@ bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, } break; } + case JSOp::OptimizeSpreadCall: { + ICStub* stub = alloc.newStub( + Kind::OptimizeSpreadCall); + if (!addIC(loc, stub)) { + return false; + } + break; + } case JSOp::Rest: { ArrayObject* templateObject = ObjectGroup::newArrayObject( cx, nullptr, 0, TenuredObject, @@ -530,11 +533,8 @@ bool JitScript::initICEntriesAndBytecodeTypeMap(JSContext* cx, } } - // Assert all ICEntries and type map entries have been initialized. + // Assert all ICEntries have been initialized. MOZ_ASSERT(icEntryIndex == numICEntries()); - MOZ_ASSERT_IF(IsTypeInferenceEnabled(), - typeMapIndex == script->numBytecodeTypeSets()); - return true; } @@ -561,12 +561,14 @@ ICStubIterator& ICStubIterator::operator++() { return *this; } -void ICStubIterator::unlink(JSContext* cx) { +void ICStubIterator::unlink(JSContext* cx, JSScript* script) { MOZ_ASSERT(currentStub_->next() != nullptr); MOZ_ASSERT(currentStub_ != fallbackStub_); MOZ_ASSERT(!unlinked_); - fallbackStub_->unlinkStub(cx->zone(), previousStub_, currentStub_); + fallbackStub_->maybeInvalidateWarp(cx, script); + fallbackStub_->unlinkStubDontInvalidateWarp(cx->zone(), previousStub_, + currentStub_); // Mark the current iterator position as unlinked, so operator++ works // properly. @@ -618,9 +620,22 @@ uint32_t ICStub::getEnteredCount() const { } } +void ICFallbackStub::maybeInvalidateWarp(JSContext* cx, JSScript* script) { + if (!state_.usedByTranspiler()) { + return; + } + + MOZ_ASSERT(JitOptions.warpBuilder); + clearUsedByTranspiler(); + + if (script->hasIonScript()) { + Invalidate(cx, script); + } +} + void ICStub::updateCode(JitCode* code) { // Write barrier on the old code. - JitCode::writeBarrierPre(jitCode()); + gc::PreWriteBarrier(jitCode()); stubCode_ = code->raw(); } @@ -718,68 +733,6 @@ void ICStub::trace(JSTracer* trc) { } } -bool ICStub::stubDataHasNurseryPointers(const CacheIRStubInfo* stubInfo) { - MOZ_ASSERT(IsCacheIRKind(kind())); - - uint32_t field = 0; - size_t offset = 0; - while (true) { - StubField::Type fieldType = stubInfo->fieldType(field); - switch (fieldType) { - case StubField::Type::RawWord: - case StubField::Type::RawInt64: - case StubField::Type::DOMExpandoGeneration: - break; - case StubField::Type::Shape: - static_assert(std::is_convertible_v, - "Code assumes shapes are tenured"); - break; - case StubField::Type::ObjectGroup: - static_assert(std::is_convertible_v, - "Code assumes groups are tenured"); - break; - case StubField::Type::Symbol: - static_assert(std::is_convertible_v, - "Code assumes symbols are tenured"); - break; - case StubField::Type::JSObject: { - JSObject* obj = stubInfo->getStubField(this, offset); - if (IsInsideNursery(obj)) { - return true; - } - break; - } - case StubField::Type::String: { - JSString* str = stubInfo->getStubField(this, offset); - if (IsInsideNursery(str)) { - return true; - } - break; - } - case StubField::Type::Id: { -#ifdef DEBUG - // jsid never contains nursery-allocated things. - jsid id = stubInfo->getStubField(this, offset); - MOZ_ASSERT_IF(id.isGCThing(), - !IsInsideNursery(id.toGCCellPtr().asCell())); -#endif - break; - } - case StubField::Type::Value: { - Value v = stubInfo->getStubField(this, offset); - if (v.isGCThing() && IsInsideNursery(v.toGCThing())) { - return true; - } - break; - } - case StubField::Type::Limit: - return false; // Done. Didn't find any nursery pointers. - } - field++; - offset += StubField::sizeInBytes(fieldType); - } -} - // This helper handles ICState updates/transitions while attaching CacheIR // stubs. template @@ -787,11 +740,12 @@ static void TryAttachStub(const char* name, JSContext* cx, BaselineFrame* frame, ICFallbackStub* stub, BaselineCacheIRStubKind kind, Args&&... args) { if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } if (stub->state().canAttachStub()) { RootedScript script(cx, frame->script()); + ICScript* icScript = frame->icScript(); jsbytecode* pc = stub->icEntry()->pc(script); bool attached = false; @@ -801,7 +755,7 @@ static void TryAttachStub(const char* name, JSContext* cx, BaselineFrame* frame, case AttachDecision::Attach: { ICStub* newStub = AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), - kind, script, stub, &attached); + kind, script, icScript, stub, &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached %s CacheIR stub", name); } @@ -819,7 +773,8 @@ static void TryAttachStub(const char* name, JSContext* cx, BaselineFrame* frame, } } -void ICFallbackStub::unlinkStub(Zone* zone, ICStub* prev, ICStub* stub) { +void ICFallbackStub::unlinkStubDontInvalidateWarp(Zone* zone, ICStub* prev, + ICStub* stub) { MOZ_ASSERT(stub->next()); if (prev) { @@ -863,9 +818,9 @@ void ICFallbackStub::unlinkStub(Zone* zone, ICStub* prev, ICStub* stub) { #endif } -void ICFallbackStub::discardStubs(JSContext* cx) { +void ICFallbackStub::discardStubs(JSContext* cx, JSScript* script) { for (ICStubIterator iter = beginChain(); !iter.atEnd(); iter++) { - iter.unlink(cx); + iter.unlink(cx, script); } } @@ -985,9 +940,11 @@ bool ICCacheIR_Updated::initUpdatingChain(JSContext* cx, ICStubSpace* space) { /* static */ ICStubSpace* ICStubCompiler::StubSpaceForStub(bool makesGCCalls, - JSScript* script) { + JSScript* script, + ICScript* icScript) { if (makesGCCalls) { - return script->jitScript()->fallbackStubSpace(); + return icScript ? icScript->fallbackStubSpace() + : script->jitScript()->fallbackStubSpace(); } return script->zone()->jitZone()->optimizedStubSpace(); } @@ -1767,12 +1724,12 @@ bool ICTypeUpdate_SingleObject::Compiler::generateStubCode( bool ICTypeUpdate_ObjectGroup::Compiler::generateStubCode( MacroAssembler& masm) { Label failure; - masm.branchTestObject(Assembler::NotEqual, R0, &failure); + + Register scratch1 = R1.scratchReg(); + masm.fallibleUnboxObject(R0, scratch1, &failure); // Guard on the object's ObjectGroup. Address expectedGroup(ICStubReg, ICTypeUpdate_ObjectGroup::offsetOfGroup()); - Register scratch1 = R1.scratchReg(); - masm.unboxObject(R0, scratch1); masm.branchTestObjGroup(Assembler::NotEqual, scratch1, expectedGroup, scratch1, R0.payloadOrValueReg(), &failure); @@ -1829,7 +1786,8 @@ bool FallbackICCodeCompiler::emit_ToBool() { return tailCallVM(masm); } -static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub) { +static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub, + JSScript* script) { // Before the new script properties analysis has been performed on a type, // all instances of that type have the maximum number of fixed slots. // Afterwards, the objects (even the preliminary ones) might be changed @@ -1842,13 +1800,13 @@ static void StripPreliminaryObjectStubs(JSContext* cx, ICFallbackStub* stub) { for (ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++) { if (iter->isCacheIR_Regular() && iter->toCacheIR_Regular()->hasPreliminaryObject()) { - iter.unlink(cx); + iter.unlink(cx, script); } else if (iter->isCacheIR_Monitored() && iter->toCacheIR_Monitored()->hasPreliminaryObject()) { - iter.unlink(cx); + iter.unlink(cx, script); } else if (iter->isCacheIR_Updated() && iter->toCacheIR_Updated()->hasPreliminaryObject()) { - iter.unlink(cx); + iter.unlink(cx, script); } } } @@ -1860,26 +1818,28 @@ static bool TryAttachGetPropStub(const char* name, JSContext* cx, bool attached = false; if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } if (stub->state().canAttachStub()) { RootedScript script(cx, frame->script()); + ICScript* icScript = frame->icScript(); jsbytecode* pc = stub->icEntry()->pc(script); GetPropIRGenerator gen(cx, script, pc, stub->state().mode(), kind, val, idVal, receiver, GetPropertyResultFlags::All); switch (gen.tryAttachStub()) { case AttachDecision::Attach: { - ICStub* newStub = AttachBaselineCacheIRStub( - cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Monitored, script, stub, &attached); + ICStub* newStub = + AttachBaselineCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), + BaselineCacheIRStubKind::Monitored, + script, icScript, stub, &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached %s CacheIR stub", name); if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Monitored()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { - StripPreliminaryObjectStubs(cx, stub); + StripPreliminaryObjectStubs(cx, stub, frame->invalidationScript()); } } } break; @@ -2076,11 +2036,16 @@ bool FallbackICCodeCompiler::emitGetElem(bool hasReceiver) { leaveStubFrame(masm, true); + if (!IsTypeInferenceEnabled()) { + EmitReturnFromIC(masm); + return true; + } + // When we get here, ICStubReg contains the ICGetElem_Fallback stub, // which we can't use to enter the TypeMonitor IC, because it's a // MonitoredFallbackStub instead of a MonitoredStub. So, we cheat. Note that - // we must have a non-null fallbackMonitorStub here because InitFromBailout - // delazifies. + // we must have a non-null fallbackMonitorStub here because + // BaselineStackBuilder::buildStubFrame delazifies the stub when bailing out. masm.loadPtr(Address(ICStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()), ICStubReg); @@ -2121,7 +2086,8 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, MOZ_ASSERT(op == JSOp::SetElem || op == JSOp::StrictSetElem || op == JSOp::InitElem || op == JSOp::InitHiddenElem || - op == JSOp::InitElemArray || op == JSOp::InitElemInc); + op == JSOp::InitLockedElem || op == JSOp::InitElemArray || + op == JSOp::InitElemInc); int objvIndex = -3; RootedObject obj( @@ -2136,21 +2102,27 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, return false; } + // We cannot attach a stub if the operation executed after the stub + // is attached may throw. + bool mayThrow = false; + DeferType deferType = DeferType::None; bool attached = false; if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } - if (stub->state().canAttachStub()) { + if (stub->state().canAttachStub() && !mayThrow) { + ICScript* icScript = frame->icScript(); SetPropIRGenerator gen(cx, script, pc, CacheKind::SetElem, stub->state().mode(), objv, index, rhs); switch (gen.tryAttachStub()) { case AttachDecision::Attach: { ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); + BaselineCacheIRStubKind::Updated, frame->script(), icScript, stub, + &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub"); @@ -2159,7 +2131,7 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { - StripPreliminaryObjectStubs(cx, stub); + StripPreliminaryObjectStubs(cx, stub, frame->invalidationScript()); } if (gen.attachedTypedArrayOOBStub()) { @@ -2179,7 +2151,8 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, } } - if (op == JSOp::InitElem || op == JSOp::InitHiddenElem) { + if (op == JSOp::InitElem || op == JSOp::InitHiddenElem || + op == JSOp::InitLockedElem) { if (!InitElemOperation(cx, pc, obj, index, rhs)) { return false; } @@ -2189,11 +2162,13 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, "produce JSOp::InitElemArray with an index exceeding " "int32_t range"); MOZ_ASSERT(uint32_t(index.toInt32()) == GET_UINT32(pc)); - if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs)) { + if (!InitArrayElemOperation(cx, pc, obj.as(), index.toInt32(), + rhs)) { return false; } } else if (op == JSOp::InitElemInc) { - if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs)) { + if (!InitArrayElemOperation(cx, pc, obj.as(), index.toInt32(), + rhs)) { return false; } } else { @@ -2220,7 +2195,7 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, // The SetObjectElement call might have entered this IC recursively, so try // to transition. if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } bool canAttachStub = stub->state().canAttachStub(); @@ -2234,9 +2209,11 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, switch (decision) { case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); + BaselineCacheIRStubKind::Updated, frame->script(), icScript, stub, + &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub"); @@ -2245,7 +2222,7 @@ bool DoSetElemFallback(JSContext* cx, BaselineFrame* frame, if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { - StripPreliminaryObjectStubs(cx, stub); + StripPreliminaryObjectStubs(cx, stub, frame->invalidationScript()); } } } break; @@ -2391,6 +2368,53 @@ bool FallbackICCodeCompiler::emit_HasOwn() { return tailCallVM(masm); } +// +// CheckPrivate_Fallback +// + +bool DoCheckPrivateFieldFallback(JSContext* cx, BaselineFrame* frame, + ICCheckPrivateField_Fallback* stub, + HandleValue objValue, HandleValue keyValue, + MutableHandleValue res) { + stub->incrementEnteredCount(); + RootedScript script(cx, frame->script()); + jsbytecode* pc = stub->icEntry()->pc(script); + + FallbackICSpew(cx, stub, "CheckPrivateField"); + + MOZ_ASSERT(keyValue.isSymbol() && keyValue.toSymbol()->isPrivateName()); + + TryAttachStub( + "CheckPrivate", cx, frame, stub, BaselineCacheIRStubKind::Regular, + CacheKind::CheckPrivateField, keyValue, objValue); + + bool result; + if (!CheckPrivateFieldOperation(cx, pc, objValue, keyValue, &result)) { + return false; + } + + res.setBoolean(result); + return true; +} + +bool FallbackICCodeCompiler::emit_CheckPrivateField() { + EmitRestoreTailCallReg(masm); + + // Sync for the decompiler. + masm.pushValue(R0); + masm.pushValue(R1); + + // Push arguments. + masm.pushValue(R1); + masm.pushValue(R0); + masm.push(ICStubReg); + pushStubPayload(masm, R0.scratchReg()); + + using Fn = bool (*)(JSContext*, BaselineFrame*, ICCheckPrivateField_Fallback*, + HandleValue, HandleValue, MutableHandleValue); + return tailCallVM(masm); +} + // // GetName_Fallback // @@ -2666,11 +2690,16 @@ bool FallbackICCodeCompiler::emitGetProp(bool hasReceiver) { leaveStubFrame(masm, true); + if (!IsTypeInferenceEnabled()) { + EmitReturnFromIC(masm); + return true; + } + // When we get here, ICStubReg contains the ICGetProp_Fallback stub, // which we can't use to enter the TypeMonitor IC, because it's a // MonitoredFallbackStub instead of a MonitoredStub. So, we cheat. Note that - // we must have a non-null fallbackMonitorStub here because InitFromBailout - // delazifies. + // we must have a non-null fallbackMonitorStub here because + // BaselineStackBuilder::buildStubFrame delazifies the stub when bailing out. masm.loadPtr(Address(ICStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()), ICStubReg); @@ -2728,7 +2757,7 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, DeferType deferType = DeferType::None; bool attached = false; if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } if (stub->state().canAttachStub()) { @@ -2737,9 +2766,11 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, stub->state().mode(), lhs, idVal, rhs); switch (gen.tryAttachStub()) { case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); + BaselineCacheIRStubKind::Updated, frame->script(), icScript, stub, + &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached SetProp CacheIR stub"); @@ -2748,7 +2779,7 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { - StripPreliminaryObjectStubs(cx, stub); + StripPreliminaryObjectStubs(cx, stub, frame->invalidationScript()); } } } break; @@ -2805,7 +2836,7 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, // The SetProperty call might have entered this IC recursively, so try // to transition. if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } bool canAttachStub = stub->state().canAttachStub(); @@ -2820,9 +2851,11 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, switch (decision) { case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), - BaselineCacheIRStubKind::Updated, frame->script(), stub, &attached); + BaselineCacheIRStubKind::Updated, frame->script(), icScript, stub, + &attached); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached SetElem CacheIR stub"); @@ -2831,7 +2864,7 @@ bool DoSetPropFallback(JSContext* cx, BaselineFrame* frame, if (gen.shouldNotePreliminaryObjectStub()) { newStub->toCacheIR_Updated()->notePreliminaryObject(); } else if (gen.shouldUnlinkPreliminaryObjectStubs()) { - StripPreliminaryObjectStubs(cx, stub); + StripPreliminaryObjectStubs(cx, stub, frame->invalidationScript()); } } } break; @@ -2928,7 +2961,7 @@ bool DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub, // Transition stub state to megamorphic or generic if warranted. if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } bool canAttachStub = stub->state().canAttachStub(); @@ -2939,15 +2972,17 @@ bool DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub, // allowed to attach stubs. if (canAttachStub) { HandleValueArray args = HandleValueArray::fromMarkedLocation(argc, vp + 2); - CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), argc, callee, - callArgs.thisv(), newTarget, args); + bool isFirstStub = stub->newStubIsFirstStub(); + CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), isFirstStub, + argc, callee, callArgs.thisv(), newTarget, args); switch (gen.tryAttachStub()) { case AttachDecision::NoAction: break; case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script, - stub, &handled); + icScript, stub, &handled); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached Call CacheIR stub"); @@ -3000,19 +3035,21 @@ bool DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub, // Try to transition again in case we called this IC recursively. if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } canAttachStub = stub->state().canAttachStub(); if (deferred && canAttachStub) { HandleValueArray args = HandleValueArray::fromMarkedLocation(argc, vp + 2); - CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), argc, callee, - callArgs.thisv(), newTarget, args); + bool isFirstStub = stub->newStubIsFirstStub(); + CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), isFirstStub, + argc, callee, callArgs.thisv(), newTarget, args); switch (gen.tryAttachDeferredStub(res)) { case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script, - stub, &handled); + icScript, stub, &handled); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached Call CacheIR stub"); @@ -3059,7 +3096,7 @@ bool DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, // Transition stub state to megamorphic or generic if warranted. if (stub->state().maybeTransition()) { - stub->discardStubs(cx); + stub->discardStubs(cx, frame->invalidationScript()); } // Try attaching a call stub. @@ -3072,15 +3109,17 @@ bool DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, HandleValueArray args = HandleValueArray::fromMarkedLocation( aobj->length(), aobj->getDenseElements()); - CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), 1, callee, - thisv, newTarget, args); + bool isFirstStub = stub->newStubIsFirstStub(); + CallIRGenerator gen(cx, script, pc, op, stub->state().mode(), isFirstStub, + 1, callee, thisv, newTarget, args); switch (gen.tryAttachStub()) { case AttachDecision::NoAction: break; case AttachDecision::Attach: { + ICScript* icScript = frame->icScript(); ICStub* newStub = AttachBaselineCacheIRStub( cx, gen.writerRef(), gen.cacheKind(), gen.cacheIRStubKind(), script, - stub, &handled); + icScript, stub, &handled); if (newStub) { JitSpew(JitSpew_BaselineIC, " Attached Spread Call CacheIR stub"); @@ -3266,12 +3305,17 @@ bool FallbackICCodeCompiler::emitCall(bool isSpread, bool isConstructing) { masm.bind(&skipThisReplace); } + if (!IsTypeInferenceEnabled()) { + EmitReturnFromIC(masm); + return true; + } + // At this point, ICStubReg points to the ICCall_Fallback stub, which is NOT // a MonitoredStub, but rather a MonitoredFallbackStub. To use // EmitEnterTypeMonitorIC, first load the ICTypeMonitor_Fallback stub into // ICStubReg. Then, use EmitEnterTypeMonitorIC with a custom struct offset. // Note that we must have a non-null fallbackMonitorStub here because - // InitFromBailout delazifies. + // BaselineStackBuilder::buildStubFrame delazifies the stub when bailing out. masm.loadPtr(Address(ICStubReg, ICMonitoredFallbackStub::offsetOfFallbackMonitorStub()), ICStubReg); @@ -3334,6 +3378,42 @@ bool FallbackICCodeCompiler::emit_GetIterator() { return tailCallVM(masm); } +// +// OptimizeSpreadCall_Fallback +// + +bool DoOptimizeSpreadCallFallback(JSContext* cx, BaselineFrame* frame, + ICOptimizeSpreadCall_Fallback* stub, + HandleValue value, MutableHandleValue res) { + stub->incrementEnteredCount(); + FallbackICSpew(cx, stub, "OptimizeSpreadCall"); + + TryAttachStub( + "OptimizeSpreadCall", cx, frame, stub, BaselineCacheIRStubKind::Regular, + value); + + bool optimized; + if (!OptimizeSpreadCall(cx, value, &optimized)) { + return false; + } + + res.setBoolean(optimized); + return true; +} + +bool FallbackICCodeCompiler::emit_OptimizeSpreadCall() { + EmitRestoreTailCallReg(masm); + + masm.pushValue(R0); + masm.push(ICStubReg); + pushStubPayload(masm, R0.scratchReg()); + + using Fn = + bool (*)(JSContext*, BaselineFrame*, ICOptimizeSpreadCall_Fallback*, + HandleValue, MutableHandleValue); + return tailCallVM(masm); +} + // // InstanceOf_Fallback // @@ -3612,7 +3692,7 @@ bool DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame, RootedValue lhsCopy(cx, lhs); RootedValue rhsCopy(cx, rhs); - // Perform the compare operation. + // Perform the arith operation. switch (op) { case JSOp::Add: // Do an add. @@ -3956,5 +4036,31 @@ bool JitRuntime::generateBaselineICFallbackCode(JSContext* cx) { return true; } +const CacheIRStubInfo* ICStub::cacheIRStubInfo() const { + switch (kind()) { + case ICStub::CacheIR_Regular: + return toCacheIR_Regular()->stubInfo(); + case ICStub::CacheIR_Monitored: + return toCacheIR_Monitored()->stubInfo(); + case ICStub::CacheIR_Updated: + return toCacheIR_Updated()->stubInfo(); + default: + MOZ_CRASH("Not a CacheIR stub"); + } +} + +const uint8_t* ICStub::cacheIRStubData() { + switch (kind()) { + case ICStub::CacheIR_Regular: + return toCacheIR_Regular()->stubDataStart(); + case ICStub::CacheIR_Monitored: + return toCacheIR_Monitored()->stubDataStart(); + case ICStub::CacheIR_Updated: + return toCacheIR_Updated()->stubDataStart(); + default: + MOZ_CRASH("Not a CacheIR stub"); + } +} + } // namespace jit } // namespace js diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index c678b87aa9..858a23e454 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -15,9 +15,11 @@ #include "jit/ICState.h" #include "jit/SharedICRegisters.h" #include "js/GCVector.h" +#include "proxy/DOMProxy.h" // js::GetDOMProxyHandlerFamily #include "vm/ArrayObject.h" #include "vm/BytecodeUtil.h" #include "vm/JSContext.h" +#include "vm/ProxyObject.h" #include "vm/Realm.h" namespace js { @@ -256,7 +258,7 @@ class ICEntry { return script->offsetToPC(pcOffset()); } - static inline size_t offsetOfFirstStub() { + static constexpr size_t offsetOfFirstStub() { return offsetof(ICEntry, firstStub_); } @@ -371,7 +373,7 @@ class ICStubIterator { bool atEnd() const { return currentStub_ == (ICStub*)fallbackStub_; } - void unlink(JSContext* cx); + void unlink(JSContext* cx, JSScript* script); }; // @@ -418,8 +420,6 @@ class ICStub { void updateCode(JitCode* stubCode); void trace(JSTracer* trc); - bool stubDataHasNurseryPointers(const CacheIRStubInfo* stubInfo); - static const uint16_t EXPECTED_TRACE_MAGIC = 0b1100011; template @@ -642,6 +642,9 @@ class ICStub { MOZ_ASSERT(next()); return makesGCCalls(); } + + const CacheIRStubInfo* cacheIRStubInfo() const; + const uint8_t* cacheIRStubData(); }; class ICFallbackStub : public ICStub { @@ -676,6 +679,11 @@ class ICFallbackStub : public ICStub { inline size_t numOptimizedStubs() const { return state_.numOptimizedStubs(); } + bool newStubIsFirstStub() const { + return (state_.mode() == ICState::Mode::Specialized && + numOptimizedStubs() == 0); + } + ICState& state() { return state_; } // The icEntry_ field can't be initialized when the stub is created since we @@ -700,9 +708,23 @@ class ICFallbackStub : public ICStub { ICStubIterator beginChain() { return ICStubIterator(this); } - void discardStubs(JSContext* cx); + void discardStubs(JSContext* cx, JSScript* script); + + void clearUsedByTranspiler() { state_.clearUsedByTranspiler(); } + void setUsedByTranspiler() { state_.setUsedByTranspiler(); } - void unlinkStub(Zone* zone, ICStub* prev, ICStub* stub); + TrialInliningState trialInliningState() const { + return state_.trialInliningState(); + } + void setTrialInliningState(TrialInliningState state) { + state_.setTrialInliningState(state); + } + + // If the transpiler optimized based on this IC, invalidate the script's Warp + // code. + void maybeInvalidateWarp(JSContext* cx, JSScript* script); + + void unlinkStubDontInvalidateWarp(Zone* zone, ICStub* prev, ICStub* stub); // Return the number of times this stub has successfully provided a value to // the caller. @@ -712,8 +734,11 @@ class ICFallbackStub : public ICStub { }; // Shared trait for all CacheIR stubs. -template -class ICCacheIR_Trait { +template +class ICCacheIR_Trait : public Base { + // Flags stored in the uint16_t extra_ field in ICStub. + static constexpr uint16_t PreliminaryObjectBit = 1 << 0; + protected: const CacheIRStubInfo* stubInfo_; @@ -721,33 +746,39 @@ class ICCacheIR_Trait { // // See Bug 1494473 comment 6 for a mechanism to handle overflow if overflow // becomes a concern. - uint32_t enteredCount_; + uint32_t enteredCount_ = 0; public: - explicit ICCacheIR_Trait(const CacheIRStubInfo* stubInfo) - : stubInfo_(stubInfo), enteredCount_(0) {} + template + explicit ICCacheIR_Trait(const CacheIRStubInfo* stubInfo, Args&&... args) + : Base(args...), stubInfo_(stubInfo) {} const CacheIRStubInfo* stubInfo() const { return stubInfo_; } + uint8_t* stubDataStart(); // Return the number of times this stub has successfully provided a value to // the caller. uint32_t enteredCount() const { return enteredCount_; } void resetEnteredCount() { enteredCount_ = 0; } - static size_t offsetOfEnteredCount() { return offsetof(T, enteredCount_); } + void notePreliminaryObject() { this->extra_ |= PreliminaryObjectBit; } + bool hasPreliminaryObject() const { + return (this->extra_ & PreliminaryObjectBit) != 0; + } + + static constexpr size_t offsetOfEnteredCount() { + using T = ICCacheIR_Trait; + return offsetof(T, enteredCount_); + } }; // Base class for Trait::Regular CacheIR stubs -class ICCacheIR_Regular : public ICStub, - public ICCacheIR_Trait { +class ICCacheIR_Regular : public ICCacheIR_Trait { + using Base = ICCacheIR_Trait; + public: ICCacheIR_Regular(JitCode* stubCode, const CacheIRStubInfo* stubInfo) - : ICStub(ICStub::CacheIR_Regular, stubCode), ICCacheIR_Trait(stubInfo) {} - - void notePreliminaryObject() { extra_ = 1; } - bool hasPreliminaryObject() const { return extra_; } - - uint8_t* stubDataStart(); + : Base(stubInfo, ICStub::CacheIR_Regular, stubCode) {} }; // Monitored stubs are IC stubs that feed a single resulting value out to a @@ -778,22 +809,18 @@ class ICMonitoredStub : public ICStub { } }; -class ICCacheIR_Monitored : public ICMonitoredStub, - public ICCacheIR_Trait { +class ICCacheIR_Monitored : public ICCacheIR_Trait { + using Base = ICCacheIR_Trait; + public: ICCacheIR_Monitored(JitCode* stubCode, ICStub* firstMonitorStub, const CacheIRStubInfo* stubInfo) - : ICMonitoredStub(ICStub::CacheIR_Monitored, stubCode, firstMonitorStub), - ICCacheIR_Trait(stubInfo) {} - - void notePreliminaryObject() { extra_ = 1; } - bool hasPreliminaryObject() const { return extra_; } - - uint8_t* stubDataStart(); + : Base(stubInfo, ICStub::CacheIR_Monitored, stubCode, firstMonitorStub) {} }; -class ICCacheIR_Updated : public ICStub, - public ICCacheIR_Trait { +class ICCacheIR_Updated : public ICCacheIR_Trait { + using Base = ICCacheIR_Trait; + uint32_t numOptimizedStubs_; GCPtrObjectGroup updateStubGroup_; @@ -806,8 +833,7 @@ class ICCacheIR_Updated : public ICStub, public: ICCacheIR_Updated(JitCode* stubCode, const CacheIRStubInfo* stubInfo) - : ICStub(ICStub::CacheIR_Updated, ICStub::Updated, stubCode), - ICCacheIR_Trait(stubInfo), + : Base(stubInfo, ICStub::CacheIR_Updated, ICStub::Updated, stubCode), numOptimizedStubs_(0), updateStubGroup_(nullptr), updateStubId_(JSID_EMPTY), @@ -816,8 +842,6 @@ class ICCacheIR_Updated : public ICStub, GCPtrObjectGroup& updateStubGroup() { return updateStubGroup_; } GCPtrId& updateStubId() { return updateStubId_; } - uint8_t* stubDataStart(); - inline ICStub* firstUpdateStub() const { return firstUpdateStub_; } static inline size_t offsetOfFirstUpdateStub() { @@ -826,9 +850,6 @@ class ICCacheIR_Updated : public ICStub, inline uint32_t numOptimizedStubs() const { return numOptimizedStubs_; } - void notePreliminaryObject() { extra_ = 1; } - bool hasPreliminaryObject() const { return extra_; } - MOZ_MUST_USE bool initUpdatingChain(JSContext* cx, ICStubSpace* space); MOZ_MUST_USE bool addUpdateStubForValue(JSContext* cx, HandleScript script, @@ -981,11 +1002,13 @@ class ICStubCompiler : public ICStubCompilerBase { public: virtual ICStub* getStub(ICStubSpace* space) = 0; - static ICStubSpace* StubSpaceForStub(bool makesGCCalls, JSScript* script); + static ICStubSpace* StubSpaceForStub(bool makesGCCalls, JSScript* script, + ICScript* icScript); ICStubSpace* getStubSpace(JSScript* outerScript) { + MOZ_ASSERT(IsTypeInferenceEnabled()); return StubSpaceForStub(ICStub::NonCacheIRStubMakesGCCalls(kind), - outerScript); + outerScript, /*icScript = */ nullptr); } }; @@ -1547,6 +1570,15 @@ class ICHasOwn_Fallback : public ICFallbackStub { : ICFallbackStub(ICStub::HasOwn_Fallback, stubCode) {} }; +// CheckPrivateField +// JSOp::CheckPrivateField +class ICCheckPrivateField_Fallback : public ICFallbackStub { + friend class ICStubSpace; + + explicit ICCheckPrivateField_Fallback(TrampolinePtr stubCode) + : ICFallbackStub(ICStub::CheckPrivateField_Fallback, stubCode) {} +}; + // GetName // JSOp::GetName // JSOp::GetGName @@ -1586,6 +1618,8 @@ class ICGetProp_Fallback : public ICMonitoredFallbackStub { : ICMonitoredFallbackStub(ICStub::GetProp_Fallback, stubCode) {} public: + // Whether this bytecode op called a getter. This is used by IonBuilder. + // To improve performance, the flag is not set if WarpBuilder is enabled. static const size_t ACCESSED_GETTER_BIT = 1; void noteAccessedGetter() { extra_ |= (1u << ACCESSED_GETTER_BIT); } @@ -1642,6 +1676,13 @@ class ICGetIterator_Fallback : public ICFallbackStub { : ICFallbackStub(ICStub::GetIterator_Fallback, stubCode) {} }; +class ICOptimizeSpreadCall_Fallback : public ICFallbackStub { + friend class ICStubSpace; + + explicit ICOptimizeSpreadCall_Fallback(TrampolinePtr stubCode) + : ICFallbackStub(ICStub::OptimizeSpreadCall_Fallback, stubCode) {} +}; + // InstanceOf // JSOp::Instanceof class ICInstanceOf_Fallback : public ICFallbackStub { @@ -1853,6 +1894,12 @@ extern bool DoHasOwnFallback(JSContext* cx, BaselineFrame* frame, ICHasOwn_Fallback* stub, HandleValue keyValue, HandleValue objValue, MutableHandleValue res); +extern bool DoCheckPrivateFieldFallback(JSContext* cx, BaselineFrame* frame, + ICCheckPrivateField_Fallback* stub, + HandleValue objValue, + HandleValue keyValue, + MutableHandleValue res); + extern bool DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub, HandleObject envChain, MutableHandleValue res); @@ -1882,6 +1929,11 @@ extern bool DoGetIteratorFallback(JSContext* cx, BaselineFrame* frame, ICGetIterator_Fallback* stub, HandleValue value, MutableHandleValue res); +extern bool DoOptimizeSpreadCallFallback(JSContext* cx, BaselineFrame* frame, + ICOptimizeSpreadCall_Fallback* stub, + HandleValue value, + MutableHandleValue res); + extern bool DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* stub, HandleValue lhs, HandleValue rhs, MutableHandleValue res); diff --git a/js/src/jit/BaselineICList.h b/js/src/jit/BaselineICList.h index b980a36d2a..b49b1411e1 100644 --- a/js/src/jit/BaselineICList.h +++ b/js/src/jit/BaselineICList.h @@ -37,6 +37,7 @@ namespace jit { \ _(In_Fallback) \ _(HasOwn_Fallback) \ + _(CheckPrivateField_Fallback) \ \ _(GetName_Fallback) \ \ @@ -48,6 +49,8 @@ namespace jit { \ _(GetIterator_Fallback) \ \ + _(OptimizeSpreadCall_Fallback) \ + \ _(InstanceOf_Fallback) \ \ _(TypeOf_Fallback) \ @@ -87,11 +90,13 @@ namespace jit { _(SetElem) \ _(In) \ _(HasOwn) \ + _(CheckPrivateField) \ _(GetName) \ _(BindName) \ _(GetIntrinsic) \ _(SetProp) \ _(GetIterator) \ + _(OptimizeSpreadCall) \ _(InstanceOf) \ _(TypeOf) \ _(ToPropertyKey) \ diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 02587001cd..c022674b73 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -236,16 +236,16 @@ bool BaselineInspector::dimorphicStub(jsbytecode* pc, ICStub** pfirst, static void SkipBinaryGuards(CacheIRReader& reader, bool* sawStringOperand) { while (true) { // Two skip opcodes - if (reader.matchOp(CacheOp::GuardToInt32) || - reader.matchOp(CacheOp::GuardNonDoubleType) || + if (reader.matchOp(CacheOp::GuardNonDoubleType) || reader.matchOp(CacheOp::TruncateDoubleToUInt32) || - reader.matchOp(CacheOp::GuardToBoolean)) { + reader.matchOp(CacheOp::GuardBooleanToInt32) || + reader.matchOp(CacheOp::LoadInt32Constant)) { reader.skip(); // Skip over operandId reader.skip(); // Skip over result/type. continue; } - if (reader.matchOp(CacheOp::GuardAndGetNumberFromString) || - reader.matchOp(CacheOp::GuardAndGetInt32FromString)) { + if (reader.matchOp(CacheOp::GuardStringToNumber) || + reader.matchOp(CacheOp::GuardStringToInt32)) { if (sawStringOperand) { *sawStringOperand = true; } @@ -255,10 +255,13 @@ static void SkipBinaryGuards(CacheIRReader& reader, bool* sawStringOperand) { } // One skip - if (reader.matchOp(CacheOp::GuardIsNumber) || + if (reader.matchOp(CacheOp::GuardToInt32) || + reader.matchOp(CacheOp::GuardIsNumber) || reader.matchOp(CacheOp::GuardToString) || reader.matchOp(CacheOp::GuardToObject) || - reader.matchOp(CacheOp::GuardToBigInt)) { + reader.matchOp(CacheOp::GuardToBigInt) || + reader.matchOp(CacheOp::GuardToBoolean) || + reader.matchOp(CacheOp::GuardIsNullOrUndefined)) { reader.skip(); // Skip over operandId continue; } @@ -392,6 +395,12 @@ static bool GuardType(CacheIRReader& reader, case CacheOp::GuardToBigInt: guardType[guardOperand] = MIRType::BigInt; break; + case CacheOp::GuardToBoolean: + guardType[guardOperand] = MIRType::Boolean; + break; + case CacheOp::GuardToInt32: + guardType[guardOperand] = MIRType::Int32; + break; case CacheOp::GuardIsNumber: guardType[guardOperand] = MIRType::Double; break; @@ -399,12 +408,7 @@ static bool GuardType(CacheIRReader& reader, guardType[guardOperand] = MIRType::Undefined; break; // 1 skip - case CacheOp::GuardToInt32: - guardType[guardOperand] = MIRType::Int32; - // Skip over result - reader.skip(); - break; - case CacheOp::GuardToBoolean: + case CacheOp::GuardBooleanToInt32: guardType[guardOperand] = MIRType::Boolean; // Skip over result reader.skip(); @@ -666,32 +670,14 @@ bool BaselineInspector::hasSeenDoubleResult(jsbytecode* pc) { return stub->toBinaryArith_Fallback()->sawDoubleResult(); } -static const CacheIRStubInfo* GetCacheIRStubInfo(ICStub* stub) { - const CacheIRStubInfo* stubInfo = nullptr; - switch (stub->kind()) { - case ICStub::Kind::CacheIR_Monitored: - stubInfo = stub->toCacheIR_Monitored()->stubInfo(); - break; - case ICStub::Kind::CacheIR_Regular: - stubInfo = stub->toCacheIR_Regular()->stubInfo(); - break; - case ICStub::Kind::CacheIR_Updated: - stubInfo = stub->toCacheIR_Updated()->stubInfo(); - break; - default: - MOZ_CRASH("Only cache IR stubs supported"); - } - return stubInfo; -} - static bool MaybeArgumentReader(ICStub* stub, CacheOp targetOp, mozilla::Maybe& argReader) { MOZ_ASSERT(ICStub::IsCacheIRKind(stub->kind())); - CacheIRReader stubReader(GetCacheIRStubInfo(stub)); + CacheIRReader stubReader(stub->cacheIRStubInfo()); while (stubReader.more()) { CacheOp op = stubReader.readOp(); - uint32_t argLength = CacheIROpArgLengths[size_t(op)]; + uint32_t argLength = CacheIROpInfos[size_t(op)].argLength; if (op == targetOp) { MOZ_ASSERT(argReader.isNothing(), @@ -709,7 +695,7 @@ static bool MaybeArgumentReader(ICStub* stub, CacheOp targetOp, template JSObject* MaybeTemplateObject(ICStub* stub, MetaTwoByteKind kind, Filter filter) { - const CacheIRStubInfo* stubInfo = GetCacheIRStubInfo(stub); + const CacheIRStubInfo* stubInfo = stub->cacheIRStubInfo(); mozilla::Maybe argReader; if (!MaybeArgumentReader(stub, CacheOp::MetaTwoByte, argReader) || argReader->metaKind() != kind || @@ -779,7 +765,7 @@ JSFunction* BaselineInspector::getSingleCallee(jsbytecode* pc) { } if (ICStub::IsCacheIRKind(stub->kind())) { - const CacheIRStubInfo* stubInfo = GetCacheIRStubInfo(stub); + const CacheIRStubInfo* stubInfo = stub->cacheIRStubInfo(); mozilla::Maybe argReader; if (!MaybeArgumentReader(stub, CacheOp::MetaTwoByte, argReader) || argReader->metaKind() != @@ -1614,7 +1600,7 @@ bool BaselineInspector::instanceOfData(jsbytecode* pc, Shape** shape, return false; } - if (!reader.matchOp(CacheOp::GuardFunctionPrototype, rhsId)) { + if (!reader.matchOp(CacheOp::GuardDynamicSlotIsSpecificObject, rhsId)) { return false; } diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 1a75a6007f..8894de6e1d 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -18,6 +18,7 @@ #include "jit/CompileInfo.h" #include "jit/JitCommon.h" #include "jit/JitSpewer.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimitWithStackPointer #include "util/Memory.h" #include "util/StructuredSpewer.h" #include "vm/Interpreter.h" @@ -501,7 +502,7 @@ void BaselineScript::trace(JSTracer* trc) { } /* static */ -void BaselineScript::writeBarrierPre(Zone* zone, BaselineScript* script) { +void BaselineScript::preWriteBarrier(Zone* zone, BaselineScript* script) { if (zone->needsIncrementalBarrier()) { script->trace(zone->barrierTracer()); } @@ -615,8 +616,7 @@ const RetAddrEntry& BaselineScript::retAddrEntryFromPCOffset( const RetAddrEntry& BaselineScript::prologueRetAddrEntry( RetAddrEntry::Kind kind) { - MOZ_ASSERT(kind == RetAddrEntry::Kind::StackCheck || - kind == RetAddrEntry::Kind::WarmupCounter); + MOZ_ASSERT(kind == RetAddrEntry::Kind::StackCheck); // The prologue entries will always be at a very low offset, so just do a // linear search from the beginning. diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 7fc542477f..769842e1ac 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -14,7 +14,6 @@ #include "jit/JitCode.h" #include "jit/shared/Assembler-shared.h" #include "util/TrailingArray.h" -#include "vm/EnvironmentObject.h" #include "vm/JSContext.h" #include "vm/Realm.h" #include "vm/TraceLogging.h" @@ -100,12 +99,10 @@ class RetAddrEntry { // A callVM for an op. CallVM, - // A callVM not for an op (e.g., in the prologue). + // A callVM not for an op (e.g., in the prologue) that can't + // trigger debug mode. NonOpCallVM, - // A callVM for the warmup counter. - WarmupCounter, - // A callVM for the over-recursion check on function entry. StackCheck, @@ -384,7 +381,7 @@ class alignas(uintptr_t) BaselineScript final : public TrailingArray { return offsetof(BaselineScript, resumeEntriesOffset_); } - static void writeBarrierPre(Zone* zone, BaselineScript* script); + static void preWriteBarrier(Zone* zone, BaselineScript* script); bool hasPendingIonCompileTask() const { return !!pendingIonCompileTask_; } @@ -473,7 +470,7 @@ struct alignas(uintptr_t) BaselineBailoutInfo { MOZ_MUST_USE bool BailoutIonToBaseline( JSContext* cx, JitActivation* activation, const JSJitFrameIter& iter, - bool invalidate, BaselineBailoutInfo** bailoutInfo, + BaselineBailoutInfo** bailoutInfo, const ExceptionBailoutInfo* exceptionInfo); MethodStatus BaselineCompile(JSContext* cx, JSScript* script, diff --git a/js/src/jit/BytecodeAnalysis.cpp b/js/src/jit/BytecodeAnalysis.cpp index 44b3c16763..ee48db4d35 100644 --- a/js/src/jit/BytecodeAnalysis.cpp +++ b/js/src/jit/BytecodeAnalysis.cpp @@ -5,6 +5,7 @@ #include "jit/BytecodeAnalysis.h" #include "jit/JitSpewer.h" +#include "jit/WarpBuilder.h" #include "vm/BytecodeIterator.h" #include "vm/BytecodeLocation.h" #include "vm/BytecodeUtil.h" @@ -20,20 +21,6 @@ using namespace js::jit; BytecodeAnalysis::BytecodeAnalysis(TempAllocator& alloc, JSScript* script) : script_(script), infos_(alloc), hasTryFinally_(false) {} -// Bytecode range containing only catch or finally code. -struct CatchFinallyRange { - uint32_t start; // Inclusive. - uint32_t end; // Exclusive. - - CatchFinallyRange(uint32_t start, uint32_t end) : start(start), end(end) { - MOZ_ASSERT(end > start); - } - - bool contains(uint32_t offset) const { - return start <= offset && offset < end; - } -}; - bool BytecodeAnalysis::init(TempAllocator& alloc) { if (!infos_.growByUninitialized(script_->length())) { return false; @@ -43,7 +30,40 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { mozilla::PodZero(infos_.begin(), infos_.length()); infos_[0].init(/*stackDepth=*/0); - Vector catchFinallyRanges(alloc); + // Because IonBuilder and WarpBuilder can compile try-blocks but don't compile + // the catch-body, we need some special machinery to prevent OSR into Ion/Warp + // in the following cases: + // + // (1) Loops in catch/finally blocks: + // + // try { + // .. + // } catch (e) { + // while (..) {} // Can't OSR here. + // } + // + // (2) Loops only reachable via a catch/finally block: + // + // for (;;) { + // try { + // throw 3; + // } catch (e) { + // break; + // } + // } + // while (..) {} // Loop is only reachable via the catch-block. + // + // To deal with both of these cases, we track whether the current op is + // 'normally reachable' (reachable without going through a catch/finally + // block). Forward jumps propagate this flag to their jump targets (see + // BytecodeInfo::jumpTargetNormallyReachable) and when the analysis reaches a + // jump target it updates its normallyReachable flag based on the target's + // flag. + // + // Inlining a function without a normally reachable return can cause similar + // problems. To avoid this, we mark such functions as uninlineable. + bool normallyReachable = true; + bool normallyReachableReturn = false; for (const BytecodeLocation& it : AllBytecodesIterable(script_)) { JSOp op = it.getOp(); @@ -52,6 +72,10 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { JitSpew(JitSpew_BaselineOp, "Analyzing op @ %u (end=%u): %s", unsigned(offset), unsigned(script_->length()), CodeName(op)); + if (JitOptions.warpBuilder) { + checkWarpSupport(op); + } + // If this bytecode info has not yet been initialized, it's not reachable. if (!infos_[offset].initialized) { continue; @@ -59,6 +83,10 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { uint32_t stackDepth = infos_[offset].stackDepth; + if (infos_[offset].jumpTarget) { + normallyReachable = infos_[offset].jumpTargetNormallyReachable; + } + #ifdef DEBUG size_t endOffset = offset + it.length(); for (size_t checkOffset = offset + 1; checkOffset < endOffset; @@ -83,7 +111,7 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { int32_t high = it.getTableSwitchHigh(); infos_[defaultOffset].init(stackDepth); - infos_[defaultOffset].jumpTarget = true; + infos_[defaultOffset].setJumpTarget(normallyReachable); uint32_t ncases = high - low + 1; @@ -91,7 +119,7 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { uint32_t targetOffset = it.tableSwitchCaseOffset(script_, i); if (targetOffset != defaultOffset) { infos_[targetOffset].init(stackDepth); - infos_[targetOffset].jumpTarget = true; + infos_[targetOffset].setJumpTarget(normallyReachable); } } break; @@ -103,46 +131,31 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { (tn.kind() == TryNoteKind::Catch || tn.kind() == TryNoteKind::Finally)) { uint32_t catchOrFinallyOffset = tn.start + tn.length; - infos_[catchOrFinallyOffset].init(stackDepth); - infos_[catchOrFinallyOffset].jumpTarget = true; + BytecodeInfo& targetInfo = infos_[catchOrFinallyOffset]; + targetInfo.init(stackDepth); + targetInfo.setJumpTarget(/* normallyReachable = */ false); } } - - // Get the pc of the last instruction in the try block. It's a - // JSOp::Goto to jump over the catch/finally blocks. - BytecodeLocation endOfTryLoc(script_, - it.toRawBytecode() + it.codeOffset()); - MOZ_ASSERT(endOfTryLoc.is(JSOp::Goto)); - - BytecodeLocation afterTryLoc( - script_, endOfTryLoc.toRawBytecode() + endOfTryLoc.jumpOffset()); - MOZ_ASSERT(afterTryLoc > endOfTryLoc); - - // Ensure the code following the try-block is always marked as - // reachable, to simplify Ion's ControlFlowGenerator. - uint32_t afterTryOffset = afterTryLoc.bytecodeToOffset(script_); - infos_[afterTryOffset].init(stackDepth); - infos_[afterTryOffset].jumpTarget = true; - - // Pop CatchFinallyRanges that are no longer needed. - while (!catchFinallyRanges.empty() && - catchFinallyRanges.back().end <= offset) { - catchFinallyRanges.popBack(); - } - - CatchFinallyRange range(endOfTryLoc.bytecodeToOffset(script_), - afterTryLoc.bytecodeToOffset(script_)); - if (!catchFinallyRanges.append(range)) { - return false; - } break; } case JSOp::LoopHead: - for (size_t i = 0; i < catchFinallyRanges.length(); i++) { - if (catchFinallyRanges[i].contains(offset)) { - infos_[offset].loopHeadInCatchOrFinally = true; - } + infos_[offset].loopHeadCanOsr = normallyReachable; + break; + +#ifdef DEBUG + case JSOp::Exception: + case JSOp::Finally: + // Sanity check: ops only emitted in catch/finally blocks are never + // normally reachable. + MOZ_ASSERT(!normallyReachable); + break; +#endif + + case JSOp::Return: + case JSOp::RetRval: + if (normallyReachable) { + normallyReachableReturn = true; } break; @@ -160,13 +173,24 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { uint32_t targetOffset = it.getJumpTargetOffset(script_); +#ifdef DEBUG // If this is a backedge, the target JSOp::LoopHead must have been - // analyzed already. - MOZ_ASSERT_IF(targetOffset < offset, infos_[targetOffset].initialized); + // analyzed already. Furthermore, if the backedge is normally reachable, + // the loop head must be normally reachable too (loopHeadCanOsr can be + // used to check this since it's equivalent). + if (targetOffset < offset) { + MOZ_ASSERT(infos_[targetOffset].initialized); + MOZ_ASSERT_IF(normallyReachable, infos_[targetOffset].loopHeadCanOsr); + } +#endif infos_[targetOffset].init(newStackDepth); - infos_[targetOffset].jumpTarget = true; + + // Gosub's target is a finally-block => not normally reachable. + bool targetNormallyReachable = (op != JSOp::Gosub) && normallyReachable; + infos_[targetOffset].setJumpTarget(targetNormallyReachable); } + // Handle any fallthrough from this opcode. if (it.fallsThrough()) { BytecodeLocation fallthroughLoc = it.next(); @@ -177,7 +201,10 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { // Treat the fallthrough of a branch instruction as a jump target. if (jump) { - infos_[fallthroughOffset].jumpTarget = true; + // Gosub falls through after executing a finally-block => not normally + // reachable. + bool nextNormallyReachable = (op != JSOp::Gosub) && normallyReachable; + infos_[fallthroughOffset].setJumpTarget(nextNormallyReachable); } } } @@ -190,9 +217,25 @@ bool BytecodeAnalysis::init(TempAllocator& alloc) { } } + if (!normallyReachableReturn) { + script_->setUninlineable(); + } + return true; } +void BytecodeAnalysis::checkWarpSupport(JSOp op) { + switch (op) { +#define DEF_CASE(OP) case JSOp::OP: + WARP_UNSUPPORTED_OPCODE_LIST(DEF_CASE) +#undef DEF_CASE + script_->disableIon(); + break; + default: + break; + } +} + IonBytecodeInfo js::jit::AnalyzeBytecodeForIon(JSContext* cx, JSScript* script) { IonBytecodeInfo result; diff --git a/js/src/jit/BytecodeAnalysis.h b/js/src/jit/BytecodeAnalysis.h index 916973892a..c27ac66673 100644 --- a/js/src/jit/BytecodeAnalysis.h +++ b/js/src/jit/BytecodeAnalysis.h @@ -20,8 +20,12 @@ struct BytecodeInfo { bool initialized : 1; bool jumpTarget : 1; - // If true, this is a JSOp::LoopHead op inside a catch or finally block. - bool loopHeadInCatchOrFinally : 1; + // If true, this is a JSOp::LoopHead where we can OSR into Ion/Warp code. + bool loopHeadCanOsr : 1; + + // See the comment above normallyReachable in BytecodeAnalysis.cpp for how + // this works. + bool jumpTargetNormallyReachable : 1; // True if the script has a resume offset for this bytecode op. bool hasResumeOffset : 1; @@ -32,6 +36,13 @@ struct BytecodeInfo { initialized = true; stackDepth = depth; } + + void setJumpTarget(bool normallyReachable) { + jumpTarget = true; + if (normallyReachable) { + jumpTargetNormallyReachable = true; + } + } }; class BytecodeAnalysis { @@ -60,6 +71,8 @@ class BytecodeAnalysis { } bool hasTryFinally() const { return hasTryFinally_; } + + void checkWarpSupport(JSOp op); }; // Bytecode analysis pass necessary for IonBuilder. The result is cached in diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 148e3ac14c..9661fcac04 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -8,13 +8,27 @@ #include "mozilla/FloatingPoint.h" #include "mozilla/Unused.h" +#include "builtin/DataViewObject.h" +#include "builtin/MapObject.h" +#include "builtin/ModuleObject.h" #include "jit/BaselineCacheIRCompiler.h" #include "jit/BaselineIC.h" #include "jit/CacheIRSpewer.h" #include "jit/InlinableNatives.h" -#include "jit/Ion.h" // IsIonEnabled +#include "jit/Ion.h" // IsIonEnabled +#include "jit/JitContext.h" +#include "js/experimental/JitInfo.h" // JSJitInfo +#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration +#include "js/friend/WindowProxy.h" // js::IsWindow, js::IsWindowProxy, js::ToWindowIfWindowProxy +#include "js/friend/XrayJitInfo.h" // js::jit::GetXrayJitInfo, JS::XrayJitInfo +#include "js/ScalarType.h" // js::Scalar::Type +#include "js/Wrapper.h" +#include "util/Unicode.h" +#include "vm/ArrayBufferObject.h" +#include "vm/BytecodeUtil.h" #include "vm/PlainObject.h" // js::PlainObject #include "vm/SelfHosting.h" +#include "vm/ThrowMsgKind.h" // ThrowCondition #include "jit/MacroAssembler-inl.h" #include "vm/EnvironmentObject-inl.h" @@ -31,6 +45,9 @@ using namespace js::jit; using mozilla::DebugOnly; using mozilla::Maybe; +using JS::DOMProxyShadowsResult; +using JS::ExpandoAndGeneration; + const char* const js::jit::CacheKindNames[] = { #define DEFINE_KIND(kind) #kind, CACHE_IR_KINDS(DEFINE_KIND) @@ -43,10 +60,16 @@ const char* const js::jit::CacheIROpNames[] = { #undef OPNAME }; -const uint32_t js::jit::CacheIROpArgLengths[] = { -#define ARGLENGTH(op, len) len, - CACHE_IR_OPS(ARGLENGTH) -#undef ARGLENGTH +const CacheIROpInfo js::jit::CacheIROpInfos[] = { +#define OPINFO(op, len, transpile, ...) {len, transpile}, + CACHE_IR_OPS(OPINFO) +#undef OPINFO +}; + +const uint32_t js::jit::CacheIROpHealth[] = { +#define OPHEALTH(op, len, transpile, health) health, + CACHE_IR_OPS(OPHEALTH) +#undef OPHEALTH }; #ifdef DEBUG @@ -64,6 +87,7 @@ size_t js::jit::NumInputsForCacheKind(CacheKind kind) { case CacheKind::GetName: case CacheKind::BindName: case CacheKind::Call: + case CacheKind::OptimizeSpreadCall: return 1; case CacheKind::Compare: case CacheKind::GetElem: @@ -71,6 +95,7 @@ size_t js::jit::NumInputsForCacheKind(CacheKind kind) { case CacheKind::SetProp: case CacheKind::In: case CacheKind::HasOwn: + case CacheKind::CheckPrivateField: case CacheKind::InstanceOf: case CacheKind::BinaryArith: return 2; @@ -112,6 +137,71 @@ StubField CacheIRWriter::readStubFieldForIon(uint32_t offset, return stubFields_[index]; } +CacheIRCloner::CacheIRCloner(ICStub* stub) + : stubInfo_(stub->cacheIRStubInfo()), stubData_(stub->cacheIRStubData()) {} + +void CacheIRCloner::cloneOp(CacheOp op, CacheIRReader& reader, + CacheIRWriter& writer) { + switch (op) { +#define DEFINE_OP(op, ...) \ + case CacheOp::op: \ + clone##op(reader, writer); \ + break; + CACHE_IR_OPS(DEFINE_OP) +#undef DEFINE_OP + default: + MOZ_CRASH("Invalid op"); + } +} + +uintptr_t CacheIRCloner::readStubWord(uint32_t offset) { + return stubInfo_->getStubRawWord(stubData_, offset); +} +int64_t CacheIRCloner::readStubInt64(uint32_t offset) { + return stubInfo_->getStubRawInt64(stubData_, offset); +} + +Shape* CacheIRCloner::getShapeField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +ObjectGroup* CacheIRCloner::getGroupField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +JSObject* CacheIRCloner::getObjectField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +JSString* CacheIRCloner::getStringField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +JSAtom* CacheIRCloner::getAtomField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +PropertyName* CacheIRCloner::getPropertyNameField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +JS::Symbol* CacheIRCloner::getSymbolField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +BaseScript* CacheIRCloner::getBaseScriptField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +uintptr_t CacheIRCloner::getRawWordField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +const void* CacheIRCloner::getRawPointerField(uint32_t stubOffset) { + return reinterpret_cast(readStubWord(stubOffset)); +} +uint64_t CacheIRCloner::getDOMExpandoGenerationField(uint32_t stubOffset) { + return static_cast(readStubInt64(stubOffset)); +} + +jsid CacheIRCloner::getIdField(uint32_t stubOffset) { + return jsid::fromRawBits(readStubWord(stubOffset)); +} +const Value CacheIRCloner::getValueField(uint32_t stubOffset) { + return Value::fromRawBits(uint64_t(readStubInt64(stubOffset))); +} + IRGenerator::IRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, CacheKind cacheKind, ICState::Mode mode) : writer(cx), @@ -133,15 +223,15 @@ GetPropIRGenerator::GetPropIRGenerator(JSContext* cx, HandleScript script, resultFlags_(resultFlags), preliminaryObjectAction_(PreliminaryObjectAction::None) {} -static void EmitLoadSlotResult(CacheIRWriter& writer, ObjOperandId holderOp, +static void EmitLoadSlotResult(CacheIRWriter& writer, ObjOperandId holderId, NativeObject* holder, Shape* shape) { if (holder->isFixedSlot(shape->slot())) { - writer.loadFixedSlotResult(holderOp, + writer.loadFixedSlotResult(holderId, NativeObject::getFixedSlotOffset(shape->slot())); } else { size_t dynamicSlotOffset = holder->dynamicSlotIndex(shape->slot()) * sizeof(Value); - writer.loadDynamicSlotResult(holderOp, dynamicSlotOffset); + writer.loadDynamicSlotResult(holderId, dynamicSlotOffset); } } @@ -188,20 +278,21 @@ static ProxyStubType GetProxyStubType(JSContext* cx, HandleObject obj, } DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id); - if (shadows == ShadowCheckFailed) { + if (shadows == DOMProxyShadowsResult::ShadowCheckFailed) { cx->clearPendingException(); return ProxyStubType::None; } if (DOMProxyIsShadowing(shadows)) { - if (shadows == ShadowsViaDirectExpando || - shadows == ShadowsViaIndirectExpando) { + if (shadows == DOMProxyShadowsResult::ShadowsViaDirectExpando || + shadows == DOMProxyShadowsResult::ShadowsViaIndirectExpando) { return ProxyStubType::DOMExpando; } return ProxyStubType::DOMShadowed; } - MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique); + MOZ_ASSERT(shadows == DOMProxyShadowsResult::DoesntShadow || + shadows == DOMProxyShadowsResult::DoesntShadowUnique); return ProxyStubType::DOMUnshadowed; } @@ -213,7 +304,7 @@ static bool ValueToNameOrSymbolId(JSContext* cx, HandleValue idval, return true; } - if (!ValueToId(cx, idval, id)) { + if (!PrimitiveValueToId(cx, idval, id)) { return false; } @@ -238,13 +329,6 @@ AttachDecision GetPropIRGenerator::tryAttachStub() { AutoAssertNoPendingException aanpe(cx_); - // Non-object receivers are a degenerate case, so don't try to attach - // stubs. The stubs we do emit will still perform runtime checks and - // fallback as needed. - if (isSuper() && !receiver_.isObject()) { - return AttachDecision::NoAction; - } - ValOperandId valId(writer.setInputOperandId(0)); if (cacheKind_ != CacheKind::GetProp) { MOZ_ASSERT_IF(cacheKind_ == CacheKind::GetPropSuper, @@ -265,20 +349,25 @@ AttachDecision GetPropIRGenerator::tryAttachStub() { return AttachDecision::NoAction; } + // |super.prop| getter calls use a |this| value that differs from lookup + // object. + ValOperandId receiverId = isSuper() ? getSuperReceiverValueId() : valId; + if (val_.isObject()) { RootedObject obj(cx_, &val_.toObject()); ObjOperandId objId = writer.guardToObject(valId); if (nameOrSymbol) { TRY_ATTACH(tryAttachObjectLength(obj, objId, id)); TRY_ATTACH(tryAttachTypedArrayLength(obj, objId, id)); - TRY_ATTACH(tryAttachNative(obj, objId, id)); + TRY_ATTACH(tryAttachNative(obj, objId, id, receiverId)); TRY_ATTACH(tryAttachTypedObject(obj, objId, id)); TRY_ATTACH(tryAttachModuleNamespace(obj, objId, id)); TRY_ATTACH(tryAttachWindowProxy(obj, objId, id)); TRY_ATTACH(tryAttachCrossCompartmentWrapper(obj, objId, id)); - TRY_ATTACH(tryAttachXrayCrossCompartmentWrapper(obj, objId, id)); + TRY_ATTACH( + tryAttachXrayCrossCompartmentWrapper(obj, objId, id, receiverId)); TRY_ATTACH(tryAttachFunction(obj, objId, id)); - TRY_ATTACH(tryAttachProxy(obj, objId, id)); + TRY_ATTACH(tryAttachProxy(obj, objId, id, receiverId)); trackAttached(IRGenerator::NotAttached); return AttachDecision::NoAction; @@ -296,7 +385,7 @@ AttachDecision GetPropIRGenerator::tryAttachStub() { TRY_ATTACH(tryAttachDenseElement(obj, objId, index, indexId)); TRY_ATTACH(tryAttachDenseElementHole(obj, objId, index, indexId)); TRY_ATTACH(tryAttachSparseElement(obj, objId, index, indexId)); - TRY_ATTACH(tryAttachArgumentsObjectArg(obj, objId, indexId)); + TRY_ATTACH(tryAttachArgumentsObjectArg(obj, objId, index, indexId)); TRY_ATTACH(tryAttachGenericElement(obj, objId, index, indexId)); trackAttached(IRGenerator::NotAttached); @@ -344,14 +433,15 @@ AttachDecision GetPropIRGenerator::tryAttachIdempotentStub() { ValOperandId valId(writer.setInputOperandId(0)); ObjOperandId objId = writer.guardToObject(valId); - TRY_ATTACH(tryAttachNative(obj, objId, id)); + ValOperandId receiverId = valId; + TRY_ATTACH(tryAttachNative(obj, objId, id, receiverId)); // Object lengths are supported only if int32 results are allowed. TRY_ATTACH(tryAttachObjectLength(obj, objId, id)); // Also support native data properties on DOMProxy prototypes. if (GetProxyStubType(cx_, obj, id) == ProxyStubType::DOMUnshadowed) { - return tryAttachDOMProxyUnshadowed(obj, objId, id); + return tryAttachDOMProxyUnshadowed(obj, objId, id, receiverId); } return AttachDecision::NoAction; @@ -572,7 +662,11 @@ static void GuardGroupProto(CacheIRWriter& writer, JSObject* obj, ObjectGroup* group = obj->groupRaw(); if (group->hasUncacheableProto()) { - writer.guardProto(objId, obj->staticPrototype()); + if (JSObject* proto = obj->staticPrototype()) { + writer.guardProto(objId, proto); + } else { + writer.guardNullProto(objId); + } } else { writer.guardGroupForProto(objId, group); } @@ -731,9 +825,11 @@ static void GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, // Guard prototype links from |pobj| to |holder|. while (pobj != holder) { pobj = pobj->staticPrototype(); - protoId = writer.loadProto(protoId); - writer.guardSpecificObject(protoId, pobj); + // The object's proto could be nullptr so we must use GuardProto before + // LoadProto (LoadProto asserts the proto is non-null). + writer.guardProto(protoId, pobj); + protoId = writer.loadProto(protoId); } } @@ -794,24 +890,24 @@ static bool UncacheableProtoOnChain(JSObject* obj) { static void ShapeGuardProtoChain(CacheIRWriter& writer, JSObject* obj, ObjOperandId objId) { while (true) { + JSObject* proto = obj->staticPrototype(); + // Guard on the proto if the shape does not imply the proto. - bool guardProto = obj->hasUncacheableProto(); + if (obj->hasUncacheableProto()) { + if (proto) { + writer.guardProto(objId, proto); + } else { + writer.guardNullProto(objId); + } + } - obj = obj->staticPrototype(); - if (!obj && !guardProto) { + if (!proto) { return; } + obj = proto; objId = writer.loadProto(objId); - if (guardProto) { - writer.guardSpecificObject(objId, obj); - } - - if (!obj) { - return; - } - writer.guardShape(objId, obj->as().shape()); } } @@ -915,19 +1011,17 @@ static void EmitReadSlotReturn(CacheIRWriter& writer, JSObject*, static void EmitCallGetterResultNoGuards(JSContext* cx, CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId receiverId) { + ValOperandId receiverId) { + JSFunction* target = &shape->getterValue().toObject().as(); + bool sameRealm = cx->realm() == target->realm(); + switch (IsCacheableGetPropCall(obj, holder, shape)) { case CanAttachNativeGetter: { - JSFunction* target = &shape->getterValue().toObject().as(); - MOZ_ASSERT(target->isNativeWithoutJitEntry()); - writer.callNativeGetterResult(receiverId, target); + writer.callNativeGetterResult(receiverId, target, sameRealm); writer.typeMonitorResult(); break; } case CanAttachScriptedGetter: { - JSFunction* target = &shape->getterValue().toObject().as(); - MOZ_ASSERT(target->hasJitEntry()); - bool sameRealm = cx->realm() == target->realm(); writer.callScriptedGetterResult(receiverId, target, sameRealm); writer.typeMonitorResult(); break; @@ -963,47 +1057,62 @@ static void EmitCallGetterResultGuards(CacheIRWriter& writer, JSObject* obj, static void EmitCallGetterResult(JSContext* cx, CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId objId, ObjOperandId receiverId, + ObjOperandId objId, ValOperandId receiverId, ICState::Mode mode) { EmitCallGetterResultGuards(writer, obj, holder, shape, objId, mode); EmitCallGetterResultNoGuards(cx, writer, obj, holder, shape, receiverId); } -static void EmitCallGetterResult(JSContext* cx, CacheIRWriter& writer, - JSObject* obj, JSObject* holder, Shape* shape, - ObjOperandId objId, ICState::Mode mode) { - EmitCallGetterResult(cx, writer, obj, holder, shape, objId, objId, mode); -} +static bool CanAttachDOMGetterSetter(JSContext* cx, JSJitInfo::OpType type, + HandleObject obj, HandleShape shape, + ICState::Mode mode) { + MOZ_ASSERT(type == JSJitInfo::Getter || type == JSJitInfo::Setter); + if (!JitOptions.warpBuilder) { + return false; + } -static void EmitCallGetterByValueResult(JSContext* cx, CacheIRWriter& writer, - JSObject* obj, JSObject* holder, - Shape* shape, ObjOperandId objId, - ValOperandId receiverId, - ICState::Mode mode) { - EmitCallGetterResultGuards(writer, obj, holder, shape, objId, mode); + if (mode != ICState::Mode::Specialized) { + return false; + } - switch (IsCacheableGetPropCall(obj, holder, shape)) { - case CanAttachNativeGetter: { - JSFunction* target = &shape->getterValue().toObject().as(); - MOZ_ASSERT(target->isNativeWithoutJitEntry()); - writer.callNativeGetterByValueResult(receiverId, target); - writer.typeMonitorResult(); - break; - } - case CanAttachScriptedGetter: { - JSFunction* target = &shape->getterValue().toObject().as(); - MOZ_ASSERT(target->hasJitEntry()); - bool sameRealm = cx->realm() == target->realm(); - writer.callScriptedGetterByValueResult(receiverId, target, sameRealm); - writer.typeMonitorResult(); - break; - } - default: - // CanAttachNativeGetProp guarantees that the getter is either a native or - // a scripted function. - MOZ_ASSERT_UNREACHABLE("Can't attach getter"); - break; + Value v = + type == JSJitInfo::Getter ? shape->getterValue() : shape->setterValue(); + JSFunction* fun = &v.toObject().as(); + if (!fun->hasJitInfo()) { + return false; + } + + if (cx->realm() != fun->realm()) { + return false; + } + + const JSJitInfo* jitInfo = fun->jitInfo(); + if (jitInfo->type() != type) { + return false; + } + + const JSClass* clasp = obj->getClass(); + if (!clasp->isDOMClass() || clasp->isProxy()) { + return false; } + + DOMInstanceClassHasProtoAtDepth instanceChecker = + cx->runtime()->DOMcallbacks->instanceClassMatchesProto; + return instanceChecker(clasp, jitInfo->protoID, jitInfo->depth); +} + +static void EmitCallDOMGetterResult(JSContext* cx, CacheIRWriter& writer, + JSObject* obj, JSObject* holder, + Shape* shape, ObjOperandId objId) { + // Note: this relies on EmitCallGetterResultGuards emitting a shape guard + // for specialized stubs. + // The shape guard ensures the receiver's Class is valid for this DOM getter. + EmitCallGetterResultGuards(writer, obj, holder, shape, objId, + ICState::Mode::Specialized); + + JSFunction* getter = &shape->getterValue().toObject().as(); + writer.callDOMGetterResult(objId, getter->jitInfo()); + writer.typeMonitorResult(); } void GetPropIRGenerator::attachMegamorphicNativeSlot(ObjOperandId objId, @@ -1012,7 +1121,11 @@ void GetPropIRGenerator::attachMegamorphicNativeSlot(ObjOperandId objId, MOZ_ASSERT(mode_ == ICState::Mode::Megamorphic); // The stub handles the missing-properties case only if we're seeing one - // now, to make sure Ion ICs correctly monitor the undefined type. + // now, to make sure Ion ICs correctly monitor the undefined type. Without + // TI we don't use type monitoring so always allow |undefined|. + if (!IsTypeInferenceEnabled()) { + handleMissing = true; + } if (cacheKind_ == CacheKind::GetProp || cacheKind_ == CacheKind::GetPropSuper) { @@ -1032,7 +1145,8 @@ void GetPropIRGenerator::attachMegamorphicNativeSlot(ObjOperandId objId, AttachDecision GetPropIRGenerator::tryAttachNative(HandleObject obj, ObjOperandId objId, - HandleId id) { + HandleId id, + ValOperandId receiverId) { RootedShape shape(cx_); RootedNativeObject holder(cx_); @@ -1064,12 +1178,17 @@ AttachDecision GetPropIRGenerator::tryAttachNative(HandleObject obj, return AttachDecision::Attach; case CanAttachScriptedGetter: case CanAttachNativeGetter: { - // |super.prop| accesses use a |this| value that differs from lookup - // object MOZ_ASSERT(!idempotent()); - ObjOperandId receiverId = - isSuper() ? writer.guardToObject(getSuperReceiverValueId()) : objId; maybeEmitIdGuard(id); + + if (!isSuper() && + CanAttachDOMGetterSetter(cx_, JSJitInfo::Getter, obj, shape, mode_)) { + EmitCallDOMGetterResult(cx_, writer, obj, holder, shape, objId); + + trackAttached("DOMGetter"); + return AttachDecision::Attach; + } + EmitCallGetterResult(cx_, writer, obj, holder, shape, objId, receiverId, mode_); @@ -1177,8 +1296,9 @@ AttachDecision GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, maybeEmitIdGuard(id); ObjOperandId windowObjId = GuardAndLoadWindowProxyWindow(writer, objId, windowObj); + ValOperandId receiverId = writer.boxObject(windowObjId); EmitCallGetterResult(cx_, writer, windowObj, holder, shape, windowObjId, - mode_); + receiverId, mode_); trackAttached("WindowProxyGetter"); return AttachDecision::Attach; @@ -1299,12 +1419,13 @@ static bool GetXrayExpandoShapeWrapper(JSContext* cx, HandleObject xray, } AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper( - HandleObject obj, ObjOperandId objId, HandleId id) { + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { if (!IsProxy(obj)) { return AttachDecision::NoAction; } - XrayJitInfo* info = GetXrayJitInfo(); + JS::XrayJitInfo* info = GetXrayJitInfo(); if (!info || !info->isCrossCompartmentXray(GetProxyHandler(obj))) { return AttachDecision::NoAction; } @@ -1382,17 +1503,24 @@ AttachDecision GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper( // (as we checked earlier), which store a pointer to their expando // directly. Xrays in other compartments may share their expandos with each // other and a VM call is needed just to find the expando. - writer.guardXrayExpandoShapeAndDefaultProto(objId, !!expandoShapeWrapper, - expandoShapeWrapper); + if (expandoShapeWrapper) { + writer.guardXrayExpandoShapeAndDefaultProto(objId, expandoShapeWrapper); + } else { + writer.guardXrayNoExpando(objId); + } for (size_t i = 0; i < prototypes.length(); i++) { JSObject* proto = prototypes[i]; ObjOperandId protoId = writer.loadObject(proto); - JSObject* protoShapeWrapper = prototypeExpandoShapeWrappers[i]; - writer.guardXrayExpandoShapeAndDefaultProto(protoId, !!protoShapeWrapper, - protoShapeWrapper); + if (JSObject* protoShapeWrapper = prototypeExpandoShapeWrappers[i]) { + writer.guardXrayExpandoShapeAndDefaultProto(protoId, protoShapeWrapper); + } else { + writer.guardXrayNoExpando(protoId); + } } - writer.callNativeGetterResult(objId, &getter->as()); + bool sameRealm = cx_->realm() == getter->as().realm(); + writer.callNativeGetterResult(receiverId, &getter->as(), + sameRealm); writer.typeMonitorResult(); trackAttached("XrayGetter"); @@ -1408,19 +1536,19 @@ AttachDecision GetPropIRGenerator::tryAttachGenericProxy( if (!handleDOMProxies) { // Ensure that the incoming object is not a DOM proxy, so that we can get to // the specialized stubs - writer.guardNotDOMProxy(objId); + writer.guardIsNotDOMProxy(objId); } if (cacheKind_ == CacheKind::GetProp || mode_ == ICState::Mode::Specialized) { MOZ_ASSERT(!isSuper()); maybeEmitIdGuard(id); - writer.callProxyGetResult(objId, id); + writer.proxyGetResult(objId, id); } else { // Attach a stub that handles every id. MOZ_ASSERT(cacheKind_ == CacheKind::GetElem); MOZ_ASSERT(mode_ == ICState::Mode::Megamorphic); MOZ_ASSERT(!isSuper()); - writer.callProxyGetByValueResult(objId, getElemKeyValueId()); + writer.proxyGetByValueResult(objId, getElemKeyValueId()); } writer.typeMonitorResult(); @@ -1450,9 +1578,9 @@ ObjOperandId IRGenerator::guardDOMProxyExpandoObjectAndShape( return expandoObjId; } -AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando(HandleObject obj, - ObjOperandId objId, - HandleId id) { +AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando( + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { MOZ_ASSERT(IsCacheableDOMProxy(obj)); RootedValue expandoVal(cx_, GetProxyPrivate(obj)); @@ -1497,7 +1625,7 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyExpando(HandleObject obj, MOZ_ASSERT(canCache == CanAttachNativeGetter || canCache == CanAttachScriptedGetter); EmitCallGetterResultNoGuards(cx_, writer, expandoObj, expandoObj, propShape, - objId); + receiverId); } trackAttached("DOMProxyExpando"); @@ -1512,7 +1640,7 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyShadowed(HandleObject obj, maybeEmitIdGuard(id); TestMatchingProxyReceiver(writer, &obj->as(), objId); - writer.callProxyGetResult(objId, id); + writer.proxyGetResult(objId, id); writer.typeMonitorResult(); trackAttached("DOMProxyShadowed"); @@ -1556,7 +1684,8 @@ static void CheckDOMProxyExpandoDoesNotShadow(CacheIRWriter& writer, } AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed( - HandleObject obj, ObjOperandId objId, HandleId id) { + HandleObject obj, ObjOperandId objId, HandleId id, + ValOperandId receiverId) { MOZ_ASSERT(IsCacheableDOMProxy(obj)); RootedObject checkObj(cx_, obj->staticPrototype()); @@ -1598,13 +1727,14 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed( MOZ_ASSERT(canCache == CanAttachNativeGetter || canCache == CanAttachScriptedGetter); MOZ_ASSERT(!isSuper()); - EmitCallGetterResultNoGuards(cx_, writer, checkObj, holder, shape, objId); + EmitCallGetterResultNoGuards(cx_, writer, checkObj, holder, shape, + receiverId); } } else { // Property was not found on the prototype chain. Deoptimize down to // proxy get call. MOZ_ASSERT(!isSuper()); - writer.callProxyGetResult(objId, id); + writer.proxyGetResult(objId, id); writer.typeMonitorResult(); } @@ -1614,7 +1744,8 @@ AttachDecision GetPropIRGenerator::tryAttachDOMProxyUnshadowed( AttachDecision GetPropIRGenerator::tryAttachProxy(HandleObject obj, ObjOperandId objId, - HandleId id) { + HandleId id, + ValOperandId receiverId) { ProxyStubType type = GetProxyStubType(cx_, obj, id); if (type == ProxyStubType::None) { return AttachDecision::NoAction; @@ -1633,12 +1764,12 @@ AttachDecision GetPropIRGenerator::tryAttachProxy(HandleObject obj, case ProxyStubType::None: break; case ProxyStubType::DOMExpando: - TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id)); + TRY_ATTACH(tryAttachDOMProxyExpando(obj, objId, id, receiverId)); [[fallthrough]]; // Fall through to the generic shadowed case. case ProxyStubType::DOMShadowed: return tryAttachDOMProxyShadowed(obj, objId, id); case ProxyStubType::DOMUnshadowed: - TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id)); + TRY_ATTACH(tryAttachDOMProxyUnshadowed(obj, objId, id, receiverId)); return tryAttachGenericProxy(obj, objId, id, /* handleDOMProxies = */ true); case ProxyStubType::Generic: @@ -1820,16 +1951,21 @@ AttachDecision GetPropIRGenerator::tryAttachFunction(HandleObject obj, return AttachDecision::NoAction; } + bool isLength = JSID_IS_ATOM(id, cx_->names().length); + if (!isLength && !JSID_IS_ATOM(id, cx_->names().name)) { + return AttachDecision::NoAction; + } + JSObject* holder = nullptr; PropertyResult prop; - // This property exists already, don't attach the stub. + // If this property exists already, don't attach the stub. if (LookupPropertyPure(cx_, obj, id, &holder, &prop)) { return AttachDecision::NoAction; } JSFunction* fun = &obj->as(); - if (JSID_IS_ATOM(id, cx_->names().length)) { + if (isLength) { // length was probably deleted from the function. if (fun->hasResolvedLength()) { return AttachDecision::NoAction; @@ -1840,16 +1976,44 @@ AttachDecision GetPropIRGenerator::tryAttachFunction(HandleObject obj, return AttachDecision::NoAction; } - maybeEmitIdGuard(id); - writer.guardClass(objId, GuardClassKind::JSFunction); + // Length can be non-int32 for bound functions. + if (fun->isBoundFunction()) { + constexpr auto lengthSlot = FunctionExtended::BOUND_FUNCTION_LENGTH_SLOT; + if (!fun->getExtendedSlot(lengthSlot).isInt32()) { + return AttachDecision::NoAction; + } + } + } else { + // name was probably deleted from the function. + if (fun->hasResolvedName()) { + return AttachDecision::NoAction; + } + + // Unless the bound function name prefix is present, we need to call into + // the VM to compute the full name. + if (fun->isBoundFunction() && !fun->hasBoundFunctionNamePrefix()) { + return AttachDecision::NoAction; + } + } + + maybeEmitIdGuard(id); + writer.guardClass(objId, GuardClassKind::JSFunction); + if (isLength) { writer.loadFunctionLengthResult(objId); + + // Doesn't need to be monitored, because it always returns an int32. writer.returnFromIC(); trackAttached("FunctionLength"); - return AttachDecision::Attach; - } + } else { + writer.loadFunctionNameResult(objId); - return AttachDecision::NoAction; + // Doesn't need to be monitored, because it always returns a string. + writer.returnFromIC(); + + trackAttached("FunctionName"); + } + return AttachDecision::Attach; } AttachDecision GetPropIRGenerator::tryAttachModuleNamespace(HandleObject obj, @@ -1968,8 +2132,8 @@ AttachDecision GetPropIRGenerator::tryAttachPrimitive(ValOperandId valId, maybeEmitIdGuard(id); ObjOperandId protoId = writer.loadObject(proto); - EmitCallGetterByValueResult(cx_, writer, proto, holder, shape, protoId, - valId, mode_); + EmitCallGetterResult(cx_, writer, proto, holder, shape, protoId, valId, + mode_); trackAttached("PrimitiveGetter"); return AttachDecision::Attach; @@ -1994,8 +2158,7 @@ AttachDecision GetPropIRGenerator::tryAttachStringLength(ValOperandId valId, return AttachDecision::Attach; } -static bool CanAttachStringChar(HandleValue val, HandleValue idVal, - StringChar kind) { +static bool CanAttachStringChar(HandleValue val, HandleValue idVal) { if (!val.isString() || !idVal.isInt32()) { return false; } @@ -2027,20 +2190,14 @@ static bool CanAttachStringChar(HandleValue val, HandleValue idVal, return false; } - if (kind == StringChar::CodeAt) { - return true; - } - - // For charAt we need to have StaticString for that code-point. - return str->asLinear().latin1OrTwoByteChar(index) < - StaticStrings::UNIT_STATIC_LIMIT; + return true; } AttachDecision GetPropIRGenerator::tryAttachStringChar(ValOperandId valId, ValOperandId indexId) { MOZ_ASSERT(idVal_.isInt32()); - if (!CanAttachStringChar(val_, idVal_, StringChar::At)) { + if (!CanAttachStringChar(val_, idVal_)) { return AttachDecision::NoAction; } @@ -2101,9 +2258,30 @@ AttachDecision GetPropIRGenerator::tryAttachMagicArgument( } AttachDecision GetPropIRGenerator::tryAttachArgumentsObjectArg( - HandleObject obj, ObjOperandId objId, Int32OperandId indexId) { - if (!obj->is() || - obj->as().hasOverriddenElement()) { + HandleObject obj, ObjOperandId objId, uint32_t index, + Int32OperandId indexId) { + if (!obj->is()) { + return AttachDecision::NoAction; + } + auto* args = &obj->as(); + + // No elements must have been overriden. + if (args->hasOverriddenElement()) { + return AttachDecision::NoAction; + } + + // Check bounds. + if (index >= args->initialLength()) { + return AttachDecision::NoAction; + } + + // Ensure no elements were ever deleted. + if (args->isAnyElementDeleted()) { + return AttachDecision::NoAction; + } + + // And finally also check that the argument isn't forwarded. + if (args->argIsForwarded(index)) { return AttachDecision::NoAction; } @@ -2111,10 +2289,10 @@ AttachDecision GetPropIRGenerator::tryAttachArgumentsObjectArg( return AttachDecision::NoAction; } - if (obj->is()) { + if (args->is()) { writer.guardClass(objId, GuardClassKind::MappedArguments); } else { - MOZ_ASSERT(obj->is()); + MOZ_ASSERT(args->is()); writer.guardClass(objId, GuardClassKind::UnmappedArguments); } @@ -2296,6 +2474,24 @@ static Scalar::Type TypedThingElementType(JSObject* obj) { : PrimitiveArrayTypedObjectType(obj); } +// For Uint32Array we let the stub return a double only if the current result is +// a double, to allow better codegen in Warp. +static bool AllowDoubleForUint32Array(TypedArrayObject* tarr, uint32_t index) { + if (TypedThingElementType(tarr) != Scalar::Type::Uint32) { + // Return value is only relevant for Uint32Array. + return false; + } + + if (index >= tarr->length()) { + return false; + } + + Value res; + MOZ_ALWAYS_TRUE(tarr->getElementPure(index, &res)); + MOZ_ASSERT(res.isNumber()); + return res.isDouble(); +} + AttachDecision GetPropIRGenerator::tryAttachTypedElement( HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId) { @@ -2320,9 +2516,11 @@ AttachDecision GetPropIRGenerator::tryAttachTypedElement( // Don't handle out-of-bounds accesses here because we have to ensure the // |undefined| type is monitored. See also tryAttachTypedArrayNonInt32Index. if (layout == TypedThingLayout::TypedArray) { - writer.loadTypedArrayElementResult(objId, indexId, - TypedThingElementType(obj), - /* handleOOB = */ false); + TypedArrayObject* tarr = &obj->as(); + bool allowDoubleForUint32 = AllowDoubleForUint32Array(tarr, index); + writer.loadTypedArrayElementResult( + objId, indexId, TypedThingElementType(obj), + /* handleOOB = */ false, allowDoubleForUint32); } else { writer.loadTypedObjectElementResult(objId, indexId, layout, TypedThingElementType(obj)); @@ -2350,13 +2548,27 @@ AttachDecision GetPropIRGenerator::tryAttachTypedArrayNonInt32Index( return AttachDecision::NoAction; } + TypedArrayObject* tarr = &obj->as(); + + // Try to convert the number to a typed array index. Use NumberEqualsInt32 + // because ToPropertyKey(-0) is 0. If the number is not representable as an + // int32 the result will be |undefined| so we leave |allowDoubleForUint32| as + // false. + bool allowDoubleForUint32 = false; + int32_t indexInt32; + if (mozilla::NumberEqualsInt32(idVal_.toNumber(), &indexInt32)) { + uint32_t index = uint32_t(indexInt32); + allowDoubleForUint32 = AllowDoubleForUint32Array(tarr, index); + } + ValOperandId keyId = getElemKeyValueId(); Int32OperandId indexId = writer.guardToTypedArrayIndex(keyId); - writer.guardShapeForClass(objId, obj->as().shape()); + writer.guardShapeForClass(objId, tarr->shape()); writer.loadTypedArrayElementResult(objId, indexId, TypedThingElementType(obj), - /* handleOOB = */ true); + /* handleOOB = */ true, + allowDoubleForUint32); // Always monitor the result when out-of-bounds accesses are expected. writer.typeMonitorResult(); @@ -2406,12 +2618,12 @@ AttachDecision GetPropIRGenerator::tryAttachProxyElement(HandleObject obj, // We are not guarding against DOM proxies here, because there is no other // specialized DOM IC we could attach. - // We could call maybeEmitIdGuard here and then emit CallProxyGetResult, + // We could call maybeEmitIdGuard here and then emit ProxyGetResult, // but for GetElem we prefer to attach a stub that can handle any Value // so we don't attach a new stub for every id. MOZ_ASSERT(cacheKind_ == CacheKind::GetElem); MOZ_ASSERT(!isSuper()); - writer.callProxyGetByValueResult(objId, getElemKeyValueId()); + writer.proxyGetByValueResult(objId, getElemKeyValueId()); writer.typeMonitorResult(); trackAttached("ProxyElement"); @@ -2631,8 +2843,9 @@ AttachDecision GetNameIRGenerator::tryAttachGlobalNameGetter(ObjOperandId objId, writer.guardShape(holderId, holder->lastProperty()); } + ValOperandId receiverId = writer.boxObject(globalId); EmitCallGetterResultNoGuards(cx_, writer, &globalLexical->global(), holder, - shape, globalId); + shape, receiverId); trackAttached("GlobalNameGetter"); return AttachDecision::Attach; @@ -3052,16 +3265,16 @@ AttachDecision HasPropIRGenerator::tryAttachTypedArray(HandleObject obj, return AttachDecision::NoAction; } - TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); - if (IsPrimitiveArrayTypedObject(obj)) { + TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); + writer.guardGroupForLayout(objId, obj->group()); + writer.loadTypedObjectElementExistsResult(objId, indexId, layout); } else { - writer.guardShapeForClass(objId, obj->as().shape()); + writer.guardIsTypedArray(objId); + writer.loadTypedArrayElementExistsResult(objId, indexId); } - writer.loadTypedElementExistsResult(objId, indexId, layout); - writer.returnFromIC(); trackAttached("TypedArrayObject"); @@ -3080,12 +3293,8 @@ AttachDecision HasPropIRGenerator::tryAttachTypedArrayNonInt32Index( Int32OperandId indexId = writer.guardToTypedArrayIndex(keyId); - TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); - - writer.guardShapeForClass(objId, obj->as().shape()); - - writer.loadTypedElementExistsResult(objId, indexId, layout); - + writer.guardIsTypedArray(objId); + writer.loadTypedArrayElementExistsResult(objId, indexId); writer.returnFromIC(); trackAttached("TypedArrayObjectNonInt32Index"); @@ -3166,7 +3375,7 @@ AttachDecision HasPropIRGenerator::tryAttachProxyElement(HandleObject obj, } writer.guardIsProxy(objId); - writer.callProxyHasPropResult(objId, keyId, hasOwn); + writer.proxyHasPropResult(objId, keyId, hasOwn); writer.returnFromIC(); trackAttached("ProxyHasProp"); @@ -3234,6 +3443,75 @@ void HasPropIRGenerator::trackAttached(const char* name) { #endif } +CheckPrivateFieldIRGenerator::CheckPrivateFieldIRGenerator( + JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode, + CacheKind cacheKind, HandleValue idVal, HandleValue val) + : IRGenerator(cx, script, pc, cacheKind, mode), val_(val), idVal_(idVal) { + MOZ_ASSERT(idVal.isSymbol() && idVal.toSymbol()->isPrivateName()); +} + +AttachDecision CheckPrivateFieldIRGenerator::tryAttachStub() { + AutoAssertNoPendingException aanpe(cx_); + + ValOperandId valId(writer.setInputOperandId(0)); + ValOperandId keyId(writer.setInputOperandId(1)); + + if (!val_.isObject()) { + trackAttached(IRGenerator::NotAttached); + return AttachDecision::NoAction; + } + RootedObject obj(cx_, &val_.toObject()); + ObjOperandId objId = writer.guardToObject(valId); + RootedId key(cx_, SYMBOL_TO_JSID(idVal_.toSymbol())); + + ThrowCondition condition; + ThrowMsgKind msgKind; + GetCheckPrivateFieldOperands(pc_, &condition, &msgKind); + + bool hasOwn = false; + if (!HasOwnDataPropertyPure(cx_, obj, key, &hasOwn)) { + // Can't determine if HasOwnProperty purely. + return AttachDecision::NoAction; + } + + if (CheckPrivateFieldWillThrow(condition, hasOwn)) { + // Don't attach a stub if the operation will throw. + return AttachDecision::NoAction; + } + + TRY_ATTACH(tryAttachNative(obj, objId, key, keyId, hasOwn)); + + return AttachDecision::NoAction; +} + +AttachDecision CheckPrivateFieldIRGenerator::tryAttachNative(JSObject* obj, + ObjOperandId objId, + jsid key, + ValOperandId keyId, + bool hasOwn) { + if (!obj->isNative()) { + return AttachDecision::NoAction; + } + + Maybe tempId; + emitIdGuard(keyId, key); + EmitReadSlotGuard(writer, obj, obj, objId, &tempId); + writer.loadBooleanResult(hasOwn); + writer.returnFromIC(); + + trackAttached("NativeCheckPrivateField"); + return AttachDecision::Attach; +} + +void CheckPrivateFieldIRGenerator::trackAttached(const char* name) { +#ifdef JS_CACHEIR_SPEW + if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) { + sp.valueProperty("base", val_); + sp.valueProperty("property", idVal_); + } +#endif +} + bool IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId, uint32_t* int32Index, Int32OperandId* int32IndexId) { @@ -3265,7 +3543,7 @@ bool IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId, StringOperandId strId = writer.guardToString(indexId); *int32Index = uint32_t(indexSigned); - *int32IndexId = writer.guardAndGetIndexFromString(strId); + *int32IndexId = writer.guardStringToIndex(strId); return true; } @@ -3465,8 +3743,7 @@ AttachDecision SetPropIRGenerator::tryAttachNativeSetSlot(HandleObject obj, return AttachDecision::Attach; } -OperandId SetPropIRGenerator::emitNumericGuard(ValOperandId valId, - Scalar::Type type) { +OperandId IRGenerator::emitNumericGuard(ValOperandId valId, Scalar::Type type) { switch (type) { case Scalar::Int8: case Scalar::Uint8: @@ -3494,6 +3771,13 @@ OperandId SetPropIRGenerator::emitNumericGuard(ValOperandId valId, MOZ_CRASH("Unsupported TypedArray type"); } +static bool ValueIsNumeric(Scalar::Type type, const Value& val) { + if (Scalar::isBigIntType(type)) { + return val.isBigInt(); + } + return val.isNumber(); +} + AttachDecision SetPropIRGenerator::tryAttachTypedObjectProperty( HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId) { if (!obj->is()) { @@ -3525,6 +3809,13 @@ AttachDecision SetPropIRGenerator::tryAttachTypedObjectProperty( return AttachDecision::NoAction; } + if (fieldDescr->is()) { + Scalar::Type type = fieldDescr->as().type(); + if (!ValueIsNumeric(type, rhsVal_)) { + return AttachDecision::NoAction; + } + } + uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex); TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); @@ -3666,23 +3957,31 @@ static void EmitCallSetterNoGuards(JSContext* cx, CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, ObjOperandId objId, ValOperandId rhsId) { - if (IsCacheableSetPropCallNative(obj, holder, shape)) { - JSFunction* target = &shape->setterValue().toObject().as(); - MOZ_ASSERT(target->isNativeWithoutJitEntry()); - writer.callNativeSetter(objId, target, rhsId); + JSFunction* target = &shape->setterValue().toObject().as(); + bool sameRealm = cx->realm() == target->realm(); + + if (target->isNativeWithoutJitEntry()) { + MOZ_ASSERT(IsCacheableSetPropCallNative(obj, holder, shape)); + writer.callNativeSetter(objId, target, rhsId, sameRealm); writer.returnFromIC(); return; } MOZ_ASSERT(IsCacheableSetPropCallScripted(obj, holder, shape)); - - JSFunction* target = &shape->setterValue().toObject().as(); - MOZ_ASSERT(target->hasJitEntry()); - bool sameRealm = cx->realm() == target->realm(); writer.callScriptedSetter(objId, target, rhsId, sameRealm); writer.returnFromIC(); } +static void EmitCallDOMSetterNoGuards(JSContext* cx, CacheIRWriter& writer, + Shape* shape, ObjOperandId objId, + ValOperandId rhsId) { + JSFunction* setter = &shape->setterValue().toObject().as(); + MOZ_ASSERT(cx->realm() == setter->realm()); + + writer.callDOMSetter(objId, setter->jitInfo(), rhsId); + writer.returnFromIC(); +} + AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj, ObjOperandId objId, HandleId id, @@ -3712,6 +4011,13 @@ AttachDecision SetPropIRGenerator::tryAttachSetter(HandleObject obj, writer.guardHasGetterSetter(objId, propShape); } + if (CanAttachDOMGetterSetter(cx_, JSJitInfo::Setter, obj, propShape, mode_)) { + EmitCallDOMSetterNoGuards(cx_, writer, propShape, objId, rhsId); + + trackAttached("DOMSetter"); + return AttachDecision::Attach; + } + EmitCallSetterNoGuards(cx_, writer, obj, holder, propShape, objId, rhsId); trackAttached("Setter"); @@ -3751,6 +4057,9 @@ AttachDecision SetPropIRGenerator::tryAttachSetDenseElement( return AttachDecision::NoAction; } + // Setting holes requires extra code for marking the elements non-packed. + MOZ_ASSERT(!rhsVal_.isMagic(JS_ELEMENTS_HOLE)); + // Don't optimize InitElem (DefineProperty) on non-extensible objects: when // the elements are sealed, we have to throw an exception. Note that we have // to check !isExtensible instead of denseElementsAreSealed because sealing @@ -3822,7 +4131,12 @@ static bool CanAttachAddElement(NativeObject* obj, bool isInit) { AttachDecision SetPropIRGenerator::tryAttachSetDenseElementHole( HandleObject obj, ObjOperandId objId, uint32_t index, Int32OperandId indexId, ValOperandId rhsId) { - if (!obj->isNative() || rhsVal_.isMagic(JS_ELEMENTS_HOLE)) { + if (!obj->isNative()) { + return AttachDecision::NoAction; + } + + // Setting holes requires extra code for marking the elements non-packed. + if (rhsVal_.isMagic(JS_ELEMENTS_HOLE)) { return AttachDecision::NoAction; } @@ -4000,14 +4314,8 @@ AttachDecision SetPropIRGenerator::tryAttachSetTypedElement( TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); // Don't attach if the input type doesn't match the guard added below. - if (Scalar::isBigIntType(elementType)) { - if (!rhsVal_.isBigInt()) { - return AttachDecision::NoAction; - } - } else { - if (!rhsVal_.isNumber()) { - return AttachDecision::NoAction; - } + if (!ValueIsNumeric(elementType, rhsVal_)) { + return AttachDecision::NoAction; } if (IsPrimitiveArrayTypedObject(obj)) { @@ -4049,14 +4357,8 @@ AttachDecision SetPropIRGenerator::tryAttachSetTypedArrayElementNonInt32Index( Scalar::Type elementType = TypedThingElementType(obj); // Don't attach if the input type doesn't match the guard added below. - if (Scalar::isBigIntType(elementType)) { - if (!rhsVal_.isBigInt()) { - return AttachDecision::NoAction; - } - } else { - if (!rhsVal_.isNumber()) { - return AttachDecision::NoAction; - } + if (!ValueIsNumeric(elementType, rhsVal_)) { + return AttachDecision::NoAction; } ValOperandId keyId = setElemKeyValueId(); @@ -4092,18 +4394,18 @@ AttachDecision SetPropIRGenerator::tryAttachGenericProxy( // get to the specialized stubs. If handleDOMProxies is true, we were // unable to attach a specialized DOM stub, so we just handle all // proxies here. - writer.guardNotDOMProxy(objId); + writer.guardIsNotDOMProxy(objId); } if (cacheKind_ == CacheKind::SetProp || mode_ == ICState::Mode::Specialized) { maybeEmitIdGuard(id); - writer.callProxySet(objId, id, rhsId, IsStrictSetPC(pc_)); + writer.proxySet(objId, id, rhsId, IsStrictSetPC(pc_)); } else { // Attach a stub that handles every id. MOZ_ASSERT(cacheKind_ == CacheKind::SetElem); MOZ_ASSERT(mode_ == ICState::Mode::Megamorphic); - writer.callProxySetByValue(objId, setElemKeyValueId(), rhsId, - IsStrictSetPC(pc_)); + writer.proxySetByValue(objId, setElemKeyValueId(), rhsId, + IsStrictSetPC(pc_)); } writer.returnFromIC(); @@ -4118,7 +4420,7 @@ AttachDecision SetPropIRGenerator::tryAttachDOMProxyShadowed( maybeEmitIdGuard(id); TestMatchingProxyReceiver(writer, &obj->as(), objId); - writer.callProxySet(objId, id, rhsId, IsStrictSetPC(pc_)); + writer.proxySet(objId, id, rhsId, IsStrictSetPC(pc_)); writer.returnFromIC(); trackAttached("DOMProxyShadowed"); @@ -4268,8 +4570,7 @@ AttachDecision SetPropIRGenerator::tryAttachProxyElement(HandleObject obj, // Like GetPropIRGenerator::tryAttachProxyElement, don't check for DOM // proxies here as we don't have specialized DOM stubs for this. MOZ_ASSERT(cacheKind_ == CacheKind::SetElem); - writer.callProxySetByValue(objId, setElemKeyValueId(), rhsId, - IsStrictSetPC(pc_)); + writer.proxySetByValue(objId, setElemKeyValueId(), rhsId, IsStrictSetPC(pc_)); writer.returnFromIC(); trackAttached("ProxyElement"); @@ -4346,17 +4647,22 @@ bool SetPropIRGenerator::canAttachAddSlotStub(HandleObject obj, HandleId id) { if (obj->is() && JSID_IS_ATOM(id, cx_->names().prototype)) { MOZ_ASSERT(ClassMayResolveId(cx_->names(), obj->getClass(), id, obj)); - // We check group->maybeInterpretedFunction() here and guard on the - // group. The group is unique for a particular function so this ensures - // we don't add the default prototype property to functions that don't - // have it. + // We're only interested in functions that have a builtin .prototype + // property (needsPrototypeProperty). The stub will guard on this because + // the builtin .prototype property is non-configurable/non-enumerable and it + // would be wrong to add a property with those attributes to a function that + // doesn't have a builtin .prototype. + // + // Inlining needsPrototypeProperty in JIT code is complicated so we use + // isNonBuiltinConstructor as a stronger condition that's easier to check + // from JIT code. JSFunction* fun = &obj->as(); - if (!obj->group()->maybeInterpretedFunction() || - !fun->needsPrototypeProperty()) { + if (!fun->isNonBuiltinConstructor()) { return false; } + MOZ_ASSERT(fun->needsPrototypeProperty()); - // If property exists this isn't an "add" + // If property exists this isn't an "add". if (fun->lookupPure(id)) { return false; } @@ -4371,8 +4677,10 @@ bool SetPropIRGenerator::canAttachAddSlotStub(HandleObject obj, HandleId id) { } } - // Object must be extensible. - if (!obj->nonProxyIsExtensible()) { + // Object must be extensible, or we must be initializing a private + // elem. + bool canAddNewProperty = obj->nonProxyIsExtensible() || id.isPrivateName(); + if (!canAddNewProperty) { return false; } @@ -4474,11 +4782,10 @@ AttachDecision SetPropIRGenerator::tryAttachAddSlotStub( ObjOperandId objId = writer.guardToObject(objValId); maybeEmitIdGuard(id); - // In addition to guarding for type barrier, we need this group guard (or - // shape guard below) to ensure class is unchanged. This group guard may also - // imply maybeInterpretedFunction() for the special-case of function - // prototype property set. - writer.guardGroup(objId, oldGroup); + if (IsTypeInferenceEnabled()) { + // Guard on the group for the property type barrier and group change. + writer.guardGroup(objId, oldGroup); + } // If we are adding a property to an object for which the new script // properties analysis hasn't been performed yet, make sure the stub fails @@ -4494,9 +4801,15 @@ AttachDecision SetPropIRGenerator::tryAttachAddSlotStub( preliminaryObjectAction_ = PreliminaryObjectAction::Unlink; } - // Shape guard the holder. - ObjOperandId holderId = objId; - writer.guardShape(holderId, oldShape); + // Shape guard the object. + writer.guardShape(objId, oldShape); + + // If this is the special function.prototype case, we need to guard the + // function is a non-builtin constructor. See canAttachAddSlotStub. + if (obj->is() && JSID_IS_ATOM(id, cx_->names().prototype)) { + MOZ_ASSERT(obj->as().isNonBuiltinConstructor()); + writer.guardFunctionIsNonBuiltinCtor(objId); + } ShapeGuardProtoChain(writer, obj, objId); @@ -4509,22 +4822,21 @@ AttachDecision SetPropIRGenerator::tryAttachAddSlotStub( if (holder->isFixedSlot(propShape->slot())) { size_t offset = NativeObject::getFixedSlotOffset(propShape->slot()); - writer.addAndStoreFixedSlot(holderId, offset, rhsValId, changeGroup, - newGroup, propShape); + writer.addAndStoreFixedSlot(objId, offset, rhsValId, changeGroup, newGroup, + propShape); trackAttached("AddSlot"); } else { size_t offset = holder->dynamicSlotIndex(propShape->slot()) * sizeof(Value); - uint32_t numOldSlots = NativeObject::dynamicSlotsCount(oldShape); - uint32_t numNewSlots = NativeObject::dynamicSlotsCount(propShape); + uint32_t numOldSlots = NativeObject::calculateDynamicSlots(oldShape); + uint32_t numNewSlots = holder->numDynamicSlots(); if (numOldSlots == numNewSlots) { - writer.addAndStoreDynamicSlot(holderId, offset, rhsValId, changeGroup, + writer.addAndStoreDynamicSlot(objId, offset, rhsValId, changeGroup, newGroup, propShape); trackAttached("AddSlot"); } else { MOZ_ASSERT(numNewSlots > numOldSlots); - writer.allocateAndStoreDynamicSlot(holderId, offset, rhsValId, - changeGroup, newGroup, propShape, - numNewSlots); + writer.allocateAndStoreDynamicSlot(objId, offset, rhsValId, changeGroup, + newGroup, propShape, numNewSlots); trackAttached("AllocateSlot"); } } @@ -4628,7 +4940,7 @@ AttachDecision InstanceOfIRGenerator::tryAttachStub() { // Load prototypeObject into the cache -- consumed twice in the IC ObjOperandId protoId = writer.loadObject(prototypeObject); // Ensure that rhs[slot] == prototypeObject. - writer.guardFunctionPrototype(rhsId, protoId, slot); + writer.guardDynamicSlotIsSpecificObject(rhsId, protoId, slot); // Needn't guard LHS is object, because the actual stub can handle that // and correctly return false. @@ -4775,13 +5087,170 @@ void GetIteratorIRGenerator::trackAttached(const char* name) { #endif } +OptimizeSpreadCallIRGenerator::OptimizeSpreadCallIRGenerator( + JSContext* cx, HandleScript script, jsbytecode* pc, ICState::Mode mode, + HandleValue value) + : IRGenerator(cx, script, pc, CacheKind::OptimizeSpreadCall, mode), + val_(value) {} + +AttachDecision OptimizeSpreadCallIRGenerator::tryAttachStub() { + MOZ_ASSERT(cacheKind_ == CacheKind::OptimizeSpreadCall); + + AutoAssertNoPendingException aanpe(cx_); + + TRY_ATTACH(tryAttachArray()); + TRY_ATTACH(tryAttachNotOptimizable()); + + trackAttached(IRGenerator::NotAttached); + return AttachDecision::NoAction; +} + +static bool IsArrayPrototypeOptimizable(JSContext* cx, ArrayObject* arr, + NativeObject** arrProto, uint32_t* slot, + JSFunction** iterFun) { + // Prototype must be Array.prototype. + auto* proto = cx->global()->maybeGetArrayPrototype(); + if (!proto || arr->staticPrototype() != proto) { + return false; + } + *arrProto = proto; + + // The object must not have an own @@iterator property. + JS::PropertyKey iteratorKey = SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator); + if (arr->lookupPure(iteratorKey)) { + return false; + } + + // Ensure that Array.prototype's @@iterator slot is unchanged. + Shape* shape = proto->lookupPure(iteratorKey); + if (!shape || !shape->isDataProperty()) { + return false; + } + + *slot = shape->slot(); + MOZ_ASSERT(proto->numFixedSlots() == 0, "Stub code relies on this"); + + const Value& iterVal = proto->getSlot(*slot); + if (!iterVal.isObject() || !iterVal.toObject().is()) { + return false; + } + + *iterFun = &iterVal.toObject().as(); + return IsSelfHostedFunctionWithName(*iterFun, cx->names().ArrayValues); +} + +static bool IsArrayIteratorPrototypeOptimizable(JSContext* cx, + NativeObject** arrIterProto, + uint32_t* slot, + JSFunction** nextFun) { + auto* proto = cx->global()->maybeGetArrayIteratorPrototype(); + if (!proto) { + return false; + } + *arrIterProto = proto; + + // Ensure that %ArrayIteratorPrototype%'s "next" slot is unchanged. + Shape* shape = proto->lookupPure(cx->names().next); + if (!shape || !shape->isDataProperty()) { + return false; + } + + *slot = shape->slot(); + MOZ_ASSERT(proto->numFixedSlots() == 0, "Stub code relies on this"); + + const Value& nextVal = proto->getSlot(*slot); + if (!nextVal.isObject() || !nextVal.toObject().is()) { + return false; + } + + *nextFun = &nextVal.toObject().as(); + return IsSelfHostedFunctionWithName(*nextFun, cx->names().ArrayIteratorNext); +} + +AttachDecision OptimizeSpreadCallIRGenerator::tryAttachArray() { + // The value must be a packed array. + if (!val_.isObject()) { + return AttachDecision::NoAction; + } + JSObject* obj = &val_.toObject(); + if (!IsPackedArray(obj)) { + return AttachDecision::NoAction; + } + + // Prototype must be Array.prototype and Array.prototype[@@iterator] must not + // be modified. + NativeObject* arrProto; + uint32_t arrProtoIterSlot; + JSFunction* iterFun; + if (!IsArrayPrototypeOptimizable(cx_, &obj->as(), &arrProto, + &arrProtoIterSlot, &iterFun)) { + return AttachDecision::NoAction; + } + + // %ArrayIteratorPrototype%.next must not be modified. + NativeObject* arrayIteratorProto; + uint32_t iterNextSlot; + JSFunction* nextFun; + if (!IsArrayIteratorPrototypeOptimizable(cx_, &arrayIteratorProto, + &iterNextSlot, &nextFun)) { + return AttachDecision::NoAction; + } + + ValOperandId valId(writer.setInputOperandId(0)); + ObjOperandId objId = writer.guardToObject(valId); + + // Guard the object is a packed array with Array.prototype as proto. + writer.guardShape(objId, obj->as().lastProperty()); + writer.guardArrayIsPacked(objId); + if (obj->hasUncacheableProto()) { + writer.guardProto(objId, arrProto); + } + + // Guard on Array.prototype[@@iterator]. + ObjOperandId arrProtoId = writer.loadObject(arrProto); + ObjOperandId iterId = writer.loadObject(iterFun); + writer.guardShape(arrProtoId, arrProto->lastProperty()); + writer.guardDynamicSlotIsSpecificObject(arrProtoId, iterId, arrProtoIterSlot); + + // Guard on %ArrayIteratorPrototype%.next. + ObjOperandId iterProtoId = writer.loadObject(arrayIteratorProto); + ObjOperandId nextId = writer.loadObject(nextFun); + writer.guardShape(iterProtoId, arrayIteratorProto->lastProperty()); + writer.guardDynamicSlotIsSpecificObject(iterProtoId, nextId, iterNextSlot); + + writer.loadBooleanResult(true); + writer.returnFromIC(); + + trackAttached("Array"); + return AttachDecision::Attach; +} + +AttachDecision OptimizeSpreadCallIRGenerator::tryAttachNotOptimizable() { + ValOperandId valId(writer.setInputOperandId(0)); + + writer.loadBooleanResult(false); + writer.returnFromIC(); + + trackAttached("NotOptimizable"); + return AttachDecision::Attach; +} + +void OptimizeSpreadCallIRGenerator::trackAttached(const char* name) { +#ifdef JS_CACHEIR_SPEW + if (const CacheIRSpewer::Guard& sp = CacheIRSpewer::Guard(*this, name)) { + sp.valueProperty("val", val_); + } +#endif +} + CallIRGenerator::CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, JSOp op, ICState::Mode mode, - uint32_t argc, HandleValue callee, - HandleValue thisval, HandleValue newTarget, - HandleValueArray args) + bool isFirstStub, uint32_t argc, + HandleValue callee, HandleValue thisval, + HandleValue newTarget, HandleValueArray args) : IRGenerator(cx, script, pc, CacheKind::Call, mode), op_(op), + isFirstStub_(isFirstStub), argc_(argc), callee_(callee), thisval_(thisval), @@ -4794,10 +5263,38 @@ void CallIRGenerator::emitNativeCalleeGuard(HandleFunction callee) { // Note: we rely on GuardSpecificFunction to also guard against the same // native from a different realm. MOZ_ASSERT(callee->isNativeWithoutJitEntry()); + + bool isConstructing = IsConstructPC(pc_); + CallFlags flags(isConstructing, IsSpreadPC(pc_)); + ValOperandId calleeValId = - writer.loadArgumentFixedSlot(ArgumentKind::Callee, argc_); + writer.loadArgumentFixedSlot(ArgumentKind::Callee, argc_, flags); ObjOperandId calleeObjId = writer.guardToObject(calleeValId); writer.guardSpecificFunction(calleeObjId, callee); + + // If we're constructing we also need to guard newTarget == callee. + if (isConstructing) { + MOZ_ASSERT(&newTarget_.toObject() == callee); + ValOperandId newTargetValId = + writer.loadArgumentFixedSlot(ArgumentKind::NewTarget, argc_, flags); + ObjOperandId newTargetObjId = writer.guardToObject(newTargetValId); + writer.guardSpecificFunction(newTargetObjId, callee); + } +} + +void CallIRGenerator::emitCalleeGuard(ObjOperandId calleeId, + HandleFunction callee) { + // Guarding on the callee JSFunction* is most efficient, but doesn't work well + // for lambda clones (multiple functions with the same BaseScript). We guard + // on the function's BaseScript if the callee is scripted and this isn't the + // first IC stub. + if (!JitOptions.warpBuilder || isFirstStub_ || !callee->hasBaseScript() || + callee->isSelfHostedBuiltin()) { + writer.guardSpecificFunction(calleeId, callee); + } else { + writer.guardClass(calleeId, GuardClassKind::JSFunction); + writer.guardFunctionScript(calleeId, callee->baseScript()); + } } AttachDecision CallIRGenerator::tryAttachArrayPush(HandleFunction callee) { @@ -4807,7 +5304,7 @@ AttachDecision CallIRGenerator::tryAttachArrayPush(HandleFunction callee) { } // Where |obj| is a native array. - RootedObject thisobj(cx_, &thisval_.toObject()); + JSObject* thisobj = &thisval_.toObject(); if (!thisobj->is()) { return AttachDecision::NoAction; } @@ -4816,7 +5313,7 @@ AttachDecision CallIRGenerator::tryAttachArrayPush(HandleFunction callee) { return AttachDecision::NoAction; } - RootedArrayObject thisarray(cx_, &thisobj->as()); + auto* thisarray = &thisobj->as(); // Check for other indexed properties or class hooks. if (!CanAttachAddElement(thisarray, /* isInit = */ false)) { @@ -4840,7 +5337,6 @@ AttachDecision CallIRGenerator::tryAttachArrayPush(HandleFunction callee) { MOZ_ASSERT(!thisarray->denseElementsAreFrozen(), "Extensible arrays should not have frozen elements"); - MOZ_ASSERT(thisarray->lengthIsWritable()); // After this point, we can generate code fine. @@ -4884,44 +5380,76 @@ AttachDecision CallIRGenerator::tryAttachArrayPush(HandleFunction callee) { return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachArrayJoin(HandleFunction callee) { - // Only handle argc <= 1. - if (argc_ > 1) { +AttachDecision CallIRGenerator::tryAttachArrayPopShift(HandleFunction callee, + InlinableNative native) { + // Expecting no arguments. + if (argc_ != 0) { return AttachDecision::NoAction; } - // Only optimize on obj.join(...); - if (!thisval_.isObject()) { + // Only optimize if |this| is a packed array. + if (!thisval_.isObject() || !IsPackedArray(&thisval_.toObject())) { return AttachDecision::NoAction; } - // Where |obj| is a native array. - RootedObject thisobj(cx_, &thisval_.toObject()); - if (!thisobj->is()) { + // Other conditions: + // + // * The array length needs to be writable because we're changing it. + // * The elements must not be copy-on-write because we're deleting an element. + // * The array must be extensible. Non-extensible arrays require preserving + // the |initializedLength == capacity| invariant on ObjectElements. + // See NativeObject::shrinkCapacityToInitializedLength. + // This also ensures the elements aren't sealed/frozen. + // * There must not be a for-in iterator for the elements because the IC stub + // does not suppress deleted properties. + ArrayObject* arr = &thisval_.toObject().as(); + if (!arr->lengthIsWritable() || arr->denseElementsAreCopyOnWrite() || + !arr->isExtensible() || arr->denseElementsHaveMaybeInIterationFlag()) { return AttachDecision::NoAction; } - RootedArrayObject thisarray(cx_, &thisobj->as()); + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); - // And the array is of length 0 or 1. - if (thisarray->length() > 1) { - return AttachDecision::NoAction; + // Guard callee is the 'pop' or 'shift' native function. + emitNativeCalleeGuard(callee); + + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + ObjOperandId objId = writer.guardToObject(thisValId); + writer.guardClass(objId, GuardClassKind::Array); + + if (native == InlinableNative::ArrayPop) { + writer.packedArrayPopResult(objId); + } else { + MOZ_ASSERT(native == InlinableNative::ArrayShift); + writer.packedArrayShiftResult(objId); } - // And the array is packed. - if (thisarray->getDenseInitializedLength() != thisarray->length()) { + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("ArrayPopShift"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachArrayJoin(HandleFunction callee) { + // Only handle argc <= 1. + if (argc_ > 1) { return AttachDecision::NoAction; } - // And the only element (if it exists) is a string - if (thisarray->length() == 1 && !thisarray->getDenseElement(0).isString()) { + // Only optimize if |this| is an array. + if (!thisval_.isObject() || !thisval_.toObject().is()) { return AttachDecision::NoAction; } - // We don't need to worry about indexed properties because we can perform - // hole check manually. + // The separator argument must be a string, if present. + if (argc_ > 0 && !args_[0].isString()) { + return AttachDecision::NoAction; + } - // Generate code. + // IC stub code can handle non-packed array. // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); @@ -4929,21 +5457,24 @@ AttachDecision CallIRGenerator::tryAttachArrayJoin(HandleFunction callee) { // Guard callee is the 'join' native function. emitNativeCalleeGuard(callee); - if (argc_ == 1) { - // If argcount is 1, guard that the argument is a string. - ValOperandId argValId = - writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); - writer.guardToString(argValId); - } - // Guard this is an array object. ValOperandId thisValId = writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); ObjOperandId thisObjId = writer.guardToObject(thisValId); writer.guardClass(thisObjId, GuardClassKind::Array); + StringOperandId sepId; + if (argc_ == 1) { + // If argcount is 1, guard that the argument is a string. + ValOperandId argValId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + sepId = writer.guardToString(argValId); + } else { + sepId = writer.loadConstantString(cx_->names().comma); + } + // Do the join. - writer.arrayJoinResult(thisObjId); + writer.arrayJoinResult(thisObjId, sepId); writer.returnFromIC(); @@ -4958,6 +5489,84 @@ AttachDecision CallIRGenerator::tryAttachArrayJoin(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachArraySlice(HandleFunction callee) { + // Only handle argc <= 2. + if (argc_ > 2) { + return AttachDecision::NoAction; + } + + // Only optimize if |this| is a packed array. + if (!thisval_.isObject() || !IsPackedArray(&thisval_.toObject())) { + return AttachDecision::NoAction; + } + + // Arguments for the sliced region must be integers. + if (argc_ > 0 && !args_[0].isInt32()) { + return AttachDecision::NoAction; + } + if (argc_ > 1 && !args_[1].isInt32()) { + return AttachDecision::NoAction; + } + + RootedArrayObject arr(cx_, &thisval_.toObject().as()); + + // The group of the result will be dynamically fixed up to match the input + // object, allowing us to handle 'this' objects that might have more than one + // group. Make sure that no singletons can be sliced here. + if (arr->isSingleton()) { + return AttachDecision::NoAction; + } + + JSObject* templateObj = + NewFullyAllocatedArrayTryReuseGroup(cx_, arr, 0, TenuredObject); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'slice' native function. + emitNativeCalleeGuard(callee); + + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + ObjOperandId objId = writer.guardToObject(thisValId); + writer.guardClass(objId, GuardClassKind::Array); + + Int32OperandId int32BeginId; + if (argc_ > 0) { + ValOperandId beginId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + int32BeginId = writer.guardToInt32(beginId); + } else { + int32BeginId = writer.loadInt32Constant(0); + } + + Int32OperandId int32EndId; + if (argc_ > 1) { + ValOperandId endId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + int32EndId = writer.guardToInt32(endId); + } else { + int32EndId = writer.loadInt32ArrayLength(objId); + } + + writer.packedArraySliceResult(templateObj, objId, int32BeginId, int32EndId); + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("ArraySlice"); + return AttachDecision::Attach; +} + AttachDecision CallIRGenerator::tryAttachArrayIsArray(HandleFunction callee) { // Need a single argument. if (argc_ != 1) { @@ -4983,130 +5592,289 @@ AttachDecision CallIRGenerator::tryAttachArrayIsArray(HandleFunction callee) { return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachUnsafeGetReservedSlot( - HandleFunction callee, InlinableNative native) { - // Need an object and int32 slot argument. - if (argc_ != 2 || !args_[0].isObject() || !args_[1].isInt32()) { +AttachDecision CallIRGenerator::tryAttachDataViewGet(HandleFunction callee, + Scalar::Type type) { + // Ensure |this| is a DataViewObject. + if (!thisval_.isObject() || !thisval_.toObject().is()) { return AttachDecision::NoAction; } - int32_t slot = args_[1].toInt32(); - if (slot < 0 || uint32_t(slot) >= NativeObject::MAX_FIXED_SLOTS) { + // Expected arguments: offset (number), optional littleEndian (boolean). + if (argc_ < 1 || argc_ > 2) { return AttachDecision::NoAction; } - size_t offset = NativeObject::getFixedSlotOffset(slot); + if (!args_[0].isNumber()) { + return AttachDecision::NoAction; + } + if (argc_ > 1 && !args_[1].isBoolean()) { + return AttachDecision::NoAction; + } + + DataViewObject* dv = &thisval_.toObject().as(); + + // Bounds check the offset. + int32_t offsetInt32; + if (!mozilla::NumberEqualsInt32(args_[0].toNumber(), &offsetInt32)) { + return AttachDecision::NoAction; + } + if (offsetInt32 < 0 || + !dv->offsetIsInBounds(Scalar::byteSize(type), offsetInt32)) { + return AttachDecision::NoAction; + } + + // For getUint32 we let the stub return a double only if the current result is + // a double, to allow better codegen in Warp. + bool allowDoubleForUint32 = false; + if (type == Scalar::Uint32) { + bool isLittleEndian = argc_ > 1 && args_[1].toBoolean(); + uint32_t res = dv->read(offsetInt32, isLittleEndian); + allowDoubleForUint32 = res >= INT32_MAX; + } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the correct intrinsic native function. + // Guard callee is this DataView native function. emitNativeCalleeGuard(callee); - // Guard that the first argument is an object. - ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); - ObjOperandId objId = writer.guardToObject(arg0Id); + // Guard |this| is a DataViewObject. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + ObjOperandId objId = writer.guardToObject(thisValId); + writer.guardClass(objId, GuardClassKind::DataView); - // BytecodeEmitter::checkSelfHostedUnsafeGetReservedSlot ensures that the - // slot argument is constant. (At least for direct calls) + // Convert offset to int32. + ValOperandId offsetId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + Int32OperandId int32OffsetId = writer.guardToInt32Index(offsetId); - switch (native) { - case InlinableNative::IntrinsicUnsafeGetReservedSlot: - writer.loadFixedSlotResult(objId, offset); - break; - case InlinableNative::IntrinsicUnsafeGetObjectFromReservedSlot: - writer.loadFixedSlotTypedResult(objId, offset, ValueType::Object); - break; - case InlinableNative::IntrinsicUnsafeGetInt32FromReservedSlot: - writer.loadFixedSlotTypedResult(objId, offset, ValueType::Int32); - break; - case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot: - writer.loadFixedSlotTypedResult(objId, offset, ValueType::String); - break; - case InlinableNative::IntrinsicUnsafeGetBooleanFromReservedSlot: - writer.loadFixedSlotTypedResult(objId, offset, ValueType::Boolean); - break; - default: - MOZ_CRASH("unexpected native"); + BooleanOperandId boolLittleEndianId; + if (argc_ > 1) { + ValOperandId littleEndianId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + boolLittleEndianId = writer.guardToBoolean(littleEndianId); + } else { + boolLittleEndianId = writer.loadBooleanConstant(false); } - // For simplicity just monitor all stubs. - writer.typeMonitorResult(); - cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + writer.loadDataViewValueResult(objId, int32OffsetId, boolLittleEndianId, type, + allowDoubleForUint32); - trackAttached("UnsafeGetReservedSlot"); + // This stub does not need to be monitored, because it returns the same type + // as this call. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("DataViewGet"); return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachIsSuspendedGenerator( - HandleFunction callee) { - // The IsSuspendedGenerator intrinsic is only called in - // self-hosted code, so it's safe to assume we have a single - // argument and the callee is our intrinsic. +AttachDecision CallIRGenerator::tryAttachDataViewSet(HandleFunction callee, + Scalar::Type type) { + // Ensure |this| is a DataViewObject. + if (!thisval_.isObject() || !thisval_.toObject().is()) { + return AttachDecision::NoAction; + } - MOZ_ASSERT(argc_ == 1); + // Expected arguments: offset (number), value, optional littleEndian (boolean) + if (argc_ < 2 || argc_ > 3) { + return AttachDecision::NoAction; + } + if (!args_[0].isNumber()) { + return AttachDecision::NoAction; + } + if (!ValueIsNumeric(type, args_[1])) { + return AttachDecision::NoAction; + } + if (argc_ > 2 && !args_[2].isBoolean()) { + return AttachDecision::NoAction; + } - Int32OperandId argcId(writer.setInputOperandId(0)); + DataViewObject* dv = &thisval_.toObject().as(); - // Stack layout here is (bottom to top): - // 2: Callee - // 1: ThisValue - // 0: Arg <-- Top of stack. - // We only care about the argument. - ValOperandId valId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + // Bounds check the offset. + int32_t offsetInt32; + if (!mozilla::NumberEqualsInt32(args_[0].toNumber(), &offsetInt32)) { + return AttachDecision::NoAction; + } + if (offsetInt32 < 0 || + !dv->offsetIsInBounds(Scalar::byteSize(type), offsetInt32)) { + return AttachDecision::NoAction; + } - // Check whether the argument is a suspended generator. - // We don't need guards, because IsSuspendedGenerator returns - // false for values that are not generator objects. - writer.callIsSuspendedGeneratorResult(valId); - writer.returnFromIC(); + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); - // This stub does not need to be monitored, because it always - // returns Boolean. The stack typeset will be updated when we - // attach the stub. + // Guard callee is this DataView native function. + emitNativeCalleeGuard(callee); + + // Guard |this| is a DataViewObject. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + ObjOperandId objId = writer.guardToObject(thisValId); + writer.guardClass(objId, GuardClassKind::DataView); + + // Convert offset to int32. + ValOperandId offsetId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + Int32OperandId int32OffsetId = writer.guardToInt32Index(offsetId); + + // Convert value to number or BigInt. + ValOperandId valueId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + OperandId numericValueId = emitNumericGuard(valueId, type); + + BooleanOperandId boolLittleEndianId; + if (argc_ > 2) { + ValOperandId littleEndianId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + boolLittleEndianId = writer.guardToBoolean(littleEndianId); + } else { + boolLittleEndianId = writer.loadBooleanConstant(false); + } + + writer.storeDataViewValueResult(objId, int32OffsetId, numericValueId, + boolLittleEndianId, type); + + // This stub doesn't need type monitoring, it always returns |undefined|. + writer.returnFromIC(); cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - trackAttached("IsSuspendedGenerator"); + trackAttached("DataViewSet"); return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachToString(HandleFunction callee, - InlinableNative native) { - // Need a single string argument. - // TODO(Warp): Support all or more conversions to strings. - // Note: Unlike String, ToString requires exactly one argument. - if (argc_ != 1 || !args_[0].isString()) { +AttachDecision CallIRGenerator::tryAttachUnsafeGetReservedSlot( + HandleFunction callee, InlinableNative native) { + // Self-hosted code calls this with (object, int32) arguments. + MOZ_ASSERT(argc_ == 2); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[1].isInt32()); + MOZ_ASSERT(args_[1].toInt32() >= 0); + + uint32_t slot = uint32_t(args_[1].toInt32()); + if (slot >= NativeObject::MAX_FIXED_SLOTS) { return AttachDecision::NoAction; } + size_t offset = NativeObject::getFixedSlotOffset(slot); // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'ToString' or 'String' function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. - // Guard that the argument is a string. - ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); - StringOperandId strId = writer.guardToString(argId); + // Guard that the first argument is an object. + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); - // Return the string. - writer.loadStringResult(strId); + // BytecodeEmitter::checkSelfHostedUnsafeGetReservedSlot ensures that the + // slot argument is constant. (At least for direct calls) - // This stub does not need to be monitored, because it always - // returns a string. + switch (native) { + case InlinableNative::IntrinsicUnsafeGetReservedSlot: + writer.loadFixedSlotResult(objId, offset); + break; + case InlinableNative::IntrinsicUnsafeGetObjectFromReservedSlot: + writer.loadFixedSlotTypedResult(objId, offset, ValueType::Object); + break; + case InlinableNative::IntrinsicUnsafeGetInt32FromReservedSlot: + writer.loadFixedSlotTypedResult(objId, offset, ValueType::Int32); + break; + case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot: + writer.loadFixedSlotTypedResult(objId, offset, ValueType::String); + break; + case InlinableNative::IntrinsicUnsafeGetBooleanFromReservedSlot: + writer.loadFixedSlotTypedResult(objId, offset, ValueType::Boolean); + break; + default: + MOZ_CRASH("unexpected native"); + } + + // For simplicity just monitor all stubs. + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("UnsafeGetReservedSlot"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachUnsafeSetReservedSlot( + HandleFunction callee) { + // Self-hosted code calls this with (object, int32, value) arguments. + MOZ_ASSERT(argc_ == 3); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[1].isInt32()); + MOZ_ASSERT(args_[1].toInt32() >= 0); + + uint32_t slot = uint32_t(args_[1].toInt32()); + if (slot >= NativeObject::MAX_FIXED_SLOTS) { + return AttachDecision::NoAction; + } + size_t offset = NativeObject::getFixedSlotOffset(slot); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + // Guard that the first argument is an object. + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + + // BytecodeEmitter::checkSelfHostedUnsafeSetReservedSlot ensures that the + // slot argument is constant. (At least for direct calls) + + // Get the value to set. + ValOperandId valId = writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + + // Set the fixed slot and return undefined. + writer.storeFixedSlotUndefinedResult(objId, offset, valId); + + // This stub always returns undefined. writer.returnFromIC(); cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - if (native == InlinableNative::IntrinsicToString) { - trackAttached("ToString"); - } else { - MOZ_ASSERT(native == InlinableNative::String); - trackAttached("String"); - } + trackAttached("UnsafeSetReservedSlot"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachIsSuspendedGenerator( + HandleFunction callee) { + // The IsSuspendedGenerator intrinsic is only called in + // self-hosted code, so it's safe to assume we have a single + // argument and the callee is our intrinsic. + + MOZ_ASSERT(argc_ == 1); + + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Stack layout here is (bottom to top): + // 2: Callee + // 1: ThisValue + // 0: Arg <-- Top of stack. + // We only care about the argument. + ValOperandId valId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + // Check whether the argument is a suspended generator. + // We don't need guards, because IsSuspendedGenerator returns + // false for values that are not generator objects. + writer.callIsSuspendedGeneratorResult(valId); + writer.returnFromIC(); + + // This stub does not need to be monitored, because it always + // returns Boolean. The stack typeset will be updated when we + // attach the stub. + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("IsSuspendedGenerator"); return AttachDecision::Attach; } AttachDecision CallIRGenerator::tryAttachToObject(HandleFunction callee, InlinableNative native) { + // Self-hosted code calls this with a single argument. + MOZ_ASSERT_IF(native == InlinableNative::IntrinsicToObject, argc_ == 1); + // Need a single object argument. // TODO(Warp): Support all or more conversions to object. // Note: ToObject and Object differ in their behavior for undefined/null. @@ -5117,8 +5885,11 @@ AttachDecision CallIRGenerator::tryAttachToObject(HandleFunction callee, // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'ToObject' or 'Object' function. - emitNativeCalleeGuard(callee); + // Guard callee is the 'Object' function. + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + if (native == InlinableNative::Object) { + emitNativeCalleeGuard(callee); + } // Guard that the argument is an object. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5141,19 +5912,21 @@ AttachDecision CallIRGenerator::tryAttachToObject(HandleFunction callee, } AttachDecision CallIRGenerator::tryAttachToInteger(HandleFunction callee) { + // Self-hosted code calls this with a single argument. + MOZ_ASSERT(argc_ == 1); + // Need a single int32 argument. // TODO(Warp): Support all or more conversions to integer. // Make sure to update this code correctly if we ever start // returning non-int32 integers. - if (argc_ != 1 || !args_[0].isInt32()) { + if (!args_[0].isInt32()) { return AttachDecision::NoAction; } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'ToInteger' intrinsic native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Guard that the argument is an int32. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5172,16 +5945,18 @@ AttachDecision CallIRGenerator::tryAttachToInteger(HandleFunction callee) { } AttachDecision CallIRGenerator::tryAttachToLength(HandleFunction callee) { + // Self-hosted code calls this with a single argument. + MOZ_ASSERT(argc_ == 1); + // Need a single int32 argument. - if (argc_ != 1 || !args_[0].isInt32()) { + if (!args_[0].isInt32()) { return AttachDecision::NoAction; } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'ToLength' intrinsic native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // ToLength(int32) is equivalent to max(int32, 0). ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5201,16 +5976,13 @@ AttachDecision CallIRGenerator::tryAttachToLength(HandleFunction callee) { } AttachDecision CallIRGenerator::tryAttachIsObject(HandleFunction callee) { - // Need a single argument. - if (argc_ != 1) { - return AttachDecision::NoAction; - } + // Self-hosted code calls this with a single argument. + MOZ_ASSERT(argc_ == 1); // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'IsObject' intrinsic native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Type check the argument and return result. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5225,17 +5997,38 @@ AttachDecision CallIRGenerator::tryAttachIsObject(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachIsPackedArray(HandleFunction callee) { + // Self-hosted code calls this with a single object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + // Check if the argument is packed and return result. + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + writer.isPackedArrayResult(objArgId); + + // This stub does not need to be monitored, because it always + // returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("IsPackedArray"); + return AttachDecision::Attach; +} + AttachDecision CallIRGenerator::tryAttachIsCallable(HandleFunction callee) { - // Need a single argument. - if (argc_ != 1) { - return AttachDecision::NoAction; - } + // Self-hosted code calls this with a single argument. + MOZ_ASSERT(argc_ == 1); // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'IsCallable' intrinsic native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Check if the argument is callable and return result. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5251,16 +6044,18 @@ AttachDecision CallIRGenerator::tryAttachIsCallable(HandleFunction callee) { } AttachDecision CallIRGenerator::tryAttachIsConstructor(HandleFunction callee) { + // Self-hosted code calls this with a single argument. + MOZ_ASSERT(argc_ == 1); + // Need a single object argument. - if (argc_ != 1 || !args_[0].isObject()) { + if (!args_[0].isObject()) { return AttachDecision::NoAction; } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'IsConstructor' intrinsic native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Guard that the argument is an object. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5278,13 +6073,40 @@ AttachDecision CallIRGenerator::tryAttachIsConstructor(HandleFunction callee) { return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee, - InlinableNative native) { - // Need a single object argument. - if (argc_ != 1 || !args_[0].isObject()) { +AttachDecision CallIRGenerator::tryAttachIsCrossRealmArrayConstructor( + HandleFunction callee) { + // Self-hosted code calls this with an object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + if (args_[0].toObject().is()) { return AttachDecision::NoAction; } + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(argId); + writer.guardIsNotProxy(objId); + writer.isCrossRealmArrayConstructorResult(objId); + + // This stub does not need to be monitored, it always returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("IsCrossRealmArrayConstructor"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee, + InlinableNative native) { + // Self-hosted code calls this with an object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + // Class must match. const JSClass* clasp = InlinableNativeGuardToClass(native); if (args_[0].toObject().getClass() != clasp) { @@ -5294,8 +6116,7 @@ AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee, // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'GuardToXXX' native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Guard that the argument is an object. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); @@ -5316,21 +6137,30 @@ AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee, } AttachDecision CallIRGenerator::tryAttachHasClass(HandleFunction callee, - const JSClass* clasp) { - // Need a single object argument. - if (argc_ != 1 || !args_[0].isObject()) { + const JSClass* clasp, + bool isPossiblyWrapped) { + // Self-hosted code calls this with an object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Only optimize when the object isn't a proxy. + if (isPossiblyWrapped && IsProxy(&args_[0].toObject())) { return AttachDecision::NoAction; } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'IsXXXObject' native function. - emitNativeCalleeGuard(callee); + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. // Perform the Class check. ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); ObjOperandId objId = writer.guardToObject(argId); + + if (isPossiblyWrapped) { + writer.guardIsNotProxy(objId); + } + writer.hasClassResult(objId, clasp); // Return without type monitoring, because this always returns a boolean. @@ -5343,11 +6173,14 @@ AttachDecision CallIRGenerator::tryAttachHasClass(HandleFunction callee, AttachDecision CallIRGenerator::tryAttachRegExpMatcherSearcherTester( HandleFunction callee, InlinableNative native) { - // Self-hosted code calls this with (object, string, int32) arguments. - if (argc_ != 3) { - return AttachDecision::NoAction; - } - if (!args_[0].isObject() || !args_[1].isString() || !args_[2].isInt32()) { + // Self-hosted code calls this with (object, string, number) arguments. + MOZ_ASSERT(argc_ == 3); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[1].isString()); + MOZ_ASSERT(args_[2].isNumber()); + + // It's not guaranteed that the JITs have typed |lastIndex| as an Int32. + if (!args_[2].isInt32()) { return AttachDecision::NoAction; } @@ -5449,13 +6282,11 @@ AttachDecision CallIRGenerator::tryAttachRegExpInstanceOptimizable( return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachSubstringKernel( +AttachDecision CallIRGenerator::tryAttachGetFirstDollarIndex( HandleFunction callee) { - // Self-hosted code calls this with (string, int32, int32) arguments. - MOZ_ASSERT(argc_ == 3); + // Self-hosted code calls this with a single string argument. + MOZ_ASSERT(argc_ == 1); MOZ_ASSERT(args_[0].isString()); - MOZ_ASSERT(args_[1].isInt32()); - MOZ_ASSERT(args_[2].isInt32()); // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); @@ -5465,30 +6296,260 @@ AttachDecision CallIRGenerator::tryAttachSubstringKernel( ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); StringOperandId strId = writer.guardToString(arg0Id); - ValOperandId arg1Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); - Int32OperandId beginId = writer.guardToInt32(arg1Id); - - ValOperandId arg2Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); - Int32OperandId lengthId = writer.guardToInt32(arg2Id); - - writer.callSubstringKernelResult(strId, beginId, lengthId); + writer.getFirstDollarIndexResult(strId); - // No type monitoring because this always returns a string. + // No type monitoring because this always returns an int32. writer.returnFromIC(); cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - trackAttached("SubstringKernel"); + trackAttached("GetFirstDollarIndex"); return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachStringChar(HandleFunction callee, - StringChar kind) { +AttachDecision CallIRGenerator::tryAttachSubstringKernel( + HandleFunction callee) { + // Self-hosted code calls this with (string, int32, int32) arguments. + MOZ_ASSERT(argc_ == 3); + MOZ_ASSERT(args_[0].isString()); + MOZ_ASSERT(args_[1].isInt32()); + MOZ_ASSERT(args_[2].isInt32()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + StringOperandId strId = writer.guardToString(arg0Id); + + ValOperandId arg1Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + Int32OperandId beginId = writer.guardToInt32(arg1Id); + + ValOperandId arg2Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + Int32OperandId lengthId = writer.guardToInt32(arg2Id); + + writer.callSubstringKernelResult(strId, beginId, lengthId); + + // No type monitoring because this always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("SubstringKernel"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachObjectHasPrototype( + HandleFunction callee) { + // Self-hosted code calls this with (object, object) arguments. + MOZ_ASSERT(argc_ == 2); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[1].isObject()); + + auto* obj = &args_[0].toObject().as(); + auto* proto = &args_[1].toObject().as(); + + // Only attach when obj.__proto__ is proto. + if (obj->staticPrototype() != proto) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + + writer.guardProto(objId, proto); + writer.loadBooleanResult(true); + + // No type monitoring because this always returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("ObjectHasPrototype"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachString(HandleFunction callee) { + // Need a single string argument. + // TODO(Warp): Support all or more conversions to strings. + if (argc_ != 1 || !args_[0].isString()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'String' function. + emitNativeCalleeGuard(callee); + + // Guard that the argument is a string. + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + StringOperandId strId = writer.guardToString(argId); + + // Return the string. + writer.loadStringResult(strId); + + // This stub does not need to be monitored, because it always + // returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("String"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachStringConstructor( + HandleFunction callee) { + // Need a single string argument. + // TODO(Warp): Support all or more conversions to strings. + if (argc_ != 1 || !args_[0].isString()) { + return AttachDecision::NoAction; + } + + RootedString emptyString(cx_, cx_->runtime()->emptyString); + JSObject* templateObj = StringObject::create( + cx_, emptyString, /* proto = */ nullptr, TenuredObject); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'String' function. + emitNativeCalleeGuard(callee); + + CallFlags flags(IsConstructPC(pc_), IsSpreadPC(pc_)); + + // Guard that the argument is a string. + ValOperandId argId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_, flags); + StringOperandId strId = writer.guardToString(argId); + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + + writer.newStringObjectResult(templateObj, strId); + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("StringConstructor"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachStringToStringValueOf( + HandleFunction callee) { + // Expecting no arguments. + if (argc_ != 0) { + return AttachDecision::NoAction; + } + + // Ensure |this| is a primitive string value. + if (!thisval_.isString()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'toString' OR 'valueOf' native function. + emitNativeCalleeGuard(callee); + + // Guard |this| is a string. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + StringOperandId strId = writer.guardToString(thisValId); + + // Return the string + writer.loadStringResult(strId); + + // This stub doesn't need to be monitored, because it always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("StringToStringValueOf"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachStringReplaceString( + HandleFunction callee) { + // Self-hosted code calls this with (string, string, string) arguments. + MOZ_ASSERT(argc_ == 3); + MOZ_ASSERT(args_[0].isString()); + MOZ_ASSERT(args_[1].isString()); + MOZ_ASSERT(args_[2].isString()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + StringOperandId strId = writer.guardToString(arg0Id); + + ValOperandId arg1Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + StringOperandId patternId = writer.guardToString(arg1Id); + + ValOperandId arg2Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + StringOperandId replacementId = writer.guardToString(arg2Id); + + writer.stringReplaceStringResult(strId, patternId, replacementId); + + // No type monitoring because this always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("StringReplaceString"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachStringSplitString( + HandleFunction callee) { + // Self-hosted code calls this with (string, string) arguments. + MOZ_ASSERT(argc_ == 2); + MOZ_ASSERT(args_[0].isString()); + MOZ_ASSERT(args_[1].isString()); + + ObjectGroup* group = ObjectGroupRealm::getStringSplitStringGroup(cx_); + if (!group) { + cx_->clearPendingException(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + StringOperandId strId = writer.guardToString(arg0Id); + + ValOperandId arg1Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + StringOperandId separatorId = writer.guardToString(arg1Id); + + writer.stringSplitStringResult(strId, separatorId, group); + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("StringSplitString"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachStringChar(HandleFunction callee, + StringChar kind) { // Need one argument. if (argc_ != 1) { return AttachDecision::NoAction; } - if (!CanAttachStringChar(thisval_, args_[0], kind)) { + if (!CanAttachStringChar(thisval_, args_[0])) { return AttachDecision::NoAction; } @@ -5569,90 +6630,301 @@ AttachDecision CallIRGenerator::tryAttachStringFromCharCode( return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachMathRandom(HandleFunction callee) { - // Expecting no arguments. - if (argc_ != 0) { +AttachDecision CallIRGenerator::tryAttachStringFromCodePoint( + HandleFunction callee) { + // Need one int32 argument. + if (argc_ != 1 || !args_[0].isInt32()) { return AttachDecision::NoAction; } - MOZ_ASSERT(cx_->realm() == callee->realm(), - "Shouldn't inline cross-realm Math.random because per-realm RNG"); + // String.fromCodePoint throws for invalid code points. + int32_t codePoint = args_[0].toInt32(); + if (codePoint < 0 || codePoint > int32_t(unicode::NonBMPMax)) { + return AttachDecision::NoAction; + } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'random' native function. + // Guard callee is the 'fromCodePoint' native function. emitNativeCalleeGuard(callee); - mozilla::non_crypto::XorShift128PlusRNG* rng = - &cx_->realm()->getOrCreateRandomNumberGenerator(); - writer.mathRandomResult(rng); + // Guard int32 argument. + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + Int32OperandId codeId = writer.guardToInt32(argId); + // Return string created from code point. + writer.stringFromCodePointResult(codeId); + + // This stub doesn't need to be monitored, because it always returns a string. writer.returnFromIC(); cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - trackAttached("MathRandom"); + trackAttached("StringFromCodePoint"); return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachMathAbs(HandleFunction callee) { - // Need one argument. - if (argc_ != 1) { +AttachDecision CallIRGenerator::tryAttachStringToLowerCase( + HandleFunction callee) { + // Expecting no arguments. + if (argc_ != 0) { return AttachDecision::NoAction; } - if (!args_[0].isNumber()) { + // Ensure |this| is a primitive string value. + if (!thisval_.isString()) { return AttachDecision::NoAction; } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'abs' native function. + // Guard callee is the 'toLowerCase' native function. emitNativeCalleeGuard(callee); - ValOperandId argumentId = - writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + // Guard this is a string. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + StringOperandId strId = writer.guardToString(thisValId); - // abs(INT_MIN) is a double. - if (args_[0].isInt32() && args_[0].toInt32() != INT_MIN) { - Int32OperandId int32Id = writer.guardToInt32(argumentId); - writer.mathAbsInt32Result(int32Id); - } else { - NumberOperandId numberId = writer.guardIsNumber(argumentId); - writer.mathAbsNumberResult(numberId); - } + // Return string converted to lower-case. + writer.stringToLowerCaseResult(strId); - // The INT_MIN case and implementation details of the C++ abs - // make this a bit tricky. We probably can just remove monitoring - // in the future completely, so do the easy thing right now. - writer.typeMonitorResult(); - cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + // This stub doesn't need to be monitored, because it always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - trackAttached("MathAbs"); + trackAttached("StringToLowerCase"); return AttachDecision::Attach; } -AttachDecision CallIRGenerator::tryAttachMathFloor(HandleFunction callee) { - // Need one (number) argument. - if (argc_ != 1 || !args_[0].isNumber()) { +AttachDecision CallIRGenerator::tryAttachStringToUpperCase( + HandleFunction callee) { + // Expecting no arguments. + if (argc_ != 0) { return AttachDecision::NoAction; } - // Check if the result fits in int32. - double res = math_floor_impl(args_[0].toNumber()); - int32_t unused; - bool resultIsInt32 = mozilla::NumberIsInt32(res, &unused); + // Ensure |this| is a primitive string value. + if (!thisval_.isString()) { + return AttachDecision::NoAction; + } // Initialize the input operand. Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard callee is the 'floor' native function. + // Guard callee is the 'toUpperCase' native function. emitNativeCalleeGuard(callee); - ValOperandId argumentId = - writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); - NumberOperandId numberId = writer.guardIsNumber(argumentId); + // Guard this is a string. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + StringOperandId strId = writer.guardToString(thisValId); + + // Return string converted to upper-case. + writer.stringToUpperCaseResult(strId); + + // This stub doesn't need to be monitored, because it always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("StringToUpperCase"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathRandom(HandleFunction callee) { + // Expecting no arguments. + if (argc_ != 0) { + return AttachDecision::NoAction; + } + + MOZ_ASSERT(cx_->realm() == callee->realm(), + "Shouldn't inline cross-realm Math.random because per-realm RNG"); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'random' native function. + emitNativeCalleeGuard(callee); + + mozilla::non_crypto::XorShift128PlusRNG* rng = + &cx_->realm()->getOrCreateRandomNumberGenerator(); + writer.mathRandomResult(rng); + + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathRandom"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathAbs(HandleFunction callee) { + // Need one argument. + if (argc_ != 1) { + return AttachDecision::NoAction; + } + + if (!args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'abs' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + // abs(INT_MIN) is a double. + if (args_[0].isInt32() && args_[0].toInt32() != INT_MIN) { + Int32OperandId int32Id = writer.guardToInt32(argumentId); + writer.mathAbsInt32Result(int32Id); + } else { + NumberOperandId numberId = writer.guardIsNumber(argumentId); + writer.mathAbsNumberResult(numberId); + } + + // The INT_MIN case and implementation details of the C++ abs + // make this a bit tricky. We probably can just remove monitoring + // in the future completely, so do the easy thing right now. + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("MathAbs"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathClz32(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'clz32' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + Int32OperandId int32Id; + if (args_[0].isInt32()) { + int32Id = writer.guardToInt32(argId); + } else { + MOZ_ASSERT(args_[0].isDouble()); + NumberOperandId numId = writer.guardIsNumber(argId); + int32Id = writer.truncateDoubleToUInt32(numId); + } + writer.mathClz32Result(int32Id); + + // Math.clz32 always returns an int32 so we don't need type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathClz32"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathSign(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'sign' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + if (args_[0].isInt32()) { + Int32OperandId int32Id = writer.guardToInt32(argId); + writer.mathSignInt32Result(int32Id); + } else { + // Math.sign returns a double only if the input is -0 or NaN so try to + // optimize the common Number => Int32 case. + double d = math_sign_impl(args_[0].toDouble()); + int32_t unused; + bool resultIsInt32 = mozilla::NumberIsInt32(d, &unused); + + NumberOperandId numId = writer.guardIsNumber(argId); + if (resultIsInt32) { + writer.mathSignNumberToInt32Result(numId); + } else { + writer.mathSignNumberResult(numId); + } + } + + // The stub's return type matches the current return value so we don't need + // type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathSign"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathImul(HandleFunction callee) { + // Need two (number) arguments. + if (argc_ != 2 || !args_[0].isNumber() || !args_[1].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'imul' native function. + emitNativeCalleeGuard(callee); + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ValOperandId arg1Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + + Int32OperandId int32Arg0Id, int32Arg1Id; + if (args_[0].isInt32() && args_[1].isInt32()) { + int32Arg0Id = writer.guardToInt32(arg0Id); + int32Arg1Id = writer.guardToInt32(arg1Id); + } else { + // Treat both arguments as numbers if at least one of them is non-int32. + NumberOperandId numArg0Id = writer.guardIsNumber(arg0Id); + NumberOperandId numArg1Id = writer.guardIsNumber(arg1Id); + int32Arg0Id = writer.truncateDoubleToUInt32(numArg0Id); + int32Arg1Id = writer.truncateDoubleToUInt32(numArg1Id); + } + writer.mathImulResult(int32Arg0Id, int32Arg1Id); + + // Math.imul always returns int32 so we don't need type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathImul"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachMathFloor(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Check if the result fits in int32. + double res = math_floor_impl(args_[0].toNumber()); + int32_t unused; + bool resultIsInt32 = mozilla::NumberIsInt32(res, &unused); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'floor' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + NumberOperandId numberId = writer.guardIsNumber(argumentId); if (resultIsInt32) { writer.mathFloorToInt32Result(numberId); @@ -5701,6 +6973,40 @@ AttachDecision CallIRGenerator::tryAttachMathCeil(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachMathTrunc(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Check if the result fits in int32. + double res = math_trunc_impl(args_[0].toNumber()); + int32_t unused; + bool resultIsInt32 = mozilla::NumberIsInt32(res, &unused); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'trunc' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + NumberOperandId numberId = writer.guardIsNumber(argumentId); + + if (resultIsInt32) { + writer.mathTruncToInt32Result(numberId); + } else { + writer.mathFunctionNumberResult(numberId, UnaryMathFunction::Trunc); + } + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("MathTrunc"); + return AttachDecision::Attach; +} + AttachDecision CallIRGenerator::tryAttachMathRound(HandleFunction callee) { // Need one (number) argument. if (argc_ != 1 || !args_[0].isNumber()) { @@ -5736,12 +7042,8 @@ AttachDecision CallIRGenerator::tryAttachMathRound(HandleFunction callee) { } AttachDecision CallIRGenerator::tryAttachMathSqrt(HandleFunction callee) { - // Need one argument. - if (argc_ != 1) { - return AttachDecision::NoAction; - } - - if (!args_[0].isNumber()) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { return AttachDecision::NoAction; } @@ -5764,6 +7066,31 @@ AttachDecision CallIRGenerator::tryAttachMathSqrt(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachMathFRound(HandleFunction callee) { + // Need one (number) argument. + if (argc_ != 1 || !args_[0].isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'fround' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + NumberOperandId numberId = writer.guardIsNumber(argumentId); + writer.mathFRoundNumberResult(numberId); + + // Math.fround always returns a double so we don't need type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathFRound"); + return AttachDecision::Attach; +} + static bool CanAttachInt32Pow(const Value& baseVal, const Value& powerVal) { MOZ_ASSERT(baseVal.isInt32() || baseVal.isBoolean()); MOZ_ASSERT(powerVal.isInt32() || powerVal.isBoolean()); @@ -5820,6 +7147,64 @@ AttachDecision CallIRGenerator::tryAttachMathPow(HandleFunction callee) { return AttachDecision::Attach; } +AttachDecision CallIRGenerator::tryAttachMathHypot(HandleFunction callee) { + // Only optimize if there are 2-4 arguments. + if (argc_ < 2 || argc_ > 4) { + return AttachDecision::NoAction; + } + + for (size_t i = 0; i < argc_; i++) { + if (!args_[i].isNumber()) { + return AttachDecision::NoAction; + } + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'hypot' native function. + emitNativeCalleeGuard(callee); + + ValOperandId firstId = writer.loadStandardCallArgument(0, argc_); + ValOperandId secondId = writer.loadStandardCallArgument(1, argc_); + + NumberOperandId firstNumId = writer.guardIsNumber(firstId); + NumberOperandId secondNumId = writer.guardIsNumber(secondId); + + ValOperandId thirdId; + ValOperandId fourthId; + NumberOperandId thirdNumId; + NumberOperandId fourthNumId; + + switch (argc_) { + case 2: + writer.mathHypot2NumberResult(firstNumId, secondNumId); + break; + case 3: + thirdId = writer.loadStandardCallArgument(2, argc_); + thirdNumId = writer.guardIsNumber(thirdId); + writer.mathHypot3NumberResult(firstNumId, secondNumId, thirdNumId); + break; + case 4: + thirdId = writer.loadStandardCallArgument(2, argc_); + fourthId = writer.loadStandardCallArgument(3, argc_); + thirdNumId = writer.guardIsNumber(thirdId); + fourthNumId = writer.guardIsNumber(fourthId); + writer.mathHypot4NumberResult(firstNumId, secondNumId, thirdNumId, + fourthNumId); + break; + default: + MOZ_CRASH("Unexpected number of arguments to hypot function."); + } + + // Math.hypot always returns a double so we don't need type monitoring. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("MathHypot"); + return AttachDecision::Attach; +} + AttachDecision CallIRGenerator::tryAttachMathATan2(HandleFunction callee) { // Requires two numbers as arguments. if (argc_ != 2 || !args_[0].isNumber() || !args_[1].isNumber()) { @@ -5925,82 +7310,1449 @@ AttachDecision CallIRGenerator::tryAttachMathFunction(HandleFunction callee, writer.returnFromIC(); cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; - trackAttached("MathFunction"); - return AttachDecision::Attach; -} + trackAttached("MathFunction"); + return AttachDecision::Attach; +} + +StringOperandId EmitToStringGuard(CacheIRWriter& writer, ValOperandId id, + HandleValue v) { + if (v.isString()) { + return writer.guardToString(id); + } + if (v.isInt32()) { + Int32OperandId intId = writer.guardToInt32(id); + return writer.callInt32ToString(intId); + } + // At this point we are creating an IC that will handle + // both Int32 and Double cases. + MOZ_ASSERT(v.isNumber()); + NumberOperandId numId = writer.guardIsNumber(id); + return writer.callNumberToString(numId); +} + +AttachDecision CallIRGenerator::tryAttachNumberToString(HandleFunction callee) { + // Expecting no arguments, which means base 10. + if (argc_ != 0) { + return AttachDecision::NoAction; + } + + // Ensure |this| is a primitive number value. + if (!thisval_.isNumber()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'toString' native function. + emitNativeCalleeGuard(callee); + + // Initialize the |this| operand. + ValOperandId thisValId = + writer.loadArgumentFixedSlot(ArgumentKind::This, argc_); + + // Guard on number and convert to string. + StringOperandId strId = EmitToStringGuard(writer, thisValId, thisval_); + + // Return the string. + writer.loadStringResult(strId); + + // This stub doesn't need to be monitored, because it always returns a string. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("NumberToString"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachReflectGetPrototypeOf( + HandleFunction callee) { + // Need one argument. + if (argc_ != 1) { + return AttachDecision::NoAction; + } + + if (!args_[0].isObject()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'getPrototypeOf' native function. + emitNativeCalleeGuard(callee); + + ValOperandId argumentId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(argumentId); + + writer.reflectGetPrototypeOfResult(objId); + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("ReflectGetPrototypeOf"); + return AttachDecision::Attach; +} + +static bool AtomicsMeetsPreconditions(TypedArrayObject* typedArray, + double index) { + switch (typedArray->type()) { + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Int16: + case Scalar::Uint16: + case Scalar::Int32: + case Scalar::Uint32: + break; + + case Scalar::BigInt64: + case Scalar::BigUint64: + // Bug 1638295: Not yet implemented. + return false; + + case Scalar::Float32: + case Scalar::Float64: + case Scalar::Uint8Clamped: + // Exclude floating types and Uint8Clamped. + return false; + + case Scalar::MaxTypedArrayViewType: + case Scalar::Int64: +// case Scalar::Simd128: + MOZ_CRASH("Unsupported TypedArray type"); + } + + // Bounds check the index argument. + int32_t indexInt32; + if (!mozilla::NumberEqualsInt32(index, &indexInt32)) { + return false; + } + if (indexInt32 < 0 || uint32_t(indexInt32) >= typedArray->length()) { + return false; + } + + return true; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsCompareExchange( + HandleFunction callee) { + if (!JitSupportsAtomics()) { + return AttachDecision::NoAction; + } + + // Need four arguments. + if (argc_ != 4) { + return AttachDecision::NoAction; + } + + // Arguments: typedArray, index (number), expected, replacement. + if (!args_[0].isObject() || !args_[0].toObject().is()) { + return AttachDecision::NoAction; + } + if (!args_[1].isNumber()) { + return AttachDecision::NoAction; + } + if (!args_[2].isNumber()) { + return AttachDecision::NoAction; + } + if (!args_[3].isNumber()) { + return AttachDecision::NoAction; + } + + auto* typedArray = &args_[0].toObject().as(); + if (!AtomicsMeetsPreconditions(typedArray, args_[1].toNumber())) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `compareExchange` native function. + emitNativeCalleeGuard(callee); + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + writer.guardShapeForClass(objId, typedArray->shape()); + + // Convert index to int32. + ValOperandId indexId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + Int32OperandId int32IndexId = writer.guardToInt32Index(indexId); + + // Convert expected value to int32. + ValOperandId expectedId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + Int32OperandId int32ExpectedId = writer.guardToInt32ModUint32(expectedId); + + // Convert replacement value to int32. + ValOperandId replacementId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg3, argc_); + Int32OperandId int32ReplacementId = + writer.guardToInt32ModUint32(replacementId); + + writer.atomicsCompareExchangeResult(objId, int32IndexId, int32ExpectedId, + int32ReplacementId, typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsCompareExchange"); + return AttachDecision::Attach; +} + +bool CallIRGenerator::canAttachAtomicsReadWriteModify() { + if (!JitSupportsAtomics()) { + return false; + } + + // Need three arguments. + if (argc_ != 3) { + return false; + } + + // Arguments: typedArray, index (number), value. + if (!args_[0].isObject() || !args_[0].toObject().is()) { + return false; + } + if (!args_[1].isNumber()) { + return false; + } + if (!args_[2].isNumber()) { + return false; + } + + auto* typedArray = &args_[0].toObject().as(); + if (!AtomicsMeetsPreconditions(typedArray, args_[1].toNumber())) { + return false; + } + + return true; +} + +CallIRGenerator::AtomicsReadWriteModifyOperands +CallIRGenerator::emitAtomicsReadWriteModifyOperands(HandleFunction callee) { + MOZ_ASSERT(canAttachAtomicsReadWriteModify()); + + auto* typedArray = &args_[0].toObject().as(); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is this Atomics function. + emitNativeCalleeGuard(callee); + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + writer.guardShapeForClass(objId, typedArray->shape()); + + // Convert index to int32. + ValOperandId indexId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + Int32OperandId int32IndexId = writer.guardToInt32Index(indexId); + + // Convert value to int32. + ValOperandId valueId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + Int32OperandId int32ValueId = writer.guardToInt32ModUint32(valueId); + + return {objId, int32IndexId, int32ValueId}; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsExchange( + HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsExchangeResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsExchange"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsAdd(HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsAddResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsAdd"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsSub(HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsSubResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsSub"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsAnd(HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsAndResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsAnd"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsOr(HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsOrResult(objId, int32IndexId, int32ValueId, typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsOr"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsXor(HandleFunction callee) { + if (!canAttachAtomicsReadWriteModify()) { + return AttachDecision::NoAction; + } + + auto [objId, int32IndexId, int32ValueId] = + emitAtomicsReadWriteModifyOperands(callee); + + auto* typedArray = &args_[0].toObject().as(); + + writer.atomicsXorResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsXor"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsLoad(HandleFunction callee) { + if (!JitSupportsAtomics()) { + return AttachDecision::NoAction; + } + + // Need two arguments. + if (argc_ != 2) { + return AttachDecision::NoAction; + } + + // Arguments: typedArray, index (number). + if (!args_[0].isObject() || !args_[0].toObject().is()) { + return AttachDecision::NoAction; + } + if (!args_[1].isNumber()) { + return AttachDecision::NoAction; + } + + auto* typedArray = &args_[0].toObject().as(); + if (!AtomicsMeetsPreconditions(typedArray, args_[1].toNumber())) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `load` native function. + emitNativeCalleeGuard(callee); + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + writer.guardShapeForClass(objId, typedArray->shape()); + + // Convert index to int32. + ValOperandId indexId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + Int32OperandId int32IndexId = writer.guardToInt32Index(indexId); + + writer.atomicsLoadResult(objId, int32IndexId, typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or, for uint32, a double. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsLoad"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsStore(HandleFunction callee) { + if (!JitSupportsAtomics()) { + return AttachDecision::NoAction; + } + + // Need three arguments. + if (argc_ != 3) { + return AttachDecision::NoAction; + } + + // Atomics.store() is annoying because it returns the result of converting the + // value by ToInteger(), not the input value, nor the result of converting the + // value by ToInt32(). It is especially annoying because almost nobody uses + // the result value. + // + // As an expedient compromise, therefore, we inline only if the result is + // obviously unused or if the argument is already Int32 and thus requires no + // conversion. + + // Arguments: typedArray, index (number), value. + if (!args_[0].isObject() || !args_[0].toObject().is()) { + return AttachDecision::NoAction; + } + if (!args_[1].isNumber()) { + return AttachDecision::NoAction; + } + if (op_ == JSOp::CallIgnoresRv ? !args_[2].isNumber() : !args_[2].isInt32()) { + return AttachDecision::NoAction; + } + + auto* typedArray = &args_[0].toObject().as(); + if (!AtomicsMeetsPreconditions(typedArray, args_[1].toNumber())) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `store` native function. + emitNativeCalleeGuard(callee); + + ValOperandId arg0Id = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objId = writer.guardToObject(arg0Id); + writer.guardShapeForClass(objId, typedArray->shape()); + + // Convert index to int32. + ValOperandId indexId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + Int32OperandId int32IndexId = writer.guardToInt32Index(indexId); + + // Ensure value is int32. + ValOperandId valueId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + Int32OperandId int32ValueId; + if (op_ == JSOp::CallIgnoresRv) { + int32ValueId = writer.guardToInt32ModUint32(valueId); + } else { + int32ValueId = writer.guardToInt32(valueId); + } + + writer.atomicsStoreResult(objId, int32IndexId, int32ValueId, + typedArray->type()); + + // This stub doesn't need to be monitored, because it always returns an int32 + // or the result is not observed. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsStore"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAtomicsIsLockFree( + HandleFunction callee) { + // Need one argument. + if (argc_ != 1) { + return AttachDecision::NoAction; + } + + if (!args_[0].isInt32()) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `isLockFree` native function. + emitNativeCalleeGuard(callee); + + // Ensure value is int32. + ValOperandId valueId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + Int32OperandId int32ValueId = writer.guardToInt32(valueId); + + writer.atomicsIsLockFreeResult(int32ValueId); + + // This stub doesn't need to be monitored, because it always returns a bool. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AtomicsIsLockFree"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachBoolean(HandleFunction callee) { + // Need zero or one argument. + if (argc_ > 1) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'Boolean' native function. + emitNativeCalleeGuard(callee); + + if (argc_ == 0) { + writer.loadBooleanResult(false); + } else { + ValOperandId valId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + writer.loadValueTruthyResult(valId); + } + + // This stub doesn't need to be monitored, because it always returns a bool. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("Boolean"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachBailout(HandleFunction callee) { + // Expecting no arguments. + if (argc_ != 0) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'bailout' native function. + emitNativeCalleeGuard(callee); + + writer.bailout(); + writer.loadUndefinedResult(); + + // This stub doesn't need to be monitored, it always returns undefined. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("Bailout"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAssertFloat32(HandleFunction callee) { + // Expecting two arguments. + if (argc_ != 2) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'assertFloat32' native function. + emitNativeCalleeGuard(callee); + + // TODO: Warp doesn't yet optimize Float32 (bug 1655773). + + // NOP when not in IonMonkey. + writer.loadUndefinedResult(); + + // This stub doesn't need to be monitored, it always returns undefined. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AssertFloat32"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachAssertRecoveredOnBailout( + HandleFunction callee) { + // Expecting two arguments. + if (argc_ != 2) { + return AttachDecision::NoAction; + } + + // (Fuzzing unsafe) testing function which must be called with a constant + // boolean as its second argument. + bool mustBeRecovered = args_[1].toBoolean(); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'assertRecoveredOnBailout' native function. + emitNativeCalleeGuard(callee); + + ValOperandId valId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + writer.assertRecoveredOnBailoutResult(valId, mustBeRecovered); + + // This stub doesn't need to be monitored, it always returns undefined. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("AssertRecoveredOnBailout"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachObjectIs(HandleFunction callee) { + // Need two arguments. + if (argc_ != 2) { + return AttachDecision::NoAction; + } + + // TODO(Warp): attach this stub just once to prevent slowdowns for polymorphic + // calls. + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `is` native function. + emitNativeCalleeGuard(callee); + + ValOperandId lhsId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ValOperandId rhsId = writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + + HandleValue lhs = args_[0]; + HandleValue rhs = args_[1]; + + if (lhs.isNumber() && rhs.isNumber() && !(lhs.isInt32() && rhs.isInt32())) { + NumberOperandId lhsNumId = writer.guardIsNumber(lhsId); + NumberOperandId rhsNumId = writer.guardIsNumber(rhsId); + writer.compareDoubleSameValueResult(lhsNumId, rhsNumId); + } else if (!SameType(lhs, rhs)) { + // Compare tags for strictly different types. + ValueTagOperandId lhsTypeId = writer.loadValueTag(lhsId); + ValueTagOperandId rhsTypeId = writer.loadValueTag(rhsId); + writer.guardTagNotEqual(lhsTypeId, rhsTypeId); + writer.loadBooleanResult(false); + } else { + MOZ_ASSERT(lhs.type() == rhs.type()); + MOZ_ASSERT(lhs.type() != JS::ValueType::Double); + + switch (lhs.type()) { + case JS::ValueType::Int32: { + Int32OperandId lhsIntId = writer.guardToInt32(lhsId); + Int32OperandId rhsIntId = writer.guardToInt32(rhsId); + writer.compareInt32Result(JSOp::StrictEq, lhsIntId, rhsIntId); + break; + } + case JS::ValueType::Boolean: { + Int32OperandId lhsIntId = writer.guardBooleanToInt32(lhsId); + Int32OperandId rhsIntId = writer.guardBooleanToInt32(rhsId); + writer.compareInt32Result(JSOp::StrictEq, lhsIntId, rhsIntId); + break; + } + case JS::ValueType::Undefined: { + writer.guardIsUndefined(lhsId); + writer.guardIsUndefined(rhsId); + writer.loadBooleanResult(true); + break; + } + case JS::ValueType::Null: { + writer.guardIsNull(lhsId); + writer.guardIsNull(rhsId); + writer.loadBooleanResult(true); + break; + } + case JS::ValueType::String: { + StringOperandId lhsStrId = writer.guardToString(lhsId); + StringOperandId rhsStrId = writer.guardToString(rhsId); + writer.compareStringResult(JSOp::StrictEq, lhsStrId, rhsStrId); + break; + } + case JS::ValueType::Symbol: { + SymbolOperandId lhsSymId = writer.guardToSymbol(lhsId); + SymbolOperandId rhsSymId = writer.guardToSymbol(rhsId); + writer.compareSymbolResult(JSOp::StrictEq, lhsSymId, rhsSymId); + break; + } + case JS::ValueType::BigInt: { + BigIntOperandId lhsBigIntId = writer.guardToBigInt(lhsId); + BigIntOperandId rhsBigIntId = writer.guardToBigInt(rhsId); + writer.compareBigIntResult(JSOp::StrictEq, lhsBigIntId, rhsBigIntId); + break; + } + case JS::ValueType::Object: { + ObjOperandId lhsObjId = writer.guardToObject(lhsId); + ObjOperandId rhsObjId = writer.guardToObject(rhsId); + writer.compareObjectResult(JSOp::StrictEq, lhsObjId, rhsObjId); + break; + } + + case JS::ValueType::Double: + case JS::ValueType::Magic: + case JS::ValueType::PrivateGCThing: + MOZ_CRASH("Unexpected type"); + } + } + + // This stub does not need to be monitored, because it always returns a + // boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("ObjectIs"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachObjectIsPrototypeOf( + HandleFunction callee) { + // Ensure |this| is an object. + if (!thisval_.isObject()) { + return AttachDecision::NoAction; + } + + // Need a single argument. + if (argc_ != 1) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the `isPrototypeOf` native function. + emitNativeCalleeGuard(callee); + + // Guard that |this| is an object. + ValOperandId thisValId = + writer.loadArgumentDynamicSlot(ArgumentKind::This, argcId); + ObjOperandId thisObjId = writer.guardToObject(thisValId); + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + + writer.loadInstanceOfObjectResult(argId, thisObjId); + + // This stub does not need to be monitored, because it always returns a + // boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("ObjectIsPrototypeOf"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachFunCall(HandleFunction callee) { + if (!callee->isNativeWithoutJitEntry() || callee->native() != fun_call) { + return AttachDecision::NoAction; + } + + if (!thisval_.isObject() || !thisval_.toObject().is()) { + return AttachDecision::NoAction; + } + RootedFunction target(cx_, &thisval_.toObject().as()); + + bool isScripted = target->hasJitEntry(); + MOZ_ASSERT_IF(!isScripted, target->isNativeWithoutJitEntry()); + + if (target->isClassConstructor()) { + return AttachDecision::NoAction; + } + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard that callee is the |fun_call| native function. + ValOperandId calleeValId = + writer.loadArgumentDynamicSlot(ArgumentKind::Callee, argcId); + ObjOperandId calleeObjId = writer.guardToObject(calleeValId); + writer.guardSpecificFunction(calleeObjId, callee); + + // Guard that |this| is an object. + ValOperandId thisValId = + writer.loadArgumentDynamicSlot(ArgumentKind::This, argcId); + ObjOperandId thisObjId = writer.guardToObject(thisValId); + + if (mode_ == ICState::Mode::Specialized) { + // Ensure that |this| is the expected target function. + emitCalleeGuard(thisObjId, target); + + CallFlags targetFlags(CallFlags::FunCall); + if (isScripted) { + writer.callScriptedFunction(thisObjId, argcId, targetFlags); + } else { + writer.callNativeFunction(thisObjId, argcId, op_, target, targetFlags); + } + } else { + // Guard that |this| is a function. + writer.guardClass(thisObjId, GuardClassKind::JSFunction); + + // Guard that function is not a class constructor. + writer.guardNotClassConstructor(thisObjId); + + CallFlags targetFlags(CallFlags::FunCall); + if (isScripted) { + writer.guardFunctionHasJitEntry(thisObjId, /*isConstructing =*/false); + writer.callScriptedFunction(thisObjId, argcId, targetFlags); + } else { + writer.guardFunctionHasNoJitEntry(thisObjId); + writer.callAnyNativeFunction(thisObjId, argcId, targetFlags); + } + } + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + if (isScripted) { + trackAttached("Scripted fun_call"); + } else { + trackAttached("Native fun_call"); + } + + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachIsTypedArray(HandleFunction callee, + bool isPossiblyWrapped) { + // Self-hosted code calls this with a single object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + writer.isTypedArrayResult(objArgId, isPossiblyWrapped); + + // This stub does not need to be monitored because it always returns a bool. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached(isPossiblyWrapped ? "IsPossiblyWrappedTypedArray" + : "IsTypedArray"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachIsTypedArrayConstructor( + HandleFunction callee) { + // Self-hosted code calls this with a single object argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + writer.isTypedArrayConstructorResult(objArgId); + + // This stub does not need to be monitored because it always returns a bool. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("IsTypedArrayConstructor"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachTypedArrayByteOffset( + HandleFunction callee) { + // Self-hosted code calls this with a single TypedArrayObject argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[0].toObject().is()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + writer.typedArrayByteOffsetResult(objArgId); + + // This stub does not need to be monitored because it always returns int32. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("TypedArrayByteOffset"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachTypedArrayElementShift( + HandleFunction callee) { + // Self-hosted code calls this with a single TypedArrayObject argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + MOZ_ASSERT(args_[0].toObject().is()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + writer.typedArrayElementShiftResult(objArgId); + + // This stub does not need to be monitored because it always returns int32. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("TypedArrayElementShift"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachTypedArrayLength( + HandleFunction callee, bool isPossiblyWrapped) { + // Self-hosted code calls this with a single, possibly wrapped, + // TypedArrayObject argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Only optimize when the object isn't a wrapper. + if (isPossiblyWrapped && IsWrapper(&args_[0].toObject())) { + return AttachDecision::NoAction; + } + + MOZ_ASSERT(args_[0].toObject().is()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + + if (isPossiblyWrapped) { + writer.guardIsNotProxy(objArgId); + } + + // Note: the "getter" argument is a hint for IonBuilder. Just pass |callee|, + // the field isn't used for this intrinsic call. + writer.loadTypedArrayLengthResult(objArgId, callee); + + // This stub does not need to be monitored because it always returns int32. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("TypedArrayLength"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachArrayBufferByteLength( + HandleFunction callee, bool isPossiblyWrapped) { + // Self-hosted code calls this with a single, possibly wrapped, + // ArrayBufferObject argument. + MOZ_ASSERT(argc_ == 1); + MOZ_ASSERT(args_[0].isObject()); + + // Only optimize when the object isn't a wrapper. + if (isPossiblyWrapped && IsWrapper(&args_[0].toObject())) { + return AttachDecision::NoAction; + } + + MOZ_ASSERT(args_[0].toObject().is()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objArgId = writer.guardToObject(argId); + + if (isPossiblyWrapped) { + writer.guardIsNotProxy(objArgId); + } + + size_t offset = + NativeObject::getFixedSlotOffset(ArrayBufferObject::BYTE_LENGTH_SLOT); + + writer.loadFixedSlotTypedResult(objArgId, offset, ValueType::Int32); + + // This stub does not need to be monitored because it always returns int32. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("ArrayBufferByteLength"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachIsConstructing(HandleFunction callee) { + // Self-hosted code calls this with no arguments in function scripts. + MOZ_ASSERT(argc_ == 0); + MOZ_ASSERT(script_->isFunction()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + writer.frameIsConstructingResult(); + + // This stub does not need to be monitored, it always returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("IsConstructing"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachGetNextMapSetEntryForIterator( + HandleFunction callee, bool isMap) { + // Self-hosted code calls this with two objects. + MOZ_ASSERT(argc_ == 2); + if (isMap) { + MOZ_ASSERT(args_[0].toObject().is()); + } else { + MOZ_ASSERT(args_[0].toObject().is()); + } + MOZ_ASSERT(args_[1].toObject().is()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId iterId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objIterId = writer.guardToObject(iterId); + + ValOperandId resultArrId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + ObjOperandId objResultArrId = writer.guardToObject(resultArrId); + + writer.getNextMapSetEntryForIteratorResult(objIterId, objResultArrId, isMap); + + // This stub does not need to be monitored, it always returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("GetNextMapSetEntryForIterator"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachFinishBoundFunctionInit( + HandleFunction callee) { + // Self-hosted code calls this with (boundFunction, targetObj, argCount) + // arguments. + MOZ_ASSERT(argc_ == 3); + MOZ_ASSERT(args_[0].toObject().is()); + MOZ_ASSERT(args_[1].isObject()); + MOZ_ASSERT(args_[2].isInt32()); + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ValOperandId boundId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + ObjOperandId objBoundId = writer.guardToObject(boundId); + + ValOperandId targetId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + ObjOperandId objTargetId = writer.guardToObject(targetId); + + ValOperandId argCountId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_); + Int32OperandId int32ArgCountId = writer.guardToInt32(argCountId); + + writer.finishBoundFunctionInitResult(objBoundId, objTargetId, + int32ArgCountId); + + // This stub does not need to be monitored, it always returns |undefined|. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("FinishBoundFunctionInit"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachNewArrayIterator( + HandleFunction callee) { + // Self-hosted code calls this without any arguments + MOZ_ASSERT(argc_ == 0); + + JSObject* templateObj = NewArrayIteratorTemplate(cx_); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + writer.newArrayIteratorResult(templateObj); + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("NewArrayIterator"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachNewStringIterator( + HandleFunction callee) { + // Self-hosted code calls this without any arguments + MOZ_ASSERT(argc_ == 0); + + JSObject* templateObj = NewStringIteratorTemplate(cx_); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + writer.newStringIteratorResult(templateObj); + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("NewStringIterator"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachNewRegExpStringIterator( + HandleFunction callee) { + // Self-hosted code calls this without any arguments + MOZ_ASSERT(argc_ == 0); + + JSObject* templateObj = NewRegExpStringIteratorTemplate(cx_); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + writer.newRegExpStringIteratorResult(templateObj); + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("NewRegExpStringIterator"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachArrayIteratorPrototypeOptimizable( + HandleFunction callee) { + // Self-hosted code calls this without any arguments + MOZ_ASSERT(argc_ == 0); + + // TODO(Warp): attach this stub just once to prevent slowdowns for polymorphic + // calls. + + NativeObject* arrayIteratorProto; + uint32_t slot; + JSFunction* nextFun; + if (!IsArrayIteratorPrototypeOptimizable(cx_, &arrayIteratorProto, &slot, + &nextFun)) { + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Note: we don't need to call emitNativeCalleeGuard for intrinsics. + + ObjOperandId protoId = writer.loadObject(arrayIteratorProto); + ObjOperandId nextId = writer.loadObject(nextFun); + + writer.guardShape(protoId, arrayIteratorProto->lastProperty()); + + // Ensure that proto[slot] == nextFun. + writer.guardDynamicSlotIsSpecificObject(protoId, nextId, slot); + writer.loadBooleanResult(true); + + // This stub does not need to be monitored, it always returns a boolean. + writer.returnFromIC(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Regular; + + trackAttached("ArrayIteratorPrototypeOptimizable"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachObjectCreate(HandleFunction callee) { + // Need a single object-or-null argument. + if (argc_ != 1 || !args_[0].isObjectOrNull()) { + return AttachDecision::NoAction; + } + + // TODO(Warp): attach this stub just once to prevent slowdowns for + // polymorphic calls. + + RootedObject proto(cx_, args_[0].toObjectOrNull()); + JSObject* templateObj = ObjectCreateImpl(cx_, proto, TenuredObject); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee is the 'create' native function. + emitNativeCalleeGuard(callee); + + // Guard on the proto argument. + ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_); + if (proto) { + ObjOperandId protoId = writer.guardToObject(argId); + writer.guardSpecificObject(protoId, proto); + } else { + writer.guardIsNull(argId); + } + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + + writer.objectCreateResult(templateObj); + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("ObjectCreate"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachArrayConstructor( + HandleFunction callee) { + // Only optimize the |Array()| and |Array(n)| cases (with or without |new|) + // for now. Note that self-hosted code calls this without |new| via std_Array. + if (argc_ > 1) { + return AttachDecision::NoAction; + } + if (argc_ == 1 && !args_[0].isInt32()) { + return AttachDecision::NoAction; + } + + int32_t length = (argc_ == 1) ? args_[0].toInt32() : 0; + if (length < 0 || uint32_t(length) > ArrayObject::EagerAllocationMaxLength) { + return AttachDecision::NoAction; + } + + // We allow inlining this function across realms so make sure the template + // object is allocated in that realm. See CanInlineNativeCrossRealm. + JSObject* templateObj; + { + AutoRealm ar(cx_, callee); + templateObj = NewFullyAllocatedArrayForCallingAllocationSite(cx_, length, + TenuredObject); + if (!templateObj) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } + } + + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); + + // Guard callee and newTarget (if constructing) are this Array constructor + // function. + emitNativeCalleeGuard(callee); + + CallFlags flags(IsConstructPC(pc_), IsSpreadPC(pc_)); + + Int32OperandId lengthId; + if (argc_ == 1) { + ValOperandId arg0Id = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_, flags); + lengthId = writer.guardToInt32(arg0Id); + } else { + MOZ_ASSERT(argc_ == 0); + lengthId = writer.loadInt32Constant(0); + } + + writer.newArrayFromLengthResult(templateObj, lengthId); + + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + + writer.typeMonitorResult(); + cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; + + trackAttached("ArrayConstructor"); + return AttachDecision::Attach; +} + +AttachDecision CallIRGenerator::tryAttachTypedArrayConstructor( + HandleFunction callee) { + MOZ_ASSERT(IsConstructPC(pc_)); + + if (argc_ == 0 || argc_ > 3) { + return AttachDecision::NoAction; + } + + // TODO(Warp); attach this stub just once to prevent slowdowns for + // polymorphic calls. -AttachDecision CallIRGenerator::tryAttachFunCall(HandleFunction callee) { - MOZ_ASSERT(callee->isNativeWithoutJitEntry()); - if (callee->native() != fun_call) { + // The first argument must be int32 or a non-proxy object. + if (!args_[0].isInt32() && !args_[0].isObject()) { + return AttachDecision::NoAction; + } + if (args_[0].isObject() && args_[0].toObject().is()) { return AttachDecision::NoAction; } - if (!thisval_.isObject() || !thisval_.toObject().is()) { +#ifdef JS_CODEGEN_X86 + // Unfortunately NewTypedArrayFromArrayBufferResult needs more registers than + // we can easily support on 32-bit x86 for now. + if (args_[0].isObject() && + args_[0].toObject().is()) { return AttachDecision::NoAction; } - RootedFunction target(cx_, &thisval_.toObject().as()); +#endif - bool isScripted = target->hasJitEntry(); - MOZ_ASSERT_IF(!isScripted, target->isNativeWithoutJitEntry()); + RootedObject templateObj(cx_); + if (!TypedArrayObject::GetTemplateObjectForNative(cx_, callee->native(), + args_, &templateObj)) { + cx_->recoverFromOutOfMemory(); + return AttachDecision::NoAction; + } - if (target->isClassConstructor()) { + if (!templateObj) { + // This can happen for large length values. + MOZ_ASSERT(args_[0].isInt32()); return AttachDecision::NoAction; } - Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard that callee is the |fun_call| native function. - ValOperandId calleeValId = - writer.loadArgumentDynamicSlot(ArgumentKind::Callee, argcId); - ObjOperandId calleeObjId = writer.guardToObject(calleeValId); - writer.guardSpecificFunction(calleeObjId, callee); + // Initialize the input operand. + Int32OperandId argcId(writer.setInputOperandId(0)); - // Guard that |this| is an object. - ValOperandId thisValId = - writer.loadArgumentDynamicSlot(ArgumentKind::This, argcId); - ObjOperandId thisObjId = writer.guardToObject(thisValId); + // Guard callee and newTarget are this TypedArray constructor function. + emitNativeCalleeGuard(callee); - if (mode_ == ICState::Mode::Specialized) { - // Ensure that |this| is the expected target function. - writer.guardSpecificFunction(thisObjId, target); + CallFlags flags(IsConstructPC(pc_), IsSpreadPC(pc_)); + ValOperandId arg0Id = + writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_, flags); - CallFlags targetFlags(CallFlags::FunCall); - if (isScripted) { - writer.callScriptedFunction(thisObjId, argcId, targetFlags); - } else { - writer.callNativeFunction(thisObjId, argcId, op_, target, targetFlags); - } + if (args_[0].isInt32()) { + // From length. + Int32OperandId lengthId = writer.guardToInt32(arg0Id); + writer.newTypedArrayFromLengthResult(templateObj, lengthId); } else { - // Guard that |this| is a function. - writer.guardClass(thisObjId, GuardClassKind::JSFunction); - - // Guard that function is not a class constructor. - writer.guardNotClassConstructor(thisObjId); + JSObject* obj = &args_[0].toObject(); + ObjOperandId objId = writer.guardToObject(arg0Id); - CallFlags targetFlags(CallFlags::FunCall); - if (isScripted) { - writer.guardFunctionHasJitEntry(thisObjId, /*isConstructing =*/false); - writer.callScriptedFunction(thisObjId, argcId, targetFlags); + if (obj->is()) { + // From ArrayBuffer. + if (obj->is()) { + writer.guardClass(objId, GuardClassKind::ArrayBuffer); + } else { + MOZ_ASSERT(obj->is()); + writer.guardClass(objId, GuardClassKind::SharedArrayBuffer); + } + ValOperandId byteOffsetId; + if (argc_ > 1) { + byteOffsetId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_, flags); + } else { + byteOffsetId = writer.loadUndefined(); + } + ValOperandId lengthId; + if (argc_ > 2) { + lengthId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg2, argc_, flags); + } else { + lengthId = writer.loadUndefined(); + } + writer.newTypedArrayFromArrayBufferResult(templateObj, objId, + byteOffsetId, lengthId); } else { - writer.guardFunctionHasNoJitEntry(thisObjId); - writer.callAnyNativeFunction(thisObjId, argcId, targetFlags); + // From Array-like. + writer.guardIsNotArrayBufferMaybeShared(objId); + writer.guardIsNotProxy(objId); + writer.newTypedArrayFromArrayResult(templateObj, objId); } } + if (!JitOptions.warpBuilder) { + // Store the template object for BaselineInspector. + writer.metaNativeTemplateObject(callee, templateObj); + } + writer.typeMonitorResult(); cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; - if (isScripted) { - trackAttached("Scripted fun_call"); - } else { - trackAttached("Native fun_call"); - } - + trackAttached("TypedArrayConstructor"); return AttachDecision::Attach; } AttachDecision CallIRGenerator::tryAttachFunApply(HandleFunction calleeFunc) { - MOZ_ASSERT(calleeFunc->isNativeWithoutJitEntry()); - if (calleeFunc->native() != fun_apply) { + if (!calleeFunc->isNativeWithoutJitEntry() || + calleeFunc->native() != fun_apply) { return AttachDecision::NoAction; } @@ -6025,7 +8777,7 @@ AttachDecision CallIRGenerator::tryAttachFunApply(HandleFunction calleeFunc) { format = CallFlags::FunApplyArgs; } else if (args_[1].isObject() && args_[1].toObject().is() && args_[1].toObject().as().length() <= - CacheIRCompiler::MAX_ARGS_ARRAY_LENGTH) { + JIT_ARGS_LENGTH_MAX) { format = CallFlags::FunApplyArray; } else { return AttachDecision::NoAction; @@ -6037,28 +8789,51 @@ AttachDecision CallIRGenerator::tryAttachFunApply(HandleFunction calleeFunc) { ValOperandId calleeValId = writer.loadArgumentDynamicSlot(ArgumentKind::Callee, argcId); ObjOperandId calleeObjId = writer.guardToObject(calleeValId); - writer.guardSpecificNativeFunction(calleeObjId, fun_apply); + writer.guardSpecificFunction(calleeObjId, calleeFunc); - // Guard that |this| is a function. + // Guard that |this| is an object. ValOperandId thisValId = writer.loadArgumentDynamicSlot(ArgumentKind::This, argcId); ObjOperandId thisObjId = writer.guardToObject(thisValId); - writer.guardClass(thisObjId, GuardClassKind::JSFunction); - // Guard that function is not a class constructor. - writer.guardNotClassConstructor(thisObjId); + ValOperandId argValId = + writer.loadArgumentFixedSlot(ArgumentKind::Arg1, argc_); + if (format == CallFlags::FunApplyArgs) { + writer.guardMagicValue(argValId, JS_OPTIMIZED_ARGUMENTS); + writer.guardFrameHasNoArgumentsObject(); + } else { + MOZ_ASSERT(format == CallFlags::FunApplyArray); + ObjOperandId argObjId = writer.guardToObject(argValId); + writer.guardClass(argObjId, GuardClassKind::Array); + writer.guardArrayIsPacked(argObjId); + } CallFlags targetFlags(format); - writer.guardFunApply(argcId, targetFlags); + if (mode_ == ICState::Mode::Specialized) { + // Ensure that |this| is the expected target function. + emitCalleeGuard(thisObjId, target); - if (isScripted) { - // Guard that function is scripted. - writer.guardFunctionHasJitEntry(thisObjId, /*isConstructing =*/false); - writer.callScriptedFunction(thisObjId, argcId, targetFlags); + if (isScripted) { + writer.callScriptedFunction(thisObjId, argcId, targetFlags); + } else { + writer.callNativeFunction(thisObjId, argcId, op_, target, targetFlags); + } } else { - // Guard that function is native. - writer.guardFunctionHasNoJitEntry(thisObjId); - writer.callAnyNativeFunction(thisObjId, argcId, targetFlags); + // Guard that |this| is a function. + writer.guardClass(thisObjId, GuardClassKind::JSFunction); + + // Guard that function is not a class constructor. + writer.guardNotClassConstructor(thisObjId); + + if (isScripted) { + // Guard that function is scripted. + writer.guardFunctionHasJitEntry(thisObjId, /*constructing =*/false); + writer.callScriptedFunction(thisObjId, argcId, targetFlags); + } else { + // Guard that function is native. + writer.guardFunctionHasNoJitEntry(thisObjId); + writer.callAnyNativeFunction(thisObjId, argcId, targetFlags); + } } writer.typeMonitorResult(); @@ -6079,7 +8854,7 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( MOZ_ASSERT(callee->isNativeWithoutJitEntry()); // Special case functions are only optimized for normal calls. - if (op_ != JSOp::Call && op_ != JSOp::CallIgnoresRv) { + if (op_ != JSOp::Call && op_ != JSOp::New && op_ != JSOp::CallIgnoresRv) { return AttachDecision::NoAction; } @@ -6095,16 +8870,85 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( return AttachDecision::NoAction; } + // Check for special-cased native constructors. + if (op_ == JSOp::New) { + // newTarget must match the callee. CacheIR for this is emitted in + // emitNativeCalleeGuard. + if (callee_ != newTarget_) { + return AttachDecision::NoAction; + } + switch (native) { + case InlinableNative::Array: + return tryAttachArrayConstructor(callee); + case InlinableNative::TypedArrayConstructor: + return tryAttachTypedArrayConstructor(callee); + case InlinableNative::String: + return tryAttachStringConstructor(callee); + default: + break; + } + return AttachDecision::NoAction; + } + // Check for special-cased native functions. switch (native) { // Array natives. + case InlinableNative::Array: + return tryAttachArrayConstructor(callee); case InlinableNative::ArrayPush: return tryAttachArrayPush(callee); + case InlinableNative::ArrayPop: + case InlinableNative::ArrayShift: + return tryAttachArrayPopShift(callee, native); case InlinableNative::ArrayJoin: return tryAttachArrayJoin(callee); + case InlinableNative::ArraySlice: + return tryAttachArraySlice(callee); case InlinableNative::ArrayIsArray: return tryAttachArrayIsArray(callee); + // DataView natives. + case InlinableNative::DataViewGetInt8: + return tryAttachDataViewGet(callee, Scalar::Int8); + case InlinableNative::DataViewGetUint8: + return tryAttachDataViewGet(callee, Scalar::Uint8); + case InlinableNative::DataViewGetInt16: + return tryAttachDataViewGet(callee, Scalar::Int16); + case InlinableNative::DataViewGetUint16: + return tryAttachDataViewGet(callee, Scalar::Uint16); + case InlinableNative::DataViewGetInt32: + return tryAttachDataViewGet(callee, Scalar::Int32); + case InlinableNative::DataViewGetUint32: + return tryAttachDataViewGet(callee, Scalar::Uint32); + case InlinableNative::DataViewGetFloat32: + return tryAttachDataViewGet(callee, Scalar::Float32); + case InlinableNative::DataViewGetFloat64: + return tryAttachDataViewGet(callee, Scalar::Float64); + case InlinableNative::DataViewGetBigInt64: + return tryAttachDataViewGet(callee, Scalar::BigInt64); + case InlinableNative::DataViewGetBigUint64: + return tryAttachDataViewGet(callee, Scalar::BigUint64); + case InlinableNative::DataViewSetInt8: + return tryAttachDataViewSet(callee, Scalar::Int8); + case InlinableNative::DataViewSetUint8: + return tryAttachDataViewSet(callee, Scalar::Uint8); + case InlinableNative::DataViewSetInt16: + return tryAttachDataViewSet(callee, Scalar::Int16); + case InlinableNative::DataViewSetUint16: + return tryAttachDataViewSet(callee, Scalar::Uint16); + case InlinableNative::DataViewSetInt32: + return tryAttachDataViewSet(callee, Scalar::Int32); + case InlinableNative::DataViewSetUint32: + return tryAttachDataViewSet(callee, Scalar::Uint32); + case InlinableNative::DataViewSetFloat32: + return tryAttachDataViewSet(callee, Scalar::Float32); + case InlinableNative::DataViewSetFloat64: + return tryAttachDataViewSet(callee, Scalar::Float64); + case InlinableNative::DataViewSetBigInt64: + return tryAttachDataViewSet(callee, Scalar::BigInt64); + case InlinableNative::DataViewSetBigUint64: + return tryAttachDataViewSet(callee, Scalar::BigUint64); + // Intl natives. case InlinableNative::IntlGuardToCollator: case InlinableNative::IntlGuardToDateTimeFormat: @@ -6122,12 +8966,12 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( case InlinableNative::IntrinsicUnsafeGetStringFromReservedSlot: case InlinableNative::IntrinsicUnsafeGetBooleanFromReservedSlot: return tryAttachUnsafeGetReservedSlot(callee, native); + case InlinableNative::IntrinsicUnsafeSetReservedSlot: + return tryAttachUnsafeSetReservedSlot(callee); // Intrinsics. case InlinableNative::IntrinsicIsSuspendedGenerator: return tryAttachIsSuspendedGenerator(callee); - case InlinableNative::IntrinsicToString: - return tryAttachToString(callee, native); case InlinableNative::IntrinsicToObject: return tryAttachToObject(callee, native); case InlinableNative::IntrinsicToInteger: @@ -6136,23 +8980,47 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( return tryAttachToLength(callee); case InlinableNative::IntrinsicIsObject: return tryAttachIsObject(callee); + case InlinableNative::IntrinsicIsPackedArray: + return tryAttachIsPackedArray(callee); case InlinableNative::IntrinsicIsCallable: return tryAttachIsCallable(callee); case InlinableNative::IntrinsicIsConstructor: return tryAttachIsConstructor(callee); + case InlinableNative::IntrinsicIsCrossRealmArrayConstructor: + return tryAttachIsCrossRealmArrayConstructor(callee); case InlinableNative::IntrinsicGuardToArrayIterator: case InlinableNative::IntrinsicGuardToMapIterator: case InlinableNative::IntrinsicGuardToSetIterator: case InlinableNative::IntrinsicGuardToStringIterator: case InlinableNative::IntrinsicGuardToRegExpStringIterator: case InlinableNative::IntrinsicGuardToWrapForValidIterator: + case InlinableNative::IntrinsicGuardToIteratorHelper: + case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: return tryAttachGuardToClass(callee, native); case InlinableNative::IntrinsicSubstringKernel: return tryAttachSubstringKernel(callee); + case InlinableNative::IntrinsicIsConstructing: + return tryAttachIsConstructing(callee); + case InlinableNative::IntrinsicFinishBoundFunctionInit: + return tryAttachFinishBoundFunctionInit(callee); + case InlinableNative::IntrinsicNewArrayIterator: + return tryAttachNewArrayIterator(callee); + case InlinableNative::IntrinsicNewStringIterator: + return tryAttachNewStringIterator(callee); + case InlinableNative::IntrinsicNewRegExpStringIterator: + return tryAttachNewRegExpStringIterator(callee); + case InlinableNative::IntrinsicArrayIteratorPrototypeOptimizable: + return tryAttachArrayIteratorPrototypeOptimizable(callee); + case InlinableNative::IntrinsicObjectHasPrototype: + return tryAttachObjectHasPrototype(callee); // RegExp natives. case InlinableNative::IsRegExpObject: - return tryAttachHasClass(callee, &RegExpObject::class_); + return tryAttachHasClass(callee, &RegExpObject::class_, + /* isPossiblyWrapped = */ false); + case InlinableNative::IsPossiblyWrappedRegExpObject: + return tryAttachHasClass(callee, &RegExpObject::class_, + /* isPossiblyWrapped = */ true); case InlinableNative::RegExpMatcher: case InlinableNative::RegExpSearcher: case InlinableNative::RegExpTester: @@ -6161,30 +9029,57 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( return tryAttachRegExpPrototypeOptimizable(callee); case InlinableNative::RegExpInstanceOptimizable: return tryAttachRegExpInstanceOptimizable(callee); + case InlinableNative::GetFirstDollarIndex: + return tryAttachGetFirstDollarIndex(callee); // String natives. case InlinableNative::String: - return tryAttachToString(callee, native); + return tryAttachString(callee); + case InlinableNative::StringToString: + case InlinableNative::StringValueOf: + return tryAttachStringToStringValueOf(callee); case InlinableNative::StringCharCodeAt: return tryAttachStringCharCodeAt(callee); case InlinableNative::StringCharAt: return tryAttachStringCharAt(callee); case InlinableNative::StringFromCharCode: return tryAttachStringFromCharCode(callee); + case InlinableNative::StringFromCodePoint: + return tryAttachStringFromCodePoint(callee); + case InlinableNative::StringToLowerCase: + return tryAttachStringToLowerCase(callee); + case InlinableNative::StringToUpperCase: + return tryAttachStringToUpperCase(callee); + case InlinableNative::IntrinsicStringReplaceString: + return tryAttachStringReplaceString(callee); + case InlinableNative::IntrinsicStringSplitString: + return tryAttachStringSplitString(callee); // Math natives. case InlinableNative::MathRandom: return tryAttachMathRandom(callee); case InlinableNative::MathAbs: return tryAttachMathAbs(callee); + case InlinableNative::MathClz32: + return tryAttachMathClz32(callee); + case InlinableNative::MathSign: + return tryAttachMathSign(callee); + case InlinableNative::MathImul: + return tryAttachMathImul(callee); case InlinableNative::MathFloor: return tryAttachMathFloor(callee); case InlinableNative::MathCeil: return tryAttachMathCeil(callee); + case InlinableNative::MathTrunc: + return tryAttachMathTrunc(callee); case InlinableNative::MathRound: return tryAttachMathRound(callee); case InlinableNative::MathSqrt: return tryAttachMathSqrt(callee); + case InlinableNative::MathFRound: + return tryAttachMathFRound(callee); + case InlinableNative::MathHypot: + return tryAttachMathHypot(callee); case InlinableNative::MathATan2: return tryAttachMathATan2(callee); case InlinableNative::MathSin: @@ -6235,90 +9130,166 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative( // Map intrinsics. case InlinableNative::IntrinsicGuardToMapObject: return tryAttachGuardToClass(callee, native); + case InlinableNative::IntrinsicGetNextMapEntryForIterator: + return tryAttachGetNextMapSetEntryForIterator(callee, /* isMap = */ true); + + // Number natives. + case InlinableNative::NumberToString: + return tryAttachNumberToString(callee); // Object natives. case InlinableNative::Object: return tryAttachToObject(callee, native); + case InlinableNative::ObjectCreate: + return tryAttachObjectCreate(callee); + case InlinableNative::ObjectIs: + return tryAttachObjectIs(callee); + case InlinableNative::ObjectIsPrototypeOf: + return tryAttachObjectIsPrototypeOf(callee); + case InlinableNative::ObjectToString: + return AttachDecision::NoAction; // Not yet supported. // Set intrinsics. case InlinableNative::IntrinsicGuardToSetObject: return tryAttachGuardToClass(callee, native); + case InlinableNative::IntrinsicGetNextSetEntryForIterator: + return tryAttachGetNextMapSetEntryForIterator(callee, + /* isMap = */ false); // ArrayBuffer intrinsics. case InlinableNative::IntrinsicGuardToArrayBuffer: return tryAttachGuardToClass(callee, native); + case InlinableNative::IntrinsicArrayBufferByteLength: + return tryAttachArrayBufferByteLength(callee, + /* isPossiblyWrapped = */ false); + case InlinableNative::IntrinsicPossiblyWrappedArrayBufferByteLength: + return tryAttachArrayBufferByteLength(callee, + /* isPossiblyWrapped = */ true); // SharedArrayBuffer intrinsics. case InlinableNative::IntrinsicGuardToSharedArrayBuffer: return tryAttachGuardToClass(callee, native); - default: - return AttachDecision::NoAction; + // TypedArray intrinsics. + case InlinableNative::TypedArrayConstructor: + return AttachDecision::NoAction; // Not callable. + case InlinableNative::IntrinsicIsTypedArray: + return tryAttachIsTypedArray(callee, /* isPossiblyWrapped = */ false); + case InlinableNative::IntrinsicIsPossiblyWrappedTypedArray: + return tryAttachIsTypedArray(callee, /* isPossiblyWrapped = */ true); + case InlinableNative::IntrinsicIsTypedArrayConstructor: + return tryAttachIsTypedArrayConstructor(callee); + case InlinableNative::IntrinsicTypedArrayByteOffset: + return tryAttachTypedArrayByteOffset(callee); + case InlinableNative::IntrinsicTypedArrayElementShift: + return tryAttachTypedArrayElementShift(callee); + case InlinableNative::IntrinsicTypedArrayLength: + return tryAttachTypedArrayLength(callee, /* isPossiblyWrapped = */ false); + case InlinableNative::IntrinsicPossiblyWrappedTypedArrayLength: + return tryAttachTypedArrayLength(callee, /* isPossiblyWrapped = */ true); + + // Reflect natives. + case InlinableNative::ReflectGetPrototypeOf: + return tryAttachReflectGetPrototypeOf(callee); + + // Atomics intrinsics: + case InlinableNative::AtomicsCompareExchange: + return tryAttachAtomicsCompareExchange(callee); + case InlinableNative::AtomicsExchange: + return tryAttachAtomicsExchange(callee); + case InlinableNative::AtomicsAdd: + return tryAttachAtomicsAdd(callee); + case InlinableNative::AtomicsSub: + return tryAttachAtomicsSub(callee); + case InlinableNative::AtomicsAnd: + return tryAttachAtomicsAnd(callee); + case InlinableNative::AtomicsOr: + return tryAttachAtomicsOr(callee); + case InlinableNative::AtomicsXor: + return tryAttachAtomicsXor(callee); + case InlinableNative::AtomicsLoad: + return tryAttachAtomicsLoad(callee); + case InlinableNative::AtomicsStore: + return tryAttachAtomicsStore(callee); + case InlinableNative::AtomicsIsLockFree: + return tryAttachAtomicsIsLockFree(callee); + + // Boolean natives. + case InlinableNative::Boolean: + return tryAttachBoolean(callee); + + // Testing functions. + case InlinableNative::TestBailout: + return tryAttachBailout(callee); + case InlinableNative::TestAssertFloat32: + return tryAttachAssertFloat32(callee); + case InlinableNative::TestAssertRecoveredOnBailout: + return tryAttachAssertRecoveredOnBailout(callee); + + case InlinableNative::Limit: + break; } + + MOZ_CRASH("Shouldn't get here"); } // Remember the template object associated with any script being called // as a constructor, for later use during Ion compilation. -bool CallIRGenerator::getTemplateObjectForScripted(HandleFunction calleeFunc, - MutableHandleObject result, - bool* skipAttach) { - MOZ_ASSERT(!*skipAttach); - +ScriptedThisResult CallIRGenerator::getThisForScripted( + HandleFunction calleeFunc, MutableHandleObject result) { // Some constructors allocate their own |this| object. if (calleeFunc->constructorNeedsUninitializedThis()) { - return true; - } - - // Don't allocate a template object for super() calls as Ion doesn't support - // super() yet. - bool isSuper = op_ == JSOp::SuperCall || op_ == JSOp::SpreadSuperCall; - if (isSuper) { - return true; + return ScriptedThisResult::UninitializedThis; } - // Only attach a stub if the function already has a prototype and - // we can look it up without causing side effects. + // Only attach a stub if the newTarget is a function with a + // nonconfigurable prototype. RootedValue protov(cx_); RootedObject newTarget(cx_, &newTarget_.toObject()); + if (!newTarget->is() || + !newTarget->as().hasNonConfigurablePrototypeDataProperty()) { + return ScriptedThisResult::NoAction; + } + if (!GetPropertyPure(cx_, newTarget, NameToId(cx_->names().prototype), protov.address())) { - // Can't purely lookup function prototype - trackAttached(IRGenerator::NotAttached); - *skipAttach = true; - return true; + // The lazy prototype property hasn't been resolved yet. + MOZ_ASSERT(newTarget->as().needsPrototypeProperty()); + return ScriptedThisResult::TemporarilyUnoptimizable; + } + + if (!protov.isObject()) { + return ScriptedThisResult::NoAction; } - if (protov.isObject()) { + { AutoRealm ar(cx_, calleeFunc); TaggedProto proto(&protov.toObject()); ObjectGroup* group = ObjectGroup::defaultNewGroup(cx_, &PlainObject::class_, proto, newTarget); if (!group) { - return false; + cx_->clearPendingException(); + return ScriptedThisResult::NoAction; } AutoSweepObjectGroup sweep(group); if (group->newScript(sweep) && !group->newScript(sweep)->analyzed()) { - // Function newScript has not been analyzed - trackAttached(IRGenerator::NotAttached); - *skipAttach = true; - return true; + // The new script analysis has not been done on this function. + // Don't attach until after the analysis has been done. + return ScriptedThisResult::TemporarilyUnoptimizable; } } - JSObject* thisObject = + PlainObject* thisObject = CreateThisForFunction(cx_, calleeFunc, newTarget, TenuredObject); if (!thisObject) { - return false; + cx_->clearPendingException(); + return ScriptedThisResult::NoAction; } MOZ_ASSERT(thisObject->nonCCWRealm() == calleeFunc->realm()); - - if (thisObject->is()) { - result.set(thisObject); - } - - return true; + result.set(thisObject); + return ScriptedThisResult::TemplateObject; } AttachDecision CallIRGenerator::tryAttachCallScripted( @@ -6355,6 +9326,11 @@ AttachDecision CallIRGenerator::tryAttachCallScripted( return AttachDecision::TemporarilyUnoptimizable; } + // Verify that spread calls have a reasonable number of arguments. + if (isSpread && args_.length() > JIT_ARGS_LENGTH_MAX) { + return AttachDecision::NoAction; + } + // Keep track of the function's |prototype| property in type // information, for use during Ion compilation. if (IsIonEnabled(cx_)) { @@ -6362,14 +9338,18 @@ AttachDecision CallIRGenerator::tryAttachCallScripted( } RootedObject templateObj(cx_); - bool skipAttach = false; - if (isConstructing && isSpecialized && - !getTemplateObjectForScripted(calleeFunc, &templateObj, &skipAttach)) { - cx_->clearPendingException(); - return AttachDecision::NoAction; - } - if (skipAttach) { - return AttachDecision::TemporarilyUnoptimizable; + if (isConstructing && isSpecialized) { + switch (getThisForScripted(calleeFunc, &templateObj)) { + case ScriptedThisResult::TemplateObject: + break; + case ScriptedThisResult::UninitializedThis: + flags.setNeedsUninitializedThis(); + break; + case ScriptedThisResult::TemporarilyUnoptimizable: + return AttachDecision::TemporarilyUnoptimizable; + case ScriptedThisResult::NoAction: + return AttachDecision::NoAction; + } } // Load argc. @@ -6381,8 +9361,34 @@ AttachDecision CallIRGenerator::tryAttachCallScripted( ObjOperandId calleeObjId = writer.guardToObject(calleeValId); if (isSpecialized) { + MOZ_ASSERT_IF(isConstructing, + templateObj || flags.needsUninitializedThis()); + // Ensure callee matches this stub's callee - writer.guardSpecificFunction(calleeObjId, calleeFunc); + emitCalleeGuard(calleeObjId, calleeFunc); + if (templateObj) { + // Call metaScriptedTemplateObject before emitting the call, so that Warp + // can use this template object before transpiling the call. + if (JitOptions.warpBuilder) { + // Emit guards to ensure the newTarget's .prototype property is what we + // expect. Note that getThisForScripted checked newTarget is a function + // with a non-configurable .prototype data property. + JSFunction* newTarget = &newTarget_.toObject().as(); + Shape* shape = newTarget->lookupPure(cx_->names().prototype); + MOZ_ASSERT(shape); + MOZ_ASSERT(newTarget->numFixedSlots() == 0, "Stub code relies on this"); + uint32_t slot = shape->slot(); + JSObject* prototypeObject = &newTarget->getSlot(slot).toObject(); + + ValOperandId newTargetValId = writer.loadArgumentDynamicSlot( + ArgumentKind::NewTarget, argcId, flags); + ObjOperandId newTargetObjId = writer.guardToObject(newTargetValId); + writer.guardShape(newTargetObjId, newTarget->lastProperty()); + ObjOperandId protoId = writer.loadObject(prototypeObject); + writer.guardDynamicSlotIsSpecificObject(newTargetObjId, protoId, slot); + } + writer.metaScriptedTemplateObject(calleeFunc, templateObj); + } } else { // Guard that object is a scripted function writer.guardClass(calleeObjId, GuardClassKind::JSFunction); @@ -6400,11 +9406,6 @@ AttachDecision CallIRGenerator::tryAttachCallScripted( writer.callScriptedFunction(calleeObjId, argcId, flags); writer.typeMonitorResult(); - if (templateObj) { - MOZ_ASSERT(isSpecialized); - writer.metaScriptedTemplateObject(calleeFunc, templateObj); - } - cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored; if (isSpecialized) { trackAttached("Call scripted func"); @@ -6419,8 +9420,8 @@ bool CallIRGenerator::getTemplateObjectForNative(HandleFunction calleeFunc, MutableHandleObject res) { AutoRealm ar(cx_, calleeFunc); - // Don't allocate a template object for super() calls as Ion doesn't support - // super() yet. + // Don't allocate a template object for super() calls as Ion doesn't inline + // native super(). bool isSuper = op_ == JSOp::SuperCall || op_ == JSOp::SpreadSuperCall; if (isSuper) { return true; @@ -6431,6 +9432,8 @@ bool CallIRGenerator::getTemplateObjectForNative(HandleFunction calleeFunc, return true; } + bool isConstructing = IsConstructOp(op_); + // Check for natives to which template objects can be attached. This is // done to provide templates to Ion for inlining these natives later on. switch (calleeFunc->jitInfo()->inlinableNative) { @@ -6438,14 +9441,13 @@ bool CallIRGenerator::getTemplateObjectForNative(HandleFunction calleeFunc, // Note: the template array won't be used if its length is inaccurately // computed here. (We allocate here because compilation may occur on a // separate thread where allocation is impossible.) - size_t count = 0; - if (args_.length() != 1) { - count = args_.length(); - } else if (args_.length() == 1 && args_[0].isInt32() && - args_[0].toInt32() >= 0) { - count = args_[0].toInt32(); + + if (args_.length() <= 1) { + // This case is handled by tryAttachArrayConstructor. + return true; } + size_t count = args_.length(); if (count > ArrayObject::EagerAllocationMaxLength) { return true; } @@ -6467,46 +9469,37 @@ bool CallIRGenerator::getTemplateObjectForNative(HandleFunction calleeFunc, return true; } + if (IsPackedArray(obj)) { + // This case is handled by tryAttachArraySlice. + return true; + } + + // TODO(Warp): Support non-packed arrays in tryAttachArraySlice if they're + // common in user code. + if (JitOptions.warpBuilder) { + return true; + } + res.set(NewFullyAllocatedArrayTryReuseGroup(cx_, obj, 0, TenuredObject)); return !!res; } case InlinableNative::String: { - RootedString emptyString(cx_, cx_->runtime()->emptyString); - res.set(StringObject::create(cx_, emptyString, /* proto = */ nullptr, - TenuredObject)); - return !!res; - } - - case InlinableNative::ObjectCreate: { - if (args_.length() != 1 || !args_[0].isObjectOrNull()) { + if (!isConstructing) { return true; } - RootedObject proto(cx_, args_[0].toObjectOrNull()); - res.set(ObjectCreateImpl(cx_, proto, TenuredObject)); - return !!res; - } - case InlinableNative::IntrinsicNewArrayIterator: { - res.set(NewArrayIteratorTemplate(cx_)); - return !!res; - } - - case InlinableNative::IntrinsicNewStringIterator: { - res.set(NewStringIteratorTemplate(cx_)); - return !!res; - } + if (args_.length() == 1 && args_[0].isString()) { + // This case is handled by tryAttachStringConstructor. + return true; + } - case InlinableNative::IntrinsicNewRegExpStringIterator: { - res.set(NewRegExpStringIteratorTemplate(cx_)); + RootedString emptyString(cx_, cx_->runtime()->emptyString); + res.set(StringObject::create(cx_, emptyString, /* proto = */ nullptr, + TenuredObject)); return !!res; } - case InlinableNative::TypedArrayConstructor: { - return TypedArrayObject::GetTemplateObjectForNative( - cx_, calleeFunc->native(), args_, res); - } - default: return true; } @@ -6526,6 +9519,11 @@ AttachDecision CallIRGenerator::tryAttachCallNative(HandleFunction calleeFunc) { return AttachDecision::NoAction; } + // Verify that spread calls have a reasonable number of arguments. + if (isSpread && args_.length() > JIT_ARGS_LENGTH_MAX) { + return AttachDecision::NoAction; + } + // Check for specific native-function optimizations. if (isSpecialized) { TRY_ATTACH(tryAttachInlinableNative(calleeFunc)); @@ -6582,7 +9580,7 @@ AttachDecision CallIRGenerator::tryAttachCallNative(HandleFunction calleeFunc) { } AttachDecision CallIRGenerator::tryAttachCallHook(HandleObject calleeObj) { - if (op_ == JSOp::FunApply) { + if (op_ == JSOp::FunCall || op_ == JSOp::FunApply) { return AttachDecision::NoAction; } @@ -6602,6 +9600,11 @@ AttachDecision CallIRGenerator::tryAttachCallHook(HandleObject calleeObj) { return AttachDecision::NoAction; } + // Verify that spread calls have a reasonable number of arguments. + if (isSpread && args_.length() > JIT_ARGS_LENGTH_MAX) { + return AttachDecision::NoAction; + } + // Load argc. Int32OperandId argcId(writer.setInputOperandId(0)); @@ -6654,7 +9657,14 @@ AttachDecision CallIRGenerator::tryAttachStub() { return tryAttachCallHook(calleeObj); } - RootedFunction calleeFunc(cx_, &calleeObj->as()); + HandleFunction calleeFunc = calleeObj.as(); + + if (op_ == JSOp::FunCall) { + return tryAttachFunCall(calleeFunc); + } + if (op_ == JSOp::FunApply) { + return tryAttachFunApply(calleeFunc); + } // Check for scripted optimizations. if (calleeFunc->hasJitEntry()) { @@ -6664,12 +9674,6 @@ AttachDecision CallIRGenerator::tryAttachStub() { // Check for native-function optimizations. MOZ_ASSERT(calleeFunc->isNativeWithoutJitEntry()); - if (op_ == JSOp::FunCall) { - return tryAttachFunCall(calleeFunc); - } - if (op_ == JSOp::FunApply) { - return tryAttachFunApply(calleeFunc); - } return tryAttachCallNative(calleeFunc); } @@ -6719,7 +9723,7 @@ JSObject* jit::NewWrapperWithObjectShape(JSContext* cx, { AutoRealm ar(cx, obj); wrapper = NewBuiltinClassInstance(cx, &shapeContainerClass); - if (!obj) { + if (!wrapper) { return nullptr; } wrapper->as().setSlot( @@ -6737,8 +9741,7 @@ void jit::LoadShapeWrapperContents(MacroAssembler& masm, Register obj, masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), dst); Address privateAddr(dst, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()); - masm.branchTestObject(Assembler::NotEqual, privateAddr, failure); - masm.unboxObject(privateAddr, dst); + masm.fallibleUnboxObject(privateAddr, dst, failure); masm.unboxNonDouble( Address(dst, NativeObject::getFixedSlotOffset(SHAPE_CONTAINER_SLOT)), dst, JSVAL_TYPE_PRIVATE_GCTHING); @@ -6837,10 +9840,12 @@ AttachDecision CompareIRGenerator::tryAttachInt32(ValOperandId lhsId, return AttachDecision::NoAction; } - Int32OperandId lhsIntId = lhsVal_.isBoolean() ? writer.guardToBoolean(lhsId) - : writer.guardToInt32(lhsId); - Int32OperandId rhsIntId = rhsVal_.isBoolean() ? writer.guardToBoolean(rhsId) - : writer.guardToInt32(rhsId); + Int32OperandId lhsIntId = lhsVal_.isBoolean() + ? writer.guardBooleanToInt32(lhsId) + : writer.guardToInt32(lhsId); + Int32OperandId rhsIntId = rhsVal_.isBoolean() + ? writer.guardBooleanToInt32(rhsId) + : writer.guardToInt32(rhsId); // Strictly different types should have been handed by // tryAttachStrictDifferentTypes @@ -7035,7 +10040,7 @@ AttachDecision CompareIRGenerator::tryAttachStringNumber(ValOperandId lhsId, auto createGuards = [&](HandleValue v, ValOperandId vId) { if (v.isString()) { StringOperandId strId = writer.guardToString(vId); - return writer.guardAndGetNumberFromString(strId); + return writer.guardStringToNumber(strId); } MOZ_ASSERT(v.isNumber()); NumberOperandId numId = writer.guardIsNumber(vId); @@ -7122,12 +10127,12 @@ AttachDecision CompareIRGenerator::tryAttachBoolStringOrNumber( auto createGuards = [&](HandleValue v, ValOperandId vId) { if (v.isBoolean()) { - Int32OperandId boolId = writer.guardToBoolean(vId); - return writer.guardAndGetNumberFromBoolean(boolId); + BooleanOperandId boolId = writer.guardToBoolean(vId); + return writer.booleanToNumber(boolId); } if (v.isString()) { StringOperandId strId = writer.guardToString(vId); - return writer.guardAndGetNumberFromString(strId); + return writer.guardStringToNumber(strId); } MOZ_ASSERT(v.isNumber()); return writer.guardIsNumber(vId); @@ -7155,7 +10160,7 @@ AttachDecision CompareIRGenerator::tryAttachBigIntInt32(ValOperandId lhsId, auto createGuards = [&](HandleValue v, ValOperandId vId) { if (v.isBoolean()) { - return writer.guardToBoolean(vId); + return writer.guardBooleanToInt32(vId); } MOZ_ASSERT(v.isInt32()); return writer.guardToInt32(vId); @@ -7474,6 +10479,7 @@ AttachDecision UnaryArithIRGenerator::tryAttachStub() { AutoAssertNoPendingException aanpe(cx_); TRY_ATTACH(tryAttachInt32()); TRY_ATTACH(tryAttachNumber()); + TRY_ATTACH(tryAttachBitwise()); TRY_ATTACH(tryAttachBigInt()); TRY_ATTACH(tryAttachStringInt32()); TRY_ATTACH(tryAttachStringNumber()); @@ -7483,6 +10489,9 @@ AttachDecision UnaryArithIRGenerator::tryAttachStub() { } AttachDecision UnaryArithIRGenerator::tryAttachInt32() { + if (op_ == JSOp::BitNot) { + return AttachDecision::NoAction; + } if (!val_.isInt32() || !res_.isInt32()) { return AttachDecision::NoAction; } @@ -7491,10 +10500,6 @@ AttachDecision UnaryArithIRGenerator::tryAttachInt32() { Int32OperandId intId = writer.guardToInt32(valId); switch (op_) { - case JSOp::BitNot: - writer.int32NotResult(intId); - trackAttached("UnaryArith.Int32Not"); - break; case JSOp::Pos: writer.loadInt32Result(intId); trackAttached("UnaryArith.Int32Pos"); @@ -7524,6 +10529,9 @@ AttachDecision UnaryArithIRGenerator::tryAttachInt32() { } AttachDecision UnaryArithIRGenerator::tryAttachNumber() { + if (op_ == JSOp::BitNot) { + return AttachDecision::NoAction; + } if (!val_.isNumber()) { return AttachDecision::NoAction; } @@ -7533,11 +10541,6 @@ AttachDecision UnaryArithIRGenerator::tryAttachNumber() { NumberOperandId numId = writer.guardIsNumber(valId); Int32OperandId truncatedId; switch (op_) { - case JSOp::BitNot: - truncatedId = writer.truncateDoubleToUInt32(numId); - writer.int32NotResult(truncatedId); - trackAttached("UnaryArith.DoubleNot"); - break; case JSOp::Pos: writer.loadDoubleResult(numId); trackAttached("UnaryArith.DoublePos"); @@ -7566,6 +10569,60 @@ AttachDecision UnaryArithIRGenerator::tryAttachNumber() { return AttachDecision::Attach; } +static bool CanTruncateToInt32(const Value& val) { + return val.isNumber() || val.isBoolean() || val.isNullOrUndefined() || + val.isString(); +} + +// Convert type into int32 for the bitwise/shift operands. +static Int32OperandId EmitTruncateToInt32Guard(CacheIRWriter& writer, + ValOperandId id, + HandleValue val) { + MOZ_ASSERT(CanTruncateToInt32(val)); + if (val.isInt32()) { + return writer.guardToInt32(id); + } + if (val.isBoolean()) { + return writer.guardBooleanToInt32(id); + } + if (val.isNullOrUndefined()) { + writer.guardIsNullOrUndefined(id); + return writer.loadInt32Constant(0); + } + NumberOperandId numId; + if (val.isString()) { + StringOperandId strId = writer.guardToString(id); + numId = writer.guardStringToNumber(strId); + } else { + MOZ_ASSERT(val.isDouble()); + numId = writer.guardIsNumber(id); + } + return writer.truncateDoubleToUInt32(numId); +} + +AttachDecision UnaryArithIRGenerator::tryAttachBitwise() { + // Only bitwise operators. + if (op_ != JSOp::BitNot) { + return AttachDecision::NoAction; + } + + // Check guard conditions + if (!CanTruncateToInt32(val_)) { + return AttachDecision::NoAction; + } + + // Bitwise operators always produce Int32 values. + MOZ_ASSERT(res_.isInt32()); + + ValOperandId valId(writer.setInputOperandId(0)); + Int32OperandId intId = EmitTruncateToInt32Guard(writer, valId, val_); + writer.int32NotResult(intId); + trackAttached("BinaryArith.Bitwise.BitNot"); + + writer.returnFromIC(); + return AttachDecision::Attach; +} + AttachDecision UnaryArithIRGenerator::tryAttachBigInt() { if (!val_.isBigInt()) { return AttachDecision::NoAction; @@ -7612,19 +10669,18 @@ AttachDecision UnaryArithIRGenerator::tryAttachStringInt32() { } MOZ_ASSERT(res_.isNumber()); + // Case should have been handled by tryAttachBitwise. + MOZ_ASSERT(op_ != JSOp::BitNot); + if (!res_.isInt32()) { return AttachDecision::NoAction; } ValOperandId valId(writer.setInputOperandId(0)); StringOperandId stringId = writer.guardToString(valId); - Int32OperandId intId = writer.guardAndGetInt32FromString(stringId); + Int32OperandId intId = writer.guardStringToInt32(stringId); switch (op_) { - case JSOp::BitNot: - writer.int32NotResult(intId); - trackAttached("UnaryArith.StringInt32Not"); - break; case JSOp::Pos: writer.loadInt32Result(intId); trackAttached("UnaryArith.StringInt32Pos"); @@ -7659,17 +10715,15 @@ AttachDecision UnaryArithIRGenerator::tryAttachStringNumber() { } MOZ_ASSERT(res_.isNumber()); + // Case should have been handled by tryAttachBitwise. + MOZ_ASSERT(op_ != JSOp::BitNot); + ValOperandId valId(writer.setInputOperandId(0)); StringOperandId stringId = writer.guardToString(valId); - NumberOperandId numId = writer.guardAndGetNumberFromString(stringId); + NumberOperandId numId = writer.guardStringToNumber(stringId); Int32OperandId truncatedId; switch (op_) { - case JSOp::BitNot: - truncatedId = writer.truncateDoubleToUInt32(numId); - writer.int32NotResult(truncatedId); - trackAttached("UnaryArith.StringNumberNot"); - break; case JSOp::Pos: writer.loadDoubleResult(numId); trackAttached("UnaryArith.StringNumberPos"); @@ -7814,7 +10868,8 @@ AttachDecision BinaryArithIRGenerator::tryAttachStub() { // Arithmetic operations with Int32 operands TRY_ATTACH(tryAttachInt32()); - // Bitwise operations with Int32/Double/Boolean operands. + // Bitwise operations with Int32/Double/Boolean/Null/Undefined/String + // operands. TRY_ATTACH(tryAttachBitwise()); // Arithmetic operations with Double operands. This needs to come after @@ -7851,8 +10906,7 @@ AttachDecision BinaryArithIRGenerator::tryAttachBitwise() { } // Check guard conditions - if (!(lhs_.isNumber() || lhs_.isBoolean()) || - !(rhs_.isNumber() || rhs_.isBoolean())) { + if (!CanTruncateToInt32(lhs_) || !CanTruncateToInt32(rhs_)) { return AttachDecision::NoAction; } @@ -7862,21 +10916,8 @@ AttachDecision BinaryArithIRGenerator::tryAttachBitwise() { ValOperandId lhsId(writer.setInputOperandId(0)); ValOperandId rhsId(writer.setInputOperandId(1)); - // Convert type into int32 for the bitwise/shift operands. - auto guardToInt32 = [&](ValOperandId id, HandleValue val) { - if (val.isInt32()) { - return writer.guardToInt32(id); - } - if (val.isBoolean()) { - return writer.guardToBoolean(id); - } - MOZ_ASSERT(val.isDouble()); - NumberOperandId numId = writer.guardIsNumber(id); - return writer.truncateDoubleToUInt32(numId); - }; - - Int32OperandId lhsIntId = guardToInt32(lhsId, lhs_); - Int32OperandId rhsIntId = guardToInt32(rhsId, rhs_); + Int32OperandId lhsIntId = EmitTruncateToInt32Guard(writer, lhsId, lhs_); + Int32OperandId rhsIntId = EmitTruncateToInt32Guard(writer, rhsId, rhs_); switch (op_) { case JSOp::BitOr: @@ -7991,7 +11032,7 @@ AttachDecision BinaryArithIRGenerator::tryAttachInt32() { return writer.guardToInt32(id); } MOZ_ASSERT(v.isBoolean()); - return writer.guardToBoolean(id); + return writer.guardBooleanToInt32(id); }; Int32OperandId lhsIntId = guardToInt32(lhsId, lhs_); @@ -8044,23 +11085,8 @@ AttachDecision BinaryArithIRGenerator::tryAttachStringNumberConcat() { ValOperandId lhsId(writer.setInputOperandId(0)); ValOperandId rhsId(writer.setInputOperandId(1)); - auto guardToString = [&](ValOperandId id, HandleValue v) { - if (v.isString()) { - return writer.guardToString(id); - } - if (v.isInt32()) { - Int32OperandId intId = writer.guardToInt32(id); - return writer.callInt32ToString(intId); - } - // At this point we are creating an IC that will handle - // both Int32 and Double cases. - MOZ_ASSERT(v.isNumber()); - NumberOperandId numId = writer.guardIsNumber(id); - return writer.callNumberToString(numId); - }; - - StringOperandId lhsStrId = guardToString(lhsId, lhs_); - StringOperandId rhsStrId = guardToString(rhsId, rhs_); + StringOperandId lhsStrId = EmitToStringGuard(writer, lhsId, lhs_); + StringOperandId rhsStrId = EmitToStringGuard(writer, rhsId, rhs_); writer.callStringConcatResult(lhsStrId, rhsStrId); @@ -8088,8 +11114,8 @@ AttachDecision BinaryArithIRGenerator::tryAttachStringBooleanConcat() { return writer.guardToString(id); } MOZ_ASSERT(v.isBoolean()); - Int32OperandId intId = writer.guardToBoolean(id); - return writer.booleanToString(intId); + BooleanOperandId boolId = writer.guardToBoolean(id); + return writer.booleanToString(boolId); }; StringOperandId lhsStrId = guardToString(lhsId, lhs_); @@ -8276,7 +11302,7 @@ AttachDecision BinaryArithIRGenerator::tryAttachStringInt32Arith() { MOZ_ASSERT(v.isString()); StringOperandId strId = writer.guardToString(id); - return writer.guardAndGetInt32FromString(strId); + return writer.guardStringToInt32(strId); }; Int32OperandId lhsIntId = guardToInt32(lhsId, lhs_); @@ -8365,10 +11391,10 @@ AttachDecision NewObjectIRGenerator::tryAttachStub() { #ifdef JS_SIMULATOR bool js::jit::CallAnyNative(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); - RootedObject calleeObj(cx, &args.callee()); + JSObject* calleeObj = &args.callee(); MOZ_ASSERT(calleeObj->is()); - RootedFunction calleeFunc(cx, &calleeObj->as()); + auto* calleeFunc = &calleeObj->as(); MOZ_ASSERT(calleeFunc->isNativeWithoutJitEntry()); JSNative native = calleeFunc->native(); diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index f565528d75..cb8257ce8a 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -11,12 +11,14 @@ #include "NamespaceImports.h" +#include "builtin/TypedObject.h" #include "gc/Rooting.h" #include "jit/CacheIROpsGenerated.h" #include "jit/CompactBuffer.h" #include "jit/ICState.h" -#include "jit/MacroAssembler.h" #include "jit/Simulator.h" +#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo +#include "js/ScalarType.h" // js::Scalar::Type #include "vm/Iteration.h" #include "vm/Shape.h" @@ -26,6 +28,11 @@ namespace jit { enum class BaselineCacheIRStubKind; enum class InlinableNative : uint16_t; +class ICStub; +class ICScript; +class Label; +class MacroAssembler; + // [SMDOC] CacheIR // // CacheIR is an (extremely simple) linear IR language for inline caches. @@ -124,6 +131,12 @@ class BigIntOperandId : public OperandId { explicit BigIntOperandId(uint16_t id) : OperandId(id) {} }; +class BooleanOperandId : public OperandId { + public: + BooleanOperandId() = default; + explicit BooleanOperandId(uint16_t id) : OperandId(id) {} +}; + class Int32OperandId : public OperandId { public: Int32OperandId() = default; @@ -142,6 +155,8 @@ class TypedOperandId : public OperandId { : OperandId(id.id()), type_(JSVAL_TYPE_SYMBOL) {} MOZ_IMPLICIT TypedOperandId(BigIntOperandId id) : OperandId(id.id()), type_(JSVAL_TYPE_BIGINT) {} + MOZ_IMPLICIT TypedOperandId(BooleanOperandId id) + : OperandId(id.id()), type_(JSVAL_TYPE_BOOLEAN) {} MOZ_IMPLICIT TypedOperandId(Int32OperandId id) : OperandId(id.id()), type_(JSVAL_TYPE_INT32) {} MOZ_IMPLICIT TypedOperandId(ValueTagOperandId val) @@ -164,10 +179,12 @@ class TypedOperandId : public OperandId { _(BindName) \ _(In) \ _(HasOwn) \ + _(CheckPrivateField) \ _(TypeOf) \ _(ToPropertyKey) \ _(InstanceOf) \ _(GetIterator) \ + _(OptimizeSpreadCall) \ _(Compare) \ _(ToBool) \ _(Call) \ @@ -193,8 +210,17 @@ enum class CacheOp { #undef DEFINE_OP }; +// CacheIR opcode info that's read in performance-sensitive code. Stored as a +// single byte per op for better cache locality. +struct CacheIROpInfo { + uint8_t argLength : 7; + bool transpile : 1; +}; +static_assert(sizeof(CacheIROpInfo) == 1); +extern const CacheIROpInfo CacheIROpInfos[]; + extern const char* const CacheIROpNames[]; -extern const uint32_t CacheIROpArgLengths[]; +extern const uint32_t CacheIROpHealth[]; class StubField { public: @@ -206,6 +232,7 @@ class StubField { JSObject, Symbol, String, + BaseScript, Id, // These fields take up 64 bits on all platforms. @@ -266,6 +293,7 @@ class StubField { class CallFlags { public: enum ArgFormat : uint8_t { + Unknown, Standard, Spread, FunCall, @@ -274,12 +302,14 @@ class CallFlags { LastArgFormat = FunApplyArray }; - CallFlags(bool isConstructing, bool isSpread, bool isSameRealm = false) + CallFlags() = default; + explicit CallFlags(ArgFormat format) : argFormat_(format) {} + CallFlags(bool isConstructing, bool isSpread, bool isSameRealm = false, + bool needsUninitializedThis = false) : argFormat_(isSpread ? Spread : Standard), isConstructing_(isConstructing), - isSameRealm_(isSameRealm) {} - explicit CallFlags(ArgFormat format) - : argFormat_(format), isConstructing_(false), isSameRealm_(false) {} + isSameRealm_(isSameRealm), + needsUninitializedThis_(needsUninitializedThis) {} ArgFormat getArgFormat() const { return argFormat_; } bool isConstructing() const { @@ -289,8 +319,12 @@ class CallFlags { } bool isSameRealm() const { return isSameRealm_; } + bool needsUninitializedThis() const { return needsUninitializedThis_; } + void setNeedsUninitializedThis() { needsUninitializedThis_ = true; } + uint8_t toByte() const { // See CacheIRReader::callFlags() + MOZ_ASSERT(argFormat_ != ArgFormat::Unknown); uint8_t value = getArgFormat(); if (isConstructing()) { value |= CallFlags::IsConstructing; @@ -298,13 +332,17 @@ class CallFlags { if (isSameRealm()) { value |= CallFlags::IsSameRealm; } + if (needsUninitializedThis()) { + value |= CallFlags::NeedsUninitializedThis; + } return value; } private: - ArgFormat argFormat_; - bool isConstructing_; - bool isSameRealm_; + ArgFormat argFormat_ = ArgFormat::Unknown; + bool isConstructing_ = false; + bool isSameRealm_ = false; + bool needsUninitializedThis_ = false; // Used for encoding/decoding static const uint8_t ArgFormatBits = 4; @@ -312,6 +350,7 @@ class CallFlags { static_assert(LastArgFormat <= ArgFormatMask, "Not enough arg format bits"); static const uint8_t IsConstructing = 1 << 5; static const uint8_t IsSameRealm = 1 << 6; + static const uint8_t NeedsUninitializedThis = 1 << 7; friend class CacheIRReader; friend class CacheIRWriter; @@ -352,7 +391,15 @@ enum class AttachDecision { // Set of arguments supported by GetIndexOfArgument. // Support for higher argument indices can be added easily, but is currently // unneeded. -enum class ArgumentKind : uint8_t { Callee, This, NewTarget, Arg0, Arg1, Arg2 }; +enum class ArgumentKind : uint8_t { + Callee, + This, + NewTarget, + Arg0, + Arg1, + Arg2, + Arg3 +}; // This function calculates the index of an argument based on the call flags. // addArgc is an out-parameter, indicating whether the value of argc should @@ -382,6 +429,7 @@ inline int32_t GetIndexOfArgument(ArgumentKind kind, CallFlags flags, MOZ_ASSERT(kind <= ArgumentKind::Arg0); *addArgc = false; break; + case CallFlags::Unknown: case CallFlags::FunCall: case CallFlags::FunApplyArgs: case CallFlags::FunApplyArray: @@ -402,6 +450,8 @@ inline int32_t GetIndexOfArgument(ArgumentKind kind, CallFlags flags, return flags.isConstructing() + hasArgumentArray - 2; case ArgumentKind::Arg2: return flags.isConstructing() + hasArgumentArray - 3; + case ArgumentKind::Arg3: + return flags.isConstructing() + hasArgumentArray - 4; case ArgumentKind::NewTarget: MOZ_ASSERT(flags.isConstructing()); *addArgc = false; @@ -415,6 +465,9 @@ inline int32_t GetIndexOfArgument(ArgumentKind kind, CallFlags flags, // in the IR, to keep the IR compact and the same size on all platforms. enum class GuardClassKind : uint8_t { Array, + ArrayBuffer, + SharedArrayBuffer, + DataView, MappedArguments, UnmappedArguments, WindowProxy, @@ -469,6 +522,10 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { static const size_t MaxStubDataSizeInBytes = 20 * sizeof(uintptr_t); bool tooLarge_; + // Assume this stub can't be trial inlined until we see a scripted call/inline + // instruction. + TrialInliningState trialInliningState_ = TrialInliningState::Failure; + // Basic caching to avoid quadatic lookup behaviour in readStubFieldForIon. mutable uint32_t lastOffset_; mutable uint32_t lastIndex_; @@ -482,8 +539,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { void assertSameCompartment(JSObject*); void writeOp(CacheOp op) { - MOZ_ASSERT(uint32_t(op) <= UINT8_MAX); - buffer_.writeByte(uint32_t(op)); + buffer_.writeUnsigned15Bit(uint32_t(op)); nextInstructionId_++; #ifdef DEBUG MOZ_ASSERT(currentOp_.isNothing(), "Missing call to assertLengthMatches?"); @@ -495,7 +551,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { void assertLengthMatches() { #ifdef DEBUG // After writing arguments, assert the length matches CacheIROpArgLengths. - size_t expectedLen = CacheIROpArgLengths[size_t(*currentOp_)]; + size_t expectedLen = CacheIROpInfos[size_t(*currentOp_)].argLength; MOZ_ASSERT_IF(!failed(), buffer_.length() - currentOpArgsStart_ == expectedLen); currentOp_.reset(); @@ -547,6 +603,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { addStubField(uintptr_t(group), StubField::Type::ObjectGroup); } void writeObjectField(JSObject* obj) { + MOZ_ASSERT(obj); assertSameCompartment(obj); addStubField(uintptr_t(obj), StubField::Type::JSObject); } @@ -558,6 +615,10 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { MOZ_ASSERT(sym); addStubField(uintptr_t(sym), StubField::Type::Symbol); } + void writeBaseScriptField(BaseScript* script) { + MOZ_ASSERT(script); + addStubField(uintptr_t(script), StubField::Type::BaseScript); + } void writeRawWordField(uintptr_t word) { addStubField(word, StubField::Type::RawWord); } @@ -651,6 +712,8 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { bool failed() const { return buffer_.oom() || tooLarge_; } + TrialInliningState trialInliningState() const { return trialInliningState_; } + uint32_t numInputOperands() const { return numInputOperands_; } uint32_t numOperandIds() const { return nextOperandId_; } uint32_t numInstructions() const { return nextInstructionId_; } @@ -722,11 +785,25 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { return BigIntOperandId(input.id()); } + BooleanOperandId guardToBoolean(ValOperandId input) { + guardToBoolean_(input); + return BooleanOperandId(input.id()); + } + + Int32OperandId guardToInt32(ValOperandId input) { + guardToInt32_(input); + return Int32OperandId(input.id()); + } + NumberOperandId guardIsNumber(ValOperandId input) { guardIsNumber_(input); return NumberOperandId(input.id()); } + ValOperandId boxObject(ObjOperandId input) { + return ValOperandId(input.id()); + } + void guardShapeForClass(ObjOperandId obj, Shape* shape) { // Guard shape to ensure that object class is unchanged. This is true // for all shapes. @@ -762,20 +839,31 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { guardGroup(obj, group); } + static uint32_t encodeNargsAndFlags(JSFunction* fun) { + static_assert(JSFunction::NArgsBits == 16); + static_assert(sizeof(decltype(fun->flags().toRaw())) == sizeof(uint16_t)); + return (uint32_t(fun->nargs()) << 16) | fun->flags().toRaw(); + } + void guardSpecificFunction(ObjOperandId obj, JSFunction* expected) { // Guard object is a specific function. This implies immutable fields on // the JSFunction struct itself are unchanged. // Bake in the nargs and FunctionFlags so Warp can use them off-main thread, // instead of directly using the JSFunction fields. - static_assert(JSFunction::NArgsBits == 16); - static_assert(sizeof(decltype(expected->flags().toRaw())) == - sizeof(uint16_t)); - - uint32_t nargsAndFlags = - (uint32_t(expected->nargs()) << 16) | expected->flags().toRaw(); + uint32_t nargsAndFlags = encodeNargsAndFlags(expected); guardSpecificFunction_(obj, expected, nargsAndFlags); } + void guardFunctionScript(ObjOperandId fun, BaseScript* expected) { + // Guard function has a specific BaseScript. This implies immutable fields + // on the JSFunction struct itself are unchanged and are equivalent for + // lambda clones. + // Bake in the nargs and FunctionFlags so Warp can use them off-main thread, + // instead of directly using the JSFunction fields. + uint32_t nargsAndFlags = encodeNargsAndFlags(expected->function()); + guardFunctionScript_(fun, expected, nargsAndFlags); + } + ValOperandId loadArgumentFixedSlot( ArgumentKind kind, uint32_t argc, CallFlags flags = CallFlags(CallFlags::Standard)) { @@ -808,6 +896,18 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { return loadArgumentFixedSlot_(slotIndex); } + void callScriptedFunction(ObjOperandId callee, Int32OperandId argc, + CallFlags flags) { + callScriptedFunction_(callee, argc, flags); + trialInliningState_ = TrialInliningState::Candidate; + } + + void callInlinedFunction(ObjOperandId callee, Int32OperandId argc, + ICScript* icScript, CallFlags flags) { + callInlinedFunction_(callee, argc, icScript, flags); + trialInliningState_ = TrialInliningState::Inlined; + } + void callNativeFunction(ObjOperandId calleeId, Int32OperandId argc, JSOp op, HandleFunction calleeFunc, CallFlags flags) { // Some native functions can be implemented faster if we know that @@ -868,6 +968,34 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { callClassHook_(calleeId, argc, flags, target); } + void callScriptedGetterResult(ValOperandId receiver, JSFunction* getter, + bool sameRealm) { + MOZ_ASSERT(getter->hasJitEntry()); + uint32_t nargsAndFlags = encodeNargsAndFlags(getter); + callScriptedGetterResult_(receiver, getter, sameRealm, nargsAndFlags); + } + + void callNativeGetterResult(ValOperandId receiver, JSFunction* getter, + bool sameRealm) { + MOZ_ASSERT(getter->isNativeWithoutJitEntry()); + uint32_t nargsAndFlags = encodeNargsAndFlags(getter); + callNativeGetterResult_(receiver, getter, sameRealm, nargsAndFlags); + } + + void callScriptedSetter(ObjOperandId receiver, JSFunction* setter, + ValOperandId rhs, bool sameRealm) { + MOZ_ASSERT(setter->hasJitEntry()); + uint32_t nargsAndFlags = encodeNargsAndFlags(setter); + callScriptedSetter_(receiver, setter, rhs, sameRealm, nargsAndFlags); + } + + void callNativeSetter(ObjOperandId receiver, JSFunction* setter, + ValOperandId rhs, bool sameRealm) { + MOZ_ASSERT(setter->isNativeWithoutJitEntry()); + uint32_t nargsAndFlags = encodeNargsAndFlags(setter); + callNativeSetter_(receiver, setter, rhs, sameRealm, nargsAndFlags); + } + // These generate no code, but save the template object in a stub // field for BaselineInspector. void metaNativeTemplateObject(JSFunction* callee, JSObject* templateObject) { @@ -879,6 +1007,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter { metaTwoByte_(MetaTwoByteKind::ScriptedTemplateObject, callee, templateObject); } + friend class CacheIRCloner; CACHE_IR_WRITER_GENERATED }; @@ -901,7 +1030,7 @@ class MOZ_RAII CacheIRReader { bool more() const { return buffer_.more(); } - CacheOp readOp() { return CacheOp(buffer_.readByte()); } + CacheOp readOp() { return CacheOp(buffer_.readUnsigned15Bit()); } // Skip data not currently used. void skip() { buffer_.readByte(); } @@ -932,6 +1061,10 @@ class MOZ_RAII CacheIRReader { return BigIntOperandId(buffer_.readByte()); } + BooleanOperandId booleanOperandId() { + return BooleanOperandId(buffer_.readByte()); + } + Int32OperandId int32OperandId() { return Int32OperandId(buffer_.readByte()); } uint32_t rawOperandId() { return buffer_.readByte(); } @@ -973,11 +1106,17 @@ class MOZ_RAII CacheIRReader { CallFlags::ArgFormat(encoded & CallFlags::ArgFormatMask); bool isConstructing = encoded & CallFlags::IsConstructing; bool isSameRealm = encoded & CallFlags::IsSameRealm; + bool needsUninitializedThis = encoded & CallFlags::NeedsUninitializedThis; + MOZ_ASSERT_IF(needsUninitializedThis, isConstructing); switch (format) { + case CallFlags::Unknown: + MOZ_CRASH("Unexpected call flags"); case CallFlags::Standard: - return CallFlags(isConstructing, /*isSpread =*/false, isSameRealm); + return CallFlags(isConstructing, /*isSpread =*/false, isSameRealm, + needsUninitializedThis); case CallFlags::Spread: - return CallFlags(isConstructing, /*isSpread =*/true, isSameRealm); + return CallFlags(isConstructing, /*isSpread =*/true, isSameRealm, + needsUninitializedThis); default: // The existing non-standard argument formats (FunCall and FunApply) // can't be constructors and have no support for isSameRealm. @@ -1023,6 +1162,36 @@ class MOZ_RAII CacheIRReader { const uint8_t* currentPosition() const { return buffer_.currentPosition(); } }; +class MOZ_RAII CacheIRCloner { + public: + explicit CacheIRCloner(ICStub* stubInfo); + + void cloneOp(CacheOp op, CacheIRReader& reader, CacheIRWriter& writer); + + CACHE_IR_CLONE_GENERATED + + private: + const CacheIRStubInfo* stubInfo_; + const uint8_t* stubData_; + + uintptr_t readStubWord(uint32_t offset); + int64_t readStubInt64(uint32_t offset); + + Shape* getShapeField(uint32_t stubOffset); + ObjectGroup* getGroupField(uint32_t stubOffset); + JSObject* getObjectField(uint32_t stubOffset); + JSString* getStringField(uint32_t stubOffset); + JSAtom* getAtomField(uint32_t stubOffset); + PropertyName* getPropertyNameField(uint32_t stubOffset); + JS::Symbol* getSymbolField(uint32_t stubOffset); + BaseScript* getBaseScriptField(uint32_t stubOffset); + uintptr_t getRawWordField(uint32_t stubOffset); + const void* getRawPointerField(uint32_t stubOffset); + jsid getIdField(uint32_t stubOffset); + const Value getValueField(uint32_t stubOffset); + uint64_t getDOMExpandoGenerationField(uint32_t stubOffset); +}; + class MOZ_RAII IRGenerator { protected: CacheIRWriter writer; @@ -1045,6 +1214,8 @@ class MOZ_RAII IRGenerator { void emitIdGuard(ValOperandId valId, jsid id); + OperandId emitNumericGuard(ValOperandId valId, Scalar::Type type); + friend class CacheIRSpewer; public: @@ -1102,7 +1273,7 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator { PreliminaryObjectAction preliminaryObjectAction_; AttachDecision tryAttachNative(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachUnboxed(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachUnboxedExpando(HandleObject obj, ObjOperandId objId, @@ -1122,20 +1293,22 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator { HandleId id); AttachDecision tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, + ValOperandId receiverId); AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id, bool handleDOMProxies); AttachDecision tryAttachDOMProxyExpando(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId, HandleId id); AttachDecision tryAttachDOMProxyUnshadowed(HandleObject obj, - ObjOperandId objId, HandleId id); + ObjOperandId objId, HandleId id, + ValOperandId receiverId); AttachDecision tryAttachProxy(HandleObject obj, ObjOperandId objId, - HandleId id); + HandleId id, ValOperandId receiverId); AttachDecision tryAttachPrimitive(ValOperandId valId, HandleId id); AttachDecision tryAttachStringChar(ValOperandId valId, ValOperandId indexId); @@ -1145,7 +1318,7 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator { AttachDecision tryAttachMagicArgument(ValOperandId valId, ValOperandId indexId); AttachDecision tryAttachArgumentsObjectArg(HandleObject obj, - ObjOperandId objId, + ObjOperandId objId, uint32_t index, Int32OperandId indexId); AttachDecision tryAttachDenseElement(HandleObject obj, ObjOperandId objId, @@ -1330,8 +1503,6 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator { // matches |id|. void maybeEmitIdGuard(jsid id); - OperandId emitNumericGuard(ValOperandId valId, Scalar::Type type); - AttachDecision tryAttachNativeSetSlot(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId); AttachDecision tryAttachUnboxedExpandoSetSlot(HandleObject obj, @@ -1467,6 +1638,23 @@ class MOZ_RAII HasPropIRGenerator : public IRGenerator { AttachDecision tryAttachStub(); }; +class MOZ_RAII CheckPrivateFieldIRGenerator : public IRGenerator { + HandleValue val_; + HandleValue idVal_; + + AttachDecision tryAttachNative(JSObject* obj, ObjOperandId objId, jsid key, + ValOperandId keyId, bool hasOwn); + + void trackAttached(const char* name); + + public: + CheckPrivateFieldIRGenerator(JSContext* cx, HandleScript script, + jsbytecode* pc, ICState::Mode mode, + CacheKind cacheKind, HandleValue idVal, + HandleValue val); + AttachDecision tryAttachStub(); +}; + class MOZ_RAII InstanceOfIRGenerator : public IRGenerator { HandleValue lhsVal_; HandleObject rhsObj_; @@ -1508,11 +1696,34 @@ class MOZ_RAII GetIteratorIRGenerator : public IRGenerator { void trackAttached(const char* name); }; +class MOZ_RAII OptimizeSpreadCallIRGenerator : public IRGenerator { + HandleValue val_; + + AttachDecision tryAttachArray(); + AttachDecision tryAttachNotOptimizable(); + + public: + OptimizeSpreadCallIRGenerator(JSContext* cx, HandleScript script, + jsbytecode* pc, ICState::Mode mode, + HandleValue value); + + AttachDecision tryAttachStub(); + + void trackAttached(const char* name); +}; + enum class StringChar { CodeAt, At }; +enum class ScriptedThisResult { + NoAction, + TemporarilyUnoptimizable, + UninitializedThis, + TemplateObject +}; class MOZ_RAII CallIRGenerator : public IRGenerator { private: JSOp op_; + bool isFirstStub_; uint32_t argc_; HandleValue callee_; HandleValue thisval_; @@ -1521,52 +1732,125 @@ class MOZ_RAII CallIRGenerator : public IRGenerator { PropertyTypeCheckInfo typeCheckInfo_; BaselineCacheIRStubKind cacheIRStubKind_; - bool getTemplateObjectForScripted(HandleFunction calleeFunc, - MutableHandleObject result, - bool* skipAttach); + ScriptedThisResult getThisForScripted(HandleFunction calleeFunc, + MutableHandleObject result); bool getTemplateObjectForNative(HandleFunction calleeFunc, MutableHandleObject result); void emitNativeCalleeGuard(HandleFunction callee); + void emitCalleeGuard(ObjOperandId calleeId, HandleFunction callee); + + bool canAttachAtomicsReadWriteModify(); + + struct AtomicsReadWriteModifyOperands { + ObjOperandId objId; + Int32OperandId int32IndexId; + Int32OperandId int32ValueId; + }; + + AtomicsReadWriteModifyOperands emitAtomicsReadWriteModifyOperands( + HandleFunction callee); AttachDecision tryAttachArrayPush(HandleFunction callee); + AttachDecision tryAttachArrayPopShift(HandleFunction callee, + InlinableNative native); AttachDecision tryAttachArrayJoin(HandleFunction callee); + AttachDecision tryAttachArraySlice(HandleFunction callee); AttachDecision tryAttachArrayIsArray(HandleFunction callee); + AttachDecision tryAttachDataViewGet(HandleFunction callee, Scalar::Type type); + AttachDecision tryAttachDataViewSet(HandleFunction callee, Scalar::Type type); AttachDecision tryAttachUnsafeGetReservedSlot(HandleFunction callee, InlinableNative native); + AttachDecision tryAttachUnsafeSetReservedSlot(HandleFunction callee); AttachDecision tryAttachIsSuspendedGenerator(HandleFunction callee); - AttachDecision tryAttachToString(HandleFunction callee, - InlinableNative native); AttachDecision tryAttachToObject(HandleFunction callee, InlinableNative native); AttachDecision tryAttachToInteger(HandleFunction callee); AttachDecision tryAttachToLength(HandleFunction callee); AttachDecision tryAttachIsObject(HandleFunction callee); + AttachDecision tryAttachIsPackedArray(HandleFunction callee); AttachDecision tryAttachIsCallable(HandleFunction callee); AttachDecision tryAttachIsConstructor(HandleFunction callee); + AttachDecision tryAttachIsCrossRealmArrayConstructor(HandleFunction callee); AttachDecision tryAttachGuardToClass(HandleFunction callee, InlinableNative native); - AttachDecision tryAttachHasClass(HandleFunction callee, const JSClass* clasp); + AttachDecision tryAttachHasClass(HandleFunction callee, const JSClass* clasp, + bool isPossiblyWrapped); AttachDecision tryAttachRegExpMatcherSearcherTester(HandleFunction callee, InlinableNative native); AttachDecision tryAttachRegExpPrototypeOptimizable(HandleFunction callee); AttachDecision tryAttachRegExpInstanceOptimizable(HandleFunction callee); + AttachDecision tryAttachGetFirstDollarIndex(HandleFunction callee); AttachDecision tryAttachSubstringKernel(HandleFunction callee); + AttachDecision tryAttachObjectHasPrototype(HandleFunction callee); + AttachDecision tryAttachString(HandleFunction callee); + AttachDecision tryAttachStringConstructor(HandleFunction callee); + AttachDecision tryAttachStringToStringValueOf(HandleFunction callee); AttachDecision tryAttachStringChar(HandleFunction callee, StringChar kind); AttachDecision tryAttachStringCharCodeAt(HandleFunction callee); AttachDecision tryAttachStringCharAt(HandleFunction callee); AttachDecision tryAttachStringFromCharCode(HandleFunction callee); + AttachDecision tryAttachStringFromCodePoint(HandleFunction callee); + AttachDecision tryAttachStringToLowerCase(HandleFunction callee); + AttachDecision tryAttachStringToUpperCase(HandleFunction callee); + AttachDecision tryAttachStringReplaceString(HandleFunction callee); + AttachDecision tryAttachStringSplitString(HandleFunction callee); AttachDecision tryAttachMathRandom(HandleFunction callee); AttachDecision tryAttachMathAbs(HandleFunction callee); + AttachDecision tryAttachMathClz32(HandleFunction callee); + AttachDecision tryAttachMathSign(HandleFunction callee); + AttachDecision tryAttachMathImul(HandleFunction callee); AttachDecision tryAttachMathFloor(HandleFunction callee); AttachDecision tryAttachMathCeil(HandleFunction callee); + AttachDecision tryAttachMathTrunc(HandleFunction callee); AttachDecision tryAttachMathRound(HandleFunction callee); AttachDecision tryAttachMathSqrt(HandleFunction callee); + AttachDecision tryAttachMathFRound(HandleFunction callee); + AttachDecision tryAttachMathHypot(HandleFunction callee); AttachDecision tryAttachMathATan2(HandleFunction callee); AttachDecision tryAttachMathFunction(HandleFunction callee, UnaryMathFunction fun); AttachDecision tryAttachMathPow(HandleFunction callee); AttachDecision tryAttachMathMinMax(HandleFunction callee, bool isMax); + AttachDecision tryAttachIsTypedArray(HandleFunction callee, + bool isPossiblyWrapped); + AttachDecision tryAttachIsTypedArrayConstructor(HandleFunction callee); + AttachDecision tryAttachTypedArrayByteOffset(HandleFunction callee); + AttachDecision tryAttachTypedArrayElementShift(HandleFunction callee); + AttachDecision tryAttachTypedArrayLength(HandleFunction callee, + bool isPossiblyWrapped); + AttachDecision tryAttachArrayBufferByteLength(HandleFunction callee, + bool isPossiblyWrapped); + AttachDecision tryAttachIsConstructing(HandleFunction callee); + AttachDecision tryAttachGetNextMapSetEntryForIterator(HandleFunction callee, + bool isMap); + AttachDecision tryAttachFinishBoundFunctionInit(HandleFunction callee); + AttachDecision tryAttachNewArrayIterator(HandleFunction callee); + AttachDecision tryAttachNewStringIterator(HandleFunction callee); + AttachDecision tryAttachNewRegExpStringIterator(HandleFunction callee); + AttachDecision tryAttachArrayIteratorPrototypeOptimizable( + HandleFunction callee); + AttachDecision tryAttachObjectCreate(HandleFunction callee); + AttachDecision tryAttachArrayConstructor(HandleFunction callee); + AttachDecision tryAttachTypedArrayConstructor(HandleFunction callee); + AttachDecision tryAttachNumberToString(HandleFunction callee); + AttachDecision tryAttachReflectGetPrototypeOf(HandleFunction callee); + AttachDecision tryAttachAtomicsCompareExchange(HandleFunction callee); + AttachDecision tryAttachAtomicsExchange(HandleFunction callee); + AttachDecision tryAttachAtomicsAdd(HandleFunction callee); + AttachDecision tryAttachAtomicsSub(HandleFunction callee); + AttachDecision tryAttachAtomicsAnd(HandleFunction callee); + AttachDecision tryAttachAtomicsOr(HandleFunction callee); + AttachDecision tryAttachAtomicsXor(HandleFunction callee); + AttachDecision tryAttachAtomicsLoad(HandleFunction callee); + AttachDecision tryAttachAtomicsStore(HandleFunction callee); + AttachDecision tryAttachAtomicsIsLockFree(HandleFunction callee); + AttachDecision tryAttachBoolean(HandleFunction callee); + AttachDecision tryAttachBailout(HandleFunction callee); + AttachDecision tryAttachAssertFloat32(HandleFunction callee); + AttachDecision tryAttachAssertRecoveredOnBailout(HandleFunction callee); + AttachDecision tryAttachObjectIs(HandleFunction callee); + AttachDecision tryAttachObjectIsPrototypeOf(HandleFunction callee); AttachDecision tryAttachFunCall(HandleFunction calleeFunc); AttachDecision tryAttachFunApply(HandleFunction calleeFunc); @@ -1579,9 +1863,9 @@ class MOZ_RAII CallIRGenerator : public IRGenerator { public: CallIRGenerator(JSContext* cx, HandleScript script, jsbytecode* pc, JSOp op, - ICState::Mode mode, uint32_t argc, HandleValue callee, - HandleValue thisval, HandleValue newTarget, - HandleValueArray args); + ICState::Mode mode, bool isFirstStub, uint32_t argc, + HandleValue callee, HandleValue thisval, + HandleValue newTarget, HandleValueArray args); AttachDecision tryAttachStub(); @@ -1670,6 +1954,7 @@ class MOZ_RAII UnaryArithIRGenerator : public IRGenerator { AttachDecision tryAttachInt32(); AttachDecision tryAttachNumber(); + AttachDecision tryAttachBitwise(); AttachDecision tryAttachBigInt(); AttachDecision tryAttachStringInt32(); AttachDecision tryAttachStringNumber(); @@ -1764,6 +2049,9 @@ inline ReferenceType ReferenceTypeFromSimpleTypeDescrKey(uint32_t key) { // Returns whether obj is a WindowProxy wrapping the script's global. extern bool IsWindowProxyForScriptGlobal(JSScript* script, JSObject* obj); +// Retrieve Xray JIT info set by the embedder. +extern JS::XrayJitInfo* GetXrayJitInfo(); + } // namespace jit } // namespace js diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index 3d5d083c5a..280ee86738 100644 --- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -6,6 +6,7 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/FunctionTypeTraits.h" +#include "mozilla/MaybeOneOf.h" #include "mozilla/ScopeExit.h" #include @@ -14,12 +15,17 @@ #include "jslibmath.h" #include "jsmath.h" +#include "builtin/DataViewObject.h" +#include "builtin/MapObject.h" #include "gc/Allocator.h" #include "jit/BaselineCacheIRCompiler.h" #include "jit/IonCacheIRCompiler.h" #include "jit/IonIC.h" #include "jit/SharedICHelpers.h" #include "jit/SharedICRegisters.h" +#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration +#include "js/friend/XrayJitInfo.h" // js::jit::GetXrayJitInfo +#include "js/ScalarType.h" // js::Scalar::Type #include "proxy/Proxy.h" #include "vm/ArrayBufferObject.h" #include "vm/ArrayBufferViewObject.h" @@ -40,6 +46,8 @@ using namespace js::jit; using mozilla::BitwiseCast; using mozilla::Maybe; +using JS::ExpandoAndGeneration; + ValueOperand CacheRegisterAllocator::useValueRegister(MacroAssembler& masm, ValOperandId op) { OperandLocation& loc = operandLocations_[op.id()]; @@ -111,12 +119,12 @@ ValueOperand CacheRegisterAllocator::useValueRegister(MacroAssembler& masm, // guarded isNumber on the provided val. void CacheRegisterAllocator::ensureDoubleRegister(MacroAssembler& masm, NumberOperandId op, - FloatRegister dest) { + FloatRegister dest) const { // If AutoScratchFloatRegister is active, we have to add sizeof(double) to // any stack slot offsets below. int32_t stackOffset = hasAutoScratchFloatRegisterSpill() ? sizeof(double) : 0; - OperandLocation& loc = operandLocations_[op.id()]; + const OperandLocation& loc = operandLocations_[op.id()]; Label failure, done; switch (loc.kind()) { @@ -181,6 +189,53 @@ void CacheRegisterAllocator::ensureDoubleRegister(MacroAssembler& masm, masm.bind(&done); } +void CacheRegisterAllocator::copyToScratchRegister(MacroAssembler& masm, + TypedOperandId typedId, + Register dest) const { + // If AutoScratchFloatRegister is active, we have to add sizeof(double) to + // any stack slot offsets below. + int32_t stackOffset = hasAutoScratchFloatRegisterSpill() ? sizeof(double) : 0; + + const OperandLocation& loc = operandLocations_[typedId.id()]; + + Label failure, done; + switch (loc.kind()) { + case OperandLocation::ValueReg: { + masm.unboxNonDouble(loc.valueReg(), dest, typedId.type()); + break; + } + case OperandLocation::ValueStack: { + Address addr = valueAddress(masm, &loc); + addr.offset += stackOffset; + masm.unboxNonDouble(addr, dest, typedId.type()); + break; + } + case OperandLocation::BaselineFrame: { + Address addr = addressOf(masm, loc.baselineFrameSlot()); + addr.offset += stackOffset; + masm.unboxNonDouble(addr, dest, typedId.type()); + break; + } + case OperandLocation::PayloadReg: { + MOZ_ASSERT(loc.payloadType() == typedId.type()); + masm.mov(loc.payloadReg(), dest); + return; + } + case OperandLocation::PayloadStack: { + MOZ_ASSERT(loc.payloadType() == typedId.type()); + MOZ_ASSERT(loc.payloadStack() <= stackPushed_); + Address addr(masm.getStackPointer(), stackPushed_ - loc.payloadStack()); + addr.offset += stackOffset; + masm.loadPtr(addr, dest); + return; + } + case OperandLocation::DoubleReg: + case OperandLocation::Constant: + case OperandLocation::Uninitialized: + MOZ_CRASH("Unhandled operand location"); + } +} + ValueOperand CacheRegisterAllocator::useFixedValueRegister(MacroAssembler& masm, ValOperandId valId, ValueOperand reg) { @@ -776,7 +831,7 @@ void CacheRegisterAllocator::popPayload(MacroAssembler& masm, } Address CacheRegisterAllocator::valueAddress(MacroAssembler& masm, - OperandLocation* loc) { + const OperandLocation* loc) const { MOZ_ASSERT(loc >= operandLocations_.begin() && loc < operandLocations_.end()); return Address(masm.getStackPointer(), stackPushed_ - loc->valueStack()); } @@ -987,6 +1042,26 @@ uintptr_t CacheIRStubInfo::getStubRawWord(ICStub* stub, uint32_t offset) const { return getStubRawWord(stubData, offset); } +int64_t CacheIRStubInfo::getStubRawInt64(const uint8_t* stubData, + uint32_t offset) const { + MOZ_ASSERT(uintptr_t(stubData) % sizeof(int64_t) == 0); + return *reinterpret_cast(stubData + offset); +} + +int64_t CacheIRStubInfo::getStubRawInt64(ICStub* stub, uint32_t offset) const { + uint8_t* stubData = (uint8_t*)stub + stubDataOffset_; + return getStubRawInt64(stubData, offset); +} + +void CacheIRStubInfo::replaceStubRawWord(uint8_t* stubData, uint32_t offset, + uintptr_t oldWord, + uintptr_t newWord) const { + MOZ_ASSERT(uintptr_t(stubData) % sizeof(uintptr_t) == 0); + uintptr_t* addr = reinterpret_cast(stubData + offset); + MOZ_ASSERT(*addr == oldWord); + *addr = newWord; +} + template GCPtr& CacheIRStubInfo::getStubField(Stub* stub, uint32_t offset) const { uint8_t* stubData = (uint8_t*)stub + stubDataOffset_; @@ -1046,6 +1121,9 @@ void CacheIRWriter::copyStubData(uint8_t* dest) const { case StubField::Type::String: InitGCPtr(destWords, field.asWord()); break; + case StubField::Type::BaseScript: + InitGCPtr(destWords, field.asWord()); + break; case StubField::Type::Id: AsGCPtr(destWords)->init(jsid::fromRawBits(field.asWord())); break; @@ -1077,28 +1155,28 @@ void jit::TraceCacheIRStub(JSTracer* trc, T* stub, case StubField::Type::DOMExpandoGeneration: break; case StubField::Type::Shape: - TraceNullableEdge(trc, &stubInfo->getStubField(stub, offset), - "cacheir-shape"); + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-shape"); break; case StubField::Type::ObjectGroup: - TraceNullableEdge( - trc, &stubInfo->getStubField(stub, offset), - "cacheir-group"); + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-group"); break; case StubField::Type::JSObject: - TraceNullableEdge(trc, - &stubInfo->getStubField(stub, offset), - "cacheir-object"); + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-object"); break; case StubField::Type::Symbol: - TraceNullableEdge(trc, - &stubInfo->getStubField(stub, offset), - "cacheir-symbol"); + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-symbol"); break; case StubField::Type::String: - TraceNullableEdge(trc, - &stubInfo->getStubField(stub, offset), - "cacheir-string"); + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-string"); + break; + case StubField::Type::BaseScript: + TraceEdge(trc, &stubInfo->getStubField(stub, offset), + "cacheir-script"); break; case StubField::Type::Id: TraceEdge(trc, &stubInfo->getStubField(stub, offset), @@ -1458,13 +1536,14 @@ bool CacheIRCompiler::emitGuardIsObjectOrNull(ValOperandId inputId) { return true; } -bool CacheIRCompiler::emitGuardToBoolean(ValOperandId inputId, - Int32OperandId resultId) { +bool CacheIRCompiler::emitGuardBooleanToInt32(ValOperandId inputId, + Int32OperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register output = allocator.defineRegister(masm, resultId); if (allocator.knownType(inputId) == JSVAL_TYPE_BOOLEAN) { - Register input = allocator.useRegister(masm, Int32OperandId(inputId.id())); + Register input = + allocator.useRegister(masm, BooleanOperandId(inputId.id())); masm.move32(input, output); return true; } @@ -1475,8 +1554,7 @@ bool CacheIRCompiler::emitGuardToBoolean(ValOperandId inputId, return false; } - masm.branchTestBoolean(Assembler::NotEqual, input, failure->label()); - masm.unboxBoolean(input, output); + masm.fallibleUnboxBoolean(input, output, failure->label()); return true; } @@ -1525,16 +1603,29 @@ bool CacheIRCompiler::emitGuardToBigInt(ValOperandId inputId) { return true; } -bool CacheIRCompiler::emitGuardToInt32(ValOperandId inputId, - Int32OperandId resultId) { +bool CacheIRCompiler::emitGuardToBoolean(ValOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + if (allocator.knownType(inputId) == JSVAL_TYPE_BOOLEAN) { + return true; + } + + ValueOperand input = allocator.useValueRegister(masm, inputId); + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + masm.branchTestBoolean(Assembler::NotEqual, input, failure->label()); + return true; +} + +bool CacheIRCompiler::emitGuardToInt32(ValOperandId inputId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register output = allocator.defineRegister(masm, resultId); if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) { - Register input = allocator.useRegister(masm, Int32OperandId(inputId.id())); - masm.move32(input, output); return true; } + ValueOperand input = allocator.useValueRegister(masm, inputId); FailurePath* failure; @@ -1543,7 +1634,6 @@ bool CacheIRCompiler::emitGuardToInt32(ValOperandId inputId, } masm.branchTestInt32(Assembler::NotEqual, input, failure->label()); - masm.unboxInt32(input, output); return true; } @@ -1817,6 +1907,15 @@ bool CacheIRCompiler::emitGuardClass(ObjOperandId objId, GuardClassKind kind) { case GuardClassKind::Array: clasp = &ArrayObject::class_; break; + case GuardClassKind::ArrayBuffer: + clasp = &ArrayBufferObject::class_; + break; + case GuardClassKind::SharedArrayBuffer: + clasp = &SharedArrayBufferObject::class_; + break; + case GuardClassKind::DataView: + clasp = &DataViewObject::class_; + break; case GuardClassKind::MappedArguments: clasp = &MappedArgumentsObject::class_; break; @@ -1843,6 +1942,21 @@ bool CacheIRCompiler::emitGuardClass(ObjOperandId objId, GuardClassKind kind) { return true; } +bool CacheIRCompiler::emitGuardNullProto(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.loadObjProto(obj, scratch); + masm.branchTestPtr(Assembler::NonZero, scratch, scratch, failure->label()); + return true; +} + bool CacheIRCompiler::emitGuardIsExtensible(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); @@ -1871,35 +1985,11 @@ bool CacheIRCompiler::emitGuardIsExtensible(ObjOperandId objId) { return true; } -bool CacheIRCompiler::emitGuardSpecificNativeFunction(ObjOperandId objId, - JSNative native) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - Register obj = allocator.useRegister(masm, objId); - AutoScratchRegister scratch(allocator, masm); - - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } - - // Ensure obj is a function. - const JSClass* clasp = &JSFunction::class_; - masm.branchTestObjClass(Assembler::NotEqual, obj, clasp, scratch, obj, - failure->label()); - - // Ensure function native matches. - masm.branchPtr(Assembler::NotEqual, - Address(obj, JSFunction::offsetOfNativeOrEnv()), - ImmPtr(native), failure->label()); - return true; -} - -bool CacheIRCompiler::emitGuardFunctionPrototype(ObjOperandId objId, - ObjOperandId protoId, - uint32_t slotOffset) { +bool CacheIRCompiler::emitGuardDynamicSlotIsSpecificObject( + ObjOperandId objId, ObjOperandId expectedId, uint32_t slotOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); - Register prototypeObject = allocator.useRegister(masm, protoId); + Register expectedObject = allocator.useRegister(masm, expectedId); // Allocate registers before the failure path to make sure they're registered // by addFailurePath. @@ -1911,14 +2001,13 @@ bool CacheIRCompiler::emitGuardFunctionPrototype(ObjOperandId objId, return false; } - // Guard on the .prototype object. + // Guard on the expected object. StubFieldOffset slot(slotOffset, StubField::Type::RawWord); masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch1); emitLoadStubField(slot, scratch2); - BaseObjectSlotIndex prototypeSlot(scratch1, scratch2); - masm.branchTestObject(Assembler::NotEqual, prototypeSlot, failure->label()); - masm.unboxObject(prototypeSlot, scratch1); - masm.branchPtr(Assembler::NotEqual, prototypeObject, scratch1, + BaseObjectSlotIndex expectedSlot(scratch1, scratch2); + masm.fallibleUnboxObject(expectedSlot, scratch1, failure->label()); + masm.branchPtr(Assembler::NotEqual, expectedObject, scratch1, failure->label()); return true; @@ -1926,6 +2015,7 @@ bool CacheIRCompiler::emitGuardFunctionPrototype(ObjOperandId objId, bool CacheIRCompiler::emitGuardIsNativeObject(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); AutoScratchRegister scratch(allocator, masm); @@ -1940,6 +2030,7 @@ bool CacheIRCompiler::emitGuardIsNativeObject(ObjOperandId objId) { bool CacheIRCompiler::emitGuardIsProxy(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); AutoScratchRegister scratch(allocator, masm); @@ -1952,7 +2043,57 @@ bool CacheIRCompiler::emitGuardIsProxy(ObjOperandId objId) { return true; } -bool CacheIRCompiler::emitGuardNotDOMProxy(ObjOperandId objId) { +bool CacheIRCompiler::emitGuardIsNotProxy(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.branchTestObjectIsProxy(true, obj, scratch, failure->label()); + return true; +} + +bool CacheIRCompiler::emitGuardIsNotArrayBufferMaybeShared(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.loadObjClassUnsafe(obj, scratch); + masm.branchPtr(Assembler::Equal, scratch, ImmPtr(&ArrayBufferObject::class_), + failure->label()); + masm.branchPtr(Assembler::Equal, scratch, + ImmPtr(&SharedArrayBufferObject::class_), failure->label()); + return true; +} + +bool CacheIRCompiler::emitGuardIsTypedArray(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.loadObjClassUnsafe(obj, scratch); + masm.branchIfClassIsNotTypedArray(scratch, failure->label()); + return true; +} + +bool CacheIRCompiler::emitGuardIsNotDOMProxy(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register obj = allocator.useRegister(masm, objId); AutoScratchRegister scratch(allocator, masm); @@ -2001,8 +2142,8 @@ bool CacheIRCompiler::emitGuardNoDenseElements(ObjOperandId objId) { return true; } -bool CacheIRCompiler::emitGuardAndGetInt32FromString(StringOperandId strId, - Int32OperandId resultId) { +bool CacheIRCompiler::emitGuardStringToInt32(StringOperandId strId, + Int32OperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register str = allocator.useRegister(masm, strId); Register output = allocator.defineRegister(masm, resultId); @@ -2013,58 +2154,14 @@ bool CacheIRCompiler::emitGuardAndGetInt32FromString(StringOperandId strId, return false; } - Label vmCall, done; - // Use indexed value as fast path if possible. - masm.loadStringIndexValue(str, output, &vmCall); - masm.jump(&done); - { - masm.bind(&vmCall); - - // Reserve stack for holding the result value of the call. - masm.reserveStack(sizeof(int32_t)); - masm.moveStackPtrTo(output); - - // We cannot use callVM, as callVM expects to be able to clobber all - // operands, however, since this op is not the last in the generated IC, we - // want to be able to reference other live values. - LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), - liveVolatileFloatRegs()); - masm.PushRegsInMask(volatileRegs); - - masm.setupUnalignedABICall(scratch); - masm.loadJSContext(scratch); - masm.passABIArg(scratch); - masm.passABIArg(str); - masm.passABIArg(output); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetInt32FromStringPure)); - masm.mov(ReturnReg, scratch); - - LiveRegisterSet ignore; - ignore.add(scratch); - masm.PopRegsInMaskIgnore(volatileRegs, ignore); - - Label ok; - masm.branchIfTrueBool(scratch, &ok); - { - // OOM path, recovered by GetInt32FromStringPure. - // - // Use addToStackPtr instead of freeStack as freeStack tracks stack height - // flow-insensitively, and using it twice would confuse the stack height - // tracking. - masm.addToStackPtr(Imm32(sizeof(int32_t))); - masm.jump(failure->label()); - } - masm.bind(&ok); - - masm.load32(Address(output, 0), output); - masm.freeStack(sizeof(int32_t)); - } - masm.bind(&done); + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + masm.guardStringToInt32(str, output, scratch, volatileRegs, failure->label()); return true; } -bool CacheIRCompiler::emitGuardAndGetNumberFromString( - StringOperandId strId, NumberOperandId resultId) { +bool CacheIRCompiler::emitGuardStringToNumber(StringOperandId strId, + NumberOperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register str = allocator.useRegister(masm, strId); ValueOperand output = allocator.defineValueRegister(masm, resultId); @@ -2130,8 +2227,8 @@ bool CacheIRCompiler::emitGuardAndGetNumberFromString( return true; } -bool CacheIRCompiler::emitGuardAndGetNumberFromBoolean( - Int32OperandId booleanId, NumberOperandId resultId) { +bool CacheIRCompiler::emitBooleanToNumber(BooleanOperandId booleanId, + NumberOperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register boolean = allocator.useRegister(masm, booleanId); ValueOperand output = allocator.defineValueRegister(masm, resultId); @@ -2139,8 +2236,8 @@ bool CacheIRCompiler::emitGuardAndGetNumberFromBoolean( return true; } -bool CacheIRCompiler::emitGuardAndGetIndexFromString(StringOperandId strId, - Int32OperandId resultId) { +bool CacheIRCompiler::emitGuardStringToIndex(StringOperandId strId, + Int32OperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register str = allocator.useRegister(masm, strId); Register output = allocator.defineRegister(masm, resultId); @@ -2163,7 +2260,7 @@ bool CacheIRCompiler::emitGuardAndGetIndexFromString(StringOperandId strId, masm.setupUnalignedABICall(output); masm.passABIArg(str); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetIndexFromString)); - masm.mov(ReturnReg, output); + masm.storeCallInt32Result(output); LiveRegisterSet ignore; ignore.add(output); @@ -2182,6 +2279,16 @@ bool CacheIRCompiler::emitLoadProto(ObjOperandId objId, ObjOperandId resultId) { Register obj = allocator.useRegister(masm, objId); Register reg = allocator.defineRegister(masm, resultId); masm.loadObjProto(obj, reg); + +#ifdef DEBUG + // We shouldn't encounter a null or lazy proto. + MOZ_ASSERT(uintptr_t(TaggedProto::LazyProto) == 1); + + Label done; + masm.branchPtr(Assembler::Above, reg, ImmWord(1), &done); + masm.assumeUnreachable("Unexpected null or lazy proto in CacheIR LoadProto"); + masm.bind(&done); +#endif return true; } @@ -2330,6 +2437,25 @@ bool CacheIRCompiler::emitLoadInt32ArrayLengthResult(ObjOperandId objId) { return true; } +bool CacheIRCompiler::emitLoadInt32ArrayLength(ObjOperandId objId, + Int32OperandId resultId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); + Register res = allocator.defineRegister(masm, resultId); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), res); + masm.load32(Address(res, ObjectElements::offsetOfLength()), res); + + // Guard length fits in an int32. + masm.branchTest32(Assembler::Signed, res, res, failure->label()); + return true; +} + bool CacheIRCompiler::emitDoubleAddResult(NumberOperandId lhsId, NumberOperandId rhsId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -2598,39 +2724,6 @@ bool CacheIRCompiler::emitInt32ModResult(Int32OperandId lhsId, return true; } -// Like AutoScratchRegisterMaybeOutput, but tries to use the ValueOperand's -// type register for the scratch register on 32-bit. -// -// Word of warning: Passing an instance of this class and AutoOutputRegister to -// functions may not work correctly, because no guarantee is given that the type -// register is used last when modifying the output's ValueOperand. -class MOZ_RAII AutoScratchRegisterMaybeOutputType { - mozilla::Maybe scratch_; - Register scratchReg_; - - public: - AutoScratchRegisterMaybeOutputType(CacheRegisterAllocator& alloc, - MacroAssembler& masm, - const AutoOutputRegister& output) { -#if defined(JS_NUNBOX32) - scratchReg_ = output.hasValue() ? output.valueReg().typeReg() : InvalidReg; -#else - scratchReg_ = InvalidReg; -#endif - if (scratchReg_ == InvalidReg) { - scratch_.emplace(alloc, masm); - scratchReg_ = scratch_.ref(); - } - } - - AutoScratchRegisterMaybeOutputType( - const AutoScratchRegisterMaybeOutputType&) = delete; - - void operator=(const AutoScratchRegisterMaybeOutputType&) = delete; - - operator Register() const { return scratchReg_; } -}; - bool CacheIRCompiler::emitInt32PowResult(Int32OperandId lhsId, Int32OperandId rhsId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -2706,8 +2799,6 @@ bool CacheIRCompiler::emitInt32LeftShiftResult(Int32OperandId lhsId, AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); masm.mov(lhs, scratch); - // Mask shift amount as specified by 12.9.3.1 Step 7 - masm.and32(Imm32(0x1F), rhs); masm.flexibleLshift32(rhs, scratch); EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); @@ -2723,8 +2814,6 @@ bool CacheIRCompiler::emitInt32RightShiftResult(Int32OperandId lhsId, AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); masm.mov(lhs, scratch); - // Mask shift amount as specified by 12.9.4.1 Step 7 - masm.and32(Imm32(0x1F), rhs); masm.flexibleRshift32Arithmetic(rhs, scratch); EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); @@ -2747,8 +2836,6 @@ bool CacheIRCompiler::emitInt32URightShiftResult(Int32OperandId lhsId, } masm.mov(lhs, scratch); - // Mask shift amount as specified by 12.9.4.1 Step 7 - masm.and32(Imm32(0x1F), rhs); masm.flexibleRshift32(rhs, scratch); Label intDone, floatDone; if (allowDouble) { @@ -3066,18 +3153,8 @@ bool CacheIRCompiler::emitLoadArgumentsObjectLengthResult(ObjOperandId objId) { return false; } - // Get initial length value. - masm.unboxInt32(Address(obj, ArgumentsObject::getInitialLengthSlotOffset()), - scratch); - - // Test if length has been overridden. - masm.branchTest32(Assembler::NonZero, scratch, - Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT), - failure->label()); + masm.loadArgumentsObjectLength(obj, scratch, failure->label()); - // Shift out arguments length and return it. No need to type monitor - // because this stub always returns int32. - masm.rshiftPtr(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratch); EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); return true; } @@ -3121,43 +3198,32 @@ bool CacheIRCompiler::emitLoadFunctionLengthResult(ObjOperandId objId) { return true; } -bool CacheIRCompiler::emitLoadStringLengthResult(StringOperandId strId) { +bool CacheIRCompiler::emitLoadFunctionNameResult(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); - Register str = allocator.useRegister(masm, strId); + Register obj = allocator.useRegister(masm, objId); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); - masm.loadStringLength(str, scratch); - EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); - return true; -} - -bool CacheIRCompiler::emitLoadStringCharResult(StringOperandId strId, - Int32OperandId indexId) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); - Register str = allocator.useRegister(masm, strId); - Register index = allocator.useRegister(masm, indexId); - AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output); - AutoScratchRegister scratch2(allocator, masm); - FailurePath* failure; if (!addFailurePath(&failure)) { return false; } - // Bounds check, load string char. - masm.spectreBoundsCheck32(index, Address(str, JSString::offsetOfLength()), - scratch1, failure->label()); - masm.loadStringChar(str, index, scratch1, scratch2, failure->label()); + masm.loadFunctionName(obj, scratch, ImmGCPtr(cx_->names().empty), + failure->label()); + + EmitStoreResult(masm, scratch, JSVAL_TYPE_STRING, output); + return true; +} - // Load StaticString for this char. - masm.boundsCheck32PowerOfTwo(scratch1, StaticStrings::UNIT_STATIC_LIMIT, - failure->label()); - masm.movePtr(ImmPtr(&cx_->staticStrings().unitStaticTable), scratch2); - masm.loadPtr(BaseIndex(scratch2, scratch1, ScalePointer), scratch2); +bool CacheIRCompiler::emitLoadStringLengthResult(StringOperandId strId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + Register str = allocator.useRegister(masm, strId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); - EmitStoreResult(masm, scratch2, JSVAL_TYPE_STRING, output); + masm.loadStringLength(str, scratch); + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); return true; } @@ -3184,47 +3250,67 @@ bool CacheIRCompiler::emitLoadStringCharCodeResult(StringOperandId strId, return true; } -bool CacheIRCompiler::emitLoadArgumentsObjectArgResult(ObjOperandId objId, - Int32OperandId indexId) { +bool CacheIRCompiler::emitNewStringObjectResult(uint32_t templateObjectOffset, + StringOperandId strId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); - Register obj = allocator.useRegister(masm, objId); - Register index = allocator.useRegister(masm, indexId); - AutoScratchRegister scratch1(allocator, masm); - AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output); - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } + AutoCallVM callvm(masm, this, allocator); - // Get initial length value. - masm.unboxInt32(Address(obj, ArgumentsObject::getInitialLengthSlotOffset()), - scratch1); + Register str = allocator.useRegister(masm, strId); - // Ensure no overridden length/element. - masm.branchTest32(Assembler::NonZero, scratch1, - Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT | - ArgumentsObject::ELEMENT_OVERRIDDEN_BIT), - failure->label()); + callvm.prepare(); + masm.Push(str); - // Bounds check. - masm.rshift32(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratch1); - masm.spectreBoundsCheck32(index, scratch1, scratch2, failure->label()); + using Fn = JSObject* (*)(JSContext*, HandleString); + callvm.call(); + return true; +} - // Load ArgumentsData. - masm.loadPrivate(Address(obj, ArgumentsObject::getDataSlotOffset()), - scratch1); +bool CacheIRCompiler::emitStringToLowerCaseResult(StringOperandId strId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - // Fail if we have a RareArgumentsData (elements were deleted). - masm.branchPtr(Assembler::NotEqual, - Address(scratch1, offsetof(ArgumentsData, rareData)), - ImmWord(0), failure->label()); + AutoCallVM callvm(masm, this, allocator); + + Register str = allocator.useRegister(masm, strId); + + callvm.prepare(); + masm.Push(str); + + using Fn = JSString* (*)(JSContext*, HandleString); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitStringToUpperCaseResult(StringOperandId strId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + + Register str = allocator.useRegister(masm, strId); + + callvm.prepare(); + masm.Push(str); + + using Fn = JSString* (*)(JSContext*, HandleString); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitLoadArgumentsObjectArgResult(ObjOperandId objId, + Int32OperandId indexId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register index = allocator.useRegister(masm, indexId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } - // Guard the argument is not a FORWARD_TO_CALL_SLOT MagicValue. - BaseValueIndex argValue(scratch1, index, ArgumentsData::offsetOfArgs()); - masm.branchTestMagic(Assembler::Equal, argValue, failure->label()); - masm.loadValue(argValue, output.valueReg()); + masm.loadArgumentsObjectElement(obj, index, output.valueReg(), scratch, + failure->label()); return true; } @@ -3377,17 +3463,15 @@ bool CacheIRCompiler::emitGuardTagNotEqual(ValueTagOperandId lhsId, } bool CacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto( - ObjOperandId objId, bool hasExpando, uint32_t shapeWrapperOffset) { + ObjOperandId objId, uint32_t shapeWrapperOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register obj = allocator.useRegister(masm, objId); StubFieldOffset shapeWrapper(shapeWrapperOffset, StubField::Type::JSObject); AutoScratchRegister scratch(allocator, masm); - Maybe scratch2, scratch3; - if (hasExpando) { - scratch2.emplace(allocator, masm); - scratch3.emplace(allocator, masm); - } + AutoScratchRegister scratch2(allocator, masm); + AutoScratchRegister scratch3(allocator, masm); FailurePath* failure; if (!addFailurePath(&failure)) { @@ -3400,39 +3484,50 @@ bool CacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto( Address expandoAddress(scratch, NativeObject::getFixedSlotOffset( GetXrayJitInfo()->holderExpandoSlot)); - if (hasExpando) { - masm.branchTestObject(Assembler::NotEqual, holderAddress, failure->label()); - masm.unboxObject(holderAddress, scratch); - masm.branchTestObject(Assembler::NotEqual, expandoAddress, - failure->label()); - masm.unboxObject(expandoAddress, scratch); - - // Unwrap the expando before checking its shape. - masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), - scratch); - masm.unboxObject( - Address(scratch, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()), - scratch); - - emitLoadStubField(shapeWrapper, scratch2.ref()); - LoadShapeWrapperContents(masm, scratch2.ref(), scratch2.ref(), - failure->label()); - masm.branchTestObjShape(Assembler::NotEqual, scratch, *scratch2, *scratch3, - scratch, failure->label()); - - // The reserved slots on the expando should all be in fixed slots. - Address protoAddress(scratch, NativeObject::getFixedSlotOffset( - GetXrayJitInfo()->expandoProtoSlot)); - masm.branchTestUndefined(Assembler::NotEqual, protoAddress, - failure->label()); - } else { - Label done; - masm.branchTestObject(Assembler::NotEqual, holderAddress, &done); - masm.unboxObject(holderAddress, scratch); - masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label()); - masm.bind(&done); + masm.fallibleUnboxObject(holderAddress, scratch, failure->label()); + masm.fallibleUnboxObject(expandoAddress, scratch, failure->label()); + + // Unwrap the expando before checking its shape. + masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), scratch); + masm.unboxObject( + Address(scratch, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()), + scratch); + + emitLoadStubField(shapeWrapper, scratch2); + LoadShapeWrapperContents(masm, scratch2, scratch2, failure->label()); + masm.branchTestObjShape(Assembler::NotEqual, scratch, scratch2, scratch3, + scratch, failure->label()); + + // The reserved slots on the expando should all be in fixed slots. + Address protoAddress(scratch, NativeObject::getFixedSlotOffset( + GetXrayJitInfo()->expandoProtoSlot)); + masm.branchTestUndefined(Assembler::NotEqual, protoAddress, failure->label()); + + return true; +} + +bool CacheIRCompiler::emitGuardXrayNoExpando(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; } + masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch); + Address holderAddress(scratch, + sizeof(Value) * GetXrayJitInfo()->xrayHolderSlot); + Address expandoAddress(scratch, NativeObject::getFixedSlotOffset( + GetXrayJitInfo()->holderExpandoSlot)); + + Label done; + masm.fallibleUnboxObject(holderAddress, scratch, &done); + masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label()); + masm.bind(&done); + return true; } @@ -3494,6 +3589,32 @@ bool CacheIRCompiler::emitGuardFunctionHasNoJitEntry(ObjOperandId funId) { return true; } +bool CacheIRCompiler::emitGuardFunctionIsNonBuiltinCtor(ObjOperandId funId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + Register fun = allocator.useRegister(masm, funId); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Guard the function has the BASESCRIPT and CONSTRUCTOR flags and does NOT + // have the SELF_HOSTED flag. + // This is equivalent to JSFunction::isNonBuiltinConstructor. + constexpr uint32_t mask = FunctionFlags::BASESCRIPT | + FunctionFlags::SELF_HOSTED | + FunctionFlags::CONSTRUCTOR; + constexpr uint32_t expected = + FunctionFlags::BASESCRIPT | FunctionFlags::CONSTRUCTOR; + masm.load16ZeroExtend(Address(fun, JSFunction::offsetOfFlags()), scratch); + masm.and32(Imm32(mask), scratch); + masm.branch32(Assembler::NotEqual, scratch, Imm32(expected), + failure->label()); + return true; +} + bool CacheIRCompiler::emitGuardFunctionIsConstructor(ObjOperandId funId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register funcReg = allocator.useRegister(masm, funId); @@ -3524,6 +3645,20 @@ bool CacheIRCompiler::emitGuardNotClassConstructor(ObjOperandId funId) { return true; } +bool CacheIRCompiler::emitGuardArrayIsPacked(ObjOperandId arrayId) { + Register array = allocator.useRegister(masm, arrayId); + AutoScratchRegister scratch(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.branchArrayIsNotPacked(array, scratch, scratch2, failure->label()); + return true; +} + bool CacheIRCompiler::emitLoadDenseElementHoleResult(ObjOperandId objId, Int32OperandId indexId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -3570,7 +3705,6 @@ bool CacheIRCompiler::emitLoadDenseElementHoleResult(ObjOperandId objId, bool CacheIRCompiler::emitLoadTypedElementExistsResult( ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, objId); Register index = allocator.useRegister(masm, indexId); @@ -3591,6 +3725,19 @@ bool CacheIRCompiler::emitLoadTypedElementExistsResult( return true; } +bool CacheIRCompiler::emitLoadTypedArrayElementExistsResult( + ObjOperandId objId, Int32OperandId indexId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + return emitLoadTypedElementExistsResult(objId, indexId, + TypedThingLayout::TypedArray); +} + +bool CacheIRCompiler::emitLoadTypedObjectElementExistsResult( + ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + return emitLoadTypedElementExistsResult(objId, indexId, layout); +} + bool CacheIRCompiler::emitLoadDenseElementExistsResult(ObjOperandId objId, Int32OperandId indexId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -3658,50 +3805,41 @@ bool CacheIRCompiler::emitLoadDenseElementHoleExistsResult( return true; } -bool CacheIRCompiler::emitArrayJoinResult(ObjOperandId objId) { +bool CacheIRCompiler::emitPackedArrayPopResult(ObjOperandId arrayId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); - Register obj = allocator.useRegister(masm, objId); - AutoScratchRegister scratch(allocator, masm); + Register array = allocator.useRegister(masm, arrayId); + AutoScratchRegister scratch1(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); FailurePath* failure; if (!addFailurePath(&failure)) { return false; } - // Load obj->elements in scratch. - masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), scratch); - Address lengthAddr(scratch, ObjectElements::offsetOfLength()); - - // If array length is 0, return empty string. - Label finished; - - { - Label arrayNotEmpty; - masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(0), &arrayNotEmpty); - masm.movePtr(ImmGCPtr(cx_->names().empty), scratch); - masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg()); - masm.jump(&finished); - masm.bind(&arrayNotEmpty); - } - - // Otherwise, handle array length 1 case. - masm.branch32(Assembler::NotEqual, lengthAddr, Imm32(1), failure->label()); - - // But only if initializedLength is also 1. - Address initLength(scratch, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::NotEqual, initLength, Imm32(1), failure->label()); + masm.packedArrayPop(array, output.valueReg(), scratch1, scratch2, + failure->label()); + return true; +} - // And only if elem0 is a string. - Address elementAddr(scratch, 0); - masm.branchTestString(Assembler::NotEqual, elementAddr, failure->label()); +bool CacheIRCompiler::emitPackedArrayShiftResult(ObjOperandId arrayId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - // Store the value. - masm.loadValue(elementAddr, output.valueReg()); + AutoOutputRegister output(*this); + Register array = allocator.useRegister(masm, arrayId); + AutoScratchRegister scratch1(allocator, masm); + AutoScratchRegister scratch2(allocator, masm); - masm.bind(&finished); + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + masm.packedArrayShift(array, output.valueReg(), scratch1, scratch2, + volatileRegs, failure->label()); return true; } @@ -3719,6 +3857,19 @@ bool CacheIRCompiler::emitIsObjectResult(ValOperandId inputId) { return true; } +bool CacheIRCompiler::emitIsPackedArrayResult(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + AutoScratchRegister scratch(allocator, masm); + + Register outputScratch = output.valueReg().scratchReg(); + masm.setIsPackedArray(obj, outputScratch, scratch); + masm.tagValue(JSVAL_TYPE_BOOLEAN, outputScratch, output.valueReg()); + return true; +} + bool CacheIRCompiler::emitIsCallableResult(ValOperandId inputId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -3795,144 +3946,607 @@ bool CacheIRCompiler::emitIsConstructorResult(ObjOperandId objId) { return true; } -bool CacheIRCompiler::emitMathAbsInt32Result(Int32OperandId inputId) { +bool CacheIRCompiler::emitIsCrossRealmArrayConstructorResult( + ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); - Register input = allocator.useRegister(masm, inputId); + masm.setIsCrossRealmArrayConstructor(obj, scratch); + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); + return true; +} - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } +bool CacheIRCompiler::emitTypedArrayByteOffsetResult(ObjOperandId objId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - masm.mov(input, scratch); - // Don't negate already positive values. - Label positive; - masm.branchTest32(Assembler::NotSigned, scratch, scratch, &positive); - // neg32 might overflow for INT_MIN. - masm.branchNeg32(Assembler::Overflow, scratch, failure->label()); - masm.bind(&positive); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); - EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + masm.unboxInt32(Address(obj, ArrayBufferViewObject::byteOffsetOffset()), + scratch); + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); return true; } -bool CacheIRCompiler::emitMathAbsNumberResult(NumberOperandId inputId) { +bool CacheIRCompiler::emitTypedArrayElementShiftResult(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); - AutoAvailableFloatRegister scratch(*this, FloatReg0); - - allocator.ensureDoubleRegister(masm, inputId, scratch); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); - masm.absDouble(scratch, scratch); - masm.boxDouble(scratch, output.valueReg(), scratch); + masm.typedArrayElementShift(obj, scratch); + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); return true; } -bool CacheIRCompiler::emitMathSqrtNumberResult(NumberOperandId inputId) { +bool CacheIRCompiler::emitIsTypedArrayConstructorResult(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); - AutoAvailableFloatRegister scratch(*this, FloatReg0); - - allocator.ensureDoubleRegister(masm, inputId, scratch); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); - masm.sqrtDouble(scratch, scratch); - masm.boxDouble(scratch, output.valueReg(), scratch); + masm.setIsDefinitelyTypedArrayConstructor(obj, scratch); + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); return true; } -bool CacheIRCompiler::emitMathAtan2NumberResult(NumberOperandId yId, - NumberOperandId xId) { +bool CacheIRCompiler::emitGetNextMapSetEntryForIteratorResult( + ObjOperandId iterId, ObjOperandId resultArrId, bool isMap) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); - - AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); - AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); - - allocator.ensureDoubleRegister(masm, yId, floatScratch0); - allocator.ensureDoubleRegister(masm, xId, floatScratch1); + Register iter = allocator.useRegister(masm, iterId); + Register resultArr = allocator.useRegister(masm, resultArrId); LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + save.takeUnchecked(output.valueReg()); + save.takeUnchecked(scratch); masm.PushRegsInMask(save); masm.setupUnalignedABICall(scratch); - masm.passABIArg(floatScratch0, MoveOp::DOUBLE); - masm.passABIArg(floatScratch1, MoveOp::DOUBLE); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::ecmaAtan2), MoveOp::DOUBLE); - masm.storeCallFloatResult(floatScratch0); - - LiveRegisterSet ignore; - ignore.add(floatScratch0); - masm.PopRegsInMaskIgnore(save, ignore); + masm.passABIArg(iter); + masm.passABIArg(resultArr); + if (isMap) { + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, MapIteratorObject::next)); + } else { + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, SetIteratorObject::next)); + } + masm.storeCallBoolResult(scratch); - masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + masm.PopRegsInMask(save); + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); return true; } -bool CacheIRCompiler::emitMathFloorToInt32Result(NumberOperandId inputId) { +bool CacheIRCompiler::emitFinishBoundFunctionInitResult( + ObjOperandId boundId, ObjOperandId targetId, Int32OperandId argCountId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); - AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoCallVM callvm(masm, this, allocator); - AutoAvailableFloatRegister scratchFloat(*this, FloatReg0); + Register bound = allocator.useRegister(masm, boundId); + Register target = allocator.useRegister(masm, targetId); + Register argCount = allocator.useRegister(masm, argCountId); - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } + callvm.prepare(); - allocator.ensureDoubleRegister(masm, inputId, scratchFloat); + masm.Push(argCount); + masm.Push(target); + masm.Push(bound); - masm.floorDoubleToInt32(scratchFloat, scratch, failure->label()); + using Fn = bool (*)(JSContext * cx, HandleFunction bound, HandleObject target, + int32_t argCount); + callvm.callNoResult(); - EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + masm.moveValue(UndefinedValue(), callvm.outputValueReg()); return true; } -bool CacheIRCompiler::emitMathCeilToInt32Result(NumberOperandId inputId) { +bool CacheIRCompiler::emitNewArrayIteratorResult( + uint32_t templateObjectOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); - AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoCallVM callvm(masm, this, allocator); - AutoAvailableFloatRegister scratchFloat(*this, FloatReg0); + callvm.prepare(); - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } + using Fn = ArrayIteratorObject* (*)(JSContext*); + callvm.call(); + return true; +} - allocator.ensureDoubleRegister(masm, inputId, scratchFloat); +bool CacheIRCompiler::emitNewStringIteratorResult( + uint32_t templateObjectOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - masm.ceilDoubleToInt32(scratchFloat, scratch, failure->label()); + AutoCallVM callvm(masm, this, allocator); - EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + callvm.prepare(); + + using Fn = StringIteratorObject* (*)(JSContext*); + callvm.call(); return true; } -bool CacheIRCompiler::emitMathRoundToInt32Result(NumberOperandId inputId) { +bool CacheIRCompiler::emitNewRegExpStringIteratorResult( + uint32_t templateObjectOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoOutputRegister output(*this); - AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoCallVM callvm(masm, this, allocator); - AutoAvailableFloatRegister scratchFloat0(*this, FloatReg0); - AutoAvailableFloatRegister scratchFloat1(*this, FloatReg1); + callvm.prepare(); - FailurePath* failure; - if (!addFailurePath(&failure)) { - return false; - } + using Fn = RegExpStringIteratorObject* (*)(JSContext*); + callvm.call(); + return true; +} - allocator.ensureDoubleRegister(masm, inputId, scratchFloat0); +bool CacheIRCompiler::emitObjectCreateResult(uint32_t templateObjectOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + AutoScratchRegister scratch(allocator, masm); + + StubFieldOffset objectField(templateObjectOffset, StubField::Type::JSObject); + emitLoadStubField(objectField, scratch); + + callvm.prepare(); + masm.Push(scratch); + + using Fn = PlainObject* (*)(JSContext*, HandlePlainObject); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitNewArrayFromLengthResult( + uint32_t templateObjectOffset, Int32OperandId lengthId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + AutoScratchRegister scratch(allocator, masm); + Register length = allocator.useRegister(masm, lengthId); + + StubFieldOffset objectField(templateObjectOffset, StubField::Type::JSObject); + emitLoadStubField(objectField, scratch); + + callvm.prepare(); + masm.Push(length); + masm.Push(scratch); + + using Fn = ArrayObject* (*)(JSContext*, HandleArrayObject, int32_t length); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitNewTypedArrayFromLengthResult( + uint32_t templateObjectOffset, Int32OperandId lengthId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + AutoScratchRegister scratch(allocator, masm); + Register length = allocator.useRegister(masm, lengthId); + + StubFieldOffset objectField(templateObjectOffset, StubField::Type::JSObject); + emitLoadStubField(objectField, scratch); + + callvm.prepare(); + masm.Push(length); + masm.Push(scratch); + + using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, int32_t length); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitNewTypedArrayFromArrayBufferResult( + uint32_t templateObjectOffset, ObjOperandId bufferId, + ValOperandId byteOffsetId, ValOperandId lengthId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + +#ifdef JS_CODEGEN_X86 + MOZ_CRASH("Instruction not supported on 32-bit x86, not enough registers"); +#endif + + AutoCallVM callvm(masm, this, allocator); + AutoScratchRegister scratch(allocator, masm); + Register buffer = allocator.useRegister(masm, bufferId); + ValueOperand byteOffset = allocator.useValueRegister(masm, byteOffsetId); + ValueOperand length = allocator.useValueRegister(masm, lengthId); + + StubFieldOffset objectField(templateObjectOffset, StubField::Type::JSObject); + emitLoadStubField(objectField, scratch); + + callvm.prepare(); + masm.Push(length); + masm.Push(byteOffset); + masm.Push(buffer); + masm.Push(scratch); + + using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, HandleObject, + HandleValue, HandleValue); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitNewTypedArrayFromArrayResult( + uint32_t templateObjectOffset, ObjOperandId arrayId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + AutoScratchRegister scratch(allocator, masm); + Register array = allocator.useRegister(masm, arrayId); + + StubFieldOffset objectField(templateObjectOffset, StubField::Type::JSObject); + emitLoadStubField(objectField, scratch); + + callvm.prepare(); + masm.Push(array); + masm.Push(scratch); + + using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, HandleObject); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitMathAbsInt32Result(Int32OperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + Register input = allocator.useRegister(masm, inputId); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + masm.mov(input, scratch); + // Don't negate already positive values. + Label positive; + masm.branchTest32(Assembler::NotSigned, scratch, scratch, &positive); + // neg32 might overflow for INT_MIN. + masm.branchNeg32(Assembler::Overflow, scratch, failure->label()); + masm.bind(&positive); + + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + return true; +} + +bool CacheIRCompiler::emitMathAbsNumberResult(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoAvailableFloatRegister scratch(*this, FloatReg0); + + allocator.ensureDoubleRegister(masm, inputId, scratch); + + masm.absDouble(scratch, scratch); + masm.boxDouble(scratch, output.valueReg(), scratch); + return true; +} + +bool CacheIRCompiler::emitMathClz32Result(Int32OperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register input = allocator.useRegister(masm, inputId); + + masm.clz32(input, scratch, /* knownNotZero = */ false); + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + return true; +} + +bool CacheIRCompiler::emitMathSignInt32Result(Int32OperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register input = allocator.useRegister(masm, inputId); + + masm.signInt32(input, scratch); + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); + return true; +} + +bool CacheIRCompiler::emitMathSignNumberResult(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch2(*this, FloatReg1); + + allocator.ensureDoubleRegister(masm, inputId, floatScratch1); + + masm.signDouble(floatScratch1, floatScratch2); + masm.boxDouble(floatScratch2, output.valueReg(), floatScratch2); + return true; +} + +bool CacheIRCompiler::emitMathSignNumberToInt32Result(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch2(*this, FloatReg1); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + allocator.ensureDoubleRegister(masm, inputId, floatScratch1); + + masm.signDoubleToInt32(floatScratch1, scratch, floatScratch2, + failure->label()); + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); + return true; +} + +bool CacheIRCompiler::emitMathImulResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register lhs = allocator.useRegister(masm, lhsId); + Register rhs = allocator.useRegister(masm, rhsId); + + masm.mov(lhs, scratch); + masm.mul32(rhs, scratch); + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); + return true; +} + +bool CacheIRCompiler::emitMathSqrtNumberResult(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoAvailableFloatRegister scratch(*this, FloatReg0); + + allocator.ensureDoubleRegister(masm, inputId, scratch); + + masm.sqrtDouble(scratch, scratch); + masm.boxDouble(scratch, output.valueReg(), scratch); + return true; +} + +bool CacheIRCompiler::emitMathFRoundNumberResult(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoAvailableFloatRegister scratch(*this, FloatReg0); + FloatRegister scratchFloat32 = scratch.get().asSingle(); + + allocator.ensureDoubleRegister(masm, inputId, scratch); + + masm.convertDoubleToFloat32(scratch, scratchFloat32); + masm.convertFloat32ToDouble(scratchFloat32, scratch); + + masm.boxDouble(scratch, output.valueReg(), scratch); + return true; +} + +bool CacheIRCompiler::emitMathHypot2NumberResult(NumberOperandId first, + NumberOperandId second) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); + + allocator.ensureDoubleRegister(masm, first, floatScratch0); + allocator.ensureDoubleRegister(masm, second, floatScratch1); + + LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + masm.PushRegsInMask(save); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(floatScratch0, MoveOp::DOUBLE); + masm.passABIArg(floatScratch1, MoveOp::DOUBLE); + + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ecmaHypot), MoveOp::DOUBLE); + masm.storeCallFloatResult(floatScratch0); + + LiveRegisterSet ignore; + ignore.add(floatScratch0); + masm.PopRegsInMaskIgnore(save, ignore); + + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + return true; +} + +bool CacheIRCompiler::emitMathHypot3NumberResult(NumberOperandId first, + NumberOperandId second, + NumberOperandId third) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); + AutoAvailableFloatRegister floatScratch2(*this, FloatReg2); + + allocator.ensureDoubleRegister(masm, first, floatScratch0); + allocator.ensureDoubleRegister(masm, second, floatScratch1); + allocator.ensureDoubleRegister(masm, third, floatScratch2); + + LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + masm.PushRegsInMask(save); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(floatScratch0, MoveOp::DOUBLE); + masm.passABIArg(floatScratch1, MoveOp::DOUBLE); + masm.passABIArg(floatScratch2, MoveOp::DOUBLE); + + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, hypot3), MoveOp::DOUBLE); + masm.storeCallFloatResult(floatScratch0); + + LiveRegisterSet ignore; + ignore.add(floatScratch0); + masm.PopRegsInMaskIgnore(save, ignore); + + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + return true; +} + +bool CacheIRCompiler::emitMathHypot4NumberResult(NumberOperandId first, + NumberOperandId second, + NumberOperandId third, + NumberOperandId fourth) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); + AutoAvailableFloatRegister floatScratch2(*this, FloatReg2); + AutoAvailableFloatRegister floatScratch3(*this, FloatReg3); + + allocator.ensureDoubleRegister(masm, first, floatScratch0); + allocator.ensureDoubleRegister(masm, second, floatScratch1); + allocator.ensureDoubleRegister(masm, third, floatScratch2); + allocator.ensureDoubleRegister(masm, fourth, floatScratch3); + + LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + masm.PushRegsInMask(save); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(floatScratch0, MoveOp::DOUBLE); + masm.passABIArg(floatScratch1, MoveOp::DOUBLE); + masm.passABIArg(floatScratch2, MoveOp::DOUBLE); + masm.passABIArg(floatScratch3, MoveOp::DOUBLE); + + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, hypot4), MoveOp::DOUBLE); + masm.storeCallFloatResult(floatScratch0); + + LiveRegisterSet ignore; + ignore.add(floatScratch0); + masm.PopRegsInMaskIgnore(save, ignore); + + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + return true; +} + +bool CacheIRCompiler::emitMathAtan2NumberResult(NumberOperandId yId, + NumberOperandId xId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); + + allocator.ensureDoubleRegister(masm, yId, floatScratch0); + allocator.ensureDoubleRegister(masm, xId, floatScratch1); + + LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); + masm.PushRegsInMask(save); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(floatScratch0, MoveOp::DOUBLE); + masm.passABIArg(floatScratch1, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::ecmaAtan2), MoveOp::DOUBLE); + masm.storeCallFloatResult(floatScratch0); + + LiveRegisterSet ignore; + ignore.add(floatScratch0); + masm.PopRegsInMaskIgnore(save, ignore); + + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + + return true; +} + +bool CacheIRCompiler::emitMathFloorToInt32Result(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister scratchFloat(*this, FloatReg0); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + allocator.ensureDoubleRegister(masm, inputId, scratchFloat); + + masm.floorDoubleToInt32(scratchFloat, scratch, failure->label()); + + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + return true; +} + +bool CacheIRCompiler::emitMathCeilToInt32Result(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister scratchFloat(*this, FloatReg0); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + allocator.ensureDoubleRegister(masm, inputId, scratchFloat); + + masm.ceilDoubleToInt32(scratchFloat, scratch, failure->label()); + + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + return true; +} + +bool CacheIRCompiler::emitMathTruncToInt32Result(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister scratchFloat(*this, FloatReg0); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + allocator.ensureDoubleRegister(masm, inputId, scratchFloat); + + masm.truncDoubleToInt32(scratchFloat, scratch, failure->label()); + + EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output); + return true; +} + +bool CacheIRCompiler::emitMathRoundToInt32Result(NumberOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + AutoAvailableFloatRegister scratchFloat0(*this, FloatReg0); + AutoAvailableFloatRegister scratchFloat1(*this, FloatReg1); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + allocator.ensureDoubleRegister(masm, inputId, scratchFloat0); masm.roundDoubleToInt32(scratchFloat0, scratch, scratchFloat1, failure->label()); @@ -4153,11 +4767,9 @@ static void EmitAllocateBigInt(MacroAssembler& masm, Register result, masm.bind(&done); } -bool CacheIRCompiler::emitLoadTypedElementResult(ObjOperandId objId, - Int32OperandId indexId, - TypedThingLayout layout, - Scalar::Type elementType, - bool handleOOB) { +bool CacheIRCompiler::emitLoadTypedElementResult( + ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout, + Scalar::Type elementType, bool handleOOB, bool allowDoubleForUint32) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, objId); @@ -4197,106 +4809,496 @@ bool CacheIRCompiler::emitLoadTypedElementResult(ObjOperandId objId, return false; } - // Bounds check. - Label outOfBounds; - LoadTypedThingLength(masm, layout, obj, scratch1); - masm.spectreBoundsCheck32(index, scratch1, scratch2, - handleOOB ? &outOfBounds : failure->label()); + // Bounds check. + Label outOfBounds; + LoadTypedThingLength(masm, layout, obj, scratch1); + masm.spectreBoundsCheck32(index, scratch1, scratch2, + handleOOB ? &outOfBounds : failure->label()); + + // Allocate BigInt if needed. The code after this should be infallible. + Maybe bigInt; + if (Scalar::isBigIntType(elementType)) { + bigInt.emplace(output.valueReg().scratchReg()); + + LiveRegisterSet save(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + save.takeUnchecked(scratch1); + save.takeUnchecked(scratch2); + save.takeUnchecked(output); + + bool attemptNursery = CanNurseryAllocateBigInt(cx_); + EmitAllocateBigInt(masm, *bigInt, scratch1, save, failure->label(), + attemptNursery); + } + + // Load the elements vector. + LoadTypedThingData(masm, layout, obj, scratch1); + + // Load the value. + BaseIndex source(scratch1, index, + ScaleFromElemWidth(Scalar::byteSize(elementType))); + + if (output.hasValue()) { + if (Scalar::isBigIntType(elementType)) { +#ifdef JS_PUNBOX64 + Register64 temp(scratch2); +#else + // We don't have more registers available on x86, so spill |obj| and + // additionally use the output's type register. + MOZ_ASSERT(output.valueReg().scratchReg() != output.valueReg().typeReg()); + masm.push(obj); + Register64 temp(output.valueReg().typeReg(), obj); +#endif + + masm.loadFromTypedBigIntArray(elementType, source, *bigInt, temp); + +#ifndef JS_PUNBOX64 + masm.pop(obj); +#endif + + masm.tagValue(JSVAL_TYPE_BIGINT, *bigInt, output.valueReg()); + } else { + bool allowDouble = *allowDoubleResult_ && allowDoubleForUint32; + masm.loadFromTypedArray(elementType, source, output.valueReg(), + allowDouble, scratch1, failure->label()); + } + } else { + bool needGpr = + (elementType == Scalar::Int8 || elementType == Scalar::Uint8 || + elementType == Scalar::Int16 || elementType == Scalar::Uint16 || + elementType == Scalar::Uint8Clamped || elementType == Scalar::Int32); + if (needGpr && output.type() == JSVAL_TYPE_DOUBLE) { + // Load the element as integer, then convert it to double. + masm.loadFromTypedArray(elementType, source, AnyRegister(scratch1), + scratch1, failure->label()); + masm.convertInt32ToDouble(source, output.typedReg().fpu()); + } else { + masm.loadFromTypedArray(elementType, source, output.typedReg(), scratch1, + failure->label()); + } + } + + if (handleOOB) { + Label done; + masm.jump(&done); + + masm.bind(&outOfBounds); + if (output.hasValue()) { + masm.moveValue(UndefinedValue(), output.valueReg()); + } else { + masm.assumeUnreachable("Should have monitored undefined result"); + } + + masm.bind(&done); + } + + return true; +} + +bool CacheIRCompiler::emitLoadTypedArrayElementResult( + ObjOperandId objId, Int32OperandId indexId, Scalar::Type elementType, + bool handleOOB, bool allowDoubleForUint32) { + return emitLoadTypedElementResult(objId, indexId, + TypedThingLayout::TypedArray, elementType, + handleOOB, allowDoubleForUint32); +} + +bool CacheIRCompiler::emitLoadTypedObjectElementResult( + ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout, + Scalar::Type elementType) { + return emitLoadTypedElementResult(objId, indexId, layout, elementType, + /* handleOOB = */ false, + /* allowDoubleForUint32 = */ true); +} + +static void EmitDataViewBoundsCheck(MacroAssembler& masm, size_t byteSize, + Register obj, Register offset, + Register scratch, Label* fail) { + // Ensure both offset < length and offset + (byteSize - 1) < length. + static_assert(ArrayBufferObject::MaxBufferByteLength <= INT32_MAX, + "Code assumes DataView length fits in int32"); + masm.unboxInt32(Address(obj, DataViewObject::lengthOffset()), scratch); + if (byteSize == 1) { + masm.spectreBoundsCheck32(offset, scratch, InvalidReg, fail); + } else { + // temp := length - (byteSize - 1) + // if temp < 0: fail + // if offset >= temp: fail + masm.branchSub32(Assembler::Signed, Imm32(byteSize - 1), scratch, fail); + masm.spectreBoundsCheck32(offset, scratch, InvalidReg, fail); + } +} + +bool CacheIRCompiler::emitLoadDataViewValueResult( + ObjOperandId objId, Int32OperandId offsetId, + BooleanOperandId littleEndianId, Scalar::Type elementType, + bool allowDoubleForUint32) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register offset = allocator.useRegister(masm, offsetId); + Register littleEndian = allocator.useRegister(masm, littleEndianId); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + + Register64 outputReg64 = output.valueReg().toRegister64(); + Register outputScratch = outputReg64.scratchReg(); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + const size_t byteSize = Scalar::byteSize(elementType); + + EmitDataViewBoundsCheck(masm, byteSize, obj, offset, outputScratch, + failure->label()); + + masm.loadPtr(Address(obj, DataViewObject::dataOffset()), outputScratch); + + // Load the value. + BaseIndex source(outputScratch, offset, TimesOne); + switch (elementType) { + case Scalar::Int8: + masm.load8SignExtend(source, outputScratch); + break; + case Scalar::Uint8: + masm.load8ZeroExtend(source, outputScratch); + break; + case Scalar::Int16: + masm.load16UnalignedSignExtend(source, outputScratch); + break; + case Scalar::Uint16: + masm.load16UnalignedZeroExtend(source, outputScratch); + break; + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Float32: + masm.load32Unaligned(source, outputScratch); + break; + case Scalar::Float64: + case Scalar::BigInt64: + case Scalar::BigUint64: + masm.load64Unaligned(source, outputReg64); + break; + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid typed array type"); + } + + // Swap the bytes in the loaded value. + if (byteSize > 1) { + Label skip; + masm.branch32(MOZ_LITTLE_ENDIAN() ? Assembler::NotEqual : Assembler::Equal, + littleEndian, Imm32(0), &skip); + + switch (elementType) { + case Scalar::Int16: + masm.byteSwap16SignExtend(outputScratch); + break; + case Scalar::Uint16: + masm.byteSwap16ZeroExtend(outputScratch); + break; + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Float32: + masm.byteSwap32(outputScratch); + break; + case Scalar::Float64: + case Scalar::BigInt64: + case Scalar::BigUint64: + masm.byteSwap64(outputReg64); + break; + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid type"); + } + + masm.bind(&skip); + } + + // Move the value into the output register. + switch (elementType) { + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Int16: + case Scalar::Uint16: + case Scalar::Int32: + masm.tagValue(JSVAL_TYPE_INT32, outputScratch, output.valueReg()); + break; + case Scalar::Uint32: + masm.boxUint32(outputScratch, output.valueReg(), allowDoubleForUint32, + failure->label()); + break; + case Scalar::Float32: { + FloatRegister scratchFloat32 = floatScratch0.get().asSingle(); + masm.moveGPRToFloat32(outputScratch, scratchFloat32); + masm.canonicalizeFloat(scratchFloat32); + masm.convertFloat32ToDouble(scratchFloat32, floatScratch0); + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + break; + } + case Scalar::Float64: + masm.moveGPR64ToDouble(outputReg64, floatScratch0); + masm.canonicalizeDouble(floatScratch0); + masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0); + break; + case Scalar::BigInt64: + case Scalar::BigUint64: { + // We need two extra registers. Reuse the obj/littleEndian registers. + Register bigInt = obj; + Register bigIntScratch = littleEndian; + masm.push(bigInt); + masm.push(bigIntScratch); + Label fail, done; + LiveRegisterSet save(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + save.takeUnchecked(bigInt); + save.takeUnchecked(bigIntScratch); + bool attemptNursery = CanNurseryAllocateBigInt(cx_); + EmitAllocateBigInt(masm, bigInt, bigIntScratch, save, &fail, + attemptNursery); + masm.jump(&done); + + masm.bind(&fail); + masm.pop(bigIntScratch); + masm.pop(bigInt); + masm.jump(failure->label()); + + masm.bind(&done); + masm.initializeBigInt64(elementType, bigInt, outputReg64); + masm.tagValue(JSVAL_TYPE_BIGINT, bigInt, output.valueReg()); + masm.pop(bigIntScratch); + masm.pop(bigInt); + break; + } + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid typed array type"); + } + + return true; +} + +bool CacheIRCompiler::emitStoreDataViewValueResult( + ObjOperandId objId, Int32OperandId offsetId, uint32_t valueId, + BooleanOperandId littleEndianId, Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); +#ifdef JS_CODEGEN_X86 + // Use a scratch register to avoid running out of the registers. + Register obj = output.valueReg().typeReg(); + allocator.copyToScratchRegister(masm, objId, obj); +#else + Register obj = allocator.useRegister(masm, objId); +#endif + Register offset = allocator.useRegister(masm, offsetId); + Register littleEndian = allocator.useRegister(masm, littleEndianId); + + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + Maybe valInt32; + Maybe valBigInt; + switch (elementType) { + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Int16: + case Scalar::Uint16: + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Uint8Clamped: + valInt32.emplace(allocator.useRegister(masm, Int32OperandId(valueId))); + break; + + case Scalar::Float32: + case Scalar::Float64: + allocator.ensureDoubleRegister(masm, NumberOperandId(valueId), + floatScratch0); + break; + + case Scalar::BigInt64: + case Scalar::BigUint64: + valBigInt.emplace(allocator.useRegister(masm, BigIntOperandId(valueId))); + break; + + case Scalar::MaxTypedArrayViewType: + case Scalar::Int64: + MOZ_CRASH("Unsupported type"); + } + + Register scratch1 = output.valueReg().scratchReg(); + MOZ_ASSERT(scratch1 != obj, "scratchReg must not be typeReg"); + + // On platforms with enough registers, |scratch2| is an extra scratch register + // (pair) used for byte-swapping the value. +#ifndef JS_CODEGEN_X86 + mozilla::MaybeOneOf scratch2; + switch (elementType) { + case Scalar::Int8: + case Scalar::Uint8: + break; + case Scalar::Int16: + case Scalar::Uint16: + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Float32: + scratch2.construct(allocator, masm); + break; + case Scalar::Float64: + case Scalar::BigInt64: + case Scalar::BigUint64: + scratch2.construct(allocator, masm); + break; + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid type"); + } +#endif + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + const size_t byteSize = Scalar::byteSize(elementType); - // Allocate BigInt if needed. The code after this should be infallible. - Maybe bigInt; - if (Scalar::isBigIntType(elementType)) { - bigInt.emplace(output.valueReg().scratchReg()); + EmitDataViewBoundsCheck(masm, byteSize, obj, offset, scratch1, + failure->label()); - LiveRegisterSet save(GeneralRegisterSet::Volatile(), - liveVolatileFloatRegs()); - save.takeUnchecked(scratch1); - save.takeUnchecked(scratch2); - save.takeUnchecked(output); + masm.loadPtr(Address(obj, DataViewObject::dataOffset()), scratch1); + BaseIndex dest(scratch1, offset, TimesOne); - bool attemptNursery = CanNurseryAllocateBigInt(cx_); - EmitAllocateBigInt(masm, *bigInt, scratch1, save, failure->label(), - attemptNursery); + if (byteSize == 1) { + // Byte swapping has no effect, so just do the byte store. + masm.store8(*valInt32, dest); + masm.moveValue(UndefinedValue(), output.valueReg()); + return true; } - // Load the elements vector. - LoadTypedThingData(masm, layout, obj, scratch1); - - // Load the value. - BaseIndex source(scratch1, index, - ScaleFromElemWidth(Scalar::byteSize(elementType))); - - if (output.hasValue()) { - if (Scalar::isBigIntType(elementType)) { -#ifdef JS_PUNBOX64 - Register64 temp(scratch2); + // On 32-bit x86, |obj| is already a scratch register so use that. If we need + // a Register64 we also use the littleEndian register and use the stack + // location for the check below. + bool pushedLittleEndian = false; +#ifdef JS_CODEGEN_X86 + if (byteSize == 8) { + masm.push(littleEndian); + pushedLittleEndian = true; + } + auto valScratch32 = [&]() -> Register { return obj; }; + auto valScratch64 = [&]() -> Register64 { + return Register64(obj, littleEndian); + }; #else - // We don't have more registers available on x86, so spill |obj| and - // additionally use the output's type register. - MOZ_ASSERT(output.valueReg().scratchReg() != output.valueReg().typeReg()); - masm.push(obj); - Register64 temp(output.valueReg().typeReg(), obj); -#endif - - masm.loadFromTypedBigIntArray(elementType, source, *bigInt, temp); - -#ifndef JS_PUNBOX64 - masm.pop(obj); + auto valScratch32 = [&]() -> Register { + return scratch2.ref(); + }; + auto valScratch64 = [&]() -> Register64 { + return scratch2.ref(); + }; #endif - masm.tagValue(JSVAL_TYPE_BIGINT, *bigInt, output.valueReg()); - } else { - masm.loadFromTypedArray(elementType, source, output.valueReg(), - *allowDoubleResult_, scratch1, failure->label()); + // Load the value into a gpr register. + switch (elementType) { + case Scalar::Int16: + case Scalar::Uint16: + case Scalar::Int32: + case Scalar::Uint32: + masm.move32(*valInt32, valScratch32()); + break; + case Scalar::Float32: { + FloatRegister scratchFloat32 = floatScratch0.get().asSingle(); + masm.convertDoubleToFloat32(floatScratch0, scratchFloat32); + masm.canonicalizeFloatIfDeterministic(scratchFloat32); + masm.moveFloat32ToGPR(scratchFloat32, valScratch32()); + break; } - } else { - bool needGpr = - (elementType == Scalar::Int8 || elementType == Scalar::Uint8 || - elementType == Scalar::Int16 || elementType == Scalar::Uint16 || - elementType == Scalar::Uint8Clamped || elementType == Scalar::Int32); - if (needGpr && output.type() == JSVAL_TYPE_DOUBLE) { - // Load the element as integer, then convert it to double. - masm.loadFromTypedArray(elementType, source, AnyRegister(scratch1), - scratch1, failure->label()); - masm.convertInt32ToDouble(source, output.typedReg().fpu()); - } else { - masm.loadFromTypedArray(elementType, source, output.typedReg(), scratch1, - failure->label()); + case Scalar::Float64: { + masm.canonicalizeDoubleIfDeterministic(floatScratch0); + masm.moveDoubleToGPR64(floatScratch0, valScratch64()); + break; } + case Scalar::BigInt64: + case Scalar::BigUint64: + masm.loadBigInt64(*valBigInt, valScratch64()); + break; + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid type"); } - if (handleOOB) { - Label done; - masm.jump(&done); + // Swap the bytes in the loaded value. + Label skip; + if (pushedLittleEndian) { + masm.branch32(MOZ_LITTLE_ENDIAN() ? Assembler::NotEqual : Assembler::Equal, + Address(masm.getStackPointer(), 0), Imm32(0), &skip); + } else { + masm.branch32(MOZ_LITTLE_ENDIAN() ? Assembler::NotEqual : Assembler::Equal, + littleEndian, Imm32(0), &skip); + } + switch (elementType) { + case Scalar::Int16: + masm.byteSwap16SignExtend(valScratch32()); + break; + case Scalar::Uint16: + masm.byteSwap16ZeroExtend(valScratch32()); + break; + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Float32: + masm.byteSwap32(valScratch32()); + break; + case Scalar::Float64: + case Scalar::BigInt64: + case Scalar::BigUint64: + masm.byteSwap64(valScratch64()); + break; + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid type"); + } + masm.bind(&skip); - masm.bind(&outOfBounds); - if (output.hasValue()) { - masm.moveValue(UndefinedValue(), output.valueReg()); - } else { - masm.assumeUnreachable("Should have monitored undefined result"); - } + // Store the value. + switch (elementType) { + case Scalar::Int16: + case Scalar::Uint16: + masm.store16Unaligned(valScratch32(), dest); + break; + case Scalar::Int32: + case Scalar::Uint32: + case Scalar::Float32: + masm.store32Unaligned(valScratch32(), dest); + break; + case Scalar::Float64: + case Scalar::BigInt64: + case Scalar::BigUint64: + masm.store64Unaligned(valScratch64(), dest); + break; + case Scalar::Int8: + case Scalar::Uint8: + case Scalar::Uint8Clamped: + default: + MOZ_CRASH("Invalid typed array type"); + } - masm.bind(&done); +#ifdef JS_CODEGEN_X86 + // Restore registers. + if (pushedLittleEndian) { + masm.pop(littleEndian); } +#endif + masm.moveValue(UndefinedValue(), output.valueReg()); return true; } -bool CacheIRCompiler::emitLoadTypedArrayElementResult(ObjOperandId objId, - Int32OperandId indexId, - Scalar::Type elementType, - bool handleOOB) { - return emitLoadTypedElementResult( - objId, indexId, TypedThingLayout::TypedArray, elementType, handleOOB); -} - -bool CacheIRCompiler::emitLoadTypedObjectElementResult( - ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout, - Scalar::Type elementType) { - return emitLoadTypedElementResult(objId, indexId, layout, elementType, - /* handleOOB = */ false); -} - bool CacheIRCompiler::emitStoreTypedObjectScalarProperty( ObjOperandId objId, uint32_t offsetOffset, TypedThingLayout layout, Scalar::Type type, uint32_t rhsId) { @@ -4472,6 +5474,28 @@ bool CacheIRCompiler::emitLoadTypedObjectResult(ObjOperandId objId, return true; } +bool CacheIRCompiler::emitStoreFixedSlotUndefinedResult(ObjOperandId objId, + uint32_t offsetOffset, + ValOperandId rhsId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + Register obj = allocator.useRegister(masm, objId); + ValueOperand val = allocator.useValueRegister(masm, rhsId); + + StubFieldOffset offset(offsetOffset, StubField::Type::RawWord); + emitLoadStubField(offset, scratch); + + BaseIndex slot(obj, scratch, TimesOne); + EmitPreBarrier(masm, slot, MIRType::Value); + masm.storeValue(val, slot); + emitPostBarrierSlot(obj, val, scratch); + + masm.moveValue(UndefinedValue(), output.valueReg()); + return true; +} + bool CacheIRCompiler::emitLoadObjectResult(ObjOperandId objId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoOutputRegister output(*this); @@ -4680,12 +5704,23 @@ bool CacheIRCompiler::emitLoadObjectTruthyResult(ObjOperandId objId) { masm.jump(&done); masm.bind(&slowPath); - masm.setupUnalignedABICall(scratch); - masm.passABIArg(obj); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::EmulatesUndefined)); - masm.convertBoolToInt32(ReturnReg, ReturnReg); - masm.xor32(Imm32(1), ReturnReg); - masm.tagValue(JSVAL_TYPE_BOOLEAN, ReturnReg, output.valueReg()); + { + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + volatileRegs.takeUnchecked(scratch); + volatileRegs.takeUnchecked(output); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(obj); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::EmulatesUndefined)); + masm.convertBoolToInt32(ReturnReg, scratch); + masm.xor32(Imm32(1), scratch); + + masm.PopRegsInMask(volatileRegs); + + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); + } masm.bind(&done); return true; @@ -4710,6 +5745,122 @@ bool CacheIRCompiler::emitLoadBigIntTruthyResult(BigIntOperandId bigIntId) { return true; } +bool CacheIRCompiler::emitLoadValueTruthyResult(ValOperandId inputId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + ValueOperand value = allocator.useValueRegister(masm, inputId); + AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output); + AutoScratchRegister scratch2(allocator, masm); + AutoScratchFloatRegister floatReg(this); + + Label ifFalse, ifTrue, done; + + { + ScratchTagScope tag(masm, value); + masm.splitTagForTest(value, tag); + + masm.branchTestUndefined(Assembler::Equal, tag, &ifFalse); + masm.branchTestNull(Assembler::Equal, tag, &ifFalse); + + Label notBoolean; + masm.branchTestBoolean(Assembler::NotEqual, tag, ¬Boolean); + { + ScratchTagScopeRelease _(&tag); + masm.branchTestBooleanTruthy(false, value, &ifFalse); + masm.jump(&ifTrue); + } + masm.bind(¬Boolean); + + Label notInt32; + masm.branchTestInt32(Assembler::NotEqual, tag, ¬Int32); + { + ScratchTagScopeRelease _(&tag); + masm.branchTestInt32Truthy(false, value, &ifFalse); + masm.jump(&ifTrue); + } + masm.bind(¬Int32); + + Label notObject; + masm.branchTestObject(Assembler::NotEqual, tag, ¬Object); + { + ScratchTagScopeRelease _(&tag); + + Register obj = masm.extractObject(value, scratch1); + + Label slowPath; + masm.branchIfObjectEmulatesUndefined(obj, scratch2, &slowPath, &ifFalse); + masm.jump(&ifTrue); + + masm.bind(&slowPath); + { + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + volatileRegs.takeUnchecked(scratch1); + volatileRegs.takeUnchecked(scratch2); + volatileRegs.takeUnchecked(output); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(scratch2); + masm.passABIArg(obj); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::EmulatesUndefined)); + masm.storeCallBoolResult(scratch2); + + masm.PopRegsInMask(volatileRegs); + + masm.branchTest32(Assembler::NonZero, scratch2, scratch2, &ifFalse); + masm.jump(&ifTrue); + } + } + masm.bind(¬Object); + + Label notString; + masm.branchTestString(Assembler::NotEqual, tag, ¬String); + { + ScratchTagScopeRelease _(&tag); + masm.branchTestStringTruthy(false, value, &ifFalse); + masm.jump(&ifTrue); + } + masm.bind(¬String); + + Label notBigInt; + masm.branchTestBigInt(Assembler::NotEqual, tag, ¬BigInt); + { + ScratchTagScopeRelease _(&tag); + masm.branchTestBigIntTruthy(false, value, &ifFalse); + masm.jump(&ifTrue); + } + masm.bind(¬BigInt); + + masm.branchTestSymbol(Assembler::Equal, tag, &ifTrue); + +#ifdef DEBUG + Label isDouble; + masm.branchTestDouble(Assembler::Equal, tag, &isDouble); + masm.assumeUnreachable("Unexpected value type"); + masm.bind(&isDouble); +#endif + + { + ScratchTagScopeRelease _(&tag); + masm.unboxDouble(value, floatReg); + masm.branchTestDoubleTruthy(false, floatReg, &ifFalse); + } + + // Fall through to true case. + } + + masm.bind(&ifTrue); + masm.moveValue(BooleanValue(true), output.valueReg()); + masm.jump(&done); + + masm.bind(&ifFalse); + masm.moveValue(BooleanValue(false), output.valueReg()); + + masm.bind(&done); + return true; +} + bool CacheIRCompiler::emitLoadNewObjectFromTemplateResult( uint32_t templateObjectOffset, uint32_t, uint32_t) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -5331,6 +6482,24 @@ bool CacheIRCompiler::emitCompareObjectUndefinedNullResult(JSOp op, return true; } +bool CacheIRCompiler::emitCompareDoubleSameValueResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoAvailableFloatRegister floatScratch0(*this, FloatReg0); + AutoAvailableFloatRegister floatScratch1(*this, FloatReg1); + AutoAvailableFloatRegister floatScratch2(*this, FloatReg2); + + allocator.ensureDoubleRegister(masm, lhsId, floatScratch0); + allocator.ensureDoubleRegister(masm, rhsId, floatScratch1); + + masm.sameValueDouble(floatScratch0, floatScratch1, floatScratch2, scratch); + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); + return true; +} + bool CacheIRCompiler::emitCallPrintString(const char* str) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); masm.printf(str); @@ -5362,8 +6531,7 @@ void CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val, case ReferenceType::TYPE_OBJECT: { EmitPreBarrier(masm, dest, MIRType::Object); Label isNull, done; - masm.branchTestObject(Assembler::NotEqual, val, &isNull); - masm.unboxObject(val, scratch); + masm.fallibleUnboxObject(val, scratch, &isNull); masm.storePtr(scratch, dest); masm.jump(&done); masm.bind(&isNull); @@ -5411,11 +6579,8 @@ void CacheIRCompiler::emitPostBarrierShared(Register obj, } TypedOrValueRegister reg = val.reg(); - if (reg.hasTyped()) { - if (reg.type() != MIRType::Object && reg.type() != MIRType::String && - reg.type() != MIRType::BigInt) { - return; - } + if (reg.hasTyped() && !NeedsPostBarrier(reg.type())) { + return; } Label skipBarrier; @@ -5736,10 +6901,9 @@ bool CacheIRCompiler::emitLoadInstanceOfObjectResult(ValOperandId lhsId, } Label returnFalse, returnTrue, done; - masm.branchTestObject(Assembler::NotEqual, lhs, &returnFalse); + masm.fallibleUnboxObject(lhs, scratch, &returnFalse); // LHS is an object. Load its proto. - masm.unboxObject(lhs, scratch); masm.loadObjProto(scratch, scratch); { // Walk the proto chain until we either reach the target object, @@ -5913,6 +7077,31 @@ bool CacheIRCompiler::emitLoadInt32Constant(uint32_t valOffset, return true; } +bool CacheIRCompiler::emitLoadBooleanConstant(bool val, + BooleanOperandId resultId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register reg = allocator.defineRegister(masm, resultId); + masm.move32(Imm32(val), reg); + return true; +} + +bool CacheIRCompiler::emitLoadUndefined(ValOperandId resultId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + ValueOperand reg = allocator.defineValueRegister(masm, resultId); + masm.moveValue(UndefinedValue(), reg); + return true; +} + +bool CacheIRCompiler::emitLoadConstantString(uint32_t strOffset, + StringOperandId resultId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + Register reg = allocator.defineRegister(masm, resultId); + StubFieldOffset str(strOffset, StubField::Type::String); + emitLoadStubField(str, reg); + return true; +} + bool CacheIRCompiler::emitCallInt32ToString(Int32OperandId inputId, StringOperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -5978,7 +7167,7 @@ bool CacheIRCompiler::emitCallNumberToString(NumberOperandId inputId, return true; } -bool CacheIRCompiler::emitBooleanToString(Int32OperandId inputId, +bool CacheIRCompiler::emitBooleanToString(BooleanOperandId inputId, StringOperandId resultId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); Register boolean = allocator.useRegister(masm, inputId); @@ -6045,10 +7234,12 @@ bool CacheIRCompiler::emitCallStringConcatResult(StringOperandId lhsId, callvm.prepare(); + masm.Push(static_cast(js::gc::DefaultHeap)); masm.Push(rhs); masm.Push(lhs); - using Fn = JSString* (*)(JSContext*, HandleString, HandleString); + using Fn = JSString* (*)(JSContext*, HandleString, HandleString, + js::gc::InitialHeap); callvm.call>(); return true; @@ -6063,10 +7254,9 @@ bool CacheIRCompiler::emitCallIsSuspendedGeneratorResult(ValOperandId valId) { // Test if it's an object. Label returnFalse, done; - masm.branchTestObject(Assembler::NotEqual, input, &returnFalse); + masm.fallibleUnboxObject(input, scratch, &returnFalse); // Test if it's a GeneratorObject. - masm.unboxObject(input, scratch); masm.branchTestObjClass(Assembler::NotEqual, scratch, &GeneratorObject::class_, scratch2, scratch, &returnFalse); @@ -6074,8 +7264,7 @@ bool CacheIRCompiler::emitCallIsSuspendedGeneratorResult(ValOperandId valId) { // If the resumeIndex slot holds an int32 value < RESUME_INDEX_RUNNING, // the generator is suspended. Address addr(scratch, AbstractGeneratorObject::offsetOfResumeIndexSlot()); - masm.branchTestInt32(Assembler::NotEqual, addr, &returnFalse); - masm.unboxInt32(addr, scratch); + masm.fallibleUnboxInt32(addr, scratch, &returnFalse); masm.branch32(Assembler::AboveOrEqual, scratch, Imm32(AbstractGeneratorObject::RESUME_INDEX_RUNNING), &returnFalse); @@ -6116,9 +7305,8 @@ bool CacheIRCompiler::emitCallNativeGetElementResult(ObjOperandId objId, return true; } -bool CacheIRCompiler::emitCallProxyHasPropResult(ObjOperandId objId, - ValOperandId idId, - bool hasOwn) { +bool CacheIRCompiler::emitProxyHasPropResult(ObjOperandId objId, + ValOperandId idId, bool hasOwn) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoCallVM callvm(masm, this, allocator); @@ -6139,8 +7327,8 @@ bool CacheIRCompiler::emitCallProxyHasPropResult(ObjOperandId objId, return true; } -bool CacheIRCompiler::emitCallProxyGetByValueResult(ObjOperandId objId, - ValOperandId idId) { +bool CacheIRCompiler::emitProxyGetByValueResult(ObjOperandId objId, + ValOperandId idId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoCallVM callvm(masm, this, allocator); @@ -6267,6 +7455,54 @@ bool CacheIRCompiler::emitCallSubstringKernelResult(StringOperandId strId, return true; } +bool CacheIRCompiler::emitStringReplaceStringResult( + StringOperandId strId, StringOperandId patternId, + StringOperandId replacementId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + + Register str = allocator.useRegister(masm, strId); + Register pattern = allocator.useRegister(masm, patternId); + Register replacement = allocator.useRegister(masm, replacementId); + + callvm.prepare(); + masm.Push(replacement); + masm.Push(pattern); + masm.Push(str); + + using Fn = + JSString* (*)(JSContext*, HandleString, HandleString, HandleString); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitStringSplitStringResult(StringOperandId strId, + StringOperandId separatorId, + uint32_t groupOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + + Register str = allocator.useRegister(masm, strId); + Register separator = allocator.useRegister(masm, separatorId); + AutoScratchRegister scratch(allocator, masm); + + StubFieldOffset group(groupOffset, StubField::Type::ObjectGroup); + emitLoadStubField(group, scratch); + + callvm.prepare(); + masm.Push(Imm32(INT32_MAX)); + masm.Push(separator); + masm.Push(str); + masm.Push(scratch); + + using Fn = ArrayObject* (*)(JSContext*, HandleObjectGroup, HandleString, + HandleString, uint32_t); + callvm.call(); + return true; +} + bool CacheIRCompiler::emitRegExpPrototypeOptimizableResult( ObjOperandId protoId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -6341,6 +7577,322 @@ bool CacheIRCompiler::emitRegExpInstanceOptimizableResult( return true; } +bool CacheIRCompiler::emitGetFirstDollarIndexResult(StringOperandId strId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoCallVM callvm(masm, this, allocator); + + Register str = allocator.useRegister(masm, strId); + + callvm.prepare(); + masm.Push(str); + + using Fn = bool (*)(JSContext*, JSString*, int32_t*); + callvm.call(); + return true; +} + +bool CacheIRCompiler::emitAtomicsCompareExchangeResult( + ObjOperandId objId, Int32OperandId indexId, Int32OperandId expectedId, + Int32OperandId replacementId, Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); +#ifdef JS_CODEGEN_X86 + // Use a scratch register to avoid running out of registers. + Register obj = output.valueReg().typeReg(); + allocator.copyToScratchRegister(masm, objId, obj); +#else + Register obj = allocator.useRegister(masm, objId); +#endif + Register index = allocator.useRegister(masm, indexId); + Register expected = allocator.useRegister(masm, expectedId); + Register replacement = allocator.useRegister(masm, replacementId); + + Register scratch = output.valueReg().scratchReg(); + MOZ_ASSERT(scratch != obj, "scratchReg must not be typeReg"); + + // Not enough registers on X86. + Register spectreTemp = Register::Invalid(); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check. + LoadTypedThingLength(masm, TypedThingLayout::TypedArray, obj, scratch); + masm.spectreBoundsCheck32(index, scratch, spectreTemp, failure->label()); + + // Atomic operations are highly platform-dependent, for example x86/x64 has + // specific requirements on which registers are used; MIPS needs multiple + // additional temporaries. Therefore we're using an ABI call here instead of + // handling each platform separately. + { + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + volatileRegs.takeUnchecked(output.valueReg()); + volatileRegs.takeUnchecked(scratch); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(obj); + masm.passABIArg(index); + masm.passABIArg(expected); + masm.passABIArg(replacement); + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, AtomicsCompareExchange(elementType))); + masm.storeCallInt32Result(scratch); + + masm.PopRegsInMask(volatileRegs); + } + + if (elementType != Scalar::Uint32) { + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); + } else { + ScratchDoubleScope fpscratch(masm); + masm.convertUInt32ToDouble(scratch, fpscratch); + masm.boxDouble(fpscratch, output.valueReg(), fpscratch); + } + + return true; +} + +bool CacheIRCompiler::emitAtomicsReadModifyWriteResult( + ObjOperandId objId, Int32OperandId indexId, Int32OperandId valueId, + Scalar::Type elementType, AtomicsReadWriteModifyFn fn) { + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register index = allocator.useRegister(masm, indexId); + Register value = allocator.useRegister(masm, valueId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + // Not enough registers on X86. + Register spectreTemp = Register::Invalid(); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check. + LoadTypedThingLength(masm, TypedThingLayout::TypedArray, obj, scratch); + masm.spectreBoundsCheck32(index, scratch, spectreTemp, failure->label()); + + // See comment in emitAtomicsCompareExchange for why we use an ABI call. + { + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + volatileRegs.takeUnchecked(output.valueReg()); + volatileRegs.takeUnchecked(scratch); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(scratch); + masm.passABIArg(obj); + masm.passABIArg(index); + masm.passABIArg(value); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, fn)); + masm.storeCallInt32Result(scratch); + + masm.PopRegsInMask(volatileRegs); + } + + if (elementType != Scalar::Uint32) { + masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg()); + } else { + ScratchDoubleScope fpscratch(masm); + masm.convertUInt32ToDouble(scratch, fpscratch); + masm.boxDouble(fpscratch, output.valueReg(), fpscratch); + } + + return true; +} + +bool CacheIRCompiler::emitAtomicsExchangeResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsExchange(elementType)); +} + +bool CacheIRCompiler::emitAtomicsAddResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsAdd(elementType)); +} + +bool CacheIRCompiler::emitAtomicsSubResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsSub(elementType)); +} + +bool CacheIRCompiler::emitAtomicsAndResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsAnd(elementType)); +} + +bool CacheIRCompiler::emitAtomicsOrResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsOr(elementType)); +} + +bool CacheIRCompiler::emitAtomicsXorResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + return emitAtomicsReadModifyWriteResult(objId, indexId, valueId, elementType, + AtomicsXor(elementType)); +} + +bool CacheIRCompiler::emitAtomicsLoadResult(ObjOperandId objId, + Int32OperandId indexId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register index = allocator.useRegister(masm, indexId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoSpectreBoundsScratchRegister spectreTemp(allocator, masm); + AutoAvailableFloatRegister floatReg(*this, FloatReg0); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check. + LoadTypedThingLength(masm, TypedThingLayout::TypedArray, obj, scratch); + masm.spectreBoundsCheck32(index, scratch, spectreTemp, failure->label()); + + // Load the elements vector. + LoadTypedThingData(masm, TypedThingLayout::TypedArray, obj, scratch); + + // Load the value. + BaseIndex source(scratch, index, + ScaleFromElemWidth(Scalar::byteSize(elementType))); + + auto sync = Synchronization::Load(); + + masm.memoryBarrierBefore(sync); + if (elementType != Scalar::Uint32) { + bool allowDouble = false; + Register tempUint32 = Register::Invalid(); + Label* failUint32 = nullptr; + + masm.loadFromTypedArray(elementType, source, output.valueReg(), allowDouble, + tempUint32, failUint32); + } else { + Label* failUint32 = nullptr; + + masm.loadFromTypedArray(elementType, source, AnyRegister(floatReg), scratch, + failUint32); + masm.boxDouble(floatReg, output.valueReg(), floatReg); + } + masm.memoryBarrierAfter(sync); + + return true; +} + +bool CacheIRCompiler::emitAtomicsStoreResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register obj = allocator.useRegister(masm, objId); + Register index = allocator.useRegister(masm, indexId); + Register value = allocator.useRegister(masm, valueId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + // Not enough registers on X86. + Register spectreTemp = Register::Invalid(); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check. + LoadTypedThingLength(masm, TypedThingLayout::TypedArray, obj, scratch); + masm.spectreBoundsCheck32(index, scratch, spectreTemp, failure->label()); + + // Load the elements vector. + LoadTypedThingData(masm, TypedThingLayout::TypedArray, obj, scratch); + + // Store the value. + BaseIndex dest(scratch, index, + ScaleFromElemWidth(Scalar::byteSize(elementType))); + + auto sync = Synchronization::Store(); + + masm.memoryBarrierBefore(sync); + masm.storeToTypedIntArray(elementType, value, dest); + masm.memoryBarrierAfter(sync); + + masm.tagValue(JSVAL_TYPE_INT32, value, output.valueReg()); + + return true; +} + +bool CacheIRCompiler::emitAtomicsIsLockFreeResult(Int32OperandId valueId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + Register value = allocator.useRegister(masm, valueId); + AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + + masm.atomicIsLockFreeJS(value, scratch); + masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); + + return true; +} + +bool CacheIRCompiler::emitBailout() { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + // Generates no code. + + return true; +} + +bool CacheIRCompiler::emitAssertRecoveredOnBailoutResult(ValOperandId valId, + bool mustBeRecovered) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + + AutoOutputRegister output(*this); + + // NOP when not in IonMonkey + masm.moveValue(UndefinedValue(), output.valueReg()); + + return true; +} + template void CacheIRCompiler::callVM(MacroAssembler& masm) { VMFunctionId id = VMFunctionToId::id; @@ -6448,7 +8000,9 @@ void AutoCallVM::storeResult(JSValueType returnType) { } } } +} +void AutoCallVM::leaveBaselineStubFrame() { if (compiler_->mode_ == CacheIRCompiler::Mode::Baseline) { stubFrame_->leave(masm_); } @@ -6490,6 +8044,34 @@ template <> struct ReturnTypeToJSValueType { static constexpr JSValueType result = JSVAL_TYPE_BIGINT; }; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; +template <> +struct ReturnTypeToJSValueType { + static constexpr JSValueType result = JSVAL_TYPE_OBJECT; +}; template void AutoCallVM::storeResult() { diff --git a/js/src/jit/CacheIRCompiler.h b/js/src/jit/CacheIRCompiler.h index 4774213016..6be4af1b50 100644 --- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -10,14 +10,18 @@ #include "jit/CacheIR.h" #include "jit/JitOptions.h" #include "jit/SharedICRegisters.h" +#include "js/ScalarType.h" // js::Scalar::Type namespace js { + +class TypedArrayObject; + namespace jit { class BaselineCacheIRCompiler; class IonCacheIRCompiler; -// [SMDDOC] CacheIR Value Representation and Tracking +// [SMDOC] CacheIR Value Representation and Tracking // // While compiling an IC stub the CacheIR compiler needs to keep track of the // physical location for each logical piece of data we care about, as well as @@ -345,7 +349,7 @@ class MOZ_RAII CacheRegisterAllocator { void popPayload(MacroAssembler& masm, OperandLocation* loc, Register dest); void popValue(MacroAssembler& masm, OperandLocation* loc, ValueOperand dest); - Address valueAddress(MacroAssembler& masm, OperandLocation* loc); + Address valueAddress(MacroAssembler& masm, const OperandLocation* loc) const; #ifdef DEBUG void assertValidState() const; @@ -494,9 +498,17 @@ class MOZ_RAII CacheRegisterAllocator { // Loads (potentially coercing) and unboxes a value into a float register // This is infallible, as there should have been a previous guard - // to ensure the ValOperandId is already a number. + // to ensure the value is already a number. + // Does not change the allocator's state. void ensureDoubleRegister(MacroAssembler& masm, NumberOperandId op, - FloatRegister dest); + FloatRegister dest) const; + + // Loads an unboxed value into a scratch register. This can be useful + // especially on 32-bit x86 when there are not enough registers for + // useRegister. + // Does not change the allocator's state. + void copyToScratchRegister(MacroAssembler& masm, TypedOperandId typedId, + Register dest) const; // Returns |val|'s JSValueType or JSVAL_TYPE_UNKNOWN. JSValueType knownType(ValOperandId val) const; @@ -752,9 +764,14 @@ class MOZ_RAII CacheIRCompiler { !allocator.isDeadAfterInstruction(objId); } + bool emitLoadTypedElementExistsResult(ObjOperandId objId, + Int32OperandId indexId, + TypedThingLayout layout); + bool emitLoadTypedElementResult(ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout, - Scalar::Type elementType, bool handleOOB); + Scalar::Type elementType, bool handleOOB, + bool allowDoubleForUint32); bool emitStoreTypedElement(ObjOperandId objId, TypedThingLayout layout, Scalar::Type elementType, Int32OperandId indexId, @@ -805,6 +822,13 @@ class MOZ_RAII CacheIRCompiler { bool emitDoubleIncDecResult(bool isInc, NumberOperandId inputId); + using AtomicsReadWriteModifyFn = int32_t (*)(TypedArrayObject*, int32_t, + int32_t); + + MOZ_MUST_USE bool emitAtomicsReadModifyWriteResult( + ObjOperandId objId, Int32OperandId indexId, Int32OperandId valueId, + Scalar::Type elementType, AtomicsReadWriteModifyFn fn); + CACHE_IR_COMPILER_SHARED_GENERATED void emitLoadStubField(StubFieldOffset val, Register dest); @@ -879,11 +903,6 @@ class MOZ_RAII CacheIRCompiler { #endif public: - // The maximum number of arguments passed to a spread call or - // fun_apply IC. Keep this small to avoid controllable stack - // overflows by attackers passing large arrays. - static const uint32_t MAX_ARGS_ARRAY_LENGTH = 16; - void callVMInternal(MacroAssembler& masm, VMFunctionId id); template void callVM(MacroAssembler& masm); @@ -987,6 +1006,39 @@ class MOZ_RAII AutoScratchRegisterMaybeOutput { operator Register() const { return scratchReg_; } }; +// Like AutoScratchRegisterMaybeOutput, but tries to use the ValueOperand's +// type register for the scratch register on 32-bit. +// +// Word of warning: Passing an instance of this class and AutoOutputRegister to +// functions may not work correctly, because no guarantee is given that the type +// register is used last when modifying the output's ValueOperand. +class MOZ_RAII AutoScratchRegisterMaybeOutputType { + mozilla::Maybe scratch_; + Register scratchReg_; + + public: + AutoScratchRegisterMaybeOutputType(CacheRegisterAllocator& alloc, + MacroAssembler& masm, + const AutoOutputRegister& output) { +#if defined(JS_NUNBOX32) + scratchReg_ = output.hasValue() ? output.valueReg().typeReg() : InvalidReg; +#else + scratchReg_ = InvalidReg; +#endif + if (scratchReg_ == InvalidReg) { + scratch_.emplace(alloc, masm); + scratchReg_ = scratch_.ref(); + } + } + + AutoScratchRegisterMaybeOutputType( + const AutoScratchRegisterMaybeOutputType&) = delete; + + void operator=(const AutoScratchRegisterMaybeOutputType&) = delete; + + operator Register() const { return scratchReg_; } +}; + // AutoCallVM is a wrapper class that unifies methods shared by // IonCacheIRCompiler and BaselineCacheIRCompiler that perform a callVM, but // require stub specific functionality before performing the VM call. @@ -1043,6 +1095,8 @@ class MOZ_RAII AutoCallVM { template void storeResult(); + void leaveBaselineStubFrame(); + public: AutoCallVM(MacroAssembler& masm, CacheIRCompiler* compiler, CacheRegisterAllocator& allocator); @@ -1053,7 +1107,16 @@ class MOZ_RAII AutoCallVM { void call() { compiler_->callVM(masm_); storeResult(); + leaveBaselineStubFrame(); + } + + template + void callNoResult() { + compiler_->callVM(masm_); + leaveBaselineStubFrame(); } + + ValueOperand outputValueReg() const { return output_->valueReg(); } }; // RAII class to allocate FloatReg0 as a scratch register and release it when @@ -1169,6 +1232,12 @@ class CacheIRStubInfo { uintptr_t getStubRawWord(const uint8_t* stubData, uint32_t offset) const; uintptr_t getStubRawWord(ICStub* stub, uint32_t offset) const; + + int64_t getStubRawInt64(const uint8_t* stubData, uint32_t offset) const; + int64_t getStubRawInt64(ICStub* stub, uint32_t offset) const; + + void replaceStubRawWord(uint8_t* stubData, uint32_t offset, uintptr_t oldWord, + uintptr_t newWord) const; }; template diff --git a/js/src/jit/CacheIRHealth.cpp b/js/src/jit/CacheIRHealth.cpp new file mode 100644 index 0000000000..75685eb072 --- /dev/null +++ b/js/src/jit/CacheIRHealth.cpp @@ -0,0 +1,186 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifdef JS_CACHEIR_SPEW + +# include "jit/CacheIRHealth.h" + +# include "mozilla/Maybe.h" + +# include "jit/JitScript.h" + +using namespace js; +using namespace js::jit; + +// TODO: Refine how we assign happiness based on total health score. +CacheIRHealth::Happiness CacheIRHealth::determineStubHappiness( + uint32_t stubHealthScore) { + if (stubHealthScore >= 30) { + return Sad; + } + + if (stubHealthScore >= 20) { + return MediumSad; + } + + if (stubHealthScore >= 10) { + return MediumHappy; + } + + return Happy; +} + +CacheIRHealth::Happiness CacheIRHealth::spewStubHealth( + AutoStructuredSpewer& spew, ICStub* stub) { + const CacheIRStubInfo* stubInfo = stub->cacheIRStubInfo(); + CacheIRReader stubReader(stubInfo); + uint32_t totalStubHealth = 0; + + spew->beginListProperty("cacheIROps"); + while (stubReader.more()) { + CacheOp op = stubReader.readOp(); + uint32_t opHealth = CacheIROpHealth[size_t(op)]; + uint32_t argLength = CacheIROpInfos[size_t(op)].argLength; + const char* opName = CacheIROpNames[size_t(op)]; + + spew->beginObject(); + if (opHealth == UINT32_MAX) { + spew->property("unscoredOp", opName); + } else { + spew->property("cacheIROp", opName); + spew->property("opHealth", opHealth); + totalStubHealth += opHealth; + } + spew->endObject(); + + stubReader.skip(argLength); + } + spew->endList(); // cacheIROps + + spew->property("stubHealth", totalStubHealth); + + Happiness stubHappiness = determineStubHappiness(totalStubHealth); + spew->property("stubHappiness", stubHappiness); + + return stubHappiness; +} + +CacheIRHealth::Happiness CacheIRHealth::spewHealthForStubsInCacheIREntry( + AutoStructuredSpewer& spew, ICEntry* entry) { + jit::ICStub* stub = entry->firstStub(); + + spew->beginListProperty("stubs"); + + Happiness entryHappiness = Happy; + bool sawNonZeroCount = false; + + while (stub && !stub->isFallback()) { + spew->beginObject(); + { + uint32_t count; + if (js::jit::GetStubEnteredCount(stub, &count)) { + Happiness stubHappiness = spewStubHealth(spew, stub); + if (stubHappiness < entryHappiness) { + entryHappiness = stubHappiness; + } + + if (count > 0 && sawNonZeroCount) { + // More than one stub has a hit count greater than zero. + // This is sad because we do not Warp transpile in this case. + entryHappiness = Sad; + } else if (count > 0 && !sawNonZeroCount) { + sawNonZeroCount = true; + } + + spew->property("hitCount", count); + } + } + + spew->endObject(); + stub = stub->next(); + } + spew->endList(); // stubs + + if (entry->fallbackStub()->state().mode() != ICState::Mode::Specialized) { + entryHappiness = Sad; + } + + spew->property("entryHappiness", uint8_t(entryHappiness)); + + spew->property("mode", uint8_t(entry->fallbackStub()->state().mode())); + + spew->property("fallbackCount", entry->fallbackStub()->enteredCount()); + + return entryHappiness; +} + +CacheIRHealth::Happiness CacheIRHealth::spewJSOpAndCacheIRHealth( + AutoStructuredSpewer& spew, HandleScript script, jit::ICEntry* entry, + jsbytecode* pc, JSOp op) { + spew->beginObject(); + spew->property("op", CodeName(op)); + + if (pc == script->main()) { + spew->property("main", true); + } + + // TODO: If a perf issue arises, look into improving the SrcNotes + // API call below. + unsigned column; + spew->property("lineno", PCToLineNumber(script, pc, &column)); + spew->property("column", column); + + Happiness entryHappiness = spewHealthForStubsInCacheIREntry(spew, entry); + spew->endObject(); + + return entryHappiness; +} + +bool CacheIRHealth::rateMyCacheIR(JSContext* cx, HandleScript script) { + AutoStructuredSpewer spew(cx, SpewChannel::RateMyCacheIR, script); + if (!spew) { + return true; + } + + jit::JitScript* jitScript = script->jitScript(); + jsbytecode* next = script->code(); + jsbytecode* end = script->codeEnd(); + + spew->beginListProperty("entries"); + ICEntry* prevEntry = nullptr; + Happiness scriptHappiness = Happy; + while (next < end) { + uint32_t len = 0; + uint32_t pcOffset = script->pcToOffset(next); + + jit::ICEntry* entry = + jitScript->maybeICEntryFromPCOffset(pcOffset, prevEntry); + if (entry) { + prevEntry = entry; + } + + JSOp op = JSOp(*next); + const JSCodeSpec& cs = CodeSpec(op); + len = cs.length; + MOZ_ASSERT(len); + + if (entry && (entry->firstStub()->isFallback() || + ICStub::IsCacheIRKind(entry->firstStub()->kind()))) { + Happiness entryHappiness = + spewJSOpAndCacheIRHealth(spew, script, entry, next, op); + + if (entryHappiness < scriptHappiness) { + scriptHappiness = entryHappiness; + } + } + + next += len; + } + spew->endList(); // entries + + spew->property("scriptHappiness", uint8_t(scriptHappiness)); + + return true; +} + +#endif /* JS_CACHEIR_SPEW */ diff --git a/js/src/jit/CacheIRHealth.h b/js/src/jit/CacheIRHealth.h new file mode 100644 index 0000000000..d3bc1fdaf6 --- /dev/null +++ b/js/src/jit/CacheIRHealth.h @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 jit_CacheIRHealth_h +#define jit_CacheIRHealth_h + +#ifdef JS_CACHEIR_SPEW + +# include "mozilla/Sprintf.h" + +# include "jit/CacheIR.h" + +namespace js { +namespace jit { + +class ICEntry; + +// [SMDOC] CacheIR Health Rating +// +// The goal of CacheIR health rating is to make the costlier +// CacheIR stubs more apparent and easier to diagnose. +// This is done by using the scores assigned to different CacheIROps in +// CacheIROps.yaml (see the description of cost_estimate in the +// aforementioned file for how these scores are determined), summing +// the score of each op generated for a particular stub together, and displaying +// this score for each stub in a CacheIR chain. The higher the total stub score +// the more expensive the stub is. +// +// To see the CacheIR health rating for a script, simply call the +// rateMyCacheIR() shell function. This function takes either a particular +// function as a parameter and then prints the health of the CacheIR generated +// for the script associated with that function, or if you call rateMyCacheIR() +// without any parameters it will take the topmost script and rate that. +// + +class CacheIRHealth { + enum Happiness : uint8_t { Sad, MediumSad, MediumHappy, Happy }; + + public: + // Get happiness from health score. + Happiness determineStubHappiness(uint32_t stubHealthScore); + // Health of an individual stub. + Happiness spewStubHealth(AutoStructuredSpewer& spew, ICStub* stub); + // Health of all the stubs in an individual CacheIR Entry. + Happiness spewHealthForStubsInCacheIREntry(AutoStructuredSpewer& spew, + ICEntry* entry); + // Show JSOps present in the script, formatted for CacheIR + // health report. + Happiness spewJSOpAndCacheIRHealth(AutoStructuredSpewer& spew, + HandleScript script, jit::ICEntry* entry, + jsbytecode* pc, JSOp op); + // If a JitScript exists, shows health of all ICEntries that exist + // for the specified script. + bool rateMyCacheIR(JSContext* cx, HandleScript script); +}; + +} // namespace jit +} // namespace js + +#endif /* JS_CACHEIR_SPEW */ +#endif /* jit_CacheIRHealth_h */ diff --git a/js/src/jit/CacheIROps.yaml b/js/src/jit/CacheIROps.yaml index 486c5ceb9a..324d120849 100644 --- a/js/src/jit/CacheIROps.yaml +++ b/js/src/jit/CacheIROps.yaml @@ -23,6 +23,31 @@ # ========= # Whether this op can be transpiled to MIR by WarpCacheIRTranspiler. # +# cost_estimate +# ========= +# Score of an individual CacheIR Opcode's contribution to the overall score for +# each stub. This score is based off of the cost of the masm calls made by the op's +# implementation. The higher the score the more costly the op is. +# +# How to decide the cost estimate for a CacheIROp: +# 0 points - Generates no code +# 1 point - 1-5 simple masm ops, no callVM or callWithABI +# 2 points - 5-20 masm ops, no callVM or callWithABI +# 3 points - 20+ masm ops, no callVM or callWithABI +# 4 points - callWithABI +# 5 points - callVM +# 6 points - more than one callWithABI or callVM +# +# In the case of the op not being shared, default to counting the Baseline +# implementation. +# +# If the cost estimate is different based off of what branch of a conditional +# is taken, assign the score of the branch with the highest cost. +# +# Note: +# Currently, the scoring is tentative. It is in place to provide an +# estimate for the cost of each op. The scoring will be refined. +# # custom_writer (optional) # ======================== # If true, the generated CacheIRWriter method will be private and has a trailing @@ -49,9 +74,22 @@ # If there's an argument named 'result', the generated CacheIRWriter method will # return a new OperandId of this type. +- name: TypeMonitorResult + shared: false + transpile: true + cost_estimate: 1 + args: + +- name: ReturnFromIC + shared: false + transpile: true + cost_estimate: 1 + args: + - name: GuardToObject shared: true transpile: true + cost_estimate: 1 custom_writer: true args: input: ValId @@ -59,37 +97,43 @@ - name: GuardIsObjectOrNull shared: true transpile: false + cost_estimate: 1 args: input: ValId - name: GuardIsNullOrUndefined shared: true transpile: true + cost_estimate: 1 args: input: ValId - name: GuardIsNull shared: true transpile: true + cost_estimate: 1 args: input: ValId - name: GuardIsUndefined shared: true transpile: true + cost_estimate: 1 args: input: ValId - name: GuardToBoolean shared: true transpile: true + cost_estimate: 1 + custom_writer: true args: input: ValId - result: Int32Id - name: GuardToString shared: true transpile: true + cost_estimate: 1 custom_writer: true args: input: ValId @@ -97,13 +141,15 @@ - name: GuardToSymbol shared: true transpile: true + cost_estimate: 1 custom_writer: true args: input: ValId - name: GuardToBigInt shared: true - transpile: false + transpile: true + cost_estimate: 1 custom_writer: true args: input: ValId @@ -111,6 +157,7 @@ - name: GuardIsNumber shared: true transpile: true + cost_estimate: 1 custom_writer: true args: input: ValId @@ -118,6 +165,16 @@ - name: GuardToInt32 shared: true transpile: true + cost_estimate: 1 + custom_writer: true + args: + input: ValId + +# If the Value is a boolean, convert it to int32. +- name: GuardBooleanToInt32 + shared: true + transpile: true + cost_estimate: 1 args: input: ValId result: Int32Id @@ -125,6 +182,7 @@ - name: GuardToInt32Index shared: true transpile: true + cost_estimate: 1 args: input: ValId result: Int32Id @@ -132,6 +190,7 @@ - name: GuardToTypedArrayIndex shared: true transpile: true + cost_estimate: 2 args: input: ValId result: Int32Id @@ -139,13 +198,15 @@ - name: GuardToInt32ModUint32 shared: true transpile: true + cost_estimate: 2 args: input: ValId result: Int32Id - name: GuardToUint8Clamped shared: true - transpile: false + transpile: true + cost_estimate: 2 args: input: ValId result: Int32Id @@ -155,6 +216,7 @@ - name: GuardNonDoubleType shared: true transpile: true + cost_estimate: 1 args: input: ValId type: ValueTypeImm @@ -162,28 +224,39 @@ - name: GuardShape shared: false transpile: true + cost_estimate: 1 args: obj: ObjId shape: ShapeField - name: GuardGroup shared: false - transpile: false + transpile: true + cost_estimate: 1 args: obj: ObjId group: GroupField - name: GuardProto shared: false - transpile: false + transpile: true + cost_estimate: 1 args: obj: ObjId proto: ObjectField +- name: GuardNullProto + shared: true + transpile: true + cost_estimate: 1 + args: + obj: ObjId + # Guard per GuardClassKind. - name: GuardClass shared: true transpile: true + cost_estimate: 1 args: obj: ObjId kind: GuardClassKindImm @@ -192,6 +265,7 @@ - name: GuardAnyClass shared: false transpile: true + cost_estimate: 1 args: obj: ObjId clasp: RawPointerField @@ -199,6 +273,7 @@ - name: HasClassResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId clasp: RawPointerField @@ -206,6 +281,7 @@ - name: CallRegExpMatcherResult shared: true transpile: true + cost_estimate: 5 args: regexp: ObjId input: StringId @@ -214,6 +290,7 @@ - name: CallRegExpSearcherResult shared: true transpile: true + cost_estimate: 5 args: regexp: ObjId input: StringId @@ -222,6 +299,7 @@ - name: CallRegExpTesterResult shared: true transpile: true + cost_estimate: 5 args: regexp: ObjId input: StringId @@ -230,28 +308,57 @@ - name: CallSubstringKernelResult shared: true transpile: true + cost_estimate: 5 args: str: StringId begin: Int32Id length: Int32Id +- name: StringReplaceStringResult + shared: true + transpile: true + cost_estimate: 5 + args: + str: StringId + pattern: StringId + replacement: StringId + +- name: StringSplitStringResult + shared: true + transpile: true + cost_estimate: 5 + args: + str: StringId + separator: StringId + group: GroupField + - name: RegExpPrototypeOptimizableResult shared: true transpile: true + cost_estimate: 4 args: proto: ObjId - name: RegExpInstanceOptimizableResult shared: true transpile: true + cost_estimate: 4 args: regexp: ObjId proto: ObjId +- name: GetFirstDollarIndexResult + shared: true + transpile: true + cost_estimate: 5 + args: + str: StringId + # Add a reference to a global in the compartment to keep it alive. - name: GuardCompartment shared: false transpile: false + cost_estimate: 2 args: obj: ObjId global: ObjectField @@ -260,37 +367,64 @@ - name: GuardIsExtensible shared: true transpile: false + cost_estimate: 1 args: obj: ObjId - name: GuardIsNativeObject shared: true transpile: false + cost_estimate: 1 args: obj: ObjId - name: GuardIsProxy shared: true - transpile: false + transpile: true + cost_estimate: 1 + args: + obj: ObjId + +- name: GuardIsNotProxy + shared: true + transpile: true + cost_estimate: 1 + args: + obj: ObjId + +- name: GuardIsNotArrayBufferMaybeShared + shared: true + transpile: true + cost_estimate: 1 + args: + obj: ObjId + +- name: GuardIsTypedArray + shared: true + transpile: true + cost_estimate: 1 args: obj: ObjId - name: GuardHasProxyHandler shared: false transpile: false + cost_estimate: 1 args: obj: ObjId handler: RawPointerField -- name: GuardNotDOMProxy +- name: GuardIsNotDOMProxy shared: true - transpile: false + transpile: true + cost_estimate: 1 args: obj: ObjId - name: GuardSpecificObject shared: false transpile: true + cost_estimate: 1 args: obj: ObjId expected: ObjectField @@ -298,15 +432,27 @@ - name: GuardSpecificFunction shared: false transpile: true + cost_estimate: 1 custom_writer: true args: - obj: ObjId + fun: ObjId expected: ObjectField nargsAndFlags: RawWordField +- name: GuardFunctionScript + shared: false + transpile: true + cost_estimate: 1 + custom_writer: true + args: + obj: ObjId + expected: BaseScriptField + nargsAndFlags: RawWordField + - name: GuardSpecificAtom shared: false transpile: true + cost_estimate: 4 args: str: StringId expected: AtomField @@ -314,66 +460,68 @@ - name: GuardSpecificSymbol shared: false transpile: true + cost_estimate: 1 args: sym: SymbolId expected: SymbolField -- name: GuardSpecificNativeFunction - shared: true - transpile: false - args: - obj: ObjId - native: JSNativeImm - - name: GuardMagicValue shared: true - transpile: false + transpile: true + cost_estimate: 1 args: val: ValId magic: JSWhyMagicImm - name: GuardFrameHasNoArgumentsObject shared: false - transpile: false + transpile: true + cost_estimate: 1 args: - name: GuardNoDenseElements shared: true transpile: true + cost_estimate: 1 args: obj: ObjId -- name: GuardAndGetIndexFromString +- name: GuardStringToIndex shared: true - transpile: false + transpile: true + cost_estimate: 4 args: str: StringId result: Int32Id -- name: GuardAndGetInt32FromString +- name: GuardStringToInt32 shared: true - transpile: false + transpile: true + cost_estimate: 4 args: str: StringId result: Int32Id -- name: GuardAndGetNumberFromString +- name: GuardStringToNumber shared: true - transpile: false + transpile: true + cost_estimate: 4 args: str: StringId result: NumberId -- name: GuardAndGetNumberFromBoolean +- name: BooleanToNumber shared: true - transpile: false + transpile: true + cost_estimate: 1 args: - boolean: Int32Id + boolean: BooleanId result: NumberId - name: GuardAndGetIterator shared: false transpile: false + cost_estimate: 4 args: obj: ObjId iter: ObjectField @@ -383,6 +531,7 @@ - name: GuardHasGetterSetter shared: false transpile: false + cost_estimate: 4 args: obj: ObjId shape: ShapeField @@ -390,18 +539,21 @@ - name: GuardGroupHasUnanalyzedNewScript shared: true transpile: false + cost_estimate: 1 args: group: GroupField - name: GuardIndexIsNonNegative shared: true transpile: false + cost_estimate: 1 args: index: Int32Id - name: GuardIndexGreaterThanArrayLength shared: true transpile: false + cost_estimate: 1 args: obj: ObjId index: Int32Id @@ -409,6 +561,7 @@ - name: GuardIndexIsValidUpdateOrAdd shared: true transpile: false + cost_estimate: 1 args: obj: ObjId index: Int32Id @@ -416,13 +569,15 @@ - name: GuardIndexGreaterThanDenseInitLength shared: true transpile: false + cost_estimate: 1 args: obj: ObjId index: Int32Id - name: GuardTagNotEqual shared: true - transpile: false + transpile: true + cost_estimate: 1 args: lhs: ValueTagId rhs: ValueTagId @@ -430,66 +585,88 @@ - name: GuardXrayExpandoShapeAndDefaultProto shared: true transpile: false + cost_estimate: 2 args: obj: ObjId - hasExpando: BoolImm shapeWrapper: ObjectField -# Guard obj[slot] == proto. -- name: GuardFunctionPrototype +- name: GuardXrayNoExpando shared: true transpile: false + cost_estimate: 2 args: obj: ObjId - proto: ObjId + +# Guard obj[slot] == expected. +- name: GuardDynamicSlotIsSpecificObject + shared: true + transpile: true + cost_estimate: 1 + args: + obj: ObjId + expected: ObjId slot: RawWordField - name: GuardNoAllocationMetadataBuilder shared: true transpile: false + cost_estimate: 1 args: - name: GuardObjectGroupNotPretenured shared: true transpile: false + cost_estimate: 1 args: group: GroupField - name: GuardFunctionHasJitEntry shared: true - transpile: false + transpile: true + cost_estimate: 1 args: fun: ObjId constructing: BoolImm - name: GuardFunctionHasNoJitEntry + shared: true + transpile: true + cost_estimate: 1 + args: + fun: ObjId + +- name: GuardFunctionIsNonBuiltinCtor shared: true transpile: false + cost_estimate: 1 args: fun: ObjId - name: GuardFunctionIsConstructor shared: true - transpile: false + transpile: true + cost_estimate: 1 args: fun: ObjId - name: GuardNotClassConstructor shared: true - transpile: false + transpile: true + cost_estimate: 1 args: fun: ObjId -- name: GuardFunApply - shared: false - transpile: false +- name: GuardArrayIsPacked + shared: true + transpile: true + cost_estimate: 1 args: - argc: Int32Id - flags: CallFlagsImm + array: ObjId - name: LoadObject shared: true transpile: true + cost_estimate: 1 args: result: ObjId obj: ObjectField @@ -497,6 +674,7 @@ - name: LoadProto shared: true transpile: true + cost_estimate: 1 args: obj: ObjId result: ObjId @@ -504,20 +682,23 @@ - name: LoadEnclosingEnvironment shared: true transpile: true + cost_estimate: 1 args: obj: ObjId result: ObjId - name: LoadWrapperTarget shared: true - transpile: false + transpile: true + cost_estimate: 1 args: obj: ObjId result: ObjId - name: LoadValueTag shared: true - transpile: false + transpile: true + cost_estimate: 1 args: val: ValId result: ValueTagId @@ -525,6 +706,7 @@ - name: LoadArgumentFixedSlot shared: false transpile: true + cost_estimate: 1 custom_writer: true args: result: ValId @@ -533,6 +715,7 @@ - name: LoadArgumentDynamicSlot shared: false transpile: true + cost_estimate: 1 custom_writer: true args: result: ValId @@ -542,13 +725,15 @@ - name: TruncateDoubleToUInt32 shared: true transpile: true + cost_estimate: 4 args: input: NumberId result: Int32Id - name: MegamorphicLoadSlotResult shared: true - transpile: false + transpile: true + cost_estimate: 4 args: obj: ObjId name: PropertyNameField @@ -556,7 +741,8 @@ - name: MegamorphicLoadSlotByValueResult shared: true - transpile: false + transpile: true + cost_estimate: 4 args: obj: ObjId id: ValId @@ -564,7 +750,8 @@ - name: MegamorphicStoreSlot shared: true - transpile: false + transpile: true + cost_estimate: 4 args: obj: ObjId name: PropertyNameField @@ -573,7 +760,8 @@ - name: MegamorphicSetElement shared: false - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: ValId @@ -582,7 +770,8 @@ - name: MegamorphicHasPropResult shared: true - transpile: false + transpile: true + cost_estimate: 4 args: obj: ObjId id: ValId @@ -592,6 +781,7 @@ - name: LoadDOMExpandoValue shared: true transpile: false + cost_estimate: 1 args: obj: ObjId result: ValId @@ -599,6 +789,7 @@ - name: LoadDOMExpandoValueGuardGeneration shared: false transpile: false + cost_estimate: 2 args: obj: ObjId expandoAndGeneration: RawPointerField @@ -608,6 +799,7 @@ - name: LoadDOMExpandoValueIgnoreGeneration shared: true transpile: false + cost_estimate: 1 args: obj: ObjId result: ValId @@ -615,6 +807,7 @@ - name: GuardDOMExpandoMissingOrGuardShape shared: false transpile: false + cost_estimate: 2 args: expando: ValId shape: ShapeField @@ -622,6 +815,7 @@ - name: StoreFixedSlot shared: false transpile: true + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -630,6 +824,7 @@ - name: StoreDynamicSlot shared: false transpile: true + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -637,7 +832,8 @@ - name: AddAndStoreFixedSlot shared: false - transpile: false + transpile: true + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -648,7 +844,8 @@ - name: AddAndStoreDynamicSlot shared: false - transpile: false + transpile: true + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -659,7 +856,8 @@ - name: AllocateAndStoreDynamicSlot shared: false - transpile: false + transpile: true + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -672,6 +870,7 @@ - name: StoreTypedObjectReferenceProperty shared: false transpile: false + cost_estimate: 6 args: obj: ObjId offset: RawWordField @@ -682,6 +881,7 @@ - name: StoreTypedObjectScalarProperty shared: true transpile: false + cost_estimate: 2 args: obj: ObjId offset: RawWordField @@ -692,6 +892,7 @@ - name: StoreDenseElement shared: false transpile: true + cost_estimate: 6 args: obj: ObjId index: Int32Id @@ -699,7 +900,8 @@ - name: StoreDenseElementHole shared: false - transpile: false + transpile: true + cost_estimate: 6 args: obj: ObjId index: Int32Id @@ -709,75 +911,333 @@ - name: ArrayPush shared: false transpile: true + cost_estimate: 6 args: obj: ObjId rhs: ValId - name: ArrayJoinResult - shared: true - transpile: false + shared: false + transpile: true + cost_estimate: 5 args: obj: ObjId + sep: StringId + +- name: PackedArrayPopResult + shared: true + transpile: true + cost_estimate: 2 + args: + array: ObjId + +- name: PackedArrayShiftResult + shared: true + transpile: true + cost_estimate: 4 + args: + array: ObjId + +- name: PackedArraySliceResult + shared: false + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + array: ObjId + begin: Int32Id + end: Int32Id - name: IsArrayResult shared: false transpile: true + cost_estimate: 5 args: input: ValId +- name: StoreFixedSlotUndefinedResult + shared: true + transpile: true + args: + obj: ObjId + offset: RawWordField + rhs: ValId + - name: IsObjectResult shared: true transpile: true + cost_estimate: 1 args: input: ValId +- name: IsPackedArrayResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + - name: IsCallableResult shared: true transpile: true + cost_estimate: 4 args: input: ValId - name: IsConstructorResult shared: true transpile: true + cost_estimate: 4 + args: + obj: ObjId + +- name: IsCrossRealmArrayConstructorResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + +- name: IsTypedArrayResult + shared: false + transpile: true + cost_estimate: 5 + args: + obj: ObjId + isPossiblyWrapped: BoolImm + +- name: IsTypedArrayConstructorResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + +- name: TypedArrayByteOffsetResult + shared: true + transpile: true + cost_estimate: 1 args: obj: ObjId +- name: TypedArrayElementShiftResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + +- name: FinishBoundFunctionInitResult + shared: true + transpile: true + cost_estimate: 5 + args: + bound: ObjId + target: ObjId + argCount: Int32Id + +- name: NewArrayIteratorResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + +- name: NewStringIteratorResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + +- name: NewRegExpStringIteratorResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + +- name: ObjectCreateResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + +- name: NewArrayFromLengthResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + length: Int32Id + +- name: NewTypedArrayFromLengthResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + length: Int32Id + +- name: NewTypedArrayFromArrayBufferResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + buffer: ObjId + byteOffset: ValId + length: ValId + +- name: NewTypedArrayFromArrayResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + array: ObjId + +- name: NewStringObjectResult + shared: true + transpile: true + cost_estimate: 5 + args: + templateObject: ObjectField + str: StringId + - name: StringFromCharCodeResult shared: false transpile: true + cost_estimate: 5 + args: + code: Int32Id + +- name: StringFromCodePointResult + shared: false + transpile: true + cost_estimate: 5 args: code: Int32Id +- name: StringToLowerCaseResult + shared: true + transpile: true + cost_estimate: 5 + args: + str: StringId + +- name: StringToUpperCaseResult + shared: true + transpile: true + cost_estimate: 5 + args: + str: StringId + - name: MathAbsInt32Result shared: true transpile: true + cost_estimate: 2 args: input: Int32Id - name: MathAbsNumberResult shared: true transpile: true + cost_estimate: 1 args: input: NumberId +- name: MathClz32Result + shared: true + transpile: true + cost_estimate: 1 + args: + input: Int32Id + +- name: MathSignInt32Result + shared: true + transpile: true + cost_estimate: 1 + args: + input: Int32Id + +- name: MathSignNumberResult + shared: true + transpile: true + cost_estimate: 2 + args: + input: NumberId + +- name: MathSignNumberToInt32Result + shared: true + transpile: true + cost_estimate: 2 + args: + input: NumberId + +- name: MathImulResult + shared: true + transpile: true + cost_estimate: 1 + args: + lhs: Int32Id + rhs: Int32Id + - name: MathSqrtNumberResult shared: true transpile: true + cost_estimate: 1 args: input: NumberId -# Because Baseline stub code is shared by all realms in the Zone, this -# instruction loads a pointer to the RNG from a stub field. -- name: MathRandomResult - shared: false +- name: MathFRoundNumberResult + shared: true + transpile: true + cost_estimate: 1 + args: + input: NumberId + +# Because Baseline stub code is shared by all realms in the Zone, this +# instruction loads a pointer to the RNG from a stub field. +- name: MathRandomResult + shared: false + transpile: true + cost_estimate: 3 + args: + rng: RawPointerField + +- name: MathHypot2NumberResult + shared: true + transpile: true + cost_estimate: 4 + args: + first: NumberId + second: NumberId + +- name: MathHypot3NumberResult + shared: true + transpile: true + cost_estimate: 4 + args: + first: NumberId + second: NumberId + third: NumberId + +- name: MathHypot4NumberResult + shared: true transpile: true + cost_estimate: 4 args: - rng: RawPointerField + first: NumberId + second: NumberId + third: NumberId + fourth: NumberId - name: MathAtan2NumberResult shared: true transpile: true + cost_estimate: 4 args: lhs: NumberId rhs: NumberId @@ -785,10 +1245,18 @@ - name: MathFloorToInt32Result shared: true transpile: true + cost_estimate: 3 args: input: NumberId - name: MathCeilToInt32Result + shared: true + transpile: true + cost_estimate: 1 + args: + input: NumberId + +- name: MathTruncToInt32Result shared: true transpile: true args: @@ -797,12 +1265,14 @@ - name: MathRoundToInt32Result shared: true transpile: true + cost_estimate: 1 args: input: NumberId - name: Int32MinMax shared: true transpile: true + cost_estimate: 1 args: isMax: BoolImm first: Int32Id @@ -812,6 +1282,7 @@ - name: NumberMinMax shared: true transpile: true + cost_estimate: 1 args: isMax: BoolImm first: NumberId @@ -821,13 +1292,22 @@ - name: MathFunctionNumberResult shared: true transpile: true + cost_estimate: 4 args: input: NumberId fun: UnaryMathFunctionImm +- name: ReflectGetPrototypeOfResult + shared: false + transpile: true + cost_estimate: 5 + args: + obj: ObjId + - name: StoreTypedArrayElement shared: true transpile: true + cost_estimate: 3 args: obj: ObjId elementType: ScalarTypeImm @@ -838,6 +1318,7 @@ - name: StoreTypedObjectElement shared: true transpile: false + cost_estimate: 3 args: obj: ObjId layout: TypedThingLayoutImm @@ -845,43 +1326,159 @@ index: Int32Id rhs: RawId +- name: AtomicsCompareExchangeResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + expected: Int32Id + replacement: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsExchangeResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsAddResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsSubResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsAndResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsOrResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsXorResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsLoadResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + index: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsStoreResult + shared: true + transpile: true + cost_estimate: 2 + args: + obj: ObjId + index: Int32Id + value: Int32Id + elementType: ScalarTypeImm + +- name: AtomicsIsLockFreeResult + shared: true + transpile: true + cost_estimate: 1 + args: + value: Int32Id + - name: CallNativeSetter shared: false - transpile: false + transpile: true + cost_estimate: 5 + custom_writer: true args: - obj: ObjId + receiver: ObjId setter: ObjectField rhs: ValId + sameRealm: BoolImm + nargsAndFlags: RawWordField - name: CallScriptedSetter shared: false - transpile: false + transpile: true + cost_estimate: 3 + custom_writer: true args: - obj: ObjId + receiver: ObjId setter: ObjectField rhs: ValId sameRealm: BoolImm + nargsAndFlags: RawWordField + +- name: CallDOMSetter + shared: false + transpile: true + cost_estimate: 4 + args: + obj: ObjId + jitInfo: RawPointerField + rhs: ValId - name: CallSetArrayLength shared: false - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId strict: BoolImm rhs: ValId -- name: CallProxySet +- name: ProxySet shared: false - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: IdField rhs: ValId strict: BoolImm -- name: CallProxySetByValue +- name: ProxySetByValue shared: false - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: ValId @@ -891,6 +1488,7 @@ - name: CallAddOrUpdateSparseElementHelper shared: false transpile: false + cost_estimate: 5 args: obj: ObjId id: Int32Id @@ -899,28 +1497,33 @@ - name: CallInt32ToString shared: true - transpile: false + transpile: true + cost_estimate: 4 args: input: Int32Id result: StringId - name: CallNumberToString shared: true - transpile: false + transpile: true + cost_estimate: 4 args: input: NumberId result: StringId - name: BooleanToString shared: true - transpile: false + transpile: true + cost_estimate: 2 args: - input: Int32Id + input: BooleanId result: StringId - name: CallScriptedFunction shared: false transpile: true + cost_estimate: 3 + custom_writer: true args: callee: ObjId argc: Int32Id @@ -928,8 +1531,8 @@ - name: CallNativeFunction shared: false - transpile: false transpile: true + cost_estimate: 4 custom_writer: true args: callee: ObjId @@ -944,6 +1547,7 @@ - name: CallClassHook shared: false transpile: false + cost_estimate: 4 custom_writer: true args: callee: ObjId @@ -951,10 +1555,23 @@ flags: CallFlagsImm target: RawPointerField +- name: CallInlinedFunction + shared: false + transpile: true + cost_estimate: 4 + custom_writer: true + args: + callee: ObjId + argc: Int32Id + icScript: RawPointerField + flags: CallFlagsImm + + # Meta ops generate no code, but contain data for BaselineInspector. - name: MetaTwoByte shared: true transpile: true + cost_estimate: 0 custom_writer: true args: kind: MetaTwoByteKindImm @@ -964,6 +1581,7 @@ - name: LoadFixedSlotResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId offset: RawWordField @@ -971,6 +1589,7 @@ - name: LoadFixedSlotTypedResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId offset: RawWordField @@ -979,6 +1598,7 @@ - name: LoadDynamicSlotResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId offset: RawWordField @@ -986,6 +1606,7 @@ - name: LoadTypedObjectResult shared: true transpile: false + cost_estimate: 4 args: obj: ObjId layout: TypedThingLayoutImm @@ -995,6 +1616,7 @@ - name: LoadDenseElementResult shared: true transpile: true + cost_estimate: 2 args: obj: ObjId index: Int32Id @@ -1002,6 +1624,7 @@ - name: LoadDenseElementHoleResult shared: true transpile: true + cost_estimate: 2 args: obj: ObjId index: Int32Id @@ -1009,20 +1632,31 @@ - name: CallGetSparseElementResult shared: true transpile: false + cost_estimate: 5 args: obj: ObjId index: Int32Id - name: LoadDenseElementExistsResult shared: true - transpile: false + transpile: true + cost_estimate: 1 + args: + obj: ObjId + index: Int32Id + +- name: LoadTypedArrayElementExistsResult + shared: true + transpile: true + cost_estimate: 2 args: obj: ObjId index: Int32Id -- name: LoadTypedElementExistsResult +- name: LoadTypedObjectElementExistsResult shared: true transpile: false + cost_estimate: 2 args: obj: ObjId index: Int32Id @@ -1031,6 +1665,7 @@ - name: LoadDenseElementHoleExistsResult shared: true transpile: false + cost_estimate: 2 args: obj: ObjId index: Int32Id @@ -1038,56 +1673,102 @@ - name: LoadTypedArrayElementResult shared: true transpile: true + cost_estimate: 4 args: obj: ObjId index: Int32Id elementType: ScalarTypeImm handleOOB: BoolImm + allowDoubleForUint32: BoolImm - name: LoadTypedObjectElementResult shared: true transpile: false + cost_estimate: 4 args: obj: ObjId index: Int32Id layout: TypedThingLayoutImm elementType: ScalarTypeImm +- name: LoadDataViewValueResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + offset: Int32Id + littleEndian: BooleanId + elementType: ScalarTypeImm + allowDoubleForUint32: BoolImm + +- name: StoreDataViewValueResult + shared: true + transpile: true + cost_estimate: 4 + args: + obj: ObjId + offset: Int32Id + value: RawId + littleEndian: BooleanId + elementType: ScalarTypeImm + - name: LoadInt32ArrayLengthResult shared: true transpile: true + cost_estimate: 1 + args: + obj: ObjId + +- name: LoadInt32ArrayLength + shared: true + transpile: true + cost_estimate: 1 args: obj: ObjId + result: Int32Id - name: LoadArgumentsObjectArgResult shared: true - transpile: false + transpile: true + cost_estimate: 2 args: obj: ObjId index: Int32Id - name: LoadArgumentsObjectLengthResult shared: true - transpile: false + transpile: true + cost_estimate: 1 args: obj: ObjId - name: LoadFunctionLengthResult shared: true - transpile: false + transpile: true + cost_estimate: 2 + args: + obj: ObjId + +- name: LoadFunctionNameResult + shared: true + transpile: true + cost_estimate: 2 args: obj: ObjId - name: LoadTypedArrayLengthResult shared: true transpile: true + cost_estimate: 1 args: obj: ObjId getter: ObjectField - name: LoadStringCharResult - shared: true + shared: false transpile: true + cost_estimate: 5 args: str: StringId index: Int32Id @@ -1095,6 +1776,7 @@ - name: LoadStringCharCodeResult shared: true transpile: true + cost_estimate: 3 args: str: StringId index: Int32Id @@ -1102,28 +1784,39 @@ - name: LoadStringLengthResult shared: true transpile: true + cost_estimate: 1 args: str: StringId - name: LoadFrameCalleeResult shared: false - transpile: false + transpile: true + cost_estimate: 1 args: - name: LoadFrameNumActualArgsResult shared: false - transpile: false + transpile: true + cost_estimate: 1 args: - name: LoadFrameArgumentResult shared: false - transpile: false + transpile: true + cost_estimate: 1 args: index: Int32Id +- name: FrameIsConstructingResult + shared: false + transpile: true + cost_estimate: 1 + args: + - name: LoadEnvironmentFixedSlotResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId offset: RawWordField @@ -1131,6 +1824,7 @@ - name: LoadEnvironmentDynamicSlotResult shared: false transpile: true + cost_estimate: 1 args: obj: ObjId offset: RawWordField @@ -1138,86 +1832,95 @@ - name: LoadObjectResult shared: true transpile: true + cost_estimate: 1 args: obj: ObjId - name: LoadStringResult shared: true transpile: true + cost_estimate: 1 args: str: StringId - name: LoadSymbolResult shared: true transpile: true + cost_estimate: 1 args: sym: SymbolId - name: LoadInt32Result shared: true transpile: true + cost_estimate: 1 args: val: Int32Id - name: LoadDoubleResult shared: true transpile: true + cost_estimate: 2 args: val: NumberId - name: LoadBigIntResult shared: true transpile: true + cost_estimate: 1 args: val: BigIntId - name: CallScriptedGetterResult shared: false - transpile: false + transpile: true + cost_estimate: 5 + custom_writer: true args: - obj: ObjId + receiver: ValId getter: ObjectField sameRealm: BoolImm + nargsAndFlags: RawWordField -- name: CallScriptedGetterByValueResult +- name: CallNativeGetterResult shared: false - transpile: false + transpile: true + cost_estimate: 5 + custom_writer: true args: - val: ValId + receiver: ValId getter: ObjectField sameRealm: BoolImm + nargsAndFlags: RawWordField -- name: CallNativeGetterResult +- name: CallDOMGetterResult shared: false - transpile: false + transpile: true + cost_estimate: 4 args: obj: ObjId - getter: ObjectField + jitInfo: RawPointerField -- name: CallNativeGetterByValueResult +- name: ProxyGetResult shared: false - transpile: false - args: - val: ValId - getter: ObjectField - -- name: CallProxyGetResult - shared: false - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: IdField -- name: CallProxyGetByValueResult +- name: ProxyGetByValueResult shared: true - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: ValId -- name: CallProxyHasPropResult +- name: ProxyHasPropResult shared: true - transpile: false + transpile: true + cost_estimate: 5 args: obj: ObjId id: ValId @@ -1226,6 +1929,7 @@ - name: CallObjectHasSparseElementResult shared: true transpile: false + cost_estimate: 4 args: obj: ObjId index: Int32Id @@ -1233,37 +1937,75 @@ - name: CallNativeGetElementResult shared: true transpile: false + cost_estimate: 5 args: obj: ObjId index: Int32Id +- name: GetNextMapSetEntryForIteratorResult + shared: true + transpile: true + cost_estimate: 4 + args: + iter: ObjId + resultArr: ObjId + isMap: BoolImm + - name: LoadUndefinedResult shared: true transpile: true + cost_estimate: 1 args: - name: LoadBooleanResult shared: true transpile: true + cost_estimate: 1 args: val: BoolImm - name: LoadInt32Constant shared: true transpile: true + cost_estimate: 1 args: val: RawWordField result: Int32Id +- name: LoadBooleanConstant + shared: true + transpile: true + cost_estimate: 1 + args: + val: BoolImm + result: BooleanId + +- name: LoadUndefined + shared: true + transpile: true + cost_estimate: 1 + args: + result: ValId + +- name: LoadConstantString + shared: true + transpile: true + cost_estimate: 1 + args: + str: StringField + result: StringId + - name: LoadConstantStringResult shared: false transpile: false + cost_estimate: 1 args: str: StringField - name: LoadInstanceOfObjectResult shared: true - transpile: false + transpile: true + cost_estimate: 3 args: lhs: ValId proto: ObjId @@ -1271,12 +2013,14 @@ - name: LoadTypeOfObjectResult shared: true transpile: false + cost_estimate: 4 args: obj: ObjId - name: DoubleAddResult shared: true transpile: true + cost_estimate: 2 args: lhs: NumberId rhs: NumberId @@ -1284,6 +2028,7 @@ - name: DoubleSubResult shared: true transpile: true + cost_estimate: 2 args: lhs: NumberId rhs: NumberId @@ -1291,6 +2036,7 @@ - name: DoubleMulResult shared: true transpile: true + cost_estimate: 2 args: lhs: NumberId rhs: NumberId @@ -1298,6 +2044,7 @@ - name: DoubleDivResult shared: true transpile: true + cost_estimate: 2 args: lhs: NumberId rhs: NumberId @@ -1305,6 +2052,7 @@ - name: DoubleModResult shared: true transpile: true + cost_estimate: 4 args: lhs: NumberId rhs: NumberId @@ -1312,6 +2060,7 @@ - name: DoublePowResult shared: true transpile: true + cost_estimate: 4 args: lhs: NumberId rhs: NumberId @@ -1319,6 +2068,7 @@ - name: Int32AddResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1326,6 +2076,7 @@ - name: Int32SubResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1333,6 +2084,7 @@ - name: Int32MulResult shared: true transpile: true + cost_estimate: 2 args: lhs: Int32Id rhs: Int32Id @@ -1340,6 +2092,7 @@ - name: Int32DivResult shared: true transpile: true + cost_estimate: 2 args: lhs: Int32Id rhs: Int32Id @@ -1347,6 +2100,7 @@ - name: Int32ModResult shared: true transpile: true + cost_estimate: 2 args: lhs: Int32Id rhs: Int32Id @@ -1354,6 +2108,7 @@ - name: Int32PowResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1361,6 +2116,7 @@ - name: BigIntAddResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1368,6 +2124,7 @@ - name: BigIntSubResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1375,6 +2132,7 @@ - name: BigIntMulResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1382,6 +2140,7 @@ - name: BigIntDivResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1389,6 +2148,7 @@ - name: BigIntModResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1396,6 +2156,7 @@ - name: BigIntPowResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1403,6 +2164,7 @@ - name: Int32BitOrResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1410,6 +2172,7 @@ - name: Int32BitXorResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1417,6 +2180,7 @@ - name: Int32BitAndResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1424,6 +2188,7 @@ - name: Int32LeftShiftResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1431,6 +2196,7 @@ - name: Int32RightShiftResult shared: true transpile: true + cost_estimate: 1 args: lhs: Int32Id rhs: Int32Id @@ -1438,6 +2204,7 @@ - name: Int32URightShiftResult shared: true transpile: true + cost_estimate: 2 args: lhs: Int32Id rhs: Int32Id @@ -1446,12 +2213,14 @@ - name: Int32NotResult shared: true transpile: true + cost_estimate: 1 args: input: Int32Id - name: BigIntBitOrResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1459,6 +2228,7 @@ - name: BigIntBitXorResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1466,6 +2236,7 @@ - name: BigIntBitAndResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1473,6 +2244,7 @@ - name: BigIntLeftShiftResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1480,6 +2252,7 @@ - name: BigIntRightShiftResult shared: true transpile: false + cost_estimate: 5 args: lhs: BigIntId rhs: BigIntId @@ -1487,102 +2260,126 @@ - name: BigIntNotResult shared: true transpile: false + cost_estimate: 5 args: input: BigIntId - name: Int32NegationResult shared: true transpile: true + cost_estimate: 1 args: input: Int32Id - name: DoubleNegationResult shared: true transpile: true + cost_estimate: 1 args: input: NumberId - name: BigIntNegationResult shared: true transpile: false + cost_estimate: 5 args: input: BigIntId - name: Int32IncResult shared: true transpile: true + cost_estimate: 1 args: input: Int32Id - name: Int32DecResult shared: true transpile: true + cost_estimate: 1 args: input: Int32Id - name: DoubleIncResult shared: true - transpile: false + transpile: true + cost_estimate: 1 args: input: NumberId - name: DoubleDecResult shared: true - transpile: false + transpile: true + cost_estimate: 1 args: input: NumberId - name: BigIntIncResult shared: true transpile: false + cost_estimate: 5 args: input: BigIntId - name: BigIntDecResult shared: true transpile: false + cost_estimate: 5 args: input: BigIntId - name: LoadInt32TruthyResult shared: true transpile: false + cost_estimate: 2 args: input: ValId - name: LoadDoubleTruthyResult shared: true transpile: false + cost_estimate: 2 args: input: NumberId - name: LoadStringTruthyResult shared: true transpile: false + cost_estimate: 2 args: str: StringId - name: LoadObjectTruthyResult shared: true transpile: false + cost_estimate: 4 args: obj: ObjId - name: LoadBigIntTruthyResult shared: true transpile: false + cost_estimate: 2 args: bigInt: BigIntId +- name: LoadValueTruthyResult + shared: true + transpile: true + cost_estimate: 4 + args: + input: ValId + - name: LoadValueResult shared: false transpile: false + cost_estimate: 1 args: val: ValueField - name: LoadNewObjectFromTemplateResult shared: true transpile: false + cost_estimate: 4 args: templateObject: ObjectField disambiguationIdHi: UInt32Imm @@ -1591,6 +2388,7 @@ - name: CallStringConcatResult shared: true transpile: true + cost_estimate: 5 args: lhs: StringId rhs: StringId @@ -1598,6 +2396,7 @@ - name: CallStringObjectConcatResult shared: false transpile: false + cost_estimate: 5 args: lhs: ValId rhs: ValId @@ -1605,12 +2404,14 @@ - name: CallIsSuspendedGeneratorResult shared: true transpile: false + cost_estimate: 2 args: val: ValId - name: CompareStringResult shared: false transpile: true + cost_estimate: 5 args: op: JSOpImm lhs: StringId @@ -1619,6 +2420,7 @@ - name: CompareObjectResult shared: true transpile: true + cost_estimate: 2 args: op: JSOpImm lhs: ObjId @@ -1626,7 +2428,8 @@ - name: CompareSymbolResult shared: true - transpile: false + transpile: true + cost_estimate: 2 args: op: JSOpImm lhs: SymbolId @@ -1635,6 +2438,7 @@ - name: CompareInt32Result shared: true transpile: true + cost_estimate: 2 args: op: JSOpImm lhs: Int32Id @@ -1643,6 +2447,7 @@ - name: CompareDoubleResult shared: true transpile: true + cost_estimate: 2 args: op: JSOpImm lhs: NumberId @@ -1651,6 +2456,7 @@ - name: CompareBigIntResult shared: true transpile: false + cost_estimate: 4 args: op: JSOpImm lhs: BigIntId @@ -1659,6 +2465,7 @@ - name: CompareBigIntInt32Result shared: true transpile: false + cost_estimate: 3 args: op: JSOpImm lhs: BigIntId @@ -1667,6 +2474,7 @@ - name: CompareInt32BigIntResult shared: true transpile: false + cost_estimate: 3 args: op: JSOpImm lhs: Int32Id @@ -1675,6 +2483,7 @@ - name: CompareBigIntNumberResult shared: true transpile: false + cost_estimate: 4 args: op: JSOpImm lhs: BigIntId @@ -1683,6 +2492,7 @@ - name: CompareNumberBigIntResult shared: true transpile: false + cost_estimate: 4 args: op: JSOpImm lhs: NumberId @@ -1691,6 +2501,7 @@ - name: CompareBigIntStringResult shared: true transpile: false + cost_estimate: 5 args: op: JSOpImm lhs: BigIntId @@ -1699,6 +2510,7 @@ - name: CompareStringBigIntResult shared: true transpile: false + cost_estimate: 5 args: op: JSOpImm lhs: StringId @@ -1707,32 +2519,48 @@ - name: CompareObjectUndefinedNullResult shared: true transpile: false + cost_estimate: 2 args: op: JSOpImm obj: ObjId +- name: CompareDoubleSameValueResult + shared: true + transpile: true + cost_estimate: 3 + args: + lhs: NumberId + rhs: NumberId + - name: CallPrintString shared: true transpile: false + cost_estimate: 1 args: str: StaticStringImm - name: Breakpoint shared: true transpile: false + cost_estimate: 1 args: -- name: TypeMonitorResult - shared: false - transpile: true +- name: WrapResult + shared: true + transpile: false + cost_estimate: 4 args: -- name: ReturnFromIC - shared: false +- name: Bailout + shared: true transpile: true + cost_estimate: 0 args: -- name: WrapResult +- name: AssertRecoveredOnBailoutResult shared: true - transpile: false + transpile: true + cost_estimate: 1 args: + val: ValId + mustBeRecovered: BoolImm diff --git a/js/src/jit/CacheIRSpewer.cpp b/js/src/jit/CacheIRSpewer.cpp index 6f483f8b48..6cf26199dc 100644 --- a/js/src/jit/CacheIRSpewer.cpp +++ b/js/src/jit/CacheIRSpewer.cpp @@ -20,6 +20,7 @@ # include "jsmath.h" +# include "js/ScalarType.h" // js::Scalar::Type # include "util/Text.h" # include "vm/JSFunction.h" # include "vm/JSObject.h" @@ -96,9 +97,11 @@ class MOZ_RAII CacheIROpsJitSpewer { out_.printf("%s %u", name, val); } void spewCallFlagsImm(const char* name, CallFlags flags) { - out_.printf("%s (format %u, isConstructing %u, isSameRealm %u)", name, - flags.getArgFormat(), flags.isConstructing(), - flags.isSameRealm()); + out_.printf( + "%s (format %u%s%s%s)", name, flags.getArgFormat(), + flags.isConstructing() ? ", isConstructing" : "", + flags.isSameRealm() ? ", isSameRealm" : "", + flags.needsUninitializedThis() ? ", needsUninitializedThis" : ""); } void spewJSWhyMagicImm(const char* name, JSWhyMagic magic) { out_.printf("%s JSWhyMagic(%u)", name, unsigned(magic)); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 78e3ff3664..44174afd4d 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -31,7 +31,6 @@ #include "builtin/TypedObject.h" #include "gc/Nursery.h" #include "irregexp/RegExpTypes.h" -#include "jit/AtomicOperations.h" #include "jit/BaselineCodeGen.h" #include "jit/IonIC.h" #include "jit/IonOptimizationLevels.h" @@ -46,12 +45,16 @@ #include "jit/SharedICHelpers.h" #include "jit/StackSlotAllocator.h" #include "jit/VMFunctions.h" +#include "jit/WarpSnapshot.h" +#include "js/experimental/JitInfo.h" // JSJit{Getter,Setter}CallArgs, JSJitMethodCallArgsTraits, JSJitInfo #include "js/RegExpFlags.h" // JS::RegExpFlag +#include "js/ScalarType.h" // js::Scalar::Type #include "util/CheckedArithmetic.h" #include "util/Unicode.h" #include "vm/ArrayBufferViewObject.h" #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" +#include "vm/BuiltinObjectKind.h" #include "vm/EqualityOperations.h" // js::SameValue #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/MatchPairs.h" @@ -730,6 +733,26 @@ void CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool) { masm.jump(ool->rejoin()); return; } + case CacheKind::OptimizeSpreadCall: { + auto* optimizeSpreadCallIC = ic->asOptimizeSpreadCallIC(); + + saveLive(lir); + + pushArg(optimizeSpreadCallIC->value()); + icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1)); + pushArg(ImmGCPtr(gen->outerInfo().script())); + + using Fn = bool (*)(JSContext*, HandleScript, IonOptimizeSpreadCallIC*, + HandleValue, bool*); + callVM(lir); + + StoreRegisterTo(optimizeSpreadCallIC->output()).generate(this); + restoreLiveIgnore( + lir, StoreRegisterTo(optimizeSpreadCallIC->output()).clobbered()); + + masm.jump(ool->rejoin()); + return; + } case CacheKind::In: { IonInIC* inIC = ic->asInIC(); @@ -770,6 +793,28 @@ void CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool) { masm.jump(ool->rejoin()); return; } + case CacheKind::CheckPrivateField: { + IonCheckPrivateFieldIC* checkPrivateFieldIC = ic->asCheckPrivateFieldIC(); + + saveLive(lir); + + pushArg(checkPrivateFieldIC->id()); + pushArg(checkPrivateFieldIC->value()); + + icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1)); + pushArg(ImmGCPtr(gen->outerInfo().script())); + + using Fn = bool (*)(JSContext*, HandleScript, IonCheckPrivateFieldIC*, + HandleValue, HandleValue, bool*); + callVM(lir); + + StoreRegisterTo(checkPrivateFieldIC->output()).generate(this); + restoreLiveIgnore( + lir, StoreRegisterTo(checkPrivateFieldIC->output()).clobbered()); + + masm.jump(ool->rejoin()); + return; + } case CacheKind::InstanceOf: { IonInstanceOfIC* hasInstanceOfIC = ic->asInstanceOfIC(); @@ -892,6 +937,7 @@ CodeGenerator::CodeGenerator(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm) : CodeGeneratorSpecific(gen, graph, masm), ionScriptLabels_(gen->alloc()), + ionNurseryObjectLabels_(gen->alloc()), scriptCounts_(nullptr), realmStubsToReadBarrier_(0) {} @@ -1845,8 +1891,7 @@ void CodeGenerator::visitValueToObject(LValueToObject* lir) { OutOfLineCode* ool = oolCallVM( lir, ArgList(input, Imm32(0)), StoreRegisterTo(output)); - masm.branchTestObject(Assembler::NotEqual, input, ool->entry()); - masm.unboxObject(input, output); + masm.fallibleUnboxObject(input, output, ool->entry()); masm.bind(ool->rejoin()); } @@ -2715,8 +2760,8 @@ JitCode* JitRealm::generateRegExpMatcherStub(JSContext* cx) { masm.bind(&matchResultJoin); MOZ_ASSERT(nativeTemplateObj.numFixedSlots() == 0); - // Dynamic slot count is always rounded to a power of 2 - MOZ_ASSERT(nativeTemplateObj.numDynamicSlots() == 4); + // Dynamic slot count is always one less than a power of 2. + MOZ_ASSERT(nativeTemplateObj.numDynamicSlots() == 3); static_assert(RegExpRealm::MatchResultObjectIndexSlot == 0, "First slot holds the 'index' property"); static_assert(RegExpRealm::MatchResultObjectInputSlot == 1, @@ -3818,13 +3863,6 @@ void CodeGenerator::visitTableSwitchV(LTableSwitchV* ins) { emitTableSwitchDispatch(mir, index, ToRegisterOrInvalid(ins->tempPointer())); } -void CodeGenerator::visitCloneLiteral(LCloneLiteral* lir) { - pushArg(ToRegister(lir->getObjectLiteral())); - - using Fn = JSObject* (*)(JSContext*, HandleObject); - callVM(lir); -} - void CodeGenerator::visitParameter(LParameter* lir) {} void CodeGenerator::visitCallee(LCallee* lir) { @@ -4066,6 +4104,20 @@ void CodeGenerator::visitPointer(LPointer* lir) { } } +void CodeGenerator::visitNurseryObject(LNurseryObject* lir) { + MOZ_ASSERT(JitOptions.warpBuilder); + + Register output = ToRegister(lir->output()); + uint32_t nurseryIndex = lir->mir()->nurseryIndex(); + + // Load a pointer to the entry in IonScript's nursery objects list. + CodeOffset label = masm.movWithPatch(ImmWord(uintptr_t(-1)), output); + masm.propagateOOM(ionNurseryObjectLabels_.emplaceBack(label, nurseryIndex)); + + // Load the JSObject*. + masm.loadPtr(Address(output, 0), output); +} + void CodeGenerator::visitKeepAliveObject(LKeepAliveObject* lir) { // No-op. } @@ -4409,6 +4461,307 @@ void CodeGenerator::visitGuardShape(LGuardShape* guard) { bailoutFrom(&bail, guard->snapshot()); } +void CodeGenerator::visitGuardProto(LGuardProto* guard) { + Register obj = ToRegister(guard->object()); + Register expected = ToRegister(guard->expected()); + Register temp = ToRegister(guard->temp()); + + masm.loadObjProto(obj, temp); + + Label bail; + masm.branchPtr(Assembler::NotEqual, temp, expected, &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitGuardNullProto(LGuardNullProto* guard) { + Register obj = ToRegister(guard->input()); + Register temp = ToRegister(guard->temp()); + + masm.loadObjProto(obj, temp); + + Label bail; + masm.branchTestPtr(Assembler::NonZero, temp, temp, &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitGuardIsProxy(LGuardIsProxy* guard) { + Register obj = ToRegister(guard->input()); + Register temp = ToRegister(guard->temp()); + + Label bail; + masm.branchTestObjectIsProxy(false, obj, temp, &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitGuardIsNotProxy(LGuardIsNotProxy* guard) { + Register obj = ToRegister(guard->input()); + Register temp = ToRegister(guard->temp()); + + Label bail; + masm.branchTestObjectIsProxy(true, obj, temp, &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitGuardIsNotDOMProxy(LGuardIsNotDOMProxy* guard) { + Register proxy = ToRegister(guard->proxy()); + Register temp = ToRegister(guard->temp()); + + Label bail; + masm.branchTestProxyHandlerFamily(Assembler::Equal, proxy, temp, + GetDOMProxyHandlerFamily(), &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitProxyGet(LProxyGet* lir) { + Register proxy = ToRegister(lir->proxy()); + Register temp = ToRegister(lir->temp()); + + pushArg(lir->mir()->id(), temp); + pushArg(proxy); + + using Fn = bool (*)(JSContext*, HandleObject, HandleId, MutableHandleValue); + callVM(lir); +} + +void CodeGenerator::visitProxyGetByValue(LProxyGetByValue* lir) { + Register proxy = ToRegister(lir->proxy()); + ValueOperand idVal = ToValue(lir, LProxyGetByValue::IdIndex); + + pushArg(idVal); + pushArg(proxy); + + using Fn = + bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue); + callVM(lir); +} + +void CodeGenerator::visitProxyHasProp(LProxyHasProp* lir) { + Register proxy = ToRegister(lir->proxy()); + ValueOperand idVal = ToValue(lir, LProxyHasProp::IdIndex); + + pushArg(idVal); + pushArg(proxy); + + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, bool*); + if (lir->mir()->hasOwn()) { + callVM(lir); + } else { + callVM(lir); + } +} + +void CodeGenerator::visitProxySet(LProxySet* lir) { + Register proxy = ToRegister(lir->proxy()); + ValueOperand rhs = ToValue(lir, LProxySet::RhsIndex); + Register temp = ToRegister(lir->temp()); + + pushArg(Imm32(lir->mir()->strict())); + pushArg(rhs); + pushArg(lir->mir()->id(), temp); + pushArg(proxy); + + using Fn = bool (*)(JSContext*, HandleObject, HandleId, HandleValue, bool); + callVM(lir); +} + +void CodeGenerator::visitProxySetByValue(LProxySetByValue* lir) { + Register proxy = ToRegister(lir->proxy()); + ValueOperand idVal = ToValue(lir, LProxySetByValue::IdIndex); + ValueOperand rhs = ToValue(lir, LProxySetByValue::RhsIndex); + + pushArg(Imm32(lir->mir()->strict())); + pushArg(rhs); + pushArg(idVal); + pushArg(proxy); + + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValue, bool); + callVM(lir); +} + +void CodeGenerator::visitCallSetArrayLength(LCallSetArrayLength* lir) { + Register obj = ToRegister(lir->obj()); + ValueOperand rhs = ToValue(lir, LCallSetArrayLength::RhsIndex); + + pushArg(Imm32(lir->mir()->strict())); + pushArg(rhs); + pushArg(obj); + + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, bool); + callVM(lir); +} + +void CodeGenerator::visitMegamorphicLoadSlot(LMegamorphicLoadSlot* lir) { + Register obj = ToRegister(lir->object()); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + Register temp3 = ToRegister(lir->temp3()); + ValueOperand output = ToOutValue(lir); + + Label bail; + masm.branchIfNonNativeObj(obj, temp1, &bail); + + masm.pushValue(UndefinedValue()); + masm.moveStackPtrTo(temp3); + + masm.setupUnalignedABICall(temp1); + masm.loadJSContext(temp1); + masm.passABIArg(temp1); + masm.passABIArg(obj); + masm.movePtr(ImmGCPtr(lir->mir()->name()), temp2); + masm.passABIArg(temp2); + masm.passABIArg(temp3); + + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataPropertyPure))); + + MOZ_ASSERT(!output.aliases(ReturnReg)); + masm.popValue(output); + + masm.branchIfFalseBool(ReturnReg, &bail); + + if (JitOptions.spectreJitToCxxCalls) { + masm.speculationBarrier(); + } + + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitMegamorphicLoadSlotByValue( + LMegamorphicLoadSlotByValue* lir) { + Register obj = ToRegister(lir->object()); + ValueOperand idVal = ToValue(lir, LMegamorphicLoadSlotByValue::IdIndex); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + ValueOperand output = ToOutValue(lir); + + Label bail; + masm.branchIfNonNativeObj(obj, temp1, &bail); + + // idVal will be in vp[0], result will be stored in vp[1]. + masm.subFromStackPtr(Imm32(sizeof(Value))); + masm.pushValue(idVal); + masm.moveStackPtrTo(temp1); + + masm.setupUnalignedABICall(temp2); + masm.loadJSContext(temp2); + masm.passABIArg(temp2); + masm.passABIArg(obj); + masm.passABIArg(temp1); + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, (GetNativeDataPropertyByValuePure))); + + MOZ_ASSERT(!idVal.aliases(temp1)); + masm.mov(ReturnReg, temp1); + masm.popValue(idVal); + + Label ok; + masm.branchIfTrueBool(temp1, &ok); + masm.addToStackPtr(Imm32(sizeof(Value))); // Discard result Value. + masm.jump(&bail); + + masm.bind(&ok); + if (JitOptions.spectreJitToCxxCalls) { + masm.speculationBarrier(); + } + masm.popValue(output); + + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitMegamorphicStoreSlot(LMegamorphicStoreSlot* lir) { + Register obj = ToRegister(lir->object()); + ValueOperand rhs = ToValue(lir, LMegamorphicStoreSlot::RhsIndex); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + Register temp3 = ToRegister(lir->temp3()); + + masm.pushValue(rhs); + masm.moveStackPtrTo(temp1); + + masm.setupUnalignedABICall(temp2); + masm.loadJSContext(temp2); + masm.passABIArg(temp2); + masm.passABIArg(obj); + masm.movePtr(ImmGCPtr(lir->mir()->name()), temp3); + masm.passABIArg(temp3); + masm.passABIArg(temp1); + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, (SetNativeDataPropertyPure))); + + MOZ_ASSERT(!rhs.aliases(temp1)); + masm.mov(ReturnReg, temp1); + masm.popValue(rhs); + + Label bail; + masm.branchIfFalseBool(temp1, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitMegamorphicHasProp(LMegamorphicHasProp* lir) { + Register obj = ToRegister(lir->object()); + ValueOperand idVal = ToValue(lir, LMegamorphicHasProp::IdIndex); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + Register output = ToRegister(lir->output()); + + // idVal will be in vp[0], result will be stored in vp[1]. + masm.subFromStackPtr(Imm32(sizeof(Value))); + masm.pushValue(idVal); + masm.moveStackPtrTo(temp1); + + masm.setupUnalignedABICall(temp2); + masm.loadJSContext(temp2); + masm.passABIArg(temp2); + masm.passABIArg(obj); + masm.passABIArg(temp1); + if (lir->mir()->hasOwn()) { + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, HasNativeDataPropertyPure)); + } else { + masm.callWithABI( + JS_FUNC_TO_DATA_PTR(void*, HasNativeDataPropertyPure)); + } + + MOZ_ASSERT(!idVal.aliases(temp1)); + masm.mov(ReturnReg, temp1); + masm.popValue(idVal); + + Label bail, ok; + masm.branchIfTrueBool(temp1, &ok); + masm.addToStackPtr(Imm32(sizeof(Value))); // Discard result Value. + masm.jump(&bail); + + masm.bind(&ok); + masm.unboxBoolean(Address(masm.getStackPointer(), 0), output); + masm.addToStackPtr(Imm32(sizeof(Value))); + + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitGuardIsNotArrayBufferMaybeShared( + LGuardIsNotArrayBufferMaybeShared* guard) { + Register obj = ToRegister(guard->input()); + Register temp = ToRegister(guard->temp()); + + Label bail; + masm.loadObjClassUnsafe(obj, temp); + masm.branchPtr(Assembler::Equal, temp, ImmPtr(&ArrayBufferObject::class_), + &bail); + masm.branchPtr(Assembler::Equal, temp, + ImmPtr(&SharedArrayBufferObject::class_), &bail); + bailoutFrom(&bail, guard->snapshot()); +} + +void CodeGenerator::visitGuardIsTypedArray(LGuardIsTypedArray* guard) { + Register obj = ToRegister(guard->input()); + Register temp = ToRegister(guard->temp()); + + Label bail; + masm.loadObjClassUnsafe(obj, temp); + masm.branchIfClassIsNotTypedArray(temp, &bail); + bailoutFrom(&bail, guard->snapshot()); +} + void CodeGenerator::visitGuardObjectGroup(LGuardObjectGroup* guard) { Register obj = ToRegister(guard->input()); Register temp = ToTempRegisterOrInvalid(guard->temp()); @@ -4437,19 +4790,15 @@ void CodeGenerator::visitGuardSpecificFunction(LGuardSpecificFunction* guard) { void CodeGenerator::visitGuardSpecificAtom(LGuardSpecificAtom* guard) { Register str = ToRegister(guard->str()); + Register scratch = ToRegister(guard->temp()); - Label done; - masm.branchPtr(Assembler::Equal, str, ImmGCPtr(guard->mir()->atom()), &done); - - // The pointers are not equal, so if the input string is also an atom it - // must be a different string. - bailoutTest32(Assembler::NonZero, Address(str, JSString::offsetOfFlags()), - Imm32(JSString::ATOM_BIT), guard->snapshot()); + LiveRegisterSet volatileRegs = liveVolatileRegs(guard); + volatileRegs.takeUnchecked(scratch); - // Todo: Check length + VM fallback. - bailout(guard->snapshot()); - - masm.bind(&done); + Label bail; + masm.guardSpecificAtom(str, guard->mir()->atom(), scratch, volatileRegs, + &bail); + bailoutFrom(&bail, guard->snapshot()); } void CodeGenerator::visitGuardSpecificSymbol(LGuardSpecificSymbol* guard) { @@ -4459,6 +4808,101 @@ void CodeGenerator::visitGuardSpecificSymbol(LGuardSpecificSymbol* guard) { guard->snapshot()); } +void CodeGenerator::visitGuardStringToIndex(LGuardStringToIndex* lir) { + Register str = ToRegister(lir->string()); + Register output = ToRegister(lir->output()); + + Label bail, vmCall, done; + masm.loadStringIndexValue(str, output, &vmCall); + masm.jump(&done); + + { + masm.bind(&vmCall); + + LiveRegisterSet volatileRegs = liveVolatileRegs(lir); + volatileRegs.takeUnchecked(output); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(output); + masm.passABIArg(str); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetIndexFromString)); + masm.storeCallInt32Result(output); + + masm.PopRegsInMask(volatileRegs); + + // GetIndexFromString returns a negative value on failure. + masm.branchTest32(Assembler::Signed, output, output, &bail); + } + + masm.bind(&done); + + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitGuardStringToInt32(LGuardStringToInt32* lir) { + Register str = ToRegister(lir->string()); + Register output = ToRegister(lir->output()); + Register temp = ToRegister(lir->temp()); + + LiveRegisterSet volatileRegs = liveVolatileRegs(lir); + + Label bail; + masm.guardStringToInt32(str, output, temp, volatileRegs, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitGuardStringToDouble(LGuardStringToDouble* lir) { + Register str = ToRegister(lir->string()); + FloatRegister output = ToFloatRegister(lir->output()); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + + Label bail, vmCall, done; + // Use indexed value as fast path if possible. + masm.loadStringIndexValue(str, temp1, &vmCall); + masm.convertInt32ToDouble(temp1, output); + masm.jump(&done); + { + masm.bind(&vmCall); + + // Reserve stack for holding the result value of the call. + masm.reserveStack(sizeof(double)); + masm.moveStackPtrTo(temp1); + + LiveRegisterSet volatileRegs = liveVolatileRegs(lir); + volatileRegs.takeUnchecked(temp1); + volatileRegs.takeUnchecked(temp2); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(temp2); + masm.loadJSContext(temp2); + masm.passABIArg(temp2); + masm.passABIArg(str); + masm.passABIArg(temp1); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, StringToNumberPure)); + masm.mov(ReturnReg, temp1); + + masm.PopRegsInMask(volatileRegs); + + Label ok; + masm.branchIfTrueBool(temp1, &ok); + { + // OOM path, recovered by StringToNumberPure. + // + // Use addToStackPtr instead of freeStack as freeStack tracks stack height + // flow-insensitively, and using it here would confuse the stack height + // tracking. + masm.addToStackPtr(Imm32(sizeof(double))); + masm.jump(&bail); + } + masm.bind(&ok); + masm.Pop(output); + } + masm.bind(&done); + + bailoutFrom(&bail, lir->snapshot()); +} + void CodeGenerator::visitGuardNoDenseElements(LGuardNoDenseElements* guard) { Register obj = ToRegister(guard->input()); Register temp = ToRegister(guard->temp()); @@ -4522,6 +4966,136 @@ void CodeGenerator::emitCreateBigInt(LInstruction* lir, Scalar::Type type, masm.bind(ool->rejoin()); } +void CodeGenerator::visitBooleanToInt64(LBooleanToInt64* lir) { + Register input = ToRegister(lir->input()); + Register64 output = ToOutRegister64(lir); + + masm.move32To64ZeroExtend(input, output); +} + +void CodeGenerator::emitStringToInt64(LInstruction* lir, Register input, + Register64 output) { + Register temp = output.scratchReg(); + + saveLive(lir); + + masm.reserveStack(sizeof(uint64_t)); + masm.moveStackPtrTo(temp); + pushArg(temp); + pushArg(input); + + using Fn = bool (*)(JSContext*, HandleString, uint64_t*); + callVM(lir); + + masm.load64(Address(masm.getStackPointer(), 0), output); + masm.freeStack(sizeof(uint64_t)); + + restoreLiveIgnore(lir, StoreValueTo(output).clobbered()); +} + +void CodeGenerator::visitStringToInt64(LStringToInt64* lir) { + Register input = ToRegister(lir->input()); + Register64 output = ToOutRegister64(lir); + + emitStringToInt64(lir, input, output); +} + +void CodeGenerator::visitValueToInt64(LValueToInt64* lir) { + ValueOperand input = ToValue(lir, LValueToInt64::Input); + Register temp = ToRegister(lir->temp()); + Register64 output = ToOutRegister64(lir); + + bool maybeBigInt = lir->mir()->input()->mightBeType(MIRType::BigInt); + bool maybeBool = lir->mir()->input()->mightBeType(MIRType::Boolean); + bool maybeString = lir->mir()->input()->mightBeType(MIRType::String); + int checks = int(maybeBigInt) + int(maybeBool) + int(maybeString); + + if (checks == 0) { + // Bail on other types. + bailout(lir->snapshot()); + } else { + Label fail, done; + // Jump to fail if this is the last check and we fail it, + // otherwise to the next test. + auto emitTestAndUnbox = [&](auto testAndUnbox) { + MOZ_ASSERT(checks > 0); + + checks--; + Label notType; + Label* target = checks ? ¬Type : &fail; + + testAndUnbox(target); + + if (checks) { + masm.jump(&done); + masm.bind(¬Type); + } + }; + + Register tag = masm.extractTag(input, temp); + + // BigInt. + if (maybeBigInt) { + emitTestAndUnbox([&](Label* target) { + masm.branchTestBigInt(Assembler::NotEqual, tag, target); + masm.unboxBigInt(input, temp); + masm.loadBigInt64(temp, output); + }); + } + + // Boolean + if (maybeBool) { + emitTestAndUnbox([&](Label* target) { + masm.branchTestBoolean(Assembler::NotEqual, tag, target); + masm.unboxBoolean(input, temp); + masm.move32To64ZeroExtend(temp, output); + }); + } + + // String + if (maybeString) { + emitTestAndUnbox([&](Label* target) { + masm.branchTestString(Assembler::NotEqual, tag, target); + masm.unboxString(input, temp); + emitStringToInt64(lir, temp, output); + }); + } + + MOZ_ASSERT(checks == 0); + + bailoutFrom(&fail, lir->snapshot()); + masm.bind(&done); + } +} + +void CodeGenerator::visitTruncateBigIntToInt64(LTruncateBigIntToInt64* lir) { + Register operand = ToRegister(lir->input()); + Register64 output = ToOutRegister64(lir); + + masm.loadBigInt64(operand, output); +} + +void CodeGenerator::visitInt64ToBigInt(LInt64ToBigInt* lir) { + Register64 input = ToRegister64(lir->input()); + Register temp = ToRegister(lir->temp()); + Register output = ToRegister(lir->output()); + +#if JS_BITS_PER_WORD == 32 + using Fn = BigInt* (*)(JSContext*, uint32_t, uint32_t); + auto args = ArgList(input.low, input.high); +#else + using Fn = BigInt* (*)(JSContext*, uint64_t); + auto args = ArgList(input); +#endif + + OutOfLineCode* ool = oolCallVM( + lir, args, StoreRegisterTo(output)); + + masm.newGCBigInt(output, temp, ool->entry(), bigIntsCanBeInNursery()); + masm.initializeBigInt64(Scalar::BigInt64, output, input); + masm.bind(ool->rejoin()); +} + void CodeGenerator::visitTypeBarrierV(LTypeBarrierV* lir) { ValueOperand operand = ToValue(lir, LTypeBarrierV::Input); Register unboxScratch = ToTempRegisterOrInvalid(lir->unboxTemp()); @@ -4575,6 +5149,15 @@ void CodeGenerator::visitGuardValue(LGuardValue* lir) { bailoutFrom(&bail, lir->snapshot()); } +void CodeGenerator::visitGuardNotOptimizedArguments( + LGuardNotOptimizedArguments* lir) { + ValueOperand input = ToValue(lir, LGuardNotOptimizedArguments::Input); + Label bail; + masm.branchTestValue(Assembler::Equal, input, + MagicValue(JS_OPTIMIZED_ARGUMENTS), &bail); + bailoutFrom(&bail, lir->snapshot()); +} + void CodeGenerator::visitGuardNullOrUndefined(LGuardNullOrUndefined* lir) { ValueOperand input = ToValue(lir, LGuardNullOrUndefined::Input); @@ -4591,6 +5174,39 @@ void CodeGenerator::visitGuardNullOrUndefined(LGuardNullOrUndefined* lir) { masm.bind(&done); } +void CodeGenerator::visitGuardFunctionFlags(LGuardFunctionFlags* lir) { + Register function = ToRegister(lir->function()); + + Assembler::Condition cond = + lir->mir()->bailWhenSet() ? Assembler::NonZero : Assembler::Zero; + + Label bail; + masm.branchTestFunctionFlags(function, lir->mir()->flags(), cond, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitGuardFunctionKind(LGuardFunctionKind* lir) { + Register function = ToRegister(lir->function()); + Register temp = ToRegister(lir->temp()); + + Assembler::Condition cond = + lir->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual; + + Label bail; + masm.branchFunctionKind(cond, lir->mir()->expected(), function, temp, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitGuardFunctionScript(LGuardFunctionScript* lir) { + Register function = ToRegister(lir->function()); + + Label bail; + Address scriptAddr(function, JSFunction::offsetOfBaseScript()); + masm.branchPtr(Assembler::NotEqual, scriptAddr, + ImmGCPtr(lir->mir()->expected()), &bail); + bailoutFrom(&bail, lir->snapshot()); +} + // Out-of-line path to update the store buffer. class OutOfLineCallPostWriteBarrier : public OutOfLineCodeBase { LInstruction* lir_; @@ -4737,6 +5353,8 @@ void CodeGenerator::maybeEmitGlobalBarrierCheck(const LAllocation* maybeGlobal, template void CodeGenerator::visitPostWriteBarrierCommon(LPostBarrierType* lir, OutOfLineCode* ool) { + static_assert(NeedsPostBarrier(nurseryType)); + addOutOfLineCode(ool, lir->mir()); Register temp = ToTempRegisterOrInvalid(lir->temp()); @@ -4753,16 +5371,16 @@ void CodeGenerator::visitPostWriteBarrierCommon(LPostBarrierType* lir, maybeEmitGlobalBarrierCheck(lir->object(), ool); Register value = ToRegister(lir->value()); - if (nurseryType == MIRType::Object) { + if constexpr (nurseryType == MIRType::Object) { if (lir->mir()->value()->type() == MIRType::ObjectOrNull) { masm.branchTestPtr(Assembler::Zero, value, value, ool->rejoin()); } else { MOZ_ASSERT(lir->mir()->value()->type() == MIRType::Object); } - } else if (nurseryType == MIRType::String) { + } else if constexpr (nurseryType == MIRType::String) { MOZ_ASSERT(lir->mir()->value()->type() == MIRType::String); } else { - MOZ_ASSERT(nurseryType == MIRType::BigInt); + static_assert(nurseryType == MIRType::BigInt); MOZ_ASSERT(lir->mir()->value()->type() == MIRType::BigInt); } masm.branchPtrInNurseryChunk(Assembler::Equal, value, temp, ool->entry()); @@ -4935,7 +5553,7 @@ void CodeGenerator::visitCallNative(LCallNative* call) { // Push a Value containing the callee object: natives are allowed to access // their callee before setting the return value. The StackPointer is moved // to &vp[0]. - masm.Push(ObjectValue(*target->rawJSFunction())); + masm.Push(ObjectValue(*target->rawNativeJSFunction())); // Preload arguments into registers. masm.loadJSContext(argContextReg); @@ -4945,7 +5563,7 @@ void CodeGenerator::visitCallNative(LCallNative* call) { masm.Push(argUintNReg); if (call->mir()->maybeCrossRealm()) { - masm.movePtr(ImmGCPtr(target->rawJSFunction()), tempReg); + masm.movePtr(ImmGCPtr(target->rawNativeJSFunction()), tempReg); masm.switchToObjectRealm(tempReg, tempReg); } @@ -5084,7 +5702,7 @@ void CodeGenerator::visitCallDOMNative(LCallDOMNative* call) { // Push a Value containing the callee object: natives are allowed to access // their callee before setting the return value. After this the StackPointer // points to &vp[0]. - masm.Push(ObjectValue(*target->rawJSFunction())); + masm.Push(ObjectValue(*target->rawNativeJSFunction())); // Now compute the argv value. Since StackPointer is pointing to &vp[0] and // argv is &vp[2] we just need to add 2*sizeof(Value) to the current @@ -5114,7 +5732,7 @@ void CodeGenerator::visitCallDOMNative(LCallDOMNative* call) { if (call->mir()->maybeCrossRealm()) { // We use argJSContext as scratch register here. - masm.movePtr(ImmGCPtr(target->rawJSFunction()), argJSContext); + masm.movePtr(ImmGCPtr(target->rawNativeJSFunction()), argJSContext); masm.switchToObjectRealm(argJSContext, argJSContext); } @@ -5887,17 +6505,11 @@ void CodeGenerator::emitApplyGeneric(T* apply) { } void CodeGenerator::visitApplyArgsGeneric(LApplyArgsGeneric* apply) { - // Limit the number of parameters we can handle to a number that does not risk - // us allocating too much stack, notably on Windows where there is a 4K guard - // page that has to be touched to extend the stack. See bug 1351278. The - // value "3000" is the size of the guard page minus an arbitrary, but large, - // safety margin. - LSnapshot* snapshot = apply->snapshot(); Register argcreg = ToRegister(apply->getArgc()); - uint32_t limit = 3000 / sizeof(Value); - bailoutCmp32(Assembler::Above, argcreg, Imm32(limit), snapshot); + // Ensure that we have a reasonable number of arguments. + bailoutCmp32(Assembler::Above, argcreg, Imm32(JIT_ARGS_LENGTH_MAX), snapshot); emitApplyGeneric(apply); } @@ -5910,10 +6522,8 @@ void CodeGenerator::visitApplyArrayGeneric(LApplyArrayGeneric* apply) { ObjectElements::offsetOfLength()); masm.load32(length, tmp); - // See comment in visitApplyArgsGeneric, above. - - uint32_t limit = 3000 / sizeof(Value); - bailoutCmp32(Assembler::Above, tmp, Imm32(limit), snapshot); + // Ensure that we have a reasonable number of arguments. + bailoutCmp32(Assembler::Above, tmp, Imm32(JIT_ARGS_LENGTH_MAX), snapshot); // Ensure that the array does not contain an uninitialized tail. @@ -5933,10 +6543,8 @@ void CodeGenerator::visitConstructArrayGeneric(LConstructArrayGeneric* lir) { ObjectElements::offsetOfLength()); masm.load32(length, tmp); - // See comment in visitApplyArgsGeneric, above. - - uint32_t limit = 3000 / sizeof(Value); - bailoutCmp32(Assembler::Above, tmp, Imm32(limit), snapshot); + // Ensure that we have a reasonable number of arguments. + bailoutCmp32(Assembler::Above, tmp, Imm32(JIT_ARGS_LENGTH_MAX), snapshot); // Ensure that the array does not contain an uninitialized tail. @@ -5958,6 +6566,14 @@ void CodeGenerator::visitEncodeSnapshot(LEncodeSnapshot* lir) { encode(lir->snapshot()); } +void CodeGenerator::visitUnreachableResultV(LUnreachableResultV* lir) { + masm.assumeUnreachable("must be unreachable"); +} + +void CodeGenerator::visitUnreachableResultT(LUnreachableResultT* lir) { + masm.assumeUnreachable("must be unreachable"); +} + void CodeGenerator::visitGetDynamicName(LGetDynamicName* lir) { Register envChain = ToRegister(lir->getEnvironmentChain()); Register name = ToRegister(lir->getName()); @@ -6617,6 +7233,10 @@ bool CodeGenerator::generateBody() { } #endif + if (current->mir()->isLoopHeader() && gen->compilingWasm()) { + masm.nopAlign(CodeAlignment); + } + for (LInstructionIterator iter = current->begin(); iter != current->end(); iter++) { if (!alloc().ensureBallast()) { @@ -6836,9 +7456,9 @@ void CodeGenerator::visitNewArrayDynamicLength(LNewArrayDynamicLength* lir) { JSObject* templateObject = lir->mir()->templateObject(); gc::InitialHeap initialHeap = lir->mir()->initialHeap(); - using Fn = ArrayObject* (*)(JSContext*, HandleObjectGroup, int32_t length); + using Fn = ArrayObject* (*)(JSContext*, HandleArrayObject, int32_t length); OutOfLineCode* ool = oolCallVM( - lir, ArgList(ImmGCPtr(templateObject->group()), lengthReg), + lir, ArgList(ImmGCPtr(templateObject), lengthReg), StoreRegisterTo(objReg)); bool canInline = true; @@ -7445,6 +8065,26 @@ void CodeGenerator::visitSetArgumentsObjectArg(LSetArgumentsObjectArg* lir) { masm.storeValue(value, argAddr); } +void CodeGenerator::visitLoadArgumentsObjectArg(LLoadArgumentsObjectArg* lir) { + Register temp = ToRegister(lir->temp()); + Register argsObj = ToRegister(lir->getArgsObject()); + Register index = ToRegister(lir->index()); + ValueOperand out = ToOutValue(lir); + + Label bail; + masm.loadArgumentsObjectElement(argsObj, index, out, temp, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitArgumentsObjectLength(LArgumentsObjectLength* lir) { + Register argsObj = ToRegister(lir->getArgsObject()); + Register out = ToRegister(lir->output()); + + Label bail; + masm.loadArgumentsObjectLength(argsObj, out, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + void CodeGenerator::visitReturnFromCtor(LReturnFromCtor* lir) { ValueOperand value = ToValue(lir, LReturnFromCtor::ValueIndex); Register obj = ToRegister(lir->getObject()); @@ -7468,18 +8108,61 @@ void CodeGenerator::visitReturnFromCtor(LReturnFromCtor* lir) { masm.bind(&end); } +class OutOfLineBoxNonStrictThis : public OutOfLineCodeBase { + LBoxNonStrictThis* ins_; + + public: + explicit OutOfLineBoxNonStrictThis(LBoxNonStrictThis* ins) : ins_(ins) {} + void accept(CodeGenerator* codegen) override { + codegen->visitOutOfLineBoxNonStrictThis(this); + } + LBoxNonStrictThis* ins() const { return ins_; } +}; + void CodeGenerator::visitBoxNonStrictThis(LBoxNonStrictThis* lir) { ValueOperand value = ToValue(lir, LBoxNonStrictThis::ValueIndex); Register output = ToRegister(lir->output()); - using Fn = JSObject* (*)(JSContext*, HandleValue); - OutOfLineCode* ool = oolCallVM(lir, ArgList(value), - StoreRegisterTo(output)); + auto* ool = new (alloc()) OutOfLineBoxNonStrictThis(lir); + addOutOfLineCode(ool, lir->mir()); masm.fallibleUnboxObject(value, output, ool->entry()); masm.bind(ool->rejoin()); } +void CodeGenerator::visitOutOfLineBoxNonStrictThis( + OutOfLineBoxNonStrictThis* ool) { + LBoxNonStrictThis* lir = ool->ins(); + + ValueOperand value = ToValue(lir, LBoxNonStrictThis::ValueIndex); + Register output = ToRegister(lir->output()); + + Label notNullOrUndefined; + { + Label isNullOrUndefined; + ScratchTagScope tag(masm, value); + masm.splitTagForTest(value, tag); + masm.branchTestUndefined(Assembler::Equal, tag, &isNullOrUndefined); + masm.branchTestNull(Assembler::NotEqual, tag, ¬NullOrUndefined); + masm.bind(&isNullOrUndefined); + masm.movePtr(ImmGCPtr(lir->mir()->globalThis()), output); + masm.jump(ool->rejoin()); + } + + masm.bind(¬NullOrUndefined); + + saveLive(lir); + + pushArg(value); + using Fn = JSObject* (*)(JSContext*, HandleValue); + callVM(lir); + + StoreRegisterTo(output).generate(this); + restoreLiveIgnore(lir, StoreRegisterTo(output).clobbered()); + + masm.jump(ool->rejoin()); +} + void CodeGenerator::visitImplicitThis(LImplicitThis* lir) { pushArg(ImmGCPtr(lir->mir()->name())); pushArg(ToRegister(lir->env())); @@ -7497,8 +8180,19 @@ void CodeGenerator::visitArrowNewTarget(LArrowNewTarget* lir) { } void CodeGenerator::visitArrayLength(LArrayLength* lir) { - Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength()); - masm.load32(length, ToRegister(lir->output())); + Register elements = ToRegister(lir->elements()); + Register output = ToRegister(lir->output()); + + Address length(elements, ObjectElements::offsetOfLength()); + masm.load32(length, output); + + // IonBuilder relies on TI knowing the length fits in int32, but Warp needs to + // check this dynamically. + if (JitOptions.warpBuilder) { + Label bail; + masm.branchTest32(Assembler::Signed, output, output, &bail); + bailoutFrom(&bail, lir->snapshot()); + } } static void SetLengthFromIndex(MacroAssembler& masm, const LAllocation* index, @@ -7518,6 +8212,40 @@ void CodeGenerator::visitSetArrayLength(LSetArrayLength* lir) { SetLengthFromIndex(masm, lir->index(), length); } +void CodeGenerator::visitFunctionLength(LFunctionLength* lir) { + Register function = ToRegister(lir->function()); + Register output = ToRegister(lir->output()); + + Label bail; + + // Get the JSFunction flags. + masm.load16ZeroExtend(Address(function, JSFunction::offsetOfFlags()), output); + + // Functions with a SelfHostedLazyScript must be compiled with the slow-path + // before the function length is known. If the length was previously resolved, + // the length property may be shadowed. + masm.branchTest32( + Assembler::NonZero, output, + Imm32(FunctionFlags::SELFHOSTLAZY | FunctionFlags::RESOLVED_LENGTH), + &bail); + + masm.loadFunctionLength(function, output, output, &bail); + + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitFunctionName(LFunctionName* lir) { + Register function = ToRegister(lir->function()); + Register output = ToRegister(lir->output()); + + Label bail; + + const JSAtomState& names = gen->runtime->names(); + masm.loadFunctionName(function, output, ImmGCPtr(names.empty), &bail); + + bailoutFrom(&bail, lir->snapshot()); +} + template static void RangeFront(MacroAssembler&, Register, Register, Register); @@ -7944,81 +8672,16 @@ void CodeGenerator::visitArrayBufferViewByteOffset( void CodeGenerator::visitArrayBufferViewElements( LArrayBufferViewElements* lir) { - Register obj = ToRegister(lir->object()); - Register out = ToRegister(lir->output()); - masm.loadPtr(Address(obj, ArrayBufferViewObject::dataOffset()), out); -} - -static constexpr bool ValidateShiftRange(Scalar::Type from, Scalar::Type to) { - for (Scalar::Type type = from; type < to; type = Scalar::Type(type + 1)) { - if (TypedArrayShift(type) != TypedArrayShift(from)) { - return false; - } - } - return true; -} - -void CodeGenerator::visitTypedArrayElementShift(LTypedArrayElementShift* lir) { - Register obj = ToRegister(lir->object()); - Register out = ToRegister(lir->output()); - - static_assert(Scalar::Int8 == 0, "Int8 is the first typed array class"); - static_assert( - (Scalar::BigUint64 - Scalar::Int8) == Scalar::MaxTypedArrayViewType - 1, - "BigUint64 is the last typed array class"); - - Label zero, one, two, three, done; - - masm.loadObjClassUnsafe(obj, out); - - static_assert(ValidateShiftRange(Scalar::Int8, Scalar::Int16), - "shift amount is zero in [Int8, Int16)"); - masm.branchPtr(Assembler::Below, out, - ImmPtr(TypedArrayObject::classForType(Scalar::Int16)), &zero); - - static_assert(ValidateShiftRange(Scalar::Int16, Scalar::Int32), - "shift amount is one in [Int16, Int32)"); - masm.branchPtr(Assembler::Below, out, - ImmPtr(TypedArrayObject::classForType(Scalar::Int32)), &one); - - static_assert(ValidateShiftRange(Scalar::Int32, Scalar::Float64), - "shift amount is two in [Int32, Float64)"); - masm.branchPtr(Assembler::Below, out, - ImmPtr(TypedArrayObject::classForType(Scalar::Float64)), &two); - - static_assert(ValidateShiftRange(Scalar::Float64, Scalar::Uint8Clamped), - "shift amount is three in [Float64, Uint8Clamped)"); - masm.branchPtr(Assembler::Below, out, - ImmPtr(TypedArrayObject::classForType(Scalar::Uint8Clamped)), - &three); - - static_assert(ValidateShiftRange(Scalar::Uint8Clamped, Scalar::BigInt64), - "shift amount is zero in [Uint8Clamped, BigInt64)"); - masm.branchPtr(Assembler::Below, out, - ImmPtr(TypedArrayObject::classForType(Scalar::BigInt64)), - &zero); - - static_assert( - ValidateShiftRange(Scalar::BigInt64, Scalar::MaxTypedArrayViewType), - "shift amount is three in [BigInt64, MaxTypedArrayViewType)"); - // Fall through for BigInt64 and BigUint64 - - masm.bind(&three); - masm.move32(Imm32(3), out); - masm.jump(&done); - - masm.bind(&two); - masm.move32(Imm32(2), out); - masm.jump(&done); - - masm.bind(&one); - masm.move32(Imm32(1), out); - masm.jump(&done); + Register obj = ToRegister(lir->object()); + Register out = ToRegister(lir->output()); + masm.loadPtr(Address(obj, ArrayBufferViewObject::dataOffset()), out); +} - masm.bind(&zero); - masm.move32(Imm32(0), out); +void CodeGenerator::visitTypedArrayElementShift(LTypedArrayElementShift* lir) { + Register obj = ToRegister(lir->object()); + Register out = ToRegister(lir->output()); - masm.bind(&done); + masm.typedArrayElementShift(obj, out); } class OutOfLineTypedArrayIndexToInt32 @@ -8201,36 +8864,13 @@ void CodeGenerator::visitSqrtF(LSqrtF* ins) { void CodeGenerator::visitSignI(LSignI* ins) { Register input = ToRegister(ins->input()); Register output = ToRegister(ins->output()); - - Label done; - masm.move32(input, output); - masm.rshift32Arithmetic(Imm32(31), output); - masm.branch32(Assembler::LessThanOrEqual, input, Imm32(0), &done); - masm.move32(Imm32(1), output); - masm.bind(&done); + masm.signInt32(input, output); } void CodeGenerator::visitSignD(LSignD* ins) { FloatRegister input = ToFloatRegister(ins->input()); FloatRegister output = ToFloatRegister(ins->output()); - - Label done, zeroOrNaN, negative; - masm.loadConstantDouble(0.0, output); - masm.branchDouble(Assembler::DoubleEqualOrUnordered, input, output, - &zeroOrNaN); - masm.branchDouble(Assembler::DoubleLessThan, input, output, &negative); - - masm.loadConstantDouble(1.0, output); - masm.jump(&done); - - masm.bind(&negative); - masm.loadConstantDouble(-1.0, output); - masm.jump(&done); - - masm.bind(&zeroOrNaN); - masm.moveDouble(input, output); - - masm.bind(&done); + masm.signDouble(input, output); } void CodeGenerator::visitSignDI(LSignDI* ins) { @@ -8238,33 +8878,9 @@ void CodeGenerator::visitSignDI(LSignDI* ins) { FloatRegister temp = ToFloatRegister(ins->temp()); Register output = ToRegister(ins->output()); - Label done, zeroOrNaN, negative; - masm.loadConstantDouble(0.0, temp); - masm.branchDouble(Assembler::DoubleEqualOrUnordered, input, temp, &zeroOrNaN); - masm.branchDouble(Assembler::DoubleLessThan, input, temp, &negative); - - masm.move32(Imm32(1), output); - masm.jump(&done); - - masm.bind(&negative); - masm.move32(Imm32(-1), output); - masm.jump(&done); - - // Bailout for NaN and negative zero. - Label bailout; - masm.bind(&zeroOrNaN); - masm.branchDouble(Assembler::DoubleUnordered, input, input, &bailout); - - // The easiest way to distinguish -0.0 from 0.0 is that 1.0/-0.0 - // is -Infinity instead of Infinity. - masm.loadConstantDouble(1.0, temp); - masm.divDouble(input, temp); - masm.branchDouble(Assembler::DoubleLessThan, temp, input, &bailout); - masm.move32(Imm32(0), output); - - bailoutFrom(&bailout, ins->snapshot()); - - masm.bind(&done); + Label bail; + masm.signDoubleToInt32(input, output, temp, &bail); + bailoutFrom(&bail, ins->snapshot()); } void CodeGenerator::visitMathFunctionD(LMathFunctionD* ins) { @@ -8390,6 +9006,24 @@ void CodeGenerator::visitRoundF(LRoundF* lir) { bailoutFrom(&bail, lir->snapshot()); } +void CodeGenerator::visitTrunc(LTrunc* lir) { + FloatRegister input = ToFloatRegister(lir->input()); + Register output = ToRegister(lir->output()); + + Label bail; + masm.truncDoubleToInt32(input, output, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + +void CodeGenerator::visitTruncF(LTruncF* lir) { + FloatRegister input = ToFloatRegister(lir->input()); + Register output = ToRegister(lir->output()); + + Label bail; + masm.truncFloat32ToInt32(input, output, &bail); + bailoutFrom(&bail, lir->snapshot()); +} + void CodeGenerator::emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output) { MOZ_ASSERT(lir->isCompareS() || lir->isCompareStrictS()); @@ -8785,62 +9419,13 @@ void CodeGenerator::visitIsNullOrLikeUndefinedAndBranchT( } } -void CodeGenerator::emitSameValue(FloatRegister left, FloatRegister right, - FloatRegister temp, Register output) { - Label nonEqual, isSameValue, isNotSameValue; - masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, left, right, - &nonEqual); - { - // First, test for being equal to 0.0, which also includes -0.0. - masm.loadConstantDouble(0.0, temp); - masm.branchDouble(Assembler::DoubleNotEqual, left, temp, &isSameValue); - - // The easiest way to distinguish -0.0 from 0.0 is that 1.0/-0.0 - // is -Infinity instead of Infinity. - Label isNegInf; - masm.loadConstantDouble(1.0, temp); - masm.divDouble(left, temp); - masm.branchDouble(Assembler::DoubleLessThan, temp, left, &isNegInf); - { - masm.loadConstantDouble(1.0, temp); - masm.divDouble(right, temp); - masm.branchDouble(Assembler::DoubleGreaterThan, temp, right, - &isSameValue); - masm.jump(&isNotSameValue); - } - masm.bind(&isNegInf); - { - masm.loadConstantDouble(1.0, temp); - masm.divDouble(right, temp); - masm.branchDouble(Assembler::DoubleLessThan, temp, right, &isSameValue); - masm.jump(&isNotSameValue); - } - } - masm.bind(&nonEqual); - { - // Test if both values are NaN. - masm.branchDouble(Assembler::DoubleOrdered, left, left, &isNotSameValue); - masm.branchDouble(Assembler::DoubleOrdered, right, right, &isNotSameValue); - } - - Label done; - masm.bind(&isSameValue); - masm.move32(Imm32(1), output); - masm.jump(&done); - - masm.bind(&isNotSameValue); - masm.move32(Imm32(0), output); - - masm.bind(&done); -} - void CodeGenerator::visitSameValueD(LSameValueD* lir) { FloatRegister left = ToFloatRegister(lir->left()); FloatRegister right = ToFloatRegister(lir->right()); FloatRegister temp = ToFloatRegister(lir->tempFloat()); Register output = ToRegister(lir->output()); - emitSameValue(left, right, temp, output); + masm.sameValueDouble(left, right, temp, output); } void CodeGenerator::visitSameValueV(LSameValueV* lir) { @@ -8853,7 +9438,7 @@ void CodeGenerator::visitSameValueV(LSameValueV* lir) { Label nonDouble; masm.move32(Imm32(0), output); masm.ensureDouble(left, temp1, &nonDouble); - emitSameValue(temp1, right, temp2, output); + masm.sameValueDouble(temp1, right, temp2, output); masm.bind(&nonDouble); } @@ -8867,9 +9452,11 @@ void CodeGenerator::visitSameValueVM(LSameValueVM* lir) { void CodeGenerator::emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output) { - using Fn = JSString* (*)(JSContext*, HandleString, HandleString); + using Fn = JSString* (*)(JSContext*, HandleString, HandleString, + js::gc::InitialHeap); OutOfLineCode* ool = oolCallVM>( - lir, ArgList(lhs, rhs), StoreRegisterTo(output)); + lir, ArgList(lhs, rhs, static_cast(gc::DefaultHeap)), + StoreRegisterTo(output)); const JitRealm* jitRealm = gen->realm->jitRealm(); JitCode* stringConcatStub = @@ -9791,6 +10378,7 @@ void CodeGenerator::emitStoreElementTyped(const LAllocation* value, MIRType elementType, Register elements, const LAllocation* index) { + MOZ_ASSERT(valueType != MIRType::MagicHole); ConstantOrRegister v = ToConstantOrRegister(value, valueType); if (index->isConstant()) { Address dest(elements, ToInt32(index) * sizeof(js::Value)); @@ -9839,6 +10427,17 @@ void CodeGenerator::visitStoreElementV(LStoreElementV* lir) { } } +void CodeGenerator::visitStoreHoleValueElement(LStoreHoleValueElement* lir) { + Register elements = ToRegister(lir->elements()); + Register index = ToRegister(lir->index()); + + Address elementsFlags(elements, ObjectElements::offsetOfFlags()); + masm.or32(Imm32(ObjectElements::NON_PACKED), elementsFlags); + + BaseObjectElementIndex element(elements, index); + masm.storeValue(MagicValue(JS_ELEMENTS_HOLE), element); +} + template void CodeGenerator::emitStoreElementHoleT(T* lir) { static_assert(std::is_same_v || @@ -10171,10 +10770,24 @@ void CodeGenerator::emitArrayPopShift(LInstruction* lir, void CodeGenerator::visitArrayPopShiftV(LArrayPopShiftV* lir) { Register obj = ToRegister(lir->object()); - Register elements = ToRegister(lir->temp0()); - Register length = ToRegister(lir->temp1()); + Register temp1 = ToRegister(lir->temp0()); + Register temp2 = ToRegister(lir->temp1()); TypedOrValueRegister out(ToOutValue(lir)); - emitArrayPopShift(lir, lir->mir(), obj, elements, length, out); + + if (JitOptions.warpBuilder) { + Label bail; + if (lir->mir()->mode() == MArrayPopShift::Pop) { + masm.packedArrayPop(obj, out.valueReg(), temp1, temp2, &bail); + } else { + MOZ_ASSERT(lir->mir()->mode() == MArrayPopShift::Shift); + LiveRegisterSet volatileRegs = liveVolatileRegs(lir); + masm.packedArrayShift(obj, out.valueReg(), temp1, temp2, volatileRegs, + &bail); + } + bailoutFrom(&bail, lir->snapshot()); + } else { + emitArrayPopShift(lir, lir->mir(), obj, temp1, temp2, out); + } } void CodeGenerator::visitArrayPopShiftT(LArrayPopShiftT* lir) { @@ -10182,6 +10795,8 @@ void CodeGenerator::visitArrayPopShiftT(LArrayPopShiftT* lir) { Register elements = ToRegister(lir->temp0()); Register length = ToRegister(lir->temp1()); TypedOrValueRegister out(lir->mir()->type(), ToAnyRegister(lir->output())); + + MOZ_ASSERT(!JitOptions.warpBuilder); emitArrayPopShift(lir, lir->mir(), obj, elements, length, out); } @@ -10197,8 +10812,8 @@ void CodeGenerator::emitArrayPush(LInstruction* lir, Register obj, masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp); masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length); - // TODO(Warp): reuse/share the CacheIR implementation when IonBuilder and TI - // are gone (bug 1654180). + // TODO(post-Warp): reuse/share the CacheIR implementation when IonBuilder and + // TI are gone (bug 1654180). if (!IsTypeInferenceEnabled()) { // Bailout if the incremented length does not fit in int32. bailoutCmp32(Assembler::AboveOrEqual, length, Imm32(INT32_MAX), @@ -10272,6 +10887,13 @@ void CodeGenerator::visitArraySlice(LArraySlice* lir) { Label call, fail; + if (JitOptions.warpBuilder) { + Label bail; + masm.branchArrayIsNotPacked(object, temp1, temp2, &bail); + + bailoutFrom(&bail, lir->snapshot()); + } + // Try to allocate an object. TemplateObject templateObject(lir->mir()->templateObj()); masm.createGCObject(temp1, temp2, templateObject, lir->mir()->initialHeap(), @@ -10354,6 +10976,17 @@ void CodeGenerator::visitGetIteratorCache(LGetIteratorCache* lir) { addIC(lir, allocateIC(ic)); } +void CodeGenerator::visitOptimizeSpreadCallCache( + LOptimizeSpreadCallCache* lir) { + LiveRegisterSet liveRegs = lir->safepoint()->liveRegs(); + ValueOperand val = ToValue(lir, LOptimizeSpreadCallCache::Value); + Register output = ToRegister(lir->output()); + Register temp = ToRegister(lir->temp()); + + IonOptimizeSpreadCallIC ic(liveRegs, val, output, temp); + addIC(lir, allocateIC(ic)); +} + void CodeGenerator::visitIteratorMore(LIteratorMore* lir) { const Register obj = ToRegister(lir->object()); const ValueOperand output = ToOutValue(lir); @@ -10821,7 +11454,28 @@ bool CodeGenerator::generate() { return !masm.oom(); } -bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { +static bool AddInlinedCompilations(HandleScript script, + IonCompilationId compilationId, + const WarpSnapshot* snapshot) { + RecompileInfo recompileInfo(script, compilationId); + + for (const auto* scriptSnapshot : snapshot->scripts()) { + JSScript* inlinedScript = scriptSnapshot->script(); + if (inlinedScript == script) { + continue; + } + AutoSweepJitScript sweep(inlinedScript); + if (!inlinedScript->jitScript()->addInlinedCompilation(sweep, + recompileInfo)) { + return false; + } + } + + return true; +} + +bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints, + const WarpSnapshot* snapshot) { // We cancel off-thread Ion compilations in a few places during GC, but if // this compilation was performed off-thread it will already have been // removed from the relevant lists by this point. Don't allow GC here. @@ -10870,6 +11524,14 @@ bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { return true; } + if (JitOptions.warpBuilder) { + // If an inlined script is invalidated (for example, by attaching + // a debugger), we must also invalidate the parent IonScript. + if (!AddInlinedCompilations(script, compilationId, snapshot)) { + return false; + } + } + // IonMonkey could have inferred better type information during // compilation. Since adding the new information to the actual type // information can reset the usecount, increase it back to what it was @@ -10889,16 +11551,21 @@ bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { return false; } + size_t numNurseryObjects = 0; + if (JitOptions.warpBuilder) { + numNurseryObjects = snapshot->nurseryObjects().length(); + } + IonScript* ionScript = IonScript::New( cx, compilationId, graph.totalSlotCount(), argumentSlots, scriptFrameSize, snapshots_.listSize(), snapshots_.RVATableSize(), recovers_.size(), - bailouts_.length(), graph.numConstants(), safepointIndices_.length(), - osiIndices_.length(), icList_.length(), runtimeData_.length(), - safepoints_.size(), optimizationLevel); + bailouts_.length(), graph.numConstants(), numNurseryObjects, + safepointIndices_.length(), osiIndices_.length(), icList_.length(), + runtimeData_.length(), safepoints_.size(), optimizationLevel); if (!ionScript) { return false; } - auto guardIonScript = mozilla::MakeScopeExit([&ionScript] { + auto freeIonScript = mozilla::MakeScopeExit([&ionScript] { // Use js_free instead of IonScript::Destroy: the cache list is still // uninitialized. js_free(ionScript); @@ -10971,16 +11638,19 @@ bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { ionScript->setHasProfilingInstrumentation(); } - script->jitScript()->setIonScript(script, ionScript); - Assembler::PatchDataWithValueCheck( CodeLocationLabel(code, invalidateEpilogueData_), ImmPtr(ionScript), ImmPtr((void*)-1)); - for (size_t i = 0; i < ionScriptLabels_.length(); i++) { - Assembler::PatchDataWithValueCheck( - CodeLocationLabel(code, ionScriptLabels_[i]), ImmPtr(ionScript), - ImmPtr((void*)-1)); + for (CodeOffset offset : ionScriptLabels_) { + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, offset), + ImmPtr(ionScript), ImmPtr((void*)-1)); + } + + for (NurseryObjectLabel label : ionNurseryObjectLabels_) { + void* entry = ionScript->addressOfNurseryObject(label.nurseryIndex); + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, label.offset), + ImmPtr(entry), ImmPtr((void*)-1)); } #ifdef JS_TRACE_LOGGING @@ -11038,8 +11708,10 @@ bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { ionScript->setInvalidationEpilogueDataOffset( invalidateEpilogueData_.offset()); - ionScript->setOsrPc(gen->outerInfo().osrPc()); - ionScript->setOsrEntryOffset(getOsrEntryOffset()); + if (jsbytecode* osrPc = gen->outerInfo().osrPc()) { + ionScript->setOsrPc(osrPc); + ionScript->setOsrEntryOffset(getOsrEntryOffset()); + } ionScript->setInvalidationEpilogueOffset(invalidate_.offset()); #if defined(JS_ION_PERF) @@ -11093,7 +11765,23 @@ bool CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) { script->addIonCounts(counts); } - guardIonScript.release(); + // WARNING: Code after this point must be infallible! + + // Copy the list of nursery objects. Note that the store buffer can add + // HeapPtr edges that must be cleared in IonScript::Destroy. See the + // infallibility warning above. + if (JitOptions.warpBuilder) { + const auto& nurseryObjects = snapshot->nurseryObjects(); + for (size_t i = 0; i < nurseryObjects.length(); i++) { + ionScript->nurseryObjects()[i].init(nurseryObjects[i]); + } + } + + // Transfer ownership of the IonScript to the JitScript. At this point enough + // of the IonScript must be initialized for IonScript::Destroy to work. + freeIonScript.release(); + script->jitScript()->setIonScript(script, ionScript); + return true; } @@ -11199,8 +11887,8 @@ void CodeGenerator::visitCallInitElementArray(LCallInitElementArray* lir) { pushArg(ToRegister(lir->object())); pushArg(ImmPtr(lir->mir()->resumePoint()->pc())); - using Fn = - bool (*)(JSContext*, jsbytecode*, HandleObject, uint32_t, HandleValue); + using Fn = bool (*)(JSContext*, jsbytecode*, HandleArrayObject, uint32_t, + HandleValue); callVM(lir); } @@ -11313,6 +12001,67 @@ void CodeGenerator::visitLoadElementAndUnbox(LLoadElementAndUnbox* ins) { } } +void CodeGenerator::visitAddAndStoreSlot(LAddAndStoreSlot* ins) { + const Register obj = ToRegister(ins->getOperand(0)); + const ValueOperand value = ToValue(ins, LAddAndStoreSlot::Value); + const Register maybeTemp = ToTempRegisterOrInvalid(ins->getTemp(0)); + + Shape* shape = ins->mir()->shape(); + masm.storeObjShape(shape, obj, [](MacroAssembler& masm, const Address& addr) { + EmitPreBarrier(masm, addr, MIRType::Shape); + }); + + // Perform the store. No pre-barrier required since this is a new + // initialization. + + uint32_t offset = ins->mir()->slotOffset(); + if (ins->mir()->kind() == MAddAndStoreSlot::Kind::FixedSlot) { + Address slot(obj, offset); + masm.storeValue(value, slot); + } else { + masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), maybeTemp); + Address slot(maybeTemp, offset); + masm.storeValue(value, slot); + } +} + +void CodeGenerator::visitAllocateAndStoreSlot(LAllocateAndStoreSlot* ins) { + const Register obj = ToRegister(ins->getOperand(0)); + const ValueOperand value = ToValue(ins, LAllocateAndStoreSlot::Value); + const Register temp1 = ToRegister(ins->getTemp(0)); + const Register temp2 = ToRegister(ins->getTemp(1)); + + masm.push(obj); + masm.pushValue(value); + + masm.setupUnalignedABICall(temp1); + masm.loadJSContext(temp1); + masm.passABIArg(temp1); + masm.passABIArg(obj); + masm.move32(Imm32(ins->mir()->numNewSlots()), temp2); + masm.passABIArg(temp2); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, NativeObject::growSlotsPure)); + masm.storeCallBoolResult(temp1); + + masm.popValue(value); + masm.pop(obj); + + Label bail; + masm.branchIfFalseBool(temp1, &bail); + bailoutFrom(&bail, ins->snapshot()); + + masm.storeObjShape(ins->mir()->shape(), obj, + [](MacroAssembler& masm, const Address& addr) { + EmitPreBarrier(masm, addr, MIRType::Shape); + }); + + // Perform the store. No pre-barrier required since this is a new + // initialization. + masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), temp1); + Address slot(temp1, ins->mir()->slotOffset()); + masm.storeValue(value, slot); +} + void CodeGenerator::visitStoreFixedSlotV(LStoreFixedSlotV* ins) { const Register obj = ToRegister(ins->getOperand(0)); size_t slot = ins->mir()->slot(); @@ -11524,6 +12273,22 @@ void CodeGenerator::visitHasOwnCache(LHasOwnCache* ins) { addIC(ins, allocateIC(cache)); } +void CodeGenerator::visitCheckPrivateFieldCache(LCheckPrivateFieldCache* ins) { + LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); + TypedOrValueRegister value = + toConstantOrRegister(ins, LCheckPrivateFieldCache::Value, + ins->mir()->value()->type()) + .reg(); + TypedOrValueRegister id = + toConstantOrRegister(ins, LCheckPrivateFieldCache::Id, + ins->mir()->idval()->type()) + .reg(); + Register output = ToRegister(ins->output()); + + IonCheckPrivateFieldIC cache(liveRegs, value, id, output); + addIC(ins, allocateIC(cache)); +} + void CodeGenerator::visitCallSetProperty(LCallSetProperty* ins) { ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LCallSetProperty::Value)); @@ -12031,24 +12796,24 @@ void CodeGenerator::visitLoadDataViewElement(LLoadDataViewElement* lir) { switch (storageType) { case Scalar::Int16: - masm.swap16SignExtend(out.gpr()); + masm.byteSwap16SignExtend(out.gpr()); break; case Scalar::Uint16: - masm.swap16ZeroExtend(out.gpr()); + masm.byteSwap16ZeroExtend(out.gpr()); break; case Scalar::Int32: - masm.swap32(out.gpr()); + masm.byteSwap32(out.gpr()); break; case Scalar::Uint32: - masm.swap32(out.isFloat() ? temp : out.gpr()); + masm.byteSwap32(out.isFloat() ? temp : out.gpr()); break; case Scalar::Float32: - masm.swap32(temp); + masm.byteSwap32(temp); break; case Scalar::Float64: case Scalar::BigInt64: case Scalar::BigUint64: - masm.swap64(temp64); + masm.byteSwap64(temp64); break; case Scalar::Int8: case Scalar::Uint8: @@ -12550,20 +13315,20 @@ void CodeGenerator::visitStoreDataViewElement(LStoreDataViewElement* lir) { switch (writeType) { case Scalar::Int16: - masm.swap16SignExtend(temp); + masm.byteSwap16SignExtend(temp); break; case Scalar::Uint16: - masm.swap16ZeroExtend(temp); + masm.byteSwap16ZeroExtend(temp); break; case Scalar::Int32: case Scalar::Uint32: case Scalar::Float32: - masm.swap32(temp); + masm.byteSwap32(temp); break; case Scalar::Float64: case Scalar::BigInt64: case Scalar::BigUint64: - masm.swap64(temp64); + masm.byteSwap64(temp64); break; case Scalar::Int8: case Scalar::Uint8: @@ -12658,20 +13423,7 @@ void CodeGenerator::visitAtomicIsLockFree(LAtomicIsLockFree* lir) { Register value = ToRegister(lir->value()); Register output = ToRegister(lir->output()); - // Keep this in sync with isLockfreeJS() in jit/AtomicOperations.h. - MOZ_ASSERT(AtomicOperations::isLockfreeJS(1)); // Implementation artifact - MOZ_ASSERT(AtomicOperations::isLockfreeJS(2)); // Implementation artifact - MOZ_ASSERT(AtomicOperations::isLockfreeJS(4)); // Spec requirement - MOZ_ASSERT( - !AtomicOperations::isLockfreeJS(8)); // Implementation invariant, for now - - Label Ldone, Lfailed; - masm.move32(Imm32(1), output); - masm.branch32(Assembler::Equal, value, Imm32(4), &Ldone); - masm.branch32(Assembler::Equal, value, Imm32(2), &Ldone); - masm.branch32(Assembler::Equal, value, Imm32(1), &Ldone); - masm.move32(Imm32(0), output); - masm.bind(&Ldone); + masm.atomicIsLockFreeJS(value, output); } void CodeGenerator::visitClampIToUint8(LClampIToUint8* lir) { @@ -12743,7 +13495,7 @@ void CodeGenerator::visitInArray(LInArray* lir) { MOZ_ASSERT_IF(index < 0, mir->needsNegativeIntCheck()); if (mir->needsNegativeIntCheck()) { - using Fn = bool (*)(JSContext*, uint32_t, HandleObject, bool*); + using Fn = bool (*)(JSContext*, int32_t, HandleObject, bool*); ool = oolCallVM( lir, ArgList(Imm32(index), ToRegister(lir->object())), StoreRegisterTo(output)); @@ -12774,7 +13526,7 @@ void CodeGenerator::visitInArray(LInArray* lir) { if (mir->needsNegativeIntCheck()) { masm.bind(&negativeIntCheck); - using Fn = bool (*)(JSContext*, uint32_t, HandleObject, bool*); + using Fn = bool (*)(JSContext*, int32_t, HandleObject, bool*); ool = oolCallVM( lir, ArgList(index, ToRegister(lir->object())), StoreRegisterTo(output)); @@ -12797,16 +13549,31 @@ void CodeGenerator::visitInArray(LInArray* lir) { } } +void CodeGenerator::visitGuardElementNotHole(LGuardElementNotHole* lir) { + Register elements = ToRegister(lir->elements()); + const LAllocation* index = lir->index(); + + Label testMagic; + if (index->isConstant()) { + Address address(elements, ToInt32(index) * sizeof(js::Value)); + masm.branchTestMagic(Assembler::Equal, address, &testMagic); + } else { + BaseObjectElementIndex address(elements, ToRegister(index)); + masm.branchTestMagic(Assembler::Equal, address, &testMagic); + } + bailoutFrom(&testMagic, lir->snapshot()); +} + void CodeGenerator::visitInstanceOfO(LInstanceOfO* ins) { - emitInstanceOf(ins, ins->mir()->prototypeObject()); + emitInstanceOf(ins, ins->rhs()); } void CodeGenerator::visitInstanceOfV(LInstanceOfV* ins) { - emitInstanceOf(ins, ins->mir()->prototypeObject()); + emitInstanceOf(ins, ins->rhs()); } void CodeGenerator::emitInstanceOf(LInstruction* ins, - JSObject* prototypeObject) { + const LAllocation* prototypeObject) { // This path implements fun_hasInstance when the function's prototype is // known to be prototypeObject. @@ -12827,6 +13594,14 @@ void CodeGenerator::emitInstanceOf(LInstruction* ins, objReg = ToRegister(ins->toInstanceOfO()->lhs()); } + mozilla::Maybe protoPtr; + mozilla::Maybe protoReg; + if (prototypeObject->isConstant()) { + protoPtr.emplace(&prototypeObject->toConstant()->toObject()); + } else { + protoReg.emplace(ToRegister(prototypeObject)); + } + // Crawl the lhs's prototype chain in a loop to search for prototypeObject. // This follows the main loop of js::IsPrototypeOf, though additionally breaks // out of the loop on Proxy::LazyProto. @@ -12841,8 +13616,13 @@ void CodeGenerator::emitInstanceOf(LInstruction* ins, // Test for the target prototype object. Label notPrototypeObject; - masm.branchPtr(Assembler::NotEqual, output, ImmGCPtr(prototypeObject), - ¬PrototypeObject); + if (protoPtr) { + masm.branchPtr(Assembler::NotEqual, output, *protoPtr, + ¬PrototypeObject); + } else { + masm.branchPtr(Assembler::NotEqual, output, *protoReg, + ¬PrototypeObject); + } masm.mov(ImmWord(1), output); masm.jump(&done); masm.bind(¬PrototypeObject); @@ -12865,8 +13645,14 @@ void CodeGenerator::emitInstanceOf(LInstruction* ins, // register is already correct. using Fn = bool (*)(JSContext*, HandleObject, JSObject*, bool*); - OutOfLineCode* ool = oolCallVM( - ins, ArgList(ImmGCPtr(prototypeObject), objReg), StoreRegisterTo(output)); + OutOfLineCode* ool; + if (protoPtr) { + ool = oolCallVM(ins, ArgList(*protoPtr, objReg), + StoreRegisterTo(output)); + } else { + ool = oolCallVM(ins, ArgList(*protoReg, objReg), + StoreRegisterTo(output)); + } // Regenerate the original lhs object for the VM call. Label regenerate, *lazyEntry; @@ -13144,8 +13930,7 @@ void CodeGenerator::visitIsCallableV(LIsCallableV* ins) { Register temp = ToRegister(ins->temp()); Label notObject; - masm.branchTestObject(Assembler::NotEqual, val, ¬Object); - masm.unboxObject(val, temp); + masm.fallibleUnboxObject(val, temp, ¬Object); OutOfLineIsCallable* ool = new (alloc()) OutOfLineIsCallable(temp, output); addOutOfLineCode(ool, ins->mir()); @@ -13210,6 +13995,14 @@ void CodeGenerator::visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool) { masm.jump(ool->rejoin()); } +void CodeGenerator::visitIsCrossRealmArrayConstructor( + LIsCrossRealmArrayConstructor* ins) { + Register object = ToRegister(ins->object()); + Register output = ToRegister(ins->output()); + + masm.setIsCrossRealmArrayConstructor(object, output); +} + static void EmitObjectIsArray(MacroAssembler& masm, OutOfLineCode* ool, Register obj, Register output, Label* notArray = nullptr) { @@ -13250,8 +14043,7 @@ void CodeGenerator::visitIsArrayV(LIsArrayV* lir) { Register temp = ToRegister(lir->temp()); Label notArray; - masm.branchTestObject(Assembler::NotEqual, val, ¬Array); - masm.unboxObject(val, temp); + masm.fallibleUnboxObject(val, temp, ¬Array); using Fn = bool (*)(JSContext*, HandleObject, bool*); OutOfLineCode* ool = oolCallVM( @@ -13273,21 +14065,8 @@ void CodeGenerator::visitIsTypedArray(LIsTypedArray* lir) { Label notTypedArray; Label done; - static_assert(Scalar::Int8 == 0, "Int8 is the first typed array class"); - const JSClass* firstTypedArrayClass = - TypedArrayObject::classForType(Scalar::Int8); - - static_assert( - (Scalar::BigUint64 - Scalar::Int8) == Scalar::MaxTypedArrayViewType - 1, - "BigUint64 is the last typed array class"); - const JSClass* lastTypedArrayClass = - TypedArrayObject::classForType(Scalar::BigUint64); - masm.loadObjClassUnsafe(object, output); - masm.branchPtr(Assembler::Below, output, ImmPtr(firstTypedArrayClass), - ¬TypedArray); - masm.branchPtr(Assembler::Above, output, ImmPtr(lastTypedArrayClass), - ¬TypedArray); + masm.branchIfClassIsNotTypedArray(output, ¬TypedArray); masm.move32(Imm32(1), output); masm.jump(&done); @@ -13556,6 +14335,27 @@ void CodeGenerator::emitAssertRangeD(const Range* r, FloatRegister input, } } +void CodeGenerator::visitAssertClass(LAssertClass* ins) { + Register obj = ToRegister(ins->input()); + Register temp = ToRegister(ins->getTemp(0)); + + Label success; + masm.branchTestObjClassNoSpectreMitigations( + Assembler::Equal, obj, ins->mir()->getClass(), temp, &success); + masm.assumeUnreachable("Wrong KnownClass during run-time"); + masm.bind(&success); +} + +void CodeGenerator::visitAssertShape(LAssertShape* ins) { + Register obj = ToRegister(ins->input()); + + Label success; + masm.branchTestObjShapeNoSpectreMitigations(Assembler::Equal, obj, + ins->mir()->shape(), &success); + masm.assumeUnreachable("Wrong Shape during run-time"); + masm.bind(&success); +} + void CodeGenerator::visitAssertResultV(LAssertResultV* ins) { #ifdef DEBUG const ValueOperand value = ToValue(ins, LAssertResultV::Input); @@ -13869,12 +14669,14 @@ void CodeGenerator::visitCheckReturn(LCheckReturn* ins) { } void CodeGenerator::visitCheckIsObj(LCheckIsObj* ins) { - ValueOperand checkValue = ToValue(ins, LCheckIsObj::CheckValue); + ValueOperand value = ToValue(ins, LCheckIsObj::ValueIndex); + Register output = ToRegister(ins->output()); using Fn = bool (*)(JSContext*, CheckIsObjectKind); OutOfLineCode* ool = oolCallVM( ins, ArgList(Imm32(ins->mir()->checkKind())), StoreNothing()); - masm.branchTestObject(Assembler::NotEqual, checkValue, ool->entry()); + + masm.fallibleUnboxObject(value, output, ool->entry()); masm.bind(ool->rejoin()); } @@ -14108,7 +14910,7 @@ void CodeGenerator::visitFinishBoundFunctionInit( Label* slowPath = ool->entry(); const size_t boundLengthOffset = - FunctionExtended::offsetOfExtendedSlot(BOUND_FUN_LENGTH_SLOT); + FunctionExtended::offsetOfBoundFunctionLengthSlot(); // Take the slow path if the target is not a JSFunction. masm.branchTestObjClass(Assembler::NotEqual, target, &JSFunction::class_, @@ -14148,17 +14950,21 @@ void CodeGenerator::visitFinishBoundFunctionInit( } void CodeGenerator::visitIsPackedArray(LIsPackedArray* lir) { - Register array = ToRegister(lir->array()); + Register obj = ToRegister(lir->object()); Register output = ToRegister(lir->output()); - Register elementsTemp = ToRegister(lir->temp()); + Register temp = ToRegister(lir->temp()); - // Load elements and length. - masm.loadPtr(Address(array, NativeObject::offsetOfElements()), elementsTemp); - masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), output); + masm.setIsPackedArray(obj, output, temp); +} - // Test length == initializedLength. - Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength()); - masm.cmp32Set(Assembler::Equal, initLength, output, output); +void CodeGenerator::visitGuardArrayIsPacked(LGuardArrayIsPacked* lir) { + Register array = ToRegister(lir->array()); + Register temp1 = ToRegister(lir->temp1()); + Register temp2 = ToRegister(lir->temp2()); + + Label bail; + masm.branchArrayIsNotPacked(array, temp1, temp2, &bail); + bailoutFrom(&bail, lir->snapshot()); } void CodeGenerator::visitGetPrototypeOf(LGetPrototypeOf* lir) { @@ -14213,9 +15019,11 @@ void CodeGenerator::visitObjectStaticProto(LObjectStaticProto* lir) { #endif } -void CodeGenerator::visitFunctionProto(LFunctionProto* lir) { - using Fn = JSObject* (*)(JSContext*); - callVM(lir); +void CodeGenerator::visitBuiltinObject(LBuiltinObject* lir) { + pushArg(Imm32(static_cast(lir->mir()->builtinObjectKind()))); + + using Fn = JSObject* (*)(JSContext*, BuiltinObjectKind); + callVM(lir); } void CodeGenerator::visitSuperFunction(LSuperFunction* lir) { @@ -14268,6 +15076,50 @@ void CodeGenerator::visitInitHomeObject(LInitHomeObject* lir) { masm.storeValue(homeObject, addr); } +void CodeGenerator::visitIsTypedArrayConstructor( + LIsTypedArrayConstructor* lir) { + Register object = ToRegister(lir->object()); + Register output = ToRegister(lir->output()); + + masm.setIsDefinitelyTypedArrayConstructor(object, output); +} + +void CodeGenerator::visitLoadValueTag(LLoadValueTag* lir) { + ValueOperand value = ToValue(lir, LLoadValueTag::Value); + Register output = ToRegister(lir->output()); + + Register tag = masm.extractTag(value, output); + if (tag != output) { + masm.mov(tag, output); + } +} + +void CodeGenerator::visitGuardTagNotEqual(LGuardTagNotEqual* lir) { + Register lhs = ToRegister(lir->lhs()); + Register rhs = ToRegister(lir->rhs()); + + bailoutCmp32(Assembler::Equal, lhs, rhs, lir->snapshot()); + + // If both lhs and rhs are numbers, can't use tag comparison to do inequality + // comparison + Label done; + masm.branchTestNumber(Assembler::NotEqual, lhs, &done); + masm.branchTestNumber(Assembler::NotEqual, rhs, &done); + bailout(lir->snapshot()); + + masm.bind(&done); +} + +void CodeGenerator::visitLoadWrapperTarget(LLoadWrapperTarget* lir) { + Register object = ToRegister(lir->object()); + Register output = ToRegister(lir->output()); + + masm.loadPtr(Address(object, ProxyObject::offsetOfReservedSlots()), output); + masm.unboxObject( + Address(output, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()), + output); +} + template void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase* lir) { wasm::JitCallStackArgVector stackArgs; @@ -14284,19 +15136,17 @@ void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase* lir) { MIRType argMir; switch (sig.args()[i].kind()) { case wasm::ValType::I32: + case wasm::ValType::I64: case wasm::ValType::F32: case wasm::ValType::F64: argMir = ToMIRType(sig.args()[i]); break; - case wasm::ValType::I64: - MOZ_CRASH("unexpected argument type when calling from ion to wasm"); case wasm::ValType::Ref: switch (sig.args()[i].refTypeKind()) { case wasm::RefType::Any: // AnyRef is boxed on the JS side, so passed as a pointer here. argMir = ToMIRType(sig.args()[i]); break; - case wasm::RefType::Null: case wasm::RefType::Func: case wasm::RefType::TypeIndex: MOZ_CRASH("unexpected argument type when calling from ion to wasm"); @@ -14347,6 +15197,10 @@ void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase* lir) { MOZ_ASSERT(lir->mir()->type() == MIRType::Int32); MOZ_ASSERT(ToRegister(lir->output()) == ReturnReg); break; + case wasm::ValType::I64: + MOZ_ASSERT(lir->mir()->type() == MIRType::Int64); + MOZ_ASSERT(ToOutRegister64(lir) == ReturnReg64); + break; case wasm::ValType::F32: MOZ_ASSERT(lir->mir()->type() == MIRType::Float32); MOZ_ASSERT(ToFloatRegister(lir->output()) == ReturnFloat32Reg); @@ -14355,13 +15209,10 @@ void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase* lir) { MOZ_ASSERT(lir->mir()->type() == MIRType::Double); MOZ_ASSERT(ToFloatRegister(lir->output()) == ReturnDoubleReg); break; - case wasm::ValType::I64: - MOZ_CRASH("unexpected return type when calling from ion to wasm"); case wasm::ValType::Ref: switch (results[0].refTypeKind()) { case wasm::RefType::Any: case wasm::RefType::Func: - case wasm::RefType::Null: // The wasm stubs layer unboxes anything that needs to be unboxed // and leaves it in a Value. A FuncRef we could in principle leave // as a raw object pointer but for now it complicates the API to do @@ -14400,6 +15251,9 @@ void CodeGenerator::visitIonToWasmCall(LIonToWasmCall* lir) { void CodeGenerator::visitIonToWasmCallV(LIonToWasmCallV* lir) { emitIonToWasmCallBase(lir); } +void CodeGenerator::visitIonToWasmCallI64(LIonToWasmCallI64* lir) { + emitIonToWasmCallBase(lir); +} void CodeGenerator::visitWasmNullConstant(LWasmNullConstant* lir) { masm.xorPtr(ToRegister(lir->output()), ToRegister(lir->output())); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 7e49707541..adc712108f 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -5,12 +5,11 @@ #ifndef jit_CodeGenerator_h #define jit_CodeGenerator_h -#include "jsfriendapi.h" - #include "jit/CacheIR.h" #if defined(JS_ION_PERF) # include "jit/PerfSpewer.h" #endif +#include "js/ScalarType.h" // js::Scalar::Type #if defined(JS_CODEGEN_X86) # include "jit/x86/CodeGenerator-x86.h" @@ -35,6 +34,8 @@ namespace js { namespace jit { +class WarpSnapshot; + template class OutOfLineCallVM; @@ -63,6 +64,7 @@ class OutOfLineRegExpInstanceOptimizable; class OutOfLineNaNToZero; class OutOfLineZeroIfNaN; class OutOfLineTypedArrayIndexToInt32; +class OutOfLineBoxNonStrictThis; class CodeGenerator final : public CodeGeneratorSpecific { void generateArgumentsChecks(bool assert = false); @@ -101,7 +103,8 @@ class CodeGenerator final : public CodeGeneratorSpecific { wasm::FuncOffsets* offsets, wasm::StackMaps* stackMaps); - MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints); + MOZ_MUST_USE bool link(JSContext* cx, CompilerConstraintList* constraints, + const WarpSnapshot* snapshot); void emitOOLTestObject(Register objreg, Label* ifTruthy, Label* ifFalsy, Register scratch); @@ -135,6 +138,8 @@ class CodeGenerator final : public CodeGeneratorSpecific { void visitOutOfLineUnboxFloatingPoint(OutOfLineUnboxFloatingPoint* ool); void visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool); + void visitOutOfLineBoxNonStrictThis(OutOfLineBoxNonStrictThis* ool); + void visitOutOfLineICFallback(OutOfLineICFallback* ool); void visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool); @@ -189,8 +194,6 @@ class CodeGenerator final : public CodeGeneratorSpecific { const ConstantOrRegister& value); void emitCompareS(LInstruction* lir, JSOp op, Register left, Register right, Register output); - void emitSameValue(FloatRegister left, FloatRegister right, - FloatRegister temp, Register output); void emitConcat(LInstruction* lir, Register lhs, Register rhs, Register output); @@ -213,7 +216,7 @@ class CodeGenerator final : public CodeGeneratorSpecific { Register temp0, Register temp1, unsigned numFormals, JSObject* templateObject, bool saveAndRestore, Register resultreg); - void emitInstanceOf(LInstruction* ins, JSObject* prototypeObject); + void emitInstanceOf(LInstruction* ins, const LAllocation* prototypeObject); void loadJSScriptForBlock(MBasicBlock* block, Register reg); void loadOutermostJSScript(Register reg); @@ -260,6 +263,8 @@ class CodeGenerator final : public CodeGeneratorSpecific { template void emitLoadIteratorValues(Register result, Register temp, Register front); + void emitStringToInt64(LInstruction* lir, Register input, Register64 output); + void emitCreateBigInt(LInstruction* lir, Scalar::Type type, Register64 input, Register output, Register maybeTemp); @@ -335,6 +340,16 @@ class CodeGenerator final : public CodeGeneratorSpecific { Vector ionScriptLabels_; + // Used to bake in a pointer into the IonScript's list of nursery objects, for + // MNurseryObject codegen. + struct NurseryObjectLabel { + CodeOffset offset; + uint32_t nurseryIndex; + NurseryObjectLabel(CodeOffset offset, uint32_t nurseryIndex) + : offset(offset), nurseryIndex(nurseryIndex) {} + }; + Vector ionNurseryObjectLabels_; + void branchIfInvalidated(Register temp, Label* invalidated); #ifdef DEBUG diff --git a/js/src/jit/CompactBuffer.h b/js/src/jit/CompactBuffer.h index f1691ba8b6..1c70da862b 100644 --- a/js/src/jit/CompactBuffer.h +++ b/js/src/jit/CompactBuffer.h @@ -81,7 +81,15 @@ class CompactBufferReader { } return result; } - + // Reads a value written by writeUnsigned15Bit. + uint32_t readUnsigned15Bit() { + uint8_t byte = readByte(); + uint32_t val = byte >> 1; + if (byte & 1) { + val |= uint32_t(readByte()) << 7; + } + return val; + } void* readRawPointer() { uintptr_t ptrWord = 0; for (unsigned i = 0; i < sizeof(uintptr_t); i++) { @@ -117,7 +125,9 @@ class CompactBufferWriter { // assert. void writeByte(uint32_t byte) { MOZ_ASSERT(byte <= 0xFF); - enoughMemory_ &= buffer_.append(byte); + if (!buffer_.append(byte)) { + enoughMemory_ = false; + } } void writeByteAt(uint32_t pos, uint32_t byte) { MOZ_ASSERT(byte <= 0xFF); @@ -125,6 +135,18 @@ class CompactBufferWriter { buffer_[pos] = byte; } } + // Writes a variable-length value similar to writeUnsigned, but optimized for + // small 15-bit values that fit in one or two variable-length-encoded bytes. + // Must be read using readUnsigned15Bit. + void writeUnsigned15Bit(uint32_t value) { + uint8_t byte1 = ((value & 0x7F) << 1) | (value > 0x7F); + writeByte(byte1); + value >>= 7; + if (value) { + MOZ_ASSERT(value <= 0xFF); + writeByte(value); + } + } void writeUnsigned(uint32_t value) { do { uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F); diff --git a/js/src/jit/CompileInfo-inl.h b/js/src/jit/CompileInfo-inl.h index e83a0cd8a1..a20cba8ff0 100644 --- a/js/src/jit/CompileInfo-inl.h +++ b/js/src/jit/CompileInfo-inl.h @@ -18,7 +18,7 @@ inline RegExpObject* CompileInfo::getRegExp(jsbytecode* pc) const { } inline JSFunction* CompileInfo::getFunction(jsbytecode* pc) const { - return script_->getFunction(GET_UINT32_INDEX(pc)); + return script_->getFunction(pc); } InlineScriptTree* InlineScriptTree::New(TempAllocator* allocator, @@ -52,6 +52,18 @@ InlineScriptTree* InlineScriptTree::addCallee(TempAllocator* allocator, return calleeTree; } +void InlineScriptTree::removeCallee(InlineScriptTree* callee) { + InlineScriptTree** prevPtr = &children_; + for (InlineScriptTree* child = children_; child; child = child->nextCallee_) { + if (child == callee) { + *prevPtr = child->nextCallee_; + return; + } + prevPtr = &child->nextCallee_; + } + MOZ_CRASH("Callee not found"); +} + static inline const char* AnalysisModeString(AnalysisMode mode) { switch (mode) { case Analysis_None: diff --git a/js/src/jit/CompileInfo.h b/js/src/jit/CompileInfo.h index 8bad770b51..f71410e710 100644 --- a/js/src/jit/CompileInfo.h +++ b/js/src/jit/CompileInfo.h @@ -12,7 +12,6 @@ #include "jit/JitAllocPolicy.h" #include "jit/JitFrames.h" #include "jit/Registers.h" -#include "vm/EnvironmentObject.h" #include "vm/JSFunction.h" namespace js { @@ -79,6 +78,7 @@ class InlineScriptTree { InlineScriptTree* addCallee(TempAllocator* allocator, jsbytecode* callerPc, JSScript* calleeScript); + void removeCallee(InlineScriptTree* callee); InlineScriptTree* caller() const { return caller_; } @@ -168,6 +168,7 @@ class CompileInfo { hadOverflowBailout_(script->hadOverflowBailout()), hadFrequentBailouts_(script->hadFrequentBailouts()), mayReadFrameArgsDirectly_(script->mayReadFrameArgsDirectly()), + isDerivedClassConstructor_(script->isDerivedClassConstructor()), inlineScriptTree_(inlineScriptTree) { MOZ_ASSERT_IF(osrPc, JSOp(*osrPc) == JSOp::LoopHead); @@ -260,19 +261,13 @@ class CompileInfo { // Script accessors based on PC. - JSAtom* getAtom(jsbytecode* pc) const { - return script_->getAtom(GET_UINT32_INDEX(pc)); - } + JSAtom* getAtom(jsbytecode* pc) const { return script_->getAtom(pc); } - PropertyName* getName(jsbytecode* pc) const { - return script_->getName(GET_UINT32_INDEX(pc)); - } + PropertyName* getName(jsbytecode* pc) const { return script_->getName(pc); } inline RegExpObject* getRegExp(jsbytecode* pc) const; - JSObject* getObject(jsbytecode* pc) const { - return script_->getObject(GET_UINT32_INDEX(pc)); - } + JSObject* getObject(jsbytecode* pc) const { return script_->getObject(pc); } inline JSFunction* getFunction(jsbytecode* pc) const; @@ -466,6 +461,8 @@ class CompileInfo { bool hadFrequentBailouts() const { return hadFrequentBailouts_; } bool mayReadFrameArgsDirectly() const { return mayReadFrameArgsDirectly_; } + bool isDerivedClassConstructor() const { return isDerivedClassConstructor_; } + private: unsigned nimplicit_; unsigned nargs_; @@ -490,6 +487,8 @@ class CompileInfo { bool mayReadFrameArgsDirectly_; + bool isDerivedClassConstructor_; + InlineScriptTree* inlineScriptTree_; // Whether a script needs environments within its body. This informs us diff --git a/js/src/jit/CompileWrappers.cpp b/js/src/jit/CompileWrappers.cpp index bcb4f7bcf5..04a48a3fe2 100644 --- a/js/src/jit/CompileWrappers.cpp +++ b/js/src/jit/CompileWrappers.cpp @@ -55,6 +55,10 @@ const WellKnownSymbols& CompileRuntime::wellKnownSymbols() { return *runtime()->wellKnownSymbols; } +const JSClass* CompileRuntime::maybeWindowProxyClass() { + return runtime()->maybeWindowProxyClass(); +} + const void* CompileRuntime::mainContextPtr() { return runtime()->mainContextFromAnyThread(); } @@ -201,24 +205,11 @@ bool CompileRealm::hasAllocationMetadataBuilder() { return realm()->hasAllocationMetadataBuilder(); } -// Note: This function is thread-safe because setSingletonAsValue sets a boolean -// variable to false, and this boolean variable has no way to be resetted to -// true. So even if there is a concurrent write, this concurrent write will -// always have the same value. If there is a concurrent read, then we will -// clone a singleton instead of using the value which is baked in the JSScript, -// and this would be an unfortunate allocation, but this will not change the -// semantics of the JavaScript code which is executed. -void CompileRealm::setSingletonsAsValues() { - realm()->behaviors().setSingletonsAsValues(); -} - JitCompileOptions::JitCompileOptions() - : cloneSingletons_(false), - profilerSlowAssertionsEnabled_(false), + : profilerSlowAssertionsEnabled_(false), offThreadCompilationAvailable_(false) {} JitCompileOptions::JitCompileOptions(JSContext* cx) { - cloneSingletons_ = cx->realm()->creationOptions().cloneSingletons(); profilerSlowAssertionsEnabled_ = cx->runtime()->geckoProfiler().enabled() && cx->runtime()->geckoProfiler().slowAssertionsEnabled(); diff --git a/js/src/jit/CompileWrappers.h b/js/src/jit/CompileWrappers.h index 3b2efa8319..1e9cec6a2a 100644 --- a/js/src/jit/CompileWrappers.h +++ b/js/src/jit/CompileWrappers.h @@ -40,6 +40,7 @@ class CompileRuntime { const PropertyName* emptyString(); const StaticStrings& staticStrings(); const WellKnownSymbols& wellKnownSymbols(); + const JSClass* maybeWindowProxyClass(); const void* mainContextPtr(); uint32_t* addressOfTenuredAllocCount(); @@ -106,9 +107,6 @@ class CompileRealm { const uint32_t* addressOfGlobalWriteBarriered(); bool hasAllocationMetadataBuilder(); - - // Mirror RealmOptions. - void setSingletonsAsValues(); }; class JitCompileOptions { @@ -116,8 +114,6 @@ class JitCompileOptions { JitCompileOptions(); explicit JitCompileOptions(JSContext* cx); - bool cloneSingletons() const { return cloneSingletons_; } - bool profilerSlowAssertionsEnabled() const { return profilerSlowAssertionsEnabled_; } @@ -131,7 +127,6 @@ class JitCompileOptions { #endif private: - bool cloneSingletons_; bool profilerSlowAssertionsEnabled_; bool offThreadCompilationAvailable_; #ifdef DEBUG diff --git a/js/src/jit/GenerateCacheIRFiles.py b/js/src/jit/GenerateCacheIRFiles.py index dafc9546b0..1cc44ded99 100644 --- a/js/src/jit/GenerateCacheIRFiles.py +++ b/js/src/jit/GenerateCacheIRFiles.py @@ -64,6 +64,7 @@ def construct_mapping(loader, node): 'ObjId': ('ObjOperandId', 'writeOperandId'), 'StringId': ('StringOperandId', 'writeOperandId'), 'SymbolId': ('SymbolOperandId', 'writeOperandId'), + 'BooleanId': ('BooleanOperandId', 'writeOperandId'), 'Int32Id': ('Int32OperandId', 'writeOperandId'), 'NumberId': ('NumberOperandId', 'writeOperandId'), 'BigIntId': ('BigIntOperandId', 'writeOperandId'), @@ -77,6 +78,7 @@ def construct_mapping(loader, node): 'AtomField': ('JSAtom*', 'writeStringField'), 'PropertyNameField': ('PropertyName*', 'writeStringField'), 'SymbolField': ('JS::Symbol*', 'writeSymbolField'), + 'BaseScriptField': ('BaseScript*', 'writeBaseScriptField'), 'RawWordField': ('uintptr_t', 'writeRawWordField'), 'RawPointerField': ('const void*', 'writeRawPointerField'), 'IdField': ('jsid', 'writeIdField'), @@ -160,6 +162,7 @@ def gen_writer_method(name, args, custom_writer): 'ObjId': ('ObjOperandId', 'Id', 'reader.objOperandId()'), 'StringId': ('StringOperandId', 'Id', 'reader.stringOperandId()'), 'SymbolId': ('SymbolOperandId', 'Id', 'reader.symbolOperandId()'), + 'BooleanId': ('BooleanOperandId', 'Id', 'reader.booleanOperandId()'), 'Int32Id': ('Int32OperandId', 'Id', 'reader.int32OperandId()'), 'NumberId': ('NumberOperandId', 'Id', 'reader.numberOperandId()'), 'BigIntId': ('BigIntOperandId', 'Id', 'reader.bigIntOperandId()'), @@ -173,6 +176,7 @@ def gen_writer_method(name, args, custom_writer): 'AtomField': ('uint32_t', 'Offset', 'reader.stubOffset()'), 'PropertyNameField': ('uint32_t', 'Offset', 'reader.stubOffset()'), 'SymbolField': ('uint32_t', 'Offset', 'reader.stubOffset()'), + 'BaseScriptField': ('uint32_t', 'Offset', 'reader.stubOffset()'), 'RawWordField': ('uint32_t', 'Offset', 'reader.stubOffset()'), 'RawPointerField': ('uint32_t', 'Offset', 'reader.stubOffset()'), 'IdField': ('uint32_t', 'Offset', 'reader.stubOffset()'), @@ -242,6 +246,7 @@ def gen_compiler_method(name, args): 'ObjId': 'spewOperandId', 'StringId': 'spewOperandId', 'SymbolId': 'spewOperandId', + 'BooleanId': 'spewOperandId', 'Int32Id': 'spewOperandId', 'NumberId': 'spewOperandId', 'BigIntId': 'spewOperandId', @@ -255,6 +260,7 @@ def gen_compiler_method(name, args): 'AtomField': 'spewField', 'PropertyNameField': 'spewField', 'SymbolField': 'spewField', + 'BaseScriptField': 'spewField', 'RawWordField': 'spewField', 'RawPointerField': 'spewField', 'IdField': 'spewField', @@ -315,6 +321,57 @@ def gen_spewer_method(name, args): return code +def gen_clone_method(name, args): + """Generates code for cloning a single opcode.""" + + method_name = 'clone' + name + + # Generate code like this: + # + # void cloneGuardShape(CacheIRReader& reader, CacheIRWriter& writer) { + # writer.writeOp(CacheOp::GuardShape); + # ObjOperandId objId = reader.objOperandId(); + # writer.writeOperandId(objId); + # uint32_t shapeOffset = reader.stubOffset(); + # Shape* shape = getShapeField(shapeOffset); + # writer.writeShapeField(shape); + # writer.assertLengthMatches(); + # } + + args_code = '' + if args: + for arg_name, arg_type in six.iteritems(args): + if arg_type == 'RawId': + arg_type = 'ValId' + + read_type, suffix, readexpr = arg_reader_info[arg_type] + read_name = arg_name + suffix + value_name = read_name + args_code += ' {} {} = {};\\\n'.format(read_type, read_name, readexpr) + + write_type, write_method = arg_writer_info[arg_type] + if arg_name == 'result': + args_code += ' writer.newOperandId();\\\n' + if suffix == 'Offset': + # If the write function takes T&, the intermediate variable + # should be of type T. + if write_type.endswith('&'): + write_type = write_type[:-1] + value_name = arg_name + args_code += ' {} {} = get{}({});\\\n'.format(write_type, value_name, + arg_type, read_name) + args_code += ' writer.{}({});\\\n'.format(write_method, value_name) + + code = 'void {}'.format(method_name) + code += '(CacheIRReader& reader, CacheIRWriter& writer) {{\\\n' + code += ' writer.writeOp(CacheOp::{});\\\n'.format(name) + code += args_code + code += ' writer.assertLengthMatches();\\\n' + code += '}}\\\n' + + return code + + # Length in bytes for each argument type, either an integer or a C++ expression. # This is used to generate the CacheIROpArgLengths array. CacheIRWriter asserts # the number of bytes written matches the value in that array. @@ -323,6 +380,7 @@ def gen_spewer_method(name, args): 'ObjId': 1, 'StringId': 1, 'SymbolId': 1, + 'BooleanId': 1, 'Int32Id': 1, 'NumberId': 1, 'BigIntId': 1, @@ -336,6 +394,7 @@ def gen_spewer_method(name, args): 'AtomField': 1, 'PropertyNameField': 1, 'SymbolField': 1, + 'BaseScriptField': 1, 'RawWordField': 1, 'RawPointerField': 1, 'DOMExpandoGenerationField': 1, @@ -390,6 +449,9 @@ def generate_cacheirops_header(c_out, yaml_path): # Generated methods for spewers. spewer_methods = [] + # Generated methods for cloning IC stubs + clone_methods = [] + for op in data: name = op['name'] @@ -402,6 +464,10 @@ def generate_cacheirops_header(c_out, yaml_path): transpile = op['transpile'] assert isinstance(transpile, bool) + # Unscored Ops default to UINT32_MAX + cost_estimate = op.get('cost_estimate', int(0xffffffff)) + #assert isinstance(cost_estimate, int) + custom_writer = op.get('custom_writer', False) assert isinstance(custom_writer, bool) @@ -409,7 +475,10 @@ def generate_cacheirops_header(c_out, yaml_path): args_length = ' + '.join([str(arg_length[v]) for v in args.values()]) else: args_length = '0' - ops_items.append('_({}, {})'.format(name, args_length)) + + transpile_str = ('true' if transpile else 'false') + ops_items.append('_({}, {}, {}, {})'.format( + name, args_length, transpile_str, cost_estimate)) writer_methods.append(gen_writer_method(name, args, custom_writer)) @@ -424,6 +493,8 @@ def generate_cacheirops_header(c_out, yaml_path): spewer_methods.append(gen_spewer_method(name, args)) + clone_methods.append(gen_clone_method(name, args)) + contents = '#define CACHE_IR_OPS(_)\\\n' contents += '\\\n'.join(ops_items) contents += '\n\n' @@ -452,4 +523,8 @@ def generate_cacheirops_header(c_out, yaml_path): contents += '\\\n'.join(spewer_methods) contents += '\n\n' + contents += '#define CACHE_IR_CLONE_GENERATED \\\n' + contents += '\\\n'.join(clone_methods) + contents += '\n\n' + generate_header(c_out, 'jit_CacheIROpsGenerated_h', contents) diff --git a/js/src/jit/ICState.h b/js/src/jit/ICState.h index e5f726ba81..28d830e19b 100644 --- a/js/src/jit/ICState.h +++ b/js/src/jit/ICState.h @@ -10,6 +10,15 @@ namespace js { namespace jit { +// Used to track trial inlining status for a Baseline IC. +// See also setTrialInliningState below. +enum class TrialInliningState : uint8_t { + Initial = 0, + Candidate, + Inlined, + Failure, +}; + // ICState stores information about a Baseline or Ion IC. class ICState { public: @@ -24,7 +33,14 @@ class ICState { enum class Mode : uint8_t { Specialized = 0, Megamorphic, Generic }; private: - Mode mode_; + uint32_t mode_ : 2; + + // The TrialInliningState for a Baseline IC. + uint32_t trialInliningState_ : 2; + + // Whether WarpOracle created a snapshot based on stubs attached to this + // Baseline IC. + bool usedByTranspiler_ : 1; // Number of optimized stubs currently attached to this IC. uint8_t numOptimizedStubs_; @@ -34,9 +50,14 @@ class ICState { static const size_t MaxOptimizedStubs = 6; + void setMode(Mode mode) { + mode_ = uint32_t(mode); + MOZ_ASSERT(Mode(mode_) == mode, "mode must fit in bitfield"); + } + void transition(Mode mode) { - MOZ_ASSERT(mode > mode_); - mode_ = mode; + MOZ_ASSERT(mode > this->mode()); + setMode(mode); numFailures_ = 0; } @@ -52,7 +73,7 @@ class ICState { public: ICState() { reset(); } - Mode mode() const { return mode_; } + Mode mode() const { return Mode(mode_); } size_t numOptimizedStubs() const { return numOptimizedStubs_; } bool hasFailures() const { return (numFailures_ != 0); } @@ -60,7 +81,7 @@ class ICState { // Note: we cannot assert that numOptimizedStubs_ <= MaxOptimizedStubs // because old-style baseline ICs may attach more stubs than // MaxOptimizedStubs allows. - if (mode_ == Mode::Generic || JitOptions.disableCacheIR) { + if (mode() == Mode::Generic || JitOptions.disableCacheIR) { return false; } return true; @@ -72,23 +93,25 @@ class ICState { // Note: we cannot assert that numOptimizedStubs_ <= MaxOptimizedStubs // because old-style baseline ICs may attach more stubs than // MaxOptimizedStubs allows. - if (mode_ == Mode::Generic) { + if (mode() == Mode::Generic) { return false; } if (numOptimizedStubs_ < MaxOptimizedStubs && numFailures_ < maxFailures()) { return false; } - if (numFailures_ == maxFailures() || mode_ == Mode::Megamorphic) { + if (numFailures_ == maxFailures() || mode() == Mode::Megamorphic) { transition(Mode::Generic); return true; } - MOZ_ASSERT(mode_ == Mode::Specialized); + MOZ_ASSERT(mode() == Mode::Specialized); transition(Mode::Megamorphic); return true; } void reset() { - mode_ = Mode::Specialized; + setMode(Mode::Specialized); + trialInliningState_ = uint32_t(TrialInliningState::Initial); + usedByTranspiler_ = false; numOptimizedStubs_ = 0; numFailures_ = 0; } @@ -116,6 +139,43 @@ class ICState { numOptimizedStubs_--; } void trackUnlinkedAllStubs() { numOptimizedStubs_ = 0; } + + void clearUsedByTranspiler() { usedByTranspiler_ = false; } + void setUsedByTranspiler() { usedByTranspiler_ = true; } + bool usedByTranspiler() const { return usedByTranspiler_; } + + TrialInliningState trialInliningState() const { + return TrialInliningState(trialInliningState_); + } + void setTrialInliningState(TrialInliningState state) { +#ifdef DEBUG + // Moving to the Failure state is always valid. The other states should + // happen in this order: + // + // Initial -> Candidate -> Inlined + // + // This ensures we perform trial inlining at most once per IC site. + if (state != TrialInliningState::Failure) { + switch (trialInliningState()) { + case TrialInliningState::Initial: + MOZ_ASSERT(state == TrialInliningState::Candidate); + break; + case TrialInliningState::Candidate: + MOZ_ASSERT(state == TrialInliningState::Candidate || + state == TrialInliningState::Inlined); + break; + case TrialInliningState::Inlined: + case TrialInliningState::Failure: + MOZ_CRASH("Inlined and Failure can only change to Failure"); + break; + } + } +#endif + + trialInliningState_ = uint32_t(state); + MOZ_ASSERT(trialInliningState() == state, + "TrialInliningState must fit in bitfield"); + } }; } // namespace jit diff --git a/js/src/jit/InlinableNatives.cpp b/js/src/jit/InlinableNatives.cpp index b4673cce77..7bb6d0d04d 100644 --- a/js/src/jit/InlinableNatives.cpp +++ b/js/src/jit/InlinableNatives.cpp @@ -15,6 +15,7 @@ #endif #include "builtin/MapObject.h" #include "vm/ArrayBufferObject.h" +#include "vm/AsyncIteration.h" #include "vm/Iteration.h" #include "vm/SharedArrayObject.h" @@ -63,6 +64,10 @@ const JSClass* js::jit::InlinableNativeGuardToClass(InlinableNative native) { return &RegExpStringIteratorObject::class_; case InlinableNative::IntrinsicGuardToWrapForValidIterator: return &WrapForValidIteratorObject::class_; + case InlinableNative::IntrinsicGuardToIteratorHelper: + return &IteratorHelperObject::class_; + case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: + return &AsyncIteratorHelperObject::class_; case InlinableNative::IntrinsicGuardToMapObject: return &MapObject::class_; @@ -167,7 +172,6 @@ bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { case InlinableNative::IntrinsicIsCrossRealmArrayConstructor: case InlinableNative::IntrinsicToInteger: case InlinableNative::IntrinsicToLength: - case InlinableNative::IntrinsicToString: case InlinableNative::IntrinsicIsConstructing: case InlinableNative::IntrinsicIsSuspendedGenerator: case InlinableNative::IntrinsicSubstringKernel: @@ -177,6 +181,8 @@ bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { case InlinableNative::IntrinsicGuardToStringIterator: case InlinableNative::IntrinsicGuardToRegExpStringIterator: case InlinableNative::IntrinsicGuardToWrapForValidIterator: + case InlinableNative::IntrinsicGuardToIteratorHelper: + case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: case InlinableNative::IntrinsicObjectHasPrototype: case InlinableNative::IntrinsicFinishBoundFunctionInit: case InlinableNative::IntrinsicIsPackedArray: @@ -240,8 +246,11 @@ bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { case InlinableNative::DataViewSetFloat64: case InlinableNative::DataViewSetBigInt64: case InlinableNative::DataViewSetBigUint64: + case InlinableNative::NumberToString: case InlinableNative::ReflectGetPrototypeOf: case InlinableNative::String: + case InlinableNative::StringToString: + case InlinableNative::StringValueOf: case InlinableNative::StringCharCodeAt: case InlinableNative::StringFromCharCode: case InlinableNative::StringFromCodePoint: @@ -251,6 +260,7 @@ bool js::jit::CanInlineNativeCrossRealm(InlinableNative native) { case InlinableNative::Object: case InlinableNative::ObjectCreate: case InlinableNative::ObjectIs: + case InlinableNative::ObjectIsPrototypeOf: case InlinableNative::ObjectToString: case InlinableNative::TypedArrayConstructor: // Default to false for most natives. diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h index 7a4c67a6fb..c9a7d2ac30 100644 --- a/js/src/jit/InlinableNatives.h +++ b/js/src/jit/InlinableNatives.h @@ -96,6 +96,8 @@ _(MathTrunc) \ _(MathCbrt) \ \ + _(NumberToString) \ + \ _(ReflectGetPrototypeOf) \ \ _(RegExpMatcher) \ @@ -108,6 +110,8 @@ _(GetFirstDollarIndex) \ \ _(String) \ + _(StringToString) \ + _(StringValueOf) \ _(StringCharCodeAt) \ _(StringFromCharCode) \ _(StringFromCodePoint) \ @@ -121,6 +125,7 @@ _(Object) \ _(ObjectCreate) \ _(ObjectIs) \ + _(ObjectIsPrototypeOf) \ _(ObjectToString) \ \ _(TestBailout) \ @@ -141,7 +146,6 @@ _(IntrinsicIsCrossRealmArrayConstructor) \ _(IntrinsicToInteger) \ _(IntrinsicToLength) \ - _(IntrinsicToString) \ _(IntrinsicIsConstructing) \ _(IntrinsicSubstringKernel) \ _(IntrinsicObjectHasPrototype) \ @@ -156,6 +160,8 @@ _(IntrinsicGuardToStringIterator) \ _(IntrinsicGuardToRegExpStringIterator) \ _(IntrinsicGuardToWrapForValidIterator) \ + _(IntrinsicGuardToIteratorHelper) \ + _(IntrinsicGuardToAsyncIteratorHelper) \ \ _(IntrinsicGuardToMapObject) \ _(IntrinsicGetNextMapEntryForIterator) \ @@ -183,7 +189,7 @@ _(IntrinsicTypedArrayByteOffset) \ _(IntrinsicTypedArrayElementShift) -struct JSJitInfo; +class JSJitInfo; namespace js { namespace jit { diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 52c6d2ba7a..3ac01f6dc4 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -52,7 +52,7 @@ #include "js/UniquePtr.h" #include "util/Memory.h" #include "util/Windows.h" -#include "vm/HelperThreads.h" +#include "vm/HelperThreadState.h" #include "vm/Realm.h" #include "vm/TraceLogging.h" #ifdef MOZ_VTUNE @@ -172,8 +172,11 @@ bool JitRuntime::generateTrampolines(JSContext* cx) { static_assert(sizeof(JitFrameLayout) == sizeof(WasmToJSJitFrameLayout), "thus a rectifier frame can be used with a wasm frame"); - JitSpew(JitSpew_Codegen, "# Emitting sequential arguments rectifier"); - generateArgumentsRectifier(masm); + JitSpew(JitSpew_Codegen, "# Emitting arguments rectifier"); + generateArgumentsRectifier(masm, ArgumentsRectifierKind::Normal); + + JitSpew(JitSpew_Codegen, "# Emitting trial inlining arguments rectifier"); + generateArgumentsRectifier(masm, ArgumentsRectifierKind::TrialInlining); JitSpew(JitSpew_Codegen, "# Emitting EnterJIT sequence"); generateEnterJIT(cx, masm); @@ -321,13 +324,14 @@ void JitRealm::performStubReadBarriers(uint32_t stubsToBarrier) const { static bool LinkCodeGen(JSContext* cx, CodeGenerator* codegen, HandleScript script, - CompilerConstraintList* constraints) { + CompilerConstraintList* constraints, + const WarpSnapshot* snapshot) { TraceLoggerThread* logger = TraceLoggerForCurrentThread(cx); TraceLoggerEvent event(TraceLogger_AnnotateScripts, script); AutoTraceLog logScript(logger, event); AutoTraceLog logLink(logger, TraceLogger_IonLinking); - if (!codegen->link(cx, constraints)) { + if (!codegen->link(cx, constraints, snapshot)) { return false; } @@ -342,7 +346,8 @@ static bool LinkBackgroundCodeGen(JSContext* cx, IonCompileTask* task) { JitContext jctx(cx, &task->alloc()); RootedScript script(cx, task->script()); - return LinkCodeGen(cx, codegen, script, task->constraints()); + return LinkCodeGen(cx, codegen, script, task->constraints(), + task->snapshot()); } void jit::LinkIonScript(JSContext* cx, HandleScript calleeScript) { @@ -577,7 +582,7 @@ void JitCode::finalize(JSFreeOp* fop) { headerSize_ + bufferSize_))) { pool_->addRef(); } - cellHeaderAndCode_.setPtr(nullptr); + setHeaderPtr(nullptr); // Code buffers are stored inside ExecutablePools. Pools are refcounted. // Releasing the pool may free it. Horrible hack: if we are using perf @@ -606,9 +611,9 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId, uint32_t frameSize, size_t snapshotsListSize, size_t snapshotsRVATableSize, size_t recoversSize, size_t bailoutEntries, size_t constants, - size_t safepointIndices, size_t osiIndices, - size_t icEntries, size_t runtimeSize, - size_t safepointsSize, + size_t nurseryObjects, size_t safepointIndices, + size_t osiIndices, size_t icEntries, + size_t runtimeSize, size_t safepointsSize, OptimizationLevel optimizationLevel) { if (snapshotsListSize >= MAX_BUFFER_SIZE || (bailoutEntries >= MAX_BUFFER_SIZE / sizeof(uint32_t))) { @@ -627,6 +632,7 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId, CheckedInt allocSize = sizeof(IonScript); allocSize += CheckedInt(constants) * sizeof(Value); allocSize += CheckedInt(runtimeSize); + allocSize += CheckedInt(nurseryObjects) * sizeof(HeapPtrObject); allocSize += CheckedInt(osiIndices) * sizeof(OsiIndex); allocSize += CheckedInt(safepointIndices) * sizeof(SafepointIndex); allocSize += CheckedInt(bailoutEntries) * sizeof(SnapshotOffset); @@ -659,6 +665,11 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId, script->runtimeDataOffset_ = offsetCursor; offsetCursor += runtimeSize; + MOZ_ASSERT(offsetCursor % alignof(HeapPtrObject) == 0); + script->initElements(offsetCursor, nurseryObjects); + script->nurseryObjectsOffset_ = offsetCursor; + offsetCursor += nurseryObjects * sizeof(HeapPtrObject); + MOZ_ASSERT(offsetCursor % alignof(OsiIndex) == 0); script->osiIndexOffset_ = offsetCursor; offsetCursor += osiIndices * sizeof(OsiIndex); @@ -691,6 +702,7 @@ IonScript* IonScript::New(JSContext* cx, IonCompilationId compilationId, MOZ_ASSERT(script->numConstants() == constants); MOZ_ASSERT(script->runtimeSize() == runtimeSize); + MOZ_ASSERT(script->numNurseryObjects() == nurseryObjects); MOZ_ASSERT(script->numOsiIndices() == osiIndices); MOZ_ASSERT(script->numSafepointIndices() == safepointIndices); MOZ_ASSERT(script->numBailoutEntries() == bailoutEntries); @@ -713,6 +725,10 @@ void IonScript::trace(JSTracer* trc) { TraceEdge(trc, &getConstant(i), "constant"); } + for (size_t i = 0; i < numNurseryObjects(); i++) { + TraceEdge(trc, &nurseryObjects()[i], "nursery-object"); + } + // Trace caches so that the JSScript pointer can be updated if moved. for (size_t i = 0; i < numICs(); i++) { getICFromIndex(i).trace(trc, this); @@ -720,7 +736,7 @@ void IonScript::trace(JSTracer* trc) { } /* static */ -void IonScript::writeBarrierPre(Zone* zone, IonScript* ionScript) { +void IonScript::preWriteBarrier(Zone* zone, IonScript* ionScript) { if (zone->needsIncrementalBarrier()) { ionScript->trace(zone->barrierTracer()); } @@ -855,6 +871,22 @@ const OsiIndex* IonScript::getOsiIndex(uint8_t* retAddr) const { } void IonScript::Destroy(JSFreeOp* fop, IonScript* script) { + // Make sure there are no pointers into the IonScript's nursery objects list + // in the store buffer. Because this can be called during sweeping when + // discarding JIT code, we have to lock the store buffer when we find an + // object that's (still) in the nursery. + mozilla::Maybe lock; + for (size_t i = 0, len = script->numNurseryObjects(); i < len; i++) { + JSObject* obj = script->nurseryObjects()[i]; + if (!IsInsideNursery(obj)) { + continue; + } + if (lock.isNothing()) { + lock.emplace(&fop->runtime()->gc.storeBuffer()); + } + script->nurseryObjects()[i] = HeapPtrObject(); + } + // This allocation is tracked by JSScript::setIonScriptImpl. fop->deleteUntracked(script); } @@ -1436,7 +1468,8 @@ CodeGenerator* CompileBackEnd(MIRGenerator* mir, WarpSnapshot* snapshot) { MOZ_ASSERT(!!snapshot == JitOptions.warpBuilder); if (snapshot) { - WarpBuilder builder(*snapshot, *mir); + WarpCompilation comp(mir->alloc()); + WarpBuilder builder(*snapshot, *mir, &comp); if (!builder.build()) { return nullptr; } @@ -1658,6 +1691,10 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script, script->ionScript()->setRecompiling(); } + if (osrPc) { + script->jitScript()->setHadIonOSR(); + } + WarpSnapshot* snapshot = nullptr; if (JitOptions.warpBuilder) { AbortReasonOr result = @@ -1723,7 +1760,7 @@ static AbortReason IonCompile(JSContext* cx, HandleScript script, return AbortReason::Disable; } - succeeded = LinkCodeGen(cx, codegen.get(), script, constraints); + succeeded = LinkCodeGen(cx, codegen.get(), script, constraints, snapshot); } if (succeeded) { @@ -2013,6 +2050,10 @@ MethodStatus jit::CanEnterIon(JSContext* cx, RunState& state) { if (status != Method_Compiled) { return status; } + // Bytecode analysis may forbid compilation for a script. + if (!script->canIonCompile()) { + return Method_CantCompile; + } } MOZ_ASSERT(!script->isIonCompilingOffThread()); @@ -2112,7 +2153,8 @@ static MethodStatus BaselineCanEnterAtBranch(JSContext* cx, HandleScript script, bool force = false; if (script->hasIonScript() && pc != script->ionScript()->osrPc()) { uint32_t count = script->ionScript()->incrOsrPcMismatchCounter(); - if (count <= JitOptions.osrPcMismatchesBeforeRecompile) { + if (count <= JitOptions.osrPcMismatchesBeforeRecompile && + !JitOptions.eagerIonCompilation()) { return Method_Skipped; } force = true; diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index 89a2ccb1be..6499bf4396 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -105,10 +105,7 @@ inline size_t NumLocalsAndArgs(JSScript* script) { // backend compilation. class MOZ_RAII AutoEnterIonBackend { public: - explicit AutoEnterIonBackend( - bool safeForMinorGC MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - + explicit AutoEnterIonBackend(bool safeForMinorGC) { #ifdef DEBUG JitContext* jcx = GetJitContext(); jcx->enterIonBackend(safeForMinorGC); @@ -121,8 +118,6 @@ class MOZ_RAII AutoEnterIonBackend { jcx->leaveIonBackend(); } #endif - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; bool OffThreadCompilationAvailable(JSContext* cx); diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 287aca108a..a7126ebbeb 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -16,6 +16,8 @@ #include "jit/LIR.h" #include "jit/Lowering.h" #include "jit/MIRGraph.h" +#include "jit/WarpBuilder.h" +#include "jit/WarpOracle.h" #include "util/CheckedArithmetic.h" #include "vm/PlainObject.h" // js::PlainObject #include "vm/RegExpObject.h" @@ -341,7 +343,7 @@ static void RemoveFromSuccessors(MBasicBlock* block) { static void ConvertToBailingBlock(TempAllocator& alloc, MBasicBlock* block) { // Add a bailout instruction. - MBail* bail = MBail::New(alloc, Bailout_FirstExecution); + MBail* bail = MBail::New(alloc, BailoutKind::FirstExecution); MInstruction* bailPoint = block->safeInsertTop(); block->insertBefore(block->safeInsertTop(), bail); @@ -3851,10 +3853,14 @@ static bool NeedsKeepAlive(MInstruction* slotsOrElements, MInstruction* use) { case MDefinition::Opcode::LoadFixedSlot: case MDefinition::Opcode::StoreFixedSlot: case MDefinition::Opcode::LoadElement: + case MDefinition::Opcode::LoadElementAndUnbox: case MDefinition::Opcode::StoreElement: + case MDefinition::Opcode::StoreHoleValueElement: case MDefinition::Opcode::InitializedLength: case MDefinition::Opcode::ArrayLength: case MDefinition::Opcode::BoundsCheck: + case MDefinition::Opcode::GuardElementNotHole: + case MDefinition::Opcode::SpectreMaskIndex: iter++; break; default: @@ -4586,9 +4592,18 @@ static bool ArgumentsUseCanBeLazy(JSContext* cx, JSScript* script, } // arguments[i] can read fp->unaliasedActual(i) directly. - if (ins->isCallGetElement() && index == 0) { - *argumentsContentsObserved = true; - return true; + if (JitOptions.warpBuilder) { + if (ins->isGetPropertyCache() && index == 0 && + IsGetElemPC(ins->resumePoint()->pc())) { + script->setUninlineable(); + *argumentsContentsObserved = true; + return true; + } + } else { + if (ins->isCallGetElement() && index == 0) { + *argumentsContentsObserved = true; + return true; + } } // MGetArgumentsObjectArg needs to be considered as a use that allows @@ -4600,11 +4615,29 @@ static bool ArgumentsUseCanBeLazy(JSContext* cx, JSScript* script, // arguments.length length can read fp->numActualArgs() directly. // arguments.callee can read fp->callee() directly if the arguments object // is mapped. - if (ins->isCallGetProperty() && index == 0 && - (ins->toCallGetProperty()->name() == cx->names().length || - (script->hasMappedArgsObj() && - ins->toCallGetProperty()->name() == cx->names().callee))) { - return true; + auto getPropCanBeLazy = [cx, script](JSString* name) { + if (name == cx->names().length) { + return true; + } + if (script->hasMappedArgsObj() && name == cx->names().callee) { + return true; + } + return false; + }; + + if (JitOptions.warpBuilder) { + if (ins->isGetPropertyCache() && index == 0) { + MDefinition* id = ins->toGetPropertyCache()->idval(); + if (id->isConstant() && id->type() == MIRType::String && + getPropCanBeLazy(id->toConstant()->toString())) { + return true; + } + } + } else { + if (ins->isCallGetProperty() && index == 0 && + getPropCanBeLazy(ins->toCallGetProperty()->name())) { + return true; + } } return false; @@ -4637,11 +4670,6 @@ bool jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg) { return true; } - if (JitOptions.warpBuilder) { - // TODO: support using WarpBuilder for arguments analysis. - return true; - } - static const uint32_t MAX_SCRIPT_SIZE = 10000; if (script->length() > MAX_SCRIPT_SIZE) { return true; @@ -4687,32 +4715,58 @@ bool jit::AnalyzeArgumentsUsage(JSContext* cx, JSScript* scriptArg) { const OptimizationInfo* optimizationInfo = IonOptimizations.get(OptimizationLevel::Normal); - CompilerConstraintList* constraints = NewCompilerConstraintList(temp); - if (!constraints) { - ReportOutOfMemory(cx); - return false; - } - - BaselineInspector inspector(script); const JitCompileOptions options(cx); MIRGenerator mirGen(CompileRealm::get(cx->realm()), options, &temp, &graph, &info, optimizationInfo); - IonBuilder builder(nullptr, mirGen, &info, constraints, &inspector, - /* baselineFrame = */ nullptr); - AbortReasonOr buildResult = builder.build(); - if (buildResult.isErr()) { - AbortReason reason = buildResult.unwrapErr(); - if (cx->isThrowingOverRecursed() || cx->isThrowingOutOfMemory()) { + if (JitOptions.warpBuilder) { + WarpOracle oracle(cx, mirGen, script); + + AbortReasonOr result = oracle.createSnapshot(); + if (result.isErr()) { + AbortReason reason = result.unwrapErr(); + if (cx->isThrowingOverRecursed() || cx->isThrowingOutOfMemory()) { + return false; + } + if (reason == AbortReason::Alloc) { + ReportOutOfMemory(cx); + return false; + } + MOZ_ASSERT(!cx->isExceptionPending()); + return true; + } + + WarpCompilation comp(temp); + WarpBuilder builder(*result.unwrap(), mirGen, &comp); + if (!builder.build()) { + ReportOutOfMemory(cx); return false; } - if (reason == AbortReason::Alloc) { + } else { + CompilerConstraintList* constraints = NewCompilerConstraintList(temp); + if (!constraints) { ReportOutOfMemory(cx); return false; } - MOZ_ASSERT(!cx->isExceptionPending()); - return true; + + BaselineInspector inspector(script); + IonBuilder builder(nullptr, mirGen, &info, constraints, &inspector, + /* baselineFrame = */ nullptr); + + AbortReasonOr buildResult = builder.build(); + if (buildResult.isErr()) { + AbortReason reason = buildResult.unwrapErr(); + if (cx->isThrowingOverRecursed() || cx->isThrowingOutOfMemory()) { + return false; + } + if (reason == AbortReason::Alloc) { + ReportOutOfMemory(cx); + return false; + } + MOZ_ASSERT(!cx->isExceptionPending()); + return true; + } } if (!SplitCriticalEdges(graph)) { @@ -5149,6 +5203,10 @@ void jit::DumpMIRExpressions(MIRGraph& graph, const CompileInfo& info, } } - out.printf("===== %s:%u =====\n", info.filename(), info.lineno()); + if (info.compilingWasm()) { + out.printf("===== end wasm MIR dump =====\n"); + } else { + out.printf("===== %s:%u =====\n", info.filename(), info.lineno()); + } #endif } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 436d5060b2..4265223046 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -10,6 +10,7 @@ #include #include "builtin/Eval.h" +#include "builtin/ModuleObject.h" #include "builtin/TypedObject.h" #include "frontend/SourceNotes.h" #include "jit/BaselineFrame.h" @@ -20,12 +21,15 @@ #include "jit/JitSpewer.h" #include "jit/Lowering.h" #include "jit/MIRGraph.h" +#include "js/experimental/JitInfo.h" // JSJitInfo +#include "js/Object.h" // JS::GetReservedSlot +#include "js/ScalarType.h" // js::Scalar::Type #include "util/CheckedArithmetic.h" #include "vm/ArgumentsObject.h" +#include "vm/BuiltinObjectKind.h" #include "vm/BytecodeIterator.h" #include "vm/BytecodeLocation.h" #include "vm/BytecodeUtil.h" -#include "vm/EnvironmentObject.h" #include "vm/Instrumentation.h" #include "vm/Opcodes.h" #include "vm/PlainObject.h" // js::PlainObject @@ -1263,7 +1267,7 @@ AbortReasonOr IonBuilder::initEnvironmentChain(MDefinition* callee) { // Update the environment slot from UndefinedValue only after initial // environment is created so that bailout doesn't see a partial env. - // See: |InitFromBailout| + // See: |BaselineStackBuilder::buildBaselineFrame| current->setEnvironmentChain(env); return Ok(); } @@ -1407,25 +1411,7 @@ AbortReasonOr IonBuilder::maybeAddOsrTypeBarriers() { // the types in the preheader. MBasicBlock* osrBlock = graph().osrBlock(); - if (!osrBlock) { - // Because IonBuilder does not compile catch blocks, it's possible to - // end up without an OSR block if the OSR pc is only reachable via a - // break-statement inside the catch block. For instance: - // - // for (;;) { - // try { - // throw 3; - // } catch(e) { - // break; - // } - // } - // while (..) { } // <= OSR here, only reachable via catch block. - // - // For now we just abort in this case. - MOZ_ASSERT(graph().hasTryBlock()); - return abort(AbortReason::Disable, - "OSR block only reachable through catch block"); - } + MOZ_ASSERT(osrBlock); MBasicBlock* preheader = osrBlock->getSuccessor(0); MBasicBlock* header = preheader->getSuccessor(0); @@ -2027,6 +2013,7 @@ AbortReasonOr IonBuilder::inspectOpcode(JSOp op, bool* restarted) { case JSOp::InitElem: case JSOp::InitHiddenElem: + case JSOp::InitLockedElem: return jsop_initelem(); case JSOp::InitElemInc: @@ -2291,7 +2278,7 @@ AbortReasonOr IonBuilder::inspectOpcode(JSOp op, bool* restarted) { return jsop_setfunname(GET_UINT8(pc)); case JSOp::PushLexicalEnv: - return jsop_pushlexicalenv(GET_UINT32_INDEX(pc)); + return jsop_pushlexicalenv(GET_GCTHING_INDEX(pc)); case JSOp::PopLexicalEnv: current->setEnvironmentChain(walkEnvironmentChain(1)); @@ -2321,6 +2308,9 @@ AbortReasonOr IonBuilder::inspectOpcode(JSOp op, bool* restarted) { case JSOp::HasOwn: return jsop_hasown(); + case JSOp::CheckPrivateField: + return jsop_checkprivatefield(); + case JSOp::SetRval: MOZ_ASSERT(!script()->noScriptRval()); current->setSlot(info().returnValueSlot(), current->pop()); @@ -2398,8 +2388,8 @@ AbortReasonOr IonBuilder::inspectOpcode(JSOp op, bool* restarted) { case JSOp::ObjWithProto: return jsop_objwithproto(); - case JSOp::FunctionProto: - return jsop_functionproto(); + case JSOp::BuiltinObject: + return jsop_builtinobject(); case JSOp::CheckReturn: return jsop_checkreturn(); @@ -2560,6 +2550,8 @@ AbortReasonOr IonBuilder::replaceTypeSet(MDefinition* subject, return Ok(); } + MOZ_ASSERT(!type->hasType(TypeSet::MagicArgType())); + // Don't emit MFilterTypeSet if it doesn't improve the typeset. if (subject->resultTypeSet()) { if (subject->resultTypeSet()->equals(type)) { @@ -2683,7 +2675,7 @@ AbortReasonOr IonBuilder::improveTypesAtTypeOfCompare(MCompare* ins, alloc_->lifoAlloc()); } - if (inputTypes->unknown()) { + if (inputTypes->unknown() || inputTypes->hasType(TypeSet::MagicArgType())) { return Ok(); } @@ -2774,7 +2766,7 @@ AbortReasonOr IonBuilder::improveTypesAtNullOrUndefinedCompare( alloc_->lifoAlloc()); } - if (inputTypes->unknown()) { + if (inputTypes->unknown() || inputTypes->hasType(TypeSet::MagicArgType())) { return Ok(); } @@ -2857,7 +2849,7 @@ AbortReasonOr IonBuilder::improveTypesAtTest(MDefinition* ins, alloc_->lifoAlloc()); } - if (oldType->unknown()) { + if (oldType->unknown() || oldType->hasType(TypeSet::MagicArgType())) { return Ok(); } @@ -2891,7 +2883,7 @@ AbortReasonOr IonBuilder::improveTypesAtTest(MDefinition* ins, } // If ins does not have a typeset we return as we cannot optimize. - if (oldType->unknown()) { + if (oldType->unknown() || oldType->hasType(TypeSet::MagicArgType())) { return Ok(); } @@ -2940,7 +2932,7 @@ AbortReasonOr IonBuilder::improveTypesAtTest(MDefinition* ins, } // If ins does not have a typeset we return as we cannot optimize. - if (oldType->unknown()) { + if (oldType->unknown() || oldType->hasType(TypeSet::MagicArgType())) { return Ok(); } @@ -3043,7 +3035,7 @@ AbortReasonOr IonBuilder::visitTest(JSOp op, bool* restarted) { current->end(mir); if (TestTrueTargetIsJoinPoint(op)) { - mozilla::Swap(target1, target2); + std::swap(target1, target2); } MOZ_TRY(addPendingEdge(PendingEdge::NewTestTrue(current, op), target1)); @@ -3092,39 +3084,12 @@ AbortReasonOr IonBuilder::visitTry() { return abort(AbortReason::Disable, "Try-catch during analysis"); } - // Get the pc of the last instruction in the try block. It's a JSOp::Goto to - // jump over the catch block. - jsbytecode* endpc = pc + GET_CODE_OFFSET(pc); - MOZ_ASSERT(JSOp(*endpc) == JSOp::Goto); - MOZ_ASSERT(GET_JUMP_OFFSET(endpc) > 0); - - jsbytecode* afterTry = endpc + GET_JUMP_OFFSET(endpc); - - // The baseline compiler should not attempt to enter the catch block - // via OSR. - MOZ_ASSERT(info().osrPc() < endpc || info().osrPc() >= afterTry); - - // If controlflow in the try body is terminated (by a return or throw - // statement), the code after the try-statement may still be reachable - // via the catch block (which we don't compile) and OSR can enter it. - // For example: - // - // try { - // throw 3; - // } catch(e) { } - // - // for (var i=0; i<1000; i++) {} - // - // To handle this, we create two blocks: one for the try block and one - // for the code following the try-catch statement. - graph().setHasTryBlock(); MBasicBlock* tryBlock; MOZ_TRY_VAR(tryBlock, newBlock(current, GetNextPc(pc))); - current->end(MGotoWithFake::New(alloc(), tryBlock, nullptr)); - MOZ_TRY(addPendingEdge(PendingEdge::NewGotoWithFake(current), afterTry)); + current->end(MGoto::New(alloc(), tryBlock)); return startTraversingBlock(tryBlock); } @@ -3261,11 +3226,6 @@ AbortReasonOr IonBuilder::visitJumpTarget(JSOp op) { MOZ_TRY(addEdge(source, 0)); lastIns->toGoto()->initSuccessor(0, joinBlock); continue; - - case PendingEdge::Kind::GotoWithFake: - MOZ_TRY(addEdge(source, 0)); - lastIns->toGotoWithFake()->initSuccessor(1, joinBlock); - continue; } MOZ_CRASH("Invalid kind"); } @@ -3977,19 +3937,6 @@ AbortReasonOr IonBuilder::jsop_tostring() { return Ok(); } -class AutoAccumulateReturns { - MIRGraph& graph_; - MIRGraphReturns* prev_; - - public: - AutoAccumulateReturns(MIRGraph& graph, MIRGraphReturns& returns) - : graph_(graph) { - prev_ = graph_.returnAccumulator(); - graph_.setReturnAccumulator(&returns); - } - ~AutoAccumulateReturns() { graph_.setReturnAccumulator(prev_); } -}; - IonBuilder::InliningResult IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target) { MOZ_ASSERT(target->hasBytecode()); @@ -4011,7 +3958,9 @@ IonBuilder::InliningResult IonBuilder::inlineScriptedCall(CallInfo& callInfo, } // Capture formals in the outer resume point. - MOZ_TRY(callInfo.pushCallStack(&mirGen_, current)); + if (!callInfo.pushCallStack(&mirGen_, current)) { + return abort(AbortReason::Alloc); + } MResumePoint* outerResumePoint = MResumePoint::New(alloc(), current, pc, MResumePoint::Outer); @@ -4842,7 +4791,9 @@ AbortReasonOr IonBuilder::inlineCalls(CallInfo& callInfo, MBasicBlock* dispatchBlock = current; callInfo.setImplicitlyUsedUnchecked(); - MOZ_TRY(callInfo.pushCallStack(&mirGen_, dispatchBlock)); + if (!callInfo.pushCallStack(&mirGen_, dispatchBlock)) { + return abort(AbortReason::Alloc); + } // Patch any InlinePropertyTable to only contain functions that are // inlineable. The InlinePropertyTable will also be patched at the end to @@ -5489,7 +5440,9 @@ AbortReasonOr IonBuilder::jsop_funcall(uint32_t argc) { // Save prior call stack in case we need to resolve during bailout // recovery of inner inlined function. This includes the JSFunction and the // 'call' native function. - MOZ_TRY(callInfo.savePriorCallStack(&mirGen_, current, argc + 2)); + if (!callInfo.savePriorCallStack(&mirGen_, current, argc + 2)) { + return abort(AbortReason::Alloc); + } // Shimmy the slots down to remove the native 'call' function. current->shimmySlots(funcDepth - 1); @@ -5735,8 +5688,6 @@ bool IonBuilder::ensureArrayIteratorPrototypeNextNotModified() { AbortReasonOr IonBuilder::jsop_optimize_spreadcall() { MDefinition* arr = current->peek(-1); - // Assuming optimization isn't available doesn't affect correctness. - // TODO: Investigate dynamic checks. bool result = false; do { // Inline with MIsPackedArray if the conditions described in @@ -5749,11 +5700,6 @@ AbortReasonOr IonBuilder::jsop_optimize_spreadcall() { break; } - // The array has no hole. - if (types->hasObjectFlags(constraints(), OBJECT_FLAG_NON_PACKED)) { - break; - } - // The array's prototype is Array.prototype. JSObject* proto; if (!types->getCommonPrototype(constraints(), &proto)) { @@ -5789,11 +5735,13 @@ AbortReasonOr IonBuilder::jsop_optimize_spreadcall() { auto* ins = MIsPackedArray::New(alloc(), arr); current->add(ins); current->push(ins); - } else { - arr->setImplicitlyUsedUnchecked(); - pushConstant(BooleanValue(false)); + return Ok(); } - return Ok(); + + auto* ins = MOptimizeSpreadCallCache::New(alloc(), arr); + current->add(ins); + current->push(ins); + return resumeAfter(ins); } AbortReasonOr IonBuilder::jsop_funapplyarray(uint32_t argc) { @@ -5840,18 +5788,17 @@ AbortReasonOr IonBuilder::jsop_funapplyarray(uint32_t argc) { return pushTypeBarrier(apply, types, BarrierKind::TypeSet); } -AbortReasonOr CallInfo::savePriorCallStack(MIRGenerator* mir, - MBasicBlock* current, - size_t peekDepth) { +bool CallInfo::savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, + size_t peekDepth) { MOZ_ASSERT(priorArgs_.empty()); if (!priorArgs_.reserve(peekDepth)) { - return mir->abort(AbortReason::Alloc); + return false; } while (peekDepth) { priorArgs_.infallibleAppend(current->peek(0 - int32_t(peekDepth))); peekDepth--; } - return Ok(); + return true; } AbortReasonOr IonBuilder::jsop_funapplyarguments(uint32_t argc) { @@ -5917,7 +5864,9 @@ AbortReasonOr IonBuilder::jsop_funapplyarguments(uint32_t argc) { CallInfo callInfo(alloc(), pc, /* constructing = */ false, /* ignoresReturnValue = */ BytecodeIsPopped(pc)); - MOZ_TRY(callInfo.savePriorCallStack(&mirGen_, current, 4)); + if (!callInfo.savePriorCallStack(&mirGen_, current, 4)) { + return abort(AbortReason::Alloc); + } // Vp MDefinition* vp = current->pop(); @@ -6303,7 +6252,7 @@ AbortReasonOr IonBuilder::makeCall(const Maybe& targets, if (call->isCallDOMNative()) { return pushDOMTypeBarrier(call, types, - call->getSingleTarget()->rawJSFunction()); + call->getSingleTarget()->rawNativeJSFunction()); } return pushTypeBarrier(call, types, BarrierKind::TypeSet); @@ -6425,10 +6374,6 @@ AbortReasonOr IonBuilder::jsop_compare(JSOp op, MDefinition* left, bool emitted = false; if (!forceInlineCaches()) { - MOZ_TRY(compareTryCharacter(&emitted, op, left, right)); - if (emitted) { - return Ok(); - } MOZ_TRY(compareTrySpecialized(&emitted, op, left, right)); if (emitted) { return Ok(); @@ -6462,79 +6407,6 @@ AbortReasonOr IonBuilder::jsop_compare(JSOp op, MDefinition* left, return Ok(); } -AbortReasonOr IonBuilder::compareTryCharacter(bool* emitted, JSOp op, - MDefinition* left, - MDefinition* right) { - MOZ_ASSERT(*emitted == false); - - // |str[i]| is compiled as |MFromCharCode(MCharCodeAt(str, i))|. - auto isCharAccess = [](MDefinition* ins) { - return ins->isFromCharCode() && - ins->toFromCharCode()->input()->isCharCodeAt(); - }; - - if (left->isConstant() || right->isConstant()) { - // Try to optimize |MConstant(string) (MFromCharCode MCharCodeAt)| - // as |MConstant(charcode) MCharCodeAt|. - MConstant* constant; - MDefinition* operand; - if (left->isConstant()) { - constant = left->toConstant(); - operand = right; - } else { - constant = right->toConstant(); - operand = left; - } - - if (constant->type() != MIRType::String || - constant->toString()->length() != 1 || !isCharAccess(operand)) { - return Ok(); - } - - char16_t charCode = constant->toString()->asAtom().latin1OrTwoByteChar(0); - constant->setImplicitlyUsedUnchecked(); - - MConstant* charCodeConst = MConstant::New(alloc(), Int32Value(charCode)); - current->add(charCodeConst); - - MDefinition* charCodeAt = operand->toFromCharCode()->input(); - operand->setImplicitlyUsedUnchecked(); - - if (left == constant) { - left = charCodeConst; - right = charCodeAt; - } else { - left = charCodeAt; - right = charCodeConst; - } - } else if (isCharAccess(left) && isCharAccess(right)) { - // Try to optimize |(MFromCharCode MCharCodeAt) (MFromCharCode - // MCharCodeAt)| as |MCharCodeAt MCharCodeAt|. - - MDefinition* leftCharCodeAt = left->toFromCharCode()->input(); - left->setImplicitlyUsedUnchecked(); - - MDefinition* rightCharCodeAt = right->toFromCharCode()->input(); - right->setImplicitlyUsedUnchecked(); - - left = leftCharCodeAt; - right = rightCharCodeAt; - } else { - return Ok(); - } - - MCompare* ins = MCompare::New(alloc(), left, right, op); - ins->setCompareType(MCompare::Compare_Int32); - ins->cacheOperandMightEmulateUndefined(constraints()); - - current->add(ins); - current->push(ins); - - MOZ_ASSERT(!ins->isEffectful()); - *emitted = true; - return Ok(); -} - static bool ObjectOrSimplePrimitive(MDefinition* op) { // Return true if op is either undefined/null/boolean/int32/symbol or an // object. @@ -6915,7 +6787,8 @@ AbortReasonOr IonBuilder::jsop_newobject() { } AbortReasonOr IonBuilder::jsop_initelem() { - MOZ_ASSERT(JSOp(*pc) == JSOp::InitElem || JSOp(*pc) == JSOp::InitHiddenElem); + MOZ_ASSERT(JSOp(*pc) == JSOp::InitElem || JSOp(*pc) == JSOp::InitHiddenElem || + JSOp(*pc) == JSOp::InitLockedElem); MDefinition* value = current->pop(); MDefinition* id = current->pop(); @@ -7067,9 +6940,15 @@ AbortReasonOr IonBuilder::initArrayElementFastPath( } // Store the value. - MStoreElement* store = MStoreElement::New(alloc(), elements, id, value, - /* needsHoleCheck = */ false); - current->add(store); + if (value->type() == MIRType::MagicHole) { + value->setImplicitlyUsedUnchecked(); + auto* store = MStoreHoleValueElement::New(alloc(), elements, id); + current->add(store); + } else { + auto* store = MStoreElement::New(alloc(), elements, id, value, + /* needsHoleCheck = */ false); + current->add(store); + } if (addResumePointAndIncrementInitializedLength) { // Update the initialized length. (The template object for this @@ -9801,7 +9680,7 @@ AbortReasonOr IonBuilder::jsop_checkobjcoercible() { MCheckObjCoercible* check = MCheckObjCoercible::New(alloc(), current->pop()); current->add(check); current->push(check); - return Ok(); + return resumeAfter(check); } AbortReasonOr IonBuilder::jsop_checkclassheritage() { @@ -10897,7 +10776,7 @@ AbortReasonOr IonBuilder::getPropTryCommonGetter(bool* emitted, if (singleton && jitinfo->aliasSet() == JSJitInfo::AliasNone) { size_t slot = jitinfo->slotIndex; *emitted = true; - pushConstant(GetReservedSlot(singleton, slot)); + pushConstant(JS::GetReservedSlot(singleton, slot)); return Ok(); } @@ -11767,15 +11646,6 @@ AbortReasonOr IonBuilder::jsop_regexp(RegExpObject* reobj) { } AbortReasonOr IonBuilder::jsop_object(JSObject* obj) { - if (mirGen_.options.cloneSingletons()) { - MCloneLiteral* clone = - MCloneLiteral::New(alloc(), constant(ObjectValue(*obj))); - current->add(clone); - current->push(clone); - return resumeAfter(clone); - } - - realm->setSingletonsAsValues(); pushConstant(ObjectValue(*obj)); return Ok(); } @@ -11866,7 +11736,7 @@ AbortReasonOr IonBuilder::jsop_setfunname(uint8_t prefixKind) { return resumeAfter(ins); } -AbortReasonOr IonBuilder::jsop_pushlexicalenv(uint32_t index) { +AbortReasonOr IonBuilder::jsop_pushlexicalenv(GCThingIndex index) { MOZ_ASSERT(usesEnvironmentChain()); LexicalScope* scope = &script()->getScope(index)->as(); @@ -12077,18 +11947,20 @@ AbortReasonOr IonBuilder::jsop_functionthis() { "JSOp::FunctionThis would need non-syntactic global"); } + LexicalEnvironmentObject* globalLexical = + &script()->global().lexicalEnvironment(); + JSObject* globalThis = globalLexical->thisObject(); + if (IsNullOrUndefined(def->type())) { - LexicalEnvironmentObject* globalLexical = - &script()->global().lexicalEnvironment(); - pushConstant(ObjectValue(*globalLexical->thisObject())); + pushConstant(ObjectValue(*globalThis)); return Ok(); } - MBoxNonStrictThis* thisObj = MBoxNonStrictThis::New(alloc(), def); + MBoxNonStrictThis* thisObj = MBoxNonStrictThis::New(alloc(), def, globalThis); current->add(thisObj); current->push(thisObj); - return resumeAfter(thisObj); + return Ok(); } AbortReasonOr IonBuilder::jsop_globalthis() { @@ -12107,7 +11979,7 @@ AbortReasonOr IonBuilder::jsop_globalthis() { AbortReasonOr IonBuilder::jsop_typeof() { MDefinition* input = current->pop(); - MTypeOf* ins = MTypeOf::New(alloc(), input, input->type()); + MTypeOf* ins = MTypeOf::New(alloc(), input); ins->cacheInputMaybeCallableOrEmulatesUndefined(constraints()); @@ -12438,6 +12310,18 @@ AbortReasonOr IonBuilder::jsop_hasown() { return Ok(); } +AbortReasonOr IonBuilder::jsop_checkprivatefield() { + MDefinition* id = current->peek(-1); + MDefinition* obj = current->peek(-2); + + MCheckPrivateFieldCache* ins = MCheckPrivateFieldCache::New(alloc(), obj, id); + current->add(ins); + current->push(ins); + + MOZ_TRY(resumeAfter(ins)); + return Ok(); +} + AbortReasonOr IonBuilder::hasOnProtoChain(TypeSet::ObjectKey* key, JSObject* protoObject, bool* onProto) { @@ -12599,7 +12483,8 @@ AbortReasonOr IonBuilder::jsop_instanceof() { return Ok(); } - MInstanceOf* ins = MInstanceOf::New(alloc(), obj, protoObject); + MConstant* protoConst = constant(ObjectValue(*protoObject)); + MInstanceOf* ins = MInstanceOf::New(alloc(), obj, protoConst); current->add(ins); current->push(ins); @@ -12638,7 +12523,7 @@ AbortReasonOr IonBuilder::jsop_instanceof() { return Ok(); } - MInstanceOf* ins = MInstanceOf::New(alloc(), obj, protoObject); + MInstanceOf* ins = MInstanceOf::New(alloc(), obj, protoConst); current->add(ins); current->push(ins); return resumeAfter(ins); @@ -12735,17 +12620,17 @@ AbortReasonOr IonBuilder::jsop_objwithproto() { return resumeAfter(ins); } -AbortReasonOr IonBuilder::jsop_functionproto() { - JSProtoKey key = JSProto_Function; +AbortReasonOr IonBuilder::jsop_builtinobject() { + auto kind = BuiltinObjectKind(GET_UINT8(pc)); - // Bake in the prototype if it exists. - if (JSObject* proto = script()->global().maybeGetPrototype(key)) { - pushConstant(ObjectValue(*proto)); + // Bake in the built-in if it exists. + if (JSObject* builtin = MaybeGetBuiltinObject(&script()->global(), kind)) { + pushConstant(ObjectValue(*builtin)); return Ok(); } // Otherwise emit code to generate it. - auto* ins = MFunctionProto::New(alloc()); + auto* ins = MBuiltinObject::New(alloc(), kind); current->add(ins); current->push(ins); return resumeAfter(ins); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 2d2b02fee7..98f775adc7 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -21,6 +21,9 @@ #include "jit/MIRGenerator.h" #include "jit/MIRGraph.h" #include "jit/TIOracle.h" +#include "js/experimental/JitInfo.h" // JSJitInfo +#include "js/ScalarType.h" // js::Scalar::Type +#include "vm/SharedStencil.h" // GCThingIndex namespace js { @@ -91,9 +94,9 @@ using CallTargets = Vector; // whenever we need to execute the catch-block. // // Because we don't compile the catch-block and the code after the try-catch may -// only be reachable via the catch-block, MGotoWithFake is used to ensure the -// code after the try-catch is always compiled and is part of the graph. -// See IonBuilder::visitTry for more information. +// only be reachable via the catch-block, Baseline's BytecodeAnalysis ensures +// Baseline does not attempt OSR into Ion/Warp when loops are only reachable via +// catch/finally blocks. // // Finally-blocks are currently not supported by Ion. @@ -422,8 +425,6 @@ class MOZ_STACK_CLASS IonBuilder { bool* emitted, JSOp op, MDefinition* left, MDefinition* right); AbortReasonOr compareTryBinaryStub(bool* emitted, MDefinition* left, MDefinition* right); - AbortReasonOr compareTryCharacter(bool* emitted, JSOp op, - MDefinition* left, MDefinition* right); // jsop_newarray helpers. AbortReasonOr newArrayTryTemplateObject(bool* emitted, @@ -634,7 +635,7 @@ class MOZ_STACK_CLASS IonBuilder { AbortReasonOr jsop_lambda_arrow(JSFunction* fun); AbortReasonOr jsop_funwithproto(JSFunction* fun); AbortReasonOr jsop_setfunname(uint8_t prefixKind); - AbortReasonOr jsop_pushlexicalenv(uint32_t index); + AbortReasonOr jsop_pushlexicalenv(GCThingIndex index); AbortReasonOr jsop_copylexicalenv(bool copySlots); AbortReasonOr jsop_functionthis(); AbortReasonOr jsop_globalthis(); @@ -649,6 +650,7 @@ class MOZ_STACK_CLASS IonBuilder { AbortReasonOr jsop_iternext(); AbortReasonOr jsop_in(); AbortReasonOr jsop_hasown(); + AbortReasonOr jsop_checkprivatefield(); AbortReasonOr jsop_instanceof(); AbortReasonOr jsop_getaliasedvar(EnvironmentCoordinate ec); AbortReasonOr jsop_setaliasedvar(EnvironmentCoordinate ec); @@ -667,7 +669,7 @@ class MOZ_STACK_CLASS IonBuilder { AbortReasonOr jsop_instrumentation_scriptid(); AbortReasonOr jsop_coalesce(); AbortReasonOr jsop_objwithproto(); - AbortReasonOr jsop_functionproto(); + AbortReasonOr jsop_builtinobject(); AbortReasonOr jsop_checkreturn(); AbortReasonOr jsop_checkthis(); AbortReasonOr jsop_checkthisreinit(); @@ -760,7 +762,6 @@ class MOZ_STACK_CLASS IonBuilder { // String natives. InliningResult inlineStringObject(CallInfo& callInfo); InliningResult inlineStrCharCodeAt(CallInfo& callInfo); - InliningResult inlineConstantCharCodeAt(CallInfo& callInfo); InliningResult inlineStrFromCharCode(CallInfo& callInfo); InliningResult inlineStrFromCodePoint(CallInfo& callInfo); InliningResult inlineStrCharAt(CallInfo& callInfo); @@ -789,6 +790,7 @@ class MOZ_STACK_CLASS IonBuilder { InliningResult inlineObject(CallInfo& callInfo); InliningResult inlineObjectCreate(CallInfo& callInfo); InliningResult inlineObjectIs(CallInfo& callInfo); + InliningResult inlineObjectIsPrototypeOf(CallInfo& callInfo); InliningResult inlineObjectToString(CallInfo& callInfo); InliningResult inlineDefineDataProperty(CallInfo& callInfo); @@ -834,7 +836,6 @@ class MOZ_STACK_CLASS IonBuilder { InliningResult inlineIsCrossRealmArrayConstructor(CallInfo& callInfo); InliningResult inlineToInteger(CallInfo& callInfo); InliningResult inlineToLength(CallInfo& callInfo); - InliningResult inlineToString(CallInfo& callInfo); InliningResult inlineDump(CallInfo& callInfo); InliningResult inlineGuardToClass(CallInfo& callInfo, InlinableNative native); InliningResult inlineIsConstructing(CallInfo& callInfo); diff --git a/js/src/jit/IonCacheIRCompiler.cpp b/js/src/jit/IonCacheIRCompiler.cpp index 1fe56933e2..751e01adae 100644 --- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -15,6 +15,7 @@ #include "jit/Linker.h" #include "jit/SharedICHelpers.h" #include "jit/VMFunctions.h" +#include "js/friend/DOMProxy.h" // JS::ExpandoAndGeneration #include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" #include "util/Memory.h" @@ -31,6 +32,8 @@ using namespace js::jit; using mozilla::DebugOnly; using mozilla::Maybe; +using JS::ExpandoAndGeneration; + namespace js { namespace jit { @@ -403,6 +406,21 @@ bool IonCacheIRCompiler::init() { allocator.initInputLocation(0, ic->value()); break; } + case CacheKind::OptimizeSpreadCall: { + auto* ic = ic_->asOptimizeSpreadCallIC(); + Register output = ic->output(); + + available.add(output); + available.add(ic->temp()); + + liveRegs_.emplace(ic->liveRegs()); + outputUnchecked_.emplace( + TypedOrValueRegister(MIRType::Boolean, AnyRegister(output))); + + MOZ_ASSERT(numInputs == 1); + allocator.initInputLocation(0, ic->value()); + break; + } case CacheKind::In: { IonInIC* ic = ic_->asInIC(); Register output = ic->output(); @@ -434,6 +452,21 @@ bool IonCacheIRCompiler::init() { allocator.initInputLocation(1, ic->value()); break; } + case CacheKind::CheckPrivateField: { + IonCheckPrivateFieldIC* ic = ic_->asCheckPrivateFieldIC(); + Register output = ic->output(); + + available.add(output); + + liveRegs_.emplace(ic->liveRegs()); + outputUnchecked_.emplace( + TypedOrValueRegister(MIRType::Boolean, AnyRegister(output))); + + MOZ_ASSERT(numInputs == 2); + allocator.initInputLocation(0, ic->value()); + allocator.initInputLocation(1, ic->id()); + break; + } case CacheKind::InstanceOf: { IonInstanceOfIC* ic = ic_->asInstanceOfIC(); Register output = ic->output(); @@ -590,9 +623,11 @@ void IonCacheIRCompiler::assertFloatRegisterAvailable(FloatRegister reg) { case CacheKind::GetIterator: case CacheKind::In: case CacheKind::HasOwn: + case CacheKind::CheckPrivateField: case CacheKind::InstanceOf: case CacheKind::UnaryArith: case CacheKind::ToPropertyKey: + case CacheKind::OptimizeSpreadCall: MOZ_CRASH("No float registers available"); case CacheKind::SetProp: case CacheKind::SetElem: @@ -793,37 +828,11 @@ bool IonCacheIRCompiler::emitGuardSpecificAtom(StringOperandId strId, return false; } - Label done; - masm.branchPtr(Assembler::Equal, str, ImmGCPtr(atom), &done); - - // The pointers are not equal, so if the input string is also an atom it - // must be a different string. - masm.branchTest32(Assembler::NonZero, Address(str, JSString::offsetOfFlags()), - Imm32(JSString::ATOM_BIT), failure->label()); - - // Check the length. - masm.branch32(Assembler::NotEqual, Address(str, JSString::offsetOfLength()), - Imm32(atom->length()), failure->label()); - - // We have a non-atomized string with the same length. Call a helper - // function to do the comparison. LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); - masm.PushRegsInMask(volatileRegs); - - masm.setupUnalignedABICall(scratch); - masm.movePtr(ImmGCPtr(atom), scratch); - masm.passABIArg(scratch); - masm.passABIArg(str); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, EqualStringsHelperPure)); - masm.mov(ReturnReg, scratch); - - LiveRegisterSet ignore; - ignore.add(scratch); - masm.PopRegsInMaskIgnore(volatileRegs, ignore); - masm.branchIfFalseBool(scratch, failure->label()); + volatileRegs.takeUnchecked(scratch); - masm.bind(&done); + masm.guardSpecificAtom(str, atom, scratch, volatileRegs, failure->label()); return true; } @@ -910,9 +919,15 @@ bool IonCacheIRCompiler::emitGuardHasGetterSetter(ObjOperandId objId, return true; } -bool IonCacheIRCompiler::emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm, - TypedOrValueRegister output) { +bool IonCacheIRCompiler::emitCallScriptedGetterResult( + ValOperandId receiverId, uint32_t getterOffset, bool sameRealm, + uint32_t nargsAndFlagsOffset) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoSaveLiveRegisters save(*this); + AutoOutputRegister output(*this); + + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); + JSFunction* target = &objectStubField(getterOffset)->as(); AutoScratchRegister scratch(allocator, masm); @@ -975,35 +990,15 @@ bool IonCacheIRCompiler::emitCallScriptedGetterResultShared( return true; } -bool IonCacheIRCompiler::emitCallScriptedGetterResult(ObjOperandId objId, - uint32_t getterOffset, - bool sameRealm) { - JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); - AutoSaveLiveRegisters save(*this); - AutoOutputRegister output(*this); - - Register obj = allocator.useRegister(masm, objId); - - return emitCallScriptedGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - sameRealm, output); -} - -bool IonCacheIRCompiler::emitCallScriptedGetterByValueResult( - ValOperandId valId, uint32_t getterOffset, bool sameRealm) { +bool IonCacheIRCompiler::emitCallNativeGetterResult( + ValOperandId receiverId, uint32_t getterOffset, bool sameRealm, + uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); - ValueOperand val = allocator.useValueRegister(masm, valId); + ValueOperand receiver = allocator.useValueRegister(masm, receiverId); - return emitCallScriptedGetterResultShared(val, getterOffset, sameRealm, - output); -} - -bool IonCacheIRCompiler::emitCallNativeGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, - const AutoOutputRegister& output, AutoSaveLiveRegisters& save) { JSFunction* target = &objectStubField(getterOffset)->as(); MOZ_ASSERT(target->isNative()); @@ -1039,7 +1034,7 @@ bool IonCacheIRCompiler::emitCallNativeGetterResultShared( } masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameType::IonOOLNative); - if (target->realm() != cx_->realm()) { + if (!sameRealm) { masm.switchToRealm(target->realm(), scratch); } @@ -1055,7 +1050,7 @@ bool IonCacheIRCompiler::emitCallNativeGetterResultShared( // Test for failure. masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); - if (target->realm() != cx_->realm()) { + if (!sameRealm) { masm.switchToRealm(cx_->realm(), ReturnReg); } @@ -1072,32 +1067,55 @@ bool IonCacheIRCompiler::emitCallNativeGetterResultShared( return true; } -bool IonCacheIRCompiler::emitCallNativeGetterResult(ObjOperandId objId, - uint32_t getterOffset) { +bool IonCacheIRCompiler::emitCallDOMGetterResult(ObjOperandId objId, + uint32_t jitInfoOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, objId); - return emitCallNativeGetterResultShared( - TypedOrValueRegister(MIRType::Object, AnyRegister(obj)), getterOffset, - output, save); + const JSJitInfo* info = rawWordStubField(jitInfoOffset); + + allocator.discardStack(masm); + prepareVMCall(masm, save); + + masm.Push(obj); + masm.Push(ImmPtr(info)); + + using Fn = + bool (*)(JSContext*, const JSJitInfo*, HandleObject, MutableHandleValue); + callVM(masm); + + masm.storeCallResultValue(output); + return true; } -bool IonCacheIRCompiler::emitCallNativeGetterByValueResult( - ValOperandId valId, uint32_t getterOffset) { +bool IonCacheIRCompiler::emitCallDOMSetter(ObjOperandId objId, + uint32_t jitInfoOffset, + ValOperandId rhsId) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); - AutoOutputRegister output(*this); - ValueOperand val = allocator.useValueRegister(masm, valId); + Register obj = allocator.useRegister(masm, objId); + ValueOperand val = allocator.useValueRegister(masm, rhsId); + + const JSJitInfo* info = rawWordStubField(jitInfoOffset); - return emitCallNativeGetterResultShared(val, getterOffset, output, save); + allocator.discardStack(masm); + prepareVMCall(masm, save); + + masm.Push(val); + masm.Push(obj); + masm.Push(ImmPtr(info)); + + using Fn = bool (*)(JSContext*, const JSJitInfo*, HandleObject, HandleValue); + callVM(masm); + return true; } -bool IonCacheIRCompiler::emitCallProxyGetResult(ObjOperandId objId, - uint32_t idOffset) { +bool IonCacheIRCompiler::emitProxyGetResult(ObjOperandId objId, + uint32_t idOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); @@ -1180,6 +1198,10 @@ bool IonCacheIRCompiler::emitLoadFrameArgumentResult(Int32OperandId indexId) { MOZ_CRASH("Baseline-specific op"); } +bool IonCacheIRCompiler::emitFrameIsConstructingResult() { + MOZ_CRASH("Baseline-specific op"); +} + bool IonCacheIRCompiler::emitLoadEnvironmentFixedSlotResult( ObjOperandId objId, uint32_t offsetOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); @@ -1729,6 +1751,34 @@ static void EmitAssertNoCopyOnWriteElements(MacroAssembler& masm, #endif } +static void EmitAssertExtensibleElements(MacroAssembler& masm, + Register elementsReg) { +#ifdef DEBUG + // Preceding shape guards ensure the object elements are extensible. + Address elementsFlags(elementsReg, ObjectElements::offsetOfFlags()); + Label ok; + masm.branchTest32(Assembler::Zero, elementsFlags, + Imm32(ObjectElements::Flags::NOT_EXTENSIBLE), + &ok); + masm.assumeUnreachable("Unexpected non-extensible elements"); + masm.bind(&ok); +#endif +} + +static void EmitAssertWritableArrayLengthElements(MacroAssembler& masm, + Register elementsReg) { +#ifdef DEBUG + // Preceding shape guards ensure the array length is writable. + Address elementsFlags(elementsReg, ObjectElements::offsetOfFlags()); + Label ok; + masm.branchTest32(Assembler::Zero, elementsFlags, + Imm32(ObjectElements::Flags::NONWRITABLE_ARRAY_LENGTH), + &ok); + masm.assumeUnreachable("Unexpected non-writable array length elements"); + masm.bind(&ok); +#endif +} + bool IonCacheIRCompiler::emitStoreDenseElement(ObjOperandId objId, Int32OperandId indexId, ValOperandId rhsId) { @@ -1799,6 +1849,11 @@ bool IonCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, EmitAssertNoCopyOnWriteElements(masm, scratch1); + EmitAssertExtensibleElements(masm, scratch1); + if (handleAdd) { + EmitAssertWritableArrayLengthElements(masm, scratch1); + } + Address initLength(scratch1, ObjectElements::offsetOfInitializedLength()); BaseObjectElementIndex element(scratch1, index); @@ -1817,12 +1872,14 @@ bool IonCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, masm.jump(&capacityOk); // Check for non-writable array length. We only have to do this if - // index >= capacity. + // index >= capacity and handleAdd is false. masm.bind(&allocElement); - Address elementsFlags(scratch1, ObjectElements::offsetOfFlags()); - masm.branchTest32(Assembler::NonZero, elementsFlags, - Imm32(ObjectElements::NONWRITABLE_ARRAY_LENGTH), - failure->label()); + if (!handleAdd) { + Address elementsFlags(scratch1, ObjectElements::offsetOfFlags()); + masm.branchTest32(Assembler::NonZero, elementsFlags, + Imm32(ObjectElements::NONWRITABLE_ARRAY_LENGTH), + failure->label()); + } LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs()); save.takeUnchecked(scratch1); @@ -1870,18 +1927,75 @@ bool IonCacheIRCompiler::emitStoreDenseElementHole(ObjOperandId objId, return true; } -bool IonCacheIRCompiler::emitArrayPush(ObjOperandId objId, ValOperandId rhsId) { - MOZ_ASSERT_UNREACHABLE("emitArrayPush not supported for IonCaches."); - return false; +bool IonCacheIRCompiler::emitLoadStringCharResult(StringOperandId strId, + Int32OperandId indexId) { + JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); + AutoOutputRegister output(*this); + Register str = allocator.useRegister(masm, strId); + Register index = allocator.useRegister(masm, indexId); + AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output); + AutoScratchRegister scratch2(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) { + return false; + } + + // Bounds check, load string char. + masm.spectreBoundsCheck32(index, Address(str, JSString::offsetOfLength()), + scratch1, failure->label()); + masm.loadStringChar(str, index, scratch1, scratch2, failure->label()); + + // Load StaticString for this char. For larger code units perform a VM call. + Label vmCall; + masm.boundsCheck32PowerOfTwo(scratch1, StaticStrings::UNIT_STATIC_LIMIT, + &vmCall); + masm.movePtr(ImmPtr(&cx_->staticStrings().unitStaticTable), scratch2); + masm.loadPtr(BaseIndex(scratch2, scratch1, ScalePointer), scratch2); + + Label done; + masm.jump(&done); + + { + masm.bind(&vmCall); + + // FailurePath and AutoSaveLiveRegisters don't get along very well. Both are + // modifying the stack and expect that no other stack manipulations are + // made. Therefore we need to use an ABI call instead of a VM call here. + + LiveRegisterSet volatileRegs(GeneralRegisterSet::Volatile(), + liveVolatileFloatRegs()); + volatileRegs.takeUnchecked(scratch1); + volatileRegs.takeUnchecked(scratch2); + volatileRegs.takeUnchecked(output); + masm.PushRegsInMask(volatileRegs); + + masm.setupUnalignedABICall(scratch2); + masm.loadJSContext(scratch2); + masm.passABIArg(scratch2); + masm.passABIArg(scratch1); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::StringFromCharCodeNoGC)); + masm.storeCallPointerResult(scratch2); + + masm.PopRegsInMask(volatileRegs); + + masm.branchPtr(Assembler::Equal, scratch2, ImmWord(0), failure->label()); + } + + masm.bind(&done); + masm.tagValue(JSVAL_TYPE_STRING, scratch2, output.valueReg()); + return true; } -bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, +bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId receiverId, uint32_t setterOffset, - ValOperandId rhsId) { + ValOperandId rhsId, + bool sameRealm, + uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); - Register obj = allocator.useRegister(masm, objId); + Register receiver = allocator.useRegister(masm, receiverId); JSFunction* target = &objectStubField(setterOffset)->as(); MOZ_ASSERT(target->isNative()); ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId); @@ -1901,7 +2015,7 @@ bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, // Build vp and move the base into argVpReg. masm.Push(val); - masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); + masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(receiver))); masm.Push(ObjectValue(*target)); masm.moveStackPtrTo(argVp.get()); @@ -1918,7 +2032,7 @@ bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, } masm.enterFakeExitFrame(argJSContext, scratch, ExitFrameType::IonOOLNative); - if (target->realm() != cx_->realm()) { + if (!sameRealm) { masm.switchToRealm(target->realm(), scratch); } @@ -1934,7 +2048,7 @@ bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, // Test for failure. masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); - if (target->realm() != cx_->realm()) { + if (!sameRealm) { masm.switchToRealm(cx_->realm(), ReturnReg); } @@ -1942,14 +2056,15 @@ bool IonCacheIRCompiler::emitCallNativeSetter(ObjOperandId objId, return true; } -bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId, +bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId receiverId, uint32_t setterOffset, ValOperandId rhsId, - bool sameRealm) { + bool sameRealm, + uint32_t nargsAndFlagsOffset) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); - Register obj = allocator.useRegister(masm, objId); + Register receiver = allocator.useRegister(masm, receiverId); JSFunction* target = &objectStubField(setterOffset)->as(); ConstantOrRegister val = allocator.useConstantOrRegister(masm, rhsId); @@ -1983,7 +2098,7 @@ bool IonCacheIRCompiler::emitCallScriptedSetter(ObjOperandId objId, masm.Push(UndefinedValue()); } masm.Push(val); - masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); + masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(receiver))); if (!sameRealm) { masm.switchToRealm(target->realm(), scratch); @@ -2033,8 +2148,8 @@ bool IonCacheIRCompiler::emitCallSetArrayLength(ObjOperandId objId, bool strict, return true; } -bool IonCacheIRCompiler::emitCallProxySet(ObjOperandId objId, uint32_t idOffset, - ValOperandId rhsId, bool strict) { +bool IonCacheIRCompiler::emitProxySet(ObjOperandId objId, uint32_t idOffset, + ValOperandId rhsId, bool strict) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); @@ -2057,10 +2172,9 @@ bool IonCacheIRCompiler::emitCallProxySet(ObjOperandId objId, uint32_t idOffset, return true; } -bool IonCacheIRCompiler::emitCallProxySetByValue(ObjOperandId objId, - ValOperandId idId, - ValOperandId rhsId, - bool strict) { +bool IonCacheIRCompiler::emitProxySetByValue(ObjOperandId objId, + ValOperandId idId, + ValOperandId rhsId, bool strict) { JitSpew(JitSpew_Codegen, "%s", __FUNCTION__); AutoSaveLiveRegisters save(*this); @@ -2392,6 +2506,12 @@ bool IonCacheIRCompiler::emitCallStringObjectConcatResult(ValOperandId lhsId, return true; } +bool IonCacheIRCompiler::emitGuardFunctionScript(ObjOperandId funId, + uint32_t expectedOffset, + uint32_t nargsAndFlagsOffset) { + MOZ_CRASH("Call ICs not used in ion"); +} + bool IonCacheIRCompiler::emitCallScriptedFunction(ObjOperandId calleeId, Int32OperandId argcId, CallFlags flags) { @@ -2421,6 +2541,13 @@ bool IonCacheIRCompiler::emitCallClassHook(ObjOperandId calleeId, MOZ_CRASH("Call ICs not used in ion"); } +bool IonCacheIRCompiler::emitCallInlinedFunction(ObjOperandId calleeId, + Int32OperandId argcId, + uint32_t icScriptOffset, + CallFlags flags) { + MOZ_CRASH("Call ICs not used in ion"); +} + bool IonCacheIRCompiler::emitLoadArgumentFixedSlot(ValOperandId resultId, uint8_t slotIndex) { MOZ_CRASH("Call ICs not used in ion"); @@ -2432,8 +2559,18 @@ bool IonCacheIRCompiler::emitLoadArgumentDynamicSlot(ValOperandId resultId, MOZ_CRASH("Call ICs not used in ion"); } -bool IonCacheIRCompiler::emitGuardFunApply(Int32OperandId argcId, - CallFlags flags) { +bool IonCacheIRCompiler::emitArrayPush(ObjOperandId objId, ValOperandId rhsId) { + MOZ_CRASH("Call ICs not used in ion"); +} + +bool IonCacheIRCompiler::emitArrayJoinResult(ObjOperandId objId, + StringOperandId sepId) { + MOZ_CRASH("Call ICs not used in ion"); +} + +bool IonCacheIRCompiler::emitPackedArraySliceResult( + uint32_t templateObjectOffset, ObjOperandId arrayId, Int32OperandId beginId, + Int32OperandId endId) { MOZ_CRASH("Call ICs not used in ion"); } @@ -2441,14 +2578,27 @@ bool IonCacheIRCompiler::emitIsArrayResult(ValOperandId inputId) { MOZ_CRASH("Call ICs not used in ion"); } +bool IonCacheIRCompiler::emitIsTypedArrayResult(ObjOperandId objId, + bool isPossiblyWrapped) { + MOZ_CRASH("Call ICs not used in ion"); +} + bool IonCacheIRCompiler::emitStringFromCharCodeResult(Int32OperandId codeId) { MOZ_CRASH("Call ICs not used in ion"); } +bool IonCacheIRCompiler::emitStringFromCodePointResult(Int32OperandId codeId) { + MOZ_CRASH("Call ICs not used in ion"); +} + bool IonCacheIRCompiler::emitMathRandomResult(uint32_t rngOffset) { MOZ_CRASH("Call ICs not used in ion"); } +bool IonCacheIRCompiler::emitReflectGetPrototypeOfResult(ObjOperandId objId) { + MOZ_CRASH("Call ICs not used in ion"); +} + bool IonCacheIRCompiler::emitHasClassResult(ObjOperandId objId, uint32_t claspOffset) { MOZ_CRASH("Call ICs not used in ion"); diff --git a/js/src/jit/IonCacheIRCompiler.h b/js/src/jit/IonCacheIRCompiler.h index 97e120a962..10e5320862 100644 --- a/js/src/jit/IonCacheIRCompiler.h +++ b/js/src/jit/IonCacheIRCompiler.h @@ -67,12 +67,6 @@ class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler { CacheOp op, ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset, mozilla::Maybe numNewSlotsOffset); - MOZ_MUST_USE bool emitCallScriptedGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, bool sameRealm, - TypedOrValueRegister output); - MOZ_MUST_USE bool emitCallNativeGetterResultShared( - TypedOrValueRegister receiver, uint32_t getterOffset, - const AutoOutputRegister& output, AutoSaveLiveRegisters& save); bool needsPostBarrier() const; diff --git a/js/src/jit/IonCompileTask.cpp b/js/src/jit/IonCompileTask.cpp index 2d7d013499..c44bca87fa 100644 --- a/js/src/jit/IonCompileTask.cpp +++ b/js/src/jit/IonCompileTask.cpp @@ -7,6 +7,7 @@ #include "jit/CodeGenerator.h" #include "jit/JitScript.h" #include "jit/WarpSnapshot.h" +#include "vm/HelperThreadState.h" #include "vm/JSScript.h" #include "vm/JSScript-inl.h" @@ -14,6 +15,31 @@ using namespace js; using namespace js::jit; +void IonCompileTask::runHelperThreadTask(AutoLockHelperThreadState& locked) { + // The build is taken by this thread. Unfreeze the LifoAlloc to allow + // mutations. + alloc().lifoAlloc()->setReadWrite(); + + { + AutoUnlockHelperThreadState unlock(locked); + runTask(); + } + + FinishOffThreadIonCompile(this, locked); + + JSRuntime* rt = script()->runtimeFromAnyThread(); + + // Ping the main thread so that the compiled code can be incorporated at the + // next interrupt callback. + // + // This must happen before the current task is reset. DestroyContext + // cancels in progress Ion compilations before destroying its target + // context, and after we reset the current task we are no longer considered + // to be Ion compiling. + rt->mainContextFromAnyThread()->requestInterrupt( + InterruptReason::AttachIonCompilations); +} + void IonCompileTask::runTask() { // This is the entry point when ion compiles are run offthread. TraceLoggerThread* logger = TraceLoggerForCurrentThread(); @@ -143,6 +169,15 @@ void jit::FreeIonCompileTask(IonCompileTask* task) { js_delete(task->alloc().lifoAlloc()); } +void IonFreeTask::runHelperThreadTask(AutoLockHelperThreadState& locked) { + { + AutoUnlockHelperThreadState unlock(locked); + jit::FreeIonCompileTask(task_); + } + + js_delete(this); +} + void jit::FinishOffThreadTask(JSRuntime* runtime, IonCompileTask* task, const AutoLockHelperThreadState& locked) { MOZ_ASSERT(runtime); @@ -170,8 +205,8 @@ void jit::FinishOffThreadTask(JSRuntime* runtime, IonCompileTask* task, if (script->isIonCompilingOffThread()) { script->jitScript()->clearIsIonCompilingOffThread(script); - AbortReasonOr status = task->mirGen().getOffThreadStatus(); - if (status.isErr() && status.unwrapErr() == AbortReason::Disable) { + const AbortReasonOr& status = task->mirGen().getOffThreadStatus(); + if (status.isErr() && status.inspectErr() == AbortReason::Disable) { script->disableIon(); } } diff --git a/js/src/jit/IonCompileTask.h b/js/src/jit/IonCompileTask.h index 8b2a630b25..bbd42cf3ca 100644 --- a/js/src/jit/IonCompileTask.h +++ b/js/src/jit/IonCompileTask.h @@ -10,6 +10,7 @@ #include "jit/MIRGenerator.h" #include "js/Utility.h" +#include "vm/HelperThreadTask.h" namespace js { @@ -21,7 +22,7 @@ class CodeGenerator; class MRootList; // IonCompileTask represents a single off-thread Ion compilation task. -class IonCompileTask final : public RunnableTask, +class IonCompileTask final : public HelperThreadTask, public mozilla::LinkedListElement { MIRGenerator& mirGen_; @@ -49,6 +50,7 @@ class IonCompileTask final : public RunnableTask, TempAllocator& alloc() { return mirGen_.alloc(); } bool scriptHasIonScript() const { return scriptHasIonScript_; } CompilerConstraintList* constraints() { return constraints_; } + WarpSnapshot* snapshot() { return snapshot_; } size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf); void trace(JSTracer* trc); @@ -63,7 +65,20 @@ class IonCompileTask final : public RunnableTask, } ThreadType threadType() override { return THREAD_TYPE_ION; } - void runTask() override; + void runTask(); + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; +}; + +class IonFreeTask : public HelperThreadTask { + public: + explicit IonFreeTask(IonCompileTask* task) : task_(task) {} + IonCompileTask* compileTask() { return task_; } + + ThreadType threadType() override { return THREAD_TYPE_ION_FREE; } + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; + + private: + IonCompileTask* task_; }; void AttachFinishedCompilations(JSContext* cx); diff --git a/js/src/jit/IonIC.cpp b/js/src/jit/IonIC.cpp index 8462bb45bc..a4e4c10a06 100644 --- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -54,8 +54,12 @@ Register IonIC::scratchRegisterForEntryJump() { return asInIC()->temp(); case CacheKind::HasOwn: return asHasOwnIC()->output(); + case CacheKind::CheckPrivateField: + return asCheckPrivateFieldIC()->output(); case CacheKind::GetIterator: return asGetIteratorIC()->temp1(); + case CacheKind::OptimizeSpreadCall: + return asOptimizeSpreadCallIC()->temp(); case CacheKind::InstanceOf: return asInstanceOfIC()->output(); case CacheKind::UnaryArith: @@ -163,6 +167,9 @@ bool IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript, IonScript* ionScript = outerScript->ionScript(); AutoDetectInvalidation adi(cx, res, ionScript); + // Optimized-arguments and other magic values must not escape to Ion ICs. + MOZ_ASSERT(!val.isMagic()); + // If the IC is idempotent, we will redo the op in the interpreter. if (ic->idempotent()) { adi.disable(); @@ -259,13 +266,20 @@ bool IonGetPropSuperIC::update(JSContext* cx, HandleScript outerScript, cx, ic, ionScript, ic->kind(), val, idVal, receiver, GetPropertyResultFlags::All); - RootedId id(cx); - if (!ValueToId(cx, idVal, &id)) { - return false; - } + if (ic->kind() == CacheKind::GetPropSuper) { + RootedPropertyName name(cx, idVal.toString()->asAtom().asPropertyName()); + if (!GetProperty(cx, obj, receiver, name, res)) { + return false; + } + } else { + MOZ_ASSERT(ic->kind() == CacheKind::GetElemSuper); - if (!GetProperty(cx, obj, receiver, id, res)) { - return false; + JSOp op = JSOp(*ic->pc()); + MOZ_ASSERT(op == JSOp::GetElemSuper); + + if (!GetObjectElementOperation(cx, op, obj, receiver, idVal, res)) { + return false; + } } // Monitor changes to cache entry. @@ -323,7 +337,8 @@ bool IonSetPropertyIC::update(JSContext* cx, HandleScript outerScript, jsbytecode* pc = ic->pc(); if (ic->kind() == CacheKind::SetElem) { if (JSOp(*pc) == JSOp::InitElemInc || JSOp(*pc) == JSOp::InitElemArray) { - if (!InitArrayElemOperation(cx, pc, obj, idVal.toInt32(), rhs)) { + if (!InitArrayElemOperation(cx, pc, obj.as(), + idVal.toInt32(), rhs)) { return false; } } else if (IsPropertyInitOp(JSOp(*pc))) { @@ -466,6 +481,18 @@ JSObject* IonGetIteratorIC::update(JSContext* cx, HandleScript outerScript, return ValueToIterator(cx, value); } +/* static */ +bool IonOptimizeSpreadCallIC::update(JSContext* cx, HandleScript outerScript, + IonOptimizeSpreadCallIC* ic, + HandleValue value, bool* result) { + IonScript* ionScript = outerScript->ionScript(); + + TryAttachIonStub( + cx, ic, ionScript, value); + + return OptimizeSpreadCall(cx, value, result); +} + /* static */ bool IonHasOwnIC::update(JSContext* cx, HandleScript outerScript, IonHasOwnIC* ic, HandleValue val, HandleValue idVal, @@ -484,6 +511,19 @@ bool IonHasOwnIC::update(JSContext* cx, HandleScript outerScript, return true; } +/* static */ +bool IonCheckPrivateFieldIC::update(JSContext* cx, HandleScript outerScript, + IonCheckPrivateFieldIC* ic, HandleValue val, + HandleValue idVal, bool* res) { + IonScript* ionScript = outerScript->ionScript(); + jsbytecode* pc = ic->pc(); + + TryAttachIonStub( + cx, ic, ionScript, CacheKind::CheckPrivateField, idVal, val); + + return CheckPrivateFieldOperation(cx, pc, val, idVal, res); +} + /* static */ bool IonInIC::update(JSContext* cx, HandleScript outerScript, IonInIC* ic, HandleValue key, HandleObject obj, bool* res) { diff --git a/js/src/jit/IonIC.h b/js/src/jit/IonIC.h index 2ae4c7db87..f1da9a50f3 100644 --- a/js/src/jit/IonIC.h +++ b/js/src/jit/IonIC.h @@ -6,6 +6,7 @@ #define jit_IonIC_h #include "jit/CacheIR.h" +#include "jit/shared/Assembler-shared.h" namespace js { namespace jit { @@ -59,12 +60,14 @@ class IonGetNameIC; class IonBindNameIC; class IonGetIteratorIC; class IonHasOwnIC; +class IonCheckPrivateFieldIC; class IonInIC; class IonInstanceOfIC; class IonCompareIC; class IonUnaryArithIC; class IonBinaryArithIC; class IonToPropertyKeyIC; +class IonOptimizeSpreadCallIC; class IonIC { // This either points at the OOL path for the fallback path, or the code for @@ -170,10 +173,18 @@ class IonIC { MOZ_ASSERT(kind_ == CacheKind::GetIterator); return (IonGetIteratorIC*)this; } + IonOptimizeSpreadCallIC* asOptimizeSpreadCallIC() { + MOZ_ASSERT(kind_ == CacheKind::OptimizeSpreadCall); + return (IonOptimizeSpreadCallIC*)this; + } IonHasOwnIC* asHasOwnIC() { MOZ_ASSERT(kind_ == CacheKind::HasOwn); return (IonHasOwnIC*)this; } + IonCheckPrivateFieldIC* asCheckPrivateFieldIC() { + MOZ_ASSERT(kind_ == CacheKind::CheckPrivateField); + return (IonCheckPrivateFieldIC*)this; + } IonInIC* asInIC() { MOZ_ASSERT(kind_ == CacheKind::In); return (IonInIC*)this; @@ -407,6 +418,31 @@ class IonGetIteratorIC : public IonIC { IonGetIteratorIC* ic, HandleValue value); }; +class IonOptimizeSpreadCallIC : public IonIC { + LiveRegisterSet liveRegs_; + ValueOperand value_; + Register output_; + Register temp_; + + public: + IonOptimizeSpreadCallIC(LiveRegisterSet liveRegs, ValueOperand value, + Register output, Register temp) + : IonIC(CacheKind::OptimizeSpreadCall), + liveRegs_(liveRegs), + value_(value), + output_(output), + temp_(temp) {} + + ValueOperand value() const { return value_; } + Register output() const { return output_; } + Register temp() const { return temp_; } + LiveRegisterSet liveRegs() const { return liveRegs_; } + + static bool update(JSContext* cx, HandleScript outerScript, + IonOptimizeSpreadCallIC* ic, HandleValue value, + bool* result); +}; + class IonHasOwnIC : public IonIC { LiveRegisterSet liveRegs_; @@ -433,6 +469,32 @@ class IonHasOwnIC : public IonIC { HandleValue idVal, int32_t* res); }; +class IonCheckPrivateFieldIC : public IonIC { + LiveRegisterSet liveRegs_; + + TypedOrValueRegister value_; + TypedOrValueRegister id_; + Register output_; + + public: + IonCheckPrivateFieldIC(LiveRegisterSet liveRegs, TypedOrValueRegister value, + TypedOrValueRegister id, Register output) + : IonIC(CacheKind::CheckPrivateField), + liveRegs_(liveRegs), + value_(value), + id_(id), + output_(output) {} + + TypedOrValueRegister value() const { return value_; } + TypedOrValueRegister id() const { return id_; } + Register output() const { return output_; } + LiveRegisterSet liveRegs() const { return liveRegs_; } + + static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, + IonCheckPrivateFieldIC* ic, HandleValue val, + HandleValue idVal, bool* res); +}; + class IonInIC : public IonIC { LiveRegisterSet liveRegs_; diff --git a/js/src/jit/IonScript.h b/js/src/jit/IonScript.h index 76a779fea8..a1912a72a6 100644 --- a/js/src/jit/IonScript.h +++ b/js/src/jit/IonScript.h @@ -58,8 +58,9 @@ class alignas(8) IonScript final : public TrailingArray { // Offset (in bytes) from `this` to the start of each trailing array. Each // array ends where following one begins. There is no implicit padding (except // possible at very end). - Offset constantTableOffset_ = 0; // JS::Value aligned - Offset runtimeDataOffset_ = 0; // uint64_t aligned + Offset constantTableOffset_ = 0; // JS::Value aligned + Offset runtimeDataOffset_ = 0; // uint64_t aligned + Offset nurseryObjectsOffset_ = 0; // pointer aligned Offset osiIndexOffset_ = 0; Offset safepointIndexOffset_ = 0; Offset bailoutTableOffset_ = 0; @@ -133,6 +134,7 @@ class alignas(8) IonScript final : public TrailingArray { // Layout helpers Offset constantTableOffset() const { return constantTableOffset_; } Offset runtimeDataOffset() const { return runtimeDataOffset_; } + Offset nurseryObjectsOffset() const { return nurseryObjectsOffset_; } Offset osiIndexOffset() const { return osiIndexOffset_; } Offset safepointIndexOffset() const { return safepointIndexOffset_; } Offset bailoutTableOffset() const { return bailoutTableOffset_; } @@ -169,7 +171,22 @@ class alignas(8) IonScript final : public TrailingArray { return offsetToPointer(runtimeDataOffset()); } size_t runtimeSize() const { - return numElements(runtimeDataOffset(), osiIndexOffset()); + return numElements(runtimeDataOffset(), nurseryObjectsOffset()); + } + + // + // List of (originally) nursery-allocated objects referenced from JIT code. + // (JSObject* alignment) + // + HeapPtrObject* nurseryObjects() { + return offsetToPointer(nurseryObjectsOffset()); + } + size_t numNurseryObjects() const { + return numElements(nurseryObjectsOffset(), osiIndexOffset()); + } + void* addressOfNurseryObject(uint32_t index) { + MOZ_ASSERT(index < numNurseryObjects()); + return &nurseryObjects()[index]; } // @@ -261,8 +278,8 @@ class alignas(8) IonScript final : public TrailingArray { uint32_t frameSize, size_t snapshotsListSize, size_t snapshotsRVATableSize, size_t recoversSize, size_t bailoutEntries, size_t constants, - size_t safepointIndices, size_t osiIndices, - size_t icEntries, size_t runtimeSize, + size_t nurseryObjects, size_t safepointIndices, + size_t osiIndices, size_t icEntries, size_t runtimeSize, size_t safepointsSize, OptimizationLevel optimizationLevel); @@ -408,7 +425,7 @@ class alignas(8) IonScript final : public TrailingArray { size_t allocBytes() const { return allocBytes_; } - static void writeBarrierPre(Zone* zone, IonScript* ionScript); + static void preWriteBarrier(Zone* zone, IonScript* ionScript); }; // Execution information for a basic block which may persist after the diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 4107a0e0cd..53b09002cb 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -11,9 +11,9 @@ #include #include -#include "jsfriendapi.h" #include "jstypes.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "js/Value.h" #include "vm/StringType.h" @@ -56,62 +56,54 @@ static const SnapshotOffset INVALID_RECOVER_OFFSET = uint32_t(-1); static const SnapshotOffset INVALID_SNAPSHOT_OFFSET = uint32_t(-1); // Different kinds of bailouts. -enum BailoutKind { +enum class BailoutKind : uint8_t { // Normal bailouts, that don't need to be handled specially when restarting // in baseline. // An inevitable bailout (MBail instruction or type barrier that always bails) - Bailout_Inevitable, + Inevitable, // Bailing out during a VM call. Many possible causes that are hard // to distinguish statically at snapshot construction time. // We just lump them together. - Bailout_DuringVMCall, + DuringVMCall, // Too many arguments for apply calls. - Bailout_TooManyArguments, + TooManyArguments, // Dynamic scope chain lookup produced |undefined| - Bailout_DynamicNameNotFound, - - // Input string contains 'arguments' or 'eval' - Bailout_StringArgumentsEval, + DynamicNameNotFound, // Bailout on overflow, but don't immediately invalidate. // Used for abs, sub and LoadUnboxedScalar (when loading a uint32 that // doesn't fit in an int32). - Bailout_Overflow, + Overflow, // floor, ceiling and round bail if input is NaN, if output would be -0 or // doesn't fit in int32 range - Bailout_Round, + Round, // Non-primitive value used as input for ToDouble, ToInt32, ToString, etc. // For ToInt32, can also mean that input can't be converted without precision // loss (e.g. 5.5). - Bailout_NonPrimitiveInput, + NonPrimitiveInput, // For ToInt32, would lose precision when converting (e.g. 5.5). - Bailout_PrecisionLoss, + PrecisionLoss, // We tripped a type barrier (object was not in the expected TypeSet) - Bailout_TypeBarrierO, + TypeBarrierO, // We tripped a type barrier (value was not in the expected TypeSet) - Bailout_TypeBarrierV, - // We tripped a type monitor (wrote an unexpected type in a property) - Bailout_MonitorTypes, + TypeBarrierV, // We hit a hole in an array. - Bailout_Hole, + Hole, // The object has dense array elements - Bailout_NoDenseElementsGuard, + NoDenseElementsGuard, // Array access with negative index - Bailout_NegativeIndex, - - // Array access with non integer index - Bailout_NonIntegerIndex, + NegativeIndex, // Pretty specific case: // - need a type barrier on a property write @@ -119,155 +111,265 @@ enum BailoutKind { // the value // - we need to guard that we're not given an object of that one other type // also used for the unused GuardClass instruction - Bailout_ObjectIdentityOrTypeGuard, + ObjectIdentityOrTypeGuard, // JSString was not equal to the expected JSAtom - Bailout_SpecificAtomGuard, + SpecificAtomGuard, // Symbol was not equal the expected JS::Symbol. - Bailout_SpecificSymbolGuard, + SpecificSymbolGuard, + + // Bailout triggered by MGuardStringToIndex. + StringToIndexGuard, + + // Bailout triggered by MGuardStringToInt32. + StringToInt32Guard, + + // Bailout triggered by MGuardStringToDouble. + StringToDoubleGuard, // Unbox expects a given type, bails out if it doesn't get it. - Bailout_NonInt32Input, - Bailout_NonNumericInput, // unboxing a double works with int32 too - Bailout_NonBooleanInput, - Bailout_NonObjectInput, - Bailout_NonStringInput, - Bailout_NonSymbolInput, - Bailout_NonBigIntInput, + NonInt32Input, + NonNumericInput, // unboxing a double works with int32 too + NonBooleanInput, + NonObjectInput, + NonStringInput, + NonSymbolInput, + NonBigIntInput, // We hit a |debugger;| statement. - Bailout_Debugger, + Debugger, // We hit this code for the first time. - Bailout_FirstExecution, + FirstExecution, + + // Array length did not fit in int32. + NonInt32ArrayLength, + + // Function length not available ("length" property was redefined or function + // has a lazy script) or did not fit in int32. + FunctionLength, + + // Function name not available ("name" property was redefined) + FunctionName, + + // Bailout triggered by MFromCodePoint + InvalidCodePoint, // END Normal bailouts // Bailouts caused by invalid assumptions based on Baseline code. // Causes immediate invalidation. - // Like Bailout_Overflow, but causes immediate invalidation. - Bailout_OverflowInvalidate, + // Like BailoutKind::Overflow, but causes immediate invalidation. + OverflowInvalidate, // Used for integer division, multiplication and modulo. // If there's a remainder, bails to return a double. // Can also signal overflow or result of -0. // Can also signal division by 0 (returns inf, a double). - Bailout_DoubleOutput, + DoubleOutput, // END Invalid assumptions bailouts // A bailout at the very start of a function indicates that there may be // a type mismatch in the arguments that necessitates a reflow. - Bailout_ArgumentCheck, + ArgumentCheck, // A bailout triggered by a bounds-check failure. - Bailout_BoundsCheck, + BoundsCheck, // A shape guard based on TI information failed. // (We saw an object whose shape does not match that / any of those observed // by the baseline IC.) - Bailout_ShapeGuard, + ShapeGuard, + + // Bailout triggered by MGuardProto or MGuardNullProto. + ProtoGuard, + + // Bailout triggered by MGuardIsProxy. + ProxyGuard, + + // Bailout triggered by MGuardIsNotProxy. + NotProxyGuard, + + // Bailout triggered by MGuardIsNotDOMProxy. + NotDOMProxyGuard, + + // Bailout triggered by MGuardIsNotArrayBufferMaybeShared. + NotArrayBufferMaybeSharedGuard, + + // Bailout triggered by MGuardIsTypedArray. + TypedArrayGuard, + + // Bailout triggered by a megamorphic load or store. + MegamorphicAccess, + + // Bailout triggered by MLoadArgumentsObjectArg and MArgumentsObjectLength. + ArgumentsObjectAccess, + + // Bailout triggered by MArrayPopShift. + ArrayPopShift, + + // Bailout triggered by MArraySlice. + ArraySlice, // Bailout triggered by MGuardValue. - Bailout_ValueGuard, + ValueGuard, + + // Bailout triggered by MGuardNotOptimizedArguments. + NotOptimizedArgumentsGuard, // Bailout triggered by MGuardNullOrUndefined. - Bailout_NullOrUndefinedGuard, + NullOrUndefinedGuard, + + // Bailout triggered by MGuardTagNotEqual. + TagNotEqualGuard, + + // Bailout triggered by MGuardFunctionFlags. + FunctionFlagsGuard, + + // Bailout triggered by MGuardFunctionKind. + FunctionKindGuard, + + // Bailout triggered by MGuardFunctionScript. + FunctionScriptGuard, + + // Bailout triggered by MGuardArrayIsPacked + PackedArrayGuard, // When we're trying to use an uninitialized lexical. - Bailout_UninitializedLexical, + UninitializedLexical, // A bailout to baseline from Ion on exception to handle Debugger hooks. - Bailout_IonExceptionDebugMode, + IonExceptionDebugMode, - Bailout_Limit + Limit }; inline const char* BailoutKindString(BailoutKind kind) { switch (kind) { // Normal bailouts. - case Bailout_Inevitable: - return "Bailout_Inevitable"; - case Bailout_DuringVMCall: - return "Bailout_DuringVMCall"; - case Bailout_TooManyArguments: - return "Bailout_TooManyArguments"; - case Bailout_DynamicNameNotFound: - return "Bailout_DynamicNameNotFound"; - case Bailout_StringArgumentsEval: - return "Bailout_StringArgumentsEval"; - case Bailout_Overflow: - return "Bailout_Overflow"; - case Bailout_Round: - return "Bailout_Round"; - case Bailout_NonPrimitiveInput: - return "Bailout_NonPrimitiveInput"; - case Bailout_PrecisionLoss: - return "Bailout_PrecisionLoss"; - case Bailout_TypeBarrierO: - return "Bailout_TypeBarrierO"; - case Bailout_TypeBarrierV: - return "Bailout_TypeBarrierV"; - case Bailout_MonitorTypes: - return "Bailout_MonitorTypes"; - case Bailout_Hole: - return "Bailout_Hole"; - case Bailout_NoDenseElementsGuard: - return "Bailout_NoDenseElementsGuard"; - case Bailout_NegativeIndex: - return "Bailout_NegativeIndex"; - case Bailout_NonIntegerIndex: - return "Bailout_NonIntegerIndex"; - case Bailout_ObjectIdentityOrTypeGuard: - return "Bailout_ObjectIdentityOrTypeGuard"; - case Bailout_SpecificAtomGuard: - return "Bailout_SpecifcAtomGuard"; - case Bailout_SpecificSymbolGuard: - return "Bailout_SpecifcSymbolGuard"; - case Bailout_NonInt32Input: - return "Bailout_NonInt32Input"; - case Bailout_NonNumericInput: - return "Bailout_NonNumericInput"; - case Bailout_NonBooleanInput: - return "Bailout_NonBooleanInput"; - case Bailout_NonObjectInput: - return "Bailout_NonObjectInput"; - case Bailout_NonStringInput: - return "Bailout_NonStringInput"; - case Bailout_NonSymbolInput: - return "Bailout_NonSymbolInput"; - case Bailout_NonBigIntInput: - return "Bailout_NonBigIntInput"; - case Bailout_Debugger: - return "Bailout_Debugger"; - case Bailout_FirstExecution: - return "Bailout_FirstExecution"; + case BailoutKind::Inevitable: + return "BailoutKind::Inevitable"; + case BailoutKind::DuringVMCall: + return "BailoutKind::DuringVMCall"; + case BailoutKind::TooManyArguments: + return "BailoutKind::TooManyArguments"; + case BailoutKind::DynamicNameNotFound: + return "BailoutKind::DynamicNameNotFound"; + case BailoutKind::Overflow: + return "BailoutKind::Overflow"; + case BailoutKind::Round: + return "BailoutKind::Round"; + case BailoutKind::NonPrimitiveInput: + return "BailoutKind::NonPrimitiveInput"; + case BailoutKind::PrecisionLoss: + return "BailoutKind::PrecisionLoss"; + case BailoutKind::TypeBarrierO: + return "BailoutKind::TypeBarrierO"; + case BailoutKind::TypeBarrierV: + return "BailoutKind::TypeBarrierV"; + case BailoutKind::Hole: + return "BailoutKind::Hole"; + case BailoutKind::NoDenseElementsGuard: + return "BailoutKind::NoDenseElementsGuard"; + case BailoutKind::NegativeIndex: + return "BailoutKind::NegativeIndex"; + case BailoutKind::ObjectIdentityOrTypeGuard: + return "BailoutKind::ObjectIdentityOrTypeGuard"; + case BailoutKind::SpecificAtomGuard: + return "BailoutKind::SpecifcAtomGuard"; + case BailoutKind::SpecificSymbolGuard: + return "BailoutKind::SpecificSymbolGuard"; + case BailoutKind::StringToIndexGuard: + return "BailoutKind::StringToIndexGuard"; + case BailoutKind::StringToInt32Guard: + return "BailoutKind::StringToInt32Guard"; + case BailoutKind::StringToDoubleGuard: + return "BailoutKind::StringToDoubleGuard"; + case BailoutKind::NonInt32Input: + return "BailoutKind::NonInt32Input"; + case BailoutKind::NonNumericInput: + return "BailoutKind::NonNumericInput"; + case BailoutKind::NonBooleanInput: + return "BailoutKind::NonBooleanInput"; + case BailoutKind::NonObjectInput: + return "BailoutKind::NonObjectInput"; + case BailoutKind::NonStringInput: + return "BailoutKind::NonStringInput"; + case BailoutKind::NonSymbolInput: + return "BailoutKind::NonSymbolInput"; + case BailoutKind::NonBigIntInput: + return "BailoutKind::NonBigIntInput"; + case BailoutKind::Debugger: + return "BailoutKind::Debugger"; + case BailoutKind::FirstExecution: + return "BailoutKind::FirstExecution"; + case BailoutKind::NonInt32ArrayLength: + return "BailoutKind::NonInt32ArrayLength"; + case BailoutKind::FunctionLength: + return "BailoutKind::FunctionLength"; + case BailoutKind::FunctionName: + return "BailoutKind::FunctionName"; + case BailoutKind::InvalidCodePoint: + return "BailoutKind::InvalidCodePoint"; // Bailouts caused by invalid assumptions. - case Bailout_OverflowInvalidate: - return "Bailout_OverflowInvalidate"; - case Bailout_DoubleOutput: - return "Bailout_DoubleOutput"; + case BailoutKind::OverflowInvalidate: + return "BailoutKind::OverflowInvalidate"; + case BailoutKind::DoubleOutput: + return "BailoutKind::DoubleOutput"; // Other bailouts. - case Bailout_ArgumentCheck: - return "Bailout_ArgumentCheck"; - case Bailout_BoundsCheck: - return "Bailout_BoundsCheck"; - case Bailout_ShapeGuard: - return "Bailout_ShapeGuard"; - case Bailout_ValueGuard: - return "Bailout_ValueGuard"; - case Bailout_NullOrUndefinedGuard: - return "Bailout_NullOrUndefinedGuard"; - case Bailout_UninitializedLexical: - return "Bailout_UninitializedLexical"; - case Bailout_IonExceptionDebugMode: - return "Bailout_IonExceptionDebugMode"; - - case Bailout_Limit: + case BailoutKind::ArgumentCheck: + return "BailoutKind::ArgumentCheck"; + case BailoutKind::BoundsCheck: + return "BailoutKind::BoundsCheck"; + case BailoutKind::ShapeGuard: + return "BailoutKind::ShapeGuard"; + case BailoutKind::ProtoGuard: + return "BailoutKind::ProtoGuard"; + case BailoutKind::ProxyGuard: + return "BailoutKind::ProxyGuard"; + case BailoutKind::NotProxyGuard: + return "BailoutKind::NotProxyGuard"; + case BailoutKind::NotDOMProxyGuard: + return "BailoutKind::NotDOMProxyGuard"; + case BailoutKind::NotArrayBufferMaybeSharedGuard: + return "BailoutKind::NotArrayBufferMaybeSharedGuard"; + case BailoutKind::TypedArrayGuard: + return "BailoutKind::TypedArrayGuard"; + case BailoutKind::MegamorphicAccess: + return "BailoutKind::MegamorphicAccess"; + case BailoutKind::ArgumentsObjectAccess: + return "BailoutKind::ArgumentsObjectAccess"; + case BailoutKind::ArrayPopShift: + return "BailoutKind::ArrayPopShift"; + case BailoutKind::ArraySlice: + return "BailoutKind::ArraySlice"; + case BailoutKind::ValueGuard: + return "BailoutKind::ValueGuard"; + case BailoutKind::NotOptimizedArgumentsGuard: + return "BailoutKind::NotOptimizedArgumentsGuard"; + case BailoutKind::NullOrUndefinedGuard: + return "BailoutKind::NullOrUndefinedGuard"; + case BailoutKind::TagNotEqualGuard: + return "BailoutKind::TagNotEqualGuard"; + case BailoutKind::FunctionFlagsGuard: + return "BailoutKind::FunctionFlagsGuard"; + case BailoutKind::FunctionKindGuard: + return "BailoutKind::FunctionKindGuard"; + case BailoutKind::FunctionScriptGuard: + return "BailoutKind::FunctionScriptGuard"; + case BailoutKind::PackedArrayGuard: + return "BailoutKind::PackedArrayGuard"; + case BailoutKind::UninitializedLexical: + return "BailoutKind::UninitializedLexical"; + case BailoutKind::IonExceptionDebugMode: + return "BailoutKind::IonExceptionDebugMode"; + + case BailoutKind::Limit: break; } @@ -711,6 +813,13 @@ static inline MIRType ScalarTypeToMIRType(Scalar::Type type) { MOZ_CRASH("unexpected kind"); } +static constexpr bool NeedsPostBarrier(MIRType type) { + MOZ_ASSERT(type != MIRType::Value); + MOZ_ASSERT(type != MIRType::ObjectOrNull); + return type == MIRType::Object || type == MIRType::String || + type == MIRType::BigInt; +} + #ifdef DEBUG // Track the pipeline of opcodes which has produced a snapshot. diff --git a/js/src/jit/JSJitFrameIter.cpp b/js/src/jit/JSJitFrameIter.cpp index a911fbf07f..14e6770247 100644 --- a/js/src/jit/JSJitFrameIter.cpp +++ b/js/src/jit/JSJitFrameIter.cpp @@ -11,6 +11,7 @@ #include "jit/JitFrames.h" #include "jit/JitScript.h" #include "jit/Safepoints.h" +#include "js/friend/DumpFunctions.h" // js::DumpObject, js::DumpValue #include "vm/JSScript-inl.h" diff --git a/js/src/jit/Jit.cpp b/js/src/jit/Jit.cpp index 30f07656b1..4c6cb65963 100644 --- a/js/src/jit/Jit.cpp +++ b/js/src/jit/Jit.cpp @@ -8,6 +8,7 @@ #include "jit/Ion.h" #include "jit/JitCommon.h" #include "jit/JitRealm.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimit #include "vm/Interpreter.h" #include "vm/Stack-inl.h" diff --git a/js/src/jit/JitAllocPolicy.h b/js/src/jit/JitAllocPolicy.h index 8cccf7abc9..4c8d7507de 100644 --- a/js/src/jit/JitAllocPolicy.h +++ b/js/src/jit/JitAllocPolicy.h @@ -6,7 +6,6 @@ #define jit_JitAllocPolicy_h #include "mozilla/Attributes.h" -#include "mozilla/GuardObjects.h" #include "mozilla/OperatorNewExtensions.h" #include diff --git a/js/src/jit/JitCode.h b/js/src/jit/JitCode.h index 523b3a4074..714d0a608a 100644 --- a/js/src/jit/JitCode.h +++ b/js/src/jit/JitCode.h @@ -12,8 +12,8 @@ #include "jstypes.h" -#include "gc/Allocator.h" // AllowGC -#include "gc/Cell.h" // gc::TenuredCell, gc::CellHeaderWithNonGCPointer +#include "gc/Allocator.h" // AllowGC +#include "gc/Cell.h" // gc::TenuredCellWithNonGCPointer #include "jit/ExecutableAllocator.h" // ExecutablePool #include "js/TraceKind.h" // JS::TraceKind #include "js/UbiNode.h" // ubi::{TracerConcrete, Size, CourseType} @@ -42,10 +42,12 @@ struct JitCodeHeader { } }; -class JitCode : public gc::TenuredCell { +class JitCode : public gc::TenuredCellWithNonGCPointer { + public: + // Raw code pointer, stored in the cell header. + uint8_t* raw() const { return headerPtr(); } + protected: - using CellHeaderWithCodePtr = gc::CellHeaderWithNonGCPointer; - CellHeaderWithCodePtr cellHeaderAndCode_; ExecutablePool* pool_; uint32_t bufferSize_; // Total buffer size. Does not include headerSize_. uint32_t insnSize_; // Instruction stream size. @@ -62,7 +64,7 @@ class JitCode : public gc::TenuredCell { JitCode() = delete; JitCode(uint8_t* code, uint32_t bufferSize, uint32_t headerSize, ExecutablePool* pool, CodeKind kind) - : cellHeaderAndCode_(code), + : TenuredCellWithNonGCPointer(code), pool_(pool), bufferSize_(bufferSize), insnSize_(0), @@ -84,7 +86,6 @@ class JitCode : public gc::TenuredCell { } public: - uint8_t* raw() const { return cellHeaderAndCode_.ptr(); } uint8_t* rawEnd() const { return raw() + insnSize_; } bool containsNativePC(const void* addr) const { const uint8_t* addr_u8 = (const uint8_t*)addr; @@ -118,10 +119,7 @@ class JitCode : public gc::TenuredCell { return code; } - static size_t offsetOfCode() { - return offsetof(JitCode, cellHeaderAndCode_) + - CellHeaderWithCodePtr::offsetOfPtr(); - } + static size_t offsetOfCode() { return offsetOfHeaderPtr(); } uint8_t* jumpRelocTable() { return raw() + jumpRelocTableOffset(); } @@ -134,7 +132,6 @@ class JitCode : public gc::TenuredCell { public: static const JS::TraceKind TraceKind = JS::TraceKind::JitCode; - const gc::CellHeader& cellHeader() const { return cellHeaderAndCode_; } }; } // namespace jit diff --git a/js/src/jit/JitContext.cpp b/js/src/jit/JitContext.cpp index 68d957a336..e5e60ced0b 100644 --- a/js/src/jit/JitContext.cpp +++ b/js/src/jit/JitContext.cpp @@ -144,15 +144,19 @@ bool jit::InitializeJit() { InitARMFlags(); #endif - // Note: these flags need to be initialized after the InitARMFlags call above. - JitOptions.supportsFloatingPoint = MacroAssembler::SupportsFloatingPoint(); - JitOptions.supportsUnalignedAccesses = - MacroAssembler::SupportsUnalignedAccesses(); + // Note: jit flags need to be initialized after the InitARMFlags call above. + ComputeJitSupportFlags(); CheckPerf(); return true; } +void jit::ComputeJitSupportFlags() { + JitOptions.supportsFloatingPoint = MacroAssembler::SupportsFloatingPoint(); + JitOptions.supportsUnalignedAccesses = + MacroAssembler::SupportsUnalignedAccesses(); +} + bool jit::JitSupportsSimd() { return js::jit::MacroAssembler::SupportsSimd(); } bool jit::JitSupportsAtomics() { diff --git a/js/src/jit/JitContext.h b/js/src/jit/JitContext.h index 399eb2fdde..e919b8b296 100644 --- a/js/src/jit/JitContext.h +++ b/js/src/jit/JitContext.h @@ -128,6 +128,10 @@ class JitContext { // Process-wide initialization of JIT data structures. MOZ_MUST_USE bool InitializeJit(); +// Call this after changing hardware parameters via command line flags (on +// platforms that support that). +void ComputeJitSupportFlags(); + // Get and set the current JIT context. JitContext* GetJitContext(); JitContext* MaybeGetJitContext(); diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 0a9fe0c67a..5154647588 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -8,6 +8,7 @@ #include +#include "builtin/ModuleObject.h" #include "gc/Marking.h" #include "jit/BaselineDebugModeOSR.h" #include "jit/BaselineFrame.h" @@ -18,12 +19,12 @@ #include "jit/JitcodeMap.h" #include "jit/JitRealm.h" #include "jit/JitSpewer.h" -#include "jit/MacroAssembler.h" #include "jit/PcScriptCache.h" #include "jit/Recover.h" #include "jit/Safepoints.h" #include "jit/Snapshots.h" #include "jit/VMFunctions.h" +#include "js/friend/DumpFunctions.h" // js::DumpObject, js::DumpValue #include "vm/ArgumentsObject.h" #include "vm/GeckoProfiler.h" #include "vm/Interpreter.h" @@ -2048,8 +2049,9 @@ void InlineFrameIterator::findNextFrame() { numActualArgs_ = GET_ARGC(pc_); } if (JSOp(*pc_) == JSOp::FunCall) { - MOZ_ASSERT(GET_ARGC(pc_) > 0); - numActualArgs_ = GET_ARGC(pc_) - 1; + if (numActualArgs_ > 0) { + numActualArgs_--; + } } else if (IsGetPropPC(pc_) || IsGetElemPC(pc_)) { numActualArgs_ = 0; } else if (IsSetPropPC(pc_)) { diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp index 6935cc02c0..87551d5efd 100644 --- a/js/src/jit/JitOptions.cpp +++ b/js/src/jit/JitOptions.cpp @@ -164,6 +164,21 @@ DefaultJitOptions::DefaultJitOptions() { // Duplicated in all.js - ensure both match. SET_DEFAULT(baselineJitWarmUpThreshold, 100); + // How many invocations or loop iterations are needed before functions + // are considered for trial inlining. + SET_DEFAULT(trialInliningWarmUpThreshold, 500); + + // The initial warm-up count for ICScripts created by trial inlining. + // + // Note: the difference between trialInliningInitialWarmUpCount and + // trialInliningWarmUpThreshold must be: + // + // * Small enough to allow inlining multiple levels deep before the outer + // script reaches its normalIonWarmUpThreshold. + // + // * Greater than inliningEntryThreshold or no scripts can be inlined. + SET_DEFAULT(trialInliningInitialWarmUpCount, 250); + // How many invocations or loop iterations are needed before functions // are compiled with the Ion compiler at OptimizationLevel::Normal. // Duplicated in all.js - ensure both match. @@ -199,7 +214,10 @@ DefaultJitOptions::DefaultJitOptions() { SET_DEFAULT(osrPcMismatchesBeforeRecompile, 6000); // The bytecode length limit for small function. - SET_DEFAULT(smallFunctionMaxBytecodeLength_, 130); + SET_DEFAULT(smallFunctionMaxBytecodeLength, 130); + + // The minimum entry count for an IC stub before it can be trial-inlined. + SET_DEFAULT(inliningEntryThreshold, 100); // An artificial testing limit for the maximum supported offset of // pc-relative jump and call instructions. @@ -301,7 +319,7 @@ DefaultJitOptions::DefaultJitOptions() { } bool DefaultJitOptions::isSmallFunction(JSScript* script) const { - return script->length() <= smallFunctionMaxBytecodeLength_; + return script->length() <= smallFunctionMaxBytecodeLength; } void DefaultJitOptions::enableGvn(bool enable) { disableGvn = !enable; } @@ -318,6 +336,28 @@ void DefaultJitOptions::setEagerIonCompilation() { fullIonWarmUpThreshold = 0; } +void DefaultJitOptions::setFastWarmUp() { + baselineInterpreterWarmUpThreshold = 4; + baselineJitWarmUpThreshold = 10; + trialInliningWarmUpThreshold = 14; + trialInliningInitialWarmUpCount = 12; + normalIonWarmUpThreshold = 30; + fullIonWarmUpThreshold = 65; + + inliningEntryThreshold = 2; + smallFunctionMaxBytecodeLength = 2000; +} + +void DefaultJitOptions::setWarpEnabled(bool enable) { +#ifdef NIGHTLY_BUILD + // WarpBuilder requires TI to be disabled and doesn't use optimization levels. + typeInference = !enable; + warpBuilder = enable; + disableOptimizationLevels = enable; + normalIonWarmUpThreshold = enable ? 1500 : 1000; +#endif +} + void DefaultJitOptions::setNormalIonWarmUpThreshold(uint32_t warmUpThreshold) { normalIonWarmUpThreshold = warmUpThreshold; diff --git a/js/src/jit/JitOptions.h b/js/src/jit/JitOptions.h index 2416b378e5..e72fc5fdc3 100644 --- a/js/src/jit/JitOptions.h +++ b/js/src/jit/JitOptions.h @@ -83,6 +83,8 @@ struct DefaultJitOptions { #endif uint32_t baselineInterpreterWarmUpThreshold; uint32_t baselineJitWarmUpThreshold; + uint32_t trialInliningWarmUpThreshold; + uint32_t trialInliningInitialWarmUpCount; uint32_t normalIonWarmUpThreshold; uint32_t fullIonWarmUpThreshold; uint32_t regexpWarmUpThreshold; @@ -90,7 +92,8 @@ struct DefaultJitOptions { uint32_t frequentBailoutThreshold; uint32_t maxStackArgs; uint32_t osrPcMismatchesBeforeRecompile; - uint32_t smallFunctionMaxBytecodeLength_; + uint32_t smallFunctionMaxBytecodeLength; + uint32_t inliningEntryThreshold; uint32_t jumpThreshold; uint32_t branchPruningHitCountFactor; uint32_t branchPruningInstFactor; @@ -128,6 +131,8 @@ struct DefaultJitOptions { void resetNormalIonWarmUpThreshold(); void resetFullIonWarmUpThreshold(); void enableGvn(bool val); + void setFastWarmUp(); + void setWarpEnabled(bool enable); bool eagerIonCompilation() const { return normalIonWarmUpThreshold == 0; } }; diff --git a/js/src/jit/JitRealm.h b/js/src/jit/JitRealm.h index 6569b9a873..7cdb73a126 100644 --- a/js/src/jit/JitRealm.h +++ b/js/src/jit/JitRealm.h @@ -116,6 +116,8 @@ class BaselineICFallbackCode { } }; +enum class ArgumentsRectifierKind { Normal, TrialInlining }; + enum class DebugTrapHandlerKind { Interpreter, Compiler, Count }; using EnterJitCode = void (*)(void*, unsigned int, Value*, InterpreterFrame*, @@ -159,9 +161,11 @@ class JitRuntime { // Generic bailout table; used if the bailout table overflows. WriteOnceData bailoutHandlerOffset_{0}; - // Argument-rectifying thunk, in the case of insufficient arguments passed - // to a function call site. + // Argument-rectifying thunks, in the case of insufficient arguments passed + // to a function call site. The return offset is used to rebuild stack frames + // when bailing out. WriteOnceData argumentsRectifierOffset_{0}; + WriteOnceData trialInliningArgumentsRectifierOffset_{0}; WriteOnceData argumentsRectifierReturnOffset_{0}; // Thunk that invalides an (Ion compiled) caller on the Ion stack. @@ -256,7 +260,8 @@ class JitRuntime { Label* profilerExitTail); void generateBailoutTailStub(MacroAssembler& masm, Label* bailoutTail); void generateEnterJIT(JSContext* cx, MacroAssembler& masm); - void generateArgumentsRectifier(MacroAssembler& masm); + void generateArgumentsRectifier(MacroAssembler& masm, + ArgumentsRectifierKind kind); BailoutTable generateBailoutTable(MacroAssembler& masm, Label* bailoutTail, uint32_t frameClass); void generateBailoutHandler(MacroAssembler& masm, Label* bailoutTail); @@ -353,7 +358,11 @@ class JitRuntime { TrampolinePtr getBailoutTable(const FrameSizeClass& frameClass) const; uint32_t getBailoutTableSize(const FrameSizeClass& frameClass) const; - TrampolinePtr getArgumentsRectifier() const { + TrampolinePtr getArgumentsRectifier( + ArgumentsRectifierKind kind = ArgumentsRectifierKind::Normal) const { + if (kind == ArgumentsRectifierKind::TrialInlining) { + return trampolineCode(trialInliningArgumentsRectifierOffset_); + } return trampolineCode(argumentsRectifierOffset_); } diff --git a/js/src/jit/JitScript.cpp b/js/src/jit/JitScript.cpp index 8e7d311bc5..e55235b28f 100644 --- a/js/src/jit/JitScript.cpp +++ b/js/src/jit/JitScript.cpp @@ -6,9 +6,10 @@ #include "mozilla/BinarySearch.h" #include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/Move.h" #include "mozilla/ScopeExit.h" +#include + #include "jit/BaselineIC.h" #include "jit/BytecodeAnalysis.h" #include "jit/IonScript.h" @@ -58,16 +59,15 @@ JitScript::JitScript(JSScript* script, Offset typeSetOffset, : profileString_(profileString), typeSetOffset_(typeSetOffset), bytecodeTypeMapOffset_(bytecodeTypeMapOffset), - endOffset_(endOffset) { + endOffset_(endOffset), + icScript_(script->getWarmUpCount(), typeSetOffset - offsetOfICScript(), + /*depth=*/0) { setTypesGeneration(script->zone()->types.generation); if (IsTypeInferenceEnabled()) { initElements(typeSetOffset, numTypeSets()); } - // Initialize the warm-up count from the count stored in the script. - warmUpCount_ = script->getWarmUpCount(); - // Ensure the baselineScript_ and ionScript_ fields match the BaselineDisabled // and IonDisabled script flags. if (!script->canBaselineCompile()) { @@ -118,6 +118,10 @@ bool JSScript::createJitScript(JSContext* cx) { static_assert(sizeof(StackTypeSet) % sizeof(uintptr_t) == 0, "Trailing arrays must be aligned properly"); + static_assert( + sizeof(JitScript) == offsetof(JitScript, icScript_) + sizeof(ICScript), + "icScript_ must be the last field"); + // Calculate allocation size. CheckedInt allocSize = sizeof(JitScript); allocSize += CheckedInt(numICEntries()) * sizeof(ICEntry); @@ -152,10 +156,14 @@ bool JSScript::createJitScript(JSContext* cx) { auto prepareForDestruction = mozilla::MakeScopeExit( [&] { jitScript->prepareForDestruction(cx->zone()); }); - if (!jitScript->initICEntriesAndBytecodeTypeMap(cx, this)) { + if (!jitScript->icScript()->initICEntries(cx, this)) { return false; } + if (IsTypeInferenceEnabled()) { + jitScript->initBytecodeTypeMap(this); + } + prepareForDestruction.release(); warmUpData_.initJitScript(jitScript.release()); AddCellMemory(this, allocSize.value(), MemoryUse::JitScript); @@ -232,6 +240,8 @@ void JitScript::CachedIonData::trace(JSTracer* trc) { } void JitScript::trace(JSTracer* trc) { + icScript_.trace(trc); + if (hasBaselineScript()) { baselineScript()->trace(trc); } @@ -244,6 +254,12 @@ void JitScript::trace(JSTracer* trc) { cachedIonData().trace(trc); } + if (hasInliningRoot()) { + inliningRoot()->trace(trc); + } +} + +void ICScript::trace(JSTracer* trc) { // Mark all IC stub codes hanging off the IC stub entries. for (size_t i = 0; i < numICEntries(); i++) { ICEntry& ent = icEntry(i); @@ -251,6 +267,65 @@ void JitScript::trace(JSTracer* trc) { } } +bool ICScript::addInlinedChild(JSContext* cx, UniquePtr child, + uint32_t pcOffset) { + MOZ_ASSERT(!hasInlinedChild(pcOffset)); + + if (!inlinedChildren_) { + inlinedChildren_ = cx->make_unique>(cx); + if (!inlinedChildren_) { + return false; + } + } + + // First reserve space in inlinedChildren_ to ensure that if the ICScript is + // added to the inlining root, it can also be added to inlinedChildren_. + CallSite callsite(child.get(), pcOffset); + if (!inlinedChildren_->reserve(inlinedChildren_->length() + 1)) { + return false; + } + if (!inliningRoot()->addInlinedScript(std::move(child))) { + return false; + } + inlinedChildren_->infallibleAppend(callsite); + return true; +} + +ICScript* ICScript::findInlinedChild(uint32_t pcOffset) { + for (auto& callsite : *inlinedChildren_) { + if (callsite.pcOffset_ == pcOffset) { + return callsite.callee_; + } + } + MOZ_CRASH("Inlined child expected at pcOffset"); +} + +void ICScript::removeInlinedChild(uint32_t pcOffset) { + MOZ_ASSERT(inliningRoot()); + inlinedChildren_->eraseIf([pcOffset](const CallSite& callsite) -> bool { + return callsite.pcOffset_ == pcOffset; + }); +} + +bool ICScript::hasInlinedChild(uint32_t pcOffset) { + if (!inlinedChildren_) { + return false; + } + for (auto& callsite : *inlinedChildren_) { + if (callsite.pcOffset_ == pcOffset) { + return true; + } + } + return false; +} + +void JitScript::resetWarmUpCount(uint32_t count) { + icScript_.resetWarmUpCount(count); + if (hasInliningRoot()) { + inliningRoot()->resetWarmUpCounts(count); + } +} + void JitScript::ensureProfileString(JSContext* cx, JSScript* script) { MOZ_ASSERT(cx->runtime()->geckoProfiler().enabled()); @@ -332,12 +407,12 @@ void JitScript::Destroy(Zone* zone, JitScript* script) { } struct ICEntries { - JitScript* const jitScript_; + ICScript* const icScript_; - explicit ICEntries(JitScript* jitScript) : jitScript_(jitScript) {} + explicit ICEntries(ICScript* icScript) : icScript_(icScript) {} - size_t numEntries() const { return jitScript_->numICEntries(); } - ICEntry& operator[](size_t index) const { return jitScript_->icEntry(index); } + size_t numEntries() const { return icScript_->numICEntries(); } + ICEntry& operator[](size_t index) const { return icScript_->icEntry(index); } }; static bool ComputeBinarySearchMid(ICEntries entries, uint32_t pcOffset, @@ -364,7 +439,7 @@ static bool ComputeBinarySearchMid(ICEntries entries, uint32_t pcOffset, loc); } -ICEntry* JitScript::maybeICEntryFromPCOffset(uint32_t pcOffset) { +ICEntry* ICScript::maybeICEntryFromPCOffset(uint32_t pcOffset) { // This method ignores prologue IC entries. There can be at most one // non-prologue IC per bytecode op. @@ -381,14 +456,14 @@ ICEntry* JitScript::maybeICEntryFromPCOffset(uint32_t pcOffset) { return &entry; } -ICEntry& JitScript::icEntryFromPCOffset(uint32_t pcOffset) { +ICEntry& ICScript::icEntryFromPCOffset(uint32_t pcOffset) { ICEntry* entry = maybeICEntryFromPCOffset(pcOffset); MOZ_RELEASE_ASSERT(entry); return *entry; } -ICEntry* JitScript::maybeICEntryFromPCOffset(uint32_t pcOffset, - ICEntry* prevLookedUpEntry) { +ICEntry* ICScript::maybeICEntryFromPCOffset(uint32_t pcOffset, + ICEntry* prevLookedUpEntry) { // Do a linear forward search from the last queried PC offset, or fallback to // a binary search if the last offset is too far away. if (prevLookedUpEntry && pcOffset >= prevLookedUpEntry->pcOffset() && @@ -408,14 +483,14 @@ ICEntry* JitScript::maybeICEntryFromPCOffset(uint32_t pcOffset, return maybeICEntryFromPCOffset(pcOffset); } -ICEntry& JitScript::icEntryFromPCOffset(uint32_t pcOffset, - ICEntry* prevLookedUpEntry) { +ICEntry& ICScript::icEntryFromPCOffset(uint32_t pcOffset, + ICEntry* prevLookedUpEntry) { ICEntry* entry = maybeICEntryFromPCOffset(pcOffset, prevLookedUpEntry); MOZ_RELEASE_ASSERT(entry); return *entry; } -ICEntry* JitScript::interpreterICEntryFromPCOffset(uint32_t pcOffset) { +ICEntry* ICScript::interpreterICEntryFromPCOffset(uint32_t pcOffset) { // We have to return the entry to store in BaselineFrame::interpreterICEntry // when resuming in the Baseline Interpreter at pcOffset. The bytecode op at // pcOffset does not necessarily have an ICEntry, so we want to return the @@ -444,7 +519,7 @@ void JitScript::purgeOptimizedStubs(JSScript* script) { MOZ_ASSERT(script->jitScript() == this); Zone* zone = script->zone(); - if (zone->isGCSweeping() && IsAboutToBeFinalizedDuringSweep(*script)) { + if (IsAboutToBeFinalizedUnbarriered(&script)) { // We're sweeping and the script is dead. Don't purge optimized stubs // because (1) accessing CacheIRStubInfo pointers in ICStubs is invalid // because we may have swept them already when we started (incremental) @@ -455,6 +530,13 @@ void JitScript::purgeOptimizedStubs(JSScript* script) { JitSpew(JitSpew_BaselineIC, "Purging optimized stubs"); + icScript()->purgeOptimizedStubs(zone); + if (hasInliningRoot()) { + inliningRoot()->purgeOptimizedStubs(zone); + } +} + +void ICScript::purgeOptimizedStubs(Zone* zone) { for (size_t i = 0; i < numICEntries(); i++) { ICEntry& entry = icEntry(i); ICStub* lastStub = entry.firstStub(); @@ -469,7 +551,11 @@ void JitScript::purgeOptimizedStubs(JSScript* script) { while (stub->next()) { if (!stub->allocatedInFallbackSpace()) { - lastStub->toFallbackStub()->unlinkStub(zone, prev, stub); + // Note: this is called when discarding JIT code, after invalidating + // all Warp code, so we don't need to check for that here. + lastStub->toFallbackStub()->clearUsedByTranspiler(); + lastStub->toFallbackStub()->unlinkStubDontInvalidateWarp(zone, prev, + stub); stub = stub->next(); continue; } @@ -614,7 +700,7 @@ void JitScript::setBaselineScriptImpl(JSScript* script, void JitScript::setBaselineScriptImpl(JSFreeOp* fop, JSScript* script, BaselineScript* baselineScript) { if (hasBaselineScript()) { - BaselineScript::writeBarrierPre(script->zone(), baselineScript_); + BaselineScript::preWriteBarrier(script->zone(), baselineScript_); fop->removeCellMemory(script, baselineScript_->allocBytes(), MemoryUse::BaselineScript); baselineScript_ = nullptr; @@ -643,7 +729,7 @@ void JitScript::setIonScriptImpl(JSFreeOp* fop, JSScript* script, !baselineScript()->hasPendingIonCompileTask()); if (hasIonScript()) { - IonScript::writeBarrierPre(script->zone(), ionScript_); + IonScript::preWriteBarrier(script->zone(), ionScript_); fop->removeCellMemory(script, ionScript_->allocBytes(), MemoryUse::IonScript); ionScript_ = nullptr; @@ -658,15 +744,17 @@ void JitScript::setIonScriptImpl(JSFreeOp* fop, JSScript* script, script->updateJitCodeRaw(fop->runtime()); } -#ifdef JS_STRUCTURED_SPEW -static bool GetStubEnteredCount(ICStub* stub, uint32_t* count) { +#if defined(JS_STRUCTURED_SPEW) || defined(JS_CACHEIR_SPEW) +bool jit::GetStubEnteredCount(ICStub* stub, uint32_t* count) { if (ICStub::IsCacheIRKind(stub->kind())) { *count = stub->getEnteredCount(); return true; } return false; } +#endif // JS_STRUCTURED_SPEW || JS_CACHEIR_SPEW +#ifdef JS_STRUCTURED_SPEW static bool HasEnteredCounters(ICEntry& entry) { ICStub* stub = entry.firstStub(); while (stub && !stub->isFallback()) { @@ -771,3 +859,52 @@ void jit::MarkActiveJitScripts(Zone* zone) { } } } + +void JitScript::initBytecodeTypeMap(JSScript* script) { + MOZ_ASSERT(IsTypeInferenceEnabled()); + MOZ_ASSERT(jit::IsBaselineInterpreterEnabled()); + MOZ_ASSERT(numICEntries() == script->numICEntries()); + + // Index of the next bytecode type map entry to initialize. + uint32_t typeMapIndex = 0; + uint32_t* const typeMap = bytecodeTypeMap(); + + // For JOF_TYPESET ops: initialize bytecode type map entries. + for (BytecodeLocation loc : js::AllBytecodesIterable(script)) { + JSOp op = loc.getOp(); + // Note: if the script is very large there will be more JOF_TYPESET ops + // than bytecode type sets. See JSScript::MaxBytecodeTypeSets. + if (BytecodeOpHasTypeSet(op) && + typeMapIndex < JSScript::MaxBytecodeTypeSets) { + typeMap[typeMapIndex] = loc.bytecodeToOffset(script); + typeMapIndex++; + } + } + MOZ_ASSERT(typeMapIndex == script->numBytecodeTypeSets()); +} + +InliningRoot* JitScript::getOrCreateInliningRoot(JSContext* cx, + JSScript* script) { + if (!inliningRoot_) { + inliningRoot_ = js::MakeUnique(cx, script); + if (!inliningRoot_) { + ReportOutOfMemory(cx); + return nullptr; + } + icScript_.inliningRoot_ = inliningRoot_.get(); + } + return inliningRoot_.get(); +} + +FallbackICStubSpace* ICScript::fallbackStubSpace() { + if (isInlined()) { + return inliningRoot_->fallbackStubSpace(); + } + return outerJitScript()->fallbackStubSpace(); +} + +JitScript* ICScript::outerJitScript() { + MOZ_ASSERT(!isInlined()); + uint8_t* ptr = reinterpret_cast(this); + return reinterpret_cast(ptr - JitScript::offsetOfICScript()); +} diff --git a/js/src/jit/JitScript.h b/js/src/jit/JitScript.h index 06985e6c02..5d3a580a94 100644 --- a/js/src/jit/JitScript.h +++ b/js/src/jit/JitScript.h @@ -9,8 +9,10 @@ #include "jstypes.h" #include "jit/BaselineIC.h" +#include "jit/TrialInlining.h" #include "js/UniquePtr.h" #include "util/TrailingArray.h" +#include "vm/EnvironmentObject.h" #include "vm/TypeInference.h" class JS_PUBLIC_API JSScript; @@ -52,6 +54,138 @@ static IonScript* const IonDisabledScriptPtr = static IonScript* const IonCompilingScriptPtr = reinterpret_cast(IonCompilingScript); +class JitScript; +class InliningRoot; + +/* [SMDOC] ICScript Lifetimes + * + * An ICScript owns an array of ICEntries, each of which owns a linked + * list of ICStubs. + * + * A JitScript contains an embedded ICScript. If it has done any trial + * inlining, it also owns an InliningRoot. The InliningRoot owns all + * of the ICScripts that have been created for inlining into the + * corresponding JitScript. This ties the lifetime of the inlined + * ICScripts to the lifetime of the JitScript itself. + * + * We store pointers to ICScripts in two other places: on the stack in + * BaselineFrame, and in IC stubs for CallInlinedFunction. + * + * The ICScript pointer in a BaselineFrame either points to the + * ICScript embedded in the JitScript for that frame, or to an inlined + * ICScript owned by a caller. In each case, there must be a frame on + * the stack corresponding to the JitScript that owns the current + * ICScript, which will keep the ICScript alive. + * + * Each ICStub is owned by an ICScript and, indirectly, a + * JitScript. An ICStub that uses CallInlinedFunction contains an + * ICScript for use by the callee. The ICStub and the callee ICScript + * are always owned by the same JitScript, so the callee ICScript will + * not be freed while the ICStub is alive. + * + * The lifetime of an ICScript is independent of the lifetimes of the + * BaselineScript and IonScript/WarpScript to which it + * corresponds. They can be destroyed and recreated, and the ICScript + * will remain valid. + */ + +class alignas(uintptr_t) ICScript final : public TrailingArray { + public: + ICScript(uint32_t warmUpCount, Offset endOffset, uint32_t depth, + InliningRoot* inliningRoot = nullptr) + : inliningRoot_(inliningRoot), + warmUpCount_(warmUpCount), + endOffset_(endOffset), + depth_(depth) {} + + bool isInlined() const { return depth_ > 0; } + + MOZ_MUST_USE bool initICEntries(JSContext* cx, JSScript* script); + + ICEntry& icEntry(size_t index) { + MOZ_ASSERT(index < numICEntries()); + return icEntries()[index]; + } + + InliningRoot* inliningRoot() const { return inliningRoot_; } + uint32_t depth() const { return depth_; } + + void resetWarmUpCount(uint32_t count) { warmUpCount_ = count; } + + static constexpr size_t offsetOfFirstStub(uint32_t entryIndex) { + return sizeof(ICScript) + entryIndex * sizeof(ICEntry) + + ICEntry::offsetOfFirstStub(); + } + + static constexpr Offset offsetOfWarmUpCount() { + return offsetof(ICScript, warmUpCount_); + } + static constexpr Offset offsetOfDepth() { return offsetof(ICScript, depth_); } + + static constexpr Offset offsetOfICEntries() { return sizeof(ICScript); } + uint32_t numICEntries() const { + return numElements(icEntriesOffset(), endOffset()); + } + + ICEntry* interpreterICEntryFromPCOffset(uint32_t pcOffset); + + ICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset); + ICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset, + ICEntry* prevLookedUpEntry); + + ICEntry& icEntryFromPCOffset(uint32_t pcOffset); + ICEntry& icEntryFromPCOffset(uint32_t pcOffset, ICEntry* prevLookedUpEntry); + + MOZ_MUST_USE bool addInlinedChild(JSContext* cx, + js::UniquePtr child, + uint32_t pcOffset); + ICScript* findInlinedChild(uint32_t pcOffset); + void removeInlinedChild(uint32_t pcOffset); + bool hasInlinedChild(uint32_t pcOffset); + + FallbackICStubSpace* fallbackStubSpace(); + void purgeOptimizedStubs(Zone* zone); + + void trace(JSTracer* trc); + + private: + class CallSite { + public: + CallSite(ICScript* callee, uint32_t pcOffset) + : callee_(callee), pcOffset_(pcOffset) {} + ICScript* callee_; + uint32_t pcOffset_; + }; + + // If this ICScript was created for trial inlining or has another + // ICScript inlined into it, a pointer to the root of the inlining + // tree. Otherwise, nullptr. + InliningRoot* inliningRoot_ = nullptr; + + // ICScripts that have been inlined into this ICScript. + js::UniquePtr> inlinedChildren_; + + // Number of times this copy of the script has been called or has had + // backedges taken. Reset if the script's JIT code is forcibly discarded. + // See also the ScriptWarmUpData class. + mozilla::Atomic warmUpCount_ = {}; + + // The size of this allocation. + Offset endOffset_; + + // The inlining depth of this ICScript. 0 for the inlining root. + uint32_t depth_; + + Offset icEntriesOffset() const { return offsetOfICEntries(); } + Offset endOffset() const { return endOffset_; } + + ICEntry* icEntries() { return offsetToPointer(icEntriesOffset()); } + + JitScript* outerJitScript(); + + friend class JitScript; +}; + // [SMDOC] JitScript // // JitScript stores type inference data, Baseline ICs and other JIT-related data @@ -59,8 +193,10 @@ static IonScript* const IonCompilingScriptPtr = // // IC Data // ======= -// All IC data for Baseline (Interpreter and JIT) is stored in JitScript. Ion -// has its own IC chains stored in IonScript. +// All IC data for Baseline (Interpreter and JIT) is stored in an ICScript. Each +// JitScript contains an ICScript as the last field. Additional free-standing +// ICScripts may be created during trial inlining. Ion has its own IC chains +// stored in IonScript. // // For each IC we store an ICEntry, which points to the first ICStub in the // chain. Note that multiple stubs in the same zone can share Baseline IC code. @@ -72,19 +208,19 @@ static IonScript* const IonCompilingScriptPtr = // because the JitScript can be reused when we have to recompile the // BaselineScript. // -// JitScript contains the following IC data structures: +// The JitScript contains a fallback stub space. This stores all fallback stubs +// and the "can GC" stubs. These stubs are never purged before destroying the +// JitScript. Other stubs are stored in the optimized stub space stored in +// JitZone and can be purged more eagerly. See JitScript::purgeOptimizedStubs. // -// * Fallback stub space: this stores all fallback stubs and the "can GC" stubs. -// These stubs are never purged before destroying the JitScript. (Other stubs -// are stored in the optimized stub space stored in JitZone and can be -// discarded more eagerly. See JitScript::purgeOptimizedStubs.) -// -// * List of IC entries, in the following order: +// An ICScript contains a list of IC entries, in the following order: // // - Type monitor IC for |this|. // - Type monitor IC for each formal argument. // - IC for each JOF_IC bytecode op. // +// The ICScript also contains the warmUpCount for the script. +// // Type Inference Data // =================== // JitScript also contains Type Inference data, most importantly: @@ -101,13 +237,15 @@ static IonScript* const IonCompilingScriptPtr = // // Memory Layout // ============= -// JitScript has various trailing (variable-length) arrays. The memory layout is -// as follows: +// JitScript contains an ICScript as the last field. ICScript has a trailing +// (variable length) ICEntry array. Following the ICScript, JitScript has +// several additional trailing arrays. The memory layout is as follows: // // Item | Offset // ------------------------+------------------------ // JitScript | 0 -// ICEntry[] | icEntriesOffset() +// -->ICScript (field) | +// ICEntry[] | icEntriesOffset() // StackTypeSet[] | typeSetOffset() // uint32_t[] | bytecodeTypeMapOffset() // (= bytecode type map) | @@ -177,11 +315,6 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { // IonCompilingScriptPtr or a valid IonScript*. IonScript* ionScript_ = nullptr; - // Number of times the script has been called or has had backedges taken. - // Reset if the script's JIT code is forcibly discarded. See also the - // ScriptWarmUpData class. - mozilla::Atomic warmUpCount_ = {}; - // Offset of the StackTypeSet array. Offset typeSetOffset_ = 0; @@ -211,9 +344,15 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { // inlined into another script. This is cleared when the script's type // information or caches are cleared. bool ionCompiledOrInlined : 1; + + // True if this script entered Ion via OSR at a loop header. + bool hadIonOSR : 1; }; Flags flags_ = {}; // Zero-initialize flags. + js::UniquePtr inliningRoot_; + + ICScript icScript_; // End of fields. Offset icEntriesOffset() const { return offsetOfICEntries(); } @@ -221,7 +360,7 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { Offset bytecodeTypeMapOffset() const { return bytecodeTypeMapOffset_; } Offset endOffset() const { return endOffset_; } - ICEntry* icEntries() { return offsetToPointer(icEntriesOffset()); } + ICEntry* icEntries() { return icScript_.icEntries(); } StackTypeSet* typeArrayDontCheckGeneration() { MOZ_ASSERT(IsTypeInferenceEnabled()); @@ -262,8 +401,7 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { } #endif - MOZ_MUST_USE bool initICEntriesAndBytecodeTypeMap(JSContext* cx, - JSScript* script); + void initBytecodeTypeMap(JSScript* script); MOZ_MUST_USE bool ensureHasCachedIonData(JSContext* cx, HandleScript script); @@ -283,6 +421,9 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { void clearIonCompiledOrInlined() { flags_.ionCompiledOrInlined = false; } bool ionCompiledOrInlined() const { return flags_.ionCompiledOrInlined; } + void setHadIonOSR() { flags_.hadIonOSR = true; } + bool hadIonOSR() const { return flags_.hadIonOSR; } + RecompileInfoVector* maybeInlinedCompilations( const js::AutoSweepJitScript& sweep) { MOZ_ASSERT(sweep.jitScript() == this); @@ -301,9 +442,7 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { return inlinedCompilations.append(info); } - uint32_t numICEntries() const { - return numElements(icEntriesOffset(), typeSetOffset()); - } + uint32_t numICEntries() const { return icScript_.numICEntries(); } uint32_t numTypeSets() const { MOZ_ASSERT(IsTypeInferenceEnabled()); return numElements(typeSetOffset(), bytecodeTypeMapOffset()); @@ -411,11 +550,16 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { static constexpr size_t offsetOfIonScript() { return offsetof(JitScript, ionScript_); } + static constexpr size_t offsetOfICScript() { + return offsetof(JitScript, icScript_); + } static constexpr size_t offsetOfWarmUpCount() { - return offsetof(JitScript, warmUpCount_); + return offsetOfICScript() + ICScript::offsetOfWarmUpCount(); } - uint32_t warmUpCount() const { return warmUpCount_; } + uint32_t warmUpCount() const { return icScript_.warmUpCount_; } + void incWarmUpCount(uint32_t amount) { icScript_.warmUpCount_ += amount; } + void resetWarmUpCount(uint32_t count); #ifdef DEBUG void printTypes(JSContext* cx, HandleScript script); @@ -442,25 +586,36 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { *fallbackStubs += fallbackStubSpace_.sizeOfExcludingThis(mallocSizeOf); } - ICEntry& icEntry(size_t index) { - MOZ_ASSERT(index < numICEntries()); - return icEntries()[index]; - } + ICEntry& icEntry(size_t index) { return icScript_.icEntry(index); } + // Used to inform IonBuilder that a getter has been used and we must + // use a type barrier. void noteAccessedGetter(uint32_t pcOffset); + // Used to inform IonBuilder that a SetElem has written to out-of-bounds + // indices, to determine whether we need a hole check. void noteHasDenseAdd(uint32_t pcOffset); void trace(JSTracer* trc); void purgeOptimizedStubs(JSScript* script); - ICEntry* interpreterICEntryFromPCOffset(uint32_t pcOffset); + ICEntry* interpreterICEntryFromPCOffset(uint32_t pcOffset) { + return icScript_.interpreterICEntryFromPCOffset(pcOffset); + } - ICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset); + ICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset) { + return icScript_.maybeICEntryFromPCOffset(pcOffset); + } ICEntry* maybeICEntryFromPCOffset(uint32_t pcOffset, - ICEntry* prevLookedUpEntry); + ICEntry* prevLookedUpEntry) { + return icScript_.maybeICEntryFromPCOffset(pcOffset, prevLookedUpEntry); + } - ICEntry& icEntryFromPCOffset(uint32_t pcOffset); - ICEntry& icEntryFromPCOffset(uint32_t pcOffset, ICEntry* prevLookedUpEntry); + ICEntry& icEntryFromPCOffset(uint32_t pcOffset) { + return icScript_.icEntryFromPCOffset(pcOffset); + }; + ICEntry& icEntryFromPCOffset(uint32_t pcOffset, ICEntry* prevLookedUpEntry) { + return icScript_.icEntryFromPCOffset(pcOffset, prevLookedUpEntry); + } MOZ_MUST_USE bool addDependentWasmImport(JSContext* cx, wasm::Instance& instance, @@ -575,6 +730,12 @@ class alignas(uintptr_t) JitScript final : public TrailingArray { MOZ_ASSERT(isIonCompilingOffThread()); setIonScriptImpl(script, nullptr); } + ICScript* icScript() { return &icScript_; } + + bool hasInliningRoot() const { return !!inliningRoot_; } + InliningRoot* inliningRoot() const { return inliningRoot_.get(); } + InliningRoot* getOrCreateInliningRoot(JSContext* cx, JSScript* script); + void clearInliningRoot() { inliningRoot_.reset(); } }; // Ensures no JitScripts are purged in the current zone. @@ -594,6 +755,10 @@ class MOZ_RAII AutoKeepJitScripts { // during GC. void MarkActiveJitScripts(Zone* zone); +#if defined(JS_STRUCTURED_SPEW) || defined(JS_CACHEIR_SPEW) +bool GetStubEnteredCount(ICStub* stub, uint32_t* count); +#endif + #ifdef JS_STRUCTURED_SPEW void JitSpewBaselineICStats(JSScript* script, const char* dumpReason); #endif diff --git a/js/src/jit/JitSpewer.cpp b/js/src/jit/JitSpewer.cpp index a39a23660c..5baf550406 100644 --- a/js/src/jit/JitSpewer.cpp +++ b/js/src/jit/JitSpewer.cpp @@ -160,8 +160,7 @@ bool IonSpewer::init() { if (usePid && *usePid != 0) { uint32_t pid = getpid(); size_t len; - len = snprintf(jsonBuffer, bufferLength, - JIT_SPEW_DIR "/ion%" PRIu32 ".json", pid); + len = SprintfLiteral(jsonBuffer, JIT_SPEW_DIR "/ion%" PRIu32 ".json", pid); if (bufferLength <= len) { fprintf(stderr, "Warning: IonSpewer::init: Cannot serialize file name."); return false; @@ -373,14 +372,11 @@ static void PrintHelpAndExit(int status = 0) { " logs-sync Same as logs, but flushes between each pass (sync. " "compiled functions only).\n" " profiling Profiling-related information\n" - " trackopts Optimization tracking information gathered by the " - "Gecko profiler. " - "(Note: call enableGeckoProfiling() in your script to enable it).\n" - " trackopts-ext Encoding information about optimization tracking\n" " dump-mir-expr Dump the MIR expressions\n" " scriptstats Tracelogger summary stats\n" " warp-snapshots WarpSnapshots created by WarpOracle\n" " warp-transpiler Warp CacheIR transpiler\n" + " warp-trial-inlining Trial inlining for Warp\n" " all Everything\n" "\n" " bl-aborts Baseline compiler abort messages\n" @@ -481,6 +477,8 @@ void jit::CheckLogging() { EnableChannel(JitSpew_WarpSnapshots); } else if (IsFlag(found, "warp-transpiler")) { EnableChannel(JitSpew_WarpTranspiler); + } else if (IsFlag(found, "warp-trial-inlining")) { + EnableChannel(JitSpew_WarpTrialInlining); } else if (IsFlag(found, "all")) { LoggingBits = uint64_t(-1); } else if (IsFlag(found, "bl-aborts")) { diff --git a/js/src/jit/JitSpewer.h b/js/src/jit/JitSpewer.h index 7009e54d45..e319f216ae 100644 --- a/js/src/jit/JitSpewer.h +++ b/js/src/jit/JitSpewer.h @@ -103,7 +103,9 @@ namespace jit { /* Generated WarpSnapshots */ \ _(WarpSnapshots) \ /* CacheIR transpiler logging */ \ - _(WarpTranspiler) + _(WarpTranspiler) \ + /* Trial inlining for Warp */ \ + _(WarpTrialInlining) enum JitSpewChannel { #define JITSPEW_CHANNEL(name) JitSpew_##name, diff --git a/js/src/jit/KnownClass.cpp b/js/src/jit/KnownClass.cpp new file mode 100644 index 0000000000..b27036cb4e --- /dev/null +++ b/js/src/jit/KnownClass.cpp @@ -0,0 +1,103 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/KnownClass.h" + +#include "jit/MIR.h" +#include "vm/ArrayObject.h" +#include "vm/Iteration.h" +#include "vm/JSFunction.h" +#include "vm/PlainObject.h" // js::PlainObject +#include "vm/RegExpObject.h" + +using namespace js; +using namespace js::jit; + +KnownClass jit::GetObjectKnownClass(const MDefinition* def) { + MOZ_ASSERT(def->type() == MIRType::Object); + + switch (def->op()) { + case MDefinition::Opcode::NewArray: + case MDefinition::Opcode::NewArrayCopyOnWrite: + return KnownClass::Array; + + case MDefinition::Opcode::NewObject: + case MDefinition::Opcode::CreateThis: + case MDefinition::Opcode::CreateThisWithTemplate: + return KnownClass::PlainObject; + + case MDefinition::Opcode::Lambda: + case MDefinition::Opcode::LambdaArrow: + case MDefinition::Opcode::FunctionWithProto: + return KnownClass::Function; + + case MDefinition::Opcode::RegExp: + return KnownClass::RegExp; + + case MDefinition::Opcode::NewIterator: + switch (def->toNewIterator()->type()) { + case MNewIterator::ArrayIterator: + return KnownClass::ArrayIterator; + case MNewIterator::StringIterator: + return KnownClass::StringIterator; + case MNewIterator::RegExpStringIterator: + return KnownClass::RegExpStringIterator; + } + MOZ_CRASH("unreachable"); + + case MDefinition::Opcode::Phi: { + if (def->numOperands() == 0) { + return KnownClass::None; + } + + MDefinition* op = def->getOperand(0); + // Check for Phis to avoid recursion for now. + if (op->isPhi()) { + return KnownClass::None; + } + + KnownClass known = GetObjectKnownClass(op); + if (known == KnownClass::None) { + return KnownClass::None; + } + + for (size_t i = 1; i < def->numOperands(); i++) { + op = def->getOperand(i); + if (op->isPhi() || GetObjectKnownClass(op) != known) { + return KnownClass::None; + } + } + + return known; + } + + default: + break; + } + + return KnownClass::None; +} + +const JSClass* jit::GetObjectKnownJSClass(const MDefinition* def) { + switch (GetObjectKnownClass(def)) { + case KnownClass::PlainObject: + return &PlainObject::class_; + case KnownClass::Array: + return &ArrayObject::class_; + case KnownClass::Function: + return &JSFunction::class_; + case KnownClass::RegExp: + return &RegExpObject::class_; + case KnownClass::ArrayIterator: + return &ArrayIteratorObject::class_; + case KnownClass::StringIterator: + return &StringIteratorObject::class_; + case KnownClass::RegExpStringIterator: + return &RegExpStringIteratorObject::class_; + case KnownClass::None: + break; + } + + return nullptr; +} diff --git a/js/src/jit/KnownClass.h b/js/src/jit/KnownClass.h new file mode 100644 index 0000000000..0b74dda176 --- /dev/null +++ b/js/src/jit/KnownClass.h @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 jit_KnownClass_h +#define jit_KnownClass_h + +#include "jspubtd.h" + +namespace js { +namespace jit { + +class MDefinition; + +// Users of this enum often can't handle Proxy and Wrapper classes, +// as well as non-Function callables. +enum class KnownClass { + PlainObject, + Array, + Function, + RegExp, + ArrayIterator, + StringIterator, + RegExpStringIterator, + None +}; + +KnownClass GetObjectKnownClass(const MDefinition* def); +const JSClass* GetObjectKnownJSClass(const MDefinition* def); + +} // namespace jit +} // namespace js + +#endif // jit_KnownClass_h diff --git a/js/src/jit/Linker.h b/js/src/jit/Linker.h index c1f5e1550a..bcf6df7c39 100644 --- a/js/src/jit/Linker.h +++ b/js/src/jit/Linker.h @@ -15,6 +15,8 @@ namespace js { namespace jit { +class MacroAssembler; + class Linker { MacroAssembler& masm; mozilla::Maybe awjcf; diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 173bc7c5a1..a95ed42371 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -14,6 +14,7 @@ #include "jit/LIR.h" #include "jit/MIR.h" #include "jit/MIRGraph.h" +#include "js/experimental/JitInfo.h" // JSJitInfo #include "util/Memory.h" #include "jit/shared/Lowering-shared-inl.h" @@ -40,16 +41,6 @@ LBoxAllocation LIRGenerator::useBoxAtStart(MDefinition* mir, return useBox(mir, policy, /* useAtStart = */ true); } -void LIRGenerator::visitCloneLiteral(MCloneLiteral* ins) { - MOZ_ASSERT(ins->type() == MIRType::Object); - MOZ_ASSERT(ins->input()->type() == MIRType::Object); - - LCloneLiteral* lir = - new (alloc()) LCloneLiteral(useRegisterAtStart(ins->input())); - defineReturn(lir, ins); - assignSafepoint(lir, ins); -} - void LIRGenerator::visitParameter(MParameter* param) { ptrdiff_t offset; if (param->index() == MParameter::THIS_SLOT) { @@ -308,10 +299,10 @@ void LIRGenerator::visitCreateThis(MCreateThis* ins) { } void LIRGenerator::visitCreateArgumentsObject(MCreateArgumentsObject* ins) { - LAllocation callObj = useFixedAtStart(ins->getCallObject(), CallTempReg0); + LAllocation callObj = useRegisterAtStart(ins->getCallObject()); LCreateArgumentsObject* lir = new (alloc()) - LCreateArgumentsObject(callObj, tempFixed(CallTempReg1), - tempFixed(CallTempReg2), tempFixed(CallTempReg3)); + LCreateArgumentsObject(callObj, tempFixed(CallTempReg0), + tempFixed(CallTempReg1), tempFixed(CallTempReg2)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -330,6 +321,28 @@ void LIRGenerator::visitSetArgumentsObjectArg(MSetArgumentsObjectArg* ins) { add(lir, ins); } +void LIRGenerator::visitLoadArgumentsObjectArg(MLoadArgumentsObjectArg* ins) { + MDefinition* argsObj = ins->getArgsObject(); + MOZ_ASSERT(argsObj->type() == MIRType::Object); + + MDefinition* index = ins->index(); + MOZ_ASSERT(index->type() == MIRType::Int32); + + auto* lir = new (alloc()) + LLoadArgumentsObjectArg(useRegister(argsObj), useRegister(index), temp()); + assignSnapshot(lir, BailoutKind::ArgumentsObjectAccess); + defineBox(lir, ins); +} + +void LIRGenerator::visitArgumentsObjectLength(MArgumentsObjectLength* ins) { + MDefinition* argsObj = ins->getArgsObject(); + MOZ_ASSERT(argsObj->type() == MIRType::Object); + + auto* lir = new (alloc()) LArgumentsObjectLength(useRegister(argsObj)); + assignSnapshot(lir, BailoutKind::ArgumentsObjectAccess); + define(lir, ins); +} + void LIRGenerator::visitReturnFromCtor(MReturnFromCtor* ins) { LReturnFromCtor* lir = new (alloc()) LReturnFromCtor(useBox(ins->getValue()), useRegister(ins->getObject())); @@ -443,15 +456,14 @@ void LIRGenerator::visitCall(MCall* call) { lir = new (alloc()) LCallNative(tempFixed(cxReg), tempFixed(numReg), tempFixed(vpReg), tempFixed(tmpReg)); } else { - lir = new (alloc()) - LCallKnown(useFixedAtStart(call->getCallee(), CallTempReg0), - tempFixed(CallTempReg2)); + lir = new (alloc()) LCallKnown(useRegisterAtStart(call->getCallee()), + tempFixed(CallTempReg0)); } } else { // Call anything, using the most generic code. lir = new (alloc()) - LCallGeneric(useFixedAtStart(call->getCallee(), CallTempReg0), - tempFixed(CallTempReg1), tempFixed(CallTempReg2)); + LCallGeneric(useRegisterAtStart(call->getCallee()), + tempFixed(CallTempReg0), tempFixed(CallTempReg1)); } defineReturn(lir, call); assignSafepoint(lir, call); @@ -472,7 +484,7 @@ void LIRGenerator::visitApplyArgs(MApplyArgs* apply) { tempFixed(CallTempReg2)); // stack counter register // Bailout is needed in the case of too many values in the arguments array. - assignSnapshot(lir, Bailout_TooManyArguments); + assignSnapshot(lir, BailoutKind::TooManyArguments); defineReturn(lir, apply); assignSafepoint(lir, apply); @@ -494,7 +506,7 @@ void LIRGenerator::visitApplyArray(MApplyArray* apply) { // Bailout is needed in the case of too many values in the array, or empty // space at the end of the array. - assignSnapshot(lir, Bailout_TooManyArguments); + assignSnapshot(lir, BailoutKind::TooManyArguments); defineReturn(lir, apply); assignSafepoint(lir, apply); @@ -519,7 +531,7 @@ void LIRGenerator::visitConstructArray(MConstructArray* mir) { // Bailout is needed in the case of too many values in the array, or empty // space at the end of the array. - assignSnapshot(lir, Bailout_TooManyArguments); + assignSnapshot(lir, BailoutKind::TooManyArguments); defineReturn(lir, mir); assignSafepoint(lir, mir); @@ -538,10 +550,20 @@ void LIRGenerator::visitUnreachable(MUnreachable* unreachable) { void LIRGenerator::visitEncodeSnapshot(MEncodeSnapshot* mir) { LEncodeSnapshot* lir = new (alloc()) LEncodeSnapshot(); - assignSnapshot(lir, Bailout_Inevitable); + assignSnapshot(lir, BailoutKind::Inevitable); add(lir, mir); } +void LIRGenerator::visitUnreachableResult(MUnreachableResult* mir) { + if (mir->type() == MIRType::Value) { + auto* lir = new (alloc()) LUnreachableResultV(); + defineBox(lir, mir); + } else { + auto* lir = new (alloc()) LUnreachableResultT(); + define(lir, mir); + } +} + void LIRGenerator::visitAssertFloat32(MAssertFloat32* assertion) { MIRType type = assertion->input()->type(); DebugOnly checkIsFloat32 = assertion->mustBeFloat32(); @@ -564,12 +586,12 @@ void LIRGenerator::visitGetDynamicName(MGetDynamicName* ins) { MDefinition* name = ins->getName(); MOZ_ASSERT(name->type() == MIRType::String); - LGetDynamicName* lir = new (alloc()) LGetDynamicName( - useFixedAtStart(envChain, CallTempReg0), - useFixedAtStart(name, CallTempReg1), tempFixed(CallTempReg2), - tempFixed(CallTempReg3), tempFixed(CallTempReg4)); + LGetDynamicName* lir = new (alloc()) + LGetDynamicName(useRegisterAtStart(envChain), useRegisterAtStart(name), + tempFixed(CallTempReg0), tempFixed(CallTempReg1), + tempFixed(CallTempReg2)); - assignSnapshot(lir, Bailout_DynamicNameNotFound); + assignSnapshot(lir, BailoutKind::DynamicNameNotFound); defineReturn(lir, ins); } @@ -898,10 +920,6 @@ void LIRGenerator::visitTest(MTest* test) { } } -void LIRGenerator::visitGotoWithFake(MGotoWithFake* gotoWithFake) { - add(new (alloc()) LGoto(gotoWithFake->target())); -} - void LIRGenerator::visitFunctionDispatch(MFunctionDispatch* ins) { LFunctionDispatch* lir = new (alloc()) LFunctionDispatch(useRegister(ins->input())); @@ -1241,7 +1259,7 @@ void LIRGenerator::lowerShiftOp(JSOp op, MShiftInstruction* ins) { LShiftI* lir = new (alloc()) LShiftI(op); if (op == JSOp::Ursh) { if (ins->toUrsh()->fallible()) { - assignSnapshot(lir, Bailout_OverflowInvalidate); + assignSnapshot(lir, BailoutKind::OverflowInvalidate); } } lowerForShift(lir, ins, lhs, rhs); @@ -1304,7 +1322,7 @@ void LIRGenerator::visitFloor(MFloor* ins) { lir = new (alloc()) LFloorF(useRegister(ins->input())); } - assignSnapshot(lir, Bailout_Round); + assignSnapshot(lir, BailoutKind::Round); define(lir, ins); } @@ -1319,7 +1337,7 @@ void LIRGenerator::visitCeil(MCeil* ins) { lir = new (alloc()) LCeilF(useRegister(ins->input())); } - assignSnapshot(lir, Bailout_Round); + assignSnapshot(lir, BailoutKind::Round); define(lir, ins); } @@ -1334,7 +1352,7 @@ void LIRGenerator::visitRound(MRound* ins) { lir = new (alloc()) LRoundF(useRegister(ins->input()), tempFloat32()); } - assignSnapshot(lir, Bailout_Round); + assignSnapshot(lir, BailoutKind::Round); define(lir, ins); } @@ -1349,7 +1367,7 @@ void LIRGenerator::visitTrunc(MTrunc* ins) { lir = new (alloc()) LTruncF(useRegister(ins->input())); } - assignSnapshot(lir, Bailout_Round); + assignSnapshot(lir, BailoutKind::Round); define(lir, ins); } @@ -1405,7 +1423,7 @@ void LIRGenerator::visitAbs(MAbs* ins) { lir = new (alloc()) LAbsI(useRegisterAtStart(num)); // needed to handle abs(INT32_MIN) if (ins->fallible()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } break; case MIRType::Float32: @@ -1543,7 +1561,7 @@ void LIRGenerator::visitPow(MPow* ins) { auto* lir = new (alloc()) LPowII(useRegister(input), useRegister(power), temp(), temp()); - assignSnapshot(lir, Bailout_PrecisionLoss); + assignSnapshot(lir, BailoutKind::PrecisionLoss); define(lir, ins); return; } @@ -1555,11 +1573,9 @@ void LIRGenerator::visitPow(MPow* ins) { LInstruction* lir; if (power->type() == MIRType::Int32) { - // Note: useRegisterAtStart here is safe, the temp is a GP register so - // it will never get the same register. - lir = new (alloc()) - LPowI(useRegisterAtStart(input), useFixedAtStart(power, CallTempReg1), - tempFixed(CallTempReg0)); + lir = + new (alloc()) LPowI(useRegisterAtStart(input), + useRegisterAtStart(power), tempFixed(CallTempReg0)); } else { lir = new (alloc()) LPowD(useRegisterAtStart(input), @@ -1583,7 +1599,7 @@ void LIRGenerator::visitSign(MSign* ins) { MOZ_ASSERT(ins->input()->type() == MIRType::Double); auto* lir = new (alloc()) LSignDI(useRegister(ins->input()), tempDouble()); - assignSnapshot(lir, Bailout_PrecisionLoss); + assignSnapshot(lir, BailoutKind::PrecisionLoss); define(lir, ins); } } @@ -1594,7 +1610,6 @@ void LIRGenerator::visitMathFunction(MMathFunction* ins) { LInstruction* lir; if (ins->type() == MIRType::Double) { - // Note: useRegisterAtStart is safe here, the temp is not a FP register. lir = new (alloc()) LMathFunctionD(useRegisterAtStart(ins->input()), tempFixed(CallTempReg0)); } else { @@ -1654,7 +1669,7 @@ void LIRGenerator::visitAdd(MAdd* ins) { LAddI* lir = new (alloc()) LAddI; if (ins->fallible()) { - assignSnapshot(lir, Bailout_OverflowInvalidate); + assignSnapshot(lir, BailoutKind::OverflowInvalidate); } lowerForALU(lir, ins, lhs, rhs); @@ -1699,7 +1714,7 @@ void LIRGenerator::visitSub(MSub* ins) { LSubI* lir = new (alloc()) LSubI; if (ins->fallible()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } lowerForALU(lir, ins, lhs, rhs); @@ -1850,7 +1865,6 @@ void LIRGenerator::visitMod(MMod* ins) { LDefinition maybeTemp = gen->compilingWasm() ? LDefinition::BogusTemp() : tempFixed(CallTempReg0); - // Note: useRegisterAtStart is safe here, the temp is not a FP register. LModD* lir = new (alloc()) LModD(useRegisterAtStart(ins->lhs()), useRegisterAtStart(ins->rhs()), maybeTemp); defineReturn(lir, ins); @@ -1877,8 +1891,8 @@ void LIRGenerator::visitConcat(MConcat* ins) { } void LIRGenerator::visitCharCodeAt(MCharCodeAt* ins) { - MDefinition* str = ins->getOperand(0); - MDefinition* idx = ins->getOperand(1); + MDefinition* str = ins->string(); + MDefinition* idx = ins->index(); MOZ_ASSERT(str->type() == MIRType::String); MOZ_ASSERT(idx->type() == MIRType::Int32); @@ -1906,7 +1920,7 @@ void LIRGenerator::visitFromCodePoint(MFromCodePoint* ins) { LFromCodePoint* lir = new (alloc()) LFromCodePoint(useRegister(codePoint), temp(), temp()); - assignSnapshot(lir, Bailout_BoundsCheck); + assignSnapshot(lir, BailoutKind::InvalidCodePoint); define(lir, ins); assignSafepoint(lir, ins); } @@ -1924,7 +1938,7 @@ void LIRGenerator::visitStart(MStart* start) { LStart* lir = new (alloc()) LStart; // Create a snapshot that captures the initial state of the function. - assignSnapshot(lir, Bailout_ArgumentCheck); + assignSnapshot(lir, BailoutKind::ArgumentCheck); if (start->block()->graph().entryBlock() == start->block()) { lirGraph_.setEntrySnapshot(lir->snapshot()); } @@ -1974,7 +1988,7 @@ void LIRGenerator::visitToDouble(MToDouble* convert) { switch (opd->type()) { case MIRType::Value: { LValueToDouble* lir = new (alloc()) LValueToDouble(useBox(opd)); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, convert); break; } @@ -2027,7 +2041,7 @@ void LIRGenerator::visitToFloat32(MToFloat32* convert) { switch (opd->type()) { case MIRType::Value: { LValueToFloat32* lir = new (alloc()) LValueToFloat32(useBox(opd)); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, convert); break; } @@ -2079,7 +2093,7 @@ void LIRGenerator::visitToNumberInt32(MToNumberInt32* convert) { case MIRType::Value: { auto* lir = new (alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(), LValueToInt32::NORMAL); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, convert); assignSafepoint(lir, convert); break; @@ -2103,14 +2117,14 @@ void LIRGenerator::visitToNumberInt32(MToNumberInt32* convert) { case MIRType::Float32: { LFloat32ToInt32* lir = new (alloc()) LFloat32ToInt32(useRegister(opd)); - assignSnapshot(lir, Bailout_PrecisionLoss); + assignSnapshot(lir, BailoutKind::PrecisionLoss); define(lir, convert); break; } case MIRType::Double: { LDoubleToInt32* lir = new (alloc()) LDoubleToInt32(useRegister(opd)); - assignSnapshot(lir, Bailout_PrecisionLoss); + assignSnapshot(lir, BailoutKind::PrecisionLoss); define(lir, convert); break; } @@ -2136,7 +2150,7 @@ void LIRGenerator::visitToIntegerInt32(MToIntegerInt32* convert) { case MIRType::Value: { auto* lir = new (alloc()) LValueToInt32(useBox(opd), tempDouble(), temp(), LValueToInt32::TRUNCATE_NOWRAP); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, convert); assignSafepoint(lir, convert); break; @@ -2154,14 +2168,14 @@ void LIRGenerator::visitToIntegerInt32(MToIntegerInt32* convert) { case MIRType::Float32: { auto* lir = new (alloc()) LFloat32ToIntegerInt32(useRegister(opd)); - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); define(lir, convert); break; } case MIRType::Double: { auto* lir = new (alloc()) LDoubleToIntegerInt32(useRegister(opd)); - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); define(lir, convert); break; } @@ -2186,7 +2200,7 @@ void LIRGenerator::visitTruncateToInt32(MTruncateToInt32* truncate) { case MIRType::Value: { LValueToInt32* lir = new (alloc()) LValueToInt32( useBox(opd), tempDouble(), temp(), LValueToInt32::TRUNCATE); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, truncate); assignSafepoint(lir, truncate); break; @@ -2227,7 +2241,7 @@ void LIRGenerator::visitToBigInt(MToBigInt* ins) { switch (opd->type()) { case MIRType::Value: { auto* lir = new (alloc()) LValueToBigInt(useBox(opd)); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, ins); assignSafepoint(lir, ins); break; @@ -2242,6 +2256,59 @@ void LIRGenerator::visitToBigInt(MToBigInt* ins) { } } +void LIRGenerator::visitToInt64(MToInt64* ins) { + MDefinition* opd = ins->input(); + + switch (opd->type()) { + case MIRType::Value: { + auto* lir = new (alloc()) LValueToInt64(useBox(opd), temp()); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); + defineInt64(lir, ins); + assignSafepoint(lir, ins); + break; + } + + case MIRType::Boolean: { + auto* lir = new (alloc()) LBooleanToInt64(useRegisterAtStart(opd)); + defineInt64(lir, ins); + break; + } + + case MIRType::String: { + auto* lir = new (alloc()) LStringToInt64(useRegister(opd)); + defineInt64(lir, ins); + assignSafepoint(lir, ins); + break; + } + + // An Int64 may be passed here from a BigInt to Int64 conversion. + case MIRType::Int64: { + redefine(ins, opd); + break; + } + + default: + // Undefined, Null, Number, and Symbol throw. + // Objects may be effectful. + // BigInt operands are eliminated by the type policy. + MOZ_CRASH("unexpected type"); + } +} + +void LIRGenerator::visitTruncateBigIntToInt64(MTruncateBigIntToInt64* ins) { + MOZ_ASSERT(ins->input()->type() == MIRType::BigInt); + auto* lir = new (alloc()) LTruncateBigIntToInt64(useRegister(ins->input())); + defineInt64(lir, ins); +} + +void LIRGenerator::visitInt64ToBigInt(MInt64ToBigInt* ins) { + MOZ_ASSERT(ins->input()->type() == MIRType::Int64); + auto* lir = + new (alloc()) LInt64ToBigInt(useInt64Register(ins->input()), temp()); + define(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitWasmTruncateToInt32(MWasmTruncateToInt32* ins) { MDefinition* input = ins->input(); switch (input->type()) { @@ -2321,7 +2388,7 @@ void LIRGenerator::visitToString(MToString* ins) { LValueToString* lir = new (alloc()) LValueToString(useBox(opd), tempToUnbox()); if (ins->needsSnapshot()) { - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); } define(lir, ins); assignSafepoint(lir, ins); @@ -2735,7 +2802,7 @@ void LIRGenerator::visitTypeBarrier(MTypeBarrier* ins) { // (Emit LBail for visibility). if (ins->alwaysBails()) { LBail* bail = new (alloc()) LBail(); - assignSnapshot(bail, Bailout_Inevitable); + assignSnapshot(bail, BailoutKind::Inevitable); add(bail, ins); redefine(ins, ins->input()); return; @@ -2751,13 +2818,13 @@ void LIRGenerator::visitTypeBarrier(MTypeBarrier* ins) { if (ins->canRedefineInput()) { LTypeBarrierV* barrier = new (alloc()) LTypeBarrierV(useBox(ins->input()), tempToUnbox(), objTemp); - assignSnapshot(barrier, Bailout_TypeBarrierV); + assignSnapshot(barrier, BailoutKind::TypeBarrierV); add(barrier, ins); redefine(ins, ins->input()); } else { LTypeBarrierV* barrier = new (alloc()) LTypeBarrierV(useBoxAtStart(ins->input()), tempToUnbox(), objTemp); - assignSnapshot(barrier, Bailout_TypeBarrierV); + assignSnapshot(barrier, BailoutKind::TypeBarrierV); defineBoxReuseInput(barrier, ins, 0); } return; @@ -2780,13 +2847,13 @@ void LIRGenerator::visitTypeBarrier(MTypeBarrier* ins) { if (ins->canRedefineInput()) { LTypeBarrierO* barrier = new (alloc()) LTypeBarrierO(useRegister(ins->input()), tmp); - assignSnapshot(barrier, Bailout_TypeBarrierO); + assignSnapshot(barrier, BailoutKind::TypeBarrierO); add(barrier, ins); redefine(ins, ins->getOperand(0)); } else { LTypeBarrierO* barrier = new (alloc()) LTypeBarrierO(useRegisterAtStart(ins->input()), tmp); - assignSnapshot(barrier, Bailout_TypeBarrierO); + assignSnapshot(barrier, BailoutKind::TypeBarrierO); defineReuseInput(barrier, ins, 0); } return; @@ -2935,7 +3002,11 @@ void LIRGenerator::visitPostWriteElementBarrier(MPostWriteElementBarrier* ins) { void LIRGenerator::visitArrayLength(MArrayLength* ins) { MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); - define(new (alloc()) LArrayLength(useRegisterAtStart(ins->elements())), ins); + auto* lir = new (alloc()) LArrayLength(useRegisterAtStart(ins->elements())); + if (JitOptions.warpBuilder) { + assignSnapshot(lir, BailoutKind::NonInt32ArrayLength); + } + define(lir, ins); } void LIRGenerator::visitSetArrayLength(MSetArrayLength* ins) { @@ -2948,6 +3019,22 @@ void LIRGenerator::visitSetArrayLength(MSetArrayLength* ins) { ins); } +void LIRGenerator::visitFunctionLength(MFunctionLength* ins) { + MOZ_ASSERT(ins->function()->type() == MIRType::Object); + + auto* lir = new (alloc()) LFunctionLength(useRegister(ins->function())); + assignSnapshot(lir, BailoutKind::FunctionLength); + define(lir, ins); +} + +void LIRGenerator::visitFunctionName(MFunctionName* ins) { + MOZ_ASSERT(ins->function()->type() == MIRType::Object); + + auto* lir = new (alloc()) LFunctionName(useRegister(ins->function())); + assignSnapshot(lir, BailoutKind::FunctionName); + define(lir, ins); +} + void LIRGenerator::visitGetNextEntryForIterator(MGetNextEntryForIterator* ins) { MOZ_ASSERT(ins->iter()->type() == MIRType::Object); MOZ_ASSERT(ins->result()->type() == MIRType::Object); @@ -3099,7 +3186,7 @@ void LIRGenerator::visitBoundsCheck(MBoundsCheck* ins) { check = new (alloc()) LBoundsCheck(useRegisterOrConstant(ins->index()), useAnyOrConstant(ins->length())); } - assignSnapshot(check, Bailout_BoundsCheck); + assignSnapshot(check, BailoutKind::BoundsCheck); add(check, ins); } @@ -3122,7 +3209,7 @@ void LIRGenerator::visitBoundsCheckLower(MBoundsCheckLower* ins) { LInstruction* check = new (alloc()) LBoundsCheckLower(useRegister(ins->index())); - assignSnapshot(check, Bailout_BoundsCheck); + assignSnapshot(check, BailoutKind::BoundsCheck); add(check, ins); } @@ -3145,6 +3232,17 @@ void LIRGenerator::visitInArray(MInArray* ins) { assignSafepoint(lir, ins); } +void LIRGenerator::visitGuardElementNotHole(MGuardElementNotHole* ins) { + MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); + MOZ_ASSERT(ins->index()->type() == MIRType::Int32); + + auto* guard = new (alloc()) + LGuardElementNotHole(useRegisterAtStart(ins->elements()), + useRegisterOrConstantAtStart(ins->index())); + assignSnapshot(guard, BailoutKind::Hole); + add(guard, ins); +} + void LIRGenerator::visitLoadElement(MLoadElement* ins) { MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); MOZ_ASSERT(ins->index()->type() == MIRType::Int32); @@ -3154,7 +3252,7 @@ void LIRGenerator::visitLoadElement(MLoadElement* ins) { LLoadElementV* lir = new (alloc()) LLoadElementV( useRegister(ins->elements()), useRegisterOrConstant(ins->index())); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Hole); + assignSnapshot(lir, BailoutKind::Hole); } defineBox(lir, ins); break; @@ -3167,7 +3265,7 @@ void LIRGenerator::visitLoadElement(MLoadElement* ins) { LLoadElementT* lir = new (alloc()) LLoadElementT( useRegister(ins->elements()), useRegisterOrConstant(ins->index())); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Hole); + assignSnapshot(lir, BailoutKind::Hole); } define(lir, ins); break; @@ -3185,7 +3283,7 @@ void LIRGenerator::visitLoadElementHole(MLoadElementHole* ins) { LLoadElementHole(useRegister(ins->elements()), useRegister(ins->index()), useRegister(ins->initLength())); if (ins->needsNegativeIntCheck()) { - assignSnapshot(lir, Bailout_NegativeIndex); + assignSnapshot(lir, BailoutKind::NegativeIndex); } defineBox(lir, ins); } @@ -3275,7 +3373,7 @@ void LIRGenerator::visitStoreElement(MStoreElement* ins) { LInstruction* lir = new (alloc()) LStoreElementV(elements, index, useBox(ins->value())); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Hole); + assignSnapshot(lir, BailoutKind::Hole); } add(lir, ins); break; @@ -3285,7 +3383,7 @@ void LIRGenerator::visitStoreElement(MStoreElement* ins) { const LAllocation value = useRegisterOrNonDoubleConstant(ins->value()); LInstruction* lir = new (alloc()) LStoreElementT(elements, index, value); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Hole); + assignSnapshot(lir, BailoutKind::Hole); } add(lir, ins); break; @@ -3293,6 +3391,15 @@ void LIRGenerator::visitStoreElement(MStoreElement* ins) { } } +void LIRGenerator::visitStoreHoleValueElement(MStoreHoleValueElement* ins) { + MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); + MOZ_ASSERT(ins->index()->type() == MIRType::Int32); + + auto* lir = new (alloc()) LStoreHoleValueElement(useRegister(ins->elements()), + useRegister(ins->index())); + add(lir, ins); +} + static bool BoundsCheckNeedsSpectreTemp() { // On x86, spectreBoundsCheck32 can emit better code if it has a scratch // register and index masking is enabled. @@ -3374,8 +3481,13 @@ void LIRGenerator::visitArrayPopShift(MArrayPopShift* ins) { case MIRType::Value: { LArrayPopShiftV* lir = new (alloc()) LArrayPopShiftV(object, temp(), temp()); + if (JitOptions.warpBuilder) { + assignSnapshot(lir, BailoutKind::ArrayPopShift); + } defineBox(lir, ins); - assignSafepoint(lir, ins); + if (!JitOptions.warpBuilder || ins->mode() == MArrayPopShift::Shift) { + assignSafepoint(lir, ins); + } break; } case MIRType::Undefined: @@ -3407,7 +3519,7 @@ void LIRGenerator::visitArrayPush(MArrayPush* ins) { // With Warp (and without TI) we will bailout before pushing // if the length would overflow INT32_MAX. if (!IsTypeInferenceEnabled()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } define(lir, ins); assignSafepoint(lir, ins); @@ -3419,7 +3531,7 @@ void LIRGenerator::visitArrayPush(MArrayPush* ins) { LArrayPushT* lir = new (alloc()) LArrayPushT(object, value, temp(), spectreTemp); if (!IsTypeInferenceEnabled()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } define(lir, ins); assignSafepoint(lir, ins); @@ -3434,11 +3546,13 @@ void LIRGenerator::visitArraySlice(MArraySlice* ins) { MOZ_ASSERT(ins->begin()->type() == MIRType::Int32); MOZ_ASSERT(ins->end()->type() == MIRType::Int32); - LArraySlice* lir = new (alloc()) - LArraySlice(useFixedAtStart(ins->object(), CallTempReg0), - useFixedAtStart(ins->begin(), CallTempReg1), - useFixedAtStart(ins->end(), CallTempReg2), - tempFixed(CallTempReg3), tempFixed(CallTempReg4)); + LArraySlice* lir = new (alloc()) LArraySlice( + useRegisterAtStart(ins->object()), useRegisterAtStart(ins->begin()), + useRegisterAtStart(ins->end()), tempFixed(CallTempReg0), + tempFixed(CallTempReg1)); + if (JitOptions.warpBuilder) { + assignSnapshot(lir, BailoutKind::ArraySlice); + } defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -3450,7 +3564,7 @@ void LIRGenerator::visitArrayJoin(MArrayJoin* ins) { LDefinition tempDef = LDefinition::BogusTemp(); if (ins->optimizeForArray()) { - tempDef = temp(); + tempDef = tempFixed(CallTempReg0); } LArrayJoin* lir = @@ -3496,7 +3610,7 @@ void LIRGenerator::visitLoadUnboxedScalar(MLoadUnboxedScalar* ins) { auto* lir = new (alloc()) LLoadUnboxedScalar(elements, index, tempDef); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } define(lir, ins); } else { @@ -3556,7 +3670,7 @@ void LIRGenerator::visitLoadDataViewElement(MLoadDataViewElement* ins) { auto* lir = new (alloc()) LLoadDataViewElement(elements, index, littleEndian, tempDef, temp64Def); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } define(lir, ins); if (Scalar::isBigIntType(ins->storageType())) { @@ -3588,7 +3702,7 @@ void LIRGenerator::visitClampToUint8(MClampToUint8* ins) { case MIRType::Value: { LClampVToUint8* lir = new (alloc()) LClampVToUint8(useBox(in), tempDouble()); - assignSnapshot(lir, Bailout_NonPrimitiveInput); + assignSnapshot(lir, BailoutKind::NonPrimitiveInput); define(lir, ins); assignSafepoint(lir, ins); break; @@ -3612,7 +3726,7 @@ void LIRGenerator::visitLoadTypedArrayElementHole( if (!Scalar::isBigIntType(ins->arrayType())) { auto* lir = new (alloc()) LLoadTypedArrayElementHole(object, index, temp()); if (ins->fallible()) { - assignSnapshot(lir, Bailout_Overflow); + assignSnapshot(lir, BailoutKind::Overflow); } defineBox(lir, ins); } else { @@ -3815,6 +3929,29 @@ void LIRGenerator::visitLoadElementAndUnbox(MLoadElementAndUnbox* ins) { define(lir, ins); } +void LIRGenerator::visitAddAndStoreSlot(MAddAndStoreSlot* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + LDefinition maybeTemp = LDefinition::BogusTemp(); + if (ins->kind() != MAddAndStoreSlot::Kind::FixedSlot) { + maybeTemp = temp(); + } + + auto* lir = new (alloc()) LAddAndStoreSlot(useRegister(ins->object()), + useBox(ins->value()), maybeTemp); + add(lir, ins); +} + +void LIRGenerator::visitAllocateAndStoreSlot(MAllocateAndStoreSlot* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = new (alloc()) LAllocateAndStoreSlot( + useRegisterAtStart(ins->object()), useBoxAtStart(ins->value()), + tempFixed(CallTempReg0), tempFixed(CallTempReg1)); + assignSnapshot(lir, BailoutKind::DuringVMCall); + add(lir, ins); +} + void LIRGenerator::visitStoreFixedSlot(MStoreFixedSlot* ins) { MOZ_ASSERT(ins->object()->type() == MIRType::Object); @@ -3913,12 +4050,12 @@ void LIRGenerator::visitGetPropertyPolymorphic(MGetPropertyPolymorphic* ins) { if (ins->type() == MIRType::Value) { LGetPropertyPolymorphicV* lir = new (alloc()) LGetPropertyPolymorphicV(useRegister(ins->object()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); defineBox(lir, ins); } else { LGetPropertyPolymorphicT* lir = new (alloc()) LGetPropertyPolymorphicT(useRegister(ins->object()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); define(lir, ins); } } @@ -3929,13 +4066,13 @@ void LIRGenerator::visitSetPropertyPolymorphic(MSetPropertyPolymorphic* ins) { if (ins->value()->type() == MIRType::Value) { LSetPropertyPolymorphicV* lir = new (alloc()) LSetPropertyPolymorphicV( useRegister(ins->object()), useBox(ins->value()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); add(lir, ins); } else { LAllocation value = useRegisterOrConstant(ins->value()); LSetPropertyPolymorphicT* lir = new (alloc()) LSetPropertyPolymorphicT( useRegister(ins->object()), value, ins->value()->type(), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); add(lir, ins); } } @@ -3962,7 +4099,7 @@ void LIRGenerator::visitCallBindVar(MCallBindVar* ins) { void LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity* ins) { LGuardObjectIdentity* guard = new (alloc()) LGuardObjectIdentity( useRegister(ins->object()), useRegister(ins->expected())); - assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard); + assignSnapshot(guard, BailoutKind::ObjectIdentityOrTypeGuard); add(guard, ins); redefine(ins, ins->object()); } @@ -3970,29 +4107,57 @@ void LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity* ins) { void LIRGenerator::visitGuardSpecificFunction(MGuardSpecificFunction* ins) { auto* guard = new (alloc()) LGuardSpecificFunction( useRegister(ins->function()), useRegister(ins->expected())); - assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard); + assignSnapshot(guard, BailoutKind::ObjectIdentityOrTypeGuard); add(guard, ins); redefine(ins, ins->function()); } void LIRGenerator::visitGuardSpecificAtom(MGuardSpecificAtom* ins) { - auto* guard = new (alloc()) LGuardSpecificAtom(useRegister(ins->str())); - assignSnapshot(guard, Bailout_SpecificAtomGuard); + auto* guard = + new (alloc()) LGuardSpecificAtom(useRegister(ins->str()), temp()); + assignSnapshot(guard, BailoutKind::SpecificAtomGuard); add(guard, ins); redefine(ins, ins->str()); + assignSafepoint(guard, ins); } void LIRGenerator::visitGuardSpecificSymbol(MGuardSpecificSymbol* ins) { auto* guard = new (alloc()) LGuardSpecificSymbol(useRegister(ins->symbol())); - assignSnapshot(guard, Bailout_SpecificSymbolGuard); + assignSnapshot(guard, BailoutKind::SpecificSymbolGuard); add(guard, ins); redefine(ins, ins->symbol()); } +void LIRGenerator::visitGuardStringToIndex(MGuardStringToIndex* ins) { + MOZ_ASSERT(ins->string()->type() == MIRType::String); + auto* guard = new (alloc()) LGuardStringToIndex(useRegister(ins->string())); + assignSnapshot(guard, BailoutKind::StringToIndexGuard); + define(guard, ins); + assignSafepoint(guard, ins); +} + +void LIRGenerator::visitGuardStringToInt32(MGuardStringToInt32* ins) { + MOZ_ASSERT(ins->string()->type() == MIRType::String); + auto* guard = + new (alloc()) LGuardStringToInt32(useRegister(ins->string()), temp()); + assignSnapshot(guard, BailoutKind::StringToInt32Guard); + define(guard, ins); + assignSafepoint(guard, ins); +} + +void LIRGenerator::visitGuardStringToDouble(MGuardStringToDouble* ins) { + MOZ_ASSERT(ins->string()->type() == MIRType::String); + auto* guard = new (alloc()) + LGuardStringToDouble(useRegister(ins->string()), temp(), temp()); + assignSnapshot(guard, BailoutKind::StringToDoubleGuard); + define(guard, ins); + assignSafepoint(guard, ins); +} + void LIRGenerator::visitGuardNoDenseElements(MGuardNoDenseElements* ins) { auto* guard = new (alloc()) LGuardNoDenseElements(useRegister(ins->object()), temp()); - assignSnapshot(guard, Bailout_NoDenseElementsGuard); + assignSnapshot(guard, BailoutKind::NoDenseElementsGuard); add(guard, ins); redefine(ins, ins->object()); } @@ -4003,17 +4168,191 @@ void LIRGenerator::visitGuardShape(MGuardShape* ins) { if (JitOptions.spectreObjectMitigationsMisc) { auto* lir = new (alloc()) LGuardShape(useRegisterAtStart(ins->object()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); defineReuseInput(lir, ins, 0); } else { auto* lir = new (alloc()) LGuardShape(useRegister(ins->object()), LDefinition::BogusTemp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); add(lir, ins); redefine(ins, ins->object()); } } +void LIRGenerator::visitGuardProto(MGuardProto* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + MOZ_ASSERT(ins->expected()->type() == MIRType::Object); + + auto* lir = new (alloc()) LGuardProto(useRegister(ins->object()), + useRegister(ins->expected()), temp()); + assignSnapshot(lir, BailoutKind::ProtoGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitGuardNullProto(MGuardNullProto* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = new (alloc()) LGuardNullProto(useRegister(ins->object()), temp()); + assignSnapshot(lir, BailoutKind::ProtoGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitGuardIsProxy(MGuardIsProxy* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = new (alloc()) LGuardIsProxy(useRegister(ins->object()), temp()); + assignSnapshot(lir, BailoutKind::ProxyGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitGuardIsNotProxy(MGuardIsNotProxy* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = + new (alloc()) LGuardIsNotProxy(useRegister(ins->object()), temp()); + assignSnapshot(lir, BailoutKind::NotProxyGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitGuardIsNotDOMProxy(MGuardIsNotDOMProxy* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + + auto* lir = + new (alloc()) LGuardIsNotDOMProxy(useRegister(ins->proxy()), temp()); + assignSnapshot(lir, BailoutKind::NotDOMProxyGuard); + add(lir, ins); + redefine(ins, ins->proxy()); +} + +void LIRGenerator::visitProxyGet(MProxyGet* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + auto* lir = new (alloc()) + LProxyGet(useRegisterAtStart(ins->proxy()), tempFixed(CallTempReg0)); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitProxyGetByValue(MProxyGetByValue* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + MOZ_ASSERT(ins->idVal()->type() == MIRType::Value); + auto* lir = new (alloc()) LProxyGetByValue(useRegisterAtStart(ins->proxy()), + useBoxAtStart(ins->idVal())); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitProxyHasProp(MProxyHasProp* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + MOZ_ASSERT(ins->idVal()->type() == MIRType::Value); + auto* lir = new (alloc()) LProxyHasProp(useRegisterAtStart(ins->proxy()), + useBoxAtStart(ins->idVal())); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitProxySet(MProxySet* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + MOZ_ASSERT(ins->rhs()->type() == MIRType::Value); + auto* lir = new (alloc()) + LProxySet(useRegisterAtStart(ins->proxy()), useBoxAtStart(ins->rhs()), + tempFixed(CallTempReg0)); + add(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitProxySetByValue(MProxySetByValue* ins) { + MOZ_ASSERT(ins->proxy()->type() == MIRType::Object); + MOZ_ASSERT(ins->idVal()->type() == MIRType::Value); + MOZ_ASSERT(ins->rhs()->type() == MIRType::Value); + auto* lir = new (alloc()) + LProxySetByValue(useRegisterAtStart(ins->proxy()), + useBoxAtStart(ins->idVal()), useBoxAtStart(ins->rhs())); + add(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitCallSetArrayLength(MCallSetArrayLength* ins) { + MOZ_ASSERT(ins->obj()->type() == MIRType::Object); + MOZ_ASSERT(ins->rhs()->type() == MIRType::Value); + auto* lir = new (alloc()) LCallSetArrayLength(useRegisterAtStart(ins->obj()), + useBoxAtStart(ins->rhs())); + add(lir, ins); + assignSafepoint(lir, ins); +} + +void LIRGenerator::visitMegamorphicLoadSlot(MMegamorphicLoadSlot* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + auto* lir = new (alloc()) LMegamorphicLoadSlot( + useRegisterAtStart(ins->object()), tempFixed(CallTempReg0), + tempFixed(CallTempReg1), tempFixed(CallTempReg2)); + assignSnapshot(lir, BailoutKind::MegamorphicAccess); + defineReturn(lir, ins); +} + +void LIRGenerator::visitMegamorphicLoadSlotByValue( + MMegamorphicLoadSlotByValue* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + MOZ_ASSERT(ins->idVal()->type() == MIRType::Value); + auto* lir = new (alloc()) LMegamorphicLoadSlotByValue( + useRegisterAtStart(ins->object()), useBoxAtStart(ins->idVal()), + tempFixed(CallTempReg0), tempFixed(CallTempReg1)); + assignSnapshot(lir, BailoutKind::MegamorphicAccess); + defineReturn(lir, ins); +} + +void LIRGenerator::visitMegamorphicStoreSlot(MMegamorphicStoreSlot* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + MOZ_ASSERT(ins->rhs()->type() == MIRType::Value); + auto* lir = new (alloc()) + LMegamorphicStoreSlot(useRegisterAtStart(ins->object()), + useBoxAtStart(ins->rhs()), tempFixed(CallTempReg0), + tempFixed(CallTempReg1), tempFixed(CallTempReg2)); + assignSnapshot(lir, BailoutKind::MegamorphicAccess); + add(lir, ins); +} + +void LIRGenerator::visitMegamorphicHasProp(MMegamorphicHasProp* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + MOZ_ASSERT(ins->idVal()->type() == MIRType::Value); + auto* lir = new (alloc()) LMegamorphicHasProp( + useRegisterAtStart(ins->object()), useBoxAtStart(ins->idVal()), + tempFixed(CallTempReg0), tempFixed(CallTempReg1)); + assignSnapshot(lir, BailoutKind::MegamorphicAccess); + defineReturn(lir, ins); +} + +void LIRGenerator::visitGuardIsNotArrayBufferMaybeShared( + MGuardIsNotArrayBufferMaybeShared* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = new (alloc()) + LGuardIsNotArrayBufferMaybeShared(useRegister(ins->object()), temp()); + assignSnapshot(lir, BailoutKind::NotArrayBufferMaybeSharedGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitGuardIsTypedArray(MGuardIsTypedArray* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + + auto* lir = + new (alloc()) LGuardIsTypedArray(useRegister(ins->object()), temp()); + assignSnapshot(lir, BailoutKind::TypedArrayGuard); + add(lir, ins); + redefine(ins, ins->object()); +} + +void LIRGenerator::visitNurseryObject(MNurseryObject* ins) { + MOZ_ASSERT(ins->type() == MIRType::Object); + + auto* lir = new (alloc()) LNurseryObject(); + define(lir, ins); +} + void LIRGenerator::visitGuardObjectGroup(MGuardObjectGroup* ins) { MOZ_ASSERT(ins->object()->type() == MIRType::Object); @@ -4058,12 +4397,12 @@ void LIRGenerator::visitGuardReceiverPolymorphic( if (JitOptions.spectreObjectMitigationsMisc) { auto* lir = new (alloc()) LGuardReceiverPolymorphic(useRegisterAtStart(ins->object()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); defineReuseInput(lir, ins, 0); } else { auto* lir = new (alloc()) LGuardReceiverPolymorphic(useRegister(ins->object()), temp()); - assignSnapshot(lir, Bailout_ShapeGuard); + assignSnapshot(lir, BailoutKind::ShapeGuard); add(lir, ins); redefine(ins, ins->object()); } @@ -4072,7 +4411,16 @@ void LIRGenerator::visitGuardReceiverPolymorphic( void LIRGenerator::visitGuardValue(MGuardValue* ins) { MOZ_ASSERT(ins->value()->type() == MIRType::Value); auto* lir = new (alloc()) LGuardValue(useBox(ins->value())); - assignSnapshot(lir, Bailout_ValueGuard); + assignSnapshot(lir, BailoutKind::ValueGuard); + add(lir, ins); + redefine(ins, ins->value()); +} + +void LIRGenerator::visitGuardNotOptimizedArguments( + MGuardNotOptimizedArguments* ins) { + MOZ_ASSERT(ins->value()->type() == MIRType::Value); + auto* lir = new (alloc()) LGuardNotOptimizedArguments(useBox(ins->value())); + assignSnapshot(lir, BailoutKind::NotOptimizedArgumentsGuard); add(lir, ins); redefine(ins, ins->value()); } @@ -4080,11 +4428,39 @@ void LIRGenerator::visitGuardValue(MGuardValue* ins) { void LIRGenerator::visitGuardNullOrUndefined(MGuardNullOrUndefined* ins) { MOZ_ASSERT(ins->value()->type() == MIRType::Value); auto* lir = new (alloc()) LGuardNullOrUndefined(useBox(ins->value())); - assignSnapshot(lir, Bailout_NullOrUndefinedGuard); + assignSnapshot(lir, BailoutKind::NullOrUndefinedGuard); add(lir, ins); redefine(ins, ins->value()); } +void LIRGenerator::visitGuardFunctionFlags(MGuardFunctionFlags* ins) { + MOZ_ASSERT(ins->function()->type() == MIRType::Object); + + auto* lir = new (alloc()) LGuardFunctionFlags(useRegister(ins->function())); + assignSnapshot(lir, BailoutKind::FunctionFlagsGuard); + add(lir, ins); + redefine(ins, ins->function()); +} + +void LIRGenerator::visitGuardFunctionKind(MGuardFunctionKind* ins) { + MOZ_ASSERT(ins->function()->type() == MIRType::Object); + + auto* lir = + new (alloc()) LGuardFunctionKind(useRegister(ins->function()), temp()); + assignSnapshot(lir, BailoutKind::FunctionKindGuard); + add(lir, ins); + redefine(ins, ins->function()); +} + +void LIRGenerator::visitGuardFunctionScript(MGuardFunctionScript* ins) { + MOZ_ASSERT(ins->function()->type() == MIRType::Object); + + auto* lir = new (alloc()) LGuardFunctionScript(useRegister(ins->function())); + assignSnapshot(lir, BailoutKind::FunctionScriptGuard); + add(lir, ins); + redefine(ins, ins->function()); +} + void LIRGenerator::visitAssertRange(MAssertRange* ins) { MDefinition* input = ins->input(); LInstruction* lir = nullptr; @@ -4118,6 +4494,17 @@ void LIRGenerator::visitAssertRange(MAssertRange* ins) { add(lir); } +void LIRGenerator::visitAssertClass(MAssertClass* ins) { + auto* lir = + new (alloc()) LAssertClass(useRegisterAtStart(ins->input()), temp()); + add(lir, ins); +} + +void LIRGenerator::visitAssertShape(MAssertShape* ins) { + auto* lir = new (alloc()) LAssertShape(useRegisterAtStart(ins->input())); + add(lir, ins); +} + void LIRGenerator::visitCallGetProperty(MCallGetProperty* ins) { LCallGetProperty* lir = new (alloc()) LCallGetProperty(useBoxAtStart(ins->value())); @@ -4214,6 +4601,15 @@ void LIRGenerator::visitGetIteratorCache(MGetIteratorCache* ins) { assignSafepoint(lir, ins); } +void LIRGenerator::visitOptimizeSpreadCallCache(MOptimizeSpreadCallCache* ins) { + MDefinition* value = ins->value(); + MOZ_ASSERT(value->type() == MIRType::Value); + + auto* lir = new (alloc()) LOptimizeSpreadCallCache(useBox(value), temp()); + define(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitIteratorMore(MIteratorMore* ins) { LIteratorMore* lir = new (alloc()) LIteratorMore(useRegister(ins->iterator()), temp()); @@ -4256,9 +4652,9 @@ void LIRGenerator::visitNewTarget(MNewTarget* ins) { void LIRGenerator::visitRest(MRest* ins) { MOZ_ASSERT(ins->numActuals()->type() == MIRType::Int32); - LRest* lir = new (alloc()) LRest( - useFixedAtStart(ins->numActuals(), CallTempReg0), tempFixed(CallTempReg1), - tempFixed(CallTempReg2), tempFixed(CallTempReg3)); + LRest* lir = new (alloc()) + LRest(useRegisterAtStart(ins->numActuals()), tempFixed(CallTempReg0), + tempFixed(CallTempReg1), tempFixed(CallTempReg2)); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -4305,17 +4701,36 @@ void LIRGenerator::visitHasOwnCache(MHasOwnCache* ins) { assignSafepoint(lir, ins); } +void LIRGenerator::visitCheckPrivateFieldCache(MCheckPrivateFieldCache* ins) { + MDefinition* value = ins->value(); + MOZ_ASSERT(value->type() == MIRType::Object || + value->type() == MIRType::Value); + + MDefinition* id = ins->idval(); + MOZ_ASSERT(id->type() == MIRType::String || id->type() == MIRType::Symbol || + id->type() == MIRType::Int32 || id->type() == MIRType::Value); + + LCheckPrivateFieldCache* lir = new (alloc()) + LCheckPrivateFieldCache(useBoxOrTyped(value), useBoxOrTyped(id)); + define(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitInstanceOf(MInstanceOf* ins) { - MDefinition* lhs = ins->getOperand(0); + MDefinition* lhs = ins->lhs(); + MDefinition* rhs = ins->rhs(); MOZ_ASSERT(lhs->type() == MIRType::Value || lhs->type() == MIRType::Object); + MOZ_ASSERT(rhs->type() == MIRType::Object); if (lhs->type() == MIRType::Object) { - LInstanceOfO* lir = new (alloc()) LInstanceOfO(useRegister(lhs)); + auto* lir = new (alloc()) + LInstanceOfO(useRegister(lhs), useRegisterOrConstant(rhs)); define(lir, ins); assignSafepoint(lir, ins); } else { - LInstanceOfV* lir = new (alloc()) LInstanceOfV(useBox(lhs)); + auto* lir = + new (alloc()) LInstanceOfV(useBox(lhs), useRegisterOrConstant(rhs)); define(lir, ins); assignSafepoint(lir, ins); } @@ -4378,6 +4793,15 @@ void LIRGenerator::visitIsConstructor(MIsConstructor* ins) { define(new (alloc()) LIsConstructor(useRegister(ins->object())), ins); } +void LIRGenerator::visitIsCrossRealmArrayConstructor( + MIsCrossRealmArrayConstructor* ins) { + MOZ_ASSERT(ins->object()->type() == MIRType::Object); + MOZ_ASSERT(ins->type() == MIRType::Boolean); + define(new (alloc()) + LIsCrossRealmArrayConstructor(useRegister(ins->object())), + ins); +} + static bool CanEmitIsObjectOrIsNullOrUndefinedAtUses(MInstruction* ins) { if (!ins->canEmitAtUses()) { return false; @@ -4437,7 +4861,7 @@ void LIRGenerator::visitGuardToClass(MGuardToClass* ins) { MOZ_ASSERT(ins->type() == MIRType::Object); LGuardToClass* lir = new (alloc()) LGuardToClass(useRegisterAtStart(ins->object()), temp()); - assignSnapshot(lir, Bailout_TypeBarrierO); + assignSnapshot(lir, BailoutKind::TypeBarrierO); defineReuseInput(lir, ins, 0); } @@ -4888,7 +5312,7 @@ void LIRGenerator::visitGlobalNameConflictsCheck( void LIRGenerator::visitDebugger(MDebugger* ins) { LDebugger* lir = new (alloc()) LDebugger(tempFixed(CallTempReg0), tempFixed(CallTempReg1)); - assignSnapshot(lir, Bailout_Debugger); + assignSnapshot(lir, BailoutKind::Debugger); add(lir, ins); } @@ -4909,12 +5333,11 @@ void LIRGenerator::visitCheckReturn(MCheckReturn* ins) { } void LIRGenerator::visitCheckIsObj(MCheckIsObj* ins) { - MDefinition* checkVal = ins->checkValue(); - MOZ_ASSERT(checkVal->type() == MIRType::Value); + MDefinition* input = ins->input(); + MOZ_ASSERT(input->type() == MIRType::Value); - LCheckIsObj* lir = new (alloc()) LCheckIsObj(useBoxAtStart(checkVal)); - redefine(ins, checkVal); - add(lir, ins); + LCheckIsObj* lir = new (alloc()) LCheckIsObj(useBox(input)); + define(lir, ins); assignSafepoint(lir, ins); } @@ -4978,13 +5401,23 @@ void LIRGenerator::visitFinishBoundFunctionInit(MFinishBoundFunctionInit* ins) { } void LIRGenerator::visitIsPackedArray(MIsPackedArray* ins) { - MOZ_ASSERT(ins->array()->type() == MIRType::Object); + MOZ_ASSERT(ins->object()->type() == MIRType::Object); MOZ_ASSERT(ins->type() == MIRType::Boolean); - auto lir = new (alloc()) LIsPackedArray(useRegister(ins->array()), temp()); + auto lir = new (alloc()) LIsPackedArray(useRegister(ins->object()), temp()); define(lir, ins); } +void LIRGenerator::visitGuardArrayIsPacked(MGuardArrayIsPacked* ins) { + MOZ_ASSERT(ins->array()->type() == MIRType::Object); + + auto* lir = new (alloc()) + LGuardArrayIsPacked(useRegister(ins->array()), temp(), temp()); + assignSnapshot(lir, BailoutKind::PackedArrayGuard); + add(lir, ins); + redefine(ins, ins->array()); +} + void LIRGenerator::visitGetPrototypeOf(MGetPrototypeOf* ins) { MOZ_ASSERT(ins->target()->type() == MIRType::Object); MOZ_ASSERT(ins->type() == MIRType::Value); @@ -5012,10 +5445,10 @@ void LIRGenerator::visitObjectStaticProto(MObjectStaticProto* ins) { define(lir, ins); }; -void LIRGenerator::visitFunctionProto(MFunctionProto* ins) { +void LIRGenerator::visitBuiltinObject(MBuiltinObject* ins) { MOZ_ASSERT(ins->type() == MIRType::Object); - auto* lir = new (alloc()) LFunctionProto(); + auto* lir = new (alloc()) LBuiltinObject(); defineReturn(lir, ins); assignSafepoint(lir, ins); } @@ -5043,6 +5476,41 @@ void LIRGenerator::visitInitHomeObject(MInitHomeObject* ins) { add(lir, ins); } +void LIRGenerator::visitIsTypedArrayConstructor(MIsTypedArrayConstructor* ins) { + MDefinition* object = ins->object(); + MOZ_ASSERT(object->type() == MIRType::Object); + + auto* lir = new (alloc()) LIsTypedArrayConstructor(useRegister(object)); + define(lir, ins); +} + +void LIRGenerator::visitLoadValueTag(MLoadValueTag* ins) { + MDefinition* value = ins->value(); + MOZ_ASSERT(value->type() == MIRType::Value); + + define(new (alloc()) LLoadValueTag(useBoxAtStart(value)), ins); +} + +void LIRGenerator::visitGuardTagNotEqual(MGuardTagNotEqual* ins) { + MDefinition* lhs = ins->lhs(); + MOZ_ASSERT(lhs->type() == MIRType::Int32); + + MDefinition* rhs = ins->rhs(); + MOZ_ASSERT(rhs->type() == MIRType::Int32); + + auto* guard = + new (alloc()) LGuardTagNotEqual(useRegister(lhs), useRegister(rhs)); + assignSnapshot(guard, BailoutKind::TagNotEqualGuard); + add(guard, ins); +} + +void LIRGenerator::visitLoadWrapperTarget(MLoadWrapperTarget* ins) { + MDefinition* object = ins->object(); + MOZ_ASSERT(object->type() == MIRType::Object); + + define(new (alloc()) LLoadWrapperTarget(useRegisterAtStart(object)), ins); +} + void LIRGenerator::visitConstant(MConstant* ins) { if (!IsFloatingPointType(ins->type()) && ins->canEmitAtUses()) { emitAtUses(ins); @@ -5378,6 +5846,8 @@ void LIRGenerator::visitIonToWasmCall(MIonToWasmCall* ins) { LInstruction* lir; if (ins->type() == MIRType::Value) { lir = allocateVariadic(ins->numOperands(), scratch, fp); + } else if (ins->type() == MIRType::Int64) { + lir = allocateVariadic(ins->numOperands(), scratch, fp); } else { lir = allocateVariadic(ins->numOperands(), scratch, fp); } diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index e516c819fc..b2a304ef17 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -18,7 +18,9 @@ #include "jit/Lowering.h" #include "jit/MIR.h" #include "jit/MIRGraph.h" +#include "js/experimental/JitInfo.h" // JSJitInfo #include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags +#include "js/ScalarType.h" // js::Scalar::Type #include "vm/ArgumentsObject.h" #include "vm/ArrayBufferObject.h" #include "vm/JSObject.h" @@ -322,6 +324,8 @@ IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo, return inlineObjectCreate(callInfo); case InlinableNative::ObjectIs: return inlineObjectIs(callInfo); + case InlinableNative::ObjectIsPrototypeOf: + return inlineObjectIsPrototypeOf(callInfo); case InlinableNative::ObjectToString: return inlineObjectToString(callInfo); @@ -362,8 +366,6 @@ IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo, return inlineToInteger(callInfo); case InlinableNative::IntrinsicToLength: return inlineToLength(callInfo); - case InlinableNative::IntrinsicToString: - return inlineToString(callInfo); case InlinableNative::IntrinsicIsConstructing: return inlineIsConstructing(callInfo); case InlinableNative::IntrinsicSubstringKernel: @@ -374,6 +376,8 @@ IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo, case InlinableNative::IntrinsicGuardToStringIterator: case InlinableNative::IntrinsicGuardToRegExpStringIterator: case InlinableNative::IntrinsicGuardToWrapForValidIterator: + case InlinableNative::IntrinsicGuardToIteratorHelper: + case InlinableNative::IntrinsicGuardToAsyncIteratorHelper: return inlineGuardToClass(callInfo, inlNative); case InlinableNative::IntrinsicObjectHasPrototype: return inlineObjectHasPrototype(callInfo); @@ -426,6 +430,9 @@ IonBuilder::InliningResult IonBuilder::inlineNativeCall(CallInfo& callInfo, case InlinableNative::IntrinsicTypedArrayElementShift: return inlineTypedArrayElementShift(callInfo); + case InlinableNative::NumberToString: + case InlinableNative::StringToString: + case InlinableNative::StringValueOf: case InlinableNative::IntrinsicIsSuspendedGenerator: // Not supported in Ion. return InliningStatus_NotInlined; @@ -935,7 +942,9 @@ IonBuilder::InliningResult IonBuilder::inlineArrayPush(CallInfo& callInfo) { // Restore the stack, such that resume points are created with the stack // as it was before the call. - MOZ_TRY(callInfo.pushPriorCallStack(&mirGen_, current)); + if (!callInfo.pushPriorCallStack(&mirGen_, current)) { + return abort(AbortReason::Alloc); + } } MInstruction* ins = nullptr; @@ -1877,34 +1886,15 @@ IonBuilder::InliningResult IonBuilder::inlineIsPackedArray(CallInfo& callInfo) { return InliningStatus_NotInlined; } - MDefinition* array = callInfo.getArg(0); - - if (array->type() != MIRType::Object) { - return InliningStatus_NotInlined; - } - - TemporaryTypeSet* arrayTypes = array->resultTypeSet(); - if (!arrayTypes) { - return InliningStatus_NotInlined; - } - - const JSClass* clasp = arrayTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_) { - return InliningStatus_NotInlined; - } - - // Only inline if the array uses dense storage. - ObjectGroupFlags unhandledFlags = OBJECT_FLAG_SPARSE_INDEXES | - OBJECT_FLAG_LENGTH_OVERFLOW | - OBJECT_FLAG_NON_PACKED; + MDefinition* obj = callInfo.getArg(0); - if (arrayTypes->hasObjectFlags(constraints(), unhandledFlags)) { + if (obj->type() != MIRType::Object) { return InliningStatus_NotInlined; } callInfo.setImplicitlyUsedUnchecked(); - auto* ins = MIsPackedArray::New(alloc(), array); + auto* ins = MIsPackedArray::New(alloc(), obj); current->add(ins); current->push(ins); @@ -1950,14 +1940,6 @@ IonBuilder::InliningResult IonBuilder::inlineStrCharCodeAt(CallInfo& callInfo) { return InliningStatus_NotInlined; } - // Check for STR.charCodeAt(IDX) where STR is a constant string and IDX is a - // constant integer. - InliningStatus constInlineStatus; - MOZ_TRY_VAR(constInlineStatus, inlineConstantCharCodeAt(callInfo)); - if (constInlineStatus != InliningStatus_NotInlined) { - return constInlineStatus; - } - callInfo.setImplicitlyUsedUnchecked(); MInstruction* index = MToIntegerInt32::New(alloc(), callInfo.getArg(0)); @@ -1974,40 +1956,6 @@ IonBuilder::InliningResult IonBuilder::inlineStrCharCodeAt(CallInfo& callInfo) { return InliningStatus_Inlined; } -IonBuilder::InliningResult IonBuilder::inlineConstantCharCodeAt( - CallInfo& callInfo) { - if (!callInfo.thisArg()->maybeConstantValue() || - !callInfo.getArg(0)->maybeConstantValue()) { - return InliningStatus_NotInlined; - } - - MConstant* strval = callInfo.thisArg()->maybeConstantValue(); - MConstant* idxval = callInfo.getArg(0)->maybeConstantValue(); - - if (strval->type() != MIRType::String || idxval->type() != MIRType::Int32) { - return InliningStatus_NotInlined; - } - - JSString* str = strval->toString(); - if (!str->isLinear()) { - return InliningStatus_NotInlined; - } - - int32_t idx = idxval->toInt32(); - if (idx < 0 || (uint32_t(idx) >= str->length())) { - return InliningStatus_NotInlined; - } - - callInfo.setImplicitlyUsedUnchecked(); - - JSLinearString& linstr = str->asLinear(); - char16_t ch = linstr.latin1OrTwoByteChar(idx); - MConstant* result = MConstant::New(alloc(), Int32Value(ch)); - current->add(result); - current->push(result); - return InliningStatus_Inlined; -} - IonBuilder::InliningResult IonBuilder::inlineStrFromCharCode( CallInfo& callInfo) { if (callInfo.argc() != 1 || callInfo.constructing()) { @@ -2452,9 +2400,7 @@ IonBuilder::InliningResult IonBuilder::inlineStringReplaceString( MInstruction* cte = MStringReplace::New(alloc(), strArg, patArg, replArg); current->add(cte); current->push(cte); - if (cte->isEffectful()) { - MOZ_TRY(resumeAfter(cte)); - } + return InliningStatus_Inlined; } @@ -2621,6 +2567,32 @@ IonBuilder::InliningResult IonBuilder::inlineObjectIs(CallInfo& callInfo) { return InliningStatus_Inlined; } +IonBuilder::InliningResult IonBuilder::inlineObjectIsPrototypeOf( + CallInfo& callInfo) { + if (callInfo.constructing() || callInfo.argc() != 1) { + return InliningStatus_NotInlined; + } + + if (getInlineReturnType() != MIRType::Boolean) { + return InliningStatus_NotInlined; + } + + MDefinition* thisArg = callInfo.thisArg(); + if (thisArg->type() != MIRType::Object) { + return InliningStatus_NotInlined; + } + + MDefinition* arg = callInfo.getArg(0); + + auto* ins = MInstanceOf::New(alloc(), arg, thisArg); + current->add(ins); + current->push(ins); + MOZ_TRY(resumeAfter(ins)); + + callInfo.setImplicitlyUsedUnchecked(); + return InliningStatus_Inlined; +} + IonBuilder::InliningResult IonBuilder::inlineObjectToString( CallInfo& callInfo) { if (callInfo.constructing() || callInfo.argc() != 0) { @@ -3329,6 +3301,7 @@ IonBuilder::InliningResult IonBuilder::inlineToObject(CallInfo& callInfo) { current->add(ins); current->push(ins); + MOZ_TRY(resumeAfter(ins)); MOZ_TRY( pushTypeBarrier(ins, getInlineReturnTypeSet(), BarrierKind::TypeSet)); } @@ -3432,25 +3405,6 @@ IonBuilder::InliningResult IonBuilder::inlineToLength(CallInfo& callInfo) { return InliningStatus_Inlined; } -IonBuilder::InliningResult IonBuilder::inlineToString(CallInfo& callInfo) { - MOZ_ASSERT(!callInfo.constructing()); - MOZ_ASSERT(callInfo.argc() == 1); - - if (getInlineReturnType() != MIRType::String) { - return InliningStatus_NotInlined; - } - - callInfo.setImplicitlyUsedUnchecked(); - MToString* toString = MToString::New( - alloc(), callInfo.getArg(0), MToString::SideEffectHandling::Supported); - current->add(toString); - current->push(toString); - if (toString->isEffectful()) { - MOZ_TRY(resumeAfter(toString)); - } - return InliningStatus_Inlined; -} - IonBuilder::InliningResult IonBuilder::inlineBailout(CallInfo& callInfo) { callInfo.setImplicitlyUsedUnchecked(); @@ -3798,9 +3752,6 @@ bool IonBuilder::atomicsMeetsPreconditions( return checkResult == DontCheckAtomicResult || getInlineReturnType() == MIRType::Int32; case Scalar::Uint32: - // Bug 1077305: it would be attractive to allow inlining even - // if the inline return type is Int32, which it will frequently - // be. return checkResult == DontCheckAtomicResult || getInlineReturnType() == MIRType::Double; case Scalar::BigInt64: @@ -3999,8 +3950,7 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo, // Check that the function doesn't take or return non-compatible JS // argument types before adding nodes to the MIR graph, otherwise they'd be // dead code. - if (sig.hasI64ArgOrRet() || - sig.temporarilyUnsupportedReftypeForInlineEntry() || + if (sig.temporarilyUnsupportedReftypeForInlineEntry() || !JitOptions.enableWasmIonFastCalls) { return InliningStatus_NotInlined; } @@ -4020,6 +3970,26 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo, return InliningStatus_NotInlined; } + // Bug 1631656 - Don't try to inline with I64 args on 32-bit platforms because + // it is more difficult (because it requires multiple LIR arguments per I64). + // + // Bug 1631650 - On 64-bit platforms, we also give up inlining for I64 args + // spilled to the stack because it causes problems with register allocation. +#ifdef JS_64BIT + const bool inlineWithI64 = true; +#else + const bool inlineWithI64 = false; +#endif + ABIArgGenerator abi; + for (const auto& valType : sig.args()) { + MIRType mirType = ToMIRType(valType); + ABIArg abiArg = abi.next(mirType); + if (mirType == MIRType::Int64 && + (!inlineWithI64 || (abiArg.kind() == ABIArg::Stack))) { + return InliningStatus_NotInlined; + } + } + auto* call = MIonToWasmCall::New(alloc(), inst.object(), funcExport); if (!call) { return abort(AbortReason::Alloc); @@ -4047,6 +4017,9 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo, case wasm::ValType::I32: conversion = MTruncateToInt32::New(alloc(), arg); break; + case wasm::ValType::I64: + conversion = MToInt64::New(alloc(), arg); + break; case wasm::ValType::F32: conversion = MToFloat32::New(alloc(), arg); break; @@ -4076,18 +4049,37 @@ IonBuilder::InliningResult IonBuilder::inlineWasmCall(CallInfo& callInfo, MOZ_CRASH("impossible per above check"); } break; - case wasm::ValType::I64: - MOZ_CRASH("impossible per above check"); } current->add(conversion); call->initArg(i, conversion); } - current->push(call); current->add(call); - MOZ_TRY(resumeAfter(call)); + // Add any post-function call conversions that are necessary. + MInstruction* postConversion = call; + const wasm::ValTypeVector& results = sig.results(); + MOZ_ASSERT(results.length() <= 1, "Multi-value returns not supported."); + if (results.length() == 0) { + // No results to convert. + } else { + switch (results[0].kind()) { + case wasm::ValType::I64: + // Ion expects a BigInt from I64 types. + postConversion = MInt64ToBigInt::New(alloc(), call); + + // Make non-movable so we can attach a resume point. + postConversion->setNotMovable(); + + current->add(postConversion); + break; + default: + break; + } + } + current->push(postConversion); + MOZ_TRY(resumeAfter(postConversion)); callInfo.setImplicitlyUsedUnchecked(); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 13b319ecef..b4d907b3b0 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -18,9 +18,12 @@ #include "jit/BaselineInspector.h" #include "jit/IonBuilder.h" #include "jit/JitSpewer.h" +#include "jit/KnownClass.h" #include "jit/MIRGraph.h" #include "jit/RangeAnalysis.h" #include "js/Conversions.h" +#include "js/experimental/JitInfo.h" // JSJitInfo, JSTypedMethodJitInfo +#include "js/ScalarType.h" // js::Scalar::Type #include "util/Text.h" #include "util/Unicode.h" #include "vm/PlainObject.h" // js::PlainObject @@ -813,6 +816,9 @@ void MDefinition::justReplaceAllUsesWith(MDefinition* dom) { if (isUseRemoved()) { dom->setUseRemovedUnchecked(); } + if (isImplicitlyUsed()) { + dom->setImplicitlyUsedUnchecked(); + } for (MUseIterator i(usesBegin()), e(usesEnd()); i != e; ++i) { i->setProducerUnchecked(dom); @@ -1471,21 +1477,28 @@ bool MParameter::congruentTo(const MDefinition* ins) const { } WrappedFunction::WrappedFunction(JSFunction* fun) - : fun_(fun), nargs_(fun->nargs()), flags_(fun->flags()) {} + : nativeFun_(fun->isNativeWithoutJitEntry() ? fun : nullptr), + nargs_(fun->nargs()), + flags_(fun->flags()) { + MOZ_ASSERT(!JitOptions.warpBuilder); +} -WrappedFunction::WrappedFunction(JSFunction* fun, uint16_t nargs, +WrappedFunction::WrappedFunction(JSFunction* nativeFun, uint16_t nargs, FunctionFlags flags) - : fun_(fun), nargs_(nargs), flags_(flags) { + : nativeFun_(nativeFun), nargs_(nargs), flags_(flags) { + MOZ_ASSERT_IF(nativeFun, isNativeWithoutJitEntry()); + #ifdef DEBUG // If we are not running off-main thread we can assert that the // metadata is consistent. - if (!CanUseExtraThreads()) { - MOZ_ASSERT(fun->nargs() == nargs); + if (!CanUseExtraThreads() && nativeFun) { + MOZ_ASSERT(nativeFun->nargs() == nargs); - MOZ_ASSERT(fun->isNativeWithoutJitEntry() == isNativeWithoutJitEntry()); - MOZ_ASSERT(fun->hasJitEntry() == hasJitEntry()); - MOZ_ASSERT(fun->isConstructor() == isConstructor()); - MOZ_ASSERT(fun->isClassConstructor() == isClassConstructor()); + MOZ_ASSERT(nativeFun->isNativeWithoutJitEntry() == + isNativeWithoutJitEntry()); + MOZ_ASSERT(nativeFun->hasJitEntry() == hasJitEntry()); + MOZ_ASSERT(nativeFun->isConstructor() == isConstructor()); + MOZ_ASSERT(nativeFun->isClassConstructor() == isClassConstructor()); } #endif } @@ -1641,6 +1654,30 @@ MDefinition* MConcat::foldsTo(TempAllocator& alloc) { return this; } +MDefinition* MCharCodeAt::foldsTo(TempAllocator& alloc) { + MDefinition* string = this->string(); + if (!string->isConstant()) { + return this; + } + + MDefinition* index = this->index(); + if (index->isSpectreMaskIndex()) { + index = index->toSpectreMaskIndex()->index(); + } + if (!index->isConstant()) { + return this; + } + + JSAtom* atom = &string->toConstant()->toString()->asAtom(); + int32_t idx = index->toConstant()->toInt32(); + if (idx < 0 || uint32_t(idx) >= atom->length()) { + return this; + } + + char16_t ch = atom->latin1OrTwoByteChar(idx); + return MConstant::New(alloc, Int32Value(ch)); +} + static bool EnsureFloatInputOrConvert(MUnaryInstruction* owner, TempAllocator& alloc) { MDefinition* input = owner->input(); @@ -2532,9 +2569,7 @@ static inline bool NeedNegativeZeroCheck(MDefinition* def) { MDefinition* first = use_def->toAdd()->lhs(); MDefinition* second = use_def->toAdd()->rhs(); if (first->id() > second->id()) { - MDefinition* temp = first; - first = second; - second = temp; + std::swap(first, second); } // Negative zero checks can be removed on the first executed // operand only if it is guaranteed the second executed operand @@ -2581,6 +2616,7 @@ static inline bool NeedNegativeZeroCheck(MDefinition* def) { [[fallthrough]]; } case MDefinition::Opcode::StoreElement: + case MDefinition::Opcode::StoreHoleValueElement: case MDefinition::Opcode::LoadElement: case MDefinition::Opcode::LoadElementHole: case MDefinition::Opcode::LoadUnboxedScalar: @@ -3419,9 +3455,10 @@ MCompare::CompareType MCompare::determineCompareType(JSOp op, MDefinition* left, MIRType lhs = left->type(); MIRType rhs = right->type(); - bool looseEq = op == JSOp::Eq || op == JSOp::Ne; - bool strictEq = op == JSOp::StrictEq || op == JSOp::StrictNe; + bool looseEq = IsLooseEqualityOp(op); + bool strictEq = IsStrictEqualityOp(op); bool relationalEq = !(looseEq || strictEq); + MOZ_ASSERT(IsRelationalOp(op) == relationalEq); // Comparisons on unsigned integers may be treated as UInt32. if (unsignedOperands(left, right)) { @@ -3529,14 +3566,25 @@ MDefinition* MBitNot::foldsTo(TempAllocator& alloc) { return this; } +static void AssertKnownClass(TempAllocator& alloc, MInstruction* ins, + MDefinition* obj) { +#ifdef DEBUG + const JSClass* clasp = GetObjectKnownJSClass(obj); + MOZ_ASSERT(clasp); + + auto* assert = MAssertClass::New(alloc, obj, clasp); + ins->block()->insertBefore(ins, assert); +#endif +} + MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) { - // Note: we can't use input->type() here, type analysis has - // boxed the input. - MOZ_ASSERT(input()->type() == MIRType::Value); + if (!input()->isBox()) { + return this; + } + MDefinition* unboxed = input()->toBox()->input(); JSType type; - - switch (inputType()) { + switch (unboxed->type()) { case MIRType::Double: case MIRType::Float32: case MIRType::Int32: @@ -3560,7 +3608,19 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) { case MIRType::Boolean: type = JSTYPE_BOOLEAN; break; - case MIRType::Object: + case MIRType::Object: { + KnownClass known = GetObjectKnownClass(unboxed); + if (known != KnownClass::None) { + if (known == KnownClass::Function) { + type = JSTYPE_FUNCTION; + } else { + type = JSTYPE_OBJECT; + } + + AssertKnownClass(alloc, this, unboxed); + break; + } + if (!inputMaybeCallableOrEmulatesUndefined()) { // Object is not callable and does not emulate undefined, so it's // safe to fold to "object". @@ -3568,6 +3628,7 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) { break; } [[fallthrough]]; + } default: return this; } @@ -3727,6 +3788,57 @@ bool MResumePoint::isRecoverableOperand(MUse* u) const { return block()->info().isRecoverableOperand(indexOf(u)); } +MDefinition* MTruncateBigIntToInt64::foldsTo(TempAllocator& alloc) { + MDefinition* input = getOperand(0); + + if (input->isBox()) { + input = input->getOperand(0); + } + + // If the operand converts an I64 to BigInt, drop both conversions. + if (input->isInt64ToBigInt()) { + return input->getOperand(0); + } + + // Fold this operation if the input operand is constant. + if (input->isConstant()) { + return MConstant::NewInt64( + alloc, BigInt::toInt64(input->toConstant()->toBigInt())); + } + + return this; +} + +MDefinition* MToInt64::foldsTo(TempAllocator& alloc) { + MDefinition* input = getOperand(0); + + if (input->isBox()) { + input = input->getOperand(0); + } + + // Unwrap MInt64ToBigInt: MToInt64(MInt64ToBigInt(int64)) = int64. + if (input->isInt64ToBigInt()) { + return input->getOperand(0); + } + + // When the input is an Int64 already, just return it. + if (input->type() == MIRType::Int64) { + return input; + } + + // Fold this operation if the input operand is constant. + if (input->isConstant()) { + switch (input->type()) { + case MIRType::Boolean: + return MConstant::NewInt64(alloc, input->toConstant()->toBoolean()); + default: + break; + } + } + + return this; +} + MDefinition* MToNumberInt32::foldsTo(TempAllocator& alloc) { MDefinition* input = getOperand(0); @@ -3989,6 +4101,12 @@ MDefinition* MToFloat32::foldsTo(TempAllocator& alloc) { float(input->toConstant()->numberToDouble())); } + // Fold ToFloat32(ToDouble(int32)) to ToFloat32(int32). + if (input->isToDouble() && + input->toToDouble()->input()->type() == MIRType::Int32) { + return MToFloat32::New(alloc, input->toToDouble()->input()); + } + return this; } @@ -4019,12 +4137,12 @@ bool MCompare::tryFoldEqualOperands(bool* result) { return false; } - // Intuitively somebody would think that if lhs == rhs, + // Intuitively somebody would think that if lhs === rhs, // then we can just return true. (Or false for !==) // However NaN !== NaN is true! So we spend some time trying // to eliminate this case. - if (jsop() != JSOp::StrictEq && jsop() != JSOp::StrictNe) { + if (!IsStrictEqualityOp(jsop())) { return false; } @@ -4073,8 +4191,7 @@ bool MCompare::tryFoldTypeOf(bool* result) { return false; } - if (jsop() != JSOp::StrictEq && jsop() != JSOp::StrictNe && - jsop() != JSOp::Eq && jsop() != JSOp::Ne) { + if (!IsEqualityOp(jsop())) { return false; } @@ -4141,7 +4258,7 @@ bool MCompare::tryFold(bool* result) { if (compareType_ == Compare_Null || compareType_ == Compare_Undefined) { // The LHS is the value we want to test against null or undefined. - if (op == JSOp::StrictEq || op == JSOp::StrictNe) { + if (IsStrictEqualityOp(op)) { if (lhs()->type() == inputType()) { *result = (op == JSOp::StrictEq); return true; @@ -4151,7 +4268,7 @@ bool MCompare::tryFold(bool* result) { return true; } } else { - MOZ_ASSERT(op == JSOp::Eq || op == JSOp::Ne); + MOZ_ASSERT(IsLooseEqualityOp(op)); if (IsNullOrUndefined(lhs()->type())) { *result = (op == JSOp::Eq); return true; @@ -4168,7 +4285,7 @@ bool MCompare::tryFold(bool* result) { } if (compareType_ == Compare_Boolean) { - MOZ_ASSERT(op == JSOp::StrictEq || op == JSOp::StrictNe); + MOZ_ASSERT(IsStrictEqualityOp(op)); MOZ_ASSERT(rhs()->type() == MIRType::Boolean); MOZ_ASSERT(lhs()->type() != MIRType::Boolean, "Should use Int32 comparison"); @@ -4181,7 +4298,7 @@ bool MCompare::tryFold(bool* result) { } if (compareType_ == Compare_StrictString) { - MOZ_ASSERT(op == JSOp::StrictEq || op == JSOp::StrictNe); + MOZ_ASSERT(IsStrictEqualityOp(op)); MOZ_ASSERT(rhs()->type() == MIRType::String); MOZ_ASSERT(lhs()->type() != MIRType::String, "Should use String comparison"); @@ -4355,6 +4472,69 @@ bool MCompare::evaluateConstantOperands(TempAllocator& alloc, bool* result) { return false; } +MDefinition* MCompare::tryFoldCharCompare(TempAllocator& alloc) { + if (compareType() != Compare_String) { + return this; + } + + MDefinition* left = lhs(); + MOZ_ASSERT(left->type() == MIRType::String); + + MDefinition* right = rhs(); + MOZ_ASSERT(right->type() == MIRType::String); + + // |str[i]| is compiled as |MFromCharCode(MCharCodeAt(str, i))|. + auto isCharAccess = [](MDefinition* ins) { + return ins->isFromCharCode() && + ins->toFromCharCode()->input()->isCharCodeAt(); + }; + + if (left->isConstant() || right->isConstant()) { + // Try to optimize |MConstant(string) (MFromCharCode MCharCodeAt)| + // as |MConstant(charcode) MCharCodeAt|. + MConstant* constant; + MDefinition* operand; + if (left->isConstant()) { + constant = left->toConstant(); + operand = right; + } else { + constant = right->toConstant(); + operand = left; + } + + if (constant->toString()->length() != 1 || !isCharAccess(operand)) { + return this; + } + + char16_t charCode = constant->toString()->asAtom().latin1OrTwoByteChar(0); + MConstant* charCodeConst = MConstant::New(alloc, Int32Value(charCode)); + block()->insertBefore(this, charCodeConst); + + MDefinition* charCodeAt = operand->toFromCharCode()->input(); + + if (left->isConstant()) { + left = charCodeConst; + right = charCodeAt; + } else { + left = charCodeAt; + right = charCodeConst; + } + } else if (isCharAccess(left) && isCharAccess(right)) { + // Try to optimize |(MFromCharCode MCharCodeAt) (MFromCharCode + // MCharCodeAt)| as |MCharCodeAt MCharCodeAt|. + + left = left->toFromCharCode()->input(); + right = right->toFromCharCode()->input(); + } else { + return this; + } + + MCompare* ins = MCompare::New(alloc, left, right, jsop()); + ins->setCompareType(MCompare::Compare_Int32); + + return ins; +} + MDefinition* MCompare::foldsTo(TempAllocator& alloc) { bool result; @@ -4367,6 +4547,10 @@ MDefinition* MCompare::foldsTo(TempAllocator& alloc) { return MConstant::New(alloc, BooleanValue(result)); } + if (MDefinition* folded = tryFoldCharCompare(alloc); folded != this) { + return folded; + } + return this; } @@ -4397,8 +4581,7 @@ void MCompare::filtersUndefinedOrNull(bool trueBranch, MDefinition** subject, return; } - MOZ_ASSERT(jsop() == JSOp::StrictNe || jsop() == JSOp::Ne || - jsop() == JSOp::StrictEq || jsop() == JSOp::Eq); + MOZ_ASSERT(IsEqualityOp(jsop())); // JSOp::*Ne only removes undefined/null from if/true branch if (!trueBranch && (jsop() == JSOp::StrictNe || jsop() == JSOp::Ne)) { @@ -4410,7 +4593,7 @@ void MCompare::filtersUndefinedOrNull(bool trueBranch, MDefinition** subject, return; } - if (jsop() == JSOp::StrictEq || jsop() == JSOp::StrictNe) { + if (IsStrictEqualityOp(jsop())) { *filtersUndefined = compareType() == Compare_Undefined; *filtersNull = compareType() == Compare_Null; } else { @@ -4940,6 +5123,18 @@ void MStoreDynamicSlot::printOpcode(GenericPrinter& out) const { } #endif +MDefinition* MGuardFunctionScript::foldsTo(TempAllocator& alloc) { + if (input()->isLambda() && + input()->toLambda()->info().baseScript == expected()) { + return input(); + } + if (input()->isLambdaArrow() && + input()->toLambdaArrow()->info().baseScript == expected()) { + return input(); + } + return this; +} + MDefinition* MFunctionEnvironment::foldsTo(TempAllocator& alloc) { if (input()->isLambda()) { return input()->toLambda()->environmentChain(); @@ -5525,6 +5720,11 @@ MDefinition* MGetFirstDollarIndex::foldsTo(TempAllocator& alloc) { MDefinition* MTypedArrayIndexToInt32::foldsTo(TempAllocator& alloc) { MDefinition* input = getOperand(0); + + if (input->isToDouble() && input->getOperand(0)->type() == MIRType::Int32) { + return input->getOperand(0); + } + if (!input->isConstant() || input->type() != MIRType::Double) { return this; } @@ -5540,6 +5740,19 @@ MDefinition* MTypedArrayIndexToInt32::foldsTo(TempAllocator& alloc) { return MConstant::New(alloc, Int32Value(ival)); } +MDefinition* MIsObject::foldsTo(TempAllocator& alloc) { + if (!object()->isBox()) { + return this; + } + + MDefinition* unboxed = object()->getOperand(0); + if (unboxed->type() == MIRType::Object) { + return MConstant::New(alloc, BooleanValue(true)); + } + + return this; +} + MDefinition* MIsNullOrUndefined::foldsTo(TempAllocator& alloc) { MDefinition* input = value(); if (input->isBox()) { @@ -5558,6 +5771,99 @@ MDefinition* MIsNullOrUndefined::foldsTo(TempAllocator& alloc) { return this; } +static MDefinition* SkipObjectGuards(MDefinition* ins) { + // These instructions don't modify the object and just guard specific + // properties. + while (true) { + if (ins->isGuardShape()) { + ins = ins->toGuardShape()->object(); + continue; + } + if (ins->isGuardObjectGroup()) { + ins = ins->toGuardObjectGroup()->object(); + continue; + } + if (ins->isGuardNullProto()) { + ins = ins->toGuardNullProto()->object(); + continue; + } + if (ins->isGuardProto()) { + ins = ins->toGuardProto()->object(); + continue; + } + + break; + } + + return ins; +} + +MDefinition* MGuardShape::foldsTo(TempAllocator& alloc) { + MDefinition* ins = dependency(); + if (!ins) { + return this; + } + + if (!ins->block()->dominates(block())) { + return this; + } + + auto AssertShape = [](TempAllocator& alloc, MGuardShape* ins) { +#ifdef DEBUG + auto* assert = MAssertShape::New(alloc, ins->object(), + const_cast(ins->shape())); + ins->block()->insertBefore(ins, assert); +#endif + }; + + if (ins->isAddAndStoreSlot()) { + auto* add = ins->toAddAndStoreSlot(); + + if (SkipObjectGuards(add->object()) != SkipObjectGuards(object()) || + add->shape() != shape()) { + return this; + } + + AssertShape(alloc, this); + return object(); + } + + if (ins->isAllocateAndStoreSlot()) { + auto* allocate = ins->toAllocateAndStoreSlot(); + + if (SkipObjectGuards(allocate->object()) != SkipObjectGuards(object()) || + allocate->shape() != shape()) { + return this; + } + + AssertShape(alloc, this); + return object(); + } + + if (ins->isStart()) { + // The guard doesn't depend on any other instruction that is modifying + // the object operand, so check it directly. + auto* obj = SkipObjectGuards(object()); + if (!obj->isNewObject()) { + return this; + } + + JSObject* templateObject = obj->toNewObject()->templateObject(); + if (!templateObject) { + return this; + } + + if (templateObject->shape() != shape()) { + return this; + } + + AssertShape(alloc, this); + return object(); + } + + return this; +} + MDefinition* MGuardValue::foldsTo(TempAllocator& alloc) { if (MConstant* cst = value()->maybeConstantValue()) { if (cst->toJSValue() == expected()) { @@ -5568,6 +5874,31 @@ MDefinition* MGuardValue::foldsTo(TempAllocator& alloc) { return this; } +/* static */ +bool MGuardNotOptimizedArguments::maybeIsOptimizedArguments(MDefinition* def) { + if (def->isBox()) { + def = def->toBox()->input(); + } + + if (def->type() != MIRType::Value && + def->type() != MIRType::MagicOptimizedArguments) { + return false; + } + + // Only phis and constants can produce optimized-arguments. + MOZ_ASSERT_IF(def->type() == MIRType::MagicOptimizedArguments, + def->isConstant()); + return def->isConstant() || def->isPhi(); +} + +MDefinition* MGuardNotOptimizedArguments::foldsTo(TempAllocator& alloc) { + if (!maybeIsOptimizedArguments(value())) { + return value(); + } + + return this; +} + MDefinition* MGuardNullOrUndefined::foldsTo(TempAllocator& alloc) { MDefinition* input = value(); if (input->isBox()) { @@ -5582,18 +5913,25 @@ MDefinition* MGuardNullOrUndefined::foldsTo(TempAllocator& alloc) { } MDefinition* MGuardObjectIdentity::foldsTo(TempAllocator& alloc) { - if (!object()->isConstant()) { - return this; + if (object()->isConstant() && expected()->isConstant()) { + JSObject* obj = &object()->toConstant()->toObject(); + JSObject* other = &expected()->toConstant()->toObject(); + if (!bailOnEquality()) { + if (obj == other) { + return object(); + } + } else { + if (obj != other) { + return object(); + } + } } - JSObject* obj = &object()->toConstant()->toObject(); - JSObject* other = &expected()->toConstant()->toObject(); - if (!bailOnEquality()) { - if (obj == other) { - return object(); - } - } else { - if (obj != other) { + if (!bailOnEquality() && object()->isNurseryObject() && + expected()->isNurseryObject()) { + uint32_t objIndex = object()->toNurseryObject()->nurseryIndex(); + uint32_t otherIndex = expected()->toNurseryObject()->nurseryIndex(); + if (objIndex == otherIndex) { return object(); } } @@ -5602,7 +5940,7 @@ MDefinition* MGuardObjectIdentity::foldsTo(TempAllocator& alloc) { } MDefinition* MGuardSpecificFunction::foldsTo(TempAllocator& alloc) { - if (function()->isConstant()) { + if (function()->isConstant() && expected()->isConstant()) { JSObject* fun = &function()->toConstant()->toObject(); JSObject* other = &expected()->toConstant()->toObject(); if (fun == other) { @@ -5610,6 +5948,14 @@ MDefinition* MGuardSpecificFunction::foldsTo(TempAllocator& alloc) { } } + if (function()->isNurseryObject() && expected()->isNurseryObject()) { + uint32_t funIndex = function()->toNurseryObject()->nurseryIndex(); + uint32_t otherIndex = expected()->toNurseryObject()->nurseryIndex(); + if (funIndex == otherIndex) { + return function(); + } + } + return this; } @@ -5634,11 +5980,137 @@ MDefinition* MGuardSpecificSymbol::foldsTo(TempAllocator& alloc) { return this; } +MDefinition* MGuardIsNotProxy::foldsTo(TempAllocator& alloc) { + KnownClass known = GetObjectKnownClass(object()); + if (known == KnownClass::None) { + return this; + } + + MOZ_ASSERT(!GetObjectKnownJSClass(object())->isProxy()); + AssertKnownClass(alloc, this, object()); + return object(); +} + +MDefinition* MGuardStringToIndex::foldsTo(TempAllocator& alloc) { + if (!string()->isConstant()) { + return this; + } + + JSAtom* atom = &string()->toConstant()->toString()->asAtom(); + + int32_t index = GetIndexFromString(atom); + if (index < 0) { + return this; + } + + return MConstant::New(alloc, Int32Value(index)); +} + +MDefinition* MGuardStringToInt32::foldsTo(TempAllocator& alloc) { + if (!string()->isConstant()) { + return this; + } + + JSAtom* atom = &string()->toConstant()->toString()->asAtom(); + if (!atom->hasIndexValue()) { + return this; + } + + uint32_t index = atom->getIndexValue(); + MOZ_ASSERT(index <= INT32_MAX); + return MConstant::New(alloc, Int32Value(index)); +} + +MDefinition* MGuardStringToDouble::foldsTo(TempAllocator& alloc) { + if (!string()->isConstant()) { + return this; + } + + JSAtom* atom = &string()->toConstant()->toString()->asAtom(); + if (!atom->hasIndexValue()) { + return this; + } + + uint32_t index = atom->getIndexValue(); + MOZ_ASSERT(index <= INT32_MAX); + return MConstant::New(alloc, DoubleValue(index)); +} + MDefinition* MGuardToClass::foldsTo(TempAllocator& alloc) { - if (getClass() == &ArrayObject::class_) { - if (object()->isNewArray() || object()->isNewArrayCopyOnWrite()) { + const JSClass* clasp = GetObjectKnownJSClass(object()); + if (!clasp || getClass() != clasp) { + return this; + } + + AssertKnownClass(alloc, this, object()); + return object(); +} + +MDefinition* MHasClass::foldsTo(TempAllocator& alloc) { + const JSClass* clasp = GetObjectKnownJSClass(object()); + if (!clasp) { + return this; + } + + AssertKnownClass(alloc, this, object()); + return MConstant::New(alloc, BooleanValue(getClass() == clasp)); +} + +MDefinition* MIsCallable::foldsTo(TempAllocator& alloc) { + if (input()->type() != MIRType::Object) { + return this; + } + + KnownClass known = GetObjectKnownClass(input()); + if (known == KnownClass::None) { + return this; + } + + AssertKnownClass(alloc, this, input()); + return MConstant::New(alloc, BooleanValue(known == KnownClass::Function)); +} + +MDefinition* MIsArray::foldsTo(TempAllocator& alloc) { + if (input()->type() != MIRType::Object) { + return this; + } + + KnownClass known = GetObjectKnownClass(input()); + if (known == KnownClass::None) { + return this; + } + + AssertKnownClass(alloc, this, input()); + return MConstant::New(alloc, BooleanValue(known == KnownClass::Array)); +} + +MDefinition* MGuardIsNotArrayBufferMaybeShared::foldsTo(TempAllocator& alloc) { + switch (GetObjectKnownClass(object())) { + case KnownClass::PlainObject: + case KnownClass::Array: + case KnownClass::Function: + case KnownClass::RegExp: + case KnownClass::ArrayIterator: + case KnownClass::StringIterator: + case KnownClass::RegExpStringIterator: { + AssertKnownClass(alloc, this, object()); return object(); } + case KnownClass::None: + break; + } + + return this; +} + +MDefinition* MCheckIsObj::foldsTo(TempAllocator& alloc) { + if (!input()->isBox()) { + return this; + } + + MDefinition* unboxed = input()->getOperand(0); + if (unboxed->type() == MIRType::Object) { + return unboxed; } return this; @@ -6206,7 +6678,7 @@ static MInstruction* AddGroupGuard(TempAllocator& alloc, MBasicBlock* current, if (key->isGroup()) { guard = MGuardObjectGroup::New(alloc, obj, key->group(), bailOnEquality, - Bailout_ObjectIdentityOrTypeGuard); + BailoutKind::ObjectIdentityOrTypeGuard); } else { MConstant* singletonConst = MConstant::NewConstraintlessObject(alloc, key->singleton()); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index f476dde35c..6bc944d684 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -18,17 +18,20 @@ #include #include +#include "builtin/ModuleObject.h" #include "jit/AtomicOp.h" #include "jit/BaselineIC.h" #include "jit/FixedList.h" #include "jit/InlineList.h" #include "jit/JitAllocPolicy.h" -#include "jit/MacroAssembler.h" #include "jit/MOpcodesGenerated.h" #include "jit/TIOracle.h" #include "jit/TypePolicy.h" +#include "js/experimental/JitInfo.h" // JSJit{Getter,Setter}Op, JSJitInfo #include "js/HeapAPI.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "vm/ArrayObject.h" +#include "vm/BuiltinObjectKind.h" #include "vm/EnvironmentObject.h" #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/RegExpObject.h" @@ -366,10 +369,10 @@ class AliasSet { WasmStackResult = 1 << 12, // A stack result from the current function // JSContext's exception state. This is used on instructions like MThrow - // that throw exceptions (other than OOM) but have no other side effect, to - // ensure that they get their own up-to-date resume point. (This resume - // point will be used when constructing the Baseline frame during exception - // bailouts.) + // or MNewArrayDynamicLength that throw exceptions (other than OOM) but have + // no other side effect, to ensure that they get their own up-to-date resume + // point. (This resume point will be used when constructing the Baseline + // frame during exception bailouts.) ExceptionState = 1 << 13, Last = ExceptionState, @@ -1001,7 +1004,7 @@ class CompilerGCPointer { using CompilerObject = CompilerGCPointer; using CompilerNativeObject = CompilerGCPointer; using CompilerFunction = CompilerGCPointer; -using CompilerScript = CompilerGCPointer; +using CompilerBaseScript = CompilerGCPointer; using CompilerPropertyName = CompilerGCPointer; using CompilerShape = CompilerGCPointer; using CompilerObjectGroup = CompilerGCPointer; @@ -1031,6 +1034,17 @@ class MRootList : public TempObject { return true; } + MOZ_MUST_USE bool append(jsid id) { + if (id.isString()) { + return append(id.toString()); + } + if (id.isSymbol()) { + return append(id.toSymbol()); + } + MOZ_ASSERT(!id.isGCThing()); + return true; + } + template MOZ_MUST_USE bool append(const CompilerGCPointer& ptr) { return append(static_cast(ptr)); @@ -1253,21 +1267,15 @@ class MBinaryInstruction : public MAryInstruction<2> { const MDefinition* left = getOperand(0); const MDefinition* right = getOperand(1); - const MDefinition* tmp; - if (isCommutative() && left->id() > right->id()) { - tmp = right; - right = left; - left = tmp; + std::swap(left, right); } const MBinaryInstruction* bi = static_cast(ins); const MDefinition* insLeft = bi->getOperand(0); const MDefinition* insRight = bi->getOperand(1); - if (isCommutative() && insLeft->id() > insRight->id()) { - tmp = insRight; - insRight = insLeft; - insLeft = tmp; + if (bi->isCommutative() && insLeft->id() > insRight->id()) { + std::swap(insLeft, insRight); } return left == insLeft && right == insRight; @@ -1646,19 +1654,6 @@ class MWasmFloatConstant : public MNullaryInstruction { } }; -// Deep clone a constant JSObject. -class MCloneLiteral : public MUnaryInstruction, public ObjectPolicy<0>::Data { - protected: - explicit MCloneLiteral(MDefinition* obj) - : MUnaryInstruction(classOpcode, obj) { - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(CloneLiteral) - TRIVIAL_NEW_WRAPPERS -}; - class MParameter : public MNullaryInstruction { int32_t index_; @@ -1960,26 +1955,6 @@ class MTest : public MAryControlInstruction<1, 2>, public TestPolicy::Data { #endif }; -// Equivalent to MTest(true, successor, fake), except without the foldsTo -// method. This allows IonBuilder to insert fake CFG edges to magically protect -// control flow for try-catch blocks. -class MGotoWithFake : public MAryControlInstruction<0, 2>, - public NoTypePolicy::Data { - MGotoWithFake(MBasicBlock* successor, MBasicBlock* fake) - : MAryControlInstruction(classOpcode) { - setSuccessor(0, successor); - setSuccessor(1, fake); - } - - public: - INSTRUCTION_HEADER(GotoWithFake) - TRIVIAL_NEW_WRAPPERS - - MBasicBlock* target() const { return getSuccessor(0); } - - AliasSet getAliasSet() const override { return AliasSet::None(); } -}; - // Returns from this function to the previous caller. class MReturn : public MAryControlInstruction<1, 0>, public BoxInputsPolicy::Data { @@ -2138,7 +2113,7 @@ class MNewArrayDynamicLength : public MUnaryInstruction, initialHeap_(initialHeap) { setGuard(); // Need to throw if length is negative. setResultType(MIRType::Object); - if (!templateObject->isSingleton()) { + if (!JitOptions.warpBuilder && !templateObject->isSingleton()) { setResultTypeSet( MakeSingletonTypeSet(alloc, constraints, templateObject)); } @@ -2152,7 +2127,10 @@ class MNewArrayDynamicLength : public MUnaryInstruction, JSObject* templateObject() const { return templateObject_; } gc::InitialHeap initialHeap() const { return initialHeap_; } - virtual AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + // Throws if length is negative. + return AliasSet::Store(AliasSet::ExceptionState); + } bool appendRoots(MRootList& roots) const override { return roots.append(templateObject_); @@ -2168,8 +2146,10 @@ class MNewTypedArray : public MUnaryInstruction, public NoTypePolicy::Data { initialHeap_(initialHeap) { MOZ_ASSERT(!templateObject()->isSingleton()); setResultType(MIRType::Object); - setResultTypeSet( - MakeSingletonTypeSet(alloc, constraints, templateObject())); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject())); + } } public: @@ -2204,7 +2184,10 @@ class MNewTypedArrayDynamicLength : public MUnaryInstruction, MOZ_ASSERT(!templateObject->isSingleton()); setGuard(); // Need to throw if length is negative. setResultType(MIRType::Object); - setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, templateObject)); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject)); + } } public: @@ -2215,7 +2198,10 @@ class MNewTypedArrayDynamicLength : public MUnaryInstruction, JSObject* templateObject() const { return templateObject_; } gc::InitialHeap initialHeap() const { return initialHeap_; } - virtual AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + // Throws if length is negative. + return AliasSet::Store(AliasSet::ExceptionState); + } bool appendRoots(MRootList& roots) const override { return roots.append(templateObject_); @@ -2238,7 +2224,10 @@ class MNewTypedArrayFromArray : public MUnaryInstruction, MOZ_ASSERT(!templateObject->isSingleton()); setGuard(); // Can throw during construction. setResultType(MIRType::Object); - setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, templateObject)); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject)); + } } public: @@ -2275,7 +2264,10 @@ class MNewTypedArrayFromArrayBuffer MOZ_ASSERT(!templateObject->isSingleton()); setGuard(); // Can throw during construction. setResultType(MIRType::Object); - setResultTypeSet(MakeSingletonTypeSet(alloc, constraints, templateObject)); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject)); + } } public: @@ -2375,8 +2367,10 @@ class MNewIterator : public MUnaryInstruction, public NoTypePolicy::Data { MConstant* templateConst, Type type) : MUnaryInstruction(classOpcode, templateConst), type_(type) { setResultType(MIRType::Object); - setResultTypeSet( - MakeSingletonTypeSet(alloc, constraints, templateObject())); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject())); + } templateConst->setEmittedAtUses(); } @@ -2601,18 +2595,19 @@ class MInitElemGetterSetter NAMED_OPERANDS((0, object), (1, idValue), (2, value)) }; -// WrappedFunction wraps a JSFunction so it can safely be used off-thread. -// In particular, a function's flags can be modified on the main thread as -// functions are relazified and delazified, so we must be careful not to access -// these flags off-thread. +// WrappedFunction stores information about a function that can safely be used +// off-thread. In particular, a function's flags can be modified on the main +// thread as functions are relazified and delazified, so we must be careful not +// to access these flags off-thread. class WrappedFunction : public TempObject { - CompilerFunction fun_; + // If this is a native function without a JitEntry, the JSFunction*. + CompilerFunction nativeFun_; uint16_t nargs_; js::FunctionFlags flags_; public: explicit WrappedFunction(JSFunction* fun); - WrappedFunction(JSFunction* fun, uint16_t nargs, FunctionFlags flags); + WrappedFunction(JSFunction* nativeFun, uint16_t nargs, FunctionFlags flags); // Note: When adding new accessors be sure to add consistency asserts // to the constructor. @@ -2629,19 +2624,24 @@ class WrappedFunction : public TempObject { // These fields never change, they can be accessed off-main thread. JSNative native() const { MOZ_ASSERT(isNativeWithoutJitEntry()); - return fun_->nativeUnchecked(); + return nativeFun_->nativeUnchecked(); } bool hasJitInfo() const { - return flags_.isBuiltinNative() && fun_->jitInfoUnchecked(); + return flags_.isBuiltinNative() && nativeFun_->jitInfoUnchecked(); } const JSJitInfo* jitInfo() const { MOZ_ASSERT(hasJitInfo()); - return fun_->jitInfoUnchecked(); + return nativeFun_->jitInfoUnchecked(); } - JSFunction* rawJSFunction() const { return fun_; } + JSFunction* rawNativeJSFunction() const { return nativeFun_; } - bool appendRoots(MRootList& roots) const { return roots.append(fun_); } + bool appendRoots(MRootList& roots) const { + if (nativeFun_) { + return roots.append(nativeFun_); + } + return true; + } }; class MCall : public MVariadicInstruction, public CallPolicy::Data { @@ -2950,7 +2950,7 @@ class MBail : public MNullaryInstruction { return new (alloc) MBail(kind); } static MBail* New(TempAllocator& alloc) { - return new (alloc) MBail(Bailout_Inevitable); + return new (alloc) MBail(BailoutKind::Inevitable); } AliasSet getAliasSet() const override { return AliasSet::None(); } @@ -3256,10 +3256,12 @@ class MCompare : public MBinaryInstruction, public ComparePolicy::Data { ALLOW_CLONE(MCompare) - protected: + private: MOZ_MUST_USE bool tryFoldEqualOperands(bool* result); MOZ_MUST_USE bool tryFoldTypeOf(bool* result); + MOZ_MUST_USE MDefinition* tryFoldCharCompare(TempAllocator& alloc); + public: bool congruentTo(const MDefinition* ins) const override { if (!binaryCongruentTo(ins)) { return false; @@ -3371,25 +3373,25 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data { BailoutKind kind; switch (type) { case MIRType::Boolean: - kind = Bailout_NonBooleanInput; + kind = BailoutKind::NonBooleanInput; break; case MIRType::Int32: - kind = Bailout_NonInt32Input; + kind = BailoutKind::NonInt32Input; break; case MIRType::Double: - kind = Bailout_NonNumericInput; // Int32s are fine too + kind = BailoutKind::NonNumericInput; // Int32s are fine too break; case MIRType::String: - kind = Bailout_NonStringInput; + kind = BailoutKind::NonStringInput; break; case MIRType::Symbol: - kind = Bailout_NonSymbolInput; + kind = BailoutKind::NonSymbolInput; break; case MIRType::BigInt: - kind = Bailout_NonBigIntInput; + kind = BailoutKind::NonBigIntInput; break; case MIRType::Object: - kind = Bailout_NonObjectInput; + kind = BailoutKind::NonObjectInput; break; default: MOZ_CRASH("Given MIRType cannot be unboxed."); @@ -3505,6 +3507,47 @@ class MAssertRange : public MUnaryInstruction, public NoTypePolicy::Data { #endif }; +class MAssertClass : public MUnaryInstruction, public NoTypePolicy::Data { + const JSClass* class_; + + MAssertClass(MDefinition* obj, const JSClass* clasp) + : MUnaryInstruction(classOpcode, obj), class_(clasp) { + MOZ_ASSERT(obj->type() == MIRType::Object); + + setGuard(); + setResultType(MIRType::None); + } + + public: + INSTRUCTION_HEADER(AssertClass) + TRIVIAL_NEW_WRAPPERS + + const JSClass* getClass() const { return class_; } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +class MAssertShape : public MUnaryInstruction, public NoTypePolicy::Data { + CompilerShape shape_; + + MAssertShape(MDefinition* obj, Shape* shape) + : MUnaryInstruction(classOpcode, obj), shape_(shape) { + MOZ_ASSERT(obj->type() == MIRType::Object); + + setGuard(); + setResultType(MIRType::None); + } + + public: + INSTRUCTION_HEADER(AssertShape) + TRIVIAL_NEW_WRAPPERS + + const Shape* shape() const { return shape_; } + AliasSet getAliasSet() const override { return AliasSet::None(); } + bool appendRoots(MRootList& roots) const override { + return roots.append(shape_); + } +}; + // Caller-side allocation of |this| for |new|: // Given a templateobject, construct |this| for JSOp::New. // Not used for JSOp::SuperCall, because Baseline doesn't attach template @@ -3519,8 +3562,10 @@ class MCreateThisWithTemplate : public MUnaryInstruction, : MUnaryInstruction(classOpcode, templateConst), initialHeap_(initialHeap) { setResultType(MIRType::Object); - setResultTypeSet( - MakeSingletonTypeSet(alloc, constraints, templateObject())); + if (!JitOptions.warpBuilder) { + setResultTypeSet( + MakeSingletonTypeSet(alloc, constraints, templateObject())); + } } public: @@ -3628,6 +3673,16 @@ class MGetArgumentsObjectArg : public MUnaryInstruction, size_t argno() const { return argno_; } + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGetArgumentsObjectArg()) { + return false; + } + if (ins->toGetArgumentsObjectArg()->argno() != argno()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::Any); } @@ -3653,6 +3708,60 @@ class MSetArgumentsObjectArg } }; +// Load |arguments[index]| from a mapped or unmapped arguments object. Bails out +// if any elements were overridden or deleted. Also bails out if the index is +// out of bounds. +class MLoadArgumentsObjectArg + : public MBinaryInstruction, + public MixPolicy, UnboxedInt32Policy<1>>::Data { + MLoadArgumentsObjectArg(MDefinition* object, MDefinition* index) + : MBinaryInstruction(classOpcode, object, index) { + setResultType(MIRType::Value); + setGuard(); + } + + public: + INSTRUCTION_HEADER(LoadArgumentsObjectArg) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, getArgsObject), (1, index)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::Any); + } +}; + +// Load |arguments.length|. Bails out if the length has been overriden. +class MArgumentsObjectLength : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MArgumentsObjectLength(MDefinition* argsObj) + : MUnaryInstruction(classOpcode, argsObj) { + setResultType(MIRType::Int32); + setMovable(); + setGuard(); + } + + public: + INSTRUCTION_HEADER(ArgumentsObjectLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, getArgsObject)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { + // Even though the "length" property is lazily resolved, it acts similar to + // a normal property load, so we can treat this operation like any other + // property read. + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } +}; + // Given a MIRType::Value A and a MIRType::Object B: // If the Value may be safely unboxed to an Object, return Object(A). // Otherwise, return B. @@ -4233,6 +4342,87 @@ class MToBigInt : public MUnaryInstruction, public ToBigIntPolicy::Data { ALLOW_CLONE(MToBigInt) }; +// Takes a Value or typed input and returns a suitable Int64 using the +// ToBigInt algorithm, possibly calling out to the VM for string, etc inputs. +class MToInt64 : public MUnaryInstruction, public ToInt64Policy::Data { + explicit MToInt64(MDefinition* def) : MUnaryInstruction(classOpcode, def) { + setResultType(MIRType::Int64); + setMovable(); + + // An object might have "valueOf", which means it is effectful. + // ToBigInt(undefined), ToBigInt(null), ToBigInt(number), and + // ToBigInt(symbol) all throw. + if (def->mightBeType(MIRType::Object) || + def->mightBeType(MIRType::Undefined) || + def->mightBeType(MIRType::Null) || def->mightBeType(MIRType::Double) || + def->mightBeType(MIRType::Float32) || + def->mightBeType(MIRType::Int32) || def->mightBeType(MIRType::Symbol)) { + setGuard(); + } + } + + public: + INSTRUCTION_HEADER(ToInt64) + TRIVIAL_NEW_WRAPPERS + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { return AliasSet::None(); } + + MDefinition* foldsTo(TempAllocator& alloc) override; + + ALLOW_CLONE(MToInt64) +}; + +// Takes a BigInt pointer and returns its toInt64 value. +class MTruncateBigIntToInt64 : public MUnaryInstruction, + public NoTypePolicy::Data { + explicit MTruncateBigIntToInt64(MDefinition* def) + : MUnaryInstruction(classOpcode, def) { + MOZ_ASSERT(def->type() == MIRType::BigInt); + setResultType(MIRType::Int64); + setMovable(); + } + + public: + INSTRUCTION_HEADER(TruncateBigIntToInt64) + TRIVIAL_NEW_WRAPPERS + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { return AliasSet::None(); } + + MDefinition* foldsTo(TempAllocator& alloc) override; + + ALLOW_CLONE(MTruncateBigIntToInt64) +}; + +// Takes an Int64 and returns a fresh BigInt pointer. +class MInt64ToBigInt : public MUnaryInstruction, public NoTypePolicy::Data { + explicit MInt64ToBigInt(MDefinition* def) + : MUnaryInstruction(classOpcode, def) { + MOZ_ASSERT(def->type() == MIRType::Int64); + setResultType(MIRType::BigInt); + setMovable(); + } + + public: + INSTRUCTION_HEADER(Int64ToBigInt) + TRIVIAL_NEW_WRAPPERS + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { return AliasSet::None(); } + + ALLOW_CLONE(MInt64ToBigInt) +}; + // Converts any type to a string class MToString : public MUnaryInstruction, public ToStringPolicy::Data { public: @@ -4321,7 +4511,10 @@ class MToObject : public MUnaryInstruction, public BoxInputsPolicy::Data { INSTRUCTION_HEADER(ToObject) TRIVIAL_NEW_WRAPPERS - AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + // Throws on null or undefined. + return AliasSet::Store(AliasSet::ExceptionState); + } ALLOW_CLONE(MToObject) }; @@ -4374,12 +4567,10 @@ class MBitNot : public MUnaryInstruction, public BitwisePolicy::Data { }; class MTypeOf : public MUnaryInstruction, public BoxInputsPolicy::Data { - MIRType inputType_; bool inputMaybeCallableOrEmulatesUndefined_; - MTypeOf(MDefinition* def, MIRType inputType) + explicit MTypeOf(MDefinition* def) : MUnaryInstruction(classOpcode, def), - inputType_(inputType), inputMaybeCallableOrEmulatesUndefined_(true) { setResultType(MIRType::String); setMovable(); @@ -4389,8 +4580,6 @@ class MTypeOf : public MUnaryInstruction, public BoxInputsPolicy::Data { INSTRUCTION_HEADER(TypeOf) TRIVIAL_NEW_WRAPPERS - MIRType inputType() const { return inputType_; } - MDefinition* foldsTo(TempAllocator& alloc) override; void cacheInputMaybeCallableOrEmulatesUndefined( CompilerConstraintList* constraints); @@ -4408,9 +4597,6 @@ class MTypeOf : public MUnaryInstruction, public BoxInputsPolicy::Data { if (!ins->isTypeOf()) { return false; } - if (inputType() != ins->toTypeOf()->inputType()) { - return false; - } if (inputMaybeCallableOrEmulatesUndefined() != ins->toTypeOf()->inputMaybeCallableOrEmulatesUndefined()) { return false; @@ -5711,6 +5897,7 @@ class MCharCodeAt public: INSTRUCTION_HEADER(CharCodeAt) TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, string), (1, index)) bool congruentTo(const MDefinition* ins) const override { return congruentIfOperandsEqual(ins); @@ -5721,6 +5908,8 @@ class MCharCodeAt return AliasSet::None(); } + MDefinition* foldsTo(TempAllocator& alloc) override; + void computeRange(TempAllocator& alloc) override; MOZ_MUST_USE bool writeRecoverData( @@ -5811,8 +6000,10 @@ class MStringSplit : public MBinaryInstruction, MDefinition* string, MDefinition* sep, ObjectGroup* group) : MBinaryInstruction(classOpcode, string, sep), group_(group) { setResultType(MIRType::Object); - TemporaryTypeSet* types = MakeSingletonTypeSet(alloc, constraints, group); - setResultTypeSet(types); + if (!JitOptions.warpBuilder) { + TemporaryTypeSet* types = MakeSingletonTypeSet(alloc, constraints, group); + setResultTypeSet(types); + } } public: @@ -5838,18 +6029,31 @@ class MStringSplit : public MBinaryInstruction, // Returns the object to use as |this| value in a non-strict function. See also // BoxNonStrictThis in Interpreter.h. class MBoxNonStrictThis : public MUnaryInstruction, public BoxPolicy<0>::Data { - explicit MBoxNonStrictThis(MDefinition* def) - : MUnaryInstruction(classOpcode, def) { + CompilerObject globalThis_; + + MBoxNonStrictThis(MDefinition* def, JSObject* globalThis) + : MUnaryInstruction(classOpcode, def), globalThis_(globalThis) { setResultType(MIRType::Object); + setMovable(); } public: INSTRUCTION_HEADER(BoxNonStrictThis) TRIVIAL_NEW_WRAPPERS + JSObject* globalThis() const { return globalThis_; } + bool possiblyCalls() const override { return true; } - // Note: don't override getAliasSet: the thisValue hook can be effectful. + AliasSet getAliasSet() const override { + // This instruction can allocate a new object for wrapped primitives, but + // has no effect on existing objects. + return AliasSet::None(); + } + + bool appendRoots(MRootList& roots) const override { + return roots.append(globalThis_); + } }; class MImplicitThis : public MUnaryInstruction, @@ -6320,7 +6524,7 @@ class MWasmTrap : public MAryControlInstruction<0, 0>, class MLexicalCheck : public MUnaryInstruction, public BoxPolicy<0>::Data { BailoutKind kind_; explicit MLexicalCheck(MDefinition* input, - BailoutKind kind = Bailout_UninitializedLexical) + BailoutKind kind = BailoutKind::UninitializedLexical) : MUnaryInstruction(classOpcode, input), kind_(kind) { setResultType(MIRType::Value); setResultTypeSet(input->resultTypeSet()); @@ -7122,6 +7326,62 @@ class MSetArrayLength : public MBinaryInstruction, public NoTypePolicy::Data { bool canRecoverOnBailout() const override { return isRecoveredOnBailout(); } }; +// Load the function length. Bails for functions with lazy scripts or a +// resolved "length" property. +class MFunctionLength : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MFunctionLength(MDefinition* fun) + : MUnaryInstruction(classOpcode, fun) { + setResultType(MIRType::Int32); + setGuard(); + } + + public: + INSTRUCTION_HEADER(FunctionLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { + // Even though the "length" property is lazily resolved, it acts similar to + // a normal property load, so we can treat this operation like any other + // property read. + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } +}; + +// Load the function name. Bails for bound functions when the bound function +// name prefix isn't present or functions with a resolved "name" property. +class MFunctionName : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MFunctionName(MDefinition* fun) + : MUnaryInstruction(classOpcode, fun) { + setResultType(MIRType::String); + setGuard(); + } + + public: + INSTRUCTION_HEADER(FunctionName) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { + // Even though the "name" property is lazily resolved, it acts similar to + // a normal property load, so we can treat this operation like any other + // property read. + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } +}; + class MGetNextEntryForIterator : public MBinaryInstruction, public MixPolicy, ObjectPolicy<1>>::Data { @@ -7236,6 +7496,11 @@ class MTypedArrayElementShift : public MUnaryInstruction, return congruentIfOperandsEqual(ins); } + AliasSet getAliasSet() const override { + // Class is immutable. See also MHasClass. + return AliasSet::None(); + } + void computeRange(TempAllocator& alloc) override; }; @@ -7651,6 +7916,7 @@ class MStoreElement : public MTernaryInstruction, needsHoleCheck_ = needsHoleCheck; MOZ_ASSERT(elements->type() == MIRType::Elements); MOZ_ASSERT(index->type() == MIRType::Int32); + MOZ_ASSERT(value->type() != MIRType::MagicHole); } public: @@ -7667,6 +7933,27 @@ class MStoreElement : public MTernaryInstruction, ALLOW_CLONE(MStoreElement) }; +// Stores MagicValue(JS_ELEMENTS_HOLE) and marks the elements as non-packed. +class MStoreHoleValueElement : public MBinaryInstruction, + public NoTypePolicy::Data { + MStoreHoleValueElement(MDefinition* elements, MDefinition* index) + : MBinaryInstruction(classOpcode, elements, index) { + MOZ_ASSERT(elements->type() == MIRType::Elements); + MOZ_ASSERT(index->type() == MIRType::Int32); + } + + public: + INSTRUCTION_HEADER(StoreHoleValueElement) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, elements), (1, index)) + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::Element | AliasSet::ObjectFields); + } + + ALLOW_CLONE(MStoreHoleValueElement) +}; + // Like MStoreElement, but supports indexes >= initialized length. The downside // is that we cannot hoist the elements vector and bounds check, since this // instruction may update the (initialized) length and reallocate the elements @@ -7680,6 +7967,7 @@ class MStoreElementHole : MQuaternaryInstruction(classOpcode, object, elements, index, value) { MOZ_ASSERT(elements->type() == MIRType::Elements); MOZ_ASSERT(index->type() == MIRType::Int32); + MOZ_ASSERT(value->type() != MIRType::MagicHole); } public: @@ -7706,6 +7994,7 @@ class MFallibleStoreElement needsHoleCheck_(needsHoleCheck) { MOZ_ASSERT(elements->type() == MIRType::Elements); MOZ_ASSERT(index->type() == MIRType::Int32); + MOZ_ASSERT(value->type() != MIRType::MagicHole); } public: @@ -7734,7 +8023,9 @@ class MArrayPopShift : public MUnaryInstruction, : MUnaryInstruction(classOpcode, object), mode_(mode), needsHoleCheck_(needsHoleCheck), - maybeUndefined_(maybeUndefined) {} + maybeUndefined_(maybeUndefined) { + setResultType(MIRType::Value); + } public: INSTRUCTION_HEADER(ArrayPopShift) @@ -8914,6 +9205,7 @@ class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data { } return congruentIfOperandsEqual(ins); } + MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::ObjectFields); } @@ -8922,68 +9214,74 @@ class MGuardShape : public MUnaryInstruction, public SingleObjectPolicy::Data { } }; -// Guard on a specific Value. -class MGuardValue : public MUnaryInstruction, public BoxInputsPolicy::Data { - Value expected_; - - MGuardValue(MDefinition* val, const Value& expected) - : MUnaryInstruction(classOpcode, val), expected_(expected) { - MOZ_ASSERT(expected.isNullOrUndefined() || expected.isMagic()); - +// Guard the object's proto is |expected|. +class MGuardProto : public MBinaryInstruction, public SingleObjectPolicy::Data { + MGuardProto(MDefinition* obj, MDefinition* expected) + : MBinaryInstruction(classOpcode, obj, expected) { + MOZ_ASSERT(expected->isConstant() || expected->isNurseryObject()); setGuard(); setMovable(); - setResultType(MIRType::Value); + setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); } public: - INSTRUCTION_HEADER(GuardValue) + INSTRUCTION_HEADER(GuardProto) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, value)) - - Value expected() const { return expected_; } + NAMED_OPERANDS((0, object), (1, expected)) bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardValue()) { - return false; - } - if (expected() != ins->toGuardValue()->expected()) { - return false; - } return congruentIfOperandsEqual(ins); } - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { return AliasSet::None(); } + + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + AliasType mightAlias(const MDefinition* def) const override { + // These instructions never modify the [[Prototype]]. + if (def->isAddAndStoreSlot() || def->isAllocateAndStoreSlot()) { + return AliasType::NoAlias; + } + return AliasType::MayAlias; + } }; -// Guard on null or undefined values. -class MGuardNullOrUndefined : public MUnaryInstruction, - public BoxInputsPolicy::Data { - explicit MGuardNullOrUndefined(MDefinition* val) - : MUnaryInstruction(classOpcode, val) { +// Guard the object has no proto. +class MGuardNullProto : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardNullProto(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { setGuard(); setMovable(); - setResultType(MIRType::Value); + setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); } public: - INSTRUCTION_HEADER(GuardNullOrUndefined) + INSTRUCTION_HEADER(GuardNullProto) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, value)) + NAMED_OPERANDS((0, object)) bool congruentTo(const MDefinition* ins) const override { return congruentIfOperandsEqual(ins); } - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + AliasType mightAlias(const MDefinition* def) const override { + // These instructions never modify the [[Prototype]]. + if (def->isAddAndStoreSlot() || def->isAllocateAndStoreSlot()) { + return AliasType::NoAlias; + } + return AliasType::MayAlias; + } }; -// Bail if the object's shape or unboxed group is not in the input list. -class MGuardReceiverPolymorphic : public MUnaryInstruction, - public SingleObjectPolicy::Data { - Vector receivers_; - - MGuardReceiverPolymorphic(TempAllocator& alloc, MDefinition* obj) - : MUnaryInstruction(classOpcode, obj), receivers_(alloc) { +// Guard the object is a proxy. +class MGuardIsProxy : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardIsProxy(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { setGuard(); setMovable(); setResultType(MIRType::Object); @@ -8991,222 +9289,906 @@ class MGuardReceiverPolymorphic : public MUnaryInstruction, } public: - INSTRUCTION_HEADER(GuardReceiverPolymorphic) + INSTRUCTION_HEADER(GuardIsProxy) + TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) - static MGuardReceiverPolymorphic* New(TempAllocator& alloc, - MDefinition* obj) { - return new (alloc) MGuardReceiverPolymorphic(alloc, obj); - } - - MOZ_MUST_USE bool addReceiver(const ReceiverGuard& receiver) { - return receivers_.append(receiver); - } - size_t numReceivers() const { return receivers_.length(); } - const ReceiverGuard& receiver(size_t i) const { return receivers_[i]; } - - bool congruentTo(const MDefinition* ins) const override; - - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); } - - bool appendRoots(MRootList& roots) const override; + AliasSet getAliasSet() const override { return AliasSet::None(); } }; -// Guard on an object's group, inclusively or exclusively. -class MGuardObjectGroup : public MUnaryInstruction, - public SingleObjectPolicy::Data { - CompilerObjectGroup group_; - bool bailOnEquality_; - BailoutKind bailoutKind_; - - MGuardObjectGroup(MDefinition* obj, ObjectGroup* group, bool bailOnEquality, - BailoutKind bailoutKind) - : MUnaryInstruction(classOpcode, obj), - group_(group), - bailOnEquality_(bailOnEquality), - bailoutKind_(bailoutKind) { +// Guard the object is not a proxy. +class MGuardIsNotProxy : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardIsNotProxy(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { setGuard(); setMovable(); setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); } public: - INSTRUCTION_HEADER(GuardObjectGroup) + INSTRUCTION_HEADER(GuardIsNotProxy) TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) - const ObjectGroup* group() const { return group_; } - bool bailOnEquality() const { return bailOnEquality_; } - BailoutKind bailoutKind() const { return bailoutKind_; } bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardObjectGroup()) { - return false; - } - if (group() != ins->toGuardObjectGroup()->group()) { - return false; - } - if (bailOnEquality() != ins->toGuardObjectGroup()->bailOnEquality()) { - return false; - } - if (bailoutKind() != ins->toGuardObjectGroup()->bailoutKind()) { - return false; - } return congruentIfOperandsEqual(ins); } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } - bool appendRoots(MRootList& roots) const override { - return roots.append(group_); - } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } }; -// Guard on an object's identity, inclusively or exclusively. -class MGuardObjectIdentity : public MBinaryInstruction, - public SingleObjectPolicy::Data { - bool bailOnEquality_; - - MGuardObjectIdentity(MDefinition* obj, MDefinition* expected, - bool bailOnEquality) - : MBinaryInstruction(classOpcode, obj, expected), - bailOnEquality_(bailOnEquality) { - MOZ_ASSERT(expected->isConstant()); +// Guard the proxy is not a DOM proxy. +class MGuardIsNotDOMProxy : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardIsNotDOMProxy(MDefinition* proxy) + : MUnaryInstruction(classOpcode, proxy) { setGuard(); setMovable(); setResultType(MIRType::Object); + setResultTypeSet(proxy->resultTypeSet()); } public: - INSTRUCTION_HEADER(GuardObjectIdentity) + INSTRUCTION_HEADER(GuardIsNotDOMProxy) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, expected)) + NAMED_OPERANDS((0, proxy)) - bool bailOnEquality() const { return bailOnEquality_; } - MDefinition* foldsTo(TempAllocator& alloc) override; bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardObjectIdentity()) { - return false; - } - if (bailOnEquality() != ins->toGuardObjectIdentity()->bailOnEquality()) { - return false; - } return congruentIfOperandsEqual(ins); } AliasSet getAliasSet() const override { return AliasSet::None(); } }; -// Guard on a specific JSFunction. Used instead of MGuardObjectIdentity, -// so we can store some metadata related to the expected function. -class MGuardSpecificFunction : public MBinaryInstruction, - public SingleObjectPolicy::Data { - uint16_t nargs_; - FunctionFlags flags_; +class MProxyGet : public MUnaryInstruction, public SingleObjectPolicy::Data { + jsid id_; - MGuardSpecificFunction(MDefinition* obj, MDefinition* expected, - uint16_t nargs, FunctionFlags flags) - : MBinaryInstruction(classOpcode, obj, expected), - nargs_(nargs), - flags_(flags) { - MOZ_ASSERT(expected->isConstant()); - setGuard(); - setMovable(); - setResultType(MIRType::Object); + MProxyGet(MDefinition* proxy, jsid id) + : MUnaryInstruction(classOpcode, proxy), id_(id) { + setResultType(MIRType::Value); } public: - INSTRUCTION_HEADER(GuardSpecificFunction) + INSTRUCTION_HEADER(ProxyGet) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, function), (1, expected)) + NAMED_OPERANDS((0, proxy)) - uint16_t nargs() const { return nargs_; } - FunctionFlags flags() const { return flags_; } + jsid id() const { return id_; } - MDefinition* foldsTo(TempAllocator& alloc) override; - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardSpecificFunction()) { - return false; - } + bool possiblyCalls() const override { return true; } - auto* other = ins->toGuardSpecificFunction(); - if (nargs() != other->nargs() || - flags().toRaw() != other->flags().toRaw()) { - return false; - } - return congruentIfOperandsEqual(other); + bool appendRoots(MRootList& roots) const override { + return roots.append(id_); } - AliasSet getAliasSet() const override { return AliasSet::None(); } }; -class MGuardSpecificAtom : public MUnaryInstruction, - public StringPolicy<0>::Data { - CompilerGCPointer atom_; - - MGuardSpecificAtom(MDefinition* str, JSAtom* atom) - : MUnaryInstruction(classOpcode, str), atom_(atom) { - setGuard(); - setMovable(); - setResultType(MIRType::String); +class MProxyGetByValue : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + MProxyGetByValue(MDefinition* proxy, MDefinition* idVal) + : MBinaryInstruction(classOpcode, proxy, idVal) { + setResultType(MIRType::Value); } public: - INSTRUCTION_HEADER(GuardSpecificAtom) + INSTRUCTION_HEADER(ProxyGetByValue) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, str)) + NAMED_OPERANDS((0, proxy), (1, idVal)) - JSAtom* atom() const { return atom_; } + bool possiblyCalls() const override { return true; } +}; - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardSpecificAtom()) { - return false; - } - if (atom() != ins->toGuardSpecificAtom()->atom()) { - return false; - } - return congruentIfOperandsEqual(ins); - } - MDefinition* foldsTo(TempAllocator& alloc) override; - AliasSet getAliasSet() const override { return AliasSet::None(); } +class MProxyHasProp : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + bool hasOwn_; - bool appendRoots(MRootList& roots) const override { - return roots.append(atom_); + MProxyHasProp(MDefinition* proxy, MDefinition* idVal, bool hasOwn) + : MBinaryInstruction(classOpcode, proxy, idVal), hasOwn_(hasOwn) { + setResultType(MIRType::Boolean); } + + public: + INSTRUCTION_HEADER(ProxyHasProp) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, proxy), (1, idVal)) + + bool hasOwn() const { return hasOwn_; } + + bool possiblyCalls() const override { return true; } }; -class MGuardSpecificSymbol : public MUnaryInstruction, - public SymbolPolicy<0>::Data { - CompilerGCPointer expected_; +class MProxySet : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + jsid id_; + bool strict_; - MGuardSpecificSymbol(MDefinition* symbol, JS::Symbol* expected) - : MUnaryInstruction(classOpcode, symbol), expected_(expected) { - setGuard(); - setMovable(); - setResultType(MIRType::Symbol); - } + MProxySet(MDefinition* proxy, jsid id, MDefinition* rhs, bool strict) + : MBinaryInstruction(classOpcode, proxy, rhs), id_(id), strict_(strict) {} public: - INSTRUCTION_HEADER(GuardSpecificSymbol) + INSTRUCTION_HEADER(ProxySet) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, symbol)) + NAMED_OPERANDS((0, proxy), (1, rhs)) - JS::Symbol* expected() const { return expected_; } + jsid id() const { return id_; } + bool strict() const { return strict_; } - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isGuardSpecificSymbol()) { - return false; - } - if (expected() != ins->toGuardSpecificSymbol()->expected()) { - return false; - } + bool possiblyCalls() const override { return true; } + + bool appendRoots(MRootList& roots) const override { + return roots.append(id_); + } +}; + +class MProxySetByValue + : public MTernaryInstruction, + public MixPolicy, BoxPolicy<1>, BoxPolicy<2>>::Data { + bool strict_; + + MProxySetByValue(MDefinition* proxy, MDefinition* idVal, MDefinition* rhs, + bool strict) + : MTernaryInstruction(classOpcode, proxy, idVal, rhs), strict_(strict) {} + + public: + INSTRUCTION_HEADER(ProxySetByValue) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, proxy), (1, idVal), (2, rhs)) + + bool strict() const { return strict_; } + + bool possiblyCalls() const override { return true; } +}; + +class MCallSetArrayLength + : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + bool strict_; + + MCallSetArrayLength(MDefinition* obj, MDefinition* rhs, bool strict) + : MBinaryInstruction(classOpcode, obj, rhs), strict_(strict) {} + + public: + INSTRUCTION_HEADER(CallSetArrayLength) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, obj), (1, rhs)) + + bool strict() const { return strict_; } + + bool possiblyCalls() const override { return true; } +}; + +class MMegamorphicLoadSlot : public MUnaryInstruction, + public SingleObjectPolicy::Data { + CompilerPropertyName name_; + + MMegamorphicLoadSlot(MDefinition* obj, PropertyName* name) + : MUnaryInstruction(classOpcode, obj), name_(name) { + setResultType(MIRType::Value); + } + + public: + INSTRUCTION_HEADER(MegamorphicLoadSlot) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + PropertyName* name() const { return name_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isMegamorphicLoadSlot()) { + return false; + } + if (ins->toMegamorphicLoadSlot()->name() != name()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } + + bool possiblyCalls() const override { return true; } + + bool appendRoots(MRootList& roots) const override { + return roots.append(name_); + } +}; + +class MMegamorphicLoadSlotByValue + : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + MMegamorphicLoadSlotByValue(MDefinition* obj, MDefinition* idVal) + : MBinaryInstruction(classOpcode, obj, idVal) { + setResultType(MIRType::Value); + } + + public: + INSTRUCTION_HEADER(MegamorphicLoadSlotByValue) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, idVal)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } + + bool possiblyCalls() const override { return true; } +}; + +class MMegamorphicStoreSlot + : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + CompilerPropertyName name_; + + MMegamorphicStoreSlot(MDefinition* obj, PropertyName* name, MDefinition* rhs) + : MBinaryInstruction(classOpcode, obj, rhs), name_(name) {} + + public: + INSTRUCTION_HEADER(MegamorphicStoreSlot) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, rhs)) + + PropertyName* name() const { return name_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isMegamorphicStoreSlot()) { + return false; + } + if (ins->toMegamorphicStoreSlot()->name() != name()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } + + bool possiblyCalls() const override { return true; } + + bool appendRoots(MRootList& roots) const override { + return roots.append(name_); + } +}; + +class MMegamorphicHasProp + : public MBinaryInstruction, + public MixPolicy, BoxPolicy<1>>::Data { + bool hasOwn_; + + MMegamorphicHasProp(MDefinition* obj, MDefinition* idVal, bool hasOwn) + : MBinaryInstruction(classOpcode, obj, idVal), hasOwn_(hasOwn) { + setResultType(MIRType::Boolean); + } + + public: + INSTRUCTION_HEADER(MegamorphicHasProp) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, idVal)) + + bool hasOwn() const { return hasOwn_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isMegamorphicHasProp()) { + return false; + } + if (ins->toMegamorphicHasProp()->hasOwn() != hasOwn()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); + } + + bool possiblyCalls() const override { return true; } +}; + +// Guard the object is not an ArrayBufferObject or SharedArrayBufferObject. +class MGuardIsNotArrayBufferMaybeShared : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardIsNotArrayBufferMaybeShared(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardIsNotArrayBufferMaybeShared) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guard the object is a TypedArray object. +class MGuardIsTypedArray : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardIsTypedArray(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardIsTypedArray) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Loads a specific JSObject* that was originally nursery-allocated. +// See also WarpObjectField. +class MNurseryObject : public MNullaryInstruction { + // Index in the Vector of objects stored in the WarpSnapshot. + uint32_t nurseryIndex_; + + explicit MNurseryObject(uint32_t nurseryIndex) + : MNullaryInstruction(classOpcode), nurseryIndex_(nurseryIndex) { + setMovable(); + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(NurseryObject) + TRIVIAL_NEW_WRAPPERS + + uint32_t nurseryIndex() const { return nurseryIndex_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isNurseryObject()) { + return false; + } + return nurseryIndex() == ins->toNurseryObject()->nurseryIndex(); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guard on a specific Value. +class MGuardValue : public MUnaryInstruction, public BoxInputsPolicy::Data { + Value expected_; + + MGuardValue(MDefinition* val, const Value& expected) + : MUnaryInstruction(classOpcode, val), expected_(expected) { + MOZ_ASSERT(expected.isNullOrUndefined() || expected.isMagic()); + + setGuard(); + setMovable(); + setResultType(MIRType::Value); + } + + public: + INSTRUCTION_HEADER(GuardValue) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value)) + + Value expected() const { return expected_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardValue()) { + return false; + } + if (expected() != ins->toGuardValue()->expected()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guards the value is not MagicValue(JS_OPTIMIZED_ARGUMENTS). If this fails, +// disable lazy arguments for the script. +class MGuardNotOptimizedArguments : public MUnaryInstruction, + public BoxInputsPolicy::Data { + explicit MGuardNotOptimizedArguments(MDefinition* val) + : MUnaryInstruction(classOpcode, val) { + setGuard(); + setResultType(MIRType::Value); + // Note: don't setMovable() to not deoptimize lazy arguments unnecessarily. + } + + public: + INSTRUCTION_HEADER(GuardNotOptimizedArguments) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + static bool maybeIsOptimizedArguments(MDefinition* def); + + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guard on null or undefined values. +class MGuardNullOrUndefined : public MUnaryInstruction, + public BoxInputsPolicy::Data { + explicit MGuardNullOrUndefined(MDefinition* val) + : MUnaryInstruction(classOpcode, val) { + setGuard(); + setMovable(); + setResultType(MIRType::Value); + } + + public: + INSTRUCTION_HEADER(GuardNullOrUndefined) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guard on function flags +class MGuardFunctionFlags : public MUnaryInstruction, + public SingleObjectPolicy::Data { + uint16_t flags_; + bool bailWhenSet_; + + explicit MGuardFunctionFlags(MDefinition* fun, uint16_t flags, + bool bailWhenSet) + : MUnaryInstruction(classOpcode, fun), + flags_(flags), + bailWhenSet_(bailWhenSet) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(fun->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardFunctionFlags) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function)) + + uint16_t flags() const { return flags_; }; + bool bailWhenSet() const { return bailWhenSet_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardFunctionFlags()) { + return false; + } + if (flags() != ins->toGuardFunctionFlags()->flags()) { + return false; + } + if (bailWhenSet() != ins->toGuardFunctionFlags()->bailWhenSet()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } +}; + +// Guard on function kind +class MGuardFunctionKind : public MUnaryInstruction, + public SingleObjectPolicy::Data { + FunctionFlags::FunctionKind expected_; + bool bailOnEquality_; + + explicit MGuardFunctionKind(MDefinition* fun, + FunctionFlags::FunctionKind expected, + bool bailOnEquality) + : MUnaryInstruction(classOpcode, fun), + expected_(expected), + bailOnEquality_(bailOnEquality) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(fun->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardFunctionKind) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function)) + + FunctionFlags::FunctionKind expected() const { return expected_; }; + bool bailOnEquality() const { return bailOnEquality_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardFunctionKind()) { + return false; + } + if (expected() != ins->toGuardFunctionKind()->expected()) { + return false; + } + if (bailOnEquality() != ins->toGuardFunctionKind()->bailOnEquality()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } +}; + +class MGuardFunctionScript : public MUnaryInstruction, + public SingleObjectPolicy::Data { + CompilerBaseScript expected_; + uint16_t nargs_; + FunctionFlags flags_; + + MGuardFunctionScript(MDefinition* fun, BaseScript* expected, uint16_t nargs, + FunctionFlags flags) + : MUnaryInstruction(classOpcode, fun), + expected_(expected), + nargs_(nargs), + flags_(flags) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(fun->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardFunctionScript) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function)) + + BaseScript* expected() const { return expected_; } + uint16_t nargs() const { return nargs_; } + FunctionFlags flags() const { return flags_; } + + MDefinition* foldsTo(TempAllocator& alloc) override; + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardFunctionScript()) { + return false; + } + if (expected() != ins->toGuardFunctionScript()->expected()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + // A JSFunction's BaseScript pointer is immutable. Relazification of + // self-hosted functions is an exception to this, but we don't use this + // guard for self-hosted functions. + MOZ_ASSERT(!flags_.isSelfHostedOrIntrinsic()); + return AliasSet::None(); + } + bool appendRoots(MRootList& roots) const override { + return roots.append(expected_); + } +}; + +// Bail if the object's shape or unboxed group is not in the input list. +class MGuardReceiverPolymorphic : public MUnaryInstruction, + public SingleObjectPolicy::Data { + Vector receivers_; + + MGuardReceiverPolymorphic(TempAllocator& alloc, MDefinition* obj) + : MUnaryInstruction(classOpcode, obj), receivers_(alloc) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(obj->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardReceiverPolymorphic) + NAMED_OPERANDS((0, object)) + + static MGuardReceiverPolymorphic* New(TempAllocator& alloc, + MDefinition* obj) { + return new (alloc) MGuardReceiverPolymorphic(alloc, obj); + } + + MOZ_MUST_USE bool addReceiver(const ReceiverGuard& receiver) { + return receivers_.append(receiver); + } + size_t numReceivers() const { return receivers_.length(); } + const ReceiverGuard& receiver(size_t i) const { return receivers_[i]; } + + bool congruentTo(const MDefinition* ins) const override; + + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + + bool appendRoots(MRootList& roots) const override; +}; + +// Guard on an object's group, inclusively or exclusively. +class MGuardObjectGroup : public MUnaryInstruction, + public SingleObjectPolicy::Data { + CompilerObjectGroup group_; + bool bailOnEquality_; + BailoutKind bailoutKind_; + + MGuardObjectGroup(MDefinition* obj, ObjectGroup* group, bool bailOnEquality, + BailoutKind bailoutKind) + : MUnaryInstruction(classOpcode, obj), + group_(group), + bailOnEquality_(bailOnEquality), + bailoutKind_(bailoutKind) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(GuardObjectGroup) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + const ObjectGroup* group() const { return group_; } + bool bailOnEquality() const { return bailOnEquality_; } + BailoutKind bailoutKind() const { return bailoutKind_; } + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardObjectGroup()) { + return false; + } + if (group() != ins->toGuardObjectGroup()->group()) { + return false; + } + if (bailOnEquality() != ins->toGuardObjectGroup()->bailOnEquality()) { + return false; + } + if (bailoutKind() != ins->toGuardObjectGroup()->bailoutKind()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } + AliasType mightAlias(const MDefinition* def) const override { + // These instructions don't modify the group only the shape. + if (def->isAddAndStoreSlot() || def->isAllocateAndStoreSlot()) { + return AliasType::NoAlias; + } + return AliasType::MayAlias; + }; + bool appendRoots(MRootList& roots) const override { + return roots.append(group_); + } +}; + +// Guard on an object's identity, inclusively or exclusively. +class MGuardObjectIdentity : public MBinaryInstruction, + public SingleObjectPolicy::Data { + bool bailOnEquality_; + + MGuardObjectIdentity(MDefinition* obj, MDefinition* expected, + bool bailOnEquality) + : MBinaryInstruction(classOpcode, obj, expected), + bailOnEquality_(bailOnEquality) { + MOZ_ASSERT(expected->isConstant() || expected->isNurseryObject()); + setGuard(); + setMovable(); + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(GuardObjectIdentity) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, expected)) + + bool bailOnEquality() const { return bailOnEquality_; } + MDefinition* foldsTo(TempAllocator& alloc) override; + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardObjectIdentity()) { + return false; + } + if (bailOnEquality() != ins->toGuardObjectIdentity()->bailOnEquality()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Guard on a specific JSFunction. Used instead of MGuardObjectIdentity, +// so we can store some metadata related to the expected function. +class MGuardSpecificFunction : public MBinaryInstruction, + public SingleObjectPolicy::Data { + uint16_t nargs_; + FunctionFlags flags_; + + MGuardSpecificFunction(MDefinition* obj, MDefinition* expected, + uint16_t nargs, FunctionFlags flags) + : MBinaryInstruction(classOpcode, obj, expected), + nargs_(nargs), + flags_(flags) { + MOZ_ASSERT(expected->isConstant() || expected->isNurseryObject()); + setGuard(); + setMovable(); + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(GuardSpecificFunction) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, function), (1, expected)) + + uint16_t nargs() const { return nargs_; } + FunctionFlags flags() const { return flags_; } + + MDefinition* foldsTo(TempAllocator& alloc) override; + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardSpecificFunction()) { + return false; + } + + auto* other = ins->toGuardSpecificFunction(); + if (nargs() != other->nargs() || + flags().toRaw() != other->flags().toRaw()) { + return false; + } + return congruentIfOperandsEqual(other); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +class MGuardSpecificAtom : public MUnaryInstruction, + public StringPolicy<0>::Data { + CompilerGCPointer atom_; + + MGuardSpecificAtom(MDefinition* str, JSAtom* atom) + : MUnaryInstruction(classOpcode, str), atom_(atom) { + setGuard(); + setMovable(); + setResultType(MIRType::String); + } + + public: + INSTRUCTION_HEADER(GuardSpecificAtom) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, str)) + + JSAtom* atom() const { return atom_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardSpecificAtom()) { + return false; + } + if (atom() != ins->toGuardSpecificAtom()->atom()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } + + bool appendRoots(MRootList& roots) const override { + return roots.append(atom_); + } +}; + +class MGuardSpecificSymbol : public MUnaryInstruction, + public SymbolPolicy<0>::Data { + CompilerGCPointer expected_; + + MGuardSpecificSymbol(MDefinition* symbol, JS::Symbol* expected) + : MUnaryInstruction(classOpcode, symbol), expected_(expected) { + setGuard(); + setMovable(); + setResultType(MIRType::Symbol); + } + + public: + INSTRUCTION_HEADER(GuardSpecificSymbol) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, symbol)) + + JS::Symbol* expected() const { return expected_; } + + bool congruentTo(const MDefinition* ins) const override { + if (!ins->isGuardSpecificSymbol()) { + return false; + } + if (expected() != ins->toGuardSpecificSymbol()->expected()) { + return false; + } + return congruentIfOperandsEqual(ins); + } + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } + + bool appendRoots(MRootList& roots) const override { + return roots.append(expected_); + } +}; + +class MGuardStringToIndex : public MUnaryInstruction, + public StringPolicy<0>::Data { + explicit MGuardStringToIndex(MDefinition* str) + : MUnaryInstruction(classOpcode, str) { + // Mark as guard because this instruction must not be eliminated. For + // example, if the string is not an index the operation could change from a + // typed array load to a getter call. + setGuard(); + setMovable(); + setResultType(MIRType::Int32); + } + + public: + INSTRUCTION_HEADER(GuardStringToIndex) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, string)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +class MGuardStringToInt32 : public MUnaryInstruction, + public StringPolicy<0>::Data { + explicit MGuardStringToInt32(MDefinition* str) + : MUnaryInstruction(classOpcode, str) { + // Mark as guard to prevent the issue described in MGuardStringToIndex's + // constructor. + setGuard(); + setMovable(); + setResultType(MIRType::Int32); + } + + public: + INSTRUCTION_HEADER(GuardStringToInt32) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, string)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + MDefinition* foldsTo(TempAllocator& alloc) override; + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +class MGuardStringToDouble : public MUnaryInstruction, + public StringPolicy<0>::Data { + explicit MGuardStringToDouble(MDefinition* str) + : MUnaryInstruction(classOpcode, str) { + // Mark as guard to prevent the issue described in MGuardStringToIndex's + // constructor. + setGuard(); + setMovable(); + setResultType(MIRType::Double); + } + + public: + INSTRUCTION_HEADER(GuardStringToDouble) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, string)) + + bool congruentTo(const MDefinition* ins) const override { return congruentIfOperandsEqual(ins); } + MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::None(); } - - bool appendRoots(MRootList& roots) const override { - return roots.append(expected_); - } }; class MGuardNoDenseElements : public MUnaryInstruction, @@ -9228,6 +10210,27 @@ class MGuardNoDenseElements : public MUnaryInstruction, } }; +class MGuardTagNotEqual + : public MBinaryInstruction, + public MixPolicy, UnboxedInt32Policy<1>>::Data { + MGuardTagNotEqual(MDefinition* left, MDefinition* right) + : MBinaryInstruction(classOpcode, left, right) { + setGuard(); + setMovable(); + setCommutative(); + } + + public: + INSTRUCTION_HEADER(GuardTagNotEqual) + TRIVIAL_NEW_WRAPPERS + + AliasSet getAliasSet() const override { return AliasSet::None(); } + + bool congruentTo(const MDefinition* ins) const override { + return binaryCongruentTo(ins); + } +}; + // Load from vp[slot] (slots that are not inline in an object). class MLoadDynamicSlot : public MUnaryInstruction, public NoTypePolicy::Data { uint32_t slot_; @@ -9354,6 +10357,80 @@ class MHomeObject : public MUnaryInstruction, public SingleObjectPolicy::Data { AliasSet getAliasSet() const override { return AliasSet::None(); } }; +class MAddAndStoreSlot + : public MBinaryInstruction, + public MixPolicy>::Data { + public: + enum class Kind { + FixedSlot, + DynamicSlot, + }; + + private: + Kind kind_; + uint32_t slotOffset_; + CompilerShape shape_; + + MAddAndStoreSlot(MDefinition* obj, MDefinition* value, Kind kind, + uint32_t slotOffset, Shape* shape) + : MBinaryInstruction(classOpcode, obj, value), + kind_(kind), + slotOffset_(slotOffset), + shape_(shape) {} + + public: + INSTRUCTION_HEADER(AddAndStoreSlot) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, value)) + + Kind kind() const { return kind_; } + uint32_t slotOffset() const { return slotOffset_; } + Shape* shape() const { return shape_; } + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::ObjectFields | + (kind() == Kind::FixedSlot ? AliasSet::FixedSlot + : AliasSet::DynamicSlot)); + } + + bool appendRoots(MRootList& roots) const override { + return roots.append(shape_); + } +}; + +class MAllocateAndStoreSlot + : public MBinaryInstruction, + public MixPolicy>::Data { + private: + CompilerShape shape_; + uint32_t slotOffset_; + uint32_t numNewSlots_; + + MAllocateAndStoreSlot(MDefinition* obj, MDefinition* value, + uint32_t slotOffset, Shape* shape, uint32_t numNewSlots) + : MBinaryInstruction(classOpcode, obj, value), + shape_(shape), + slotOffset_(slotOffset), + numNewSlots_(numNewSlots) {} + + public: + INSTRUCTION_HEADER(AllocateAndStoreSlot) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object), (1, value)) + + Shape* shape() const { return shape_; } + uint32_t slotOffset() const { return slotOffset_; } + uint32_t numNewSlots() const { return numNewSlots_; } + + AliasSet getAliasSet() const override { + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::DynamicSlot); + } + bool possiblyCalls() const override { return true; } + bool appendRoots(MRootList& roots) const override { + return roots.append(shape_); + } +}; + // Store to vp[slot] (slots that are not inline in an object). class MStoreDynamicSlot : public MBinaryInstruction, public NoFloatPolicy<1>::Data { @@ -10050,6 +11127,19 @@ class MGetIteratorCache : public MUnaryInstruction, NAMED_OPERANDS((0, value)) }; +class MOptimizeSpreadCallCache : public MUnaryInstruction, + public BoxInputsPolicy::Data { + explicit MOptimizeSpreadCallCache(MDefinition* val) + : MUnaryInstruction(classOpcode, val) { + setResultType(MIRType::Boolean); + } + + public: + INSTRUCTION_HEADER(OptimizeSpreadCallCache) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value)) +}; + class MIteratorMore : public MUnaryInstruction, public SingleObjectPolicy::Data { explicit MIteratorMore(MDefinition* iter) @@ -10144,6 +11234,45 @@ class MInArray : public MQuaternaryInstruction, public ObjectPolicy<3>::Data { } }; +// Bail when the element is a hole. +class MGuardElementNotHole : public MBinaryInstruction, + public NoTypePolicy::Data { + MGuardElementNotHole(MDefinition* elements, MDefinition* index) + : MBinaryInstruction(classOpcode, elements, index) { + setMovable(); + setGuard(); + MOZ_ASSERT(elements->type() == MIRType::Elements); + MOZ_ASSERT(index->type() == MIRType::Int32); + } + + public: + INSTRUCTION_HEADER(GuardElementNotHole) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, elements), (1, index)) + + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::Element); + } + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } +}; + +class MCheckPrivateFieldCache + : public MBinaryInstruction, + public MixPolicy, + CacheIdPolicy<1>>::Data { + MCheckPrivateFieldCache(MDefinition* obj, MDefinition* id) + : MBinaryInstruction(classOpcode, obj, id) { + setResultType(MIRType::Boolean); + } + + public: + INSTRUCTION_HEADER(CheckPrivateFieldCache) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value), (1, idval)) +}; + class MHasOwnCache : public MBinaryInstruction, public MixPolicy, CacheIdPolicy<1>>::Data { @@ -10159,23 +11288,17 @@ class MHasOwnCache : public MBinaryInstruction, }; // Implementation for instanceof operator with specific rhs. -class MInstanceOf : public MUnaryInstruction, public InstanceOfPolicy::Data { - CompilerObject protoObj_; - - MInstanceOf(MDefinition* obj, JSObject* proto) - : MUnaryInstruction(classOpcode, obj), protoObj_(proto) { +class MInstanceOf : public MBinaryInstruction, + public MixPolicy, + ObjectPolicy<1>>::Data { + MInstanceOf(MDefinition* obj, MDefinition* proto) + : MBinaryInstruction(classOpcode, obj, proto) { setResultType(MIRType::Boolean); } public: INSTRUCTION_HEADER(InstanceOf) TRIVIAL_NEW_WRAPPERS - - JSObject* prototypeObject() { return protoObj_; } - - bool appendRoots(MRootList& roots) const override { - return roots.append(protoObj_); - } }; // Implementation for instanceof operator with unknown rhs. @@ -10678,6 +11801,11 @@ class MIsCallable : public MUnaryInstruction, TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::None(); } }; @@ -10695,6 +11823,31 @@ class MIsConstructor : public MUnaryInstruction, TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +class MIsCrossRealmArrayConstructor : public MUnaryInstruction, + public SingleObjectPolicy::Data { + public: + explicit MIsCrossRealmArrayConstructor(MDefinition* object) + : MUnaryInstruction(classOpcode, object) { + setResultType(MIRType::Boolean); + setMovable(); + } + + public: + INSTRUCTION_HEADER(IsCrossRealmArrayConstructor) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } }; @@ -10710,6 +11863,7 @@ class MIsObject : public MUnaryInstruction, public BoxInputsPolicy::Data { TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) + MDefinition* foldsTo(TempAllocator& alloc) override; bool congruentTo(const MDefinition* ins) const override { return congruentIfOperandsEqual(ins); } @@ -10755,6 +11909,8 @@ class MHasClass : public MUnaryInstruction, public SingleObjectPolicy::Data { NAMED_OPERANDS((0, object)) const JSClass* getClass() const { return class_; } + + MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::None(); } bool congruentTo(const MDefinition* ins) const override { if (!ins->isHasClass()) { @@ -10814,6 +11970,8 @@ class MIsArray : public MUnaryInstruction, INSTRUCTION_HEADER(IsArray) TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, value)) + + MDefinition* foldsTo(TempAllocator& alloc) override; }; class MIsTypedArray : public MUnaryInstruction, @@ -10839,7 +11997,12 @@ class MIsTypedArray : public MUnaryInstruction, NAMED_OPERANDS((0, value)) bool isPossiblyWrapped() const { return possiblyWrapped_; } - AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + if (isPossiblyWrapped()) { + return AliasSet::Store(AliasSet::Any); + } + return AliasSet::None(); + } }; class MObjectClassToString : public MUnaryInstruction, @@ -11116,20 +12279,25 @@ class MDebugger : public MNullaryInstruction { class MCheckIsObj : public MUnaryInstruction, public BoxInputsPolicy::Data { uint8_t checkKind_; - MCheckIsObj(MDefinition* toCheck, uint8_t checkKind) - : MUnaryInstruction(classOpcode, toCheck), checkKind_(checkKind) { - setResultType(MIRType::Value); - setResultTypeSet(toCheck->resultTypeSet()); + MCheckIsObj(TempAllocator& alloc, MDefinition* value, uint8_t checkKind) + : MUnaryInstruction(classOpcode, value), checkKind_(checkKind) { + TemporaryTypeSet* resultSet = value->resultTypeSet(); + if (resultSet) { + resultSet = resultSet->cloneObjectsOnly(alloc.lifoAlloc()); + } + + setResultType(MIRType::Object); + setResultTypeSet(resultSet); setGuard(); } public: INSTRUCTION_HEADER(CheckIsObj) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, checkValue)) + TRIVIAL_NEW_WRAPPERS_WITH_ALLOC uint8_t checkKind() const { return checkKind_; } + MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::None(); } }; @@ -11147,7 +12315,11 @@ class MCheckObjCoercible : public MUnaryInstruction, TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, checkValue)) - AliasSet getAliasSet() const override { return AliasSet::None(); } + AliasSet getAliasSet() const override { + // Throws on null or undefined. + return AliasSet::Store(AliasSet::ExceptionState); + } + MDefinition* foldsTo(TempAllocator& alloc) override; }; @@ -11197,8 +12369,8 @@ class MFinishBoundFunctionInit class MIsPackedArray : public MUnaryInstruction, public SingleObjectPolicy::Data { - explicit MIsPackedArray(MDefinition* array) - : MUnaryInstruction(classOpcode, array) { + explicit MIsPackedArray(MDefinition* object) + : MUnaryInstruction(classOpcode, object) { setResultType(MIRType::Boolean); setMovable(); } @@ -11206,8 +12378,31 @@ class MIsPackedArray : public MUnaryInstruction, public: INSTRUCTION_HEADER(IsPackedArray) TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + AliasSet getAliasSet() const override { + return AliasSet::Load(AliasSet::ObjectFields); + } +}; + +class MGuardArrayIsPacked : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MGuardArrayIsPacked(MDefinition* array) + : MUnaryInstruction(classOpcode, array) { + setGuard(); + setMovable(); + setResultType(MIRType::Object); + setResultTypeSet(array->resultTypeSet()); + } + + public: + INSTRUCTION_HEADER(GuardArrayIsPacked) + TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, array)) + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::ObjectFields); } @@ -11258,20 +12453,36 @@ class MObjectStaticProto : public MUnaryInstruction, TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object)) + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::ObjectFields); } + AliasType mightAlias(const MDefinition* def) const override { + // These instructions never modify the [[Prototype]]. + if (def->isAddAndStoreSlot() || def->isAllocateAndStoreSlot()) { + return AliasType::NoAlias; + } + return AliasType::MayAlias; + } }; -class MFunctionProto : public MNullaryInstruction { - explicit MFunctionProto() : MNullaryInstruction(classOpcode) { +class MBuiltinObject : public MNullaryInstruction { + BuiltinObjectKind builtinObjectKind_; + + explicit MBuiltinObject(BuiltinObjectKind kind) + : MNullaryInstruction(classOpcode), builtinObjectKind_(kind) { setResultType(MIRType::Object); } public: - INSTRUCTION_HEADER(FunctionProto) + INSTRUCTION_HEADER(BuiltinObject) TRIVIAL_NEW_WRAPPERS + BuiltinObjectKind builtinObjectKind() const { return builtinObjectKind_; } + bool possiblyCalls() const override { return true; } }; @@ -11310,6 +12521,73 @@ class MInitHomeObject : public MBinaryInstruction, } }; +// Return true if the object is definitely a TypedArray constructor, but not +// necessarily from the currently active realm. Return false if the object is +// not a TypedArray constructor or if it's a wrapper. +class MIsTypedArrayConstructor : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MIsTypedArrayConstructor(MDefinition* object) + : MUnaryInstruction(classOpcode, object) { + setResultType(MIRType::Boolean); + } + + public: + INSTRUCTION_HEADER(IsTypedArrayConstructor) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + +// Load the JSValueTag on all platforms except ARM64. See the comments in +// MacroAssembler-arm64.h for the |cmpTag(Register, ImmTag)| method for why +// ARM64 doesn't use the raw JSValueTag, but instead a modified tag value. That +// modified tag value can't be directly compared against JSValueTag constants. +class MLoadValueTag : public MUnaryInstruction, public BoxInputsPolicy::Data { + explicit MLoadValueTag(MDefinition* value) + : MUnaryInstruction(classOpcode, value) { + setResultType(MIRType::Int32); + setMovable(); + } + + public: + INSTRUCTION_HEADER(LoadValueTag) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, value)) + + AliasSet getAliasSet() const override { return AliasSet::None(); } + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } +}; + +// Load the target object from a proxy wrapper. The target is stored in the +// proxy object's private slot. +class MLoadWrapperTarget : public MUnaryInstruction, + public SingleObjectPolicy::Data { + explicit MLoadWrapperTarget(MDefinition* obj) + : MUnaryInstruction(classOpcode, obj) { + setResultType(MIRType::Object); + setMovable(); + } + + public: + INSTRUCTION_HEADER(LoadWrapperTarget) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, object)) + + AliasSet getAliasSet() const override { + // Can't use |AliasSet::None| because the target changes on navigation. + // TODO: Investigate using a narrower or a custom alias set. + return AliasSet::Load(AliasSet::Any); + } + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } +}; + // Flips the input's sign bit, independently of the rest of the number's // payload. Note this is different from multiplying by minus-one, which has // side-effects for e.g. NaNs. @@ -12381,6 +13659,25 @@ class MUnknownValue : public MNullaryInstruction { TRIVIAL_NEW_WRAPPERS }; +// Used by MIR building to represent the bytecode result of an operation for +// which an MBail was generated, to balance the basic block's MDefinition stack. +class MUnreachableResult : public MNullaryInstruction { + protected: + explicit MUnreachableResult(MIRType type) : MNullaryInstruction(classOpcode) { + MOZ_ASSERT(type != MIRType::None); + setResultType(type); + } + + public: + INSTRUCTION_HEADER(UnreachableResult) + TRIVIAL_NEW_WRAPPERS + + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); + } + AliasSet getAliasSet() const override { return AliasSet::None(); } +}; + class MIonToWasmCall final : public MVariadicInstruction, public NoTypePolicy::Data { CompilerGCPointer instanceObj_; diff --git a/js/src/jit/MIRBuilderShared.h b/js/src/jit/MIRBuilderShared.h index 2237eb47c7..24eeebfd98 100644 --- a/js/src/jit/MIRBuilderShared.h +++ b/js/src/jit/MIRBuilderShared.h @@ -32,9 +32,6 @@ class PendingEdge { // MGoto successor. Goto, - - // MGotoWithFake second successor. - GotoWithFake, }; private: @@ -55,9 +52,6 @@ class PendingEdge { static PendingEdge NewGoto(MBasicBlock* block) { return PendingEdge(block, Kind::Goto); } - static PendingEdge NewGotoWithFake(MBasicBlock* block) { - return PendingEdge(block, Kind::GotoWithFake); - } MBasicBlock* block() const { return block_; } Kind kind() const { return kind_; } @@ -109,9 +103,9 @@ using LoopStateStack = Vector; // Helper class to manage call state. class MOZ_STACK_CLASS CallInfo { - MDefinition* callee_; - MDefinition* thisArg_; - MDefinition* newTargetArg_; + MDefinition* callee_ = nullptr; + MDefinition* thisArg_ = nullptr; + MDefinition* newTargetArg_ = nullptr; MDefinitionVector args_; // If non-empty, this corresponds to the stack prior any implicit inlining // such as before JSOp::FunApply. @@ -122,20 +116,30 @@ class MOZ_STACK_CLASS CallInfo { // True if the caller does not use the return value. bool ignoresReturnValue_; - bool setter_; + bool inlined_ = false; + bool setter_ = false; bool apply_; + public: + // For some argument formats (normal calls, FunCall, FunApplyArgs in an + // inlined function) we can shuffle around definitions in the CallInfo + // and use a normal MCall. For others, we need to use a specialized call. + enum class ArgFormat { + Standard, + Array, + FunApplyArgs, + }; + + private: + ArgFormat argFormat_ = ArgFormat::Standard; + public: CallInfo(TempAllocator& alloc, jsbytecode* pc, bool constructing, bool ignoresReturnValue) - : callee_(nullptr), - thisArg_(nullptr), - newTargetArg_(nullptr), - args_(alloc), + : args_(alloc), priorArgs_(alloc), constructing_(constructing), ignoresReturnValue_(ignoresReturnValue), - setter_(false), apply_(JSOp(*pc) == JSOp::FunApply) {} MOZ_MUST_USE bool init(CallInfo& callInfo) { @@ -180,9 +184,43 @@ class MOZ_STACK_CLASS CallInfo { return true; } + void initForSpreadCall(MBasicBlock* current) { + MOZ_ASSERT(args_.empty()); + + if (constructing()) { + setNewTarget(current->pop()); + } + + // Spread calls have one argument, an Array object containing the args. + static_assert(decltype(args_)::InlineLength >= 1, + "Appending one argument should be infallible"); + MOZ_ALWAYS_TRUE(args_.append(current->pop())); + + // Get |this| and |callee| + setThis(current->pop()); + setCallee(current->pop()); + + argFormat_ = ArgFormat::Array; + } + + void initForGetterCall(MDefinition* callee, MDefinition* thisVal) { + MOZ_ASSERT(args_.empty()); + setCallee(callee); + setThis(thisVal); + } + void initForSetterCall(MDefinition* callee, MDefinition* thisVal, + MDefinition* rhs) { + MOZ_ASSERT(args_.empty()); + setCallee(callee); + setThis(thisVal); + static_assert(decltype(args_)::InlineLength >= 1, + "Appending one argument should be infallible"); + MOZ_ALWAYS_TRUE(args_.append(rhs)); + } + // Before doing any pop to the stack, capture whatever flows into the // instruction, such that we can restore it later. - AbortReasonOr savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, + MOZ_MUST_USE bool savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, size_t peekDepth); void popPriorCallStack(MBasicBlock* current) { @@ -193,7 +231,7 @@ class MOZ_STACK_CLASS CallInfo { } } - AbortReasonOr pushPriorCallStack(MIRGenerator* mir, + MOZ_MUST_USE bool pushPriorCallStack(MIRGenerator* mir, MBasicBlock* current) { if (priorArgs_.empty()) { return pushCallStack(mir, current); @@ -201,18 +239,18 @@ class MOZ_STACK_CLASS CallInfo { for (MDefinition* def : priorArgs_) { current->push(def); } - return Ok(); + return true; } void popCallStack(MBasicBlock* current) { current->popn(numFormals()); } - AbortReasonOr pushCallStack(MIRGenerator* mir, MBasicBlock* current) { + MOZ_MUST_USE bool pushCallStack(MIRGenerator* mir, MBasicBlock* current) { // Ensure sufficient space in the slots: needed for inlining from FunApply. if (apply_) { uint32_t depth = current->stackDepth() + numFormals(); if (depth > current->nslots()) { if (!current->increaseSlots(depth - current->nslots())) { - return mir->abort(AbortReason::Alloc); + return false; } } } @@ -228,7 +266,7 @@ class MOZ_STACK_CLASS CallInfo { current->push(getNewTarget()); } - return Ok(); + return true; } uint32_t argc() const { return args_.length(); } @@ -238,6 +276,10 @@ class MOZ_STACK_CLASS CallInfo { MOZ_ASSERT(args_.empty()); return args_.appendAll(args); } + MOZ_MUST_USE bool replaceArgs(const MDefinitionVector& args) { + args_.clear(); + return setArgs(args); + } MDefinitionVector& argv() { return args_; } @@ -286,6 +328,9 @@ class MOZ_STACK_CLASS CallInfo { bool isSetter() const { return setter_; } void markAsSetter() { setter_ = true; } + bool isInlined() const { return inlined_; } + void markAsInlined() { inlined_ = true; } + MDefinition* callee() const { MOZ_ASSERT(callee_); return callee_; @@ -309,6 +354,29 @@ class MOZ_STACK_CLASS CallInfo { auto setFlag = [](MDefinition* def) { def->setImplicitlyUsedUnchecked(); }; forEachCallOperand(setFlag); } + + ArgFormat argFormat() const { return argFormat_; } + void setArgFormat(ArgFormat argFormat) { argFormat_ = argFormat; } + + MDefinition* arrayArg() const { + MOZ_ASSERT(argFormat_ == ArgFormat::Array); + MOZ_ASSERT_IF(!apply_, argc() == 1 + uint32_t(constructing_)); + MOZ_ASSERT_IF(apply_, argc() == 2 && !constructing_); + return getArg(argc() - 1 - constructing_); + } +}; + +class AutoAccumulateReturns { + MIRGraph& graph_; + MIRGraphReturns* prev_; + + public: + AutoAccumulateReturns(MIRGraph& graph, MIRGraphReturns& returns) + : graph_(graph) { + prev_ = graph_.returnAccumulator(); + graph_.setReturnAccumulator(&returns); + } + ~AutoAccumulateReturns() { graph_.setReturnAccumulator(prev_); } }; } // namespace jit diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h index 3d07a9b3c7..077eec5548 100644 --- a/js/src/jit/MIRGenerator.h +++ b/js/src/jit/MIRGenerator.h @@ -36,7 +36,7 @@ class MIRGenerator final { const CompileInfo* outerInfo, const OptimizationInfo* optimizationInfo); - void initMinWasmHeapLength(uint32_t init) { minWasmHeapLength_ = init; } + void initMinWasmHeapLength(uint64_t init) { minWasmHeapLength_ = init; } TempAllocator& alloc() { return *alloc_; } MIRGraph& graph() { return *graph_; } @@ -75,9 +75,11 @@ class MIRGenerator final { // off-thread compilation can report what error got encountered. void setOffThreadStatus(AbortReasonOr result) { MOZ_ASSERT(offThreadStatus_.isOk()); - offThreadStatus_ = result; + offThreadStatus_ = std::move(result); + } + const AbortReasonOr& getOffThreadStatus() const { + return offThreadStatus_; } - AbortReasonOr getOffThreadStatus() const { return offThreadStatus_; } MOZ_MUST_USE bool instrumentedProfiling() { if (!instrumentedProfilingIsCached_) { @@ -113,7 +115,7 @@ class MIRGenerator final { MOZ_ASSERT(wasmMaxStackArgBytes_ == 0); wasmMaxStackArgBytes_ = n; } - uint32_t minWasmHeapLength() const { return minWasmHeapLength_; } + uint64_t minWasmHeapLength() const { return minWasmHeapLength_; } void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; } bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; } @@ -145,7 +147,7 @@ class MIRGenerator final { bool stringsCanBeInNursery_; bool bigIntsCanBeInNursery_; - uint32_t minWasmHeapLength_; + uint64_t minWasmHeapLength_; #if defined(JS_ION_PERF) WasmPerfSpewer wasmPerfSpewer_; diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 082804ed38..578a70470e 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -13,7 +13,6 @@ using namespace js; using namespace js::jit; -using mozilla::Swap; MIRGenerator::MIRGenerator(CompileRealm* realm, const JitCompileOptions& options, @@ -1209,7 +1208,7 @@ void MBasicBlock::setLoopHeader(MBasicBlock* newBackedge) { } // Set the loop backedge to be the last element in predecessors_. - Swap(predecessors_[oldIndex], predecessors_[lastIndex]); + std::swap(predecessors_[oldIndex], predecessors_[lastIndex]); // If we have phis, reorder their operands accordingly. if (!phisEmpty()) { diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h index 4506a4974a..ec1d28b79c 100644 --- a/js/src/jit/MacroAssembler-inl.h +++ b/js/src/jit/MacroAssembler-inl.h @@ -11,6 +11,7 @@ #include "mozilla/MathAlgorithms.h" #include "gc/Zone.h" +#include "vm/ProxyObject.h" #if defined(JS_CODEGEN_X86) # include "jit/x86/MacroAssembler-x86-inl.h" @@ -363,20 +364,14 @@ void MacroAssembler::branchTestFunctionFlags(Register fun, uint32_t flags, void MacroAssembler::branchIfFunctionHasNoJitEntry(Register fun, bool isConstructing, Label* label) { - int32_t flags = FunctionFlags::BASESCRIPT | FunctionFlags::SELFHOSTLAZY; - if (!isConstructing) { - flags |= FunctionFlags::WASM_JIT_ENTRY; - } + uint16_t flags = FunctionFlags::HasJitEntryFlags(isConstructing); branchTestFunctionFlags(fun, flags, Assembler::Zero, label); } void MacroAssembler::branchIfFunctionHasJitEntry(Register fun, bool isConstructing, Label* label) { - int32_t flags = FunctionFlags::BASESCRIPT | FunctionFlags::SELFHOSTLAZY; - if (!isConstructing) { - flags |= FunctionFlags::WASM_JIT_ENTRY; - } + uint16_t flags = FunctionFlags::HasJitEntryFlags(isConstructing); branchTestFunctionFlags(fun, flags, Assembler::NonZero, label); } @@ -625,6 +620,14 @@ void MacroAssembler::branchTestProxyHandlerFamily(Condition cond, Register scratch, const void* handlerp, Label* label) { +#ifdef DEBUG + Label ok; + loadObjClassUnsafe(proxy, scratch); + branchTestClassIsProxy(true, scratch, &ok); + assumeUnreachable("Expected ProxyObject in branchTestProxyHandlerFamily"); + bind(&ok); +#endif + Address handlerAddr(proxy, ProxyObject::offsetOfHandler()); loadPtr(handlerAddr, scratch); Address familyAddr(scratch, BaseProxyHandler::offsetOfFamily()); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index e1a05eb660..613aed10bd 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -16,6 +16,7 @@ #include "builtin/TypedObject.h" #include "gc/GCProbes.h" #include "jit/AtomicOp.h" +#include "jit/AtomicOperations.h" #include "jit/Bailouts.h" #include "jit/BaselineFrame.h" #include "jit/BaselineIC.h" @@ -24,12 +25,16 @@ #include "jit/Lowering.h" #include "jit/MIR.h" #include "jit/MoveEmitter.h" +#include "jit/SharedICHelpers.h" #include "jit/Simulator.h" #include "js/Conversions.h" #include "js/Printf.h" +#include "js/ScalarType.h" // js::Scalar::Type +#include "vm/ArgumentsObject.h" #include "vm/ArrayBufferViewObject.h" #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/TraceLogging.h" +#include "vm/TypedArrayObject.h" #include "gc/Nursery-inl.h" #include "jit/shared/Lowering-shared-inl.h" @@ -456,6 +461,31 @@ void MacroAssembler::storeToTypedBigIntArray(Scalar::Type arrayType, StoreToTypedBigIntArray(*this, arrayType, value, dest); } +void MacroAssembler::boxUint32(Register source, ValueOperand dest, + bool allowDouble, Label* fail) { + if (allowDouble) { + // If the value fits in an int32, store an int32 type tag. + // Else, convert the value to double and box it. + Label done, isDouble; + branchTest32(Assembler::Signed, source, source, &isDouble); + { + tagValue(JSVAL_TYPE_INT32, source, dest); + jump(&done); + } + bind(&isDouble); + { + ScratchDoubleScope fpscratch(*this); + convertUInt32ToDouble(source, fpscratch); + boxDouble(fpscratch, dest, fpscratch); + } + bind(&done); + } else { + // Fail if the value does not fit in an int32. + branchTest32(Assembler::Signed, source, source, fail); + tagValue(JSVAL_TYPE_INT32, source, dest); + } +} + template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T& src, AnyRegister dest, Register temp, @@ -533,27 +563,7 @@ void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T& src, case Scalar::Uint32: // Don't clobber dest when we could fail, instead use temp. load32(src, temp); - if (allowDouble) { - // If the value fits in an int32, store an int32 type tag. - // Else, convert the value to double and box it. - Label done, isDouble; - branchTest32(Assembler::Signed, temp, temp, &isDouble); - { - tagValue(JSVAL_TYPE_INT32, temp, dest); - jump(&done); - } - bind(&isDouble); - { - ScratchDoubleScope fpscratch(*this); - convertUInt32ToDouble(temp, fpscratch); - boxDouble(fpscratch, dest, fpscratch); - } - bind(&done); - } else { - // Bailout if the value does not fit in an int32. - branchTest32(Assembler::Signed, temp, temp, fail); - tagValue(JSVAL_TYPE_INT32, temp, dest); - } + boxUint32(temp, dest, allowDouble, fail); break; case Scalar::Float32: { ScratchDoubleScope dscratch(*this); @@ -662,7 +672,7 @@ void MacroAssembler::nurseryAllocateObject(Register result, Register temp, // with the nursery's end will always fail in such cases. CompileZone* zone = GetJitContext()->realm()->zone(); size_t thingSize = gc::Arena::thingSize(allocKind); - size_t totalSize = thingSize + nDynamicSlots * sizeof(HeapSlot); + size_t totalSize = thingSize + ObjectSlots::allocSize(nDynamicSlots); MOZ_ASSERT(totalSize < INT32_MAX); MOZ_ASSERT(totalSize % gc::CellAlignBytes == 0); @@ -671,7 +681,13 @@ void MacroAssembler::nurseryAllocateObject(Register result, Register temp, zone->addressOfNurseryCurrentEnd(), JS::TraceKind::Object, totalSize); if (nDynamicSlots) { - computeEffectiveAddress(Address(result, thingSize), temp); + store32(Imm32(nDynamicSlots), + Address(result, thingSize + ObjectSlots::offsetOfCapacity())); + store32( + Imm32(0), + Address(result, thingSize + ObjectSlots::offsetOfDictionarySlotSpan())); + computeEffectiveAddress( + Address(result, thingSize + ObjectSlots::offsetOfSlots()), temp); storePtr(temp, Address(result, NativeObject::offsetOfSlots())); } } @@ -1077,12 +1093,7 @@ void MacroAssembler::initTypedArraySlots(Register obj, Register temp, for (size_t i = 0; i < numZeroPointers; i++) { storePtr(ImmWord(0), Address(obj, dataOffset + i * sizeof(char*))); } -#ifdef DEBUG - if (nbytes == 0) { - store8(Imm32(TypedArrayObject::ZeroLengthArrayData), - Address(obj, dataSlotOffset)); - } -#endif + MOZ_ASSERT(nbytes > 0, "Zero-length TypedArrays need ZeroLengthArrayData"); } else { if (lengthKind == TypedArrayLength::Fixed) { move32(Imm32(length), lengthReg); @@ -1150,9 +1161,11 @@ void MacroAssembler::initGCSlots(Register obj, Register temp, fillSlotsWithUninitialized(Address(obj, offset), temp, startOfUninitialized, std::min(startOfUndefined, nfixed)); - offset = NativeObject::getFixedSlotOffset(startOfUndefined); - fillSlotsWithUndefined(Address(obj, offset), temp, startOfUndefined, - nfixed); + if (startOfUndefined < nfixed) { + offset = NativeObject::getFixedSlotOffset(startOfUndefined); + fillSlotsWithUndefined(Address(obj, offset), temp, startOfUndefined, + nfixed); + } } if (ndynamic) { @@ -1206,7 +1219,8 @@ void MacroAssembler::initGCThing(Register obj, Register temp, // If the object has dynamic slots, the slots member has already been // filled in. if (!ntemplate.hasDynamicSlots()) { - storePtr(ImmPtr(nullptr), Address(obj, NativeObject::offsetOfSlots())); + storePtr(ImmPtr(emptyObjectSlots), + Address(obj, NativeObject::offsetOfSlots())); } if (ntemplate.denseElementsAreCopyOnWrite()) { @@ -1799,6 +1813,73 @@ void MacroAssembler::debugAssertContextRealm(const void* realm, #endif } +void MacroAssembler::setIsCrossRealmArrayConstructor(Register obj, + Register output) { +#ifdef DEBUG + Label notProxy; + branchTestObjectIsProxy(false, obj, output, ¬Proxy); + assumeUnreachable("Unexpected proxy in setIsCrossRealmArrayConstructor"); + bind(¬Proxy); +#endif + + // The object's realm must not be cx->realm. + Label isFalse, done; + loadPtr(Address(obj, JSObject::offsetOfGroup()), output); + loadPtr(Address(output, ObjectGroup::offsetOfRealm()), output); + branchPtr(Assembler::Equal, AbsoluteAddress(ContextRealmPtr()), output, + &isFalse); + + // The object must be a function. + branchTestObjClass(Assembler::NotEqual, obj, &JSFunction::class_, output, obj, + &isFalse); + + // The function must be the ArrayConstructor native. + branchPtr(Assembler::NotEqual, + Address(obj, JSFunction::offsetOfNativeOrEnv()), + ImmPtr(js::ArrayConstructor), &isFalse); + + move32(Imm32(1), output); + jump(&done); + + bind(&isFalse); + move32(Imm32(0), output); + + bind(&done); +} + +void MacroAssembler::setIsDefinitelyTypedArrayConstructor(Register obj, + Register output) { + Label isFalse, isTrue, done; + + // The object must be a function. (Wrappers are not supported.) + branchTestObjClass(Assembler::NotEqual, obj, &JSFunction::class_, output, obj, + &isFalse); + + // Load the native into |output|. + loadPtr(Address(obj, JSFunction::offsetOfNativeOrEnv()), output); + + auto branchIsTypedArrayCtor = [&](Scalar::Type type) { + // The function must be a TypedArrayConstructor native (from any realm). + JSNative constructor = TypedArrayConstructorNative(type); + branchPtr(Assembler::Equal, output, ImmPtr(constructor), &isTrue); + }; + +#define TYPED_ARRAY_CONSTRUCTOR_NATIVE(T, N) branchIsTypedArrayCtor(Scalar::N); + JS_FOR_EACH_TYPED_ARRAY(TYPED_ARRAY_CONSTRUCTOR_NATIVE) +#undef TYPED_ARRAY_CONSTRUCTOR_NATIVE + + // Falls through to the false case. + + bind(&isFalse); + move32(Imm32(0), output); + jump(&done); + + bind(&isTrue); + move32(Imm32(1), output); + + bind(&done); +} + void MacroAssembler::guardGroupHasUnanalyzedNewScript(Register group, Register scratch, Label* fail) { @@ -1819,6 +1900,89 @@ void MacroAssembler::guardGroupHasUnanalyzedNewScript(Register group, bind(&noNewScript); } +void MacroAssembler::guardSpecificAtom(Register str, JSAtom* atom, + Register scratch, + const LiveRegisterSet& volatileRegs, + Label* fail) { + Label done; + branchPtr(Assembler::Equal, str, ImmGCPtr(atom), &done); + + // The pointers are not equal, so if the input string is also an atom it + // must be a different string. + branchTest32(Assembler::NonZero, Address(str, JSString::offsetOfFlags()), + Imm32(JSString::ATOM_BIT), fail); + + // Check the length. + branch32(Assembler::NotEqual, Address(str, JSString::offsetOfLength()), + Imm32(atom->length()), fail); + + // We have a non-atomized string with the same length. Call a helper + // function to do the comparison. + PushRegsInMask(volatileRegs); + + setupUnalignedABICall(scratch); + movePtr(ImmGCPtr(atom), scratch); + passABIArg(scratch); + passABIArg(str); + callWithABI(JS_FUNC_TO_DATA_PTR(void*, EqualStringsHelperPure)); + mov(ReturnReg, scratch); + + MOZ_ASSERT(!volatileRegs.has(scratch)); + PopRegsInMask(volatileRegs); + branchIfFalseBool(scratch, fail); + + bind(&done); +} + +void MacroAssembler::guardStringToInt32(Register str, Register output, + Register scratch, + LiveRegisterSet volatileRegs, + Label* fail) { + Label vmCall, done; + // Use indexed value as fast path if possible. + loadStringIndexValue(str, output, &vmCall); + jump(&done); + { + bind(&vmCall); + + // Reserve stack for holding the result value of the call. + reserveStack(sizeof(int32_t)); + moveStackPtrTo(output); + + volatileRegs.takeUnchecked(scratch); + if (output.volatile_()) { + volatileRegs.addUnchecked(output); + } + PushRegsInMask(volatileRegs); + + setupUnalignedABICall(scratch); + loadJSContext(scratch); + passABIArg(scratch); + passABIArg(str); + passABIArg(output); + callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetInt32FromStringPure)); + mov(ReturnReg, scratch); + + PopRegsInMask(volatileRegs); + + Label ok; + branchIfTrueBool(scratch, &ok); + { + // OOM path, recovered by GetInt32FromStringPure. + // + // Use addToStackPtr instead of freeStack as freeStack tracks stack height + // flow-insensitively, and using it twice would confuse the stack height + // tracking. + addToStackPtr(Imm32(sizeof(int32_t))); + jump(fail); + } + bind(&ok); + load32(Address(output, 0), output); + freeStack(sizeof(int32_t)); + } + bind(&done); +} + void MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo) { loadJSContext(scratch); @@ -1954,6 +2118,28 @@ void MacroAssembler::loadJitCodeNoArgCheck(Register func, Register dest) { loadPtr(Address(dest, JitScript::offsetOfJitCodeSkipArgCheck()), dest); } +void MacroAssembler::loadBaselineJitCodeRaw(Register func, Register dest, + Label* failure) { + // Load JitScript + loadPtr(Address(func, JSFunction::offsetOfScript()), dest); + if (failure) { + branchIfScriptHasNoJitScript(dest, failure); + } + loadJitScript(dest, dest); + + // Load BaselineScript + loadPtr(Address(dest, JitScript::offsetOfBaselineScript()), dest); + if (failure) { + static_assert(BaselineDisabledScript == 0x1); + branchPtr(Assembler::BelowOrEqual, dest, ImmWord(BaselineDisabledScript), + failure); + } + + // Load Baseline jitcode + loadPtr(Address(dest, BaselineScript::offsetOfMethod()), dest); + loadPtr(Address(dest, JitCode::offsetOfCode()), dest); +} + void MacroAssembler::loadBaselineFramePtr(Register framePtr, Register dest) { if (framePtr != dest) { movePtr(framePtr, dest); @@ -2463,9 +2649,7 @@ void MacroAssembler::link(JitCode* code) { } MacroAssembler::AutoProfilerCallInstrumentation:: - AutoProfilerCallInstrumentation( - MacroAssembler& masm MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; + AutoProfilerCallInstrumentation(MacroAssembler& masm) { if (!masm.emitProfilingInstrumentation_) { return; } @@ -3055,6 +3239,68 @@ void MacroAssembler::pow32(Register base, Register power, Register dest, bind(&done); } +void MacroAssembler::signInt32(Register input, Register output) { + MOZ_ASSERT(input != output); + + Label done; + move32(input, output); + rshift32Arithmetic(Imm32(31), output); + branch32(Assembler::LessThanOrEqual, input, Imm32(0), &done); + move32(Imm32(1), output); + bind(&done); +} + +void MacroAssembler::signDouble(FloatRegister input, FloatRegister output) { + MOZ_ASSERT(input != output); + + Label done, zeroOrNaN, negative; + loadConstantDouble(0.0, output); + branchDouble(Assembler::DoubleEqualOrUnordered, input, output, &zeroOrNaN); + branchDouble(Assembler::DoubleLessThan, input, output, &negative); + + loadConstantDouble(1.0, output); + jump(&done); + + bind(&negative); + loadConstantDouble(-1.0, output); + jump(&done); + + bind(&zeroOrNaN); + moveDouble(input, output); + + bind(&done); +} + +void MacroAssembler::signDoubleToInt32(FloatRegister input, Register output, + FloatRegister temp, Label* fail) { + MOZ_ASSERT(input != temp); + + Label done, zeroOrNaN, negative; + loadConstantDouble(0.0, temp); + branchDouble(Assembler::DoubleEqualOrUnordered, input, temp, &zeroOrNaN); + branchDouble(Assembler::DoubleLessThan, input, temp, &negative); + + move32(Imm32(1), output); + jump(&done); + + bind(&negative); + move32(Imm32(-1), output); + jump(&done); + + // Fail for NaN and negative zero. + bind(&zeroOrNaN); + branchDouble(Assembler::DoubleUnordered, input, input, fail); + + // The easiest way to distinguish -0.0 from 0.0 is that 1.0/-0.0 + // is -Infinity instead of Infinity. + loadConstantDouble(1.0, temp); + divDouble(input, temp); + branchDouble(Assembler::DoubleLessThan, temp, input, fail); + move32(Imm32(0), output); + + bind(&done); +} + void MacroAssembler::randomDouble(Register rng, FloatRegister dest, Register64 temp0, Register64 temp1) { using mozilla::non_crypto::XorShift128PlusRNG; @@ -3117,6 +3363,53 @@ void MacroAssembler::randomDouble(Register rng, FloatRegister dest, mulDoublePtr(ImmPtr(&ScaleInv), s0Reg.scratchReg(), dest); } +void MacroAssembler::sameValueDouble(FloatRegister left, FloatRegister right, + FloatRegister temp, Register dest) { + Label nonEqual, isSameValue, isNotSameValue; + branchDouble(Assembler::DoubleNotEqualOrUnordered, left, right, &nonEqual); + { + // First, test for being equal to 0.0, which also includes -0.0. + loadConstantDouble(0.0, temp); + branchDouble(Assembler::DoubleNotEqual, left, temp, &isSameValue); + + // The easiest way to distinguish -0.0 from 0.0 is that 1.0/-0.0 + // is -Infinity instead of Infinity. + Label isNegInf; + loadConstantDouble(1.0, temp); + divDouble(left, temp); + branchDouble(Assembler::DoubleLessThan, temp, left, &isNegInf); + { + loadConstantDouble(1.0, temp); + divDouble(right, temp); + branchDouble(Assembler::DoubleGreaterThan, temp, right, &isSameValue); + jump(&isNotSameValue); + } + bind(&isNegInf); + { + loadConstantDouble(1.0, temp); + divDouble(right, temp); + branchDouble(Assembler::DoubleLessThan, temp, right, &isSameValue); + jump(&isNotSameValue); + } + } + bind(&nonEqual); + { + // Test if both values are NaN. + branchDouble(Assembler::DoubleOrdered, left, left, &isNotSameValue); + branchDouble(Assembler::DoubleOrdered, right, right, &isNotSameValue); + } + + Label done; + bind(&isSameValue); + move32(Imm32(1), dest); + jump(&done); + + bind(&isNotSameValue); + move32(Imm32(0), dest); + + bind(&done); +} + void MacroAssembler::branchIfNotRegExpPrototypeOptimizable(Register proto, Register temp, Label* fail) { @@ -3172,10 +3465,9 @@ void MacroAssembler::loadFunctionLength(Register func, Register funFlags, bind(&isBound); { // Load the length property of a bound function. - Address boundLength( - func, FunctionExtended::offsetOfExtendedSlot(BOUND_FUN_LENGTH_SLOT)); - branchTestInt32(Assembler::NotEqual, boundLength, slowPath); - unboxInt32(boundLength, output); + Address boundLength(func, + FunctionExtended::offsetOfBoundFunctionLengthSlot()); + fallibleUnboxInt32(boundLength, output, slowPath); jump(&lengthLoaded); } bind(&isInterpreted); @@ -3191,6 +3483,52 @@ void MacroAssembler::loadFunctionLength(Register func, Register funFlags, bind(&lengthLoaded); } +void MacroAssembler::loadFunctionName(Register func, Register output, + ImmGCPtr emptyString, Label* slowPath) { + MOZ_ASSERT(func != output); + + // Get the JSFunction flags. + load16ZeroExtend(Address(func, JSFunction::offsetOfFlags()), output); + + // If the name was previously resolved, the name property may be shadowed. + branchTest32(Assembler::NonZero, output, Imm32(FunctionFlags::RESOLVED_NAME), + slowPath); + + Label notBoundTarget, loadName; + branchTest32(Assembler::Zero, output, Imm32(FunctionFlags::BOUND_FUN), + ¬BoundTarget); + { + // Call into the VM if the target's name atom doesn't contain the bound + // function prefix. + branchTest32(Assembler::Zero, output, + Imm32(FunctionFlags::HAS_BOUND_FUNCTION_NAME_PREFIX), + slowPath); + + // Bound functions reuse HAS_GUESSED_ATOM for + // HAS_BOUND_FUNCTION_NAME_PREFIX, so skip the guessed atom check below. + static_assert( + FunctionFlags::HAS_BOUND_FUNCTION_NAME_PREFIX == + FunctionFlags::HAS_GUESSED_ATOM, + "HAS_BOUND_FUNCTION_NAME_PREFIX is shared with HAS_GUESSED_ATOM"); + jump(&loadName); + } + bind(¬BoundTarget); + + Label guessed, hasName; + branchTest32(Assembler::NonZero, output, + Imm32(FunctionFlags::HAS_GUESSED_ATOM), &guessed); + bind(&loadName); + loadPtr(Address(func, JSFunction::offsetOfAtom()), output); + branchTestPtr(Assembler::NonZero, output, output, &hasName); + { + bind(&guessed); + + // An absent name property defaults to the empty string. + movePtr(emptyString, output); + } + bind(&hasName); +} + void MacroAssembler::branchTestObjGroupNoSpectreMitigations( Condition cond, Register obj, const Address& group, Register scratch, Label* label) { @@ -3655,6 +3993,26 @@ void MacroAssembler::emitPreBarrierFastPath(JSRuntime* rt, MIRType type, branchTestPtr(Assembler::NonZero, temp2, temp1, noBarrier); } +// ======================================================================== +// JS atomic operations. + +void MacroAssembler::atomicIsLockFreeJS(Register value, Register output) { + // Keep this in sync with isLockfreeJS() in jit/AtomicOperations.h. + MOZ_ASSERT(AtomicOperations::isLockfreeJS(1)); // Implementation artifact + MOZ_ASSERT(AtomicOperations::isLockfreeJS(2)); // Implementation artifact + MOZ_ASSERT(AtomicOperations::isLockfreeJS(4)); // Spec requirement + MOZ_ASSERT( + !AtomicOperations::isLockfreeJS(8)); // Implementation invariant, for now + + Label done; + move32(Imm32(1), output); + branch32(Assembler::Equal, value, Imm32(4), &done); + branch32(Assembler::Equal, value, Imm32(2), &done); + branch32(Assembler::Equal, value, Imm32(1), &done); + move32(Imm32(0), output); + bind(&done); +} + // ======================================================================== // Spectre Mitigations. @@ -3702,9 +4060,8 @@ void MacroAssembler::memoryBarrierAfter(const Synchronization& sync) { } void MacroAssembler::loadWasmTlsRegFromFrame(Register dest) { - loadPtr( - Address(getStackPointer(), framePushed() + offsetof(wasm::Frame, tls)), - dest); + loadPtr(Address(getStackPointer(), framePushed() + wasm::Frame::tlsOffset()), + dest); } void MacroAssembler::BranchGCPtr::emit(MacroAssembler& masm) { @@ -3734,6 +4091,286 @@ void MacroAssembler::debugAssertObjHasFixedSlots(Register obj, #endif } +void MacroAssembler::branchArrayIsNotPacked(Register array, Register temp1, + Register temp2, Label* label) { + loadPtr(Address(array, NativeObject::offsetOfElements()), temp1); + + // Test length == initializedLength. + Label done; + Address initLength(temp1, ObjectElements::offsetOfInitializedLength()); + load32(Address(temp1, ObjectElements::offsetOfLength()), temp2); + branch32(Assembler::NotEqual, initLength, temp2, label); + + // Test the NON_PACKED flag. + Address flags(temp1, ObjectElements::offsetOfFlags()); + branchTest32(Assembler::NonZero, flags, Imm32(ObjectElements::NON_PACKED), + label); +} + +void MacroAssembler::setIsPackedArray(Register obj, Register output, + Register temp) { + // Ensure it's an ArrayObject. + Label notPackedArray; + branchTestObjClass(Assembler::NotEqual, obj, &ArrayObject::class_, temp, obj, + ¬PackedArray); + + branchArrayIsNotPacked(obj, temp, output, ¬PackedArray); + + Label done; + move32(Imm32(1), output); + jump(&done); + + bind(¬PackedArray); + move32(Imm32(0), output); + + bind(&done); +} + +void MacroAssembler::packedArrayPop(Register array, ValueOperand output, + Register temp1, Register temp2, + Label* fail) { + // Load obj->elements in temp1. + loadPtr(Address(array, NativeObject::offsetOfElements()), temp1); + + // Check flags. + static constexpr uint32_t UnhandledFlags = + ObjectElements::Flags::NON_PACKED | ObjectElements::Flags::COPY_ON_WRITE | + ObjectElements::Flags::NONWRITABLE_ARRAY_LENGTH | + ObjectElements::Flags::NOT_EXTENSIBLE | + ObjectElements::Flags::MAYBE_IN_ITERATION; + Address flags(temp1, ObjectElements::offsetOfFlags()); + branchTest32(Assembler::NonZero, flags, Imm32(UnhandledFlags), fail); + + // Load length in temp2. Ensure length == initializedLength. + Address lengthAddr(temp1, ObjectElements::offsetOfLength()); + Address initLengthAddr(temp1, ObjectElements::offsetOfInitializedLength()); + load32(lengthAddr, temp2); + branch32(Assembler::NotEqual, initLengthAddr, temp2, fail); + + // Result is |undefined| if length == 0. + Label notEmpty, done; + branchTest32(Assembler::NonZero, temp2, temp2, ¬Empty); + { + moveValue(UndefinedValue(), output); + jump(&done); + } + + bind(¬Empty); + + // Load the last element. + sub32(Imm32(1), temp2); + BaseObjectElementIndex elementAddr(temp1, temp2); + loadValue(elementAddr, output); + + // Pre-barrier the element because we're removing it from the array. + EmitPreBarrier(*this, elementAddr, MIRType::Value); + + // Update length and initializedLength. + store32(temp2, lengthAddr); + store32(temp2, initLengthAddr); + + bind(&done); +} + +void MacroAssembler::packedArrayShift(Register array, ValueOperand output, + Register temp1, Register temp2, + LiveRegisterSet volatileRegs, + Label* fail) { + // Load obj->elements in temp1. + loadPtr(Address(array, NativeObject::offsetOfElements()), temp1); + + // Check flags. + static constexpr uint32_t UnhandledFlags = + ObjectElements::Flags::NON_PACKED | ObjectElements::Flags::COPY_ON_WRITE | + ObjectElements::Flags::NONWRITABLE_ARRAY_LENGTH | + ObjectElements::Flags::NOT_EXTENSIBLE | + ObjectElements::Flags::MAYBE_IN_ITERATION; + Address flags(temp1, ObjectElements::offsetOfFlags()); + branchTest32(Assembler::NonZero, flags, Imm32(UnhandledFlags), fail); + + // Load length in temp2. Ensure length == initializedLength. + Address lengthAddr(temp1, ObjectElements::offsetOfLength()); + Address initLengthAddr(temp1, ObjectElements::offsetOfInitializedLength()); + load32(lengthAddr, temp2); + branch32(Assembler::NotEqual, initLengthAddr, temp2, fail); + + // Result is |undefined| if length == 0. + Label notEmpty, done; + branchTest32(Assembler::NonZero, temp2, temp2, ¬Empty); + { + moveValue(UndefinedValue(), output); + jump(&done); + } + + bind(¬Empty); + + // Load the first element. + Address elementAddr(temp1, 0); + loadValue(elementAddr, output); + + // Pre-barrier the element because we're removing it from the array. + EmitPreBarrier(*this, elementAddr, MIRType::Value); + + // Move the other elements. + { + // Ensure output and temp2 are in volatileRegs. Don't preserve temp1. + volatileRegs.takeUnchecked(temp1); + if (output.hasVolatileReg()) { + volatileRegs.addUnchecked(output); + } + if (temp2.volatile_()) { + volatileRegs.addUnchecked(temp2); + } + + PushRegsInMask(volatileRegs); + + setupUnalignedABICall(temp1); + passABIArg(array); + callWithABI(JS_FUNC_TO_DATA_PTR(void*, ArrayShiftMoveElements)); + + PopRegsInMask(volatileRegs); + + // Reload the elements. The call may have updated it. + loadPtr(Address(array, NativeObject::offsetOfElements()), temp1); + } + + // Update length and initializedLength. + sub32(Imm32(1), temp2); + store32(temp2, lengthAddr); + store32(temp2, initLengthAddr); + + bind(&done); +} + +void MacroAssembler::loadArgumentsObjectElement(Register obj, Register index, + ValueOperand output, + Register temp, Label* fail) { + Register temp2 = output.scratchReg(); + + // Get initial length value. + unboxInt32(Address(obj, ArgumentsObject::getInitialLengthSlotOffset()), temp); + + // Ensure no overridden elements. + branchTest32(Assembler::NonZero, temp, + Imm32(ArgumentsObject::ELEMENT_OVERRIDDEN_BIT), fail); + + // Bounds check. + rshift32(Imm32(ArgumentsObject::PACKED_BITS_COUNT), temp); + spectreBoundsCheck32(index, temp, temp2, fail); + + // Load ArgumentsData. + loadPrivate(Address(obj, ArgumentsObject::getDataSlotOffset()), temp); + + // Fail if we have a RareArgumentsData (elements were deleted). + branchPtr(Assembler::NotEqual, + Address(temp, offsetof(ArgumentsData, rareData)), ImmWord(0), fail); + + // Guard the argument is not a FORWARD_TO_CALL_SLOT MagicValue. + BaseValueIndex argValue(temp, index, ArgumentsData::offsetOfArgs()); + branchTestMagic(Assembler::Equal, argValue, fail); + loadValue(argValue, output); +} + +void MacroAssembler::loadArgumentsObjectLength(Register obj, Register output, + Label* fail) { + // Get initial length value. + unboxInt32(Address(obj, ArgumentsObject::getInitialLengthSlotOffset()), + output); + + // Test if length has been overridden. + branchTest32(Assembler::NonZero, output, + Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT), fail); + + // Shift out arguments length and return it. + rshift32(Imm32(ArgumentsObject::PACKED_BITS_COUNT), output); +} + +static constexpr bool ValidateShiftRange(Scalar::Type from, Scalar::Type to) { + for (Scalar::Type type = from; type < to; type = Scalar::Type(type + 1)) { + if (TypedArrayShift(type) != TypedArrayShift(from)) { + return false; + } + } + return true; +} + +void MacroAssembler::typedArrayElementShift(Register obj, Register output) { + static_assert(Scalar::Int8 == 0, "Int8 is the first typed array class"); + static_assert( + (Scalar::BigUint64 - Scalar::Int8) == Scalar::MaxTypedArrayViewType - 1, + "BigUint64 is the last typed array class"); + + Label zero, one, two, three, done; + + loadObjClassUnsafe(obj, output); + + static_assert(ValidateShiftRange(Scalar::Int8, Scalar::Int16), + "shift amount is zero in [Int8, Int16)"); + branchPtr(Assembler::Below, output, + ImmPtr(TypedArrayObject::classForType(Scalar::Int16)), &zero); + + static_assert(ValidateShiftRange(Scalar::Int16, Scalar::Int32), + "shift amount is one in [Int16, Int32)"); + branchPtr(Assembler::Below, output, + ImmPtr(TypedArrayObject::classForType(Scalar::Int32)), &one); + + static_assert(ValidateShiftRange(Scalar::Int32, Scalar::Float64), + "shift amount is two in [Int32, Float64)"); + branchPtr(Assembler::Below, output, + ImmPtr(TypedArrayObject::classForType(Scalar::Float64)), &two); + + static_assert(ValidateShiftRange(Scalar::Float64, Scalar::Uint8Clamped), + "shift amount is three in [Float64, Uint8Clamped)"); + branchPtr(Assembler::Below, output, + ImmPtr(TypedArrayObject::classForType(Scalar::Uint8Clamped)), + &three); + + static_assert(ValidateShiftRange(Scalar::Uint8Clamped, Scalar::BigInt64), + "shift amount is zero in [Uint8Clamped, BigInt64)"); + branchPtr(Assembler::Below, output, + ImmPtr(TypedArrayObject::classForType(Scalar::BigInt64)), &zero); + + static_assert( + ValidateShiftRange(Scalar::BigInt64, Scalar::MaxTypedArrayViewType), + "shift amount is three in [BigInt64, MaxTypedArrayViewType)"); + // Fall through for BigInt64 and BigUint64 + + bind(&three); + move32(Imm32(3), output); + jump(&done); + + bind(&two); + move32(Imm32(2), output); + jump(&done); + + bind(&one); + move32(Imm32(1), output); + jump(&done); + + bind(&zero); + move32(Imm32(0), output); + + bind(&done); +} + +void MacroAssembler::branchIfClassIsNotTypedArray(Register clasp, + Label* notTypedArray) { + static_assert(Scalar::Int8 == 0, "Int8 is the first typed array class"); + const JSClass* firstTypedArrayClass = + TypedArrayObject::classForType(Scalar::Int8); + + static_assert( + (Scalar::BigUint64 - Scalar::Int8) == Scalar::MaxTypedArrayViewType - 1, + "BigUint64 is the last typed array class"); + const JSClass* lastTypedArrayClass = + TypedArrayObject::classForType(Scalar::BigUint64); + + branchPtr(Assembler::Below, clasp, ImmPtr(firstTypedArrayClass), + notTypedArray); + branchPtr(Assembler::Above, clasp, ImmPtr(lastTypedArrayClass), + notTypedArray); +} + void MacroAssembler::branchIfNativeIteratorNotReusable(Register ni, Label* notReusable) { // See NativeIterator::isReusable. @@ -3870,10 +4507,10 @@ ObjectGroup* MacroAssembler::getGroupAndDelayBarrier(const TypeSet* types, void MacroAssembler::performPendingReadBarriers() { for (JSObject* object : pendingObjectReadBarriers_) { - JSObject::readBarrier(object); + gc::ReadBarrier(object); } for (ObjectGroup* group : pendingObjectGroupReadBarriers_) { - ObjectGroup::readBarrier(group); + gc::ReadBarrier(group); } } diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index dd95b47bcb..53102c18ff 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -9,8 +9,6 @@ #include "mozilla/MacroForEach.h" #include "mozilla/MathAlgorithms.h" -#include "vm/Realm.h" - #if defined(JS_CODEGEN_X86) # include "jit/x86/MacroAssembler-x86.h" #elif defined(JS_CODEGEN_X64) @@ -34,10 +32,8 @@ #include "jit/JitRealm.h" #include "jit/TemplateObject.h" #include "jit/VMFunctions.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "util/Memory.h" -#include "vm/ProxyObject.h" -#include "vm/Shape.h" -#include "vm/TypedArrayObject.h" // [SMDOC] MacroAssembler multi-platform overview // @@ -205,6 +201,9 @@ #endif namespace js { + +class TypedArrayObject; + namespace jit { // Defined in JitFrames.h @@ -840,16 +839,16 @@ class MacroAssembler : public MacroAssemblerSpecific { // Swap instructions // Swap the two lower bytes and sign extend the result to 32-bit. - inline void swap16SignExtend(Register reg) PER_SHARED_ARCH; + inline void byteSwap16SignExtend(Register reg) PER_SHARED_ARCH; // Swap the two lower bytes and zero extend the result to 32-bit. - inline void swap16ZeroExtend(Register reg) PER_SHARED_ARCH; + inline void byteSwap16ZeroExtend(Register reg) PER_SHARED_ARCH; // Swap all four bytes in a 32-bit integer. - inline void swap32(Register reg) PER_SHARED_ARCH; + inline void byteSwap32(Register reg) PER_SHARED_ARCH; // Swap all eight bytes in a 64-bit integer. - inline void swap64(Register64 reg) PER_ARCH; + inline void byteSwap64(Register64 reg) PER_ARCH; // =============================================================== // Arithmetic functions @@ -1021,6 +1020,16 @@ class MacroAssembler : public MacroAssemblerSpecific { void roundDoubleToInt32(FloatRegister src, Register dest, FloatRegister temp, Label* fail) PER_SHARED_ARCH; + void truncFloat32ToInt32(FloatRegister src, Register dest, + Label* fail) PER_SHARED_ARCH; + void truncDoubleToInt32(FloatRegister src, Register dest, + Label* fail) PER_SHARED_ARCH; + + void signInt32(Register input, Register output); + void signDouble(FloatRegister input, FloatRegister output); + void signDoubleToInt32(FloatRegister input, Register output, + FloatRegister temp, Label* fail); + // Returns a random double in range [0, 1) in |dest|. The |rng| register must // hold a pointer to a mozilla::non_crypto::XorShift128PlusRNG. void randomDouble(Register rng, FloatRegister dest, Register64 temp0, @@ -1045,6 +1054,9 @@ class MacroAssembler : public MacroAssemblerSpecific { void pow32(Register base, Register power, Register dest, Register temp1, Register temp2, Label* onOver); + void sameValueDouble(FloatRegister left, FloatRegister right, + FloatRegister temp, Register dest); + void branchIfNotRegExpPrototypeOptimizable(Register proto, Register temp, Label* label); void branchIfNotRegExpInstanceOptimizable(Register regexp, Register temp, @@ -1081,7 +1093,10 @@ class MacroAssembler : public MacroAssemblerSpecific { inline void rshift32Arithmetic(Register shift, Register srcDest) PER_SHARED_ARCH; - // These variants may use the stack, but do not have the above constraint. + // These variants do not have the above constraint, but may emit some extra + // instructions on x86_shared. They also handle shift >= 32 consistently by + // masking with 0x1F (either explicitly or relying on the hardware to do + // that). inline void flexibleLshift32(Register shift, Register srcDest) PER_SHARED_ARCH; inline void flexibleRshift32(Register shift, @@ -1384,6 +1399,11 @@ class MacroAssembler : public MacroAssemblerSpecific { void loadFunctionLength(Register func, Register funFlags, Register output, Label* slowPath); + // Loads the function name. This handles interpreted, native, and bound + // functions. + void loadFunctionName(Register func, Register output, ImmGCPtr emptyString, + Label* slowPath); + inline void branchFunctionKind(Condition cond, FunctionFlags::FunctionKind kind, Register fun, Register scratch, Label* label); @@ -2385,7 +2405,7 @@ class MacroAssembler : public MacroAssemblerSpecific { // // If arrayType is Scalar::Uint32 then: // - // - `output` must be a float register (this is bug 1077305) + // - `output` must be a float register // - if the operation takes one temp register then `temp` must be defined // - if the operation takes two temp registers then `temp2` must be defined. // @@ -2494,6 +2514,8 @@ class MacroAssembler : public MacroAssemblerSpecific { Register valueTemp, Register offsetTemp, Register maskTemp) DEFINED_ON(mips_shared); + void atomicIsLockFreeJS(Register value, Register output); + // ======================================================================== // Spectre Mitigations. // @@ -2671,6 +2693,12 @@ class MacroAssembler : public MacroAssemblerSpecific { void guardGroupHasUnanalyzedNewScript(Register group, Register scratch, Label* fail); + void guardSpecificAtom(Register str, JSAtom* atom, Register scratch, + const LiveRegisterSet& volatileRegs, Label* fail); + + void guardStringToInt32(Register str, Register output, Register scratch, + LiveRegisterSet volatileRegs, Label* fail); + void loadWasmTlsRegFromFrame(Register dest = WasmTlsReg); template @@ -2819,6 +2847,9 @@ class MacroAssembler : public MacroAssemblerSpecific { bind(&done); } + void boxUint32(Register source, ValueOperand dest, bool allowDouble, + Label* fail); + template void loadFromTypedArray(Scalar::Type arrayType, const T& src, AnyRegister dest, Register temp, Label* fail); @@ -2870,6 +2901,26 @@ class MacroAssembler : public MacroAssemblerSpecific { void debugAssertIsObject(const ValueOperand& val); void debugAssertObjHasFixedSlots(Register obj, Register scratch); + void branchArrayIsNotPacked(Register array, Register temp1, Register temp2, + Label* label); + + void setIsPackedArray(Register obj, Register output, Register temp); + + void packedArrayPop(Register array, ValueOperand output, Register temp1, + Register temp2, Label* fail); + void packedArrayShift(Register array, ValueOperand output, Register temp1, + Register temp2, LiveRegisterSet volatileRegs, + Label* fail); + + void loadArgumentsObjectElement(Register obj, Register index, + ValueOperand output, Register temp, + Label* fail); + + void loadArgumentsObjectLength(Register obj, Register output, Label* fail); + + void typedArrayElementShift(Register obj, Register output); + void branchIfClassIsNotTypedArray(Register clasp, Label* notTypedArray); + void branchIfNativeIteratorNotReusable(Register ni, Label* notReusable); void iteratorMore(Register obj, ValueOperand output, Register temp); @@ -2998,6 +3049,10 @@ class MacroAssembler : public MacroAssemblerSpecific { isCallableOrConstructor(false, obj, output, isProxy); } + void setIsCrossRealmArrayConstructor(Register obj, Register output); + + void setIsDefinitelyTypedArrayConstructor(Register obj, Register output); + private: void isCallableOrConstructor(bool isCallable, Register obj, Register output, Label* isProxy); @@ -3078,12 +3133,9 @@ class MacroAssembler : public MacroAssemblerSpecific { // This class is used to surround call sites throughout the assembler. This // is used by callWithABI, and callJit functions, except if suffixed by // NoProfiler. - class AutoProfilerCallInstrumentation { - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER; - + class MOZ_RAII AutoProfilerCallInstrumentation { public: - explicit AutoProfilerCallInstrumentation( - MacroAssembler& masm MOZ_GUARD_OBJECT_NOTIFIER_PARAM); + explicit AutoProfilerCallInstrumentation(MacroAssembler& masm); ~AutoProfilerCallInstrumentation() = default; }; friend class AutoProfilerCallInstrumentation; @@ -3107,6 +3159,8 @@ class MacroAssembler : public MacroAssemblerSpecific { public: void loadJitCodeRaw(Register func, Register dest); void loadJitCodeNoArgCheck(Register func, Register dest); + void loadBaselineJitCodeRaw(Register func, Register dest, + Label* failure = nullptr); void loadBaselineFramePtr(Register framePtr, Register dest); diff --git a/js/src/jit/PerfSpewer.h b/js/src/jit/PerfSpewer.h index e9d070acc2..cc9d189960 100644 --- a/js/src/jit/PerfSpewer.h +++ b/js/src/jit/PerfSpewer.h @@ -7,9 +7,10 @@ #ifdef JS_ION_PERF # include -# include "jit/MacroAssembler.h" #endif +#include "jit/Label.h" + namespace { struct AutoLockPerfMap; } diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index f3857f7322..75a24410dd 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -19,6 +19,7 @@ #include "jit/MIRGenerator.h" #include "jit/MIRGraph.h" #include "js/Conversions.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "util/CheckedArithmetic.h" #include "vm/ArgumentsObject.h" #include "vm/TypedArrayObject.h" @@ -40,7 +41,6 @@ using mozilla::IsNegativeZero; using mozilla::NegativeInfinity; using mozilla::NumberEqualsInt32; using mozilla::PositiveInfinity; -using mozilla::Swap; // [SMDOC] IonMonkey Range Analysis // @@ -910,13 +910,13 @@ Range* Range::xor_(TempAllocator& alloc, const Range* lhs, const Range* rhs) { if (lhsUpper < 0) { lhsLower = ~lhsLower; lhsUpper = ~lhsUpper; - Swap(lhsLower, lhsUpper); + std::swap(lhsLower, lhsUpper); invertAfter = !invertAfter; } if (rhsUpper < 0) { rhsLower = ~rhsLower; rhsUpper = ~rhsUpper; - Swap(rhsLower, rhsUpper); + std::swap(rhsLower, rhsUpper); invertAfter = !invertAfter; } @@ -950,7 +950,7 @@ Range* Range::xor_(TempAllocator& alloc, const Range* lhs, const Range* rhs) { if (invertAfter) { lower = ~lower; upper = ~upper; - Swap(lower, upper); + std::swap(lower, upper); } return Range::NewInt32Range(alloc, lower, upper); @@ -1767,10 +1767,12 @@ void MLoadDataViewElement::computeRange(TempAllocator& alloc) { } void MArrayLength::computeRange(TempAllocator& alloc) { - // Array lengths can go up to UINT32_MAX, but we only create MArrayLength + // Array lengths can go up to UINT32_MAX. IonBuilder only creates MArrayLength // nodes when the value is known to be int32 (see the - // OBJECT_FLAG_LENGTH_OVERFLOW flag). - setRange(Range::NewUInt32Range(alloc, 0, INT32_MAX)); + // OBJECT_FLAG_LENGTH_OVERFLOW flag). WarpBuilder does a dynamic check and we + // have to return the range pre-bailouts, so use UINT32_MAX for Warp. + uint32_t max = JitOptions.warpBuilder ? UINT32_MAX : INT32_MAX; + setRange(Range::NewUInt32Range(alloc, 0, max)); } void MInitializedLength::computeRange(TempAllocator& alloc) { @@ -2856,6 +2858,9 @@ static bool CloneForDeadBranches(TempAllocator& alloc, } MInstruction* clone = candidate->clone(alloc, operands); + if (!clone) { + return false; + } clone->setRange(nullptr); // Set UseRemoved flag on the cloned instruction in order to chain recover diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp index efd0c608b6..8f85a6fd89 100644 --- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -164,8 +164,8 @@ bool AllocationIntegrityState::check() { size_t inputIndex = 0; for (LInstruction::InputIterator alloc(*ins); alloc.more(); - alloc.next()) { - LAllocation oldInput = info.inputs[inputIndex++]; + inputIndex++, alloc.next()) { + LAllocation oldInput = info.inputs[inputIndex]; if (!oldInput.isUse()) { continue; } @@ -176,6 +176,28 @@ bool AllocationIntegrityState::check() { checkSafepointAllocation(ins, vreg, **alloc); } + // Temps must never alias inputs (even at-start uses) unless explicitly + // requested. + for (size_t i = 0; i < ins->numTemps(); i++) { + if (ins->getTemp(i)->isBogusTemp()) { + continue; + } + LAllocation* tempAlloc = ins->getTemp(i)->output(); + + // Fixed uses and fixed temps are allowed to alias. + if (oldInput.toUse()->isFixedRegister() && info.temps[i].isFixed()) { + continue; + } + + // MUST_REUSE_INPUT temps will alias their input. + if (info.temps[i].policy() == LDefinition::MUST_REUSE_INPUT && + info.temps[i].getReusedInput() == inputIndex) { + continue; + } + + MOZ_ASSERT(!tempAlloc->aliases(**alloc)); + } + // Start checking at the previous instruction, in case this // instruction reuses its input register for an output. LInstructionReverseIterator riter = block->rbegin(ins); diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h index efc5b1f99a..ba538ee71e 100644 --- a/js/src/jit/RegisterSets.h +++ b/js/src/jit/RegisterSets.h @@ -128,6 +128,9 @@ class ValueOperand { return type_ == reg || payload_ == reg; } constexpr Register payloadOrValueReg() const { return payloadReg(); } + bool hasVolatileReg() const { + return type_.volatile_() || payload_.volatile_(); + } constexpr bool operator==(const ValueOperand& o) const { return type_ == o.type_ && payload_ == o.payload_; } @@ -145,6 +148,7 @@ class ValueOperand { constexpr Register64 toRegister64() const { return Register64(valueReg()); } constexpr bool aliases(Register reg) const { return value_ == reg; } constexpr Register payloadOrValueReg() const { return valueReg(); } + bool hasVolatileReg() const { return value_.volatile_(); } constexpr bool operator==(const ValueOperand& o) const { return value_ == o.value_; } diff --git a/js/src/jit/RematerializedFrame.cpp b/js/src/jit/RematerializedFrame.cpp index e643e6c083..8f00b9eb66 100644 --- a/js/src/jit/RematerializedFrame.cpp +++ b/js/src/jit/RematerializedFrame.cpp @@ -9,6 +9,7 @@ #include "debugger/DebugAPI.h" #include "jit/JitFrames.h" +#include "js/friend/DumpFunctions.h" // js::DumpValue #include "vm/ArgumentsObject.h" #include "jit/JitFrames-inl.h" diff --git a/js/src/jit/RematerializedFrame.h b/js/src/jit/RematerializedFrame.h index baec37d647..b504e08897 100644 --- a/js/src/jit/RematerializedFrame.h +++ b/js/src/jit/RematerializedFrame.h @@ -10,11 +10,13 @@ #include "jit/JitFrames.h" #include "jit/JSJitFrameIter.h" #include "js/UniquePtr.h" -#include "vm/EnvironmentObject.h" #include "vm/JSFunction.h" #include "vm/Stack.h" namespace js { + +class CallObject; + namespace jit { // RematerializedFrame: An optimized frame that has been rematerialized with diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index 682fe184cc..4d9dc973a6 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -515,7 +515,7 @@ void ObjectMemoryView::visitStoreFixedSlot(MStoreFixedSlot* ins) { } else { // UnsafeSetReserveSlot can access baked-in slots which are guarded by // conditions, which are not seen by the escape analysis. - MBail* bailout = MBail::New(alloc_, Bailout_Inevitable); + MBail* bailout = MBail::New(alloc_, BailoutKind::Inevitable); ins->block()->insertBefore(ins, bailout); } @@ -535,7 +535,7 @@ void ObjectMemoryView::visitLoadFixedSlot(MLoadFixedSlot* ins) { } else { // UnsafeGetReserveSlot can access baked-in slots which are guarded by // conditions, which are not seen by the escape analysis. - MBail* bailout = MBail::New(alloc_, Bailout_Inevitable); + MBail* bailout = MBail::New(alloc_, BailoutKind::Inevitable); ins->block()->insertBefore(ins, bailout); ins->replaceAllUsesWith(undefinedVal_); } @@ -577,7 +577,7 @@ void ObjectMemoryView::visitStoreDynamicSlot(MStoreDynamicSlot* ins) { } else { // UnsafeSetReserveSlot can access baked-in slots which are guarded by // conditions, which are not seen by the escape analysis. - MBail* bailout = MBail::New(alloc_, Bailout_Inevitable); + MBail* bailout = MBail::New(alloc_, BailoutKind::Inevitable); ins->block()->insertBefore(ins, bailout); } @@ -601,7 +601,7 @@ void ObjectMemoryView::visitLoadDynamicSlot(MLoadDynamicSlot* ins) { } else { // UnsafeGetReserveSlot can access baked-in slots which are guarded by // conditions, which are not seen by the escape analysis. - MBail* bailout = MBail::New(alloc_, Bailout_Inevitable); + MBail* bailout = MBail::New(alloc_, BailoutKind::Inevitable); ins->block()->insertBefore(ins, bailout); ins->replaceAllUsesWith(undefinedVal_); } @@ -753,41 +753,39 @@ static bool IsElementEscaped(MDefinition* def, uint32_t arraySize) { } case MDefinition::Opcode::StoreElement: { - MOZ_ASSERT(access->toStoreElement()->elements() == def); + MStoreElement* storeElem = access->toStoreElement(); + MOZ_ASSERT(storeElem->elements() == def); // If we need hole checks, then the array cannot be escaped // as the array might refer to the prototype chain to look // for properties, thus it might do additional side-effects // which are not reflected by the alias set, is we are // bailing on holes. - if (access->toStoreElement()->needsHoleCheck()) { + if (storeElem->needsHoleCheck()) { JitSpewDef(JitSpew_Escape, "has a store element with a hole check\n", - access); + storeElem); return true; } // If the index is not a constant then this index can alias // all others. We do not handle this case. int32_t index; - if (!IndexOf(access, &index)) { + if (!IndexOf(storeElem, &index)) { JitSpewDef(JitSpew_Escape, - "has a store element with a non-trivial index\n", access); + "has a store element with a non-trivial index\n", + storeElem); return true; } if (index < 0 || arraySize <= uint32_t(index)) { JitSpewDef(JitSpew_Escape, "has a store element with an out-of-bound index\n", - access); + storeElem); return true; } - // We are not yet encoding magic hole constants in resume points. - if (access->toStoreElement()->value()->type() == MIRType::MagicHole) { - JitSpewDef(JitSpew_Escape, - "has a store element with an magic-hole constant\n", - access); - return true; - } + // Dense element holes are written using MStoreHoleValueElement instead + // of MStoreElement. + MOZ_ASSERT(storeElem->value()->type() != MIRType::MagicHole); break; } diff --git a/js/src/jit/Sink.cpp b/js/src/jit/Sink.cpp index 35e12382b6..28a4f04356 100644 --- a/js/src/jit/Sink.cpp +++ b/js/src/jit/Sink.cpp @@ -192,6 +192,9 @@ bool Sink(MIRGenerator* mir, MIRGraph& graph) { } MInstruction* clone = ins->clone(alloc, operands); + if (!clone) { + return false; + } ins->block()->insertBefore(ins, clone); clone->setRecoveredOnBailout(); diff --git a/js/src/jit/Snapshots.cpp b/js/src/jit/Snapshots.cpp index ebc22473c0..99fe77adf5 100644 --- a/js/src/jit/Snapshots.cpp +++ b/js/src/jit/Snapshots.cpp @@ -416,7 +416,8 @@ static const uint32_t SNAPSHOT_BAILOUTKIND_BITS = 6; static const uint32_t SNAPSHOT_BAILOUTKIND_MASK = COMPUTE_MASK_(SNAPSHOT_BAILOUTKIND); -static_assert((1 << SNAPSHOT_BAILOUTKIND_BITS) - 1 >= Bailout_Limit, +static_assert((1 << SNAPSHOT_BAILOUTKIND_BITS) - 1 >= + uint8_t(BailoutKind::Limit), "Not enough bits for BailoutKinds"); static const uint32_t SNAPSHOT_ROFFSET_SHIFT = diff --git a/js/src/jit/TemplateObject-inl.h b/js/src/jit/TemplateObject-inl.h index 8c98fe92ce..2146267ed0 100644 --- a/js/src/jit/TemplateObject-inl.h +++ b/js/src/jit/TemplateObject-inl.h @@ -74,10 +74,7 @@ inline bool NativeTemplateObject::hasDynamicSlots() const { } inline uint32_t NativeTemplateObject::numDynamicSlots() const { - // We can't call numDynamicSlots because that uses shape->base->clasp and - // shape->base can change when we create a ShapeTable. - return NativeObject::dynamicSlotsCount(numFixedSlots(), slotSpan(), - obj_->getClass()); + return asNative().numDynamicSlots(); } inline uint32_t NativeTemplateObject::numUsedFixedSlots() const { diff --git a/js/src/jit/TrialInlining.cpp b/js/src/jit/TrialInlining.cpp new file mode 100644 index 0000000000..61be941e61 --- /dev/null +++ b/js/src/jit/TrialInlining.cpp @@ -0,0 +1,455 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/TrialInlining.h" + +#include "jit/BaselineCacheIRCompiler.h" +#include "jit/BaselineIC.h" +#include "jit/CacheIRHealth.h" +#include "jit/Ion.h" // TooManyFormalArguments + +#include "jit/BaselineFrame-inl.h" +#include "vm/BytecodeIterator-inl.h" +#include "vm/BytecodeLocation-inl.h" + +using mozilla::Maybe; + +namespace js { +namespace jit { + +bool DoTrialInlining(JSContext* cx, BaselineFrame* frame) { + MOZ_ASSERT(JitOptions.warpBuilder); + + RootedScript script(cx, frame->script()); + ICScript* icScript = frame->icScript(); + bool isRecursive = icScript->depth() > 0; + +#ifdef JS_CACHEIR_SPEW + if (cx->spewer().enabled(cx, script, SpewChannel::RateMyCacheIR)) { + CacheIRHealth cih; + cih.rateMyCacheIR(cx, script); + } +#endif + + if (!script->canIonCompile()) { + return true; + } + + // Baseline shouldn't attempt trial inlining in scripts that are too large. + MOZ_ASSERT_IF(JitOptions.limitScriptSize, + script->length() <= JitOptions.ionMaxScriptSize); + + const uint32_t MAX_INLINING_DEPTH = 4; + if (icScript->depth() > MAX_INLINING_DEPTH) { + return true; + } + + InliningRoot* root = + isRecursive ? icScript->inliningRoot() + : script->jitScript()->getOrCreateInliningRoot(cx, script); + if (!root) { + return false; + } + + JitSpew(JitSpew_WarpTrialInlining, + "Trial inlining for %s script %s:%u:%u (%p) (inliningRoot=%p)", + (isRecursive ? "inner" : "outer"), script->filename(), + script->lineno(), script->column(), frame->script(), root); + + TrialInliner inliner(cx, script, icScript, root); + return inliner.tryInlining(); +} + +void TrialInliner::cloneSharedPrefix(ICStub* stub, const uint8_t* endOfPrefix, + CacheIRWriter& writer) { + CacheIRReader reader(stub->cacheIRStubInfo()); + CacheIRCloner cloner(stub); + while (reader.currentPosition() < endOfPrefix) { + CacheOp op = reader.readOp(); + cloner.cloneOp(op, reader, writer); + } +} + +bool TrialInliner::replaceICStub(const ICEntry& entry, CacheIRWriter& writer, + CacheKind kind) { + ICFallbackStub* fallback = entry.fallbackStub(); + MOZ_ASSERT(fallback->trialInliningState() == TrialInliningState::Candidate); + + fallback->discardStubs(cx(), root_->owningScript()); + + // Note: AttachBaselineCacheIRStub never throws an exception. + bool attached = false; + ICStub* newStub = AttachBaselineCacheIRStub( + cx(), writer, kind, BaselineCacheIRStubKind::Regular, script_, icScript_, + fallback, &attached); + if (!newStub) { + MOZ_ASSERT(fallback->trialInliningState() == TrialInliningState::Candidate); + ReportOutOfMemory(cx()); + return false; + } + + MOZ_ASSERT(attached); + MOZ_ASSERT(fallback->trialInliningState() == TrialInliningState::Inlined); + JitSpew(JitSpew_WarpTrialInlining, "Attached new stub %p", newStub); + return true; +} + +ICStub* TrialInliner::maybeSingleStub(const ICEntry& entry) { + // Look for a single non-fallback stub followed by stubs with entered-count 0. + // Allow one optimized stub before the fallback stub to support the + // CallIRGenerator::emitCalleeGuard optimization where we first try a + // GuardSpecificFunction guard before falling back to GuardFunctionHasScript. + ICStub* stub = entry.firstStub(); + if (stub->isFallback()) { + return nullptr; + } + ICStub* next = stub->next(); + if (next->getEnteredCount() != 0) { + return nullptr; + } + + ICFallbackStub* fallback = nullptr; + if (next->isFallback()) { + fallback = next->toFallbackStub(); + } else { + ICStub* nextNext = next->next(); + if (!nextNext->isFallback() || nextNext->getEnteredCount() != 0) { + return nullptr; + } + fallback = nextNext->toFallbackStub(); + } + + if (fallback->trialInliningState() != TrialInliningState::Candidate) { + return nullptr; + } + + return stub; +} + +Maybe FindInlinableCallData(ICStub* stub) { + Maybe data; + + const CacheIRStubInfo* stubInfo = stub->cacheIRStubInfo(); + const uint8_t* stubData = stub->cacheIRStubData(); + + ObjOperandId calleeGuardOperand; + CallFlags flags; + JSFunction* target = nullptr; + + CacheIRReader reader(stubInfo); + while (reader.more()) { + const uint8_t* opStart = reader.currentPosition(); + + CacheOp op = reader.readOp(); + uint32_t argLength = CacheIROpInfos[size_t(op)].argLength; + mozilla::DebugOnly argStart = reader.currentPosition(); + + switch (op) { + case CacheOp::GuardSpecificFunction: { + // If we see a guard, remember which operand we are guarding. + MOZ_ASSERT(data.isNothing()); + calleeGuardOperand = reader.objOperandId(); + uint32_t targetOffset = reader.stubOffset(); + mozilla::Unused << reader.stubOffset(); // nargsAndFlags + uintptr_t rawTarget = stubInfo->getStubRawWord(stubData, targetOffset); + target = reinterpret_cast(rawTarget); + break; + } + case CacheOp::GuardFunctionScript: { + MOZ_ASSERT(data.isNothing()); + calleeGuardOperand = reader.objOperandId(); + uint32_t targetOffset = reader.stubOffset(); + uintptr_t rawTarget = stubInfo->getStubRawWord(stubData, targetOffset); + target = reinterpret_cast(rawTarget)->function(); + mozilla::Unused << reader.stubOffset(); // nargsAndFlags + break; + } + case CacheOp::CallScriptedFunction: { + // If we see a call, check if `callee` is the previously guarded + // operand. If it is, we know the target and can inline. + ObjOperandId calleeOperand = reader.objOperandId(); + mozilla::DebugOnly argcId = reader.int32OperandId(); + flags = reader.callFlags(); + + if (calleeOperand == calleeGuardOperand) { + MOZ_ASSERT(static_cast(argcId).id() == 0); + MOZ_ASSERT(data.isNothing()); + data.emplace(); + data->endOfSharedPrefix = opStart; + } + break; + } + case CacheOp::CallInlinedFunction: { + ObjOperandId calleeOperand = reader.objOperandId(); + mozilla::DebugOnly argcId = reader.int32OperandId(); + uint32_t icScriptOffset = reader.stubOffset(); + flags = reader.callFlags(); + + if (calleeOperand == calleeGuardOperand) { + MOZ_ASSERT(static_cast(argcId).id() == 0); + MOZ_ASSERT(data.isNothing()); + data.emplace(); + data->endOfSharedPrefix = opStart; + uintptr_t rawICScript = + stubInfo->getStubRawWord(stubData, icScriptOffset); + data->icScript = reinterpret_cast(rawICScript); + } + break; + } + default: + if (data.isSome()) { + MOZ_ASSERT(op == CacheOp::ReturnFromIC || + op == CacheOp::TypeMonitorResult); + } + reader.skip(argLength); + break; + } + MOZ_ASSERT(argStart + argLength == reader.currentPosition()); + } + + if (data.isSome()) { + data->calleeOperand = calleeGuardOperand; + data->callFlags = flags; + data->target = target; + } + return data; +} + +/*static*/ +bool TrialInliner::canInline(JSFunction* target, HandleScript caller) { + if (!target->hasJitScript()) { + return false; + } + JSScript* script = target->nonLazyScript(); + if (!script->jitScript()->hasBaselineScript() || script->uninlineable() || + !script->canIonCompile() || script->needsArgsObj() || + script->isDebuggee()) { + return false; + } + // Don't inline cross-realm calls. + if (target->realm() != caller->realm()) { + return false; + } + return true; +} + +bool TrialInliner::shouldInline(JSFunction* target, ICStub* stub, + BytecodeLocation loc) { + if (!canInline(target, script_)) { + return false; + } + JitSpew(JitSpew_WarpTrialInlining, + "Inlining candidate JSOp::%s: callee script %s:%u:%u", + CodeName(loc.getOp()), target->nonLazyScript()->filename(), + target->nonLazyScript()->lineno(), target->nonLazyScript()->column()); + + // Don't inline (direct) recursive calls. This still allows recursion if + // called through another function (f => g => f). + JSScript* targetScript = target->nonLazyScript(); + if (script_ == targetScript) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: recursion"); + return false; + } + + // Don't inline if the callee has a loop that was hot enough to enter Warp + // via OSR. This helps prevent getting stuck in Baseline code for a long time. + if (targetScript->jitScript()->hadIonOSR()) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: had OSR"); + return false; + } + + // Ensure the total bytecode size does not exceed ionMaxScriptSize. + size_t newTotalSize = root_->totalBytecodeSize() + targetScript->length(); + if (newTotalSize > JitOptions.ionMaxScriptSize) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: total size too big"); + return false; + } + + uint32_t entryCount = stub->getEnteredCount(); + if (entryCount < JitOptions.inliningEntryThreshold) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: Entry count is %u (minimum %u)", + unsigned(entryCount), unsigned(JitOptions.inliningEntryThreshold)); + return false; + } + + if (!JitOptions.isSmallFunction(targetScript)) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: Length is %u (maximum %u)", + unsigned(targetScript->length()), + unsigned(JitOptions.smallFunctionMaxBytecodeLength)); + return false; + } + + if (TooManyFormalArguments(target->nargs())) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: Too many formal arguments: %u", + unsigned(target->nargs())); + return false; + } + + if (TooManyFormalArguments(loc.getCallArgc())) { + JitSpew(JitSpew_WarpTrialInlining, "SKIP: argc too large: %u", + unsigned(loc.getCallArgc())); + return false; + } + + return true; +} + +ICScript* TrialInliner::createInlinedICScript(JSFunction* target, + BytecodeLocation loc) { + MOZ_ASSERT(target->hasJitEntry()); + MOZ_ASSERT(target->hasJitScript()); + + JSScript* targetScript = target->baseScript()->asJSScript(); + + // We don't have to check for overflow here because we have already + // successfully allocated an ICScript with this number of entries + // when creating the JitScript for the target function, and we + // checked for overflow then. + uint32_t allocSize = + sizeof(ICScript) + targetScript->numICEntries() * sizeof(ICEntry); + + void* raw = cx()->pod_malloc(allocSize); + MOZ_ASSERT(uintptr_t(raw) % alignof(ICScript) == 0); + if (!raw) { + return nullptr; + } + + uint32_t initialWarmUpCount = JitOptions.trialInliningInitialWarmUpCount; + + uint32_t depth = icScript_->depth() + 1; + UniquePtr inlinedICScript( + new (raw) ICScript(initialWarmUpCount, allocSize, depth, root_)); + + { + // Suppress GC. This matches the AutoEnterAnalysis in + // JSScript::createJitScript. It is needed for allocating the + // template object for JSOp::Rest and the object group for + // JSOp::NewArray. + gc::AutoSuppressGC suppress(cx()); + if (!inlinedICScript->initICEntries(cx(), targetScript)) { + return nullptr; + } + } + + uint32_t pcOffset = loc.bytecodeToOffset(script_); + ICScript* result = inlinedICScript.get(); + if (!icScript_->addInlinedChild(cx(), std::move(inlinedICScript), pcOffset)) { + return nullptr; + } + MOZ_ASSERT(result->numICEntries() == targetScript->numICEntries()); + + root_->addToTotalBytecodeSize(targetScript->length()); + + JitSpew(JitSpew_WarpTrialInlining, + "Outer ICScript: %p Inner ICScript: %p pcOffset: %u", icScript_, + result, pcOffset); + + return result; +} + +bool TrialInliner::maybeInlineCall(const ICEntry& entry, BytecodeLocation loc) { + ICStub* stub = maybeSingleStub(entry); + if (!stub) { + return true; + } + + MOZ_ASSERT(!icScript_->hasInlinedChild(entry.pcOffset())); + + // Look for a CallScriptedFunction with a known target. + Maybe data = FindInlinableCallData(stub); + if (data.isNothing()) { + return true; + } + + MOZ_ASSERT(!data->icScript); + + // Decide whether to inline the target. + if (!shouldInline(data->target, stub, loc)) { + return true; + } + + // We only inline FunCall if we are calling the js::fun_call builtin. + MOZ_ASSERT_IF(loc.getOp() == JSOp::FunCall, + data->callFlags.getArgFormat() == CallFlags::FunCall); + + ICScript* newICScript = createInlinedICScript(data->target, loc); + if (!newICScript) { + return false; + } + + CacheIRWriter writer(cx()); + Int32OperandId argcId(writer.setInputOperandId(0)); + cloneSharedPrefix(stub, data->endOfSharedPrefix, writer); + + writer.callInlinedFunction(data->calleeOperand, argcId, newICScript, + data->callFlags); + writer.returnFromIC(); + + if (!replaceICStub(entry, writer, CacheKind::Call)) { + icScript_->removeInlinedChild(entry.pcOffset()); + return false; + } + + return true; +} + +bool TrialInliner::tryInlining() { + uint32_t numICEntries = icScript_->numICEntries(); + BytecodeLocation startLoc = script_->location(); + + for (uint32_t icIndex = 0; icIndex < numICEntries; icIndex++) { + const ICEntry& entry = icScript_->icEntry(icIndex); + BytecodeLocation loc = startLoc + BytecodeLocationOffset(entry.pcOffset()); + JSOp op = loc.getOp(); + switch (op) { + case JSOp::Call: + case JSOp::CallIgnoresRv: + case JSOp::CallIter: + case JSOp::FunCall: + case JSOp::New: + case JSOp::SuperCall: + if (!maybeInlineCall(entry, loc)) { + return false; + } + break; + default: + break; + } + } + + return true; +} + +bool InliningRoot::addInlinedScript(UniquePtr icScript) { + return inlinedScripts_.append(std::move(icScript)); +} + +void InliningRoot::removeInlinedScript(ICScript* icScript) { + inlinedScripts_.eraseIf( + [icScript](const UniquePtr& script) -> bool { + return script.get() == icScript; + }); +} + +void InliningRoot::trace(JSTracer* trc) { + TraceEdge(trc, &owningScript_, "inlining-root-owning-script"); + for (auto& inlinedScript : inlinedScripts_) { + inlinedScript->trace(trc); + } +} + +void InliningRoot::purgeOptimizedStubs(Zone* zone) { + for (auto& inlinedScript : inlinedScripts_) { + inlinedScript->purgeOptimizedStubs(zone); + } +} + +void InliningRoot::resetWarmUpCounts(uint32_t count) { + for (auto& inlinedScript : inlinedScripts_) { + inlinedScript->resetWarmUpCount(count); + } +} + +} // namespace jit +} // namespace js diff --git a/js/src/jit/TrialInlining.h b/js/src/jit/TrialInlining.h new file mode 100644 index 0000000000..b9d7378b9d --- /dev/null +++ b/js/src/jit/TrialInlining.h @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.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 jit_TrialInlining_h +#define jit_TrialInlining_h + +#include "jit/CacheIR.h" +#include "jit/ICStubSpace.h" +#include "vm/BytecodeLocation.h" + +/* + * [SMDOC] Trial Inlining + * + * WarpBuilder relies on transpiling CacheIR. When inlining scripted + * functions in WarpBuilder, we want our ICs to be as monomorphic as + * possible. Functions with multiple callers complicate this. An IC in + * such a function might be monomorphic for any given caller, but + * polymorphic overall. This make the input to WarpBuilder less precise. + * + * To solve this problem, we do trial inlining. During baseline + * execution, we identify call sites for which it would be useful to + * have more precise inlining data. For each such call site, we + * allocate a fresh ICScript and replace the existing call IC with a + * new specialized IC that invokes the callee using the new + * ICScript. Other callers of the callee will continue using the + * default ICScript. When we eventually Warp-compile the script, we + * can generate code for the callee using the IC information in our + * private ICScript, which is specialized for its caller. + * + * The same approach can be used to inline recursively. + */ + +namespace js { +namespace jit { + +class ICEntry; +class ICScript; + +/* + * An InliningRoot is owned by a JitScript. In turn, it owns the set + * of ICScripts that are candidates for being inlined in that JitScript. + */ +class InliningRoot { + public: + explicit InliningRoot(JSContext* cx, JSScript* owningScript) + : owningScript_(owningScript), + inlinedScripts_(cx), + totalBytecodeSize_(owningScript->length()) {} + + FallbackICStubSpace* fallbackStubSpace() { return &fallbackStubSpace_; } + + void trace(JSTracer* trc); + + bool addInlinedScript(js::UniquePtr icScript); + void removeInlinedScript(ICScript* icScript); + + uint32_t numInlinedScripts() const { return inlinedScripts_.length(); } + + void purgeOptimizedStubs(Zone* zone); + void resetWarmUpCounts(uint32_t count); + + JSScript* owningScript() const { return owningScript_; } + + size_t totalBytecodeSize() const { return totalBytecodeSize_; } + + void addToTotalBytecodeSize(size_t size) { totalBytecodeSize_ += size; } + + private: + FallbackICStubSpace fallbackStubSpace_ = {}; + HeapPtr owningScript_; + js::Vector> inlinedScripts_; + + // Bytecode size of outer script and all inlined scripts. + size_t totalBytecodeSize_; +}; + +class InlinableCallData { + public: + ObjOperandId calleeOperand; + CallFlags callFlags; + const uint8_t* endOfSharedPrefix = nullptr; + JSFunction* target = nullptr; + ICScript* icScript = nullptr; +}; + +mozilla::Maybe FindInlinableCallData(ICStub* stub); + +class MOZ_RAII TrialInliner { + public: + TrialInliner(JSContext* cx, HandleScript script, ICScript* icScript, + InliningRoot* root) + : cx_(cx), script_(script), icScript_(icScript), root_(root) {} + + JSContext* cx() { return cx_; } + + MOZ_MUST_USE bool tryInlining(); + MOZ_MUST_USE bool maybeInlineCall(const ICEntry& entry, BytecodeLocation loc); + + static bool canInline(JSFunction* target, HandleScript caller); + + private: + ICStub* maybeSingleStub(const ICEntry& entry); + void cloneSharedPrefix(ICStub* stub, const uint8_t* endOfPrefix, + CacheIRWriter& writer); + ICScript* createInlinedICScript(JSFunction* target, BytecodeLocation loc); + MOZ_MUST_USE bool replaceICStub(const ICEntry& entry, CacheIRWriter& writer, + CacheKind kind); + + bool shouldInline(JSFunction* target, ICStub* stub, BytecodeLocation loc); + + JSContext* cx_; + HandleScript script_; + ICScript* icScript_; + InliningRoot* root_; +}; + +bool DoTrialInlining(JSContext* cx, BaselineFrame* frame); + +} // namespace jit +} // namespace js + +#endif /* jit_TrialInlining_h */ diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index af2711251f..8777c028e1 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -7,6 +7,7 @@ #include "jit/Lowering.h" #include "jit/MIR.h" #include "jit/MIRGraph.h" +#include "js/ScalarType.h" // js::Scalar::Type #include "jit/shared/Lowering-shared-inl.h" @@ -867,6 +868,35 @@ bool ToStringPolicy::staticAdjustInputs(TempAllocator& alloc, return true; } +bool ToInt64Policy::staticAdjustInputs(TempAllocator& alloc, + MInstruction* ins) { + MOZ_ASSERT(ins->isToInt64()); + + MDefinition* input = ins->getOperand(0); + MIRType type = input->type(); + + switch (type) { + case MIRType::BigInt: { + auto* replace = MTruncateBigIntToInt64::New(alloc, input); + ins->block()->insertBefore(ins, replace); + ins->replaceOperand(0, replace); + break; + } + // No need for boxing for these types, because they are handled specially + // when this instruction is lowered to LIR. + case MIRType::Boolean: + case MIRType::String: + case MIRType::Int64: + case MIRType::Value: + break; + default: + ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0))); + break; + } + + return true; +} + template bool ObjectPolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins) { @@ -938,18 +968,6 @@ bool CallSetElementPolicy::adjustInputs(TempAllocator& alloc, return true; } -bool InstanceOfPolicy::adjustInputs(TempAllocator& alloc, - MInstruction* def) const { - // Box first operand if it isn't object - if (def->getOperand(0)->type() != MIRType::Object) { - if (!BoxPolicy<0>::staticAdjustInputs(alloc, def)) { - return false; - } - } - - return true; -} - bool StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* ins, Scalar::Type writeType, @@ -1201,7 +1219,6 @@ bool TypedArrayIndexPolicy::adjustInputs(TempAllocator& alloc, _(ClampPolicy) \ _(ComparePolicy) \ _(FilterTypeSetPolicy) \ - _(InstanceOfPolicy) \ _(PowPolicy) \ _(SameValuePolicy) \ _(SignPolicy) \ @@ -1213,6 +1230,7 @@ bool TypedArrayIndexPolicy::adjustInputs(TempAllocator& alloc, _(ToInt32Policy) \ _(ToBigIntPolicy) \ _(ToStringPolicy) \ + _(ToInt64Policy) \ _(TypeBarrierPolicy) \ _(TypedArrayIndexPolicy) @@ -1268,6 +1286,7 @@ bool TypedArrayIndexPolicy::adjustInputs(TempAllocator& alloc, _(MixPolicy, StringPolicy<1>>) \ _(MixPolicy, BoxPolicy<1>>) \ _(MixPolicy, BoxPolicy<2>, ObjectPolicy<3>>) \ + _(MixPolicy, ObjectPolicy<1>>) \ _(NoFloatPolicy<0>) \ _(NoFloatPolicy<1>) \ _(NoFloatPolicy<2>) \ diff --git a/js/src/jit/TypePolicy.h b/js/src/jit/TypePolicy.h index c400caf64c..ec2c306cb4 100644 --- a/js/src/jit/TypePolicy.h +++ b/js/src/jit/TypePolicy.h @@ -7,6 +7,7 @@ #include "jit/IonTypes.h" #include "jit/JitAllocPolicy.h" +#include "js/ScalarType.h" // js::Scalar::Type namespace js { namespace jit { @@ -365,6 +366,19 @@ class ToStringPolicy final : public TypePolicy { } }; +// Box non-Boolean, non-String, non-BigInt as input to a ToInt64 instruction. +class ToInt64Policy final : public TypePolicy { + public: + constexpr ToInt64Policy() = default; + EMPTY_DATA_; + static MOZ_MUST_USE bool staticAdjustInputs(TempAllocator& alloc, + MInstruction* ins); + MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, + MInstruction* ins) const override { + return staticAdjustInputs(alloc, ins); + } +}; + template class ObjectPolicy final : public TypePolicy { public: @@ -446,16 +460,6 @@ class CallSetElementPolicy final : public TypePolicy { MInstruction* def) const override; }; -// First operand will be boxed to a Value (except for an object) -// Second operand (if specified) will forcefully be unboxed to an object -class InstanceOfPolicy final : public TypePolicy { - public: - constexpr InstanceOfPolicy() = default; - EMPTY_DATA_; - MOZ_MUST_USE bool adjustInputs(TempAllocator& alloc, - MInstruction* def) const override; -}; - class StoreDataViewElementPolicy; class StoreTypedArrayHolePolicy; diff --git a/js/src/jit/VMFunctionList-inl.h b/js/src/jit/VMFunctionList-inl.h index a8781b9f57..4c93c0c1a5 100644 --- a/js/src/jit/VMFunctionList-inl.h +++ b/js/src/jit/VMFunctionList-inl.h @@ -6,12 +6,14 @@ #define jit_VMFunctionList_inl_h #include "builtin/Eval.h" +#include "builtin/ModuleObject.h" // js::GetOrCreateModuleMetaObject #include "builtin/Promise.h" // js::AsyncFunctionAwait #include "builtin/RegExp.h" #include "builtin/String.h" #include "jit/BaselineIC.h" #include "jit/IonIC.h" #include "jit/JitRealm.h" +#include "jit/TrialInlining.h" #include "jit/VMFunctions.h" #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" @@ -71,8 +73,10 @@ namespace jit { _(BindVarOperation, js::BindVarOperation) \ _(BoxBoxableValue, js::wasm::BoxBoxableValue) \ _(BoxNonStrictThis, js::BoxNonStrictThis) \ + _(BuiltinObjectOperation, js::BuiltinObjectOperation) \ + _(CallDOMGetter, js::jit::CallDOMGetter) \ + _(CallDOMSetter, js::jit::CallDOMSetter) \ _(CallNativeGetter, js::jit::CallNativeGetter) \ - _(CallNativeGetterByValue, js::jit::CallNativeGetterByValue) \ _(CallNativeSetter, js::jit::CallNativeSetter) \ _(CharCodeAt, js::jit::CharCodeAt) \ _(CheckClassHeritageOperation, js::CheckClassHeritageOperation) \ @@ -80,6 +84,7 @@ namespace jit { js::CheckGlobalOrEvalDeclarationConflicts) \ _(CheckOverRecursed, js::jit::CheckOverRecursed) \ _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline) \ + _(CheckPrivateFieldOperation, js::CheckPrivateFieldOperation) \ _(CloneRegExpObject, js::CloneRegExpObject) \ _(ConcatStrings, js::ConcatStrings) \ _(ConvertElementsToDoubles, js::ObjectElements::ConvertElementsToDoubles) \ @@ -101,7 +106,6 @@ namespace jit { _(DebugLeaveThenRecreateLexicalEnv, \ js::jit::DebugLeaveThenRecreateLexicalEnv) \ _(Debug_CheckSelfHosted, js::Debug_CheckSelfHosted) \ - _(DeepCloneObjectLiteral, js::DeepCloneObjectLiteral) \ _(DefFunOperation, js::DefFunOperation) \ _(DefLexicalOperation, js::DefLexicalOperation) \ _(DefVarOperation, js::DefVarOperation) \ @@ -114,13 +118,14 @@ namespace jit { _(DoCallFallback, js::jit::DoCallFallback) \ _(DoConcatStringObject, js::jit::DoConcatStringObject) \ _(DoSpreadCallFallback, js::jit::DoSpreadCallFallback) \ + _(DoStringToInt64, js::jit::DoStringToInt64) \ + _(DoTrialInlining, js::jit::DoTrialInlining) \ _(DoTypeUpdateFallback, js::jit::DoTypeUpdateFallback) \ _(EnterWith, js::jit::EnterWith) \ _(FinalSuspend, js::jit::FinalSuspend) \ _(FinishBoundFunctionInit, JSFunction::finishBoundFunctionInit) \ _(FreshenLexicalEnv, js::jit::FreshenLexicalEnv) \ _(FunWithProtoOperation, js::FunWithProtoOperation) \ - _(FunctionProtoOperation, js::FunctionProtoOperation) \ _(GeneratorThrowOrReturn, js::jit::GeneratorThrowOrReturn) \ _(GetAndClearException, js::GetAndClearException) \ _(GetElementOperation, js::GetElementOperation) \ @@ -153,6 +158,7 @@ namespace jit { _(InvokeFunction, js::jit::InvokeFunction) \ _(IonBinaryArithICUpdate, js::jit::IonBinaryArithIC::update) \ _(IonBindNameICUpdate, js::jit::IonBindNameIC::update) \ + _(IonCheckPrivateFieldICUpdate, js::jit::IonCheckPrivateFieldIC::update) \ _(IonCompareICUpdate, js::jit::IonCompareIC::update) \ _(IonCompileScriptForBaselineAtEntry, \ js::jit::IonCompileScriptForBaselineAtEntry) \ @@ -166,6 +172,7 @@ namespace jit { _(IonHasOwnICUpdate, js::jit::IonHasOwnIC::update) \ _(IonInICUpdate, js::jit::IonInIC::update) \ _(IonInstanceOfICUpdate, js::jit::IonInstanceOfIC::update) \ + _(IonOptimizeSpreadCallICUpdate, js::jit::IonOptimizeSpreadCallIC::update) \ _(IonRecompile, js::jit::IonRecompile) \ _(IonSetPropertyICUpdate, js::jit::IonSetPropertyIC::update) \ _(IonToPropertyKeyICUpdate, js::jit::IonToPropertyKeyIC::update) \ @@ -233,7 +240,6 @@ namespace jit { _(SetObjectElementWithReceiver, js::SetObjectElementWithReceiver) \ _(SetProperty, js::jit::SetProperty) \ _(SetPropertySuper, js::SetPropertySuper) \ - _(SingletonObjectLiteralOperation, js::SingletonObjectLiteralOperation) \ _(StartDynamicModuleImport, js::StartDynamicModuleImport) \ _(StrictlyEqual, js::jit::StrictlyEqual) \ _(StrictlyNotEqual, js::jit::StrictlyEqual) \ @@ -274,30 +280,34 @@ namespace jit { // The list below is for tail calls. The third argument specifies the number of // non-argument Values the VM wrapper should pop from the stack. This is used // for Baseline ICs. -#define TAIL_CALL_VMFUNCTION_LIST(_) \ - _(DoBinaryArithFallback, js::jit::DoBinaryArithFallback, 2) \ - _(DoBindNameFallback, js::jit::DoBindNameFallback, 0) \ - _(DoCompareFallback, js::jit::DoCompareFallback, 2) \ - _(DoConcatStringObject, js::jit::DoConcatStringObject, 2) \ - _(DoGetElemFallback, js::jit::DoGetElemFallback, 2) \ - _(DoGetElemSuperFallback, js::jit::DoGetElemSuperFallback, 3) \ - _(DoGetIntrinsicFallback, js::jit::DoGetIntrinsicFallback, 0) \ - _(DoGetIteratorFallback, js::jit::DoGetIteratorFallback, 1) \ - _(DoGetNameFallback, js::jit::DoGetNameFallback, 0) \ - _(DoGetPropFallback, js::jit::DoGetPropFallback, 1) \ - _(DoGetPropSuperFallback, js::jit::DoGetPropSuperFallback, 0) \ - _(DoHasOwnFallback, js::jit::DoHasOwnFallback, 2) \ - _(DoInFallback, js::jit::DoInFallback, 2) \ - _(DoInstanceOfFallback, js::jit::DoInstanceOfFallback, 2) \ - _(DoNewArrayFallback, js::jit::DoNewArrayFallback, 0) \ - _(DoNewObjectFallback, js::jit::DoNewObjectFallback, 0) \ - _(DoRestFallback, js::jit::DoRestFallback, 0) \ - _(DoSetElemFallback, js::jit::DoSetElemFallback, 2) \ - _(DoSetPropFallback, js::jit::DoSetPropFallback, 1) \ - _(DoToBoolFallback, js::jit::DoToBoolFallback, 0) \ - _(DoToPropertyKeyFallback, js::jit::DoToPropertyKeyFallback, 0) \ - _(DoTypeMonitorFallback, js::jit::DoTypeMonitorFallback, 0) \ - _(DoTypeOfFallback, js::jit::DoTypeOfFallback, 0) \ +// +// This list is required to be alphabetized. +#define TAIL_CALL_VMFUNCTION_LIST(_) \ + _(DoBinaryArithFallback, js::jit::DoBinaryArithFallback, 2) \ + _(DoBindNameFallback, js::jit::DoBindNameFallback, 0) \ + _(DoCheckPrivateFieldFallback, js::jit::DoCheckPrivateFieldFallback, 2) \ + _(DoCompareFallback, js::jit::DoCompareFallback, 2) \ + _(DoConcatStringObject, js::jit::DoConcatStringObject, 2) \ + _(DoGetElemFallback, js::jit::DoGetElemFallback, 2) \ + _(DoGetElemSuperFallback, js::jit::DoGetElemSuperFallback, 3) \ + _(DoGetIntrinsicFallback, js::jit::DoGetIntrinsicFallback, 0) \ + _(DoGetIteratorFallback, js::jit::DoGetIteratorFallback, 1) \ + _(DoGetNameFallback, js::jit::DoGetNameFallback, 0) \ + _(DoGetPropFallback, js::jit::DoGetPropFallback, 1) \ + _(DoGetPropSuperFallback, js::jit::DoGetPropSuperFallback, 0) \ + _(DoHasOwnFallback, js::jit::DoHasOwnFallback, 2) \ + _(DoInFallback, js::jit::DoInFallback, 2) \ + _(DoInstanceOfFallback, js::jit::DoInstanceOfFallback, 2) \ + _(DoNewArrayFallback, js::jit::DoNewArrayFallback, 0) \ + _(DoNewObjectFallback, js::jit::DoNewObjectFallback, 0) \ + _(DoOptimizeSpreadCallFallback, js::jit::DoOptimizeSpreadCallFallback, 0) \ + _(DoRestFallback, js::jit::DoRestFallback, 0) \ + _(DoSetElemFallback, js::jit::DoSetElemFallback, 2) \ + _(DoSetPropFallback, js::jit::DoSetPropFallback, 1) \ + _(DoToBoolFallback, js::jit::DoToBoolFallback, 0) \ + _(DoToPropertyKeyFallback, js::jit::DoToPropertyKeyFallback, 0) \ + _(DoTypeMonitorFallback, js::jit::DoTypeMonitorFallback, 0) \ + _(DoTypeOfFallback, js::jit::DoTypeOfFallback, 0) \ _(DoUnaryArithFallback, js::jit::DoUnaryArithFallback, 1) #define DEF_ID(name, ...) name, diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 2cd08057aa..737f9ccfbe 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -10,11 +10,14 @@ #include "builtin/TypedObject.h" #include "frontend/BytecodeCompiler.h" #include "jit/arm/Simulator-arm.h" +#include "jit/AtomicOperations.h" #include "jit/BaselineIC.h" #include "jit/JitFrames.h" #include "jit/JitRealm.h" #include "jit/mips32/Simulator-mips32.h" #include "jit/mips64/Simulator-mips64.h" +#include "js/friend/StackLimits.h" // js::CheckRecursionLimitWithExtra +#include "js/friend/WindowProxy.h" // js::IsWindow #include "vm/ArrayObject.h" #include "vm/EqualityOperations.h" // js::StrictlyEqual #include "vm/Interpreter.h" @@ -570,6 +573,18 @@ JSLinearString* StringFromCharCode(JSContext* cx, int32_t code) { return NewStringCopyNDontDeflate(cx, &c, 1); } +JSLinearString* StringFromCharCodeNoGC(JSContext* cx, int32_t code) { + AutoUnsafeCallWithABI unsafe; + + char16_t c = char16_t(code); + + if (StaticStrings::hasUnit(c)) { + return cx->staticStrings().getUnit(c); + } + + return NewStringCopyNDontDeflate(cx, &c, 1); +} + JSString* StringFromCodePoint(JSContext* cx, int32_t codePoint) { RootedValue rval(cx, Int32Value(codePoint)); if (!str_fromCodePoint_one_arg(cx, rval, &rval)) { @@ -649,7 +664,7 @@ bool OperatorIn(JSContext* cx, HandleValue key, HandleObject obj, bool* out) { return ToPropertyKey(cx, key, &id) && HasProperty(cx, obj, id, out); } -bool OperatorInI(JSContext* cx, uint32_t index, HandleObject obj, bool* out) { +bool OperatorInI(JSContext* cx, int32_t index, HandleObject obj, bool* out) { RootedValue key(cx, Int32Value(index)); return OperatorIn(cx, key, obj, out); } @@ -1462,8 +1477,8 @@ bool BaselineGetFunctionThis(JSContext* cx, BaselineFrame* frame, return GetFunctionThis(cx, frame, res); } -bool CallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj, - MutableHandleValue result) { +bool CallNativeGetter(JSContext* cx, HandleFunction callee, + HandleValue receiver, MutableHandleValue result) { AutoRealm ar(cx, callee); MOZ_ASSERT(callee->isNative()); @@ -1471,7 +1486,7 @@ bool CallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj, JS::RootedValueArray<2> vp(cx); vp[0].setObject(*callee.get()); - vp[1].setObject(*obj.get()); + vp[1].set(receiver); if (!natfun(cx, 0, vp.begin())) { return false; @@ -1481,23 +1496,22 @@ bool CallNativeGetter(JSContext* cx, HandleFunction callee, HandleObject obj, return true; } -bool CallNativeGetterByValue(JSContext* cx, HandleFunction callee, - HandleValue receiver, MutableHandleValue result) { - AutoRealm ar(cx, callee); - - MOZ_ASSERT(callee->isNative()); - JSNative natfun = callee->native(); - - JS::RootedValueArray<2> vp(cx); - vp[0].setObject(*callee.get()); - vp[1].set(receiver); +bool CallDOMGetter(JSContext* cx, const JSJitInfo* info, HandleObject obj, + MutableHandleValue result) { + MOZ_ASSERT(info->type() == JSJitInfo::Getter); + MOZ_ASSERT(obj->isNative()); + MOZ_ASSERT(obj->getClass()->isDOMClass()); - if (!natfun(cx, 0, vp.begin())) { - return false; - } +#ifdef DEBUG + DOMInstanceClassHasProtoAtDepth instanceChecker = + cx->runtime()->DOMcallbacks->instanceClassMatchesProto; + MOZ_ASSERT(instanceChecker(obj->getClass(), info->protoID, info->depth)); +#endif - result.set(vp[0]); - return true; + // Loading DOM_OBJECT_SLOT, which must be the first slot. + JS::Value val = JS::GetReservedSlot(obj, 0); + JSJitGetterOp getter = info->getter; + return getter(cx, obj, val.toPrivate(), JSJitGetterCallArgs(result)); } bool CallNativeSetter(JSContext* cx, HandleFunction callee, HandleObject obj, @@ -1515,6 +1529,26 @@ bool CallNativeSetter(JSContext* cx, HandleFunction callee, HandleObject obj, return natfun(cx, 1, vp.begin()); } +bool CallDOMSetter(JSContext* cx, const JSJitInfo* info, HandleObject obj, + HandleValue value) { + MOZ_ASSERT(info->type() == JSJitInfo::Setter); + MOZ_ASSERT(obj->isNative()); + MOZ_ASSERT(obj->getClass()->isDOMClass()); + +#ifdef DEBUG + DOMInstanceClassHasProtoAtDepth instanceChecker = + cx->runtime()->DOMcallbacks->instanceClassMatchesProto; + MOZ_ASSERT(instanceChecker(obj->getClass(), info->protoID, info->depth)); +#endif + + // Loading DOM_OBJECT_SLOT, which must be the first slot. + JS::Value val = JS::GetReservedSlot(obj, 0); + JSJitSetterOp setter = info->setter; + + RootedValue v(cx, value); + return setter(cx, obj, val.toPrivate(), JSJitSetterCallArgs(&v)); +} + bool EqualStringsHelperPure(JSString* str1, JSString* str2) { // IC code calls this directly so we shouldn't GC. AutoUnsafeCallWithABI unsafe; @@ -2013,6 +2047,20 @@ BigInt* CreateBigIntFromUint64(JSContext* cx, uint64_t i64) { } #endif +bool DoStringToInt64(JSContext* cx, HandleString str, uint64_t* res) { + BigInt* bi; + JS_TRY_VAR_OR_RETURN_FALSE(cx, bi, js::StringToBigInt(cx, str)); + + if (!bi) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_BIGINT_INVALID_SYNTAX); + return false; + } + + *res = js::BigInt::toUint64(bi); + return true; +} + template bool BigIntEqual(BigInt* x, BigInt* y) { AutoUnsafeCallWithABI unsafe; @@ -2145,5 +2193,224 @@ template bool StringBigIntCompare(JSContext* cx, template bool StringBigIntCompare( JSContext* cx, HandleString x, HandleBigInt y, bool* res); +template +static int32_t AtomicsCompareExchange(TypedArrayObject* typedArray, + int32_t index, int32_t expected, + int32_t replacement) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::compareExchangeSeqCst(addr + index, T(expected), + T(replacement)); +} + +AtomicsCompareExchangeFn AtomicsCompareExchange(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsCompareExchange; + case Scalar::Uint8: + return AtomicsCompareExchange; + case Scalar::Int16: + return AtomicsCompareExchange; + case Scalar::Uint16: + return AtomicsCompareExchange; + case Scalar::Int32: + return AtomicsCompareExchange; + case Scalar::Uint32: + return AtomicsCompareExchange; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsExchange(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::exchangeSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsExchange(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsExchange; + case Scalar::Uint8: + return AtomicsExchange; + case Scalar::Int16: + return AtomicsExchange; + case Scalar::Uint16: + return AtomicsExchange; + case Scalar::Int32: + return AtomicsExchange; + case Scalar::Uint32: + return AtomicsExchange; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsAdd(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::fetchAddSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsAdd(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsAdd; + case Scalar::Uint8: + return AtomicsAdd; + case Scalar::Int16: + return AtomicsAdd; + case Scalar::Uint16: + return AtomicsAdd; + case Scalar::Int32: + return AtomicsAdd; + case Scalar::Uint32: + return AtomicsAdd; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsSub(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::fetchSubSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsSub(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsSub; + case Scalar::Uint8: + return AtomicsSub; + case Scalar::Int16: + return AtomicsSub; + case Scalar::Uint16: + return AtomicsSub; + case Scalar::Int32: + return AtomicsSub; + case Scalar::Uint32: + return AtomicsSub; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsAnd(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::fetchAndSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsAnd(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsAnd; + case Scalar::Uint8: + return AtomicsAnd; + case Scalar::Int16: + return AtomicsAnd; + case Scalar::Uint16: + return AtomicsAnd; + case Scalar::Int32: + return AtomicsAnd; + case Scalar::Uint32: + return AtomicsAnd; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsOr(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::fetchOrSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsOr(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsOr; + case Scalar::Uint8: + return AtomicsOr; + case Scalar::Int16: + return AtomicsOr; + case Scalar::Uint16: + return AtomicsOr; + case Scalar::Int32: + return AtomicsOr; + case Scalar::Uint32: + return AtomicsOr; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + +template +static int32_t AtomicsXor(TypedArrayObject* typedArray, int32_t index, + int32_t value) { + AutoUnsafeCallWithABI unsafe; + + MOZ_ASSERT(!typedArray->hasDetachedBuffer()); + MOZ_ASSERT(index >= 0 && uint32_t(index) < typedArray->length()); + + SharedMem addr = typedArray->dataPointerEither().cast(); + return jit::AtomicOperations::fetchXorSeqCst(addr + index, T(value)); +} + +AtomicsReadWriteModifyFn AtomicsXor(Scalar::Type elementType) { + switch (elementType) { + case Scalar::Int8: + return AtomicsXor; + case Scalar::Uint8: + return AtomicsXor; + case Scalar::Int16: + return AtomicsXor; + case Scalar::Uint16: + return AtomicsXor; + case Scalar::Int32: + return AtomicsXor; + case Scalar::Uint32: + return AtomicsXor; + default: + MOZ_CRASH("Unexpected TypedArray type"); + } +} + } // namespace jit } // namespace js diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 76c1a6c007..b72695f99b 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -13,6 +13,7 @@ #include "jit/CompileInfo.h" #include "jit/IonScript.h" #include "jit/JitFrames.h" +#include "js/ScalarType.h" #include "vm/Interpreter.h" namespace js { @@ -900,6 +901,7 @@ MOZ_MUST_USE bool SetArrayLength(JSContext* cx, HandleObject obj, MOZ_MUST_USE bool CharCodeAt(JSContext* cx, HandleString str, int32_t index, uint32_t* code); JSLinearString* StringFromCharCode(JSContext* cx, int32_t code); +JSLinearString* StringFromCharCodeNoGC(JSContext* cx, int32_t code); JSString* StringFromCodePoint(JSContext* cx, int32_t codePoint); MOZ_MUST_USE bool SetProperty(JSContext* cx, HandleObject obj, @@ -913,7 +915,7 @@ JSObject* NewCallObject(JSContext* cx, HandleShape shape, JSObject* NewStringObject(JSContext* cx, HandleString str); bool OperatorIn(JSContext* cx, HandleValue key, HandleObject obj, bool* out); -bool OperatorInI(JSContext* cx, uint32_t index, HandleObject obj, bool* out); +bool OperatorInI(JSContext* cx, int32_t index, HandleObject obj, bool* out); MOZ_MUST_USE bool GetIntrinsicValue(JSContext* cx, HandlePropertyName name, MutableHandleValue rval); @@ -1071,11 +1073,14 @@ MOZ_MUST_USE bool BaselineGetFunctionThis(JSContext* cx, BaselineFrame* frame, MutableHandleValue res); MOZ_MUST_USE bool CallNativeGetter(JSContext* cx, HandleFunction callee, - HandleObject obj, MutableHandleValue result); + HandleValue receiver, + MutableHandleValue result); -MOZ_MUST_USE bool CallNativeGetterByValue(JSContext* cx, HandleFunction callee, - HandleValue receiver, - MutableHandleValue result); +bool CallDOMGetter(JSContext* cx, const JSJitInfo* jitInfo, HandleObject obj, + MutableHandleValue result); + +bool CallDOMSetter(JSContext* cx, const JSJitInfo* jitInfo, HandleObject obj, + HandleValue value); MOZ_MUST_USE bool CallNativeSetter(JSContext* cx, HandleFunction callee, HandleObject obj, HandleValue rhs); @@ -1122,6 +1127,7 @@ MOZ_MUST_USE bool TrySkipAwait(JSContext* cx, HandleValue val, bool IsPossiblyWrappedTypedArray(JSContext* cx, JSObject* obj, bool* result); void* AllocateBigIntNoGC(JSContext* cx, bool requestMinorGC); +bool DoStringToInt64(JSContext* cx, HandleString str, uint64_t* res); #if JS_BITS_PER_WORD == 32 BigInt* CreateBigIntFromInt64(JSContext* cx, uint32_t low, uint32_t high); @@ -1158,6 +1164,20 @@ template bool StringBigIntCompare(JSContext* cx, HandleString x, HandleBigInt y, bool* res); +using AtomicsCompareExchangeFn = int32_t (*)(TypedArrayObject*, int32_t, + int32_t, int32_t); + +using AtomicsReadWriteModifyFn = int32_t (*)(TypedArrayObject*, int32_t, + int32_t); + +AtomicsCompareExchangeFn AtomicsCompareExchange(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsExchange(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsAdd(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsSub(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsAnd(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsOr(Scalar::Type elementType); +AtomicsReadWriteModifyFn AtomicsXor(Scalar::Type elementType); + enum class TailCallVMFunctionId; enum class VMFunctionId; diff --git a/js/src/jit/WarpBuilder.cpp b/js/src/jit/WarpBuilder.cpp index 3b16bf6db1..fca2054e89 100644 --- a/js/src/jit/WarpBuilder.cpp +++ b/js/src/jit/WarpBuilder.cpp @@ -21,15 +21,34 @@ using namespace js; using namespace js::jit; -WarpBuilder::WarpBuilder(WarpSnapshot& snapshot, MIRGenerator& mirGen) - : WarpBuilderShared(mirGen, nullptr), - snapshot_(snapshot), +// Used for building the outermost script. +WarpBuilder::WarpBuilder(WarpSnapshot& snapshot, MIRGenerator& mirGen, + WarpCompilation* warpCompilation) + : WarpBuilderShared(snapshot, mirGen, nullptr), + warpCompilation_(warpCompilation), graph_(mirGen.graph()), info_(mirGen.outerInfo()), - script_(snapshot.script()->script()), - loopStack_(mirGen.alloc()), - iterators_(mirGen.alloc()) { - opSnapshotIter_ = snapshot.script()->opSnapshots().getFirst(); + scriptSnapshot_(snapshot.rootScript()), + script_(snapshot.rootScript()->script()), + loopStack_(mirGen.alloc()) { + opSnapshotIter_ = scriptSnapshot_->opSnapshots().getFirst(); +} + +// Used for building inlined scripts. +WarpBuilder::WarpBuilder(WarpBuilder* caller, WarpScriptSnapshot* snapshot, + CompileInfo& compileInfo, CallInfo* inlineCallInfo, + MResumePoint* callerResumePoint) + : WarpBuilderShared(caller->snapshot(), caller->mirGen(), nullptr), + warpCompilation_(caller->warpCompilation()), + graph_(caller->mirGen().graph()), + info_(compileInfo), + scriptSnapshot_(snapshot), + script_(snapshot->script()), + loopStack_(caller->mirGen().alloc()), + callerBuilder_(caller), + callerResumePoint_(callerResumePoint), + inlineCallInfo_(inlineCallInfo) { + opSnapshotIter_ = snapshot->opSnapshots().getFirst(); } BytecodeSite* WarpBuilder::newBytecodeSite(BytecodeLocation loc) { @@ -38,7 +57,8 @@ BytecodeSite* WarpBuilder::newBytecodeSite(BytecodeLocation loc) { return new (alloc()) BytecodeSite(info().inlineScriptTree(), pc); } -const WarpOpSnapshot* WarpBuilder::getOpSnapshotImpl(BytecodeLocation loc) { +const WarpOpSnapshot* WarpBuilder::getOpSnapshotImpl( + BytecodeLocation loc, WarpOpSnapshot::Kind kind) { uint32_t offset = loc.bytecodeToOffset(script_); // Skip snapshots until we get to a snapshot with offset >= offset. This is @@ -47,7 +67,8 @@ const WarpOpSnapshot* WarpBuilder::getOpSnapshotImpl(BytecodeLocation loc) { opSnapshotIter_ = opSnapshotIter_->getNext(); } - if (!opSnapshotIter_ || opSnapshotIter_->offset() != offset) { + if (!opSnapshotIter_ || opSnapshotIter_->offset() != offset || + opSnapshotIter_->kind() != kind) { return nullptr; } @@ -57,8 +78,7 @@ const WarpOpSnapshot* WarpBuilder::getOpSnapshotImpl(BytecodeLocation loc) { void WarpBuilder::initBlock(MBasicBlock* block) { graph().addBlock(block); - // TODO: set block hit count (for branch pruning pass) - block->setLoopDepth(loopDepth_); + block->setLoopDepth(loopDepth()); current = block; } @@ -275,17 +295,27 @@ bool WarpBuilder::build() { return false; } - if (!buildEpilogue()) { + if (!MPhi::markIteratorPhis(*iterators())) { return false; } - if (!MPhi::markIteratorPhis(iterators_)) { + MOZ_ASSERT_IF(info().osrPc(), graph().osrBlock()); + MOZ_ASSERT(loopStack_.empty()); + MOZ_ASSERT(loopDepth() == 0); + + return true; +} + +bool WarpBuilder::buildInline() { + if (!buildInlinePrologue()) { return false; } - MOZ_ASSERT(loopStack_.empty()); - MOZ_ASSERT(loopDepth_ == 0); + if (!buildBody()) { + return false; + } + MOZ_ASSERT(loopStack_.empty()); return true; } @@ -361,7 +391,7 @@ MInstruction* WarpBuilder::buildCallObject(MDefinition* callee, } bool WarpBuilder::buildEnvironmentChain() { - const WarpEnvironment& env = snapshot_.script()->environment(); + const WarpEnvironment& env = scriptSnapshot()->environment(); if (env.is()) { return true; @@ -395,7 +425,7 @@ bool WarpBuilder::buildEnvironmentChain() { // Update the environment slot from UndefinedValue only after the initial // environment is created so that bailout doesn't see a partial environment. - // See: |InitFromBailout| + // See: |BaselineStackBuilder::buildBaselineFrame| current->setEnvironmentChain(envDef); return true; } @@ -451,6 +481,73 @@ bool WarpBuilder::buildPrologue() { return true; } +bool WarpBuilder::buildInlinePrologue() { + // Generate entry block. + BytecodeLocation startLoc(script_, script_->code()); + if (!startNewEntryBlock(info().firstStackSlot(), startLoc)) { + return false; + } + current->setCallerResumePoint(callerResumePoint()); + + // Connect the entry block to the last block in the caller's graph. + MBasicBlock* pred = callerBuilder()->current; + MOZ_ASSERT(pred == callerResumePoint()->block()); + + pred->end(MGoto::New(alloc(), current)); + if (!current->addPredecessorWithoutPhis(pred)) { + return false; + } + + MConstant* undef = constant(UndefinedValue()); + + // Initialize env chain slot to Undefined. It's set later by + // |buildEnvironmentChain|. + current->initSlot(info().environmentChainSlot(), undef); + + // Initialize |return value| slot. + current->initSlot(info().returnValueSlot(), undef); + + // Initialize |arguments| slot if needed. + if (info().hasArguments()) { + current->initSlot(info().argsObjSlot(), undef); + } + + // Initialize |this| slot. + current->initSlot(info().thisSlot(), inlineCallInfo()->thisArg()); + + // We do not inline functions which need the arguments object. + // This means we can use `argSlot` below instead of `argSlotUnchecked`. + MOZ_ASSERT(!info().needsArgsObj()); + + uint32_t callerArgs = inlineCallInfo()->argc(); + uint32_t actualArgs = info().nargs(); + uint32_t passedArgs = std::min(callerArgs, actualArgs); + + // Initialize actually set arguments. + for (uint32_t i = 0; i < passedArgs; i++) { + MDefinition* arg = inlineCallInfo()->getArg(i); + current->initSlot(info().argSlot(i), arg); + } + + // Pass undefined for missing arguments. + for (uint32_t i = passedArgs; i < actualArgs; i++) { + current->initSlot(info().argSlot(i), undef); + } + + // Initialize local slots. + for (uint32_t i = 0; i < info().nlocals(); i++) { + current->initSlot(info().localSlot(i), undef); + } + + MOZ_ASSERT(current->entryResumePoint()->stackDepth() == info().totalSlots()); + + if (!buildEnvironmentChain()) { + return false; + } + + return true; +} + #ifdef DEBUG // In debug builds, after compiling a bytecode op, this class is used to check // that all values popped by this opcode either: @@ -547,8 +644,7 @@ bool WarpBuilder::buildBody() { if (loc.isBackedge() && !loopStack_.empty()) { BytecodeLocation loopHead(script_, loopStack_.back().header()->pc()); if (loc.isBackedgeForLoophead(loopHead)) { - MOZ_ASSERT(loopDepth_ > 0); - loopDepth_--; + decLoopDepth(); loopStack_.popBack(); } } @@ -594,8 +690,6 @@ bool WarpBuilder::buildBody() { WARP_UNSUPPORTED_OPCODE_LIST(DEF_OP) #undef DEF_OP -bool WarpBuilder::buildEpilogue() { return true; } - bool WarpBuilder::build_Nop(BytecodeLocation) { return true; } bool WarpBuilder::build_NopDestructuring(BytecodeLocation) { return true; } @@ -655,7 +749,6 @@ bool WarpBuilder::build_True(BytecodeLocation) { bool WarpBuilder::build_Pop(BytecodeLocation) { current->pop(); - // TODO: IonBuilder inserts a resume point in loops, re-evaluate this. return true; } @@ -779,6 +872,10 @@ bool WarpBuilder::build_Return(BytecodeLocation) { MReturn* ret = MReturn::New(alloc(), def); current->end(ret); + if (!graph().addReturn(current)) { + return false; + } + setTerminatedBlock(); return true; } @@ -794,6 +891,10 @@ bool WarpBuilder::build_RetRval(BytecodeLocation) { MReturn* ret = MReturn::New(alloc(), rval); current->end(ret); + if (!graph().addReturn(current)) { + return false; + } + setTerminatedBlock(); return true; } @@ -864,9 +965,6 @@ bool WarpBuilder::build_SetArg(BytecodeLocation loc) { "arguments aliases formals when an arguments binding is present " "and the arguments object is mapped"); - // TODO: double check corresponding IonBuilder code when supporting the - // arguments analysis in WarpBuilder. - MOZ_ASSERT(info().needsArgsObj(), "unexpected JSOp::SetArg with lazy arguments"); @@ -887,12 +985,6 @@ bool WarpBuilder::build_ToNumeric(BytecodeLocation loc) { return buildUnaryOp(loc); } -bool WarpBuilder::build_Pos(BytecodeLocation loc) { - // TODO: MUnaryCache is the most basic implementation. Optimize it for known - // numbers at least. - return buildUnaryOp(loc); -} - bool WarpBuilder::buildUnaryOp(BytecodeLocation loc) { MDefinition* value = current->pop(); return buildIC(loc, CacheKind::UnaryArith, {value}); @@ -902,6 +994,8 @@ bool WarpBuilder::build_Inc(BytecodeLocation loc) { return buildUnaryOp(loc); } bool WarpBuilder::build_Dec(BytecodeLocation loc) { return buildUnaryOp(loc); } +bool WarpBuilder::build_Pos(BytecodeLocation loc) { return buildUnaryOp(loc); } + bool WarpBuilder::build_Neg(BytecodeLocation loc) { return buildUnaryOp(loc); } bool WarpBuilder::build_BitNot(BytecodeLocation loc) { @@ -1031,9 +1125,9 @@ bool WarpBuilder::build_JumpTarget(BytecodeLocation loc) { // \ | // joinBlock // - // TODO: re-evaluate this. It would probably be better to fix FoldTests to - // support the triangle pattern so that we can remove this. IonBuilder had - // other concerns that don't apply to WarpBuilder. + // TODO(post-Warp): re-evaluate this. It would probably be better to fix + // FoldTests to support the triangle pattern so that we can remove this. + // IonBuilder had other concerns that don't apply to WarpBuilder. auto createEmptyBlockForTest = [&](MBasicBlock* pred, size_t successor, size_t numToPop) -> MBasicBlock* { MOZ_ASSERT(joinBlock); @@ -1105,13 +1199,6 @@ bool WarpBuilder::build_JumpTarget(BytecodeLocation loc) { } lastIns->toGoto()->initSuccessor(0, joinBlock); continue; - - case PendingEdge::Kind::GotoWithFake: - if (!addEdge(source, /* numToPop = */ 0)) { - return false; - } - lastIns->toGotoWithFake()->initSuccessor(1, joinBlock); - continue; } MOZ_CRASH("Invalid kind"); } @@ -1161,13 +1248,13 @@ bool WarpBuilder::addIteratorLoopPhis(BytecodeLocation loopHead) { switch (tn.kind()) { case TryNoteKind::Destructuring: case TryNoteKind::ForIn: { - // For for-in loops we add the iterator object to iterators_. For + // For for-in loops we add the iterator object to iterators(). For // destructuring loops we add the "done" value that's on top of the // stack and used in the exception handler. MOZ_ASSERT(tn.stackDepth >= 1); uint32_t slot = info().stackSlot(tn.stackDepth - 1); MPhi* phi = current->getSlot(slot)->toPhi(); - if (!iterators_.append(phi)) { + if (!iterators()->append(phi)) { return false; } break; @@ -1204,7 +1291,7 @@ bool WarpBuilder::build_LoopHead(BytecodeLocation loc) { } } - loopDepth_++; + incLoopDepth(); MBasicBlock* pred = current; if (!startNewLoopHeaderBlock(loc)) { @@ -1220,8 +1307,6 @@ bool WarpBuilder::build_LoopHead(BytecodeLocation loc) { MInterruptCheck* check = MInterruptCheck::New(alloc()); current->add(check); - // TODO: recompile check - return true; } @@ -1270,7 +1355,7 @@ bool WarpBuilder::buildTestOp(BytecodeLocation loc) { bool WarpBuilder::buildTestBackedge(BytecodeLocation loc) { JSOp op = loc.getOp(); MOZ_ASSERT(op == JSOp::IfNe); - MOZ_ASSERT(loopDepth_ > 0); + MOZ_ASSERT(loopDepth() > 0); MDefinition* value = current->pop(); @@ -1339,8 +1424,7 @@ bool WarpBuilder::build_Coalesce(BytecodeLocation loc) { } bool WarpBuilder::buildBackedge() { - MOZ_ASSERT(loopDepth_ > 0); - loopDepth_--; + decLoopDepth(); MBasicBlock* header = loopStack_.popCopy().header(); current->end(MGoto::New(alloc(), header)); @@ -1405,6 +1489,16 @@ bool WarpBuilder::build_Not(BytecodeLocation loc) { bool WarpBuilder::build_ToString(BytecodeLocation loc) { MDefinition* value = current->pop(); + + // TODO: Consider making MToString non-effectul similar to Ion. That way GVN + // will be able to fold away MToString(string) automatically. For now simply + // handle this case here. + if (value->type() == MIRType::String) { + value->setImplicitlyUsedUnchecked(); + current->push(value); + return true; + } + MToString* ins = MToString::New(alloc(), value, MToString::SideEffectHandling::Supported); current->add(ins); @@ -1479,7 +1573,10 @@ bool WarpBuilder::build_MutateProto(BytecodeLocation loc) { } MDefinition* WarpBuilder::getCallee() { - // TODO: handle inlined callees when we implement inlining. + if (inlineCallInfo()) { + return inlineCallInfo()->callee(); + } + MInstruction* callee = MCallee::New(alloc()); current->add(callee); return callee; @@ -1523,9 +1620,8 @@ bool WarpBuilder::build_ToPropertyKey(BytecodeLocation loc) { } bool WarpBuilder::build_Typeof(BytecodeLocation) { - // TODO: remove MTypeOf::inputType_ and unbox in foldsTo instead. MDefinition* input = current->pop(); - MTypeOf* ins = MTypeOf::New(alloc(), input, MIRType::Value); + MTypeOf* ins = MTypeOf::New(alloc(), input); current->add(ins); current->push(ins); return true; @@ -1634,8 +1730,8 @@ bool WarpBuilder::build_Iter(BytecodeLocation loc) { } bool WarpBuilder::build_IterNext(BytecodeLocation) { - // TODO: IterNext was added as hint to prevent IonBuilder/TI loop restarts. - // Once IonBuilder is gone this op should probably just be removed. + // TODO(post-Warp): IterNext was added as hint to prevent IonBuilder/TI loop + // restarts. Once IonBuilder is gone this op should probably just be removed. MDefinition* def = current->pop(); MInstruction* unbox = MUnbox::New(alloc(), def, MIRType::String, MUnbox::Infallible); @@ -1681,12 +1777,18 @@ bool WarpBuilder::buildCallOp(BytecodeLocation loc) { return false; } - // TODO: Consider using buildIC for this as well. - if (auto* snapshot = getOpSnapshot(loc)) { - return TranspileCacheIRToMIR(mirGen(), loc, current, snapshot, callInfo); + if (const auto* inliningSnapshot = getOpSnapshot(loc)) { + return buildInlinedCall(loc, inliningSnapshot, callInfo); } - // TODO: consider adding a Call IC like Baseline has. + if (auto* cacheIRSnapshot = getOpSnapshot(loc)) { + return TranspileCacheIRToMIR(this, loc, cacheIRSnapshot, callInfo); + } + + if (getOpSnapshot(loc)) { + callInfo.setImplicitlyUsedUnchecked(); + return buildBailoutForColdIC(loc, CacheKind::Call); + } bool needsThisCheck = false; if (callInfo.constructing()) { @@ -1700,6 +1802,11 @@ bool WarpBuilder::buildCallOp(BytecodeLocation loc) { needsThisCheck = true; } + if (op == JSOp::FunApply && argc == 2) { + MDefinition* arg = maybeGuardNotOptimizedArguments(callInfo.getArg(1)); + callInfo.setArg(1, arg); + } + MCall* call = makeCall(callInfo, needsThisCheck); if (!call) { return false; @@ -1746,25 +1853,26 @@ bool WarpBuilder::build_FunctionThis(BytecodeLocation loc) { MOZ_ASSERT(!script_->hasNonSyntacticScope(), "WarpOracle should have aborted compilation"); - // TODO: Add fast path to MBoxNonStrictThis for null/undefined => globalThis. MDefinition* def = current->getSlot(info().thisSlot()); - MBoxNonStrictThis* thisObj = MBoxNonStrictThis::New(alloc(), def); + JSObject* globalThis = snapshot().globalLexicalEnvThis(); + + auto* thisObj = MBoxNonStrictThis::New(alloc(), def, globalThis); current->add(thisObj); current->push(thisObj); - return resumeAfter(thisObj, loc); + return true; } bool WarpBuilder::build_GlobalThis(BytecodeLocation loc) { MOZ_ASSERT(!script_->hasNonSyntacticScope(), "WarpOracle should have aborted compilation"); - JSObject* obj = snapshot_.globalLexicalEnvThis(); + JSObject* obj = snapshot().globalLexicalEnvThis(); pushConstant(ObjectValue(*obj)); return true; } MConstant* WarpBuilder::globalLexicalEnvConstant() { - JSObject* globalLexical = snapshot_.globalLexicalEnv(); + JSObject* globalLexical = snapshot().globalLexicalEnv(); return constant(ObjectValue(*globalLexical)); } @@ -1805,6 +1913,13 @@ bool WarpBuilder::build_BindName(BytecodeLocation loc) { } bool WarpBuilder::build_BindGName(BytecodeLocation loc) { + if (const auto* snapshot = getOpSnapshot(loc)) { + MOZ_ASSERT(!script_->hasNonSyntacticScope()); + JSObject* globalEnv = snapshot->globalEnv(); + pushConstant(ObjectValue(*globalEnv)); + return true; + } + if (script_->hasNonSyntacticScope()) { return build_BindName(loc); } @@ -2021,13 +2136,15 @@ void WarpBuilder::buildCheckLexicalOp(BytecodeLocation loc) { JSOp op = loc.getOp(); MOZ_ASSERT(op == JSOp::CheckLexical || op == JSOp::CheckAliasedLexical); - // TODO: IonBuilder has code to mark not-movable if lexical checks failed - // before. We likely need a mechanism to prevent LICM/bailout loops. MDefinition* input = current->pop(); MInstruction* lexicalCheck = MLexicalCheck::New(alloc(), input); current->add(lexicalCheck); current->push(lexicalCheck); + if (snapshot().bailoutInfo().failedLexicalCheck()) { + lexicalCheck->setNotMovable(); + } + if (op == JSOp::CheckLexical) { // Set the local slot so that a subsequent GetLocal without a CheckLexical // (the frontend can elide lexical checks) doesn't let a definition with @@ -2081,14 +2198,15 @@ bool WarpBuilder::build_SuperFun(BytecodeLocation) { return true; } -bool WarpBuilder::build_FunctionProto(BytecodeLocation loc) { - if (auto* snapshot = getOpSnapshot(loc)) { - JSObject* proto = snapshot->proto(); - pushConstant(ObjectValue(*proto)); +bool WarpBuilder::build_BuiltinObject(BytecodeLocation loc) { + if (auto* snapshot = getOpSnapshot(loc)) { + JSObject* builtin = snapshot->builtin(); + pushConstant(ObjectValue(*builtin)); return true; } - auto* ins = MFunctionProto::New(alloc()); + auto kind = loc.getBuiltinObjectKind(); + auto* ins = MBuiltinObject::New(alloc(), kind); current->add(ins); current->push(ins); return resumeAfter(ins, loc); @@ -2109,7 +2227,7 @@ bool WarpBuilder::build_GetIntrinsic(BytecodeLocation loc) { } bool WarpBuilder::build_ImportMeta(BytecodeLocation loc) { - ModuleObject* moduleObj = snapshot_.script()->moduleObject(); + ModuleObject* moduleObj = scriptSnapshot()->moduleObject(); MOZ_ASSERT(moduleObj); MModuleMetadata* ins = MModuleMetadata::New(alloc(), moduleObj); @@ -2204,15 +2322,6 @@ bool WarpBuilder::build_Object(BytecodeLocation loc) { JSObject* obj = loc.getObject(script_); MConstant* objConst = constant(ObjectValue(*obj)); - if (mirGen().options.cloneSingletons()) { - auto* clone = MCloneLiteral::New(alloc(), objConst); - current->add(clone); - current->push(clone); - return resumeAfter(clone, loc); - } - - // WarpOracle called realm->setSingletonsAsValues() so we can just push the - // object here. current->push(objConst); return true; } @@ -2281,6 +2390,12 @@ bool WarpBuilder::build_HasOwn(BytecodeLocation loc) { return buildIC(loc, CacheKind::HasOwn, {id, obj}); } +bool WarpBuilder::build_CheckPrivateField(BytecodeLocation loc) { + MDefinition* id = current->peek(-1); + MDefinition* obj = current->peek(-2); + return buildIC(loc, CacheKind::CheckPrivateField, {obj, id}); +} + bool WarpBuilder::build_Instanceof(BytecodeLocation loc) { MDefinition* rhs = current->pop(); MDefinition* obj = current->pop(); @@ -2291,7 +2406,7 @@ bool WarpBuilder::build_NewTarget(BytecodeLocation loc) { MOZ_ASSERT(script_->isFunction()); MOZ_ASSERT(info().funMaybeLazy()); - if (snapshot_.script()->isArrowFunction()) { + if (scriptSnapshot()->isArrowFunction()) { MDefinition* callee = getCallee(); MArrowNewTarget* ins = MArrowNewTarget::New(alloc(), callee); current->add(ins); @@ -2299,7 +2414,14 @@ bool WarpBuilder::build_NewTarget(BytecodeLocation loc) { return true; } - // TODO: handle newTarget in inlined functions when we can inline. + if (inlineCallInfo()) { + if (inlineCallInfo()->constructing()) { + current->push(inlineCallInfo()->getNewTarget()); + } else { + pushConstant(UndefinedValue()); + } + return true; + } MNewTarget* ins = MNewTarget::New(alloc()); current->add(ins); @@ -2309,20 +2431,26 @@ bool WarpBuilder::build_NewTarget(BytecodeLocation loc) { bool WarpBuilder::build_CheckIsObj(BytecodeLocation loc) { CheckIsObjectKind kind = loc.getCheckIsObjectKind(); - MDefinition* val = current->pop(); + MDefinition* toCheck = current->peek(-1); + if (toCheck->type() == MIRType::Object) { + toCheck->setImplicitlyUsedUnchecked(); + return true; + } + + MDefinition* val = current->pop(); MCheckIsObj* ins = MCheckIsObj::New(alloc(), val, uint8_t(kind)); current->add(ins); current->push(ins); return true; } -bool WarpBuilder::build_CheckObjCoercible(BytecodeLocation) { +bool WarpBuilder::build_CheckObjCoercible(BytecodeLocation loc) { MDefinition* val = current->pop(); MCheckObjCoercible* ins = MCheckObjCoercible::New(alloc(), val); current->add(ins); current->push(ins); - return true; + return resumeAfter(ins, loc); } MInstruction* WarpBuilder::buildLoadSlot(MDefinition* obj, @@ -2416,11 +2544,16 @@ bool WarpBuilder::build_InitElemArray(BytecodeLocation loc) { auto* elements = MElements::New(alloc(), obj); current->add(elements); - current->add(MPostWriteBarrier::New(alloc(), obj, val)); - - auto* store = MStoreElement::New(alloc(), elements, indexConst, val, - /* needsHoleCheck = */ false); - current->add(store); + if (val->type() == MIRType::MagicHole) { + val->setImplicitlyUsedUnchecked(); + auto* store = MStoreHoleValueElement::New(alloc(), elements, indexConst); + current->add(store); + } else { + current->add(MPostWriteBarrier::New(alloc(), obj, val)); + auto* store = MStoreElement::New(alloc(), elements, indexConst, val, + /* needsHoleCheck = */ false); + current->add(store); + } auto* setLength = MSetInitializedLength::New(alloc(), elements, indexConst); current->add(setLength); @@ -2503,26 +2636,23 @@ bool WarpBuilder::build_FunWithProto(BytecodeLocation loc) { } bool WarpBuilder::build_SpreadCall(BytecodeLocation loc) { - MDefinition* argArr = current->pop(); - MDefinition* argThis = current->pop(); - MDefinition* argFunc = current->pop(); - - // Load dense elements of the argument array. Note that the bytecode ensures - // this is an array. - MElements* elements = MElements::New(alloc(), argArr); - current->add(elements); + bool constructing = false; + CallInfo callInfo(alloc(), loc.toRawBytecode(), constructing, + loc.resultIsPopped()); + callInfo.initForSpreadCall(current); - WrappedFunction* wrappedTarget = nullptr; - auto* apply = - MApplyArray::New(alloc(), wrappedTarget, argFunc, elements, argThis); - current->add(apply); - current->push(apply); + if (auto* cacheIRSnapshot = getOpSnapshot(loc)) { + return TranspileCacheIRToMIR(this, loc, cacheIRSnapshot, callInfo); + } - if (loc.resultIsPopped()) { - apply->setIgnoresReturnValue(); + MInstruction* call = makeSpreadCall(callInfo); + if (!call) { + return false; } - return resumeAfter(apply, loc); + current->add(call); + current->push(call); + return resumeAfter(call, loc); } bool WarpBuilder::build_SpreadNew(BytecodeLocation loc) { @@ -2554,12 +2684,8 @@ bool WarpBuilder::build_SpreadSuperCall(BytecodeLocation loc) { } bool WarpBuilder::build_OptimizeSpreadCall(BytecodeLocation loc) { - // TODO: like IonBuilder's slow path always deoptimize for now. Consider using - // an IC for this so that we can optimize by inlining Baseline's CacheIR. - MDefinition* arr = current->peek(-1); - arr->setImplicitlyUsedUnchecked(); - pushConstant(BooleanValue(false)); - return true; + MDefinition* value = current->peek(-1); + return buildIC(loc, CacheKind::OptimizeSpreadCall, {value}); } bool WarpBuilder::build_Debugger(BytecodeLocation loc) { @@ -2571,19 +2697,19 @@ bool WarpBuilder::build_Debugger(BytecodeLocation loc) { } bool WarpBuilder::build_InstrumentationActive(BytecodeLocation) { - bool active = snapshot_.script()->instrumentationActive(); + bool active = scriptSnapshot()->instrumentationActive(); pushConstant(BooleanValue(active)); return true; } bool WarpBuilder::build_InstrumentationCallback(BytecodeLocation) { - JSObject* callback = snapshot_.script()->instrumentationCallback(); + JSObject* callback = scriptSnapshot()->instrumentationCallback(); pushConstant(ObjectValue(*callback)); return true; } bool WarpBuilder::build_InstrumentationScriptId(BytecodeLocation) { - int32_t scriptId = snapshot_.script()->instrumentationScriptId(); + int32_t scriptId = scriptSnapshot()->instrumentationScriptId(); pushConstant(Int32Value(scriptId)); return true; } @@ -2645,11 +2771,73 @@ bool WarpBuilder::build_TableSwitch(BytecodeLocation loc) { } bool WarpBuilder::build_Rest(BytecodeLocation loc) { - // TODO: handle inlined functions once we support inlining. - auto* snapshot = getOpSnapshot(loc); ArrayObject* templateObject = snapshot->templateObject(); + if (inlineCallInfo()) { + // If we are inlining, we know the actual arguments. + unsigned numActuals = inlineCallInfo()->argc(); + unsigned numFormals = info().nargs() - 1; + unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0; + + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; + + // Allocate an array of the correct size. + MConstant* templateConst = constant(ObjectValue(*templateObject)); + MNewArray* newArray; + if (numRest > snapshot->maxInlineElements()) { + newArray = MNewArray::NewVM(alloc(), /* constraints = */ nullptr, numRest, + templateConst, heap, loc.toRawBytecode()); + } else { + newArray = MNewArray::New(alloc(), /* constraints = */ nullptr, numRest, + templateConst, heap, loc.toRawBytecode()); + } + current->add(newArray); + current->push(newArray); + + if (numRest == 0) { + // No more updating to do. (Note that in this one case the length from + // the template object is already correct.) + return true; + } + + MElements* elements = MElements::New(alloc(), newArray); + current->add(elements); + + // Unroll the argument copy loop. We don't need to do any bounds or hole + // checking here. + MConstant* index = nullptr; + for (uint32_t i = numFormals; i < numActuals; i++) { + if (!alloc().ensureBallast()) { + return false; + } + + index = MConstant::New(alloc(), Int32Value(i - numFormals)); + current->add(index); + + MDefinition* arg = inlineCallInfo()->argv()[i]; + MStoreElement* store = MStoreElement::New(alloc(), elements, index, arg, + /* needsHoleCheck = */ false); + current->add(store); + current->add(MPostWriteBarrier::New(alloc(), newArray, arg)); + } + + // The array's length is incorrectly 0 now, from the template object created + // by BaselineCompiler::emit_Rest() before the actual argument count was + // known. Set the correct length now that we know that count. + MSetArrayLength* length = MSetArrayLength::New(alloc(), elements, index); + current->add(length); + + // Update the initialized length for all the (necessarily non-hole) + // elements added. + MSetInitializedLength* initLength = + MSetInitializedLength::New(alloc(), elements, index); + current->add(initLength); + + return true; + } + MArgumentsLength* numActuals = MArgumentsLength::New(alloc()); current->add(numActuals); @@ -2667,45 +2855,19 @@ bool WarpBuilder::build_Try(BytecodeLocation loc) { // Note: WarpOracle aborts compilation for try-statements with a 'finally' // block. - // TODO: IonBuilder doesn't support try-catch in inlined functions. This is - // most likely not a hard limitation. Re-evaluate this when we can inline. - - // Get the location of the last instruction in the try block. It's a - // JSOp::Goto to jump over the catch block. - BytecodeLocation endOfTryLoc = loc.getEndOfTryLocation(); - MOZ_ASSERT(endOfTryLoc.is(JSOp::Goto)); - - BytecodeLocation afterTryLoc = endOfTryLoc.getJumpTarget(); - MOZ_ASSERT(afterTryLoc > endOfTryLoc); - - // The Baseline compiler should not attempt to enter the catch block via OSR. - MOZ_ASSERT(info().osrPc() < endOfTryLoc.toRawBytecode() || - info().osrPc() >= afterTryLoc.toRawBytecode()); - graph().setHasTryBlock(); - // If control flow in the try body is terminated (by a return or throw - // statement), the code after the try-statement may still be reachable via the - // catch block (which we don't compile) and OSR can enter it. - // For example: - // - // try { - // throw 3; - // } catch(e) { } - // - // for (var i=0; i<1000; i++) {} // OSR - // - // To handle this, we create two blocks: one for the try block and one - // for the code following the try-catch statement. MGotoWithFake is used to - // link both blocks to the predecessor block. - MBasicBlock* pred = current; if (!startNewBlock(pred, loc.next())) { return false; } - pred->end(MGotoWithFake::New(alloc(), current, nullptr)); - return addPendingEdge(PendingEdge::NewGotoWithFake(pred), afterTryLoc); + pred->end(MGoto::New(alloc(), current)); + return true; +} + +bool WarpBuilder::build_Exception(BytecodeLocation) { + MOZ_CRASH("Unreachable because we skip catch-blocks"); } bool WarpBuilder::build_Throw(BytecodeLocation loc) { @@ -2743,12 +2905,19 @@ bool WarpBuilder::buildIC(BytecodeLocation loc, CacheKind kind, mozilla::DebugOnly numInputs = inputs.size(); MOZ_ASSERT(numInputs == NumInputsForCacheKind(kind)); - if (auto* snapshot = getOpSnapshot(loc)) { + if (auto* cacheIRSnapshot = getOpSnapshot(loc)) { MDefinitionStackVector inputs_; if (!inputs_.append(inputs.begin(), inputs.end())) { return false; } - return TranspileCacheIRToMIR(mirGen(), loc, current, snapshot, inputs_); + return TranspileCacheIRToMIR(this, loc, cacheIRSnapshot, inputs_); + } + + if (getOpSnapshot(loc)) { + for (MDefinition* input : inputs) { + input->setImplicitlyUsedUnchecked(); + } + return buildBailoutForColdIC(loc, kind); } // Work around std::initializer_list not defining operator[]. @@ -2803,6 +2972,14 @@ bool WarpBuilder::buildIC(BytecodeLocation loc, CacheKind kind, current->push(ins); return resumeAfter(ins, loc); } + case CacheKind::CheckPrivateField: { + MOZ_ASSERT(numInputs == 2); + auto* ins = + MCheckPrivateFieldCache::New(alloc(), getInput(0), getInput(1)); + current->add(ins); + current->push(ins); + return resumeAfter(ins, loc); + } case CacheKind::InstanceOf: { MOZ_ASSERT(numInputs == 2); auto* ins = MInstanceOfCache::New(alloc(), getInput(0), getInput(1)); @@ -2835,21 +3012,28 @@ bool WarpBuilder::buildIC(BytecodeLocation loc, CacheKind kind, MOZ_ASSERT(numInputs == 1); PropertyName* name = loc.getPropertyName(script_); MConstant* id = constant(StringValue(name)); + MDefinition* val = getInput(0); + if (info().hasArguments()) { + const JSAtomState& names = mirGen().runtime->names(); + if (name == names.length || name == names.callee) { + val = maybeGuardNotOptimizedArguments(val); + } + } // For now pass monitoredResult = true to get the behavior we want (no // TI-related restrictions apply, similar to the Baseline IC). // See also IonGetPropertyICFlags. bool monitoredResult = true; - auto* ins = - MGetPropertyCache::New(alloc(), getInput(0), id, monitoredResult); + auto* ins = MGetPropertyCache::New(alloc(), val, id, monitoredResult); current->add(ins); current->push(ins); return resumeAfter(ins, loc); } case CacheKind::GetElem: { MOZ_ASSERT(numInputs == 2); + MDefinition* val = maybeGuardNotOptimizedArguments(getInput(0)); bool monitoredResult = true; // See GetProp case above. - auto* ins = MGetPropertyCache::New(alloc(), getInput(0), getInput(1), - monitoredResult); + auto* ins = + MGetPropertyCache::New(alloc(), val, getInput(1), monitoredResult); current->add(ins); current->push(ins); return resumeAfter(ins, loc); @@ -2900,6 +3084,13 @@ bool WarpBuilder::buildIC(BytecodeLocation loc, CacheKind kind, current->push(ins); return resumeAfter(ins, loc); } + case CacheKind::OptimizeSpreadCall: { + MOZ_ASSERT(numInputs == 1); + auto* ins = MOptimizeSpreadCallCache::New(alloc(), getInput(0)); + current->add(ins); + current->push(ins); + return resumeAfter(ins, loc); + } case CacheKind::GetIntrinsic: case CacheKind::ToBool: case CacheKind::TypeOf: @@ -2911,3 +3102,213 @@ bool WarpBuilder::buildIC(BytecodeLocation loc, CacheKind kind, return true; } + +bool WarpBuilder::buildBailoutForColdIC(BytecodeLocation loc, CacheKind kind) { + MOZ_ASSERT(loc.opHasIC()); + + // TODO: ideally we would terminate the block here and set the implicitly-used + // flag for skipped bytecode ops. OSR makes this more tricky though. + MBail* bail = MBail::New(alloc(), BailoutKind::FirstExecution); + current->add(bail); + + MIRType resultType; + switch (kind) { + case CacheKind::UnaryArith: + case CacheKind::BinaryArith: + case CacheKind::GetName: + case CacheKind::GetProp: + case CacheKind::GetElem: + case CacheKind::GetPropSuper: + case CacheKind::GetElemSuper: + case CacheKind::GetIntrinsic: + case CacheKind::Call: + case CacheKind::ToPropertyKey: + resultType = MIRType::Value; + break; + case CacheKind::BindName: + case CacheKind::GetIterator: + case CacheKind::NewObject: + resultType = MIRType::Object; + break; + case CacheKind::TypeOf: + resultType = MIRType::String; + break; + case CacheKind::ToBool: + case CacheKind::Compare: + case CacheKind::In: + case CacheKind::HasOwn: + case CacheKind::CheckPrivateField: + case CacheKind::InstanceOf: + case CacheKind::OptimizeSpreadCall: + resultType = MIRType::Boolean; + break; + case CacheKind::SetProp: + case CacheKind::SetElem: + return true; // No result. + } + + auto* ins = MUnreachableResult::New(alloc(), resultType); + current->add(ins); + current->push(ins); + + return true; +} + +MDefinition* WarpBuilder::maybeGuardNotOptimizedArguments(MDefinition* def) { + // The arguments-analysis ensures the optimized-arguments MagicValue can only + // flow into a few allowlisted JSOps, for instance arguments.length or + // arguments[i]. See ArgumentsUseCanBeLazy. + // + // Baseline ICs have fast paths for these optimized-arguments uses and the + // transpiler lets us generate MIR for them. Ion ICs, however, don't support + // optimized-arguments because it's hard/impossible to access frame values + // reliably from Ion ICs, especially in inlined functions. To deal with this, + // we insert MGuardNotOptimizedArguments here if needed. On bailout we + // deoptimize the arguments-analysis. + + if (!info().hasArguments() || info().needsArgsObj() || info().isAnalysis()) { + return def; + } + + if (!MGuardNotOptimizedArguments::maybeIsOptimizedArguments(def)) { + return def; + } + + auto* ins = MGuardNotOptimizedArguments::New(alloc(), def); + current->add(ins); + return ins; +} + +bool WarpBuilder::buildInlinedCall(BytecodeLocation loc, + const WarpInlinedCall* inlineSnapshot, + CallInfo& callInfo) { + // We transpile the CacheIR to generate the correct guards before + // inlining. In this case, CacheOp::CallInlinedFunction updates the + // CallInfo, but does not generate a call. The body of the inlined + // function is generated below. + callInfo.markAsInlined(); + if (!TranspileCacheIRToMIR(this, loc, inlineSnapshot->cacheIRSnapshot(), + callInfo)) { + return false; + } + + jsbytecode* pc = loc.toRawBytecode(); + + callInfo.setImplicitlyUsedUnchecked(); + + // Capture formals in the outer resume point. + if (!callInfo.pushCallStack(&mirGen(), current)) { + return false; + } + MResumePoint* outerResumePoint = + MResumePoint::New(alloc(), current, pc, MResumePoint::Outer); + if (!outerResumePoint) { + return false; + } + current->setOuterResumePoint(outerResumePoint); + + // Pop formals again, except leave |callee| on stack for duration of call. + callInfo.popCallStack(current); + current->push(callInfo.callee()); + + // Build the graph. + CompileInfo* calleeCompileInfo = inlineSnapshot->info(); + MIRGraphReturns returns(alloc()); + AutoAccumulateReturns aar(graph(), returns); + WarpBuilder inlineBuilder(this, inlineSnapshot->scriptSnapshot(), + *calleeCompileInfo, &callInfo, outerResumePoint); + if (!inlineBuilder.buildInline()) { + // Note: Inlining only aborts on OOM. If inlining would fail for + // any other reason, we detect it in advance and don't inline. + return false; + } + + // We mark scripts as uninlineable in BytecodeAnalysis if we cannot + // reach a return statement (without going through a catch/finally). + MOZ_ASSERT(!returns.empty()); + + // Create return block + BytecodeLocation postCall = loc.next(); + MBasicBlock* prev = current; + if (!startNewEntryBlock(prev->stackDepth(), postCall)) { + return false; + } + // Restore previous value of callerResumePoint. + current->setCallerResumePoint(callerResumePoint()); + current->inheritSlots(prev); + + // Pop |callee|. + current->pop(); + + // Accumulate return values. + MDefinition* returnValue = + patchInlinedReturns(calleeCompileInfo, callInfo, returns, current); + if (!returnValue) { + return false; + } + current->push(returnValue); + + // Initialize entry slots + if (!current->initEntrySlots(alloc())) { + return false; + } + + return true; +} + +MDefinition* WarpBuilder::patchInlinedReturns(CompileInfo* calleeCompileInfo, + CallInfo& callInfo, + MIRGraphReturns& exits, + MBasicBlock* returnBlock) { + if (exits.length() == 1) { + return patchInlinedReturn(calleeCompileInfo, callInfo, exits[0], + returnBlock); + } + + // Accumulate multiple returns with a phi. + MPhi* phi = MPhi::New(alloc()); + if (!phi->reserveLength(exits.length())) { + return nullptr; + } + + for (auto* exit : exits) { + MDefinition* rdef = + patchInlinedReturn(calleeCompileInfo, callInfo, exit, returnBlock); + if (!rdef) { + return nullptr; + } + phi->addInput(rdef); + } + returnBlock->addPhi(phi); + return phi; +} + +MDefinition* WarpBuilder::patchInlinedReturn(CompileInfo* calleeCompileInfo, + CallInfo& callInfo, + MBasicBlock* exit, + MBasicBlock* returnBlock) { + // Replace the MReturn in the exit block with an MGoto branching to + // the return block. + MDefinition* rdef = exit->lastIns()->toReturn()->input(); + exit->discardLastIns(); + + // Constructors must be patched by the caller to always return an object. + // Derived class constructors contain extra bytecode to ensure an object + // is always returned, so no additional patching is needed. + if (callInfo.constructing() && + !calleeCompileInfo->isDerivedClassConstructor()) { + auto* filter = MReturnFromCtor::New(alloc(), rdef, callInfo.thisArg()); + exit->add(filter); + rdef = filter; + } + if (callInfo.isSetter()) { + MOZ_CRASH("TODO"); + } + + exit->end(MGoto::New(alloc(), returnBlock)); + if (!returnBlock->addPredecessorWithoutPhis(exit)) { + return nullptr; + } + + return rdef; +} diff --git a/js/src/jit/WarpBuilder.h b/js/src/jit/WarpBuilder.h index f99362e308..c0a333aa94 100644 --- a/js/src/jit/WarpBuilder.h +++ b/js/src/jit/WarpBuilder.h @@ -52,8 +52,7 @@ namespace jit { _(Generator) \ _(AsyncAwait) \ _(AsyncResolve) \ - /* Catch/finally */ \ - _(Exception) \ + /* try-finally */ \ _(Finally) \ _(Gosub) \ _(Retsub) \ @@ -61,21 +60,46 @@ namespace jit { _(DelName) \ _(GetRval) \ _(SetIntrinsic) \ - _(ThrowMsg) -// === !! WARNING WARNING WARNING !! === -// Do you really want to sacrifice performance by not implementing this -// operation in the optimizing compiler? + _(ThrowMsg) \ + /* Private Fields */ \ + _(InitLockedElem) \ + // === !! WARNING WARNING WARNING !! === + // Do you really want to sacrifice performance by not implementing this + // operation in the optimizing compiler? class MIRGenerator; class MIRGraph; class WarpSnapshot; +// Data that is shared across all WarpBuilders for a given compilation. +class MOZ_STACK_CLASS WarpCompilation { + // The total loop depth, including loops in the caller while + // compiling inlined functions. + uint32_t loopDepth_ = 0; + + // Loop phis for iterators that need to be kept alive. + PhiVector iterators_; + + public: + explicit WarpCompilation(TempAllocator& alloc) : iterators_(alloc) {} + + uint32_t loopDepth() const { return loopDepth_; } + void incLoopDepth() { loopDepth_++; } + void decLoopDepth() { + MOZ_ASSERT(loopDepth() > 0); + loopDepth_--; + } + + PhiVector* iterators() { return &iterators_; } +}; + // WarpBuilder builds a MIR graph from WarpSnapshot. Unlike WarpOracle, // WarpBuilder can run off-thread. class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared { - WarpSnapshot& snapshot_; + WarpCompilation* warpCompilation_; MIRGraph& graph_; const CompileInfo& info_; + const WarpScriptSnapshot* scriptSnapshot_; JSScript* script_; // Pointer to a WarpOpSnapshot or nullptr if we reached the end of the list. @@ -83,30 +107,38 @@ class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared { // WarpOpSnapshot is sorted the same way), the iterator always moves forward. const WarpOpSnapshot* opSnapshotIter_ = nullptr; - // Note: we need both loopDepth_ and loopStack_.length(): once we support - // inlining, loopDepth_ will be moved to a per-compilation data structure - // (OuterWarpBuilder?) whereas loopStack_ and pendingEdges_ will be - // builder-specific state. - uint32_t loopDepth_ = 0; + // Note: loopStack_ is builder-specific. loopStack_.length is the + // depth relative to the current script. The overall loop depth is + // stored in the WarpCompilation. LoopStateStack loopStack_; PendingEdgesMap pendingEdges_; - // Loop phis for iterators that need to be kept alive. - // TODO: once we support inlining, this needs to be stored once per - // compilation instead of builder. - PhiVector iterators_; + // These are only initialized when building an inlined script. + WarpBuilder* callerBuilder_ = nullptr; + MResumePoint* callerResumePoint_ = nullptr; + CallInfo* inlineCallInfo_ = nullptr; + WarpCompilation* warpCompilation() const { return warpCompilation_; } MIRGraph& graph() { return graph_; } const CompileInfo& info() const { return info_; } - WarpSnapshot& snapshot() const { return snapshot_; } + const WarpScriptSnapshot* scriptSnapshot() const { return scriptSnapshot_; } + + uint32_t loopDepth() const { return warpCompilation_->loopDepth(); } + void incLoopDepth() { warpCompilation_->incLoopDepth(); } + void decLoopDepth() { warpCompilation_->decLoopDepth(); } + PhiVector* iterators() { return warpCompilation_->iterators(); } + + WarpBuilder* callerBuilder() const { return callerBuilder_; } + MResumePoint* callerResumePoint() const { return callerResumePoint_; } BytecodeSite* newBytecodeSite(BytecodeLocation loc); - const WarpOpSnapshot* getOpSnapshotImpl(BytecodeLocation loc); + const WarpOpSnapshot* getOpSnapshotImpl(BytecodeLocation loc, + WarpOpSnapshot::Kind kind); template const T* getOpSnapshot(BytecodeLocation loc) { - const WarpOpSnapshot* snapshot = getOpSnapshotImpl(loc); + const WarpOpSnapshot* snapshot = getOpSnapshotImpl(loc, T::ThisKind); return snapshot ? snapshot->as() : nullptr; } @@ -130,10 +162,12 @@ class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared { MOZ_MUST_USE bool buildPrologue(); MOZ_MUST_USE bool buildBody(); - MOZ_MUST_USE bool buildEpilogue(); + + MOZ_MUST_USE bool buildInlinePrologue(); MOZ_MUST_USE bool buildIC(BytecodeLocation loc, CacheKind kind, std::initializer_list inputs); + MOZ_MUST_USE bool buildBailoutForColdIC(BytecodeLocation loc, CacheKind kind); MOZ_MUST_USE bool buildEnvironmentChain(); MInstruction* buildNamedLambdaEnv(MDefinition* callee, MDefinition* env, @@ -146,6 +180,8 @@ class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared { MConstant* globalLexicalEnvConstant(); MDefinition* getCallee(); + MDefinition* maybeGuardNotOptimizedArguments(MDefinition* def); + MOZ_MUST_USE bool buildUnaryOp(BytecodeLocation loc); MOZ_MUST_USE bool buildBinaryOp(BytecodeLocation loc); MOZ_MUST_USE bool buildCompareOp(BytecodeLocation loc); @@ -162,14 +198,32 @@ class MOZ_STACK_CLASS WarpBuilder : public WarpBuilderShared { bool usesEnvironmentChain() const; MDefinition* walkEnvironmentChain(uint32_t numHops); + MOZ_MUST_USE bool buildInlinedCall(BytecodeLocation loc, + const WarpInlinedCall* snapshot, + CallInfo& callInfo); + + MDefinition* patchInlinedReturns(CompileInfo* calleeCompileInfo, + CallInfo& callInfo, MIRGraphReturns& exits, + MBasicBlock* returnBlock); + MDefinition* patchInlinedReturn(CompileInfo* calleeCompileInfo, + CallInfo& callInfo, MBasicBlock* exit, + MBasicBlock* returnBlock); + #define BUILD_OP(OP, ...) MOZ_MUST_USE bool build_##OP(BytecodeLocation loc); FOR_EACH_OPCODE(BUILD_OP) #undef BUILD_OP public: - WarpBuilder(WarpSnapshot& snapshot, MIRGenerator& mirGen); + WarpBuilder(WarpSnapshot& snapshot, MIRGenerator& mirGen, + WarpCompilation* warpCompilation); + WarpBuilder(WarpBuilder* caller, WarpScriptSnapshot* snapshot, + CompileInfo& compileInfo, CallInfo* inlineCallInfo, + MResumePoint* callerResumePoint); MOZ_MUST_USE bool build(); + MOZ_MUST_USE bool buildInline(); + + CallInfo* inlineCallInfo() const { return inlineCallInfo_; } }; } // namespace jit diff --git a/js/src/jit/WarpBuilderShared.cpp b/js/src/jit/WarpBuilderShared.cpp index 80134b0c0f..1b3e3017fc 100644 --- a/js/src/jit/WarpBuilderShared.cpp +++ b/js/src/jit/WarpBuilderShared.cpp @@ -11,9 +11,13 @@ using namespace js; using namespace js::jit; -WarpBuilderShared::WarpBuilderShared(MIRGenerator& mirGen, +WarpBuilderShared::WarpBuilderShared(WarpSnapshot& snapshot, + MIRGenerator& mirGen, MBasicBlock* current_) - : mirGen_(mirGen), alloc_(mirGen.alloc()), current(current_) {} + : snapshot_(snapshot), + mirGen_(mirGen), + alloc_(mirGen.alloc()), + current(current_) {} bool WarpBuilderShared::resumeAfter(MInstruction* ins, BytecodeLocation loc) { MOZ_ASSERT(ins->isEffectful()); @@ -44,6 +48,7 @@ void WarpBuilderShared::pushConstant(const Value& v) { MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck, WrappedFunction* target) { + MOZ_ASSERT(callInfo.argFormat() == CallInfo::ArgFormat::Standard); MOZ_ASSERT_IF(needsThisCheck, !target); // TODO: Investigate DOM calls. @@ -104,3 +109,24 @@ MCall* WarpBuilderShared::makeCall(CallInfo& callInfo, bool needsThisCheck, return call; } + +MInstruction* WarpBuilderShared::makeSpreadCall(CallInfo& callInfo, + bool isSameRealm, + WrappedFunction* target) { + // TODO: support SpreadNew and SpreadSuperCall + MOZ_ASSERT(!callInfo.constructing()); + + // Load dense elements of the argument array. + MElements* elements = MElements::New(alloc(), callInfo.arrayArg()); + current->add(elements); + + auto* apply = MApplyArray::New(alloc(), target, callInfo.callee(), elements, + callInfo.thisArg()); + if (callInfo.ignoresReturnValue()) { + apply->setIgnoresReturnValue(); + } + if (isSameRealm) { + apply->setNotCrossRealm(); + } + return apply; +} diff --git a/js/src/jit/WarpBuilderShared.h b/js/src/jit/WarpBuilderShared.h index 78fb7392f2..884700a020 100644 --- a/js/src/jit/WarpBuilderShared.h +++ b/js/src/jit/WarpBuilderShared.h @@ -11,21 +11,21 @@ namespace js { namespace jit { class CallInfo; +class WarpSnapshot; // Base class for code sharing between WarpBuilder and WarpCacheIRTranspiler. // Because this code is used by WarpCacheIRTranspiler we should // generally assume that we only have access to the current basic block. class WarpBuilderShared { + WarpSnapshot& snapshot_; MIRGenerator& mirGen_; TempAllocator& alloc_; protected: MBasicBlock* current; - WarpBuilderShared(MIRGenerator& mirGen, MBasicBlock* current_); - - MIRGenerator& mirGen() { return mirGen_; } - TempAllocator& alloc() { return alloc_; } + WarpBuilderShared(WarpSnapshot& snapshot, MIRGenerator& mirGen, + MBasicBlock* current_); MOZ_MUST_USE bool resumeAfter(MInstruction* ins, BytecodeLocation loc); @@ -34,6 +34,14 @@ class WarpBuilderShared { MCall* makeCall(CallInfo& callInfo, bool needsThisCheck, WrappedFunction* target = nullptr); + MInstruction* makeSpreadCall(CallInfo& callInfo, bool isSameRealm = false, + WrappedFunction* target = nullptr); + + public: + MBasicBlock* currentBlock() const { return current; } + WarpSnapshot& snapshot() const { return snapshot_; } + MIRGenerator& mirGen() { return mirGen_; } + TempAllocator& alloc() { return alloc_; } }; } // namespace jit diff --git a/js/src/jit/WarpCacheIRTranspiler.cpp b/js/src/jit/WarpCacheIRTranspiler.cpp index 115c34beee..8bb7508b8b 100644 --- a/js/src/jit/WarpCacheIRTranspiler.cpp +++ b/js/src/jit/WarpCacheIRTranspiler.cpp @@ -6,6 +6,8 @@ #include "jsmath.h" +#include "builtin/DataViewObject.h" +#include "jit/AtomicOp.h" #include "jit/CacheIR.h" #include "jit/CacheIRCompiler.h" #include "jit/CacheIROpsGenerated.h" @@ -13,14 +15,20 @@ #include "jit/MIRBuilderShared.h" #include "jit/MIRGenerator.h" #include "jit/MIRGraph.h" +#include "jit/WarpBuilder.h" #include "jit/WarpBuilderShared.h" #include "jit/WarpSnapshot.h" +#include "js/ScalarType.h" // js::Scalar::Type +#include "vm/ArgumentsObject.h" + +#include "gc/ObjectKind-inl.h" using namespace js; using namespace js::jit; // The CacheIR transpiler generates MIR from Baseline CacheIR. class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { + WarpBuilder* builder_; BytecodeLocation loc_; const CacheIRStubInfo* stubInfo_; const uint8_t* stubData_; @@ -51,6 +59,12 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { #endif } + // Bypasses all checks in addEffectful. Only used for testing functions. + inline void addEffectfulUnsafe(MInstruction* ins) { + MOZ_ASSERT(ins->isEffectful()); + current->add(ins); + } + MOZ_MUST_USE bool resumeAfter(MInstruction* ins) { MOZ_ASSERT(effectful_ == ins); return WarpBuilderShared::resumeAfter(ins, loc_); @@ -91,12 +105,21 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { JS::Symbol* symbolStubField(uint32_t offset) { return reinterpret_cast(readStubWord(offset)); } - JSObject* objectStubField(uint32_t offset) { - return reinterpret_cast(readStubWord(offset)); + ObjectGroup* groupStubField(uint32_t offset) { + return reinterpret_cast(readStubWord(offset)); + } + BaseScript* baseScriptStubField(uint32_t offset) { + return reinterpret_cast(readStubWord(offset)); + } + const JSJitInfo* jitInfoStubField(uint32_t offset) { + return reinterpret_cast(readStubWord(offset)); } const void* rawPointerField(uint32_t offset) { return reinterpret_cast(readStubWord(offset)); } + jsid idStubField(uint32_t offset) { + return jsid::fromRawBits(readStubWord(offset)); + } int32_t int32StubField(uint32_t offset) { return static_cast(readStubWord(offset)); } @@ -104,8 +127,20 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { return static_cast(readStubWord(offset)); } + // This must only be called when the caller knows the object is tenured and + // not a nursery index. + JSObject* tenuredObjectStubField(uint32_t offset) { + WarpObjectField field = WarpObjectField::fromData(readStubWord(offset)); + return field.toObject(); + } + + // Returns either MConstant or MNurseryIndex. See WarpObjectField. + MInstruction* objectStubField(uint32_t offset); + MOZ_MUST_USE bool emitGuardTo(ValOperandId inputId, MIRType type); + MOZ_MUST_USE bool emitToString(OperandId inputId, StringOperandId resultId); + template MOZ_MUST_USE bool emitDoubleBinaryArithResult(NumberOperandId lhsId, NumberOperandId rhsId); @@ -117,8 +152,23 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { MOZ_MUST_USE bool emitCompareResult(JSOp op, OperandId lhsId, OperandId rhsId, MCompare::CompareType compareType); + MOZ_MUST_USE bool emitNewIteratorResult(MNewIterator::Type type, + uint32_t templateObjectOffset); + MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length); + bool emitAddAndStoreSlotShared(MAddAndStoreSlot::Kind kind, + ObjOperandId objId, uint32_t offsetOffset, + ValOperandId rhsId, uint32_t newShapeOffset); + + void addDataViewData(MDefinition* obj, Scalar::Type type, + MDefinition** offset, MInstruction** elements); + + MOZ_MUST_USE bool emitAtomicsBinaryOp(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType, AtomicOp op); + MOZ_MUST_USE bool emitLoadArgumentSlot(ValOperandId resultId, uint32_t slotIndex); @@ -126,20 +176,39 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { // (scripted function or native function with a JitEntry). enum class CallKind { Native, Scripted }; + MOZ_MUST_USE bool updateCallInfo(MDefinition* callee, CallFlags flags); + MOZ_MUST_USE bool emitCallFunction(ObjOperandId calleeId, Int32OperandId argcId, CallFlags flags, CallKind kind); + MOZ_MUST_USE bool emitFunApplyArgs(WrappedFunction* wrappedTarget, + CallFlags flags); + + WrappedFunction* maybeWrappedFunction(MDefinition* callee, CallKind kind, + uint16_t nargs, FunctionFlags flags); + WrappedFunction* maybeCallTarget(MDefinition* callee, CallKind kind); + + bool maybeCreateThis(MDefinition* callee, CallFlags flags, CallKind kind); + + MOZ_MUST_USE bool emitCallGetterResult(CallKind kind, ValOperandId receiverId, + uint32_t getterOffset, bool sameRealm, + uint32_t nargsAndFlagsOffset); + MOZ_MUST_USE bool emitCallSetter(CallKind kind, ObjOperandId receiverId, + uint32_t setterOffset, ValOperandId rhsId, + bool sameRealm, + uint32_t nargsAndFlagsOffset); CACHE_IR_TRANSPILER_GENERATED public: - WarpCacheIRTranspiler(MIRGenerator& mirGen, BytecodeLocation loc, - MBasicBlock* current, CallInfo* callInfo, - const WarpCacheIR* snapshot) - : WarpBuilderShared(mirGen, current), + WarpCacheIRTranspiler(WarpBuilder* builder, BytecodeLocation loc, + CallInfo* callInfo, const WarpCacheIR* cacheIRSnapshot) + : WarpBuilderShared(builder->snapshot(), builder->mirGen(), + builder->currentBlock()), + builder_(builder), loc_(loc), - stubInfo_(snapshot->stubInfo()), - stubData_(snapshot->stubData()), + stubInfo_(cacheIRSnapshot->stubInfo()), + stubData_(cacheIRSnapshot->stubData()), callInfo_(callInfo) {} MOZ_MUST_USE bool transpile(const MDefinitionStackVector& inputs); @@ -174,6 +243,20 @@ bool WarpCacheIRTranspiler::transpile(const MDefinitionStackVector& inputs) { return true; } +MInstruction* WarpCacheIRTranspiler::objectStubField(uint32_t offset) { + WarpObjectField field = WarpObjectField::fromData(readStubWord(offset)); + + if (field.isNurseryIndex()) { + auto* ins = MNurseryObject::New(alloc(), field.toNurseryIndex()); + add(ins); + return ins; + } + + auto* ins = MConstant::NewConstraintlessObject(alloc(), field.toObject()); + add(ins); + return ins; +} + bool WarpCacheIRTranspiler::emitGuardClass(ObjOperandId objId, GuardClassKind kind) { MDefinition* def = getOperand(objId); @@ -183,9 +266,31 @@ bool WarpCacheIRTranspiler::emitGuardClass(ObjOperandId objId, case GuardClassKind::Array: classp = &ArrayObject::class_; break; + case GuardClassKind::ArrayBuffer: + classp = &ArrayBufferObject::class_; + break; + case GuardClassKind::SharedArrayBuffer: + classp = &SharedArrayBufferObject::class_; + break; + case GuardClassKind::DataView: + classp = &DataViewObject::class_; + break; + case GuardClassKind::MappedArguments: + classp = &MappedArgumentsObject::class_; + break; + case GuardClassKind::UnmappedArguments: + classp = &UnmappedArgumentsObject::class_; + break; + case GuardClassKind::WindowProxy: + classp = mirGen().runtime->maybeWindowProxyClass(); + break; + case GuardClassKind::JSFunction: + classp = &JSFunction::class_; + break; default: MOZ_CRASH("not yet supported"); } + MOZ_ASSERT(classp); auto* ins = MGuardToClass::New(alloc(), def, classp); add(ins); @@ -218,1212 +323,2912 @@ bool WarpCacheIRTranspiler::emitGuardShape(ObjOperandId objId, return true; } -bool WarpCacheIRTranspiler::emitGuardSpecificAtom(StringOperandId strId, - uint32_t expectedOffset) { - MDefinition* str = getOperand(strId); - JSString* expected = stringStubField(expectedOffset); +bool WarpCacheIRTranspiler::emitGuardGroup(ObjOperandId objId, + uint32_t groupOffset) { + MDefinition* def = getOperand(objId); + ObjectGroup* group = groupStubField(groupOffset); - // TODO: Improve code-gen. - auto* ins = MGuardSpecificAtom::New(alloc(), str, &expected->asAtom()); + auto* ins = MGuardObjectGroup::New(alloc(), def, group, + /* bailOnEquality = */ false, + BailoutKind::ObjectIdentityOrTypeGuard); add(ins); - setOperand(strId, ins); + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitGuardSpecificSymbol(SymbolOperandId symId, - uint32_t expectedOffset) { - MDefinition* symbol = getOperand(symId); - JS::Symbol* expected = symbolStubField(expectedOffset); +bool WarpCacheIRTranspiler::emitGuardNullProto(ObjOperandId objId) { + MDefinition* def = getOperand(objId); - auto* ins = MGuardSpecificSymbol::New(alloc(), symbol, expected); + auto* ins = MGuardNullProto::New(alloc(), def); add(ins); - setOperand(symId, ins); + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitGuardSpecificObject(ObjOperandId objId, - uint32_t expectedOffset) { +bool WarpCacheIRTranspiler::emitGuardIsProxy(ObjOperandId objId) { MDefinition* obj = getOperand(objId); - JSObject* expected = objectStubField(expectedOffset); - - auto* constObj = MConstant::NewConstraintlessObject(alloc(), expected); - add(constObj); - auto* ins = MGuardObjectIdentity::New(alloc(), obj, constObj, - /* bailOnEquality = */ false); + auto* ins = MGuardIsProxy::New(alloc(), obj); add(ins); setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitGuardSpecificFunction( - ObjOperandId objId, uint32_t expectedOffset, uint32_t nargsAndFlagsOffset) { +bool WarpCacheIRTranspiler::emitGuardIsNotProxy(ObjOperandId objId) { MDefinition* obj = getOperand(objId); - JSObject* expected = objectStubField(expectedOffset); - uint32_t nargsAndFlags = uint32StubField(nargsAndFlagsOffset); - MOZ_ASSERT(expected->is()); - - auto* constObj = MConstant::NewConstraintlessObject(alloc(), expected); - add(constObj); - - uint16_t nargs = nargsAndFlags >> 16; - FunctionFlags flags = FunctionFlags(uint16_t(nargsAndFlags)); - - auto* ins = MGuardSpecificFunction::New(alloc(), obj, constObj, nargs, flags); + auto* ins = MGuardIsNotProxy::New(alloc(), obj); add(ins); setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitGuardNoDenseElements(ObjOperandId objId) { +bool WarpCacheIRTranspiler::emitGuardIsNotDOMProxy(ObjOperandId objId) { MDefinition* obj = getOperand(objId); - auto* ins = MGuardNoDenseElements::New(alloc(), obj); + auto* ins = MGuardIsNotDOMProxy::New(alloc(), obj); add(ins); setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitGuardNonDoubleType(ValOperandId inputId, - ValueType type) { - switch (type) { - case ValueType::String: - case ValueType::Symbol: - case ValueType::BigInt: - case ValueType::Int32: - case ValueType::Boolean: - return emitGuardTo(inputId, MIRTypeFromValueType(JSValueType(type))); - case ValueType::Undefined: - return emitGuardIsUndefined(inputId); - case ValueType::Null: - return emitGuardIsNull(inputId); - case ValueType::Double: - case ValueType::Magic: - case ValueType::PrivateGCThing: - case ValueType::Object: - break; - } +bool WarpCacheIRTranspiler::emitProxyGetResult(ObjOperandId objId, + uint32_t idOffset) { + MDefinition* obj = getOperand(objId); + jsid id = idStubField(idOffset); - MOZ_CRASH("unexpected type"); + auto* ins = MProxyGet::New(alloc(), obj, id); + addEffectful(ins); + + pushResult(ins); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardTo(ValOperandId inputId, MIRType type) { - MDefinition* def = getOperand(inputId); - if (def->type() == type) { - return true; - } +bool WarpCacheIRTranspiler::emitProxyGetByValueResult(ObjOperandId objId, + ValOperandId idId) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); - auto* ins = MUnbox::New(alloc(), def, type, MUnbox::Fallible); - add(ins); + auto* ins = MProxyGetByValue::New(alloc(), obj, id); + addEffectful(ins); - setOperand(inputId, ins); - return true; + pushResult(ins); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToObject(ValOperandId inputId) { - return emitGuardTo(inputId, MIRType::Object); +bool WarpCacheIRTranspiler::emitProxyHasPropResult(ObjOperandId objId, + ValOperandId idId, + bool hasOwn) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); + + auto* ins = MProxyHasProp::New(alloc(), obj, id, hasOwn); + addEffectful(ins); + + pushResult(ins); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToString(ValOperandId inputId) { - return emitGuardTo(inputId, MIRType::String); +bool WarpCacheIRTranspiler::emitProxySet(ObjOperandId objId, uint32_t idOffset, + ValOperandId rhsId, bool strict) { + MDefinition* obj = getOperand(objId); + jsid id = idStubField(idOffset); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = MProxySet::New(alloc(), obj, id, rhs, strict); + addEffectful(ins); + + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToSymbol(ValOperandId inputId) { - return emitGuardTo(inputId, MIRType::Symbol); +bool WarpCacheIRTranspiler::emitProxySetByValue(ObjOperandId objId, + ValOperandId idId, + ValOperandId rhsId, + bool strict) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = MProxySetByValue::New(alloc(), obj, id, rhs, strict); + addEffectful(ins); + + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToBoolean(ValOperandId inputId, - Int32OperandId resultId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitCallSetArrayLength(ObjOperandId objId, + bool strict, + ValOperandId rhsId) { + MDefinition* obj = getOperand(objId); + MDefinition* rhs = getOperand(rhsId); - MDefinition* boolean; - if (input->type() == MIRType::Boolean) { - boolean = input; + auto* ins = MCallSetArrayLength::New(alloc(), obj, rhs, strict); + addEffectful(ins); + + return resumeAfter(ins); +} + +bool WarpCacheIRTranspiler::emitCallDOMGetterResult(ObjOperandId objId, + uint32_t jitInfoOffset) { + MDefinition* obj = getOperand(objId); + const JSJitInfo* jitInfo = jitInfoStubField(jitInfoOffset); + + MInstruction* ins; + if (jitInfo->isAlwaysInSlot) { + ins = MGetDOMMember::New(alloc(), jitInfo, obj, nullptr, nullptr); } else { - auto* unbox = - MUnbox::New(alloc(), input, MIRType::Boolean, MUnbox::Fallible); - add(unbox); - boolean = unbox; + // TODO(post-Warp): realms, guard operands (movable?). + ins = MGetDOMProperty::New(alloc(), jitInfo, DOMObjectKind::Native, + (JS::Realm*)mirGen().realm->realmPtr(), obj, + nullptr, nullptr); } - // This is actually a no-op, but still required to get the correct type. - auto* ins = MToIntegerInt32::New(alloc(), boolean); - add(ins); - - return defineOperand(resultId, ins); -} + if (!ins) { + return false; + } -bool WarpCacheIRTranspiler::emitGuardToInt32(ValOperandId inputId, - Int32OperandId resultId) { - MDefinition* input = getOperand(inputId); - if (input->type() == MIRType::Int32) { - return defineOperand(resultId, input); + if (ins->isEffectful()) { + addEffectful(ins); + pushResult(ins); + return resumeAfter(ins); } - auto* ins = MUnbox::New(alloc(), input, MIRType::Int32, MUnbox::Fallible); add(ins); - - return defineOperand(resultId, ins); + pushResult(ins); + return true; } -bool WarpCacheIRTranspiler::emitGuardIsNumber(ValOperandId inputId) { - // MIRType::Double also implies int32 in Ion. - return emitGuardTo(inputId, MIRType::Double); +bool WarpCacheIRTranspiler::emitCallDOMSetter(ObjOperandId objId, + uint32_t jitInfoOffset, + ValOperandId rhsId) { + MDefinition* obj = getOperand(objId); + const JSJitInfo* jitInfo = jitInfoStubField(jitInfoOffset); + MDefinition* value = getOperand(rhsId); + + MOZ_ASSERT(jitInfo->type() == JSJitInfo::Setter); + auto* set = + MSetDOMProperty::New(alloc(), jitInfo->setter, DOMObjectKind::Native, + (JS::Realm*)mirGen().realm->realmPtr(), obj, value); + addEffectful(set); + return resumeAfter(set); } -bool WarpCacheIRTranspiler::emitGuardIsNullOrUndefined(ValOperandId inputId) { - MDefinition* input = getOperand(inputId); - if (input->type() == MIRType::Null || input->type() == MIRType::Undefined) { - return true; - } +bool WarpCacheIRTranspiler::emitMegamorphicLoadSlotResult(ObjOperandId objId, + uint32_t nameOffset, + bool handleMissing) { + MDefinition* obj = getOperand(objId); + PropertyName* name = stringStubField(nameOffset)->asAtom().asPropertyName(); - auto* ins = MGuardNullOrUndefined::New(alloc(), input); + MOZ_ASSERT(handleMissing); + + auto* ins = MMegamorphicLoadSlot::New(alloc(), obj, name); add(ins); - setOperand(inputId, ins); + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitGuardIsNull(ValOperandId inputId) { - MDefinition* input = getOperand(inputId); - if (input->type() == MIRType::Null) { - return true; - } +bool WarpCacheIRTranspiler::emitMegamorphicLoadSlotByValueResult( + ObjOperandId objId, ValOperandId idId, bool handleMissing) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); - auto* ins = MGuardValue::New(alloc(), input, NullValue()); + MOZ_ASSERT(handleMissing); + + auto* ins = MMegamorphicLoadSlotByValue::New(alloc(), obj, id); add(ins); - setOperand(inputId, ins); + + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitGuardIsUndefined(ValOperandId inputId) { - MDefinition* input = getOperand(inputId); - if (input->type() == MIRType::Undefined) { - return true; - } +bool WarpCacheIRTranspiler::emitMegamorphicStoreSlot(ObjOperandId objId, + uint32_t nameOffset, + ValOperandId rhsId, + bool needsTypeBarrier) { + MDefinition* obj = getOperand(objId); + PropertyName* name = stringStubField(nameOffset)->asAtom().asPropertyName(); + MDefinition* rhs = getOperand(rhsId); - auto* ins = MGuardValue::New(alloc(), input, UndefinedValue()); - add(ins); - setOperand(inputId, ins); - return true; -} + MOZ_ASSERT(!needsTypeBarrier); -bool WarpCacheIRTranspiler::emitGuardToInt32Index(ValOperandId inputId, - Int32OperandId resultId) { - MDefinition* input = getOperand(inputId); - auto* ins = - MToNumberInt32::New(alloc(), input, IntConversionInputKind::NumbersOnly); - add(ins); + auto* ins = MMegamorphicStoreSlot::New(alloc(), obj, name, rhs); + addEffectful(ins); - return defineOperand(resultId, ins); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToTypedArrayIndex( - ValOperandId inputId, Int32OperandId resultId) { - MDefinition* input = getOperand(inputId); - auto* ins = MTypedArrayIndexToInt32::New(alloc(), input); +bool WarpCacheIRTranspiler::emitMegamorphicHasPropResult(ObjOperandId objId, + ValOperandId idId, + bool hasOwn) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); + + auto* ins = MMegamorphicHasProp::New(alloc(), obj, id, hasOwn); add(ins); - return defineOperand(resultId, ins); + pushResult(ins); + return true; } -bool WarpCacheIRTranspiler::emitTruncateDoubleToUInt32( - NumberOperandId inputId, Int32OperandId resultId) { - MDefinition* input = getOperand(inputId); - auto* ins = MTruncateToInt32::New(alloc(), input); - add(ins); +bool WarpCacheIRTranspiler::emitMegamorphicSetElement(ObjOperandId objId, + ValOperandId idId, + ValOperandId rhsId, + bool strict) { + MDefinition* obj = getOperand(objId); + MDefinition* id = getOperand(idId); + MDefinition* rhs = getOperand(rhsId); - return defineOperand(resultId, ins); + auto* ins = MCallSetElement::New(alloc(), obj, id, rhs, strict); + addEffectful(ins); + + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitGuardToInt32ModUint32(ValOperandId valId, - Int32OperandId resultId) { - MDefinition* input = getOperand(valId); - auto* ins = MTruncateToInt32::New(alloc(), input); - add(ins); +bool WarpCacheIRTranspiler::emitGuardIsNotArrayBufferMaybeShared( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); - return defineOperand(resultId, ins); -} + auto* ins = MGuardIsNotArrayBufferMaybeShared::New(alloc(), obj); + add(ins); -bool WarpCacheIRTranspiler::emitLoadInt32Result(Int32OperandId valId) { - MDefinition* val = getOperand(valId); - MOZ_ASSERT(val->type() == MIRType::Int32); - pushResult(val); + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadDoubleResult(NumberOperandId valId) { - MDefinition* val = getOperand(valId); - MOZ_ASSERT(val->type() == MIRType::Double); - pushResult(val); +bool WarpCacheIRTranspiler::emitGuardIsTypedArray(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* ins = MGuardIsTypedArray::New(alloc(), obj); + add(ins); + + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadBigIntResult(BigIntOperandId valId) { - MDefinition* val = getOperand(valId); - MOZ_ASSERT(val->type() == MIRType::BigInt); - pushResult(val); +bool WarpCacheIRTranspiler::emitGuardProto(ObjOperandId objId, + uint32_t protoOffset) { + MDefinition* def = getOperand(objId); + MDefinition* proto = objectStubField(protoOffset); + + auto* ins = MGuardProto::New(alloc(), def, proto); + add(ins); + + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadObjectResult(ObjOperandId objId) { +bool WarpCacheIRTranspiler::emitGuardDynamicSlotIsSpecificObject( + ObjOperandId objId, ObjOperandId expectedId, uint32_t slotOffset) { + size_t slotIndex = int32StubField(slotOffset); MDefinition* obj = getOperand(objId); - MOZ_ASSERT(obj->type() == MIRType::Object); - pushResult(obj); + MDefinition* expected = getOperand(expectedId); + + auto* slots = MSlots::New(alloc(), obj); + add(slots); + + auto* load = MLoadDynamicSlot::New(alloc(), slots, slotIndex); + add(load); + + auto* unbox = MUnbox::New(alloc(), load, MIRType::Object, MUnbox::Fallible); + add(unbox); + + auto* guard = MGuardObjectIdentity::New(alloc(), unbox, expected, + /* bailOnEquality = */ false); + add(guard); return true; } -bool WarpCacheIRTranspiler::emitLoadStringResult(StringOperandId strId) { +bool WarpCacheIRTranspiler::emitGuardSpecificAtom(StringOperandId strId, + uint32_t expectedOffset) { MDefinition* str = getOperand(strId); - MOZ_ASSERT(str->type() == MIRType::String); - pushResult(str); + JSString* expected = stringStubField(expectedOffset); + + auto* ins = MGuardSpecificAtom::New(alloc(), str, &expected->asAtom()); + add(ins); + + setOperand(strId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadSymbolResult(SymbolOperandId symId) { - MDefinition* sym = getOperand(symId); - MOZ_ASSERT(sym->type() == MIRType::Symbol); - pushResult(sym); +bool WarpCacheIRTranspiler::emitGuardSpecificSymbol(SymbolOperandId symId, + uint32_t expectedOffset) { + MDefinition* symbol = getOperand(symId); + JS::Symbol* expected = symbolStubField(expectedOffset); + + auto* ins = MGuardSpecificSymbol::New(alloc(), symbol, expected); + add(ins); + + setOperand(symId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadUndefinedResult() { - pushResult(constant(UndefinedValue())); +bool WarpCacheIRTranspiler::emitGuardSpecificObject(ObjOperandId objId, + uint32_t expectedOffset) { + MDefinition* obj = getOperand(objId); + MDefinition* expected = objectStubField(expectedOffset); + + auto* ins = MGuardObjectIdentity::New(alloc(), obj, expected, + /* bailOnEquality = */ false); + add(ins); + + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadBooleanResult(bool val) { - pushResult(constant(BooleanValue(val))); +bool WarpCacheIRTranspiler::emitGuardSpecificFunction( + ObjOperandId objId, uint32_t expectedOffset, uint32_t nargsAndFlagsOffset) { + MDefinition* obj = getOperand(objId); + MDefinition* expected = objectStubField(expectedOffset); + uint32_t nargsAndFlags = uint32StubField(nargsAndFlagsOffset); + + uint16_t nargs = nargsAndFlags >> 16; + FunctionFlags flags = FunctionFlags(uint16_t(nargsAndFlags)); + + auto* ins = MGuardSpecificFunction::New(alloc(), obj, expected, nargs, flags); + add(ins); + + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadInt32Constant(uint32_t valOffset, - Int32OperandId resultId) { - int32_t val = int32StubField(valOffset); - auto* valConst = constant(Int32Value(val)); - return defineOperand(resultId, valConst); -} +bool WarpCacheIRTranspiler::emitGuardFunctionScript( + ObjOperandId funId, uint32_t expectedOffset, uint32_t nargsAndFlagsOffset) { + MDefinition* fun = getOperand(funId); + BaseScript* expected = baseScriptStubField(expectedOffset); + uint32_t nargsAndFlags = uint32StubField(nargsAndFlagsOffset); -bool WarpCacheIRTranspiler::emitLoadEnclosingEnvironment( - ObjOperandId objId, ObjOperandId resultId) { - MDefinition* env = getOperand(objId); - auto* ins = MEnclosingEnvironment::New(alloc(), env); + uint16_t nargs = nargsAndFlags >> 16; + FunctionFlags flags = FunctionFlags(uint16_t(nargsAndFlags)); + + auto* ins = MGuardFunctionScript::New(alloc(), fun, expected, nargs, flags); add(ins); - return defineOperand(resultId, ins); + setOperand(funId, ins); + return true; } -bool WarpCacheIRTranspiler::emitLoadObject(ObjOperandId resultId, - uint32_t objOffset) { - JSObject* obj = objectStubField(objOffset); +bool WarpCacheIRTranspiler::emitGuardStringToIndex(StringOperandId strId, + Int32OperandId resultId) { + MDefinition* str = getOperand(strId); - auto* ins = MConstant::NewConstraintlessObject(alloc(), obj); + auto* ins = MGuardStringToIndex::New(alloc(), str); add(ins); return defineOperand(resultId, ins); } -bool WarpCacheIRTranspiler::emitLoadProto(ObjOperandId objId, - ObjOperandId resultId) { - MDefinition* obj = getOperand(objId); +bool WarpCacheIRTranspiler::emitGuardStringToInt32(StringOperandId strId, + Int32OperandId resultId) { + MDefinition* str = getOperand(strId); - auto* ins = MObjectStaticProto::New(alloc(), obj); + auto* ins = MGuardStringToInt32::New(alloc(), str); add(ins); return defineOperand(resultId, ins); } -bool WarpCacheIRTranspiler::emitLoadDynamicSlotResult(ObjOperandId objId, - uint32_t offsetOffset) { - int32_t offset = int32StubField(offsetOffset); - - MDefinition* obj = getOperand(objId); - size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); - - auto* slots = MSlots::New(alloc(), obj); - add(slots); +bool WarpCacheIRTranspiler::emitGuardStringToNumber(StringOperandId strId, + NumberOperandId resultId) { + MDefinition* str = getOperand(strId); - auto* load = MLoadDynamicSlot::New(alloc(), slots, slotIndex); - add(load); + auto* ins = MGuardStringToDouble::New(alloc(), str); + add(ins); - pushResult(load); - return true; + return defineOperand(resultId, ins); } -bool WarpCacheIRTranspiler::emitLoadFixedSlotResult(ObjOperandId objId, - uint32_t offsetOffset) { - int32_t offset = int32StubField(offsetOffset); - +bool WarpCacheIRTranspiler::emitGuardNoDenseElements(ObjOperandId objId) { MDefinition* obj = getOperand(objId); - uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); - auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); - add(load); + auto* ins = MGuardNoDenseElements::New(alloc(), obj); + add(ins); - pushResult(load); + setOperand(objId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadFixedSlotTypedResult(ObjOperandId objId, - uint32_t offsetOffset, - ValueType type) { - int32_t offset = int32StubField(offsetOffset); - - MDefinition* obj = getOperand(objId); - uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); +bool WarpCacheIRTranspiler::emitGuardMagicValue(ValOperandId valId, + JSWhyMagic magic) { + MDefinition* val = getOperand(valId); - auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); - load->setResultType(MIRTypeFromValueType(JSValueType(type))); - add(load); + auto* ins = MGuardValue::New(alloc(), val, MagicValue(magic)); + add(ins); - pushResult(load); + setOperand(valId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadEnvironmentFixedSlotResult( - ObjOperandId objId, uint32_t offsetOffset) { - int32_t offset = int32StubField(offsetOffset); - - MDefinition* obj = getOperand(objId); - uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); +bool WarpCacheIRTranspiler::emitGuardFrameHasNoArgumentsObject() { + // WarpOracle ensures this op isn't transpiled in functions that need an + // arguments object. + MOZ_ASSERT(!currentBlock()->info().needsArgsObj()); + return true; +} - auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); - add(load); +bool WarpCacheIRTranspiler::emitGuardFunctionHasJitEntry(ObjOperandId funId, + bool constructing) { + MDefinition* fun = getOperand(funId); + uint16_t flags = FunctionFlags::HasJitEntryFlags(constructing); - auto* lexicalCheck = MLexicalCheck::New(alloc(), load); - add(lexicalCheck); + auto* ins = MGuardFunctionFlags::New(alloc(), fun, flags, + /*bailWhenSet=*/false); + add(ins); - pushResult(lexicalCheck); + setOperand(funId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadEnvironmentDynamicSlotResult( - ObjOperandId objId, uint32_t offsetOffset) { - int32_t offset = int32StubField(offsetOffset); +bool WarpCacheIRTranspiler::emitGuardFunctionHasNoJitEntry(ObjOperandId funId) { + MDefinition* fun = getOperand(funId); + uint16_t flags = FunctionFlags::HasJitEntryFlags(/*isConstructing=*/false); - MDefinition* obj = getOperand(objId); - size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); + auto* ins = MGuardFunctionFlags::New(alloc(), fun, flags, + /*bailWhenSet=*/true); + add(ins); - auto* slots = MSlots::New(alloc(), obj); - add(slots); + setOperand(funId, ins); + return true; +} - auto* load = MLoadDynamicSlot::New(alloc(), slots, slotIndex); - add(load); +bool WarpCacheIRTranspiler::emitGuardFunctionIsConstructor(ObjOperandId funId) { + MDefinition* fun = getOperand(funId); - auto* lexicalCheck = MLexicalCheck::New(alloc(), load); - add(lexicalCheck); + auto* ins = MGuardFunctionFlags::New(alloc(), fun, FunctionFlags::CONSTRUCTOR, + /*bailWhenSet=*/false); + add(ins); - pushResult(lexicalCheck); + setOperand(funId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadInt32ArrayLengthResult(ObjOperandId objId) { - MDefinition* obj = getOperand(objId); - - auto* elements = MElements::New(alloc(), obj); - add(elements); +bool WarpCacheIRTranspiler::emitGuardNotClassConstructor(ObjOperandId funId) { + MDefinition* fun = getOperand(funId); - auto* length = MArrayLength::New(alloc(), elements); - add(length); + auto* ins = + MGuardFunctionKind::New(alloc(), fun, FunctionFlags::ClassConstructor, + /*bailOnEquality=*/true); + add(ins); - pushResult(length); + setOperand(funId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadTypedArrayLengthResult( - ObjOperandId objId, uint32_t getterOffset) { - MDefinition* obj = getOperand(objId); +bool WarpCacheIRTranspiler::emitGuardArrayIsPacked(ObjOperandId arrayId) { + MDefinition* array = getOperand(arrayId); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* ins = MGuardArrayIsPacked::New(alloc(), array); + add(ins); - pushResult(length); + setOperand(arrayId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadStringLengthResult(StringOperandId strId) { - MDefinition* str = getOperand(strId); - - auto* length = MStringLength::New(alloc(), str); - add(length); +bool WarpCacheIRTranspiler::emitLoadFrameCalleeResult() { + if (const CallInfo* callInfo = builder_->inlineCallInfo()) { + pushResult(callInfo->callee()); + return true; + } - pushResult(length); + auto* ins = MCallee::New(alloc()); + add(ins); + pushResult(ins); return true; } -MInstruction* WarpCacheIRTranspiler::addBoundsCheck(MDefinition* index, - MDefinition* length) { - MInstruction* check = MBoundsCheck::New(alloc(), index, length); - add(check); - - if (JitOptions.spectreIndexMasking) { - // Use a separate MIR instruction for the index masking. Doing this as - // part of MBoundsCheck would be unsound because bounds checks can be - // optimized or eliminated completely. Consider this: - // - // for (var i = 0; i < x; i++) - // res = arr[i]; - // - // If we can prove |x < arr.length|, we are able to eliminate the bounds - // check, but we should not get rid of the index masking because the - // |i < x| branch could still be mispredicted. - // - // Using a separate instruction lets us eliminate the bounds check - // without affecting the index masking. - check = MSpectreMaskIndex::New(alloc(), check, length); - add(check); +bool WarpCacheIRTranspiler::emitLoadFrameNumActualArgsResult() { + if (const CallInfo* callInfo = builder_->inlineCallInfo()) { + auto* ins = constant(Int32Value(callInfo->argc())); + pushResult(ins); + return true; } - return check; + auto* ins = MArgumentsLength::New(alloc()); + add(ins); + pushResult(ins); + return true; } -bool WarpCacheIRTranspiler::emitLoadDenseElementResult(ObjOperandId objId, - Int32OperandId indexId) { - MDefinition* obj = getOperand(objId); - MDefinition* index = getOperand(indexId); +bool WarpCacheIRTranspiler::emitLoadFrameArgumentResult( + Int32OperandId indexId) { + // We don't support arguments[i] in inlined functions. Scripts using + // arguments[i] are marked as uninlineable in arguments analysis. + MOZ_ASSERT(!builder_->inlineCallInfo()); - auto* elements = MElements::New(alloc(), obj); - add(elements); + MDefinition* index = getOperand(indexId); - auto* length = MInitializedLength::New(alloc(), elements); + auto* length = MArgumentsLength::New(alloc()); add(length); index = addBoundsCheck(index, length); - bool needsHoleCheck = true; - bool loadDouble = false; // TODO: Ion-only optimization. - auto* load = - MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble); + auto* load = MGetFrameArgument::New(alloc(), index); add(load); pushResult(load); return true; } -bool WarpCacheIRTranspiler::emitLoadDenseElementHoleResult( - ObjOperandId objId, Int32OperandId indexId) { - MDefinition* obj = getOperand(objId); - MDefinition* index = getOperand(indexId); +bool WarpCacheIRTranspiler::emitGuardNonDoubleType(ValOperandId inputId, + ValueType type) { + switch (type) { + case ValueType::String: + case ValueType::Symbol: + case ValueType::BigInt: + case ValueType::Int32: + case ValueType::Boolean: + return emitGuardTo(inputId, MIRTypeFromValueType(JSValueType(type))); + case ValueType::Undefined: + return emitGuardIsUndefined(inputId); + case ValueType::Null: + return emitGuardIsNull(inputId); + case ValueType::Double: + case ValueType::Magic: + case ValueType::PrivateGCThing: + case ValueType::Object: + break; + } - auto* elements = MElements::New(alloc(), obj); - add(elements); + MOZ_CRASH("unexpected type"); +} - auto* length = MInitializedLength::New(alloc(), elements); - add(length); +bool WarpCacheIRTranspiler::emitGuardTo(ValOperandId inputId, MIRType type) { + MDefinition* def = getOperand(inputId); + if (def->type() == type) { + return true; + } - bool needsHoleCheck = true; - auto* load = - MLoadElementHole::New(alloc(), elements, index, length, needsHoleCheck); - add(load); + auto* ins = MUnbox::New(alloc(), def, type, MUnbox::Fallible); + add(ins); - pushResult(load); + setOperand(inputId, ins); return true; } -bool WarpCacheIRTranspiler::emitLoadTypedArrayElementResult( - ObjOperandId objId, Int32OperandId indexId, Scalar::Type elementType, - bool handleOOB) { +bool WarpCacheIRTranspiler::emitGuardToObject(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::Object); +} + +bool WarpCacheIRTranspiler::emitGuardToString(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::String); +} + +bool WarpCacheIRTranspiler::emitGuardToSymbol(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::Symbol); +} + +bool WarpCacheIRTranspiler::emitGuardToBigInt(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::BigInt); +} + +bool WarpCacheIRTranspiler::emitGuardToBoolean(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::Boolean); +} + +bool WarpCacheIRTranspiler::emitGuardToInt32(ValOperandId inputId) { + return emitGuardTo(inputId, MIRType::Int32); +} + +bool WarpCacheIRTranspiler::emitGuardBooleanToInt32(ValOperandId inputId, + Int32OperandId resultId) { + MDefinition* input = getOperand(inputId); + + MDefinition* boolean; + if (input->type() == MIRType::Boolean) { + boolean = input; + } else { + auto* unbox = + MUnbox::New(alloc(), input, MIRType::Boolean, MUnbox::Fallible); + add(unbox); + boolean = unbox; + } + + auto* ins = MToIntegerInt32::New(alloc(), boolean); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitGuardIsNumber(ValOperandId inputId) { + // MIRType::Double also implies int32 in Ion. + return emitGuardTo(inputId, MIRType::Double); +} + +bool WarpCacheIRTranspiler::emitGuardIsNullOrUndefined(ValOperandId inputId) { + MDefinition* input = getOperand(inputId); + if (input->type() == MIRType::Null || input->type() == MIRType::Undefined) { + return true; + } + + auto* ins = MGuardNullOrUndefined::New(alloc(), input); + add(ins); + + setOperand(inputId, ins); + return true; +} + +bool WarpCacheIRTranspiler::emitGuardIsNull(ValOperandId inputId) { + MDefinition* input = getOperand(inputId); + if (input->type() == MIRType::Null) { + return true; + } + + auto* ins = MGuardValue::New(alloc(), input, NullValue()); + add(ins); + setOperand(inputId, ins); + return true; +} + +bool WarpCacheIRTranspiler::emitGuardIsUndefined(ValOperandId inputId) { + MDefinition* input = getOperand(inputId); + if (input->type() == MIRType::Undefined) { + return true; + } + + auto* ins = MGuardValue::New(alloc(), input, UndefinedValue()); + add(ins); + setOperand(inputId, ins); + return true; +} + +bool WarpCacheIRTranspiler::emitGuardTagNotEqual(ValueTagOperandId lhsId, + ValueTagOperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = MGuardTagNotEqual::New(alloc(), lhs, rhs); + add(ins); + + return true; +} + +bool WarpCacheIRTranspiler::emitGuardToInt32Index(ValOperandId inputId, + Int32OperandId resultId) { + MDefinition* input = getOperand(inputId); + auto* ins = + MToNumberInt32::New(alloc(), input, IntConversionInputKind::NumbersOnly); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitGuardToTypedArrayIndex( + ValOperandId inputId, Int32OperandId resultId) { + MDefinition* input = getOperand(inputId); + + MDefinition* number; + if (input->type() == MIRType::Int32 || input->type() == MIRType::Double) { + number = input; + } else { + auto* unbox = + MUnbox::New(alloc(), input, MIRType::Double, MUnbox::Fallible); + add(unbox); + number = unbox; + } + + auto* ins = MTypedArrayIndexToInt32::New(alloc(), number); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitTruncateDoubleToUInt32( + NumberOperandId inputId, Int32OperandId resultId) { + MDefinition* input = getOperand(inputId); + auto* ins = MTruncateToInt32::New(alloc(), input); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitGuardToInt32ModUint32(ValOperandId valId, + Int32OperandId resultId) { + MDefinition* input = getOperand(valId); + auto* ins = MTruncateToInt32::New(alloc(), input); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitGuardToUint8Clamped(ValOperandId valId, + Int32OperandId resultId) { + MDefinition* input = getOperand(valId); + auto* ins = MClampToUint8::New(alloc(), input); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitToString(OperandId inputId, + StringOperandId resultId) { + MDefinition* input = getOperand(inputId); + auto* ins = + MToString::New(alloc(), input, MToString::SideEffectHandling::Bailout); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitCallInt32ToString(Int32OperandId inputId, + StringOperandId resultId) { + return emitToString(inputId, resultId); +} + +bool WarpCacheIRTranspiler::emitCallNumberToString(NumberOperandId inputId, + StringOperandId resultId) { + return emitToString(inputId, resultId); +} + +bool WarpCacheIRTranspiler::emitBooleanToString(BooleanOperandId inputId, + StringOperandId resultId) { + return emitToString(inputId, resultId); +} + +bool WarpCacheIRTranspiler::emitBooleanToNumber(BooleanOperandId inputId, + NumberOperandId resultId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MToDouble::New(alloc(), input); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitLoadInt32Result(Int32OperandId valId) { + MDefinition* val = getOperand(valId); + MOZ_ASSERT(val->type() == MIRType::Int32); + pushResult(val); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadDoubleResult(NumberOperandId valId) { + MDefinition* val = getOperand(valId); + MOZ_ASSERT(val->type() == MIRType::Double); + pushResult(val); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadBigIntResult(BigIntOperandId valId) { + MDefinition* val = getOperand(valId); + MOZ_ASSERT(val->type() == MIRType::BigInt); + pushResult(val); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadObjectResult(ObjOperandId objId) { MDefinition* obj = getOperand(objId); - MDefinition* index = getOperand(indexId); + MOZ_ASSERT(obj->type() == MIRType::Object); + pushResult(obj); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadStringResult(StringOperandId strId) { + MDefinition* str = getOperand(strId); + MOZ_ASSERT(str->type() == MIRType::String); + pushResult(str); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadSymbolResult(SymbolOperandId symId) { + MDefinition* sym = getOperand(symId); + MOZ_ASSERT(sym->type() == MIRType::Symbol); + pushResult(sym); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadUndefinedResult() { + pushResult(constant(UndefinedValue())); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadBooleanResult(bool val) { + pushResult(constant(BooleanValue(val))); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadInt32Constant(uint32_t valOffset, + Int32OperandId resultId) { + int32_t val = int32StubField(valOffset); + auto* valConst = constant(Int32Value(val)); + return defineOperand(resultId, valConst); +} + +bool WarpCacheIRTranspiler::emitLoadBooleanConstant(bool val, + BooleanOperandId resultId) { + auto* valConst = constant(BooleanValue(val)); + return defineOperand(resultId, valConst); +} + +bool WarpCacheIRTranspiler::emitLoadUndefined(ValOperandId resultId) { + auto* valConst = constant(UndefinedValue()); + return defineOperand(resultId, valConst); +} + +bool WarpCacheIRTranspiler::emitLoadConstantString(uint32_t strOffset, + StringOperandId resultId) { + JSString* val = stringStubField(strOffset); + auto* valConst = constant(StringValue(val)); + return defineOperand(resultId, valConst); +} + +bool WarpCacheIRTranspiler::emitLoadEnclosingEnvironment( + ObjOperandId objId, ObjOperandId resultId) { + MDefinition* env = getOperand(objId); + auto* ins = MEnclosingEnvironment::New(alloc(), env); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitLoadObject(ObjOperandId resultId, + uint32_t objOffset) { + MInstruction* ins = objectStubField(objOffset); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitLoadProto(ObjOperandId objId, + ObjOperandId resultId) { + MDefinition* obj = getOperand(objId); + + auto* ins = MObjectStaticProto::New(alloc(), obj); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitLoadInstanceOfObjectResult( + ValOperandId lhsId, ObjOperandId protoId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* proto = getOperand(protoId); + + auto* instanceOf = MInstanceOf::New(alloc(), lhs, proto); + addEffectful(instanceOf); + + pushResult(instanceOf); + return resumeAfter(instanceOf); +} + +bool WarpCacheIRTranspiler::emitLoadValueTag(ValOperandId valId, + ValueTagOperandId resultId) { + MDefinition* val = getOperand(valId); + + auto* ins = MLoadValueTag::New(alloc(), val); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitLoadDynamicSlotResult(ObjOperandId objId, + uint32_t offsetOffset) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); + + auto* slots = MSlots::New(alloc(), obj); + add(slots); + + auto* load = MLoadDynamicSlot::New(alloc(), slots, slotIndex); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadFixedSlotResult(ObjOperandId objId, + uint32_t offsetOffset) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); + + auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadFixedSlotTypedResult(ObjOperandId objId, + uint32_t offsetOffset, + ValueType type) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); + + auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); + load->setResultType(MIRTypeFromValueType(JSValueType(type))); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadEnvironmentFixedSlotResult( + ObjOperandId objId, uint32_t offsetOffset) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + uint32_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); + + auto* load = MLoadFixedSlot::New(alloc(), obj, slotIndex); + add(load); + + auto* lexicalCheck = MLexicalCheck::New(alloc(), load); + add(lexicalCheck); + + if (snapshot().bailoutInfo().failedLexicalCheck()) { + lexicalCheck->setNotMovable(); + } + + pushResult(lexicalCheck); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadEnvironmentDynamicSlotResult( + ObjOperandId objId, uint32_t offsetOffset) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); + + auto* slots = MSlots::New(alloc(), obj); + add(slots); + + auto* load = MLoadDynamicSlot::New(alloc(), slots, slotIndex); + add(load); + + auto* lexicalCheck = MLexicalCheck::New(alloc(), load); + add(lexicalCheck); + + if (snapshot().bailoutInfo().failedLexicalCheck()) { + lexicalCheck->setNotMovable(); + } + + pushResult(lexicalCheck); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadInt32ArrayLengthResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MArrayLength::New(alloc(), elements); + add(length); + + pushResult(length); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadInt32ArrayLength(ObjOperandId objId, + Int32OperandId resultId) { + MDefinition* obj = getOperand(objId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MArrayLength::New(alloc(), elements); + add(length); + + return defineOperand(resultId, length); +} + +bool WarpCacheIRTranspiler::emitLoadArgumentsObjectArgResult( + ObjOperandId objId, Int32OperandId indexId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + auto* load = MLoadArgumentsObjectArg::New(alloc(), obj, index); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadArgumentsObjectLengthResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* length = MArgumentsObjectLength::New(alloc(), obj); + add(length); + + pushResult(length); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadFunctionLengthResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* length = MFunctionLength::New(alloc(), obj); + add(length); + + pushResult(length); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadFunctionNameResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* name = MFunctionName::New(alloc(), obj); + add(name); + + pushResult(name); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadTypedArrayLengthResult( + ObjOperandId objId, uint32_t getterOffset) { + MDefinition* obj = getOperand(objId); + + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + pushResult(length); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadStringLengthResult(StringOperandId strId) { + MDefinition* str = getOperand(strId); + + auto* length = MStringLength::New(alloc(), str); + add(length); + + pushResult(length); + return true; +} + +MInstruction* WarpCacheIRTranspiler::addBoundsCheck(MDefinition* index, + MDefinition* length) { + MInstruction* check = MBoundsCheck::New(alloc(), index, length); + add(check); + + if (snapshot().bailoutInfo().failedBoundsCheck()) { + check->setNotMovable(); + } + + if (JitOptions.spectreIndexMasking) { + // Use a separate MIR instruction for the index masking. Doing this as + // part of MBoundsCheck would be unsound because bounds checks can be + // optimized or eliminated completely. Consider this: + // + // for (var i = 0; i < x; i++) + // res = arr[i]; + // + // If we can prove |x < arr.length|, we are able to eliminate the bounds + // check, but we should not get rid of the index masking because the + // |i < x| branch could still be mispredicted. + // + // Using a separate instruction lets us eliminate the bounds check + // without affecting the index masking. + check = MSpectreMaskIndex::New(alloc(), check, length); + add(check); + } + + return check; +} + +bool WarpCacheIRTranspiler::emitLoadDenseElementResult(ObjOperandId objId, + Int32OperandId indexId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MInitializedLength::New(alloc(), elements); + add(length); + + index = addBoundsCheck(index, length); + + bool needsHoleCheck = true; + bool loadDouble = false; // TODO(post-Warp): Ion-only optimization. + auto* load = + MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadDenseElementHoleResult( + ObjOperandId objId, Int32OperandId indexId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MInitializedLength::New(alloc(), elements); + add(length); + + bool needsHoleCheck = true; + auto* load = + MLoadElementHole::New(alloc(), elements, index, length, needsHoleCheck); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadDenseElementExistsResult( + ObjOperandId objId, Int32OperandId indexId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + // Get the elements vector. + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MInitializedLength::New(alloc(), elements); + add(length); + + // Check if id < initLength. + index = addBoundsCheck(index, length); + + // And check elem[id] is not a hole. + auto* guard = MGuardElementNotHole::New(alloc(), elements, index); + add(guard); + + pushResult(constant(BooleanValue(true))); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadTypedArrayElementExistsResult( + ObjOperandId objId, Int32OperandId indexId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + // Unsigned comparison to catch negative indices. + auto* ins = MCompare::New(alloc(), index, length, JSOp::Lt); + ins->setCompareType(MCompare::Compare_UInt32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadTypedArrayElementResult( + ObjOperandId objId, Int32OperandId indexId, Scalar::Type elementType, + bool handleOOB, bool allowDoubleForUint32) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + + if (handleOOB) { + auto* load = MLoadTypedArrayElementHole::New( + alloc(), obj, index, elementType, allowDoubleForUint32); + add(load); + + pushResult(load); + return true; + } + + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + index = addBoundsCheck(index, length); + + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); + + auto* load = MLoadUnboxedScalar::New(alloc(), elements, index, elementType); + load->setResultType( + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32)); + add(load); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadStringCharResult(StringOperandId strId, + Int32OperandId indexId) { + MDefinition* str = getOperand(strId); + MDefinition* index = getOperand(indexId); + + auto* length = MStringLength::New(alloc(), str); + add(length); + + index = addBoundsCheck(index, length); + + auto* charCode = MCharCodeAt::New(alloc(), str, index); + add(charCode); + + auto* fromCharCode = MFromCharCode::New(alloc(), charCode); + add(fromCharCode); + + pushResult(fromCharCode); + return true; +} + +bool WarpCacheIRTranspiler::emitLoadStringCharCodeResult( + StringOperandId strId, Int32OperandId indexId) { + MDefinition* str = getOperand(strId); + MDefinition* index = getOperand(indexId); + + auto* length = MStringLength::New(alloc(), str); + add(length); + + index = addBoundsCheck(index, length); + + auto* charCode = MCharCodeAt::New(alloc(), str, index); + add(charCode); + + pushResult(charCode); + return true; +} + +bool WarpCacheIRTranspiler::emitNewStringObjectResult( + uint32_t templateObjectOffset, StringOperandId strId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); + MDefinition* string = getOperand(strId); + + auto* obj = MNewStringObject::New(alloc(), string, templateObj); + addEffectful(obj); + + pushResult(obj); + return resumeAfter(obj); +} + +bool WarpCacheIRTranspiler::emitStringFromCharCodeResult( + Int32OperandId codeId) { + MDefinition* code = getOperand(codeId); + + auto* fromCharCode = MFromCharCode::New(alloc(), code); + add(fromCharCode); + + pushResult(fromCharCode); + return true; +} + +bool WarpCacheIRTranspiler::emitStringFromCodePointResult( + Int32OperandId codeId) { + MDefinition* code = getOperand(codeId); + + auto* fromCodePoint = MFromCodePoint::New(alloc(), code); + add(fromCodePoint); + + pushResult(fromCodePoint); + return true; +} + +bool WarpCacheIRTranspiler::emitStringToLowerCaseResult(StringOperandId strId) { + MDefinition* str = getOperand(strId); + + auto* convert = + MStringConvertCase::New(alloc(), str, MStringConvertCase::LowerCase); + add(convert); + + pushResult(convert); + return true; +} + +bool WarpCacheIRTranspiler::emitStringToUpperCaseResult(StringOperandId strId) { + MDefinition* str = getOperand(strId); + + auto* convert = + MStringConvertCase::New(alloc(), str, MStringConvertCase::UpperCase); + add(convert); + + pushResult(convert); + return true; +} + +bool WarpCacheIRTranspiler::emitStoreDynamicSlot(ObjOperandId objId, + uint32_t offsetOffset, + ValOperandId rhsId) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); + MDefinition* rhs = getOperand(rhsId); + + auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + add(barrier); + + auto* slots = MSlots::New(alloc(), obj); + add(slots); + + auto* store = MStoreDynamicSlot::NewBarriered(alloc(), slots, slotIndex, rhs); + addEffectful(store); + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitStoreFixedSlot(ObjOperandId objId, + uint32_t offsetOffset, + ValOperandId rhsId) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + size_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); + MDefinition* rhs = getOperand(rhsId); + + auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + add(barrier); + + auto* store = MStoreFixedSlot::NewBarriered(alloc(), obj, slotIndex, rhs); + addEffectful(store); + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitStoreFixedSlotUndefinedResult( + ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId) { + int32_t offset = int32StubField(offsetOffset); + + MDefinition* obj = getOperand(objId); + size_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); + MDefinition* rhs = getOperand(rhsId); + + auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + add(barrier); + + auto* store = MStoreFixedSlot::NewBarriered(alloc(), obj, slotIndex, rhs); + addEffectful(store); + + auto* undef = constant(UndefinedValue()); + pushResult(undef); + + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitAddAndStoreSlotShared( + MAddAndStoreSlot::Kind kind, ObjOperandId objId, uint32_t offsetOffset, + ValOperandId rhsId, uint32_t newShapeOffset) { + int32_t offset = int32StubField(offsetOffset); + Shape* shape = shapeStubField(newShapeOffset); + + MDefinition* obj = getOperand(objId); + MDefinition* rhs = getOperand(rhsId); + + auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + add(barrier); + + auto* addAndStore = + MAddAndStoreSlot::New(alloc(), obj, rhs, kind, offset, shape); + addEffectful(addAndStore); + + return resumeAfter(addAndStore); +} + +bool WarpCacheIRTranspiler::emitAddAndStoreFixedSlot( + ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, + bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset) { + MOZ_ASSERT(!changeGroup); + + return emitAddAndStoreSlotShared(MAddAndStoreSlot::Kind::FixedSlot, objId, + offsetOffset, rhsId, newShapeOffset); +} + +bool WarpCacheIRTranspiler::emitAddAndStoreDynamicSlot( + ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, + bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset) { + MOZ_ASSERT(!changeGroup); + + return emitAddAndStoreSlotShared(MAddAndStoreSlot::Kind::DynamicSlot, objId, + offsetOffset, rhsId, newShapeOffset); +} + +bool WarpCacheIRTranspiler::emitAllocateAndStoreDynamicSlot( + ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, + bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset, + uint32_t numNewSlotsOffset) { + MOZ_ASSERT(!changeGroup); + + int32_t offset = int32StubField(offsetOffset); + Shape* shape = shapeStubField(newShapeOffset); + uint32_t numNewSlots = uint32StubField(numNewSlotsOffset); + + MDefinition* obj = getOperand(objId); + MDefinition* rhs = getOperand(rhsId); + + auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + add(barrier); + + auto* allocateAndStore = + MAllocateAndStoreSlot::New(alloc(), obj, rhs, offset, shape, numNewSlots); + addEffectful(allocateAndStore); + + return resumeAfter(allocateAndStore); +} + +bool WarpCacheIRTranspiler::emitStoreDenseElement(ObjOperandId objId, + Int32OperandId indexId, + ValOperandId rhsId) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + MDefinition* rhs = getOperand(rhsId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* length = MInitializedLength::New(alloc(), elements); + add(length); + + index = addBoundsCheck(index, length); + + auto* barrier = MPostWriteElementBarrier::New(alloc(), obj, rhs, index); + add(barrier); + + bool needsHoleCheck = true; + auto* store = + MStoreElement::New(alloc(), elements, index, rhs, needsHoleCheck); + store->setNeedsBarrier(); + addEffectful(store); + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitStoreDenseElementHole(ObjOperandId objId, + Int32OperandId indexId, + ValOperandId rhsId, + bool handleAdd) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + MDefinition* rhs = getOperand(rhsId); + + auto* elements = MElements::New(alloc(), obj); + add(elements); + + auto* barrier = MPostWriteElementBarrier::New(alloc(), obj, rhs, index); + add(barrier); + + MInstruction* store; + MStoreElementCommon* common; + if (handleAdd) { + // TODO(post-Warp): Consider changing MStoreElementHole to match IC code. + auto* ins = MStoreElementHole::New(alloc(), obj, elements, index, rhs); + store = ins; + common = ins; + } else { + auto* length = MInitializedLength::New(alloc(), elements); + add(length); + + index = addBoundsCheck(index, length); + + bool needsHoleCheck = false; + auto* ins = + MStoreElement::New(alloc(), elements, index, rhs, needsHoleCheck); + store = ins; + common = ins; + } + common->setNeedsBarrier(); + addEffectful(store); + + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitStoreTypedArrayElement(ObjOperandId objId, + Scalar::Type elementType, + Int32OperandId indexId, + uint32_t rhsId, + bool handleOOB) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + MDefinition* rhs = getOperand(ValOperandId(rhsId)); + + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + if (!handleOOB) { + // MStoreTypedArrayElementHole does the bounds checking. + index = addBoundsCheck(index, length); + } + + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); + + MInstruction* store; + if (handleOOB) { + store = MStoreTypedArrayElementHole::New(alloc(), elements, length, index, + rhs, elementType); + } else { + store = + MStoreUnboxedScalar::New(alloc(), elements, index, rhs, elementType); + } + addEffectful(store); + return resumeAfter(store); +} + +void WarpCacheIRTranspiler::addDataViewData(MDefinition* obj, Scalar::Type type, + MDefinition** offset, + MInstruction** elements) { + MInstruction* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + // Adjust the length to account for accesses near the end of the dataview. + if (size_t byteSize = Scalar::byteSize(type); byteSize > 1) { + // To ensure |0 <= offset && offset + byteSize <= length|, we can either + // emit |BoundsCheck(offset, length)| followed by + // |BoundsCheck(offset + (byteSize - 1), length)|, or alternatively emit + // |BoundsCheck(offset, Max(length - (byteSize - 1), 0))|. The latter should + // result in faster code when LICM moves the length adjustment and also + // ensures Spectre index masking occurs after all bounds checks. + + auto* byteSizeMinusOne = MConstant::New(alloc(), Int32Value(byteSize - 1)); + add(byteSizeMinusOne); + + length = MSub::New(alloc(), length, byteSizeMinusOne, MIRType::Int32); + length->toSub()->setTruncateKind(MDefinition::Truncate); + add(length); + + // |length| mustn't be negative for MBoundsCheck. + auto* zero = MConstant::New(alloc(), Int32Value(0)); + add(zero); + + length = MMinMax::New(alloc(), length, zero, MIRType::Int32, true); + add(length); + } + + *offset = addBoundsCheck(*offset, length); + + *elements = MArrayBufferViewElements::New(alloc(), obj); + add(*elements); +} + +bool WarpCacheIRTranspiler::emitLoadDataViewValueResult( + ObjOperandId objId, Int32OperandId offsetId, + BooleanOperandId littleEndianId, Scalar::Type elementType, + bool allowDoubleForUint32) { + MDefinition* obj = getOperand(objId); + MDefinition* offset = getOperand(offsetId); + MDefinition* littleEndian = getOperand(littleEndianId); + + // Add bounds check and get the DataViewObject's elements. + MInstruction* elements; + addDataViewData(obj, elementType, &offset, &elements); + + // Load the element. + MInstruction* load; + if (Scalar::byteSize(elementType) == 1) { + load = MLoadUnboxedScalar::New(alloc(), elements, offset, elementType); + } else { + load = MLoadDataViewElement::New(alloc(), elements, offset, littleEndian, + elementType); + } + add(load); + + MIRType knownType = + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32); + load->setResultType(knownType); + + pushResult(load); + return true; +} + +bool WarpCacheIRTranspiler::emitStoreDataViewValueResult( + ObjOperandId objId, Int32OperandId offsetId, uint32_t valueId, + BooleanOperandId littleEndianId, Scalar::Type elementType) { + MDefinition* obj = getOperand(objId); + MDefinition* offset = getOperand(offsetId); + MDefinition* value = getOperand(ValOperandId(valueId)); + MDefinition* littleEndian = getOperand(littleEndianId); + + // Add bounds check and get the DataViewObject's elements. + MInstruction* elements; + addDataViewData(obj, elementType, &offset, &elements); + + // Store the element. + MInstruction* store; + if (Scalar::byteSize(elementType) == 1) { + store = + MStoreUnboxedScalar::New(alloc(), elements, offset, value, elementType); + } else { + store = MStoreDataViewElement::New(alloc(), elements, offset, value, + littleEndian, elementType); + } + addEffectful(store); + + pushResult(constant(UndefinedValue())); + + return resumeAfter(store); +} + +bool WarpCacheIRTranspiler::emitInt32IncResult(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constOne = MConstant::New(alloc(), Int32Value(1)); + add(constOne); + + auto* ins = MAdd::New(alloc(), input, constOne, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitDoubleIncResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constOne = MConstant::New(alloc(), DoubleValue(1.0)); + add(constOne); + + auto* ins = MAdd::New(alloc(), input, constOne, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitInt32DecResult(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constOne = MConstant::New(alloc(), Int32Value(1)); + add(constOne); + + auto* ins = MSub::New(alloc(), input, constOne, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitDoubleDecResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constOne = MConstant::New(alloc(), DoubleValue(1.0)); + add(constOne); + + auto* ins = MSub::New(alloc(), input, constOne, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitInt32NegationResult(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constNegOne = MConstant::New(alloc(), Int32Value(-1)); + add(constNegOne); + + auto* ins = MMul::New(alloc(), input, constNegOne, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitDoubleNegationResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* constNegOne = MConstant::New(alloc(), DoubleValue(-1.0)); + add(constNegOne); + + auto* ins = MMul::New(alloc(), input, constNegOne, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitInt32NotResult(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MBitNot::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + +template +bool WarpCacheIRTranspiler::emitDoubleBinaryArithResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = T::New(alloc(), lhs, rhs, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitDoubleAddResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitDoubleSubResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitDoubleMulResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitDoubleDivResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitDoubleModResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitDoublePowResult(NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitDoubleBinaryArithResult(lhsId, rhsId); +} + +template +bool WarpCacheIRTranspiler::emitInt32BinaryArithResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = T::New(alloc(), lhs, rhs, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitInt32AddResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32SubResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32MulResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32DivResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32ModResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32PowResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32BitOrResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32BitXorResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32BitAndResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32LeftShiftResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32RightShiftResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitInt32BinaryArithResult(lhsId, rhsId); +} + +bool WarpCacheIRTranspiler::emitInt32URightShiftResult(Int32OperandId lhsId, + Int32OperandId rhsId, + bool allowDouble) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + MIRType specialization = allowDouble ? MIRType::Double : MIRType::Int32; + auto* ins = MUrsh::New(alloc(), lhs, rhs, specialization); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitCallStringConcatResult(StringOperandId lhsId, + StringOperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = MConcat::New(alloc(), lhs, rhs); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitCompareResult( + JSOp op, OperandId lhsId, OperandId rhsId, + MCompare::CompareType compareType) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* ins = MCompare::New(alloc(), lhs, rhs, op); + ins->setCompareType(compareType); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitCompareInt32Result(JSOp op, + Int32OperandId lhsId, + Int32OperandId rhsId) { + return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Int32); +} + +bool WarpCacheIRTranspiler::emitCompareDoubleResult(JSOp op, + NumberOperandId lhsId, + NumberOperandId rhsId) { + return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Double); +} + +bool WarpCacheIRTranspiler::emitCompareObjectResult(JSOp op, ObjOperandId lhsId, + ObjOperandId rhsId) { + MOZ_ASSERT(IsEqualityOp(op)); + return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Object); +} + +bool WarpCacheIRTranspiler::emitCompareStringResult(JSOp op, + StringOperandId lhsId, + StringOperandId rhsId) { + return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_String); +} - if (handleOOB) { - bool allowDouble = true; - auto* load = MLoadTypedArrayElementHole::New(alloc(), obj, index, - elementType, allowDouble); - add(load); +bool WarpCacheIRTranspiler::emitCompareSymbolResult(JSOp op, + SymbolOperandId lhsId, + SymbolOperandId rhsId) { + MOZ_ASSERT(IsEqualityOp(op)); + return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Symbol); +} - pushResult(load); - return true; +bool WarpCacheIRTranspiler::emitCompareDoubleSameValueResult( + NumberOperandId lhsId, NumberOperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); + MDefinition* rhs = getOperand(rhsId); + + auto* sameValue = MSameValue::New(alloc(), lhs, rhs); + add(sameValue); + + pushResult(sameValue); + return true; +} + +bool WarpCacheIRTranspiler::emitMathHypot2NumberResult( + NumberOperandId firstId, NumberOperandId secondId) { + MDefinitionVector vector(alloc()); + if (!vector.reserve(2)) { + return false; } - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + vector.infallibleAppend(getOperand(firstId)); + vector.infallibleAppend(getOperand(secondId)); - index = addBoundsCheck(index, length); + auto* ins = MHypot::New(alloc(), vector); + if (!ins) { + return false; + } + add(ins); - auto* elements = MArrayBufferViewElements::New(alloc(), obj); - add(elements); + pushResult(ins); + return true; +} - auto* load = MLoadUnboxedScalar::New(alloc(), elements, index, elementType); - // TODO: Uint32 always loaded as double. - load->setResultType(MIRTypeForArrayBufferViewRead(elementType, true)); - add(load); +bool WarpCacheIRTranspiler::emitMathHypot3NumberResult( + NumberOperandId firstId, NumberOperandId secondId, + NumberOperandId thirdId) { + MDefinitionVector vector(alloc()); + if (!vector.reserve(3)) { + return false; + } - pushResult(load); + vector.infallibleAppend(getOperand(firstId)); + vector.infallibleAppend(getOperand(secondId)); + vector.infallibleAppend(getOperand(thirdId)); + + auto* ins = MHypot::New(alloc(), vector); + if (!ins) { + return false; + } + add(ins); + + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitLoadStringCharResult(StringOperandId strId, - Int32OperandId indexId) { - MDefinition* str = getOperand(strId); - MDefinition* index = getOperand(indexId); +bool WarpCacheIRTranspiler::emitMathHypot4NumberResult( + NumberOperandId firstId, NumberOperandId secondId, NumberOperandId thirdId, + NumberOperandId fourthId) { + MDefinitionVector vector(alloc()); + if (!vector.reserve(4)) { + return false; + } - auto* length = MStringLength::New(alloc(), str); - add(length); + vector.infallibleAppend(getOperand(firstId)); + vector.infallibleAppend(getOperand(secondId)); + vector.infallibleAppend(getOperand(thirdId)); + vector.infallibleAppend(getOperand(fourthId)); - index = addBoundsCheck(index, length); + auto* ins = MHypot::New(alloc(), vector); + if (!ins) { + return false; + } + add(ins); - auto* charCode = MCharCodeAt::New(alloc(), str, index); - add(charCode); + pushResult(ins); + return true; +} - auto* fromCharCode = MFromCharCode::New(alloc(), charCode); - add(fromCharCode); +bool WarpCacheIRTranspiler::emitMathRandomResult(uint32_t rngOffset) { +#ifdef DEBUG + // CodeGenerator uses CompileRealm::addressOfRandomNumberGenerator. Assert it + // matches the RNG pointer stored in the stub field. + const void* rng = rawPointerField(rngOffset); + MOZ_ASSERT(rng == mirGen().realm->addressOfRandomNumberGenerator()); +#endif - pushResult(fromCharCode); + auto* ins = MRandom::New(alloc()); + add(ins); + + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitLoadStringCharCodeResult( - StringOperandId strId, Int32OperandId indexId) { - MDefinition* str = getOperand(strId); - MDefinition* index = getOperand(indexId); +bool WarpCacheIRTranspiler::emitInt32MinMax(bool isMax, Int32OperandId firstId, + Int32OperandId secondId, + Int32OperandId resultId) { + MDefinition* first = getOperand(firstId); + MDefinition* second = getOperand(secondId); - auto* length = MStringLength::New(alloc(), str); - add(length); + auto* ins = MMinMax::New(alloc(), first, second, MIRType::Int32, isMax); + add(ins); - index = addBoundsCheck(index, length); + return defineOperand(resultId, ins); +} - auto* charCode = MCharCodeAt::New(alloc(), str, index); - add(charCode); +bool WarpCacheIRTranspiler::emitNumberMinMax(bool isMax, + NumberOperandId firstId, + NumberOperandId secondId, + NumberOperandId resultId) { + MDefinition* first = getOperand(firstId); + MDefinition* second = getOperand(secondId); - pushResult(charCode); + auto* ins = MMinMax::New(alloc(), first, second, MIRType::Double, isMax); + add(ins); + + return defineOperand(resultId, ins); +} + +bool WarpCacheIRTranspiler::emitMathAbsInt32Result(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MAbs::New(alloc(), input, MIRType::Int32); + add(ins); + + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitStringFromCharCodeResult( - Int32OperandId codeId) { - MDefinition* code = getOperand(codeId); +bool WarpCacheIRTranspiler::emitMathAbsNumberResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); - auto* fromCharCode = MFromCharCode::New(alloc(), code); - add(fromCharCode); + auto* ins = MAbs::New(alloc(), input, MIRType::Double); + add(ins); - pushResult(fromCharCode); + pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitStoreDynamicSlot(ObjOperandId objId, - uint32_t offsetOffset, - ValOperandId rhsId) { - int32_t offset = int32StubField(offsetOffset); +bool WarpCacheIRTranspiler::emitMathClz32Result(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); - MDefinition* obj = getOperand(objId); - size_t slotIndex = NativeObject::getDynamicSlotIndexFromOffset(offset); + auto* ins = MClz::New(alloc(), input, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathSignInt32Result(Int32OperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MSign::New(alloc(), input, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathSignNumberResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MSign::New(alloc(), input, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathSignNumberToInt32Result( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MSign::New(alloc(), input, MIRType::Int32); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathImulResult(Int32OperandId lhsId, + Int32OperandId rhsId) { + MDefinition* lhs = getOperand(lhsId); MDefinition* rhs = getOperand(rhsId); - auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); - add(barrier); + auto* ins = MMul::New(alloc(), lhs, rhs, MIRType::Int32, MMul::Integer); + add(ins); - auto* slots = MSlots::New(alloc(), obj); - add(slots); + pushResult(ins); + return true; +} - auto* store = MStoreDynamicSlot::NewBarriered(alloc(), slots, slotIndex, rhs); - addEffectful(store); - return resumeAfter(store); +bool WarpCacheIRTranspiler::emitMathFloorToInt32Result( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MFloor::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; } -bool WarpCacheIRTranspiler::emitStoreFixedSlot(ObjOperandId objId, - uint32_t offsetOffset, - ValOperandId rhsId) { - int32_t offset = int32StubField(offsetOffset); +bool WarpCacheIRTranspiler::emitMathCeilToInt32Result(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MCeil::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathTruncToInt32Result( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MTrunc::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathRoundToInt32Result( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MRound::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathSqrtNumberResult(NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MSqrt::New(alloc(), input, MIRType::Double); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathFRoundNumberResult( + NumberOperandId inputId) { + MDefinition* input = getOperand(inputId); + + auto* ins = MToFloat32::New(alloc(), input); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathAtan2NumberResult(NumberOperandId yId, + NumberOperandId xId) { + MDefinition* y = getOperand(yId); + MDefinition* x = getOperand(xId); + + auto* ins = MAtan2::New(alloc(), y, x); + add(ins); + + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitMathFunctionNumberResult( + NumberOperandId inputId, UnaryMathFunction fun) { + MDefinition* input = getOperand(inputId); + + auto* ins = MMathFunction::New(alloc(), input, fun); + add(ins); + pushResult(ins); + return true; +} + +bool WarpCacheIRTranspiler::emitReflectGetPrototypeOfResult( + ObjOperandId objId) { MDefinition* obj = getOperand(objId); - size_t slotIndex = NativeObject::getFixedSlotIndexFromOffset(offset); - MDefinition* rhs = getOperand(rhsId); - auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); - add(barrier); + auto* ins = MGetPrototypeOf::New(alloc(), obj); + addEffectful(ins); + pushResult(ins); - auto* store = MStoreFixedSlot::NewBarriered(alloc(), obj, slotIndex, rhs); - addEffectful(store); - return resumeAfter(store); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitStoreDenseElement(ObjOperandId objId, - Int32OperandId indexId, - ValOperandId rhsId) { +bool WarpCacheIRTranspiler::emitArrayPush(ObjOperandId objId, + ValOperandId rhsId) { MDefinition* obj = getOperand(objId); - MDefinition* index = getOperand(indexId); - MDefinition* rhs = getOperand(rhsId); + MDefinition* value = getOperand(rhsId); auto* elements = MElements::New(alloc(), obj); add(elements); - auto* length = MInitializedLength::New(alloc(), elements); - add(length); - - index = addBoundsCheck(index, length); + auto* initLength = MInitializedLength::New(alloc(), elements); + add(initLength); - auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs); + auto* barrier = + MPostWriteElementBarrier::New(alloc(), obj, value, initLength); add(barrier); - bool needsHoleCheck = true; - auto* store = - MStoreElement::New(alloc(), elements, index, rhs, needsHoleCheck); - store->setNeedsBarrier(); - addEffectful(store); - return resumeAfter(store); + auto* ins = MArrayPush::New(alloc(), obj, value); + addEffectful(ins); + pushResult(ins); + + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitStoreTypedArrayElement(ObjOperandId objId, - Scalar::Type elementType, - Int32OperandId indexId, - uint32_t rhsId, - bool handleOOB) { +bool WarpCacheIRTranspiler::emitArrayJoinResult(ObjOperandId objId, + StringOperandId sepId) { MDefinition* obj = getOperand(objId); - MDefinition* index = getOperand(indexId); - MDefinition* rhs = getOperand(ValOperandId(rhsId)); + MDefinition* sep = getOperand(sepId); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + // TODO(Warp): This flag only make sense for the Ion implementation. Remove it + // when IonBuilder is gone. + bool optimizeForArray = true; + auto* join = MArrayJoin::New(alloc(), obj, sep, optimizeForArray); + addEffectful(join); - if (!handleOOB) { - // MStoreTypedArrayElementHole does the bounds checking. - index = addBoundsCheck(index, length); - } + pushResult(join); + return resumeAfter(join); +} - auto* elements = MArrayBufferViewElements::New(alloc(), obj); - add(elements); +bool WarpCacheIRTranspiler::emitPackedArrayPopResult(ObjOperandId arrayId) { + MDefinition* array = getOperand(arrayId); - MInstruction* store; - if (handleOOB) { - store = MStoreTypedArrayElementHole::New(alloc(), elements, length, index, - rhs, elementType); - } else { - store = - MStoreUnboxedScalar::New(alloc(), elements, index, rhs, elementType); - } - addEffectful(store); - return resumeAfter(store); -} + // TODO(post-Warp): these flags only make sense for the Ion implementation. + // Remove them when IonBuilder is gone. + bool needsHoleCheck = true; + bool maybeUndefined = true; + auto* ins = MArrayPopShift::New(alloc(), array, MArrayPopShift::Pop, + needsHoleCheck, maybeUndefined); + addEffectful(ins); -bool WarpCacheIRTranspiler::emitInt32IncResult(Int32OperandId inputId) { - MDefinition* input = getOperand(inputId); + pushResult(ins); + return resumeAfter(ins); +} - auto* constOne = MConstant::New(alloc(), Int32Value(1)); - add(constOne); +bool WarpCacheIRTranspiler::emitPackedArrayShiftResult(ObjOperandId arrayId) { + MDefinition* array = getOperand(arrayId); - auto* ins = MAdd::New(alloc(), input, constOne, MIRType::Int32); - add(ins); + // TODO(post-Warp): these flags only make sense for the Ion implementation. + // Remove them when IonBuilder is gone. + bool needsHoleCheck = true; + bool maybeUndefined = true; + auto* ins = MArrayPopShift::New(alloc(), array, MArrayPopShift::Shift, + needsHoleCheck, maybeUndefined); + addEffectful(ins); pushResult(ins); - return true; + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitInt32DecResult(Int32OperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitPackedArraySliceResult( + uint32_t templateObjectOffset, ObjOperandId arrayId, Int32OperandId beginId, + Int32OperandId endId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); - auto* constOne = MConstant::New(alloc(), Int32Value(1)); - add(constOne); + MDefinition* array = getOperand(arrayId); + MDefinition* begin = getOperand(beginId); + MDefinition* end = getOperand(endId); - auto* ins = MSub::New(alloc(), input, constOne, MIRType::Int32); - add(ins); + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; + + auto* ins = MArraySlice::New(alloc(), array, begin, end, templateObj, heap); + addEffectful(ins); pushResult(ins); + return resumeAfter(ins); +} + +bool WarpCacheIRTranspiler::emitHasClassResult(ObjOperandId objId, + uint32_t claspOffset) { + MDefinition* obj = getOperand(objId); + const JSClass* clasp = classStubField(claspOffset); + + auto* hasClass = MHasClass::New(alloc(), obj, clasp); + add(hasClass); + + pushResult(hasClass); return true; } -bool WarpCacheIRTranspiler::emitInt32NegationResult(Int32OperandId inputId) { +bool WarpCacheIRTranspiler::emitCallRegExpMatcherResult( + ObjOperandId regexpId, StringOperandId inputId, + Int32OperandId lastIndexId) { + MDefinition* regexp = getOperand(regexpId); MDefinition* input = getOperand(inputId); + MDefinition* lastIndex = getOperand(lastIndexId); - auto* constNegOne = MConstant::New(alloc(), Int32Value(-1)); - add(constNegOne); + auto* matcher = MRegExpMatcher::New(alloc(), regexp, input, lastIndex); + addEffectful(matcher); + pushResult(matcher); - auto* ins = MMul::New(alloc(), input, constNegOne, MIRType::Int32); - add(ins); + return resumeAfter(matcher); +} - pushResult(ins); - return true; +bool WarpCacheIRTranspiler::emitCallRegExpSearcherResult( + ObjOperandId regexpId, StringOperandId inputId, + Int32OperandId lastIndexId) { + MDefinition* regexp = getOperand(regexpId); + MDefinition* input = getOperand(inputId); + MDefinition* lastIndex = getOperand(lastIndexId); + + auto* searcher = MRegExpSearcher::New(alloc(), regexp, input, lastIndex); + addEffectful(searcher); + pushResult(searcher); + + return resumeAfter(searcher); } -bool WarpCacheIRTranspiler::emitDoubleNegationResult(NumberOperandId inputId) { +bool WarpCacheIRTranspiler::emitCallRegExpTesterResult( + ObjOperandId regexpId, StringOperandId inputId, + Int32OperandId lastIndexId) { + MDefinition* regexp = getOperand(regexpId); MDefinition* input = getOperand(inputId); + MDefinition* lastIndex = getOperand(lastIndexId); - auto* constNegOne = MConstant::New(alloc(), DoubleValue(-1.0)); - add(constNegOne); + auto* tester = MRegExpTester::New(alloc(), regexp, input, lastIndex); + addEffectful(tester); + pushResult(tester); - auto* ins = MMul::New(alloc(), input, constNegOne, MIRType::Double); - add(ins); + return resumeAfter(tester); +} - pushResult(ins); +bool WarpCacheIRTranspiler::emitCallSubstringKernelResult( + StringOperandId strId, Int32OperandId beginId, Int32OperandId lengthId) { + MDefinition* str = getOperand(strId); + MDefinition* begin = getOperand(beginId); + MDefinition* length = getOperand(lengthId); + + auto* substr = MSubstr::New(alloc(), str, begin, length); + add(substr); + + pushResult(substr); return true; } -bool WarpCacheIRTranspiler::emitInt32NotResult(Int32OperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitStringReplaceStringResult( + StringOperandId strId, StringOperandId patternId, + StringOperandId replacementId) { + MDefinition* str = getOperand(strId); + MDefinition* pattern = getOperand(patternId); + MDefinition* replacement = getOperand(replacementId); - auto* ins = MBitNot::New(alloc(), input); - add(ins); + auto* replace = MStringReplace::New(alloc(), str, pattern, replacement); + add(replace); - pushResult(ins); + pushResult(replace); return true; } -template -bool WarpCacheIRTranspiler::emitDoubleBinaryArithResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - MDefinition* lhs = getOperand(lhsId); - MDefinition* rhs = getOperand(rhsId); +bool WarpCacheIRTranspiler::emitStringSplitStringResult( + StringOperandId strId, StringOperandId separatorId, uint32_t groupOffset) { + MDefinition* str = getOperand(strId); + MDefinition* separator = getOperand(separatorId); + ObjectGroup* group = groupStubField(groupOffset); - auto* ins = T::New(alloc(), lhs, rhs, MIRType::Double); - add(ins); + auto* split = MStringSplit::New(alloc(), /* constraints = */ nullptr, str, + separator, group); + add(split); - pushResult(ins); + pushResult(split); return true; } -bool WarpCacheIRTranspiler::emitDoubleAddResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); -} +bool WarpCacheIRTranspiler::emitRegExpPrototypeOptimizableResult( + ObjOperandId protoId) { + MDefinition* proto = getOperand(protoId); -bool WarpCacheIRTranspiler::emitDoubleSubResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); -} + auto* optimizable = MRegExpPrototypeOptimizable::New(alloc(), proto); + add(optimizable); -bool WarpCacheIRTranspiler::emitDoubleMulResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); + pushResult(optimizable); + return true; } -bool WarpCacheIRTranspiler::emitDoubleDivResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitRegExpInstanceOptimizableResult( + ObjOperandId regexpId, ObjOperandId protoId) { + MDefinition* regexp = getOperand(regexpId); + MDefinition* proto = getOperand(protoId); + + auto* optimizable = MRegExpInstanceOptimizable::New(alloc(), regexp, proto); + add(optimizable); + + pushResult(optimizable); + return true; } -bool WarpCacheIRTranspiler::emitDoubleModResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitGetFirstDollarIndexResult( + StringOperandId strId) { + MDefinition* str = getOperand(strId); + + auto* firstDollarIndex = MGetFirstDollarIndex::New(alloc(), str); + add(firstDollarIndex); + + pushResult(firstDollarIndex); + return true; } -bool WarpCacheIRTranspiler::emitDoublePowResult(NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitDoubleBinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitIsArrayResult(ValOperandId inputId) { + MDefinition* value = getOperand(inputId); + + auto* isArray = MIsArray::New(alloc(), value); + addEffectful(isArray); + pushResult(isArray); + + return resumeAfter(isArray); } -template -bool WarpCacheIRTranspiler::emitInt32BinaryArithResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - MDefinition* lhs = getOperand(lhsId); - MDefinition* rhs = getOperand(rhsId); +bool WarpCacheIRTranspiler::emitIsObjectResult(ValOperandId inputId) { + MDefinition* value = getOperand(inputId); - auto* ins = T::New(alloc(), lhs, rhs, MIRType::Int32); - add(ins); + if (value->type() == MIRType::Object) { + pushResult(constant(BooleanValue(true))); + } else { + auto* isObject = MIsObject::New(alloc(), value); + add(isObject); + pushResult(isObject); + } - pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitInt32AddResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitIsPackedArrayResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* isPackedArray = MIsPackedArray::New(alloc(), obj); + add(isPackedArray); + + pushResult(isPackedArray); + return true; } -bool WarpCacheIRTranspiler::emitInt32SubResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitIsCallableResult(ValOperandId inputId) { + MDefinition* value = getOperand(inputId); + + auto* isCallable = MIsCallable::New(alloc(), value); + add(isCallable); + + pushResult(isCallable); + return true; } -bool WarpCacheIRTranspiler::emitInt32MulResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); +bool WarpCacheIRTranspiler::emitIsConstructorResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* isConstructor = MIsConstructor::New(alloc(), obj); + add(isConstructor); + + pushResult(isConstructor); + return true; } -bool WarpCacheIRTranspiler::emitInt32DivResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} +bool WarpCacheIRTranspiler::emitIsCrossRealmArrayConstructorResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); -bool WarpCacheIRTranspiler::emitInt32ModResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} + auto* ins = MIsCrossRealmArrayConstructor::New(alloc(), obj); + add(ins); -bool WarpCacheIRTranspiler::emitInt32PowResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); + pushResult(ins); + return true; } -bool WarpCacheIRTranspiler::emitInt32BitOrResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} +bool WarpCacheIRTranspiler::emitIsTypedArrayResult(ObjOperandId objId, + bool isPossiblyWrapped) { + MDefinition* obj = getOperand(objId); -bool WarpCacheIRTranspiler::emitInt32BitXorResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} + auto* ins = MIsTypedArray::New(alloc(), obj, isPossiblyWrapped); + if (isPossiblyWrapped) { + addEffectful(ins); + } else { + add(ins); + } -bool WarpCacheIRTranspiler::emitInt32BitAndResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} + pushResult(ins); -bool WarpCacheIRTranspiler::emitInt32LeftShiftResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); -} + if (isPossiblyWrapped) { + if (!resumeAfter(ins)) { + return false; + } + } -bool WarpCacheIRTranspiler::emitInt32RightShiftResult(Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitInt32BinaryArithResult(lhsId, rhsId); + return true; } -bool WarpCacheIRTranspiler::emitInt32URightShiftResult(Int32OperandId lhsId, - Int32OperandId rhsId, - bool allowDouble) { - MDefinition* lhs = getOperand(lhsId); - MDefinition* rhs = getOperand(rhsId); +bool WarpCacheIRTranspiler::emitTypedArrayByteOffsetResult(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); - MIRType specialization = allowDouble ? MIRType::Double : MIRType::Int32; - auto* ins = MUrsh::New(alloc(), lhs, rhs, specialization); + auto* ins = MArrayBufferViewByteOffset::New(alloc(), obj); add(ins); pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitCallStringConcatResult(StringOperandId lhsId, - StringOperandId rhsId) { - MDefinition* lhs = getOperand(lhsId); - MDefinition* rhs = getOperand(rhsId); +bool WarpCacheIRTranspiler::emitTypedArrayElementShiftResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); - auto* ins = MConcat::New(alloc(), lhs, rhs); + auto* ins = MTypedArrayElementShift::New(alloc(), obj); add(ins); pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitCompareResult( - JSOp op, OperandId lhsId, OperandId rhsId, - MCompare::CompareType compareType) { - MDefinition* lhs = getOperand(lhsId); - MDefinition* rhs = getOperand(rhsId); +bool WarpCacheIRTranspiler::emitIsTypedArrayConstructorResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); - auto* ins = MCompare::New(alloc(), lhs, rhs, op); - ins->setCompareType(compareType); + auto* ins = MIsTypedArrayConstructor::New(alloc(), obj); add(ins); pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitCompareInt32Result(JSOp op, - Int32OperandId lhsId, - Int32OperandId rhsId) { - return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Int32); -} - -bool WarpCacheIRTranspiler::emitCompareDoubleResult(JSOp op, - NumberOperandId lhsId, - NumberOperandId rhsId) { - return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Double); -} +bool WarpCacheIRTranspiler::emitGetNextMapSetEntryForIteratorResult( + ObjOperandId iterId, ObjOperandId resultArrId, bool isMap) { + MDefinition* iter = getOperand(iterId); + MDefinition* resultArr = getOperand(resultArrId); -bool WarpCacheIRTranspiler::emitCompareObjectResult(JSOp op, ObjOperandId lhsId, - ObjOperandId rhsId) { - MOZ_ASSERT(IsEqualityOp(op)); - return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_Object); -} + MGetNextEntryForIterator::Mode mode = + isMap ? MGetNextEntryForIterator::Map : MGetNextEntryForIterator::Set; + auto* ins = MGetNextEntryForIterator::New(alloc(), iter, resultArr, mode); + addEffectful(ins); + pushResult(ins); -bool WarpCacheIRTranspiler::emitCompareStringResult(JSOp op, - StringOperandId lhsId, - StringOperandId rhsId) { - return emitCompareResult(op, lhsId, rhsId, MCompare::Compare_String); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitMathRandomResult(uint32_t rngOffset) { -#ifdef DEBUG - // CodeGenerator uses CompileRealm::addressOfRandomNumberGenerator. Assert it - // matches the RNG pointer stored in the stub field. - const void* rng = rawPointerField(rngOffset); - MOZ_ASSERT(rng == mirGen().realm->addressOfRandomNumberGenerator()); -#endif +bool WarpCacheIRTranspiler::emitFrameIsConstructingResult() { + if (const CallInfo* callInfo = builder_->inlineCallInfo()) { + auto* ins = constant(BooleanValue(callInfo->constructing())); + pushResult(ins); + return true; + } - auto* ins = MRandom::New(alloc()); + auto* ins = MIsConstructing::New(alloc()); add(ins); - pushResult(ins); return true; } -bool WarpCacheIRTranspiler::emitInt32MinMax(bool isMax, Int32OperandId firstId, - Int32OperandId secondId, - Int32OperandId resultId) { - MDefinition* first = getOperand(firstId); - MDefinition* second = getOperand(secondId); +bool WarpCacheIRTranspiler::emitFinishBoundFunctionInitResult( + ObjOperandId boundId, ObjOperandId targetId, Int32OperandId argCountId) { + MDefinition* bound = getOperand(boundId); + MDefinition* target = getOperand(targetId); + MDefinition* argCount = getOperand(argCountId); - auto* ins = MMinMax::New(alloc(), first, second, MIRType::Int32, isMax); - add(ins); + auto* ins = MFinishBoundFunctionInit::New(alloc(), bound, target, argCount); + addEffectful(ins); - return defineOperand(resultId, ins); + pushResult(constant(UndefinedValue())); + return resumeAfter(ins); } -bool WarpCacheIRTranspiler::emitNumberMinMax(bool isMax, - NumberOperandId firstId, - NumberOperandId secondId, - NumberOperandId resultId) { - MDefinition* first = getOperand(firstId); - MDefinition* second = getOperand(secondId); +bool WarpCacheIRTranspiler::emitNewIteratorResult( + MNewIterator::Type type, uint32_t templateObjectOffset) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); - auto* ins = MMinMax::New(alloc(), first, second, MIRType::Double, isMax); - add(ins); + auto* templateConst = constant(ObjectValue(*templateObj)); + auto* iter = MNewIterator::New(alloc(), /* constraints = */ nullptr, + templateConst, type); + add(iter); - return defineOperand(resultId, ins); + pushResult(iter); + return true; } -bool WarpCacheIRTranspiler::emitMathAbsInt32Result(Int32OperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitNewArrayIteratorResult( + uint32_t templateObjectOffset) { + return emitNewIteratorResult(MNewIterator::ArrayIterator, + templateObjectOffset); +} - auto* ins = MAbs::New(alloc(), input, MIRType::Int32); - add(ins); +bool WarpCacheIRTranspiler::emitNewStringIteratorResult( + uint32_t templateObjectOffset) { + return emitNewIteratorResult(MNewIterator::StringIterator, + templateObjectOffset); +} - pushResult(ins); - return true; +bool WarpCacheIRTranspiler::emitNewRegExpStringIteratorResult( + uint32_t templateObjectOffset) { + return emitNewIteratorResult(MNewIterator::RegExpStringIterator, + templateObjectOffset); } -bool WarpCacheIRTranspiler::emitMathAbsNumberResult(NumberOperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitObjectCreateResult( + uint32_t templateObjectOffset) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); - auto* ins = MAbs::New(alloc(), input, MIRType::Double); - add(ins); + auto* templateConst = constant(ObjectValue(*templateObj)); - pushResult(ins); - return true; + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; + auto* obj = MNewObject::New(alloc(), /* constraints = */ nullptr, + templateConst, heap, MNewObject::ObjectCreate); + addEffectful(obj); + + pushResult(obj); + return resumeAfter(obj); } -bool WarpCacheIRTranspiler::emitMathFloorToInt32Result( - NumberOperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitNewArrayFromLengthResult( + uint32_t templateObjectOffset, Int32OperandId lengthId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); + MDefinition* length = getOperand(lengthId); - auto* ins = MFloor::New(alloc(), input); - add(ins); + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; + + if (length->isConstant()) { + int32_t lenInt32 = length->toConstant()->toInt32(); + if (lenInt32 >= 0 && + uint32_t(lenInt32) == templateObj->as().length()) { + uint32_t len = uint32_t(lenInt32); + auto* templateConst = constant(ObjectValue(*templateObj)); + + size_t inlineLength = + gc::GetGCKindSlots(templateObj->asTenured().getAllocKind()) - + ObjectElements::VALUES_PER_HEADER; + + MNewArray* obj; + if (len > inlineLength) { + obj = MNewArray::NewVM(alloc(), /* constraints = */ nullptr, len, + templateConst, heap, loc_.toRawBytecode()); + } else { + obj = MNewArray::New(alloc(), /* constraints = */ nullptr, len, + templateConst, heap, loc_.toRawBytecode()); + } + add(obj); + pushResult(obj); + return true; + } + } - pushResult(ins); - return true; + auto* obj = MNewArrayDynamicLength::New(alloc(), /* constraints = */ nullptr, + templateObj, heap, length); + addEffectful(obj); + pushResult(obj); + return resumeAfter(obj); } -bool WarpCacheIRTranspiler::emitMathCeilToInt32Result(NumberOperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitNewTypedArrayFromLengthResult( + uint32_t templateObjectOffset, Int32OperandId lengthId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); + MDefinition* length = getOperand(lengthId); - auto* ins = MCeil::New(alloc(), input); - add(ins); + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; + + if (length->isConstant()) { + int32_t len = length->toConstant()->toInt32(); + if (len > 0 && + uint32_t(len) == templateObj->as().length()) { + auto* templateConst = constant(ObjectValue(*templateObj)); + auto* obj = MNewTypedArray::New(alloc(), /* constraints = */ nullptr, + templateConst, heap); + add(obj); + pushResult(obj); + return true; + } + } - pushResult(ins); - return true; + auto* obj = MNewTypedArrayDynamicLength::New( + alloc(), /* constraints = */ nullptr, templateObj, heap, length); + addEffectful(obj); + pushResult(obj); + return resumeAfter(obj); } -bool WarpCacheIRTranspiler::emitMathRoundToInt32Result( - NumberOperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitNewTypedArrayFromArrayBufferResult( + uint32_t templateObjectOffset, ObjOperandId bufferId, + ValOperandId byteOffsetId, ValOperandId lengthId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); + MDefinition* buffer = getOperand(bufferId); + MDefinition* byteOffset = getOperand(byteOffsetId); + MDefinition* length = getOperand(lengthId); - auto* ins = MRound::New(alloc(), input); - add(ins); + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; - pushResult(ins); - return true; + auto* obj = MNewTypedArrayFromArrayBuffer::New( + alloc(), /* constraints = */ nullptr, templateObj, heap, buffer, + byteOffset, length); + addEffectful(obj); + + pushResult(obj); + return resumeAfter(obj); } -bool WarpCacheIRTranspiler::emitMathSqrtNumberResult(NumberOperandId inputId) { - MDefinition* input = getOperand(inputId); +bool WarpCacheIRTranspiler::emitNewTypedArrayFromArrayResult( + uint32_t templateObjectOffset, ObjOperandId arrayId) { + JSObject* templateObj = tenuredObjectStubField(templateObjectOffset); + MDefinition* array = getOperand(arrayId); - auto* ins = MSqrt::New(alloc(), input, MIRType::Double); - add(ins); + // TODO: support pre-tenuring. + gc::InitialHeap heap = gc::DefaultHeap; - pushResult(ins); - return true; + auto* obj = MNewTypedArrayFromArray::New(alloc(), /* constraints = */ nullptr, + templateObj, heap, array); + addEffectful(obj); + + pushResult(obj); + return resumeAfter(obj); } -bool WarpCacheIRTranspiler::emitMathAtan2NumberResult(NumberOperandId yId, - NumberOperandId xId) { - MDefinition* y = getOperand(yId); - MDefinition* x = getOperand(xId); +bool WarpCacheIRTranspiler::emitAtomicsCompareExchangeResult( + ObjOperandId objId, Int32OperandId indexId, Int32OperandId expectedId, + Int32OperandId replacementId, Scalar::Type elementType) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + MDefinition* expected = getOperand(expectedId); + MDefinition* replacement = getOperand(replacementId); - auto* ins = MAtan2::New(alloc(), y, x); - add(ins); + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); - pushResult(ins); - return true; -} + index = addBoundsCheck(index, length); -bool WarpCacheIRTranspiler::emitMathFunctionNumberResult( - NumberOperandId inputId, UnaryMathFunction fun) { - MDefinition* input = getOperand(inputId); + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); - auto* ins = MMathFunction::New(alloc(), input, fun); - add(ins); + bool allowDoubleForUint32 = true; + MIRType knownType = + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32); - pushResult(ins); - return true; + auto* cas = MCompareExchangeTypedArrayElement::New( + alloc(), elements, index, elementType, expected, replacement); + cas->setResultType(knownType); + addEffectful(cas); + + pushResult(cas); + return resumeAfter(cas); } -bool WarpCacheIRTranspiler::emitArrayPush(ObjOperandId objId, - ValOperandId rhsId) { +bool WarpCacheIRTranspiler::emitAtomicsExchangeResult( + ObjOperandId objId, Int32OperandId indexId, Int32OperandId valueId, + Scalar::Type elementType) { MDefinition* obj = getOperand(objId); - MDefinition* value = getOperand(rhsId); + MDefinition* index = getOperand(indexId); + MDefinition* value = getOperand(valueId); - auto* elements = MElements::New(alloc(), obj); - add(elements); + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); - auto* initLength = MInitializedLength::New(alloc(), elements); - add(initLength); + index = addBoundsCheck(index, length); - auto* barrier = - MPostWriteElementBarrier::New(alloc(), obj, value, initLength); - add(barrier); + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); - auto* ins = MArrayPush::New(alloc(), obj, value); - addEffectful(ins); - pushResult(ins); + bool allowDoubleForUint32 = true; + MIRType knownType = + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32); - return resumeAfter(ins); + auto* exchange = MAtomicExchangeTypedArrayElement::New( + alloc(), elements, index, value, elementType); + exchange->setResultType(knownType); + addEffectful(exchange); + + pushResult(exchange); + return resumeAfter(exchange); } -bool WarpCacheIRTranspiler::emitHasClassResult(ObjOperandId objId, - uint32_t claspOffset) { +bool WarpCacheIRTranspiler::emitAtomicsBinaryOp(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType, + AtomicOp op) { MDefinition* obj = getOperand(objId); - const JSClass* clasp = classStubField(claspOffset); + MDefinition* index = getOperand(indexId); + MDefinition* value = getOperand(valueId); - auto* hasClass = MHasClass::New(alloc(), obj, clasp); - add(hasClass); + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); - pushResult(hasClass); - return true; -} + index = addBoundsCheck(index, length); -bool WarpCacheIRTranspiler::emitCallRegExpMatcherResult( - ObjOperandId regexpId, StringOperandId inputId, - Int32OperandId lastIndexId) { - MDefinition* regexp = getOperand(regexpId); - MDefinition* input = getOperand(inputId); - MDefinition* lastIndex = getOperand(lastIndexId); + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); - auto* matcher = MRegExpMatcher::New(alloc(), regexp, input, lastIndex); - addEffectful(matcher); - pushResult(matcher); + bool allowDoubleForUint32 = true; + MIRType knownType = + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32); - return resumeAfter(matcher); -} + auto* binop = MAtomicTypedArrayElementBinop::New(alloc(), op, elements, index, + elementType, value); + binop->setResultType(knownType); + addEffectful(binop); -bool WarpCacheIRTranspiler::emitCallRegExpSearcherResult( - ObjOperandId regexpId, StringOperandId inputId, - Int32OperandId lastIndexId) { - MDefinition* regexp = getOperand(regexpId); - MDefinition* input = getOperand(inputId); - MDefinition* lastIndex = getOperand(lastIndexId); + pushResult(binop); + return resumeAfter(binop); +} - auto* searcher = MRegExpSearcher::New(alloc(), regexp, input, lastIndex); - addEffectful(searcher); - pushResult(searcher); +bool WarpCacheIRTranspiler::emitAtomicsAddResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, + AtomicFetchAddOp); +} - return resumeAfter(searcher); +bool WarpCacheIRTranspiler::emitAtomicsSubResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, + AtomicFetchSubOp); } -bool WarpCacheIRTranspiler::emitCallRegExpTesterResult( - ObjOperandId regexpId, StringOperandId inputId, - Int32OperandId lastIndexId) { - MDefinition* regexp = getOperand(regexpId); - MDefinition* input = getOperand(inputId); - MDefinition* lastIndex = getOperand(lastIndexId); +bool WarpCacheIRTranspiler::emitAtomicsAndResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, + AtomicFetchAndOp); +} - auto* tester = MRegExpTester::New(alloc(), regexp, input, lastIndex); - addEffectful(tester); - pushResult(tester); +bool WarpCacheIRTranspiler::emitAtomicsOrResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, + AtomicFetchOrOp); +} - return resumeAfter(tester); +bool WarpCacheIRTranspiler::emitAtomicsXorResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, + AtomicFetchXorOp); } -bool WarpCacheIRTranspiler::emitCallSubstringKernelResult( - StringOperandId strId, Int32OperandId beginId, Int32OperandId lengthId) { - MDefinition* str = getOperand(strId); - MDefinition* begin = getOperand(beginId); - MDefinition* length = getOperand(lengthId); +bool WarpCacheIRTranspiler::emitAtomicsLoadResult(ObjOperandId objId, + Int32OperandId indexId, + Scalar::Type elementType) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); - auto* substr = MSubstr::New(alloc(), str, begin, length); - add(substr); + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); - pushResult(substr); - return true; -} + index = addBoundsCheck(index, length); -bool WarpCacheIRTranspiler::emitRegExpPrototypeOptimizableResult( - ObjOperandId protoId) { - MDefinition* proto = getOperand(protoId); + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); - auto* optimizable = MRegExpPrototypeOptimizable::New(alloc(), proto); - add(optimizable); + bool allowDoubleForUint32 = true; + MIRType knownType = + MIRTypeForArrayBufferViewRead(elementType, allowDoubleForUint32); - pushResult(optimizable); - return true; + auto* load = MLoadUnboxedScalar::New(alloc(), elements, index, elementType, + DoesRequireMemoryBarrier); + load->setResultType(knownType); + addEffectful(load); + + pushResult(load); + return resumeAfter(load); } -bool WarpCacheIRTranspiler::emitRegExpInstanceOptimizableResult( - ObjOperandId regexpId, ObjOperandId protoId) { - MDefinition* regexp = getOperand(regexpId); - MDefinition* proto = getOperand(protoId); +bool WarpCacheIRTranspiler::emitAtomicsStoreResult(ObjOperandId objId, + Int32OperandId indexId, + Int32OperandId valueId, + Scalar::Type elementType) { + MDefinition* obj = getOperand(objId); + MDefinition* index = getOperand(indexId); + MDefinition* value = getOperand(valueId); - auto* optimizable = MRegExpInstanceOptimizable::New(alloc(), regexp, proto); - add(optimizable); + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); - pushResult(optimizable); - return true; -} + index = addBoundsCheck(index, length); -bool WarpCacheIRTranspiler::emitIsArrayResult(ValOperandId inputId) { - MDefinition* value = getOperand(inputId); + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); - auto* isArray = MIsArray::New(alloc(), value); - addEffectful(isArray); - pushResult(isArray); + auto* store = MStoreUnboxedScalar::New(alloc(), elements, index, value, + elementType, DoesRequireMemoryBarrier); + addEffectful(store); - return resumeAfter(isArray); + pushResult(value); + return resumeAfter(store); } -bool WarpCacheIRTranspiler::emitIsObjectResult(ValOperandId inputId) { - MDefinition* value = getOperand(inputId); +bool WarpCacheIRTranspiler::emitAtomicsIsLockFreeResult( + Int32OperandId valueId) { + MDefinition* value = getOperand(valueId); - if (value->type() == MIRType::Object) { - pushResult(constant(BooleanValue(true))); - } else { - auto* isObject = MIsObject::New(alloc(), value); - add(isObject); - pushResult(isObject); - } + auto* ilf = MAtomicIsLockFree::New(alloc(), value); + add(ilf); + pushResult(ilf); return true; } -bool WarpCacheIRTranspiler::emitIsCallableResult(ValOperandId inputId) { - MDefinition* value = getOperand(inputId); +bool WarpCacheIRTranspiler::emitLoadValueTruthyResult(ValOperandId inputId) { + MDefinition* input = getOperand(inputId); - auto* isCallable = MIsCallable::New(alloc(), value); - add(isCallable); + // Convert to bool with the '!!' idiom. + auto* resultInverted = MNot::New(alloc(), input); + add(resultInverted); + auto* result = MNot::New(alloc(), resultInverted); + add(result); - pushResult(isCallable); + pushResult(result); return true; } -bool WarpCacheIRTranspiler::emitIsConstructorResult(ObjOperandId objId) { +bool WarpCacheIRTranspiler::emitLoadWrapperTarget(ObjOperandId objId, + ObjOperandId resultId) { MDefinition* obj = getOperand(objId); - auto* isConstructor = MIsConstructor::New(alloc(), obj); - add(isConstructor); + auto* ins = MLoadWrapperTarget::New(alloc(), obj); + add(ins); - pushResult(isConstructor); - return true; + return defineOperand(resultId, ins); } bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId, uint32_t slotIndex) { - // Reverse of GetIndexOfArgument specialized to !hasArgumentArray. - MOZ_ASSERT(!loc_.isSpreadOp()); + // Reverse of GetIndexOfArgument. // Layout: // NewTarget | Args.. (reversed) | ThisValue | Callee @@ -1472,102 +3277,252 @@ bool WarpCacheIRTranspiler::emitLoadArgumentDynamicSlot(ValOperandId resultId, return emitLoadArgumentSlot(resultId, callInfo_->argc() + slotIndex); } -bool WarpCacheIRTranspiler::emitCallFunction(ObjOperandId calleeId, - Int32OperandId argcId, - CallFlags flags, CallKind kind) { - MDefinition* callee = getOperand(calleeId); -#ifdef DEBUG - MDefinition* argc = getOperand(argcId); - MOZ_ASSERT(argc->toConstant()->toInt32() == - static_cast(callInfo_->argc())); -#endif - - // The transpilation will add various guards to the callee. - // We replace the callee referenced by the CallInfo, so that - // the resulting MCall instruction depends on these guards. - callInfo_->setCallee(callee); - - MOZ_ASSERT(flags.getArgFormat() == CallFlags::Standard || - flags.getArgFormat() == CallFlags::FunCall); +WrappedFunction* WarpCacheIRTranspiler::maybeWrappedFunction( + MDefinition* callee, CallKind kind, uint16_t nargs, FunctionFlags flags) { + MOZ_ASSERT(callee->isConstant() || callee->isNurseryObject()); - if (flags.getArgFormat() == CallFlags::FunCall) { - MOZ_ASSERT(!callInfo_->constructing()); - - // Note: setCallee above already changed the callee to the target - // function instead of the |call| function. - - if (callInfo_->argc() == 0) { - // Special case for fun.call() with no arguments. - auto* undef = constant(UndefinedValue()); - callInfo_->setThis(undef); - } else { - // The first argument for |call| is the new this value. - callInfo_->setThis(callInfo_->getArg(0)); + // If this is a native without a JitEntry, WrappedFunction needs to know the + // target JSFunction. + // TODO: support nursery-allocated natives with WrappedFunction, maybe by + // storing the JSNative in the Baseline stub like flags/nargs. + bool isNative = flags.isNativeWithoutJitEntry(); + if (isNative && !callee->isConstant()) { + return nullptr; + } - // Shift down all other arguments by removing the first. - callInfo_->removeArg(0); - } + JSFunction* nativeTarget = nullptr; + if (isNative) { + nativeTarget = &callee->toConstant()->toObject().as(); } + WrappedFunction* wrappedTarget = + new (alloc()) WrappedFunction(nativeTarget, nargs, flags); + MOZ_ASSERT_IF(kind == CallKind::Native, + wrappedTarget->isNativeWithoutJitEntry()); + MOZ_ASSERT_IF(kind == CallKind::Scripted, wrappedTarget->hasJitEntry()); + return wrappedTarget; +} + +WrappedFunction* WarpCacheIRTranspiler::maybeCallTarget(MDefinition* callee, + CallKind kind) { // CacheIR emits the following for specialized calls: // GuardSpecificFunction .. // Call(Native|Scripted)Function .. - // We can use the JSFunction object to specialize this call. - WrappedFunction* wrappedTarget = nullptr; + // or: + // GuardClass .. + // GuardFunctionScript + + + + + Mozilla Bug ???? + + + + + \ No newline at end of file diff --git a/js/xpconnect/tests/chrome/test_scripterror.html b/js/xpconnect/tests/chrome/test_scripterror.html new file mode 100644 index 0000000000..cdb10d9f24 --- /dev/null +++ b/js/xpconnect/tests/chrome/test_scripterror.html @@ -0,0 +1,89 @@ + + +Tests for nsIScriptError + +
+ diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xul b/js/xpconnect/tests/chrome/test_xrayToJS.xul index 3a65607043..f35032ba7f 100644 --- a/js/xpconnect/tests/chrome/test_xrayToJS.xul +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul @@ -80,8 +80,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 "we end up with the appropriate constructor: " + c); is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin[c](...args)).constructor), iwin[c], "constructor property is set up right: " + c); - let expectedProto = /Opaque/.test(new iwin[c](...args)) ? iwin['Object'].prototype - : iwin[c].prototype; + let expectedProto = Cu.isOpaqueWrapper(new iwin[c](...args)) ? + iwin['Object'].prototype : iwin[c].prototype; is(Object.getPrototypeOf(new iwin[c](...args)), expectedProto, "prototype is correct: " + c); is(global(new iwin[c](...args)), iwin, "Got the right global: " + c); @@ -150,8 +150,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 "we end up with the appropriate AggregateError constructor"); is(Cu.unwaiveXrays(Cu.waiveXrays(new iwin.AggregateError(...args)).constructor), iwin.AggregateError, "AggregateError constructor property is set up right"); - let expectedProto = /Opaque/.test(new iwin.AggregateError(...args)) ? iwin['Object'].prototype - : iwin.AggregateError.prototype; + let expectedProto = Cu.isOpaqueWrapper(new iwin.AggregateError(...args)) ? + iwin['Object'].prototype : iwin.AggregateError.prototype; is(Object.getPrototypeOf(new iwin.AggregateError(...args)), expectedProto, "AggregateError prototype is correct"); is(global(new iwin.AggregateError(...args)), iwin, "Got the right global for AggregateError"); @@ -284,7 +284,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 gConstructorProperties['ArrayBuffer'] = constructorProps(["isView", Symbol.species]); - is(typeof SharedArrayBuffer, "undefined", "Enable tests!"); + gPrototypeProperties['SharedArrayBuffer'] = ["constructor", "slice", "byteLength", Symbol.toStringTag]; + gConstructorProperties['SharedArrayBuffer'] = constructorProps([Symbol.species]); gPrototypeProperties['Map'] = ["constructor", "size", Symbol.toStringTag, "get", "has", "set", "delete", @@ -373,11 +374,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 is(method.call(xray) + "", local.call(xray) + "", "Xray and local method results stringify identically"); - // If invoking this method returns something non-Xrayable, the - // stringification is going to return [object Opaque]. + // If invoking this method returns something non-Xrayable (opaque), the + // stringification is going to return [object Object]. // This happens for set[@@iterator] and other Iterator objects. let callable = lookupCallable(xray.wrappedJSObject); - if (!/Opaque/.test(method.call(xray)) && callable) { + if (!Cu.isOpaqueWrapper(method.call(xray)) && callable) { is(method.call(xray) + "", callable.call(xray.wrappedJSObject) + "", "Xray and waived method results stringify identically"); diff --git a/js/xpconnect/tests/components/js/xpctest_params.js b/js/xpconnect/tests/components/js/xpctest_params.js index 4f1f8c9846..ad6a6238e5 100644 --- a/js/xpconnect/tests/components/js/xpctest_params.js +++ b/js/xpconnect/tests/components/js/xpctest_params.js @@ -88,6 +88,17 @@ TestParams.prototype = { arr.forEach((x) => rv += x); return rv; }, + testOmittedOptionalOut(o) { + if (typeof o != "object" || o.value !== undefined) { + throw new Components.Exception( + "unexpected value", + Cr.NS_ERROR_ILLEGAL_VALUE + ); + } + o.value = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService) + .newURI("http://example.com/"); + } }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestParams]); diff --git a/js/xpconnect/tests/components/native/xpctest_params.cpp b/js/xpconnect/tests/components/native/xpctest_params.cpp index 32b427d289..28986b363c 100644 --- a/js/xpconnect/tests/components/native/xpctest_params.cpp +++ b/js/xpconnect/tests/components/native/xpctest_params.cpp @@ -6,6 +6,10 @@ #include "xpctest_interfaces.h" #include "js/Value.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsIURI.h" + NS_IMPL_ISUPPORTS(nsXPCTestParams, nsIXPCTestParams) nsXPCTestParams::nsXPCTestParams() = default; @@ -367,3 +371,28 @@ nsXPCTestParams::TestOptionalSequence(const nsTArray& aInArr, aReturnArr = aInArr; return NS_OK; } + +NS_IMETHODIMP +nsXPCTestParams::TestOmittedOptionalOut(nsIURI** aOut) { + MOZ_ASSERT(!(*aOut), "Unexpected value received"); + // Call the js component, to check XPConnect won't crash when passing nullptr + // as the optional out parameter, and that the out object is built regardless. + nsresult rv; + nsCOMPtr jsComponent = + do_CreateInstance("@mozilla.org/js/xpc/test/js/Params;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + // Invoke it directly passing nullptr. + rv = jsComponent->TestOmittedOptionalOut(nullptr); + NS_ENSURE_SUCCESS(rv, rv); + // Also invoke it with a ref pointer. + nsCOMPtr someURI; + rv = jsComponent->TestOmittedOptionalOut(getter_AddRefs(someURI)); + NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString spec; + rv = someURI->GetSpec(spec); + if (!spec.EqualsLiteral("http://example.com/")) { + return NS_ERROR_UNEXPECTED; + } + someURI.forget(aOut); + return NS_OK; +} diff --git a/js/xpconnect/tests/idl/xpctest_params.idl b/js/xpconnect/tests/idl/xpctest_params.idl index 7f9cebfa5a..770f646b51 100644 --- a/js/xpconnect/tests/idl/xpctest_params.idl +++ b/js/xpconnect/tests/idl/xpctest_params.idl @@ -12,6 +12,7 @@ #include "nsISupports.idl" +interface nsIURI; interface nsIXPCTestInterfaceA; interface nsIXPCTestInterfaceB; @@ -108,4 +109,7 @@ interface nsIXPCTestParams : nsISupports { // Test for optional array size_is. ACString testStringArrayOptionalSize([array, size_is(aLength)] in string a, [optional] in unsigned long aLength); + + // Test for omitted optional out parameter. + void testOmittedOptionalOut([optional] out nsIURI aOut); }; diff --git a/js/xpconnect/tests/marionette/manifest.ini b/js/xpconnect/tests/marionette/manifest.ini index 52e4558e3a..d8c82c37da 100644 --- a/js/xpconnect/tests/marionette/manifest.ini +++ b/js/xpconnect/tests/marionette/manifest.ini @@ -1,6 +1,3 @@ -[test_loader_global_sharing.py] -skip-if = !manage_instance || appname == 'fennec' - [test_preloader_telemetry.py] skip-if = appname == 'fennec' diff --git a/js/xpconnect/tests/marionette/test_loader_global_sharing.py b/js/xpconnect/tests/marionette/test_loader_global_sharing.py deleted file mode 100644 index 7bf34f45bf..0000000000 --- a/js/xpconnect/tests/marionette/test_loader_global_sharing.py +++ /dev/null @@ -1,113 +0,0 @@ -from __future__ import print_function - -from marionette_harness import MarionetteTestCase - - -GLOBAL_SHARING_PREF = 'jsloader.shareGlobal' -GLOBAL_SHARING_VAR = 'MOZ_LOADER_SHARE_GLOBAL' - - -class TestLoaderGlobalSharing(MarionetteTestCase): - sandbox_name = 'loader-global-sharing' - - def execute_script(self, code, *args, **kwargs): - with self.marionette.using_context(self.marionette.CONTEXT_CHROME): - return self.marionette.execute_script(code, - new_sandbox=False, - sandbox=self.sandbox_name, - *args, **kwargs) - - def get_global_sharing_enabled(self): - return self.execute_script(r''' - Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - return (Cu.getGlobalForObject(Services) === - Cu.getGlobalForObject(XPCOMUtils)) - ''') - - def set_env(self, env, value): - self.execute_script('env.set(arguments[0], arguments[1]);', - script_args=(env, value)) - - def get_env(self, env): - return self.execute_script('return env.get(arguments[0]);', - script_args=(env,)) - - def restart(self, prefs=None, env=None): - if prefs: - self.marionette.set_prefs(prefs) - - if env: - for name, value in env.items(): - self.set_env(name, value) - - self.marionette.restart(in_app=True, clean=False) - self.setUpSession() - - # Sanity check our environment. - if prefs: - for key, val in prefs.items(): - self.assertEqual(self.marionette.get_pref(key), val) - if env: - for key, val in env.items(): - self.assertEqual(self.get_env(key), val or '') - - def setUpSession(self): - self.marionette.set_context(self.marionette.CONTEXT_CHROME) - - self.execute_script(r''' - const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = - Components; - - // We're running in a function, in a sandbox, that inherits from an - // X-ray wrapped window. Anything we want to be globally available - // needs to be defined on that window. - Object.assign(window, {Cc, Ci, Cu, Cr}); - - Cu.import("resource://gre/modules/Services.jsm"); - window.env = Cc["@mozilla.org/process/environment;1"] - .getService(Ci.nsIEnvironment); - ''') - - def setUp(self): - super(TestLoaderGlobalSharing, self).setUp() - - self.setUpSession() - - def tearDown(self): - self.marionette.restart(clean=True) - - super(TestLoaderGlobalSharing, self).tearDown() - - def test_global_sharing_settings(self): - # The different cases to test, with the first element being the value - # of the MOZ_LOADER_SHARE_GLOBAL environment variable, and the second - # being the value of the "jsloader.shareGlobal" preference. - # - # The browser is restarted after each change, but the profile is not - # reset. - CASES = ( - (None, False), - (None, True), - ('0', True), - ('1', True), - ('0', False), - ('1', False), - ) - - for var, pref in CASES: - print('Testing %s=%r %s=%r' % (GLOBAL_SHARING_VAR, var, - GLOBAL_SHARING_PREF, pref)) - - # The value of the environment variable takes precedence if it's - # defined. - expect_sharing = pref if var is None else var != '0' - - self.restart(prefs={GLOBAL_SHARING_PREF: pref}, - env={GLOBAL_SHARING_VAR: var}) - - have_sharing = self.get_global_sharing_enabled() - - self.assertEqual( - have_sharing, expect_sharing, - 'Global sharing state should match settings: %r != %r' - % (have_sharing, expect_sharing)) diff --git a/js/xpconnect/tests/mochitest/mochitest.ini b/js/xpconnect/tests/mochitest/mochitest.ini index 2a484500c6..8e019bb990 100644 --- a/js/xpconnect/tests/mochitest/mochitest.ini +++ b/js/xpconnect/tests/mochitest/mochitest.ini @@ -39,8 +39,10 @@ support-files = test1_bug629331.html test2_bug629331.html finalizationRegistry_worker.js + private_field_worker.js prefs = - javascript.options.experimental.weakrefs.enabled=true + javascript.options.weakrefs=true + javascript.options.experimental.private_fields=true [test_bug384632.html] [test_bug390488.html] @@ -116,11 +118,11 @@ skip-if = (debug == false) ../../../../dom/tests/mochitest/fetch/test_fetch_basic.js [test_weakmaps.html] [test_finalizationRegistry.html] -skip-if = !nightly_build [test_finalizationRegistryInWorker.html] -skip-if = !nightly_build [test_finalizationRegistry_cleanupSome.html] +[test_finalizationRegistry_incumbent.html] [test_weakRefs.html] -skip-if = !nightly_build [test_weakRefs_cross_compartment.html] -skip-if = !nightly_build +[test_weakRefs_collected_wrapper.html] +[test_private_field_dom.html] +[test_private_field_worker.html] \ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/private_field_worker.js b/js/xpconnect/tests/mochitest/private_field_worker.js new file mode 100644 index 0000000000..b62a8a9a60 --- /dev/null +++ b/js/xpconnect/tests/mochitest/private_field_worker.js @@ -0,0 +1,17 @@ +class A { + #x; +} + +let objects = []; + +self.onmessage = function(e) { + if (e.data === 'allocate') { + objects.push(new A); + return; + } + if (e.data == 'count') { + postMessage(objects.length); + return; + } + postMessage('Unknown message type.'); +} \ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html new file mode 100644 index 0000000000..8b6c71c9cf --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html @@ -0,0 +1,62 @@ + + + + + Test FinalizationRegistry tracks its incumbent global + + + + +
+ + +
+ + diff --git a/js/xpconnect/tests/mochitest/test_private_field_dom.html b/js/xpconnect/tests/mochitest/test_private_field_dom.html new file mode 100644 index 0000000000..f2911971bc --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_dom.html @@ -0,0 +1,216 @@ + + + + + + + Test for Bug ???? + + + + + + + Mozilla Bug 1094930 +

+
+ + + + + + + +
+ + +

+ + + + + + + + + +
+ + +
+
+ +
+ +
+ + +

+

+

+

+
+
+ + +
+ + + + + + + + + + + +
  • + + + + + + + + + + + + + +
      + + + +

      + + + +
      
      +    
      +    
      +    
      +    
      +    
      +    
      +    
      +    
      +    
      +    
      +    
      + + + + + + + + + + + + +
        + + +
        + + + + \ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_private_field_worker.html b/js/xpconnect/tests/mochitest/test_private_field_worker.html new file mode 100644 index 0000000000..68351000c5 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_private_field_worker.html @@ -0,0 +1,27 @@ + + + + + Test Private Fields + + + + + \ No newline at end of file diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html new file mode 100644 index 0000000000..c7af313d96 --- /dev/null +++ b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html @@ -0,0 +1,52 @@ + + + + + Test WeakRefs with DOM wrappers that get cycle collected + + + + + diff --git a/js/xpconnect/tests/unit/test_bug1033927.js b/js/xpconnect/tests/unit/test_bug1033927.js index 5ab2365716..cd2bb210e7 100644 --- a/js/xpconnect/tests/unit/test_bug1033927.js +++ b/js/xpconnect/tests/unit/test_bug1033927.js @@ -1,6 +1,7 @@ function run_test() { var sb = Cu.Sandbox('http://www.example.com', { wantGlobalProperties: ['XMLHttpRequest']}); var xhr = Cu.evalInSandbox('new XMLHttpRequest()', sb); + Assert.equal(xhr[Symbol.toStringTag], "XMLHttpRequest"); Assert.equal(xhr.toString(), '[object XMLHttpRequest]'); Assert.equal((new sb.Object()).toString(), '[object Object]'); Assert.equal(sb.Object.prototype.toString.call(new sb.Uint16Array()), '[object Uint16Array]'); diff --git a/js/xpconnect/tests/unit/test_params.js b/js/xpconnect/tests/unit/test_params.js index ede07e1612..84455cfb7c 100644 --- a/js/xpconnect/tests/unit/test_params.js +++ b/js/xpconnect/tests/unit/test_params.js @@ -16,6 +16,7 @@ function run_test() { function test_component(contractid) { // Instantiate the object. + info("Testing " + contractid); var o = Cc[contractid].createInstance(Ci["nsIXPCTestParams"]); // Possible comparator functions. @@ -228,4 +229,9 @@ function test_component(contractid) { ret = o.testOptionalSequence([1, 2, 3]); Assert.ok(Array.isArray(ret)); Assert.equal(ret.length, 3); + + o.testOmittedOptionalOut(); + ret = {}; + o.testOmittedOptionalOut(ret); + Assert.equal(ret.value.spec, "http://example.com/") } diff --git a/js/xpconnect/tests/unit/test_private_field_xrays.js b/js/xpconnect/tests/unit/test_private_field_xrays.js new file mode 100644 index 0000000000..c67652561c --- /dev/null +++ b/js/xpconnect/tests/unit/test_private_field_xrays.js @@ -0,0 +1,61 @@ +'use strict' + +ChromeUtils.import('resource://gre/modules/Preferences.jsm'); +const {Services} = ChromeUtils.import('resource://gre/modules/Services.jsm'); + +add_task(async function() { + let webnav = Services.appShell.createWindowlessBrowser(false); + + let docShell = webnav.docShell; + + docShell.createAboutBlankContentViewer(null, null); + + let window = webnav.document.defaultView; + let unwrapped = Cu.waiveXrays(window); + + class Base { + constructor(o) { + return o; + } + }; + + var A; + try { + A = eval(` + (function() { + class A extends Base { + #x = 12; + static gx(o) { + return o.#x; + } + + static sx(o, v) { + o.#x = v; + } + }; + return A})()`); + } catch (e) { + Assert.equal(e instanceof SyntaxError, true); + Assert.equal( + /private fields are not currently supported/.test(e.message), true); + // Early return if private fields aren't enabled. + return; + } + + new A(window); + Assert.equal(A.gx(window), 12); + A.sx(window, 'wrapped'); + + // Shouldn't tunnel past xray. + Assert.throws(() => A.gx(unwrapped), TypeError); + Assert.throws(() => A.sx(unwrapped, 'unwrapped'), TypeError); + + new A(unwrapped); + Assert.equal(A.gx(unwrapped), 12); + Assert.equal(A.gx(window), 'wrapped'); + + A.sx(window, 'modified'); + Assert.equal(A.gx(unwrapped), 12); + A.sx(unwrapped, 16); + Assert.equal(A.gx(window), 'modified'); +}); diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index e91c6cec84..f82f398285 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -144,6 +144,7 @@ head = head_watchdog.js [test_xrayed_iterator.js] [test_xray_instanceof.js] [test_xray_named_element_access.js] +[test_private_field_xrays.js] [test_xray_SavedFrame.js] [test_xray_SavedFrame-02.js] [test_xray_regexp.js] diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp index 30d7b142a3..c9db7243b9 100644 --- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -13,6 +13,7 @@ #include "FilteringWrapper.h" #include "jsfriendapi.h" +#include "js/Object.h" // JS::GetClass, JS::GetCompartment #include "mozilla/BasePrincipal.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingUtils.h" @@ -38,8 +39,8 @@ nsIPrincipal* GetObjectPrincipal(JSObject* obj) { } bool AccessCheck::subsumes(JSObject* a, JSObject* b) { - return CompartmentOriginInfo::Subsumes(js::GetObjectCompartment(a), - js::GetObjectCompartment(b)); + return CompartmentOriginInfo::Subsumes(JS::GetCompartment(a), + JS::GetCompartment(b)); } // Same as above, but considering document.domain. @@ -62,8 +63,8 @@ bool AccessCheck::subsumesConsideringDomainIgnoringFPD(JS::Realm* a, bool AccessCheck::wrapperSubsumes(JSObject* wrapper) { MOZ_ASSERT(js::IsWrapper(wrapper)); JSObject* wrapped = js::UncheckedUnwrap(wrapper); - return CompartmentOriginInfo::Subsumes(js::GetObjectCompartment(wrapper), - js::GetObjectCompartment(wrapped)); + return CompartmentOriginInfo::Subsumes(JS::GetCompartment(wrapper), + JS::GetCompartment(wrapped)); } bool AccessCheck::isChrome(JS::Compartment* compartment) { @@ -75,12 +76,12 @@ bool AccessCheck::isChrome(JS::Realm* realm) { } bool AccessCheck::isChrome(JSObject* obj) { - return isChrome(js::GetObjectCompartment(obj)); + return isChrome(JS::GetCompartment(obj)); } bool IsCrossOriginAccessibleObject(JSObject* obj) { obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false); - const JSClass* clasp = js::GetObjectClass(obj); + const JSClass* clasp = JS::GetClass(obj); return (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) || (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window")); @@ -103,8 +104,8 @@ bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, // references. Without this test, the child process wouldn't be able to // pass any objects at all to CPOWs. if (mozilla::jsipc::IsWrappedCPOW(obj) && - js::GetObjectCompartment(wrapper) == - js::GetObjectCompartment(xpc::UnprivilegedJunkScope()) && + JS::GetCompartment(wrapper) == + JS::GetCompartment(xpc::UnprivilegedJunkScope()) && XRE_IsParentProcess()) { return true; } diff --git a/js/xpconnect/wrappers/AccessCheck.h b/js/xpconnect/wrappers/AccessCheck.h index 391a74f960..966a239b59 100644 --- a/js/xpconnect/wrappers/AccessCheck.h +++ b/js/xpconnect/wrappers/AccessCheck.h @@ -9,6 +9,12 @@ #include "js/Wrapper.h" #include "nsString.h" +#ifdef XP_MACOSX +// AssertMacros.h defines 'check' which conflicts with the method declarations +// in this file. +# undef check +#endif + namespace xpc { class AccessCheck { diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index f7232b0194..6db2d4622c 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -14,7 +14,9 @@ #include "XPCMaps.h" #include "mozilla/dom/BindingUtils.h" #include "jsfriendapi.h" +#include "js/friend/WindowProxy.h" // js::IsWindow, js::IsWindowProxy #include "mozilla/jsipc/CrossProcessObjectWrappers.h" +#include "js/Object.h" // JS::GetPrivate, JS::GetCompartment #include "mozilla/Likely.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/MaybeCrossOriginObject.h" @@ -42,6 +44,11 @@ const Wrapper XrayWaiver(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG); // off it. const WaiveXrayWrapper WaiveXrayWrapper::singleton(0); +bool WrapperFactory::IsOpaqueWrapper(JSObject* obj) { + return IsWrapper(obj) && + Wrapper::wrapperHandler(obj) == &PermissiveXrayOpaque::singleton; +} + bool WrapperFactory::IsCOW(JSObject* obj) { return IsWrapper(obj) && Wrapper::wrapperHandler(obj) == &ChromeObjectWrapper::singleton; @@ -109,8 +116,8 @@ bool WrapperFactory::AllowWaiver(JS::Compartment* target, /* static */ bool WrapperFactory::AllowWaiver(JSObject* wrapper) { MOZ_ASSERT(js::IsCrossCompartmentWrapper(wrapper)); - return AllowWaiver(js::GetObjectCompartment(wrapper), - js::GetObjectCompartment(js::UncheckedUnwrap(wrapper))); + return AllowWaiver(JS::GetCompartment(wrapper), + JS::GetCompartment(js::UncheckedUnwrap(wrapper))); } inline bool ShouldWaiveXray(JSContext* cx, JSObject* originalObj) { @@ -133,7 +140,7 @@ inline bool ShouldWaiveXray(JSContext* cx, JSObject* originalObj) { // Otherwise, this is a case of explicitly passing a wrapper across a // compartment boundary. In that case, we only want to preserve waivers // in transactions between same-origin compartments. - JS::Compartment* oldCompartment = js::GetObjectCompartment(originalObj); + JS::Compartment* oldCompartment = JS::GetCompartment(originalObj); JS::Compartment* newCompartment = js::GetContextCompartment(cx); bool sameOrigin = false; if (OriginAttributes::IsRestrictOpenerAccessForFPI()) { @@ -209,8 +216,7 @@ void WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, // a separate compartment, then this object is explicitly requesting // that we don't create a second JS object for it: create a security // wrapper. - if (js::GetObjectCompartment(scope) != - js::GetObjectCompartment(wrapScope)) { + if (JS::GetCompartment(scope) != JS::GetCompartment(wrapScope)) { retObj.set(waive ? WaiveXray(cx, obj) : obj); return; } @@ -264,9 +270,9 @@ void WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, // This doesn't actually pose a security issue, because we'll still // compute the correct (opaque) wrapper for the object below given the // security characteristics of the two compartments. - if (!AccessCheck::isChrome(js::GetObjectCompartment(wrapScope)) && - CompartmentOriginInfo::Subsumes(js::GetObjectCompartment(wrapScope), - js::GetObjectCompartment(obj))) { + if (!AccessCheck::isChrome(JS::GetCompartment(wrapScope)) && + CompartmentOriginInfo::Subsumes(JS::GetCompartment(wrapScope), + JS::GetCompartment(obj))) { retObj.set(waive ? WaiveXray(cx, obj) : obj); return; } @@ -639,7 +645,7 @@ bool WrapperFactory::WaiveXrayAndWrap(JSContext* cx, // |cx|, we should check whether the caller has any business with waivers // to things in |obj|'s compartment. JS::Compartment* target = js::GetContextCompartment(cx); - JS::Compartment* origin = js::GetObjectCompartment(obj); + JS::Compartment* origin = JS::GetCompartment(obj); obj = AllowWaiver(target, origin) ? WaiveXray(cx, obj) : obj; if (!obj) { return false; @@ -677,8 +683,8 @@ static bool FixWaiverAfterTransplant(JSContext* cx, HandleObject oldWaiver, // CCW1 -----------> oldWaiver --> CCW2 --+ // newWaiver | // WindowProxy <--------------------------+ - js::NukeCrossCompartmentWrapperIfExists( - cx, js::GetObjectCompartment(newobj), oldWaiver); + js::NukeCrossCompartmentWrapperIfExists(cx, JS::GetCompartment(newobj), + oldWaiver); } else { // We kept the same object identity, so the waiver should be a // waiver for our object, just in the wrong Realm. @@ -778,13 +784,13 @@ nsIGlobalObject* NativeGlobal(JSObject* obj) { // Every global needs to hold a native as its private or be a // WebIDL object with an nsISupports DOM object. - MOZ_ASSERT((GetObjectClass(obj)->flags & + MOZ_ASSERT((JS::GetClass(obj)->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE)) || dom::UnwrapDOMObjectToISupports(obj)); nsISupports* native = dom::UnwrapDOMObjectToISupports(obj); if (!native) { - native = static_cast(js::GetObjectPrivate(obj)); + native = static_cast(JS::GetPrivate(obj)); MOZ_ASSERT(native); // In some cases (like for windows) it is a wrapped native, diff --git a/js/xpconnect/wrappers/WrapperFactory.h b/js/xpconnect/wrappers/WrapperFactory.h index ce4522ccf5..f11781b57a 100644 --- a/js/xpconnect/wrappers/WrapperFactory.h +++ b/js/xpconnect/wrappers/WrapperFactory.h @@ -65,6 +65,8 @@ class WrapperFactory { js::GetProxyHandler(obj) == &CrossOriginObjectWrapper::singleton); } + static bool IsOpaqueWrapper(JSObject* obj); + static bool HasWaiveXrayFlag(JSObject* wrapper) { return HasWrapperFlag(wrapper, WAIVE_XRAY_WRAPPER_FLAG); } diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 62f76d7dfa..24944ec28d 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -16,6 +16,10 @@ #include "xpcprivate.h" #include "jsapi.h" +#include "js/experimental/TypedData.h" // JS_GetTypedArrayLength +#include "js/friend/WindowProxy.h" // js::IsWindowProxy +#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo +#include "js/Object.h" // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot, JS::SetReservedSlot #include "js/PropertySpec.h" #include "nsJSUtils.h" #include "nsPrintfCString.h" @@ -702,7 +706,7 @@ bool JSXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, } // Grab the JSClass. We require all Xrayable classes to have a ClassSpec. - const JSClass* clasp = js::GetObjectClass(target); + const JSClass* clasp = JS::GetClass(target); MOZ_ASSERT(clasp->specDefined()); // Indexed array properties are handled above, so we can just work with the @@ -985,7 +989,7 @@ bool JSXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, } // Grab the JSClass. We require all Xrayable classes to have a ClassSpec. - const JSClass* clasp = js::GetObjectClass(target); + const JSClass* clasp = JS::GetClass(target); MOZ_ASSERT(clasp->specDefined()); return AppendNamesFromFunctionAndPropertySpecs( @@ -1085,15 +1089,15 @@ JSObject* JSXrayTraits::createHolder(JSContext* cx, JSObject* wrapper) { // Store it on the holder. RootedValue v(cx); v.setNumber(static_cast(key)); - js::SetReservedSlot(holder, SLOT_PROTOKEY, v); + JS::SetReservedSlot(holder, SLOT_PROTOKEY, v); v.setBoolean(isPrototype); - js::SetReservedSlot(holder, SLOT_ISPROTOTYPE, v); + JS::SetReservedSlot(holder, SLOT_ISPROTOTYPE, v); // If this is a function, also compute whether it serves as a constructor // for a standard class. if (key == JSProto_Function) { v.setNumber(static_cast(IdentifyStandardConstructor(target))); - js::SetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR, v); + JS::SetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR, v); } return holder; @@ -1136,7 +1140,7 @@ XrayTraits* GetXrayTraits(JSObject* obj) { // one such wrapper which can create or access the expando. This allows for // faster access to the expando, including through JIT inline caches. static inline bool CompartmentHasExclusiveExpandos(JSObject* obj) { - JS::Compartment* comp = js::GetObjectCompartment(obj); + JS::Compartment* comp = JS::GetCompartment(obj); CompartmentPrivate* priv = CompartmentPrivate::Get(comp); return priv && priv->hasExclusiveExpandos; } @@ -1151,13 +1155,13 @@ static nsIPrincipal* WrapperPrincipal(JSObject* obj) { // consumers are only interested in the origin-ignoring-document.domain. // See expandoObjectMatchesConsumer. MOZ_ASSERT(IsXrayWrapper(obj)); - JS::Compartment* comp = js::GetObjectCompartment(obj); + JS::Compartment* comp = JS::GetCompartment(obj); CompartmentPrivate* priv = CompartmentPrivate::Get(comp); return priv->originInfo.GetPrincipalIgnoringDocumentDomain(); } static nsIPrincipal* GetExpandoObjectPrincipal(JSObject* expandoObject) { - Value v = JS_GetReservedSlot(expandoObject, JSSLOT_EXPANDO_ORIGIN); + Value v = JS::GetReservedSlot(expandoObject, JSSLOT_EXPANDO_ORIGIN); return static_cast(v.toPrivate()); } @@ -1201,9 +1205,9 @@ bool XrayTraits::expandoObjectMatchesConsumer(JSContext* cx, // Certain globals exclusively own the associated expandos, in which case // the caller should have used the cached expando on the wrapper instead. - JSObject* owner = - JS_GetReservedSlot(expandoObject, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) - .toObjectOrNull(); + JSObject* owner = JS::GetReservedSlot(expandoObject, + JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) + .toObjectOrNull(); return owner == nullptr; } @@ -1227,7 +1231,7 @@ bool XrayTraits::getExpandoObjectInternal(JSContext* cx, JSObject* expandoChain, if (expandoObject) { JSObject* head = expandoChain; while (head && head != expandoObject) { - head = JS_GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); } MOZ_ASSERT(head == expandoObject); } @@ -1246,7 +1250,7 @@ bool XrayTraits::getExpandoObjectInternal(JSContext* cx, JSObject* expandoChain, expandoObject.set(head); return true; } - head = JS_GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); } // Not found. @@ -1408,8 +1412,9 @@ bool XrayTraits::cloneExpandoChain(JSContext* cx, HandleObject dst, RootedObject exclusiveWrapper(cx); RootedObject exclusiveWrapperGlobal(cx); RootedObject wrapperHolder( - cx, JS_GetReservedSlot(oldHead, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) - .toObjectOrNull()); + cx, + JS::GetReservedSlot(oldHead, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER) + .toObjectOrNull()); if (wrapperHolder) { RootedObject unwrappedHolder(cx, UncheckedUnwrap(wrapperHolder)); // unwrappedHolder is the compartment of the relevant Xray, so check @@ -1437,7 +1442,7 @@ bool XrayTraits::cloneExpandoChain(JSContext* cx, HandleObject dst, if (movingIntoXrayCompartment) { // Just copy properties directly onto dst. - if (!JS_CopyPropertiesFrom(cx, dst, oldHead)) { + if (!JS_CopyOwnPropertiesAndPrivateFields(cx, dst, oldHead)) { return false; } } else { @@ -1447,11 +1452,12 @@ bool XrayTraits::cloneExpandoChain(JSContext* cx, HandleObject dst, cx, attachExpandoObject(cx, dst, exclusiveWrapper, exclusiveWrapperGlobal, GetExpandoObjectPrincipal(oldHead))); - if (!JS_CopyPropertiesFrom(cx, newHead, oldHead)) { + if (!JS_CopyOwnPropertiesAndPrivateFields(cx, newHead, oldHead)) { return false; } } - oldHead = JS_GetReservedSlot(oldHead, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + oldHead = + JS::GetReservedSlot(oldHead, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); } return true; } @@ -1470,9 +1476,9 @@ void ClearXrayExpandoSlots(JSObject* target, size_t slotIndex) { RootedObject head(rootingCx, DOMXrayTraits::singleton.getExpandoChain(rootedTarget)); while (head) { - MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(head)) > slotIndex); - js::SetReservedSlot(head, slotIndex, UndefinedValue()); - head = js::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); + MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(head)) > slotIndex); + JS::SetReservedSlot(head, slotIndex, UndefinedValue()); + head = JS::GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull(); } } @@ -1516,14 +1522,13 @@ static inline JSObject* GetCachedXrayExpando(JSObject* wrapper) { if (!holder) { return nullptr; } - Value v = JS_GetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO); + Value v = JS::GetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO); return v.isObject() ? &v.toObject() : nullptr; } static inline void SetCachedXrayExpando(JSObject* holder, JSObject* expandoWrapper) { - MOZ_ASSERT(js::GetObjectCompartment(holder) == - js::GetObjectCompartment(expandoWrapper)); + MOZ_ASSERT(JS::GetCompartment(holder) == JS::GetCompartment(expandoWrapper)); JS_SetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO, ObjectValue(*expandoWrapper)); } @@ -1756,7 +1761,7 @@ bool DOMXrayTraits::call(JSContext* cx, HandleObject wrapper, const JS::CallArgs& args, const js::Wrapper& baseInstance) { RootedObject obj(cx, getTargetObject(wrapper)); - const JSClass* clasp = js::GetObjectClass(obj); + const JSClass* clasp = JS::GetClass(obj); // What we have is either a WebIDL interface object, a WebIDL prototype // object, or a WebIDL instance object. WebIDL prototype objects never have // a clasp->call. WebIDL interface objects we want to invoke on the xray @@ -1779,7 +1784,7 @@ bool DOMXrayTraits::construct(JSContext* cx, HandleObject wrapper, const js::Wrapper& baseInstance) { RootedObject obj(cx, getTargetObject(wrapper)); MOZ_ASSERT(mozilla::dom::HasConstructor(obj)); - const JSClass* clasp = js::GetObjectClass(obj); + const JSClass* clasp = JS::GetClass(obj); // See comments in DOMXrayTraits::call() explaining what's going on here. if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) { if (JSNative construct = clasp->getConstruct()) { @@ -2206,7 +2211,7 @@ bool XrayWrapper::getPrototype( RootedValue v(cx); { // Scope for JSAutoRealm JSAutoRealm ar(cx, expando); - v = JS_GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE); + v = JS::GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE); } if (!v.isUndefined()) { protop.set(v.toObjectOrNull()); @@ -2220,13 +2225,13 @@ bool XrayWrapper::getPrototype( return false; } - Value cached = js::GetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO); + Value cached = JS::GetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO); if (cached.isUndefined()) { if (!Traits::singleton.getPrototype(cx, wrapper, target, protop)) { return false; } - js::SetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO, + JS::SetReservedSlot(holder, Traits::HOLDER_SLOT_CACHED_PROTO, ObjectOrNullValue(protop)); } else { protop.set(cached.toObjectOrNull()); @@ -2341,7 +2346,7 @@ static bool IsCrossCompartmentXrayCallback( return handler == &PermissiveXrayDOM::singleton; } -js::XrayJitInfo gXrayJitInfo = { +JS::XrayJitInfo gXrayJitInfo = { IsCrossCompartmentXrayCallback, CompartmentHasExclusiveExpandos, JSSLOT_XRAY_HOLDER, XrayTraits::HOLDER_SLOT_EXPANDO, JSSLOT_EXPANDO_PROTOTYPE}; diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index 4f79458cf0..bd6df217eb 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -10,6 +10,8 @@ #include "WrapperFactory.h" #include "jsapi.h" +#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo +#include "js/Object.h" // JS::GetReservedSlot #include "js/Proxy.h" #include "js/Wrapper.h" @@ -258,16 +260,16 @@ class JSXrayTraits : public XrayTraits { virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override; static JSProtoKey getProtoKey(JSObject* holder) { - int32_t key = js::GetReservedSlot(holder, SLOT_PROTOKEY).toInt32(); + int32_t key = JS::GetReservedSlot(holder, SLOT_PROTOKEY).toInt32(); return static_cast(key); } static bool isPrototype(JSObject* holder) { - return js::GetReservedSlot(holder, SLOT_ISPROTOTYPE).toBoolean(); + return JS::GetReservedSlot(holder, SLOT_ISPROTOTYPE).toBoolean(); } static JSProtoKey constructorFor(JSObject* holder) { - int32_t key = js::GetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR).toInt32(); + int32_t key = JS::GetReservedSlot(holder, SLOT_CONSTRUCTOR_FOR).toInt32(); return static_cast(key); } @@ -479,7 +481,7 @@ void ClearXrayExpandoSlots(JSObject* target, size_t slotIndex); JSObject* EnsureXrayExpandoObject(JSContext* cx, JS::HandleObject wrapper); // Information about xrays for use by the JITs. -extern js::XrayJitInfo gXrayJitInfo; +extern JS::XrayJitInfo gXrayJitInfo; } // namespace xpc