summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/wasm
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/wasm
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/wasm')
-rw-r--r--Source/JavaScriptCore/wasm/JSWASMModule.cpp68
-rw-r--r--Source/JavaScriptCore/wasm/JSWASMModule.h118
-rw-r--r--Source/JavaScriptCore/wasm/WASMConstants.h329
-rw-r--r--Source/JavaScriptCore/wasm/WASMFormat.h98
-rw-r--r--Source/JavaScriptCore/wasm/WASMFunctionB3IRGenerator.h394
-rw-r--r--Source/JavaScriptCore/wasm/WASMFunctionCompiler.h1541
-rw-r--r--Source/JavaScriptCore/wasm/WASMFunctionParser.cpp1225
-rw-r--r--Source/JavaScriptCore/wasm/WASMFunctionParser.h148
-rw-r--r--Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h287
-rw-r--r--Source/JavaScriptCore/wasm/WASMModuleParser.cpp377
-rw-r--r--Source/JavaScriptCore/wasm/WASMModuleParser.h77
-rw-r--r--Source/JavaScriptCore/wasm/WASMReader.cpp249
-rw-r--r--Source/JavaScriptCore/wasm/WASMReader.h79
13 files changed, 0 insertions, 4990 deletions
diff --git a/Source/JavaScriptCore/wasm/JSWASMModule.cpp b/Source/JavaScriptCore/wasm/JSWASMModule.cpp
deleted file mode 100644
index c7ea4a6ed..000000000
--- a/Source/JavaScriptCore/wasm/JSWASMModule.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSWASMModule.h"
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "JSArrayBuffer.h"
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "JSFunction.h"
-#include "SlotVisitorInlines.h"
-
-namespace JSC {
-
-const ClassInfo JSWASMModule::s_info = { "WASMModule", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWASMModule) };
-
-JSWASMModule::JSWASMModule(VM& vm, Structure* structure, JSArrayBuffer* arrayBuffer)
- : Base(vm, structure)
-{
- if (arrayBuffer)
- m_arrayBuffer.set(vm, this, arrayBuffer);
-}
-
-void JSWASMModule::destroy(JSCell* cell)
-{
- JSWASMModule* thisObject = jsCast<JSWASMModule*>(cell);
- thisObject->JSWASMModule::~JSWASMModule();
-}
-
-void JSWASMModule::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- JSWASMModule* thisObject = jsCast<JSWASMModule*>(cell);
- ASSERT_GC_OBJECT_INHERITS(thisObject, info());
- Base::visitChildren(thisObject, visitor);
- visitor.append(&thisObject->m_arrayBuffer);
- for (auto function : thisObject->m_functions)
- visitor.append(&function);
- for (auto importedFunction : thisObject->m_importedFunctions)
- visitor.append(&importedFunction);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/JSWASMModule.h b/Source/JavaScriptCore/wasm/JSWASMModule.h
deleted file mode 100644
index 2d16791cc..000000000
--- a/Source/JavaScriptCore/wasm/JSWASMModule.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSWASMModule_h
-#define JSWASMModule_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "JSDestructibleObject.h"
-#include "WASMFormat.h"
-
-namespace JSC {
-
-class JSWASMModule : public JSDestructibleObject {
-public:
- typedef JSDestructibleObject Base;
-
- union GlobalVariable {
- GlobalVariable(int32_t value)
- : intValue(value)
- {
- }
- GlobalVariable(float value)
- : floatValue(value)
- {
- }
- GlobalVariable(double value)
- : doubleValue(value)
- {
- }
-
- int32_t intValue;
- float floatValue;
- double doubleValue;
- };
-
- static JSWASMModule* create(VM& vm, Structure* structure, JSArrayBuffer* arrayBuffer)
- {
- JSWASMModule* module = new (NotNull, allocateCell<JSWASMModule>(vm.heap)) JSWASMModule(vm, structure, arrayBuffer);
- module->finishCreation(vm);
- return module;
- }
-
- DECLARE_INFO;
-
- static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
- {
- return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info());
- }
-
- static void destroy(JSCell*);
- static void visitChildren(JSCell*, SlotVisitor&);
-
- Vector<uint32_t>& i32Constants() { return m_i32Constants; }
- Vector<float>& f32Constants() { return m_f32Constants; }
- Vector<double>& f64Constants() { return m_f64Constants; }
- Vector<WASMSignature>& signatures() { return m_signatures; }
- Vector<WASMFunctionImport>& functionImports() { return m_functionImports; }
- Vector<WASMFunctionImportSignature>& functionImportSignatures() { return m_functionImportSignatures; }
- Vector<WASMType>& globalVariableTypes() { return m_globalVariableTypes; }
- Vector<WASMFunctionDeclaration>& functionDeclarations() { return m_functionDeclarations; }
- Vector<WASMFunctionPointerTable>& functionPointerTables() { return m_functionPointerTables; }
-
- const JSArrayBuffer* arrayBuffer() const { return m_arrayBuffer.get(); }
- Vector<WriteBarrier<JSFunction>>& functions() { return m_functions; }
- Vector<unsigned>& functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; }
- Vector<unsigned>& functionStackHeights() { return m_functionStackHeights; }
- Vector<GlobalVariable>& globalVariables() { return m_globalVariables; }
- Vector<WriteBarrier<JSFunction>>& importedFunctions() { return m_importedFunctions; }
-
-private:
- JSWASMModule(VM&, Structure*, JSArrayBuffer*);
-
- Vector<uint32_t> m_i32Constants;
- Vector<float> m_f32Constants;
- Vector<double> m_f64Constants;
- Vector<WASMSignature> m_signatures;
- Vector<WASMFunctionImport> m_functionImports;
- Vector<WASMFunctionImportSignature> m_functionImportSignatures;
- Vector<WASMType> m_globalVariableTypes;
- Vector<WASMFunctionDeclaration> m_functionDeclarations;
- Vector<WASMFunctionPointerTable> m_functionPointerTables;
-
- WriteBarrier<JSArrayBuffer> m_arrayBuffer;
- Vector<WriteBarrier<JSFunction>> m_functions;
- Vector<unsigned> m_functionStartOffsetsInSource;
- Vector<unsigned> m_functionStackHeights;
- Vector<GlobalVariable> m_globalVariables;
- Vector<WriteBarrier<JSFunction>> m_importedFunctions;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // JSWASMModule_h
diff --git a/Source/JavaScriptCore/wasm/WASMConstants.h b/Source/JavaScriptCore/wasm/WASMConstants.h
deleted file mode 100644
index 4e3bd443f..000000000
--- a/Source/JavaScriptCore/wasm/WASMConstants.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * =========================================================================
- *
- * Copyright (c) 2015 by the repository authors of
- * WebAssembly/polyfill-prototype-1.
- *
- * 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.
- */
-
-#ifndef WASMConstants_h
-#define WASMConstants_h
-
-#if ENABLE(WEBASSEMBLY)
-
-namespace JSC {
-
-static const uint32_t wasmMagicNumber = 0x6d736177;
-
-enum class WASMOpKind {
- Statement,
- Expression
-};
-
-enum class WASMOpStatement : uint8_t {
- SetLocal,
- SetGlobal,
- I32Store8,
- I32StoreWithOffset8,
- I32Store16,
- I32StoreWithOffset16,
- I32Store32,
- I32StoreWithOffset32,
- F32Store,
- F32StoreWithOffset,
- F64Store,
- F64StoreWithOffset,
- CallInternal,
- CallIndirect,
- CallImport,
- Return,
- Block,
- If,
- IfElse,
- While,
- Do,
- Label,
- Break,
- BreakLabel,
- Continue,
- ContinueLabel,
- Switch,
- NumberOfWASMOpStatements
-};
-
-enum class WASMOpStatementWithImmediate : uint8_t {
- SetLocal,
- SetGlobal,
- NumberOfWASMOpStatementWithImmediates
-};
-
-enum class WASMOpExpressionI32 : uint8_t {
- ConstantPoolIndex,
- Immediate,
- GetLocal,
- GetGlobal,
- SetLocal,
- SetGlobal,
- SLoad8,
- SLoadWithOffset8,
- ULoad8,
- ULoadWithOffset8,
- SLoad16,
- SLoadWithOffset16,
- ULoad16,
- ULoadWithOffset16,
- Load32,
- LoadWithOffset32,
- Store8,
- StoreWithOffset8,
- Store16,
- StoreWithOffset16,
- Store32,
- StoreWithOffset32,
- CallInternal,
- CallIndirect,
- CallImport,
- Conditional,
- Comma,
- FromF32,
- FromF64,
- Negate,
- Add,
- Sub,
- Mul,
- SDiv,
- UDiv,
- SMod,
- UMod,
- BitNot,
- BitOr,
- BitAnd,
- BitXor,
- LeftShift,
- ArithmeticRightShift,
- LogicalRightShift,
- CountLeadingZeros,
- LogicalNot,
- EqualI32,
- EqualF32,
- EqualF64,
- NotEqualI32,
- NotEqualF32,
- NotEqualF64,
- SLessThanI32,
- ULessThanI32,
- LessThanF32,
- LessThanF64,
- SLessThanOrEqualI32,
- ULessThanOrEqualI32,
- LessThanOrEqualF32,
- LessThanOrEqualF64,
- SGreaterThanI32,
- UGreaterThanI32,
- GreaterThanF32,
- GreaterThanF64,
- SGreaterThanOrEqualI32,
- UGreaterThanOrEqualI32,
- GreaterThanOrEqualF32,
- GreaterThanOrEqualF64,
- SMin,
- UMin,
- SMax,
- UMax,
- Abs,
- NumberOfWASMOpExpressionI32s
-};
-
-enum class WASMOpExpressionI32WithImmediate : uint8_t {
- ConstantPoolIndex,
- Immediate,
- GetLocal,
- NumberOfWASMOpExpressionI32WithImmediates
-};
-
-enum class WASMOpExpressionF32 : uint8_t {
- ConstantPoolIndex,
- Immediate,
- GetLocal,
- GetGlobal,
- SetLocal,
- SetGlobal,
- Load,
- LoadWithOffset,
- Store,
- StoreWithOffset,
- CallInternal,
- CallIndirect,
- Conditional,
- Comma,
- FromS32,
- FromU32,
- FromF64,
- Negate,
- Add,
- Sub,
- Mul,
- Div,
- Abs,
- Ceil,
- Floor,
- Sqrt,
- NumberOfWASMOpExpressionF32s
-};
-
-enum class WASMOpExpressionF32WithImmediate : uint8_t {
- ConstantPoolIndex,
- GetLocal,
- NumberOfWASMOpExpressionF32WithImmediates
-};
-
-enum class WASMOpExpressionF64 : uint8_t {
- ConstantPoolIndex,
- Immediate,
- GetLocal,
- GetGlobal,
- SetLocal,
- SetGlobal,
- Load,
- LoadWithOffset,
- Store,
- StoreWithOffset,
- CallInternal,
- CallIndirect,
- CallImport,
- Conditional,
- Comma,
- FromS32,
- FromU32,
- FromF32,
- Negate,
- Add,
- Sub,
- Mul,
- Div,
- Mod,
- Min,
- Max,
- Abs,
- Ceil,
- Floor,
- Sqrt,
- Cos,
- Sin,
- Tan,
- ACos,
- ASin,
- ATan,
- ATan2,
- Exp,
- Ln,
- Pow,
- NumberOfWASMOpExpressionF64s
-};
-
-enum class WASMOpExpressionF64WithImmediate : uint8_t {
- ConstantPoolIndex,
- GetLocal,
- NumberOfWASMOpExpressionF64WithImmediates
-};
-
-enum class WASMOpExpressionVoid : uint8_t {
- CallInternal,
- CallIndirect,
- CallImport,
- NumberOfWASMOpExpressionVoids
-};
-
-enum class WASMVariableTypes : uint8_t {
- I32 = 1 << 0,
- F32 = 1 << 1,
- F64 = 1 << 2,
- NumberOfVariableTypes = 8
-};
-
-enum class WASMVariableTypesWithImmediate : uint8_t {
- I32,
- NumberOfVariableTypesWithImmediates
-};
-
-enum class WASMSwitchCase : uint8_t {
- CaseWithNoStatements,
- CaseWithStatement,
- CaseWithBlockStatement,
- DefaultWithNoStatements,
- DefaultWithStatement,
- DefaultWithBlockStatement,
- NumberOfSwitchCases
-};
-
-enum class WASMExportFormat : uint8_t {
- Default,
- Record,
- NumberOfExportFormats
-};
-
-enum class WASMTypeConversion {
- ConvertSigned,
- ConvertUnsigned,
- Promote,
- Demote,
-};
-
-enum class WASMMemoryType {
- I8,
- I16,
- I32,
- F32,
- F64
-};
-
-enum class MemoryAccessOffsetMode { NoOffset, WithOffset };
-enum class MemoryAccessConversion { NoConversion, SignExtend, ZeroExtend };
-
-static const uint8_t hasImmediateInOpFlag = 0x80;
-
-static const unsigned opWithImmediateBits = 2;
-static const uint32_t opWithImmediateLimit = 1 << opWithImmediateBits;
-
-static const unsigned immediateBits = 5;
-static const uint32_t immediateLimit = 1 << immediateBits;
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMConstants_h
diff --git a/Source/JavaScriptCore/wasm/WASMFormat.h b/Source/JavaScriptCore/wasm/WASMFormat.h
deleted file mode 100644
index b36341056..000000000
--- a/Source/JavaScriptCore/wasm/WASMFormat.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * =========================================================================
- *
- * Copyright (c) 2015 by the repository authors of
- * WebAssembly/polyfill-prototype-1.
- *
- * 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.
- */
-
-#ifndef WASMFormat_h
-#define WASMFormat_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
-class JSFunction;
-
-enum class WASMType : uint8_t {
- I32,
- F32,
- F64,
- NumberOfTypes
-};
-
-enum class WASMExpressionType : uint8_t {
- I32,
- F32,
- F64,
- Void,
- NumberOfExpressionTypes
-};
-
-struct WASMSignature {
- WASMExpressionType returnType;
- Vector<WASMType> arguments;
-};
-
-struct WASMFunctionImport {
- String functionName;
-};
-
-struct WASMFunctionImportSignature {
- uint32_t signatureIndex;
- uint32_t functionImportIndex;
-};
-
-struct WASMFunctionDeclaration {
- uint32_t signatureIndex;
-};
-
-struct WASMFunctionPointerTable {
- uint32_t signatureIndex;
- Vector<uint32_t> functionIndices;
- Vector<JSFunction*> functions;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMFormat_h
diff --git a/Source/JavaScriptCore/wasm/WASMFunctionB3IRGenerator.h b/Source/JavaScriptCore/wasm/WASMFunctionB3IRGenerator.h
deleted file mode 100644
index 7813a23da..000000000
--- a/Source/JavaScriptCore/wasm/WASMFunctionB3IRGenerator.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMFunctionB3IRGenerator_h
-#define WASMFunctionB3IRGenerator_h
-
-#if ENABLE(WEBASSEMBLY) && ENABLE(FTL_JIT)
-
-#include "FTLAbbreviatedTypes.h"
-
-#define UNUSED 0
-
-namespace JSC {
-
-using FTL::LBasicBlock;
-using FTL::LValue;
-
-class WASMFunctionB3IRGenerator {
-public:
- typedef LValue Expression;
- typedef int Statement;
- typedef Vector<LValue> ExpressionList;
- struct MemoryAddress {
- MemoryAddress(void*) { }
- MemoryAddress(LValue index, uint32_t offset)
- : index(index)
- , offset(offset)
- {
- }
- LValue index;
- uint32_t offset;
- };
- typedef LBasicBlock JumpTarget;
- enum class JumpCondition { Zero, NonZero };
-
- void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(arguments);
- UNUSED_PARAM(numberOfI32LocalVariables);
- UNUSED_PARAM(numberOfF32LocalVariables);
- UNUSED_PARAM(numberOfF64LocalVariables);
- }
-
- void endFunction()
- {
- // FIXME: Implement this method.
- }
-
- LValue buildSetLocal(WASMOpKind opKind, uint32_t localIndex, LValue value, WASMType type)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(opKind);
- UNUSED_PARAM(localIndex);
- UNUSED_PARAM(value);
- UNUSED_PARAM(type);
- return UNUSED;
- }
-
- LValue buildSetGlobal(WASMOpKind opKind, uint32_t globalIndex, LValue value, WASMType type)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(opKind);
- UNUSED_PARAM(globalIndex);
- UNUSED_PARAM(value);
- UNUSED_PARAM(type);
- return UNUSED;
- }
-
- void buildReturn(LValue value, WASMExpressionType returnType)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(returnType);
- }
-
- LValue buildImmediateI32(uint32_t immediate)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(immediate);
- return UNUSED;
- }
-
- LValue buildImmediateF32(float immediate)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(immediate);
- return UNUSED;
- }
-
- LValue buildImmediateF64(double immediate)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(immediate);
- return UNUSED;
- }
-
- LValue buildGetLocal(uint32_t localIndex, WASMType type)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(localIndex);
- UNUSED_PARAM(type);
- return UNUSED;
- }
-
- LValue buildGetGlobal(uint32_t globalIndex, WASMType type)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(globalIndex);
- UNUSED_PARAM(type);
- return UNUSED;
- }
-
- LValue buildConvertType(LValue value, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion conversion)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(fromType);
- UNUSED_PARAM(toType);
- UNUSED_PARAM(conversion);
- return UNUSED;
- }
-
- LValue buildLoad(const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessConversion conversion)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(memoryAddress);
- UNUSED_PARAM(expressionType);
- UNUSED_PARAM(memoryType);
- UNUSED_PARAM(conversion);
- return UNUSED;
- }
-
- LValue buildStore(WASMOpKind opKind, const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, LValue value)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(opKind);
- UNUSED_PARAM(memoryAddress);
- UNUSED_PARAM(expressionType);
- UNUSED_PARAM(memoryType);
- UNUSED_PARAM(value);
- return UNUSED;
- }
-
- LValue buildUnaryI32(LValue value, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildUnaryF32(LValue value, WASMOpExpressionF32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildUnaryF64(LValue value, WASMOpExpressionF64 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildBinaryI32(LValue left, LValue right, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildBinaryF32(LValue left, LValue right, WASMOpExpressionF32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildBinaryF64(LValue left, LValue right, WASMOpExpressionF64 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildRelationalI32(LValue left, LValue right, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildRelationalF32(LValue left, LValue right, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildRelationalF64(LValue left, LValue right, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildMinOrMaxI32(LValue left, LValue right, WASMOpExpressionI32 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildMinOrMaxF64(LValue left, LValue right, WASMOpExpressionF64 op)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(left);
- UNUSED_PARAM(right);
- UNUSED_PARAM(op);
- return UNUSED;
- }
-
- LValue buildCallInternal(uint32_t functionIndex, const Vector<LValue>& argumentList, const WASMSignature& signature, WASMExpressionType returnType)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(functionIndex);
- UNUSED_PARAM(argumentList);
- UNUSED_PARAM(signature);
- UNUSED_PARAM(returnType);
- return UNUSED;
- }
-
- LValue buildCallIndirect(uint32_t functionPointerTableIndex, LValue index, const Vector<LValue>& argumentList, const WASMSignature& signature, WASMExpressionType returnType)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(functionPointerTableIndex);
- UNUSED_PARAM(index);
- UNUSED_PARAM(argumentList);
- UNUSED_PARAM(signature);
- UNUSED_PARAM(returnType);
- return UNUSED;
- }
-
- LValue buildCallImport(uint32_t functionImportIndex, const Vector<LValue>& argumentList, const WASMSignature& signature, WASMExpressionType returnType)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(functionImportIndex);
- UNUSED_PARAM(argumentList);
- UNUSED_PARAM(signature);
- UNUSED_PARAM(returnType);
- return UNUSED;
- }
-
- void appendExpressionList(Vector<LValue>& expressionList, LValue value)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(expressionList);
- UNUSED_PARAM(value);
- }
-
- void discard(LValue)
- {
- }
-
- void linkTarget(LBasicBlock target)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(target);
- }
-
- void jumpToTarget(LBasicBlock target)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(target);
- }
-
- void jumpToTargetIf(JumpCondition, LValue value, LBasicBlock target)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(target);
- }
-
- void startLoop()
- {
- // FIXME: Implement this method.
- }
-
- void endLoop()
- {
- // FIXME: Implement this method.
- }
-
- void startSwitch()
- {
- // FIXME: Implement this method.
- }
-
- void endSwitch()
- {
- // FIXME: Implement this method.
- }
-
- void startLabel()
- {
- // FIXME: Implement this method.
- }
-
- void endLabel()
- {
- // FIXME: Implement this method.
- }
-
- LBasicBlock breakTarget()
- {
- // FIXME: Implement this method.
- return UNUSED;
- }
-
- LBasicBlock continueTarget()
- {
- // FIXME: Implement this method.
- return UNUSED;
- }
-
- LBasicBlock breakLabelTarget(uint32_t labelIndex)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(labelIndex);
- return UNUSED;
- }
-
- LBasicBlock continueLabelTarget(uint32_t labelIndex)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(labelIndex);
- return UNUSED;
- }
-
- void buildSwitch(LValue value, const Vector<int64_t>& cases, const Vector<LBasicBlock>& targets, LBasicBlock defaultTarget)
- {
- // FIXME: Implement this method.
- UNUSED_PARAM(value);
- UNUSED_PARAM(cases);
- UNUSED_PARAM(targets);
- UNUSED_PARAM(defaultTarget);
- }
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMFunctionB3IRGenerator_h
diff --git a/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h b/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
deleted file mode 100644
index de439ba07..000000000
--- a/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
+++ /dev/null
@@ -1,1541 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMFunctionCompiler_h
-#define WASMFunctionCompiler_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "BinarySwitch.h"
-#include "CCallHelpers.h"
-#include "JIT.h"
-#include "JITOperations.h"
-#include "JSArrayBuffer.h"
-#include "LinkBuffer.h"
-#include "MaxFrameExtentForSlowPathCall.h"
-
-#define UNUSED 0
-
-namespace JSC {
-
-static int32_t JIT_OPERATION operationConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
-{
- return JSValue::decode(value).toInt32(exec);
-}
-
-static double JIT_OPERATION operationConvertJSValueToDouble(ExecState* exec, EncodedJSValue value)
-{
- return JSValue::decode(value).toNumber(exec);
-}
-
-#if !CPU(X86) && !CPU(X86_64)
-static int32_t JIT_OPERATION operationDiv(int32_t left, int32_t right)
-{
- return left / right;
-}
-
-static int32_t JIT_OPERATION operationMod(int32_t left, int32_t right)
-{
- return left % right;
-}
-
-static uint32_t JIT_OPERATION operationUnsignedDiv(uint32_t left, uint32_t right)
-{
- return left / right;
-}
-
-static uint32_t JIT_OPERATION operationUnsignedMod(uint32_t left, uint32_t right)
-{
- return left % right;
-}
-#endif
-
-#if !USE(JSVALUE64)
-static double JIT_OPERATION operationConvertUnsignedInt32ToDouble(uint32_t value)
-{
- return static_cast<double>(value);
-}
-#endif
-
-static size_t sizeOfMemoryType(WASMMemoryType memoryType)
-{
- switch (memoryType) {
- case WASMMemoryType::I8:
- return 1;
- case WASMMemoryType::I16:
- return 2;
- case WASMMemoryType::I32:
- case WASMMemoryType::F32:
- return 4;
- case WASMMemoryType::F64:
- return 8;
- default:
- ASSERT_NOT_REACHED();
- }
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
-}
-
-class WASMFunctionCompiler : private CCallHelpers {
-public:
- typedef int Expression;
- typedef int Statement;
- typedef int ExpressionList;
- struct MemoryAddress {
- MemoryAddress(void*) { }
- MemoryAddress(int, uint32_t offset)
- : offset(offset)
- {
- }
- uint32_t offset;
- };
- struct JumpTarget {
- Label label;
- JumpList jumpList;
- };
- enum class JumpCondition { Zero, NonZero };
-
- WASMFunctionCompiler(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, unsigned stackHeight)
- : CCallHelpers(&vm, codeBlock)
- , m_module(module)
- , m_stackHeight(stackHeight)
- {
- }
-
- void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
- {
- m_calleeSaveSpace = WTF::roundUpToMultipleOf(sizeof(StackSlot), RegisterSet::webAssemblyCalleeSaveRegisters().numberOfSetRegisters() * sizeof(void*));
- m_codeBlock->setCalleeSaveRegisters(RegisterSet::webAssemblyCalleeSaveRegisters());
-
- emitFunctionPrologue();
- emitPutToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
-
- m_beginLabel = label();
-
- addPtr(TrustedImm32(-m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, GPRInfo::regT1);
- m_stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm->addressOfStackLimit()), GPRInfo::regT1);
-
- move(GPRInfo::regT1, stackPointerRegister);
- checkStackPointerAlignment();
-
- emitSaveCalleeSaves();
- emitMaterializeTagCheckRegisters();
-
- m_numberOfLocals = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
-
- unsigned localIndex = 0;
- for (size_t i = 0; i < arguments.size(); ++i) {
- // FIXME: No need to do type conversion if the caller is a WebAssembly function.
- // https://bugs.webkit.org/show_bug.cgi?id=149310
- Address address(GPRInfo::callFrameRegister, CallFrame::argumentOffset(i) * sizeof(Register));
-#if USE(JSVALUE64)
- JSValueRegs valueRegs(GPRInfo::regT0);
-#else
- JSValueRegs valueRegs(GPRInfo::regT1, GPRInfo::regT0);
-#endif
- loadValue(address, valueRegs);
- switch (arguments[i]) {
- case WASMType::I32:
- convertValueToInt32(valueRegs, GPRInfo::regT0);
- store32(GPRInfo::regT0, localAddress(localIndex++));
- break;
- case WASMType::F32:
- case WASMType::F64:
-#if USE(JSVALUE64)
- convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::regT1);
-#else
- convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::regT2, FPRInfo::fpRegT1);
-#endif
- if (arguments[i] == WASMType::F32)
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, localAddress(localIndex++));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
- for (uint32_t i = 0; i < numberOfI32LocalVariables; ++i)
- store32(TrustedImm32(0), localAddress(localIndex++));
- for (uint32_t i = 0; i < numberOfF32LocalVariables; ++i)
- store32(TrustedImm32(0), localAddress(localIndex++));
- for (uint32_t i = 0; i < numberOfF64LocalVariables; ++i) {
-#if USE(JSVALUE64)
- store64(TrustedImm64(0), localAddress(localIndex++));
-#else
- store32(TrustedImm32(0), localAddress(localIndex));
- store32(TrustedImm32(0), localAddress(localIndex).withOffset(4));
- localIndex++;
-#endif
- }
-
- m_codeBlock->setNumParameters(1 + arguments.size());
- }
-
- void endFunction()
- {
- ASSERT(!m_tempStackTop);
-
- // FIXME: Remove these if the last statement is a return statement.
-#if USE(JSVALUE64)
- JSValueRegs returnValueRegs(GPRInfo::returnValueGPR);
-#else
- JSValueRegs returnValueRegs(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-#endif
- moveTrustedValue(jsUndefined(), returnValueRegs);
- emitRestoreCalleeSaves();
- emitFunctionEpilogue();
- ret();
-
- m_stackOverflow.link(this);
- if (maxFrameExtentForSlowPathCall)
- addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
- setupArgumentsWithExecState(TrustedImmPtr(m_codeBlock));
- appendCallWithExceptionCheck(operationThrowStackOverflowError);
-
- // FIXME: Implement arity check.
- Label arityCheck = label();
- emitFunctionPrologue();
- emitPutToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
- jump(m_beginLabel);
-
- if (!m_divideErrorJumpList.empty()) {
- m_divideErrorJumpList.link(this);
-
- setupArgumentsExecState();
- appendCallWithExceptionCheck(operationThrowDivideError);
- }
-
- if (!m_outOfBoundsErrorJumpList.empty()) {
- m_outOfBoundsErrorJumpList.link(this);
-
- setupArgumentsExecState();
- appendCallWithExceptionCheck(operationThrowOutOfBoundsAccessError);
- }
-
- if (!m_exceptionChecks.empty()) {
- m_exceptionChecks.link(this);
-
- copyCalleeSavesToVMCalleeSavesBuffer();
-
- // lookupExceptionHandler is passed two arguments, the VM and the exec (the CallFrame*).
- move(TrustedImmPtr(vm()), GPRInfo::argumentGPR0);
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
-
-#if CPU(X86)
- // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
- poke(GPRInfo::argumentGPR0);
- poke(GPRInfo::argumentGPR1, 1);
-#endif
- m_calls.append(std::make_pair(call(), FunctionPtr(lookupExceptionHandlerFromCallerFrame).value()));
- jumpToExceptionHandler();
- }
-
- LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock, JITCompilationMustSucceed);
-
- for (const auto& iterator : m_calls)
- patchBuffer.link(iterator.first, FunctionPtr(iterator.second));
-
- for (size_t i = 0; i < m_callCompilationInfo.size(); ++i) {
- CallCompilationInfo& compilationInfo = m_callCompilationInfo[i];
- CallLinkInfo& info = *compilationInfo.callLinkInfo;
- info.setCallLocations(patchBuffer.locationOfNearCall(compilationInfo.callReturnLocation),
- patchBuffer.locationOf(compilationInfo.hotPathBegin),
- patchBuffer.locationOfNearCall(compilationInfo.hotPathOther));
- }
-
- MacroAssemblerCodePtr withArityCheck = patchBuffer.locationOf(arityCheck);
- CodeRef result = FINALIZE_CODE(patchBuffer, ("Baseline JIT code for WebAssembly"));
- m_codeBlock->setJITCode(adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
- m_codeBlock->capabilityLevel();
- }
-
- int buildSetLocal(WASMOpKind opKind, uint32_t localIndex, int, WASMType type)
- {
- switch (type) {
- case WASMType::I32:
- case WASMType::F32:
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0);
- store32(GPRInfo::regT0, localAddress(localIndex));
- break;
- case WASMType::F64:
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, localAddress(localIndex));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- if (opKind == WASMOpKind::Statement)
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildSetGlobal(WASMOpKind opKind, uint32_t globalIndex, int, WASMType type)
- {
- move(TrustedImmPtr(&m_module->globalVariables()[globalIndex]), GPRInfo::regT0);
- switch (type) {
- case WASMType::I32:
- case WASMType::F32:
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- store32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMType::F64:
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- if (opKind == WASMOpKind::Statement)
- m_tempStackTop--;
- return UNUSED;
- }
-
- void buildReturn(int, WASMExpressionType returnType)
- {
-#if USE(JSVALUE64)
- JSValueRegs returnValueRegs(GPRInfo::returnValueGPR);
-#else
- JSValueRegs returnValueRegs(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-#endif
- switch (returnType) {
- case WASMExpressionType::I32:
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::returnValueGPR);
-#if USE(JSVALUE64)
- or64(GPRInfo::tagTypeNumberRegister, GPRInfo::returnValueGPR);
-#else
- move(TrustedImm32(JSValue::Int32Tag), GPRInfo::returnValueGPR2);
-#endif
- m_tempStackTop--;
- break;
- case WASMExpressionType::F32:
- case WASMExpressionType::F64:
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- if (returnType == WASMExpressionType::F32)
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- convertDoubleToValue(FPRInfo::fpRegT0, returnValueRegs);
- m_tempStackTop--;
- break;
- case WASMExpressionType::Void:
- moveTrustedValue(jsUndefined(), returnValueRegs);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- emitRestoreCalleeSaves();
- emitFunctionEpilogue();
- ret();
- }
-
- int buildImmediateI32(uint32_t immediate)
- {
- store32(Imm32(immediate), temporaryAddress(m_tempStackTop++));
- return UNUSED;
- }
-
- int buildImmediateF32(float immediate)
- {
- store32(Imm32(bitwise_cast<int32_t>(immediate)), temporaryAddress(m_tempStackTop++));
- return UNUSED;
- }
-
- int buildImmediateF64(double immediate)
- {
-#if USE(JSVALUE64)
- store64(Imm64(bitwise_cast<int64_t>(immediate)), temporaryAddress(m_tempStackTop++));
-#else
- union {
- double doubleValue;
- int32_t int32Values[2];
- } u = { immediate };
- m_tempStackTop++;
- store32(Imm32(u.int32Values[0]), temporaryAddress(m_tempStackTop - 1));
- store32(Imm32(u.int32Values[1]), temporaryAddress(m_tempStackTop - 1).withOffset(4));
-#endif
- return UNUSED;
- }
-
- int buildGetLocal(uint32_t localIndex, WASMType type)
- {
- switch (type) {
- case WASMType::I32:
- case WASMType::F32:
- load32(localAddress(localIndex), GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
- break;
- case WASMType::F64:
- loadDouble(localAddress(localIndex), FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- return UNUSED;
- }
-
- int buildGetGlobal(uint32_t globalIndex, WASMType type)
- {
- move(TrustedImmPtr(&m_module->globalVariables()[globalIndex]), GPRInfo::regT0);
- switch (type) {
- case WASMType::I32:
- case WASMType::F32:
- load32(GPRInfo::regT0, GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
- break;
- case WASMType::F64:
- loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- return UNUSED;
- }
-
- int buildConvertType(int, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion conversion)
- {
- switch (fromType) {
- case WASMExpressionType::I32:
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0);
- ASSERT(toType == WASMExpressionType::F32 || toType == WASMExpressionType::F64);
- if (conversion == WASMTypeConversion::ConvertSigned)
- convertInt32ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
- else {
- ASSERT(conversion == WASMTypeConversion::ConvertUnsigned);
-#if USE(JSVALUE64)
- convertInt64ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
-#else
- callOperation(operationConvertUnsignedInt32ToDouble, GPRInfo::regT0, FPRInfo::fpRegT0);
-#endif
- }
- if (toType == WASMExpressionType::F32)
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- break;
- case WASMExpressionType::F32:
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- switch (toType) {
- case WASMExpressionType::I32:
- ASSERT(conversion == WASMTypeConversion::ConvertSigned);
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- truncateDoubleToInt32(FPRInfo::fpRegT0, GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- break;
- case WASMExpressionType::F64:
- ASSERT(conversion == WASMTypeConversion::Promote);
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- break;
- case WASMExpressionType::F64:
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- switch (toType) {
- case WASMExpressionType::I32:
- ASSERT(conversion == WASMTypeConversion::ConvertSigned);
- truncateDoubleToInt32(FPRInfo::fpRegT0, GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- break;
- case WASMExpressionType::F32:
- ASSERT(conversion == WASMTypeConversion::Demote);
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- return UNUSED;
- }
-
- int buildLoad(const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessConversion conversion)
- {
- const ArrayBuffer* arrayBuffer = m_module->arrayBuffer()->impl();
- move(TrustedImmPtr(arrayBuffer->data()), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- if (memoryAddress.offset)
- add32(TrustedImm32(memoryAddress.offset), GPRInfo::regT1, GPRInfo::regT1);
- and32(TrustedImm32(~(sizeOfMemoryType(memoryType) - 1)), GPRInfo::regT1);
-
- ASSERT(arrayBuffer->byteLength() < (unsigned)(1 << 31));
- if (arrayBuffer->byteLength() >= sizeOfMemoryType(memoryType))
- m_outOfBoundsErrorJumpList.append(branch32(Above, GPRInfo::regT1, TrustedImm32(arrayBuffer->byteLength() - sizeOfMemoryType(memoryType))));
- else
- m_outOfBoundsErrorJumpList.append(jump());
-
- BaseIndex address = BaseIndex(GPRInfo::regT0, GPRInfo::regT1, TimesOne);
-
- switch (expressionType) {
- case WASMExpressionType::I32:
- switch (memoryType) {
- case WASMMemoryType::I8:
- if (conversion == MemoryAccessConversion::SignExtend)
- load8SignedExtendTo32(address, GPRInfo::regT0);
- else {
- ASSERT(conversion == MemoryAccessConversion::ZeroExtend);
- load8(address, GPRInfo::regT0);
- }
- break;
- case WASMMemoryType::I16:
- if (conversion == MemoryAccessConversion::SignExtend)
- load16SignedExtendTo32(address, GPRInfo::regT0);
- else {
- ASSERT(conversion == MemoryAccessConversion::ZeroExtend);
- load16(address, GPRInfo::regT0);
- }
- break;
- case WASMMemoryType::I32:
- load32(address, GPRInfo::regT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- break;
- case WASMExpressionType::F32:
- ASSERT(memoryType == WASMMemoryType::F32 && conversion == MemoryAccessConversion::NoConversion);
- load32(address, GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- break;
- case WASMExpressionType::F64:
- ASSERT(memoryType == WASMMemoryType::F64 && conversion == MemoryAccessConversion::NoConversion);
- loadDouble(address, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- return UNUSED;
- }
-
- int buildStore(WASMOpKind opKind, const MemoryAddress& memoryAddress, WASMExpressionType expressionType, WASMMemoryType memoryType, int)
- {
- const ArrayBuffer* arrayBuffer = m_module->arrayBuffer()->impl();
- move(TrustedImmPtr(arrayBuffer->data()), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 2), GPRInfo::regT1);
- if (memoryAddress.offset)
- add32(TrustedImm32(memoryAddress.offset), GPRInfo::regT1, GPRInfo::regT1);
- and32(TrustedImm32(~(sizeOfMemoryType(memoryType) - 1)), GPRInfo::regT1);
-
- ASSERT(arrayBuffer->byteLength() < (1u << 31));
- if (arrayBuffer->byteLength() >= sizeOfMemoryType(memoryType))
- m_outOfBoundsErrorJumpList.append(branch32(Above, GPRInfo::regT1, TrustedImm32(arrayBuffer->byteLength() - sizeOfMemoryType(memoryType))));
- else
- m_outOfBoundsErrorJumpList.append(jump());
-
- BaseIndex address = BaseIndex(GPRInfo::regT0, GPRInfo::regT1, TimesOne);
-
- switch (expressionType) {
- case WASMExpressionType::I32:
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT2);
- switch (memoryType) {
- case WASMMemoryType::I8:
- store8(GPRInfo::regT2, address);
- break;
- case WASMMemoryType::I16:
- store16(GPRInfo::regT2, address);
- break;
- case WASMMemoryType::I32:
- store32(GPRInfo::regT2, address);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- break;
- case WASMExpressionType::F32:
- ASSERT(memoryType == WASMMemoryType::F32);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT2);
- store32(GPRInfo::regT2, address);
- break;
- case WASMExpressionType::F64:
- ASSERT(memoryType == WASMMemoryType::F64);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, address);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- m_tempStackTop -= 2;
-
- if (opKind == WASMOpKind::Expression) {
- switch (expressionType) {
- case WASMExpressionType::I32:
- case WASMExpressionType::F32:
- store32(GPRInfo::regT2, temporaryAddress(m_tempStackTop++));
- break;
- case WASMExpressionType::F64:
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return UNUSED;
- }
-
- int buildUnaryI32(int, WASMOpExpressionI32 op)
- {
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0);
- switch (op) {
- case WASMOpExpressionI32::Negate:
- neg32(GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::BitNot:
- xor32(TrustedImm32(-1), GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::CountLeadingZeros:
- countLeadingZeros32(GPRInfo::regT0, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::LogicalNot: {
- // FIXME: Don't use branches.
- Jump zero = branchTest32(Zero, GPRInfo::regT0);
- move(TrustedImm32(0), GPRInfo::regT0);
- Jump end = jump();
- zero.link(this);
- move(TrustedImm32(1), GPRInfo::regT0);
- end.link(this);
- break;
- }
- case WASMOpExpressionI32::Abs: {
- // FIXME: Don't use branches.
- Jump end = branchTest32(PositiveOrZero, GPRInfo::regT0);
- neg32(GPRInfo::regT0);
- end.link(this);
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildUnaryF32(int, WASMOpExpressionF32 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- switch (op) {
- case WASMOpExpressionF32::Negate:
- convertFloatToDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT1);
- negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Abs:
- convertFloatToDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT1);
- absDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Ceil:
- callOperation(ceilf, FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Floor:
- callOperation(floorf, FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Sqrt:
- convertFloatToDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT1);
- sqrtDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildUnaryF64(int, WASMOpExpressionF64 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- switch (op) {
- case WASMOpExpressionF64::Negate:
- negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Abs:
- absDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Sqrt:
- sqrtDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Ceil:
- case WASMOpExpressionF64::Floor:
- case WASMOpExpressionF64::Cos:
- case WASMOpExpressionF64::Sin:
- case WASMOpExpressionF64::Tan:
- case WASMOpExpressionF64::ACos:
- case WASMOpExpressionF64::ASin:
- case WASMOpExpressionF64::ATan:
- case WASMOpExpressionF64::Exp:
- case WASMOpExpressionF64::Ln:
- D_JITOperation_D operation;
- switch (op) {
- case WASMOpExpressionF64::Ceil:
- operation = ceil;
- break;
- case WASMOpExpressionF64::Floor:
- operation = floor;
- break;
- case WASMOpExpressionF64::Cos:
- operation = cos;
- break;
- case WASMOpExpressionF64::Sin:
- operation = sin;
- break;
- case WASMOpExpressionF64::Tan:
- operation = tan;
- break;
- case WASMOpExpressionF64::ACos:
- operation = acos;
- break;
- case WASMOpExpressionF64::ASin:
- operation = asin;
- break;
- case WASMOpExpressionF64::ATan:
- operation = atan;
- break;
- case WASMOpExpressionF64::Exp:
- operation = exp;
- break;
- case WASMOpExpressionF64::Ln:
- operation = log;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- callOperation(operation, FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildBinaryI32(int, int, WASMOpExpressionI32 op)
- {
- load32(temporaryAddress(m_tempStackTop - 2), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- switch (op) {
- case WASMOpExpressionI32::Add:
- add32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::Sub:
- sub32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::Mul:
- mul32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::SDiv:
- case WASMOpExpressionI32::UDiv:
- case WASMOpExpressionI32::SMod:
- case WASMOpExpressionI32::UMod: {
- m_divideErrorJumpList.append(branchTest32(Zero, GPRInfo::regT1));
- if (op == WASMOpExpressionI32::SDiv || op == WASMOpExpressionI32::SMod) {
- Jump denominatorNotNeg1 = branch32(NotEqual, GPRInfo::regT1, TrustedImm32(-1));
- m_divideErrorJumpList.append(branch32(Equal, GPRInfo::regT0, TrustedImm32(-2147483647-1)));
- denominatorNotNeg1.link(this);
- }
-#if CPU(X86) || CPU(X86_64)
- ASSERT(GPRInfo::regT0 == X86Registers::eax);
- move(GPRInfo::regT1, X86Registers::ecx);
- if (op == WASMOpExpressionI32::SDiv || op == WASMOpExpressionI32::SMod) {
- x86ConvertToDoubleWord32();
- x86Div32(X86Registers::ecx);
- } else {
- ASSERT(op == WASMOpExpressionI32::UDiv || op == WASMOpExpressionI32::UMod);
- xor32(X86Registers::edx, X86Registers::edx);
- m_assembler.divl_r(X86Registers::ecx);
- }
- if (op == WASMOpExpressionI32::SMod || op == WASMOpExpressionI32::UMod)
- move(X86Registers::edx, GPRInfo::regT0);
-#else
- // FIXME: We should be able to do an inline div on ARMv7 and ARM64.
- switch (op) {
- case WASMOpExpressionI32::SDiv:
- callOperation(operationDiv, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::UDiv:
- callOperation(operationUnsignedDiv, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::SMod:
- callOperation(operationMod, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::UMod:
- callOperation(operationUnsignedMod, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-#endif
- break;
- }
- case WASMOpExpressionI32::BitOr:
- or32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::BitAnd:
- and32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::BitXor:
- xor32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::LeftShift:
- lshift32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::ArithmeticRightShift:
- rshift32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- case WASMOpExpressionI32::LogicalRightShift:
- urshift32(GPRInfo::regT1, GPRInfo::regT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- m_tempStackTop--;
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildBinaryF32(int, int, WASMOpExpressionF32 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 2), FPRInfo::fpRegT0);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- convertFloatToDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT1);
- switch (op) {
- case WASMOpExpressionF32::Add:
- addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Sub:
- subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Mul:
- mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF32::Div:
- divDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- m_tempStackTop--;
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildBinaryF64(int, int, WASMOpExpressionF64 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 2), FPRInfo::fpRegT0);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- switch (op) {
- case WASMOpExpressionF64::Add:
- addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Sub:
- subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Mul:
- mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Div:
- divDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- case WASMOpExpressionF64::Mod:
- case WASMOpExpressionF64::ATan2:
- case WASMOpExpressionF64::Pow:
- D_JITOperation_DD operation;
- switch (op) {
- case WASMOpExpressionF64::Mod:
- operation = fmod;
- break;
- case WASMOpExpressionF64::ATan2:
- operation = atan2;
- break;
- case WASMOpExpressionF64::Pow:
- operation = pow;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- callOperation(operation, FPRInfo::fpRegT0, FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- m_tempStackTop--;
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildRelationalI32(int, int, WASMOpExpressionI32 op)
- {
- load32(temporaryAddress(m_tempStackTop - 2), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- RelationalCondition condition;
- switch (op) {
- case WASMOpExpressionI32::EqualI32:
- condition = Equal;
- break;
- case WASMOpExpressionI32::NotEqualI32:
- condition = NotEqual;
- break;
- case WASMOpExpressionI32::SLessThanI32:
- condition = LessThan;
- break;
- case WASMOpExpressionI32::ULessThanI32:
- condition = Below;
- break;
- case WASMOpExpressionI32::SLessThanOrEqualI32:
- condition = LessThanOrEqual;
- break;
- case WASMOpExpressionI32::ULessThanOrEqualI32:
- condition = BelowOrEqual;
- break;
- case WASMOpExpressionI32::SGreaterThanI32:
- condition = GreaterThan;
- break;
- case WASMOpExpressionI32::UGreaterThanI32:
- condition = Above;
- break;
- case WASMOpExpressionI32::SGreaterThanOrEqualI32:
- condition = GreaterThanOrEqual;
- break;
- case WASMOpExpressionI32::UGreaterThanOrEqualI32:
- condition = AboveOrEqual;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- compare32(condition, GPRInfo::regT0, GPRInfo::regT1, GPRInfo::regT0);
- m_tempStackTop--;
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1));
- return UNUSED;
- }
-
- int buildRelationalF32(int, int, WASMOpExpressionI32 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 2), FPRInfo::fpRegT0);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- convertFloatToDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT1);
- DoubleCondition condition;
- switch (op) {
- case WASMOpExpressionI32::EqualF32:
- condition = DoubleEqual;
- break;
- case WASMOpExpressionI32::NotEqualF32:
- condition = DoubleNotEqual;
- break;
- case WASMOpExpressionI32::LessThanF32:
- condition = DoubleLessThan;
- break;
- case WASMOpExpressionI32::LessThanOrEqualF32:
- condition = DoubleLessThanOrEqual;
- break;
- case WASMOpExpressionI32::GreaterThanF32:
- condition = DoubleGreaterThan;
- break;
- case WASMOpExpressionI32::GreaterThanOrEqualF32:
- condition = DoubleGreaterThanOrEqual;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- m_tempStackTop--;
- Jump trueCase = branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1);
- store32(TrustedImm32(0), temporaryAddress(m_tempStackTop - 1));
- Jump end = jump();
- trueCase.link(this);
- store32(TrustedImm32(1), temporaryAddress(m_tempStackTop - 1));
- end.link(this);
- return UNUSED;
- }
-
- int buildRelationalF64(int, int, WASMOpExpressionI32 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 2), FPRInfo::fpRegT0);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- DoubleCondition condition;
- switch (op) {
- case WASMOpExpressionI32::EqualF64:
- condition = DoubleEqual;
- break;
- case WASMOpExpressionI32::NotEqualF64:
- condition = DoubleNotEqual;
- break;
- case WASMOpExpressionI32::LessThanF64:
- condition = DoubleLessThan;
- break;
- case WASMOpExpressionI32::LessThanOrEqualF64:
- condition = DoubleLessThanOrEqual;
- break;
- case WASMOpExpressionI32::GreaterThanF64:
- condition = DoubleGreaterThan;
- break;
- case WASMOpExpressionI32::GreaterThanOrEqualF64:
- condition = DoubleGreaterThanOrEqual;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- m_tempStackTop--;
- Jump trueCase = branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1);
- store32(TrustedImm32(0), temporaryAddress(m_tempStackTop - 1));
- Jump end = jump();
- trueCase.link(this);
- store32(TrustedImm32(1), temporaryAddress(m_tempStackTop - 1));
- end.link(this);
- return UNUSED;
- }
-
- int buildMinOrMaxI32(int, int, WASMOpExpressionI32 op)
- {
- load32(temporaryAddress(m_tempStackTop - 2), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- RelationalCondition condition;
- switch (op) {
- case WASMOpExpressionI32::SMin:
- condition = LessThanOrEqual;
- break;
- case WASMOpExpressionI32::UMin:
- condition = BelowOrEqual;
- break;
- case WASMOpExpressionI32::SMax:
- condition = GreaterThanOrEqual;
- break;
- case WASMOpExpressionI32::UMax:
- condition = AboveOrEqual;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- Jump useLeft = branch32(condition, GPRInfo::regT0, GPRInfo::regT1);
- store32(GPRInfo::regT1, temporaryAddress(m_tempStackTop - 2));
- useLeft.link(this);
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildMinOrMaxF64(int, int, WASMOpExpressionF64 op)
- {
- loadDouble(temporaryAddress(m_tempStackTop - 2), FPRInfo::fpRegT0);
- loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT1);
- DoubleCondition condition;
- switch (op) {
- case WASMOpExpressionF64::Min:
- condition = DoubleLessThanOrEqual;
- break;
- case WASMOpExpressionF64::Max:
- condition = DoubleGreaterThanOrEqual;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- Jump useLeft = branchDouble(condition, FPRInfo::fpRegT0, FPRInfo::fpRegT1);
- storeDouble(FPRInfo::fpRegT1, temporaryAddress(m_tempStackTop - 2));
- useLeft.link(this);
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildCallInternal(uint32_t functionIndex, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- boxArgumentsAndAdjustStackPointer(signature.arguments);
-
- JSFunction* function = m_module->functions()[functionIndex].get();
- move(TrustedImmPtr(function), GPRInfo::regT0);
-
- callAndUnboxResult(returnType);
- return UNUSED;
- }
-
- int buildCallIndirect(uint32_t functionPointerTableIndex, int, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- boxArgumentsAndAdjustStackPointer(signature.arguments);
-
- const Vector<JSFunction*>& functions = m_module->functionPointerTables()[functionPointerTableIndex].functions;
- move(TrustedImmPtr(functions.data()), GPRInfo::regT0);
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
- m_tempStackTop--;
- and32(TrustedImm32(functions.size() - 1), GPRInfo::regT1);
- loadPtr(BaseIndex(GPRInfo::regT0, GPRInfo::regT1, timesPtr()), GPRInfo::regT0);
-
- callAndUnboxResult(returnType);
- return UNUSED;
- }
-
- int buildCallImport(uint32_t functionImportIndex, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- boxArgumentsAndAdjustStackPointer(signature.arguments);
-
- JSFunction* function = m_module->importedFunctions()[functionImportIndex].get();
- move(TrustedImmPtr(function), GPRInfo::regT0);
-
- callAndUnboxResult(returnType);
- return UNUSED;
- }
-
- void appendExpressionList(int&, int) { }
-
- void discard(int)
- {
- m_tempStackTop--;
- }
-
- void linkTarget(JumpTarget& target)
- {
- target.label = label();
- target.jumpList.link(this);
- }
-
- void jumpToTarget(JumpTarget& target)
- {
- if (target.label.isSet())
- jump(target.label);
- else
- target.jumpList.append(jump());
- }
-
- void jumpToTargetIf(JumpCondition condition, int, JumpTarget& target)
- {
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0);
- m_tempStackTop--;
- Jump taken = branchTest32((condition == JumpCondition::Zero) ? Zero : NonZero, GPRInfo::regT0);
- if (target.label.isSet())
- taken.linkTo(target.label, this);
- else
- target.jumpList.append(taken);
- }
-
- void startLoop()
- {
- m_breakTargets.append(JumpTarget());
- m_continueTargets.append(JumpTarget());
- }
-
- void endLoop()
- {
- m_breakTargets.removeLast();
- m_continueTargets.removeLast();
- }
-
- void startSwitch()
- {
- m_breakTargets.append(JumpTarget());
- }
-
- void endSwitch()
- {
- m_breakTargets.removeLast();
- }
-
- void startLabel()
- {
- m_breakLabelTargets.append(JumpTarget());
- m_continueLabelTargets.append(JumpTarget());
-
- linkTarget(m_continueLabelTargets.last());
- }
-
- void endLabel()
- {
- linkTarget(m_breakLabelTargets.last());
-
- m_breakLabelTargets.removeLast();
- m_continueLabelTargets.removeLast();
- }
-
- JumpTarget& breakTarget()
- {
- return m_breakTargets.last();
- }
-
- JumpTarget& continueTarget()
- {
- return m_continueTargets.last();
- }
-
- JumpTarget& breakLabelTarget(uint32_t labelIndex)
- {
- return m_breakLabelTargets[labelIndex];
- }
-
- JumpTarget& continueLabelTarget(uint32_t labelIndex)
- {
- return m_continueLabelTargets[labelIndex];
- }
-
- void buildSwitch(int, const Vector<int64_t>& cases, Vector<JumpTarget>& targets, JumpTarget defaultTarget)
- {
- load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0);
- m_tempStackTop--;
- BinarySwitch binarySwitch(GPRInfo::regT0, cases, BinarySwitch::Int32);
- while (binarySwitch.advance(*this)) {
- unsigned index = binarySwitch.caseIndex();
- jump(targets[index].label);
- }
- binarySwitch.fallThrough().linkTo(defaultTarget.label, this);
- }
-
-private:
- union StackSlot {
- int32_t intValue;
- float floatValue;
- double doubleValue;
- };
-
- enum class FloatingPointPrecision { Single, Double };
-
- Address localAddress(unsigned localIndex) const
- {
- ASSERT(localIndex < m_numberOfLocals);
- return Address(GPRInfo::callFrameRegister, -m_calleeSaveSpace - (localIndex + 1) * sizeof(StackSlot));
- }
-
- Address temporaryAddress(unsigned temporaryIndex) const
- {
- ASSERT(m_numberOfLocals + temporaryIndex < m_stackHeight);
- return Address(GPRInfo::callFrameRegister, -m_calleeSaveSpace - (m_numberOfLocals + temporaryIndex + 1) * sizeof(StackSlot));
- }
-
- void appendCall(const FunctionPtr& function)
- {
- m_calls.append(std::make_pair(call(), function.value()));
- }
-
- void appendCallWithExceptionCheck(const FunctionPtr& function)
- {
- appendCall(function);
- m_exceptionChecks.append(emitExceptionCheck());
- }
-
- Call emitNakedCall(CodePtr function)
- {
- Call nakedCall = nearCall();
- m_calls.append(std::make_pair(nakedCall, function.executableAddress()));
- return nakedCall;
- }
-
- void appendCallSetResult(const FunctionPtr& function, GPRReg result)
- {
- appendCall(function);
- move(GPRInfo::returnValueGPR, result);
- }
-
-#if CPU(X86)
- void appendCallSetResult(const FunctionPtr& function, FPRReg result, FloatingPointPrecision precision)
- {
- appendCall(function);
- switch (precision) {
- case FloatingPointPrecision::Single:
- m_assembler.fstps(0, stackPointerRegister);
- break;
- case FloatingPointPrecision::Double:
- m_assembler.fstpl(0, stackPointerRegister);
- break;
- }
- loadDouble(stackPointerRegister, result);
- }
-#elif CPU(ARM) && !CPU(ARM_HARDFP)
- void appendCallSetResult(const FunctionPtr& function, FPRReg result, FloatingPointPrecision)
- {
- appendCall(function);
- m_assembler.vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
- }
-#else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
- void appendCallSetResult(const FunctionPtr& function, FPRReg result, FloatingPointPrecision)
- {
- appendCall(function);
- moveDouble(FPRInfo::returnValueFPR, result);
- }
-#endif
-
-#if USE(JSVALUE64)
- void callOperation(Z_JITOperation_EJ operation, GPRReg src, GPRReg dst)
- {
- setupArgumentsWithExecState(src);
- appendCallSetResult(operation, dst);
- }
-
- void callOperation(D_JITOperation_EJ operation, GPRReg src, FPRReg dst)
- {
- setupArgumentsWithExecState(src);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
- }
-#else
-// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned on an even-numbered register (r0, r2 or [sp]).
-// To prevent the assembler from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
-#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
-#define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
-#else
-#define EABI_32BIT_DUMMY_ARG
-#endif
-
- void callOperation(Z_JITOperation_EJ operation, GPRReg srcTag, GPRReg srcPayload, GPRReg dst)
- {
- setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG srcPayload, srcTag);
- appendCallSetResult(operation, dst);
- }
-
- void callOperation(D_JITOperation_EJ operation, GPRReg srcTag, GPRReg srcPayload, FPRReg dst)
- {
- setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG srcPayload, srcTag);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
- }
-#endif
-
- void callOperation(float JIT_OPERATION (*operation)(float), FPRegisterID src, FPRegisterID dst)
- {
- setupArguments(src);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Single);
- }
-
- void callOperation(D_JITOperation_D operation, FPRegisterID src, FPRegisterID dst)
- {
- setupArguments(src);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
- }
-
- void callOperation(int32_t JIT_OPERATION (*operation)(int32_t, int32_t), GPRReg src1, GPRReg src2, GPRReg dst)
- {
- setupArguments(src1, src2);
- appendCallSetResult(operation, dst);
- }
-
- void callOperation(uint32_t JIT_OPERATION (*operation)(uint32_t, uint32_t), GPRReg src1, GPRReg src2, GPRReg dst)
- {
- setupArguments(src1, src2);
- appendCallSetResult(operation, dst);
- }
-
- void callOperation(D_JITOperation_DD operation, FPRegisterID src1, FPRegisterID src2, FPRegisterID dst)
- {
- setupArguments(src1, src2);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
- }
-
- void callOperation(double JIT_OPERATION (*operation)(uint32_t), GPRReg src, FPRegisterID dst)
- {
- setupArguments(src);
- appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
- }
-
- void boxArgumentsAndAdjustStackPointer(const Vector<WASMType>& arguments)
- {
- size_t argumentCount = arguments.size();
- int stackOffset = -m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_numberOfLocals + m_tempStackTop + argumentCount + 1 + JSStack::CallFrameHeaderSize);
-
- storeTrustedValue(jsUndefined(), Address(GPRInfo::callFrameRegister, (stackOffset + CallFrame::thisArgumentOffset()) * sizeof(Register)));
-
- for (size_t i = 0; i < argumentCount; ++i) {
- Address address(GPRInfo::callFrameRegister, (stackOffset + CallFrame::argumentOffset(i)) * sizeof(Register));
-#if USE(JSVALUE64)
- JSValueRegs valueRegs(GPRInfo::regT0);
-#else
- JSValueRegs valueRegs(GPRInfo::regT1, GPRInfo::regT0);
-#endif
- switch (arguments[i]) {
- case WASMType::I32:
- load32(temporaryAddress(m_tempStackTop - argumentCount + i), GPRInfo::regT0);
-#if USE(JSVALUE64)
- or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);
- store64(GPRInfo::regT0, address);
-#else
- store32(GPRInfo::regT0, address.withOffset(PayloadOffset));
- store32(TrustedImm32(JSValue::Int32Tag), address.withOffset(TagOffset));
-#endif
- break;
- case WASMType::F32:
- case WASMType::F64:
- loadDouble(temporaryAddress(m_tempStackTop - argumentCount + i), FPRInfo::fpRegT0);
- if (arguments[i] == WASMType::F32)
- convertFloatToDouble(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- convertDoubleToValue(FPRInfo::fpRegT0, valueRegs);
- storeValue(valueRegs, address);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
- m_tempStackTop -= argumentCount;
-
- addPtr(TrustedImm32(stackOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), GPRInfo::callFrameRegister, stackPointerRegister);
- store32(TrustedImm32(argumentCount + 1), Address(stackPointerRegister, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
- }
-
- void callAndUnboxResult(WASMExpressionType returnType)
- {
- // regT0 holds callee.
-#if USE(JSVALUE64)
- store64(GPRInfo::regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
-#else
- store32(GPRInfo::regT0, Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
- store32(TrustedImm32(JSValue::CellTag), Address(stackPointerRegister, JSStack::Callee * static_cast<int>(sizeof(Register)) + TagOffset - sizeof(CallerFrameAndPC)));
-#endif
-
- DataLabelPtr addressOfLinkedFunctionCheck;
- Jump slowCase = branchPtrWithPatch(NotEqual, GPRInfo::regT0, addressOfLinkedFunctionCheck, TrustedImmPtr(0));
-
- CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
- info->setUpCall(CallLinkInfo::Call, CodeOrigin(), GPRInfo::regT0);
- m_callCompilationInfo.append(CallCompilationInfo());
- m_callCompilationInfo.last().hotPathBegin = addressOfLinkedFunctionCheck;
- m_callCompilationInfo.last().callLinkInfo = info;
- m_callCompilationInfo.last().hotPathOther = nearCall();
- Jump end = jump();
-
- slowCase.link(this);
- move(TrustedImmPtr(info), GPRInfo::regT2);
- m_callCompilationInfo.last().callReturnLocation = emitNakedCall(m_vm->getCTIStub(linkCallThunkGenerator).code());
-
- end.link(this);
- addPtr(TrustedImm32(-m_calleeSaveSpace - WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot) - maxFrameExtentForSlowPathCall), GPRInfo::callFrameRegister, stackPointerRegister);
- checkStackPointerAlignment();
-
- // FIXME: No need to do type conversion if the callee is a WebAssembly function.
- // https://bugs.webkit.org/show_bug.cgi?id=149310
-#if USE(JSVALUE64)
- JSValueRegs valueRegs(GPRInfo::returnValueGPR);
-#else
- JSValueRegs valueRegs(GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
-#endif
- switch (returnType) {
- case WASMExpressionType::I32:
- convertValueToInt32(valueRegs, GPRInfo::regT0);
- store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
- break;
- case WASMExpressionType::F32:
- case WASMExpressionType::F64:
-#if USE(JSVALUE64)
- convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::nonPreservedNonReturnGPR);
-#else
- convertValueToDouble(valueRegs, FPRInfo::fpRegT0, GPRInfo::nonPreservedNonReturnGPR, FPRInfo::fpRegT1);
-#endif
- if (returnType == WASMExpressionType::F32)
- convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
- storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
- break;
- case WASMExpressionType::Void:
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
-#if USE(JSVALUE64)
- void convertValueToInt32(JSValueRegs valueRegs, GPRReg dst)
- {
- Jump checkJSInt32 = branchIfInt32(valueRegs);
-
- callOperation(operationConvertJSValueToInt32, valueRegs.gpr(), valueRegs.gpr());
-
- checkJSInt32.link(this);
- move(valueRegs.gpr(), dst);
- }
-
- void convertValueToDouble(JSValueRegs valueRegs, FPRReg dst, GPRReg scratch)
- {
- Jump checkJSInt32 = branchIfInt32(valueRegs);
- Jump checkJSNumber = branchIfNumber(valueRegs, scratch);
- JumpList end;
-
- callOperation(operationConvertJSValueToDouble, valueRegs.gpr(), dst);
- end.append(jump());
-
- checkJSInt32.link(this);
- convertInt32ToDouble(valueRegs.gpr(), dst);
- end.append(jump());
-
- checkJSNumber.link(this);
- unboxDoubleWithoutAssertions(valueRegs.gpr(), dst);
- end.link(this);
- }
-#else
- void convertValueToInt32(JSValueRegs valueRegs, GPRReg dst)
- {
- Jump checkJSInt32 = branchIfInt32(valueRegs);
-
- callOperation(operationConvertJSValueToInt32, valueRegs.tagGPR(), valueRegs.payloadGPR(), valueRegs.payloadGPR());
-
- checkJSInt32.link(this);
- move(valueRegs.payloadGPR(), dst);
- }
-
- void convertValueToDouble(JSValueRegs valueRegs, FPRReg dst, GPRReg scratch, FPRReg fpScratch)
- {
- Jump checkJSInt32 = branchIfInt32(valueRegs);
- Jump checkJSNumber = branchIfNumber(valueRegs, scratch);
- JumpList end;
-
- callOperation(operationConvertJSValueToDouble, valueRegs.tagGPR(), valueRegs.payloadGPR(), dst);
- end.append(jump());
-
- checkJSInt32.link(this);
- convertInt32ToDouble(valueRegs.payloadGPR(), dst);
- end.append(jump());
-
- checkJSNumber.link(this);
- unboxDouble(valueRegs.tagGPR(), valueRegs.payloadGPR(), dst, fpScratch);
- end.link(this);
- }
-#endif
-
- void convertDoubleToValue(FPRReg fpr, JSValueRegs valueRegs)
- {
-#if USE(JSVALUE64)
- boxDouble(fpr, valueRegs.gpr());
-#else
- boxDouble(fpr, valueRegs.tagGPR(), valueRegs.payloadGPR());
-#endif
- }
-
- JSWASMModule* m_module;
- unsigned m_stackHeight;
- unsigned m_numberOfLocals;
- unsigned m_tempStackTop { 0 };
- unsigned m_calleeSaveSpace;
-
- Vector<JumpTarget> m_breakTargets;
- Vector<JumpTarget> m_continueTargets;
- Vector<JumpTarget> m_breakLabelTargets;
- Vector<JumpTarget> m_continueLabelTargets;
-
- Label m_beginLabel;
- Jump m_stackOverflow;
- JumpList m_divideErrorJumpList;
- JumpList m_outOfBoundsErrorJumpList;
- JumpList m_exceptionChecks;
-
- Vector<std::pair<Call, void*>> m_calls;
- Vector<CallCompilationInfo> m_callCompilationInfo;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMFunctionCompiler_h
diff --git a/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp b/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
deleted file mode 100644
index e65da5885..000000000
--- a/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WASMFunctionParser.h"
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "JSCJSValueInlines.h"
-#include "JSWASMModule.h"
-#include "WASMFunctionCompiler.h"
-#include "WASMFunctionB3IRGenerator.h"
-#include "WASMFunctionSyntaxChecker.h"
-
-#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
-#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return 0; } while (0)
-#define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_COMPACT_INT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_EXPRESSION_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readExpressionType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_OP_STATEMENT_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpStatement(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_OP_EXPRESSION_I32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpExpressionI32(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_OP_EXPRESSION_F32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpExpressionF32(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, errorMessage) do { if (!m_reader.readOpExpressionF64(hasImmediate, op, opWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_OP_EXPRESSION_VOID_OR_FAIL(op, errorMessage) do { if (!m_reader.readOpExpressionVoid(op)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, errorMessage) do { if (!m_reader.readVariableTypes(hasImmediate, variableTypes, variableTypesWithImmediate, immediate)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_SWITCH_CASE_OR_FAIL(result, errorMessage) do { if (!m_reader.readSwitchCase(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-
-#define UNUSED 0
-
-namespace JSC {
-
-static String nameOfType(WASMType type)
-{
- switch (type) {
- case WASMType::I32:
- return "int32";
- case WASMType::F32:
- return "float32";
- case WASMType::F64:
- return "float64";
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
-}
-
-bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage)
-{
- WASMFunctionParser parser(module, source, functionIndex);
- WASMFunctionSyntaxChecker syntaxChecker;
- parser.m_reader.setOffset(startOffsetInSource);
- parser.parseFunction(syntaxChecker);
- if (!parser.m_errorMessage.isNull()) {
- errorMessage = parser.m_errorMessage;
- return false;
- }
- endOffsetInSource = parser.m_reader.offset();
- stackHeight = syntaxChecker.stackHeight();
- return true;
-}
-
-void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode& source, size_t functionIndex)
-{
- WASMFunctionParser parser(module, source, functionIndex);
- WASMFunctionCompiler compiler(vm, codeBlock, module, module->functionStackHeights()[functionIndex]);
- parser.m_reader.setOffset(module->functionStartOffsetsInSource()[functionIndex]);
- parser.parseFunction(compiler);
- ASSERT(parser.m_errorMessage.isNull());
-}
-
-template <class Context>
-bool WASMFunctionParser::parseFunction(Context& context)
-{
- const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[m_functionIndex].signatureIndex];
-
- m_returnType = signature.returnType;
-
- parseLocalVariables();
- PROPAGATE_ERROR();
-
- const Vector<WASMType>& arguments = signature.arguments;
- for (size_t i = 0; i < arguments.size(); ++i)
- m_localTypes.append(arguments[i]);
- for (uint32_t i = 0; i < m_numberOfI32LocalVariables; ++i)
- m_localTypes.append(WASMType::I32);
- for (uint32_t i = 0; i < m_numberOfF32LocalVariables; ++i)
- m_localTypes.append(WASMType::F32);
- for (uint32_t i = 0; i < m_numberOfF64LocalVariables; ++i)
- m_localTypes.append(WASMType::F64);
-
- context.startFunction(arguments, m_numberOfI32LocalVariables, m_numberOfF32LocalVariables, m_numberOfF64LocalVariables);
-
- parseBlockStatement(context);
- PROPAGATE_ERROR();
-
- context.endFunction();
- return true;
-}
-
-bool WASMFunctionParser::parseLocalVariables()
-{
- m_numberOfI32LocalVariables = 0;
- m_numberOfF32LocalVariables = 0;
- m_numberOfF64LocalVariables = 0;
-
- bool hasImmediate;
- WASMVariableTypes variableTypes;
- WASMVariableTypesWithImmediate variableTypesWithImmediate;
- uint8_t immediate;
- READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, "Cannot read the types of local variables.");
- if (!hasImmediate) {
- if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::I32))
- READ_COMPACT_UINT32_OR_FAIL(m_numberOfI32LocalVariables, "Cannot read the number of int32 local variables.");
- if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F32))
- READ_COMPACT_UINT32_OR_FAIL(m_numberOfF32LocalVariables, "Cannot read the number of float32 local variables.");
- if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F64))
- READ_COMPACT_UINT32_OR_FAIL(m_numberOfF64LocalVariables, "Cannot read the number of float64 local variables.");
- } else
- m_numberOfI32LocalVariables = immediate;
- return true;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseStatement(Context& context)
-{
- bool hasImmediate;
- WASMOpStatement op;
- WASMOpStatementWithImmediate opWithImmediate;
- uint8_t immediate;
- READ_OP_STATEMENT_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the statement opcode.");
- if (!hasImmediate) {
- switch (op) {
- case WASMOpStatement::SetLocal:
- parseSetLocal(context, WASMOpKind::Statement, WASMExpressionType::Void);
- break;
- case WASMOpStatement::SetGlobal:
- parseSetGlobal(context, WASMOpKind::Statement, WASMExpressionType::Void);
- break;
- case WASMOpStatement::I32Store8:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset);
- break;
- case WASMOpStatement::I32StoreWithOffset8:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset);
- break;
- case WASMOpStatement::I32Store16:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset);
- break;
- case WASMOpStatement::I32StoreWithOffset16:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset);
- break;
- case WASMOpStatement::I32Store32:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
- break;
- case WASMOpStatement::I32StoreWithOffset32:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
- break;
- case WASMOpStatement::F32Store:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
- break;
- case WASMOpStatement::F32StoreWithOffset:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
- break;
- case WASMOpStatement::F64Store:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
- break;
- case WASMOpStatement::F64StoreWithOffset:
- parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
- break;
- case WASMOpStatement::CallInternal:
- parseCallInternal(context, WASMOpKind::Statement, WASMExpressionType::Void);
- break;
- case WASMOpStatement::CallIndirect:
- parseCallIndirect(context, WASMOpKind::Statement, WASMExpressionType::Void);
- break;
- case WASMOpStatement::CallImport:
- parseCallImport(context, WASMOpKind::Statement, WASMExpressionType::Void);
- break;
- case WASMOpStatement::Return:
- parseReturnStatement(context);
- break;
- case WASMOpStatement::Block:
- parseBlockStatement(context);
- break;
- case WASMOpStatement::If:
- parseIfStatement(context);
- break;
- case WASMOpStatement::IfElse:
- parseIfElseStatement(context);
- break;
- case WASMOpStatement::While:
- parseWhileStatement(context);
- break;
- case WASMOpStatement::Do:
- parseDoStatement(context);
- break;
- case WASMOpStatement::Label:
- parseLabelStatement(context);
- break;
- case WASMOpStatement::Break:
- parseBreakStatement(context);
- break;
- case WASMOpStatement::BreakLabel:
- parseBreakLabelStatement(context);
- break;
- case WASMOpStatement::Continue:
- parseContinueStatement(context);
- break;
- case WASMOpStatement::ContinueLabel:
- parseContinueLabelStatement(context);
- break;
- case WASMOpStatement::Switch:
- parseSwitchStatement(context);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- } else {
- switch (opWithImmediate) {
- case WASMOpStatementWithImmediate::SetLocal:
- parseSetLocal(context, WASMOpKind::Statement, WASMExpressionType::Void, immediate);
- break;
- case WASMOpStatementWithImmediate::SetGlobal:
- parseSetGlobal(context, WASMOpKind::Statement, WASMExpressionType::Void, immediate);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseReturnStatement(Context& context)
-{
- ContextExpression expression = 0;
- if (m_returnType != WASMExpressionType::Void) {
- expression = parseExpression(context, m_returnType);
- PROPAGATE_ERROR();
- }
- context.buildReturn(expression, m_returnType);
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseBlockStatement(Context& context)
-{
- uint32_t numberOfStatements;
- READ_COMPACT_UINT32_OR_FAIL(numberOfStatements, "Cannot read the number of statements.");
- for (uint32_t i = 0; i < numberOfStatements; ++i) {
- parseStatement(context);
- PROPAGATE_ERROR();
- }
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseIfStatement(Context& context)
-{
- ContextJumpTarget end;
-
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- context.jumpToTargetIf(Context::JumpCondition::Zero, expression, end);
-
- parseStatement(context);
- PROPAGATE_ERROR();
-
- context.linkTarget(end);
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context)
-{
- ContextJumpTarget elseTarget;
- ContextJumpTarget end;
-
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- context.jumpToTargetIf(Context::JumpCondition::Zero, expression, elseTarget);
-
- parseStatement(context);
- PROPAGATE_ERROR();
-
- context.jumpToTarget(end);
- context.linkTarget(elseTarget);
-
- parseStatement(context);
- PROPAGATE_ERROR();
-
- context.linkTarget(end);
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseWhileStatement(Context& context)
-{
- context.startLoop();
- context.linkTarget(context.continueTarget());
-
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- context.jumpToTargetIf(Context::JumpCondition::Zero, expression, context.breakTarget());
-
- m_breakScopeDepth++;
- m_continueScopeDepth++;
- parseStatement(context);
- PROPAGATE_ERROR();
- m_continueScopeDepth--;
- m_breakScopeDepth--;
-
- context.jumpToTarget(context.continueTarget());
-
- context.linkTarget(context.breakTarget());
- context.endLoop();
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseDoStatement(Context& context)
-{
- context.startLoop();
-
- ContextJumpTarget topOfLoop;
- context.linkTarget(topOfLoop);
-
- m_breakScopeDepth++;
- m_continueScopeDepth++;
- parseStatement(context);
- PROPAGATE_ERROR();
- m_continueScopeDepth--;
- m_breakScopeDepth--;
-
- context.linkTarget(context.continueTarget());
-
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- context.jumpToTargetIf(Context::JumpCondition::NonZero, expression, topOfLoop);
-
- context.linkTarget(context.breakTarget());
- context.endLoop();
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseLabelStatement(Context& context)
-{
- context.startLabel();
- m_labelDepth++;
- parseStatement(context);
- PROPAGATE_ERROR();
- m_labelDepth--;
- context.endLabel();
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseBreakStatement(Context& context)
-{
- FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement.");
- context.jumpToTarget(context.breakTarget());
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& context)
-{
- uint32_t labelIndex;
- READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
- FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
- context.jumpToTarget(context.breakLabelTarget(labelIndex));
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseContinueStatement(Context& context)
-{
- FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement.");
- context.jumpToTarget(context.continueTarget());
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& context)
-{
- uint32_t labelIndex;
- READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
- FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
- context.jumpToTarget(context.continueLabelTarget(labelIndex));
- return UNUSED;
-}
-
-template <class Context>
-ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context)
-{
- context.startSwitch();
- uint32_t numberOfCases;
- READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases.");
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- ContextJumpTarget compare;
- context.jumpToTarget(compare);
-
- Vector<int64_t> cases;
- Vector<ContextJumpTarget> targets;
- cases.reserveInitialCapacity(numberOfCases);
- targets.reserveInitialCapacity(numberOfCases);
- bool hasDefault = false;
- ContextJumpTarget defaultTarget;
-
- m_breakScopeDepth++;
- for (uint32_t i = 0; i < numberOfCases; ++i) {
- WASMSwitchCase switchCase;
- READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case.");
- switch (switchCase) {
- case WASMSwitchCase::CaseWithNoStatements:
- case WASMSwitchCase::CaseWithStatement:
- case WASMSwitchCase::CaseWithBlockStatement: {
- uint32_t value;
- READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case.");
- cases.uncheckedAppend(value);
- ContextJumpTarget target;
- context.linkTarget(target);
- targets.uncheckedAppend(target);
- if (switchCase == WASMSwitchCase::CaseWithStatement) {
- parseStatement(context);
- PROPAGATE_ERROR();
- } else if (switchCase == WASMSwitchCase::CaseWithBlockStatement) {
- parseBlockStatement(context);
- PROPAGATE_ERROR();
- }
- break;
- }
- case WASMSwitchCase::DefaultWithNoStatements:
- case WASMSwitchCase::DefaultWithStatement:
- case WASMSwitchCase::DefaultWithBlockStatement: {
- FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case.");
- hasDefault = true;
- context.linkTarget(defaultTarget);
- if (switchCase == WASMSwitchCase::DefaultWithStatement) {
- parseStatement(context);
- PROPAGATE_ERROR();
- } else if (switchCase == WASMSwitchCase::DefaultWithBlockStatement) {
- parseBlockStatement(context);
- PROPAGATE_ERROR();
- }
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- }
- if (!hasDefault)
- context.linkTarget(defaultTarget);
-
- m_breakScopeDepth--;
-
- context.jumpToTarget(context.breakTarget());
- context.linkTarget(compare);
-
- context.buildSwitch(expression, cases, targets, defaultTarget);
-
- context.linkTarget(context.breakTarget());
- context.endSwitch();
- return UNUSED;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseExpression(Context& context, WASMExpressionType expressionType)
-{
- switch (expressionType) {
- case WASMExpressionType::I32:
- return parseExpressionI32(context);
- case WASMExpressionType::F32:
- return parseExpressionF32(context);
- case WASMExpressionType::F64:
- return parseExpressionF64(context);
- case WASMExpressionType::Void:
- return parseExpressionVoid(context);
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseExpressionI32(Context& context)
-{
- bool hasImmediate;
- WASMOpExpressionI32 op;
- WASMOpExpressionI32WithImmediate opWithImmediate;
- uint8_t immediate;
- READ_OP_EXPRESSION_I32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the int32 expression opcode.");
- if (!hasImmediate) {
- switch (op) {
- case WASMOpExpressionI32::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionI32(context);
- case WASMOpExpressionI32::Immediate:
- return parseImmediateExpressionI32(context);
- case WASMOpExpressionI32::GetLocal:
- return parseGetLocalExpression(context, WASMType::I32);
- case WASMOpExpressionI32::GetGlobal:
- return parseGetGlobalExpression(context, WASMType::I32);
- case WASMOpExpressionI32::SetLocal:
- return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::I32);
- case WASMOpExpressionI32::SetGlobal:
- return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::I32);
- case WASMOpExpressionI32::SLoad8:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend);
- case WASMOpExpressionI32::SLoadWithOffset8:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend);
- case WASMOpExpressionI32::ULoad8:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend);
- case WASMOpExpressionI32::ULoadWithOffset8:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend);
- case WASMOpExpressionI32::SLoad16:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend);
- case WASMOpExpressionI32::SLoadWithOffset16:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend);
- case WASMOpExpressionI32::ULoad16:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend);
- case WASMOpExpressionI32::ULoadWithOffset16:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend);
- case WASMOpExpressionI32::Load32:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionI32::LoadWithOffset32:
- return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionI32::Store8:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionI32::StoreWithOffset8:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionI32::Store16:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionI32::StoreWithOffset16:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionI32::Store32:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionI32::StoreWithOffset32:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionI32::CallInternal:
- return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::I32);
- case WASMOpExpressionI32::CallIndirect:
- return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::I32);
- case WASMOpExpressionI32::CallImport:
- return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::I32);
- case WASMOpExpressionI32::Conditional:
- return parseConditional(context, WASMExpressionType::I32);
- case WASMOpExpressionI32::Comma:
- return parseComma(context, WASMExpressionType::I32);
- case WASMOpExpressionI32::FromF32:
- return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
- case WASMOpExpressionI32::FromF64:
- return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
- case WASMOpExpressionI32::Negate:
- case WASMOpExpressionI32::BitNot:
- case WASMOpExpressionI32::CountLeadingZeros:
- case WASMOpExpressionI32::LogicalNot:
- case WASMOpExpressionI32::Abs:
- return parseUnaryExpressionI32(context, op);
- case WASMOpExpressionI32::Add:
- case WASMOpExpressionI32::Sub:
- case WASMOpExpressionI32::Mul:
- case WASMOpExpressionI32::SDiv:
- case WASMOpExpressionI32::UDiv:
- case WASMOpExpressionI32::SMod:
- case WASMOpExpressionI32::UMod:
- case WASMOpExpressionI32::BitOr:
- case WASMOpExpressionI32::BitAnd:
- case WASMOpExpressionI32::BitXor:
- case WASMOpExpressionI32::LeftShift:
- case WASMOpExpressionI32::ArithmeticRightShift:
- case WASMOpExpressionI32::LogicalRightShift:
- return parseBinaryExpressionI32(context, op);
- case WASMOpExpressionI32::EqualI32:
- case WASMOpExpressionI32::NotEqualI32:
- case WASMOpExpressionI32::SLessThanI32:
- case WASMOpExpressionI32::ULessThanI32:
- case WASMOpExpressionI32::SLessThanOrEqualI32:
- case WASMOpExpressionI32::ULessThanOrEqualI32:
- case WASMOpExpressionI32::SGreaterThanI32:
- case WASMOpExpressionI32::UGreaterThanI32:
- case WASMOpExpressionI32::SGreaterThanOrEqualI32:
- case WASMOpExpressionI32::UGreaterThanOrEqualI32:
- return parseRelationalI32ExpressionI32(context, op);
- case WASMOpExpressionI32::EqualF32:
- case WASMOpExpressionI32::NotEqualF32:
- case WASMOpExpressionI32::LessThanF32:
- case WASMOpExpressionI32::LessThanOrEqualF32:
- case WASMOpExpressionI32::GreaterThanF32:
- case WASMOpExpressionI32::GreaterThanOrEqualF32:
- return parseRelationalF32ExpressionI32(context, op);
- case WASMOpExpressionI32::EqualF64:
- case WASMOpExpressionI32::NotEqualF64:
- case WASMOpExpressionI32::LessThanF64:
- case WASMOpExpressionI32::LessThanOrEqualF64:
- case WASMOpExpressionI32::GreaterThanF64:
- case WASMOpExpressionI32::GreaterThanOrEqualF64:
- return parseRelationalF64ExpressionI32(context, op);
- case WASMOpExpressionI32::SMin:
- case WASMOpExpressionI32::UMin:
- case WASMOpExpressionI32::SMax:
- case WASMOpExpressionI32::UMax:
- return parseMinOrMaxExpressionI32(context, op);
- default:
- ASSERT_NOT_REACHED();
- }
- } else {
- switch (opWithImmediate) {
- case WASMOpExpressionI32WithImmediate::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionI32(context, immediate);
- case WASMOpExpressionI32WithImmediate::Immediate:
- return parseImmediateExpressionI32(context, immediate);
- case WASMOpExpressionI32WithImmediate::GetLocal:
- return parseGetLocalExpression(context, WASMType::I32, immediate);
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return 0;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context, uint32_t constantPoolIndex)
-{
- FAIL_IF_FALSE(constantPoolIndex < m_module->i32Constants().size(), "The constant pool index is incorrect.");
- return context.buildImmediateI32(m_module->i32Constants()[constantPoolIndex]);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context)
-{
- uint32_t constantPoolIndex;
- READ_COMPACT_UINT32_OR_FAIL(constantPoolIndex, "Cannot read the constant pool index.");
- return parseConstantPoolIndexExpressionI32(context, constantPoolIndex);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context, uint32_t immediate)
-{
- return context.buildImmediateI32(immediate);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context)
-{
- uint32_t immediate;
- READ_COMPACT_UINT32_OR_FAIL(immediate, "Cannot read the immediate.");
- return parseImmediateExpressionI32(context, immediate);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
- return context.buildUnaryI32(expression, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseBinaryExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- ContextExpression left = parseExpressionI32(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionI32(context);
- PROPAGATE_ERROR();
- return context.buildBinaryI32(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseRelationalI32ExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- ContextExpression left = parseExpressionI32(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionI32(context);
- PROPAGATE_ERROR();
- return context.buildRelationalI32(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseRelationalF32ExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- ContextExpression left = parseExpressionF32(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionF32(context);
- PROPAGATE_ERROR();
- return context.buildRelationalF32(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseRelationalF64ExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- ContextExpression left = parseExpressionF64(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionF64(context);
- PROPAGATE_ERROR();
- return context.buildRelationalF64(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseMinOrMaxExpressionI32(Context& context, WASMOpExpressionI32 op)
-{
- uint32_t numberOfArguments;
- READ_COMPACT_UINT32_OR_FAIL(numberOfArguments, "Cannot read the number of arguments to min/max.");
- FAIL_IF_FALSE(numberOfArguments >= 2, "Min/max must be passed at least 2 arguments.");
- ContextExpression current = parseExpressionI32(context);
- PROPAGATE_ERROR();
- for (uint32_t i = 1; i < numberOfArguments; ++i) {
- ContextExpression expression = parseExpressionI32(context);
- PROPAGATE_ERROR();
- current = context.buildMinOrMaxI32(current, expression, op);
- }
- return current;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseExpressionF32(Context& context)
-{
- bool hasImmediate;
- WASMOpExpressionF32 op;
- WASMOpExpressionF32WithImmediate opWithImmediate;
- uint8_t immediate;
- READ_OP_EXPRESSION_F32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float32 expression opcode.");
- if (!hasImmediate) {
- switch (op) {
- case WASMOpExpressionF32::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionF32(context);
- case WASMOpExpressionF32::Immediate:
- return parseImmediateExpressionF32(context);
- case WASMOpExpressionF32::GetLocal:
- return parseGetLocalExpression(context, WASMType::F32);
- case WASMOpExpressionF32::GetGlobal:
- return parseGetGlobalExpression(context, WASMType::F32);
- case WASMOpExpressionF32::SetLocal:
- return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::F32);
- case WASMOpExpressionF32::SetGlobal:
- return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::F32);
- case WASMOpExpressionF32::Load:
- return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionF32::LoadWithOffset:
- return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionF32::Store:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionF32::StoreWithOffset:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionF32::CallInternal:
- return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::F32);
- case WASMOpExpressionF32::CallIndirect:
- return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::F32);
- case WASMOpExpressionF32::Conditional:
- return parseConditional(context, WASMExpressionType::F32);
- case WASMOpExpressionF32::Comma:
- return parseComma(context, WASMExpressionType::F32);
- case WASMOpExpressionF32::FromS32:
- return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertSigned);
- case WASMOpExpressionF32::FromU32:
- return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertUnsigned);
- case WASMOpExpressionF32::FromF64:
- return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::F32, WASMTypeConversion::Demote);
- case WASMOpExpressionF32::Negate:
- case WASMOpExpressionF32::Abs:
- case WASMOpExpressionF32::Ceil:
- case WASMOpExpressionF32::Floor:
- case WASMOpExpressionF32::Sqrt:
- return parseUnaryExpressionF32(context, op);
- case WASMOpExpressionF32::Add:
- case WASMOpExpressionF32::Sub:
- case WASMOpExpressionF32::Mul:
- case WASMOpExpressionF32::Div:
- return parseBinaryExpressionF32(context, op);
- default:
- ASSERT_NOT_REACHED();
- }
- } else {
- switch (opWithImmediate) {
- case WASMOpExpressionF32WithImmediate::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionF32(context, immediate);
- case WASMOpExpressionF32WithImmediate::GetLocal:
- return parseGetLocalExpression(context, WASMType::F32, immediate);
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return 0;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context, uint32_t constantIndex)
-{
- FAIL_IF_FALSE(constantIndex < m_module->f32Constants().size(), "The constant pool index is incorrect.");
- return context.buildImmediateF32(m_module->f32Constants()[constantIndex]);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context)
-{
- uint32_t constantIndex;
- READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant pool index.");
- return parseConstantPoolIndexExpressionF32(context, constantIndex);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseImmediateExpressionF32(Context& context)
-{
- float immediate;
- READ_FLOAT_OR_FAIL(immediate, "Cannot read the immediate.");
- return context.buildImmediateF32(immediate);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseUnaryExpressionF32(Context& context, WASMOpExpressionF32 op)
-{
- ContextExpression expression = parseExpressionF32(context);
- PROPAGATE_ERROR();
- return context.buildUnaryF32(expression, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseBinaryExpressionF32(Context& context, WASMOpExpressionF32 op)
-{
- ContextExpression left = parseExpressionF32(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionF32(context);
- PROPAGATE_ERROR();
- return context.buildBinaryF32(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseExpressionF64(Context& context)
-{
- bool hasImmediate;
- WASMOpExpressionF64 op;
- WASMOpExpressionF64WithImmediate opWithImmediate;
- uint8_t immediate;
- READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float64 expression opcode.");
- if (!hasImmediate) {
- switch (op) {
- case WASMOpExpressionF64::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionF64(context);
- case WASMOpExpressionF64::Immediate:
- return parseImmediateExpressionF64(context);
- case WASMOpExpressionF64::GetLocal:
- return parseGetLocalExpression(context, WASMType::F64);
- case WASMOpExpressionF64::GetGlobal:
- return parseGetGlobalExpression(context, WASMType::F64);
- case WASMOpExpressionF64::SetLocal:
- return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::F64);
- case WASMOpExpressionF64::SetGlobal:
- return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::F64);
- case WASMOpExpressionF64::Load:
- return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionF64::LoadWithOffset:
- return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionF64::Store:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
- case WASMOpExpressionF64::StoreWithOffset:
- return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
- case WASMOpExpressionF64::CallInternal:
- return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::F64);
- case WASMOpExpressionF64::CallImport:
- return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::F64);
- case WASMOpExpressionF64::CallIndirect:
- return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::F64);
- case WASMOpExpressionF64::Conditional:
- return parseConditional(context, WASMExpressionType::F64);
- case WASMOpExpressionF64::Comma:
- return parseComma(context, WASMExpressionType::F64);
- case WASMOpExpressionF64::FromS32:
- return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertSigned);
- case WASMOpExpressionF64::FromU32:
- return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertUnsigned);
- case WASMOpExpressionF64::FromF32:
- return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::F64, WASMTypeConversion::Promote);
- case WASMOpExpressionF64::Negate:
- case WASMOpExpressionF64::Abs:
- case WASMOpExpressionF64::Ceil:
- case WASMOpExpressionF64::Floor:
- case WASMOpExpressionF64::Sqrt:
- case WASMOpExpressionF64::Cos:
- case WASMOpExpressionF64::Sin:
- case WASMOpExpressionF64::Tan:
- case WASMOpExpressionF64::ACos:
- case WASMOpExpressionF64::ASin:
- case WASMOpExpressionF64::ATan:
- case WASMOpExpressionF64::Exp:
- case WASMOpExpressionF64::Ln:
- return parseUnaryExpressionF64(context, op);
- case WASMOpExpressionF64::Add:
- case WASMOpExpressionF64::Sub:
- case WASMOpExpressionF64::Mul:
- case WASMOpExpressionF64::Div:
- case WASMOpExpressionF64::Mod:
- case WASMOpExpressionF64::ATan2:
- case WASMOpExpressionF64::Pow:
- return parseBinaryExpressionF64(context, op);
- case WASMOpExpressionF64::Min:
- case WASMOpExpressionF64::Max:
- return parseMinOrMaxExpressionF64(context, op);
- default:
- ASSERT_NOT_REACHED();
- }
- } else {
- switch (opWithImmediate) {
- case WASMOpExpressionF64WithImmediate::ConstantPoolIndex:
- return parseConstantPoolIndexExpressionF64(context, immediate);
- case WASMOpExpressionF64WithImmediate::GetLocal:
- return parseGetLocalExpression(context, WASMType::F64, immediate);
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return 0;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context, uint32_t constantIndex)
-{
- FAIL_IF_FALSE(constantIndex < m_module->f64Constants().size(), "The constant index is incorrect.");
- return context.buildImmediateF64(m_module->f64Constants()[constantIndex]);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context)
-{
- uint32_t constantIndex;
- READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
- return parseConstantPoolIndexExpressionF64(context, constantIndex);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseImmediateExpressionF64(Context& context)
-{
- double immediate;
- READ_DOUBLE_OR_FAIL(immediate, "Cannot read the immediate.");
- return context.buildImmediateF64(immediate);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseUnaryExpressionF64(Context& context, WASMOpExpressionF64 op)
-{
- ContextExpression expression = parseExpressionF64(context);
- PROPAGATE_ERROR();
- return context.buildUnaryF64(expression, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseBinaryExpressionF64(Context& context, WASMOpExpressionF64 op)
-{
- ContextExpression left = parseExpressionF64(context);
- PROPAGATE_ERROR();
- ContextExpression right = parseExpressionF64(context);
- PROPAGATE_ERROR();
- return context.buildBinaryF64(left, right, op);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseMinOrMaxExpressionF64(Context& context, WASMOpExpressionF64 op)
-{
- uint32_t numberOfArguments;
- READ_COMPACT_UINT32_OR_FAIL(numberOfArguments, "Cannot read the number of arguments to min/max.");
- FAIL_IF_FALSE(numberOfArguments >= 2, "Min/max must be passed at least 2 arguments.");
- ContextExpression current = parseExpressionF64(context);
- PROPAGATE_ERROR();
- for (uint32_t i = 1; i < numberOfArguments; ++i) {
- ContextExpression expression = parseExpressionF64(context);
- PROPAGATE_ERROR();
- current = context.buildMinOrMaxF64(current, expression, op);
- }
- return current;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseExpressionVoid(Context& context)
-{
- WASMOpExpressionVoid op;
- READ_OP_EXPRESSION_VOID_OR_FAIL(op, "Cannot read the void expression opcode.");
- switch (op) {
- case WASMOpExpressionVoid::CallInternal:
- return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::Void);
- case WASMOpExpressionVoid::CallIndirect:
- return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::Void);
- case WASMOpExpressionVoid::CallImport:
- return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::Void);
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseGetLocalExpression(Context& context, WASMType type, uint32_t localIndex)
-{
- FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local index is incorrect.");
- FAIL_IF_FALSE(m_localTypes[localIndex] == type, "Expected a local of type " + nameOfType(type) + '.');
- return context.buildGetLocal(localIndex, type);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseGetLocalExpression(Context& context, WASMType type)
-{
- uint32_t localIndex;
- READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
- return parseGetLocalExpression(context, type, localIndex);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseGetGlobalExpression(Context& context, WASMType type)
-{
- uint32_t globalIndex;
- READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
- FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
- FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == type, "Expected a global of type " + nameOfType(type) + '.');
- return context.buildGetGlobal(globalIndex, type);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseSetLocal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, uint32_t localIndex)
-{
- FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
- WASMType type = m_localTypes[localIndex];
- if (opKind == WASMOpKind::Expression)
- FAIL_IF_FALSE(expressionType == WASMExpressionType(type), "The type doesn't match.");
- ContextExpression expression = parseExpression(context, WASMExpressionType(type));
- PROPAGATE_ERROR();
- return context.buildSetLocal(opKind, localIndex, expression, type);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseSetLocal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType)
-{
- uint32_t localIndex;
- READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
- return parseSetLocal(context, opKind, expressionType, localIndex);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseSetGlobal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, uint32_t globalIndex)
-{
- FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
- WASMType type = m_module->globalVariableTypes()[globalIndex];
- if (opKind == WASMOpKind::Expression)
- FAIL_IF_FALSE(expressionType == WASMExpressionType(type), "The type doesn't match.");
- ContextExpression expression = parseExpression(context, WASMExpressionType(type));
- PROPAGATE_ERROR();
- return context.buildSetGlobal(opKind, globalIndex, expression, type);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseSetGlobal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType)
-{
- uint32_t globalIndex;
- READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
- return parseSetGlobal(context, opKind, expressionType, globalIndex);
-}
-
-template <class Context>
-ContextMemoryAddress WASMFunctionParser::parseMemoryAddress(Context& context, MemoryAccessOffsetMode offsetMode)
-{
- uint32_t offset = 0;
- if (offsetMode == MemoryAccessOffsetMode::WithOffset)
- READ_COMPACT_UINT32_OR_FAIL(offset, "Cannot read the address offset.");
- ContextExpression index = parseExpressionI32(context);
- PROPAGATE_ERROR();
- return ContextMemoryAddress(index, offset);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseLoad(Context& context, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode, MemoryAccessConversion conversion)
-{
- FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided.");
- const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode);
- PROPAGATE_ERROR();
- return context.buildLoad(memoryAddress, expressionType, memoryType, conversion);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseStore(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode)
-{
- FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided.");
- const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode);
- PROPAGATE_ERROR();
-
- ContextExpression value = parseExpression(context, expressionType);
- PROPAGATE_ERROR();
- return context.buildStore(opKind, memoryAddress, expressionType, memoryType, value);
-}
-
-template <class Context>
-ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments)
-{
- ContextExpressionList argumentList;
- for (size_t i = 0; i < arguments.size(); ++i) {
- ContextExpression expression = parseExpression(context, WASMExpressionType(arguments[i]));
- PROPAGATE_ERROR();
- context.appendExpressionList(argumentList, expression);
- }
- return argumentList;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseCallInternal(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
-{
- uint32_t functionIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
- FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
- const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[functionIndex].signatureIndex];
- if (opKind == WASMOpKind::Expression)
- FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
-
- ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
- PROPAGATE_ERROR();
- return context.buildCallInternal(functionIndex, argumentList, signature, returnType);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseCallIndirect(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
-{
- uint32_t functionPointerTableIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionPointerTableIndex, "Cannot read the function pointer table index.");
- FAIL_IF_FALSE(functionPointerTableIndex < m_module->functionPointerTables().size(), "The function pointer table index is incorrect.");
- const WASMFunctionPointerTable& functionPointerTable = m_module->functionPointerTables()[functionPointerTableIndex];
- const WASMSignature& signature = m_module->signatures()[functionPointerTable.signatureIndex];
- if (opKind == WASMOpKind::Expression)
- FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
-
- ContextExpression index = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
- PROPAGATE_ERROR();
- return context.buildCallIndirect(functionPointerTableIndex, index, argumentList, signature, returnType);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseCallImport(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
-{
- uint32_t functionImportSignatureIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionImportSignatureIndex, "Cannot read the function import signature index.");
- FAIL_IF_FALSE(functionImportSignatureIndex < m_module->functionImportSignatures().size(), "The function import signature index is incorrect.");
- const WASMFunctionImportSignature& functionImportSignature = m_module->functionImportSignatures()[functionImportSignatureIndex];
- const WASMSignature& signature = m_module->signatures()[functionImportSignature.signatureIndex];
- if (opKind == WASMOpKind::Expression)
- FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
-
- ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
- PROPAGATE_ERROR();
- return context.buildCallImport(functionImportSignature.functionImportIndex, argumentList, signature, returnType);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConditional(Context& context, WASMExpressionType expressionType)
-{
- ContextJumpTarget elseTarget;
- ContextJumpTarget end;
-
- ContextExpression condition = parseExpressionI32(context);
- PROPAGATE_ERROR();
-
- context.jumpToTargetIf(Context::JumpCondition::Zero, condition, elseTarget);
-
- parseExpression(context, expressionType);
- PROPAGATE_ERROR();
-
- context.jumpToTarget(end);
- context.linkTarget(elseTarget);
-
- // We use discard() here to decrement the stack top in the baseline JIT.
- context.discard(UNUSED);
- parseExpression(context, expressionType);
- PROPAGATE_ERROR();
-
- context.linkTarget(end);
- return UNUSED;
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseComma(Context& context, WASMExpressionType expressionType)
-{
- WASMExpressionType leftExpressionType;
- READ_EXPRESSION_TYPE_OR_FAIL(leftExpressionType, "Cannot read the expression type.");
- ContextExpression leftExpression = parseExpression(context, leftExpressionType);
- PROPAGATE_ERROR();
- if (leftExpressionType != WASMExpressionType::Void)
- context.discard(leftExpression);
- return parseExpression(context, expressionType);
-}
-
-template <class Context>
-ContextExpression WASMFunctionParser::parseConvertType(Context& context, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion conversion)
-{
- ContextExpression expression = parseExpression(context, fromType);
- PROPAGATE_ERROR();
-
- return context.buildConvertType(expression, fromType, toType, conversion);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WASMFunctionParser.h b/Source/JavaScriptCore/wasm/WASMFunctionParser.h
deleted file mode 100644
index 7f09e3e85..000000000
--- a/Source/JavaScriptCore/wasm/WASMFunctionParser.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMFunctionParser_h
-#define WASMFunctionParser_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "SourceCode.h"
-#include "WASMReader.h"
-
-#define ContextExpression typename Context::Expression
-#define ContextStatement typename Context::Statement
-#define ContextExpressionList typename Context::ExpressionList
-#define ContextMemoryAddress typename Context::MemoryAddress
-#define ContextJumpTarget typename Context::JumpTarget
-
-namespace JSC {
-
-class CodeBlock;
-class JSWASMModule;
-class VM;
-
-class WASMFunctionParser {
-public:
- static bool checkSyntax(JSWASMModule*, const SourceCode&, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage);
- static void compile(VM&, CodeBlock*, JSWASMModule*, const SourceCode&, size_t functionIndex);
-
-private:
- WASMFunctionParser(JSWASMModule* module, const SourceCode& source, size_t functionIndex)
- : m_module(module)
- , m_reader(static_cast<WebAssemblySourceProvider*>(source.provider())->data())
- , m_functionIndex(functionIndex)
- , m_breakScopeDepth(0)
- , m_continueScopeDepth(0)
- , m_labelDepth(0)
- {
- }
-
- template <class Context> bool parseFunction(Context&);
- bool parseLocalVariables();
-
- template <class Context> ContextStatement parseStatement(Context&);
- template <class Context> ContextStatement parseReturnStatement(Context&);
- template <class Context> ContextStatement parseBlockStatement(Context&);
- template <class Context> ContextStatement parseIfStatement(Context&);
- template <class Context> ContextStatement parseIfElseStatement(Context&);
- template <class Context> ContextStatement parseWhileStatement(Context&);
- template <class Context> ContextStatement parseDoStatement(Context&);
- template <class Context> ContextStatement parseLabelStatement(Context&);
- template <class Context> ContextStatement parseBreakStatement(Context&);
- template <class Context> ContextStatement parseBreakLabelStatement(Context&);
- template <class Context> ContextStatement parseContinueStatement(Context&);
- template <class Context> ContextStatement parseContinueLabelStatement(Context&);
- template <class Context> ContextStatement parseSwitchStatement(Context&);
-
- template <class Context> ContextExpression parseExpression(Context&, WASMExpressionType);
-
- template <class Context> ContextExpression parseExpressionI32(Context&);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionI32(Context&, uint32_t constantPoolIndex);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionI32(Context&);
- template <class Context> ContextExpression parseImmediateExpressionI32(Context&, uint32_t immediate);
- template <class Context> ContextExpression parseImmediateExpressionI32(Context&);
- template <class Context> ContextExpression parseUnaryExpressionI32(Context&, WASMOpExpressionI32);
- template <class Context> ContextExpression parseBinaryExpressionI32(Context&, WASMOpExpressionI32);
- template <class Context> ContextExpression parseRelationalI32ExpressionI32(Context&, WASMOpExpressionI32);
- template <class Context> ContextExpression parseRelationalF32ExpressionI32(Context&, WASMOpExpressionI32);
- template <class Context> ContextExpression parseRelationalF64ExpressionI32(Context&, WASMOpExpressionI32);
- template <class Context> ContextExpression parseMinOrMaxExpressionI32(Context&, WASMOpExpressionI32);
-
- template <class Context> ContextExpression parseExpressionF32(Context&);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionF32(Context&, uint32_t constantIndex);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionF32(Context&);
- template <class Context> ContextExpression parseImmediateExpressionF32(Context&);
- template <class Context> ContextExpression parseUnaryExpressionF32(Context&, WASMOpExpressionF32);
- template <class Context> ContextExpression parseBinaryExpressionF32(Context&, WASMOpExpressionF32);
-
- template <class Context> ContextExpression parseExpressionF64(Context&);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionF64(Context&, uint32_t constantIndex);
- template <class Context> ContextExpression parseConstantPoolIndexExpressionF64(Context&);
- template <class Context> ContextExpression parseImmediateExpressionF64(Context&);
- template <class Context> ContextExpression parseUnaryExpressionF64(Context&, WASMOpExpressionF64);
- template <class Context> ContextExpression parseBinaryExpressionF64(Context&, WASMOpExpressionF64);
- template <class Context> ContextExpression parseMinOrMaxExpressionF64(Context&, WASMOpExpressionF64);
-
- template <class Context> ContextExpression parseExpressionVoid(Context&);
-
- template <class Context> ContextExpression parseGetLocalExpression(Context&, WASMType, uint32_t localIndex);
- template <class Context> ContextExpression parseGetLocalExpression(Context&, WASMType);
- template <class Context> ContextExpression parseGetGlobalExpression(Context&, WASMType);
- template <class Context> ContextExpression parseSetLocal(Context&, WASMOpKind, WASMExpressionType, uint32_t localIndex);
- template <class Context> ContextExpression parseSetLocal(Context&, WASMOpKind, WASMExpressionType);
- template <class Context> ContextExpression parseSetGlobal(Context&, WASMOpKind, WASMExpressionType, uint32_t globalIndex);
- template <class Context> ContextExpression parseSetGlobal(Context&, WASMOpKind, WASMExpressionType);
- template <class Context> ContextMemoryAddress parseMemoryAddress(Context&, MemoryAccessOffsetMode);
- template <class Context> ContextExpression parseLoad(Context&, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode, MemoryAccessConversion = MemoryAccessConversion::NoConversion);
- template <class Context> ContextExpression parseStore(Context&, WASMOpKind, WASMExpressionType, WASMMemoryType, MemoryAccessOffsetMode);
- template <class Context> ContextExpressionList parseCallArguments(Context&, const Vector<WASMType>& arguments);
- template <class Context> ContextExpression parseCallInternal(Context&, WASMOpKind, WASMExpressionType returnType);
- template <class Context> ContextExpression parseCallIndirect(Context&, WASMOpKind, WASMExpressionType returnType);
- template <class Context> ContextExpression parseCallImport(Context&, WASMOpKind, WASMExpressionType returnType);
- template <class Context> ContextExpression parseConditional(Context&, WASMExpressionType);
- template <class Context> ContextExpression parseComma(Context&, WASMExpressionType);
- template <class Context> ContextExpression parseConvertType(Context&, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion);
-
- JSWASMModule* m_module;
- WASMReader m_reader;
- size_t m_functionIndex;
- String m_errorMessage;
-
- WASMExpressionType m_returnType;
- Vector<WASMType> m_localTypes;
- uint32_t m_numberOfI32LocalVariables;
- uint32_t m_numberOfF32LocalVariables;
- uint32_t m_numberOfF64LocalVariables;
-
- unsigned m_breakScopeDepth;
- unsigned m_continueScopeDepth;
- unsigned m_labelDepth;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMFunctionParser_h
diff --git a/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h b/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
deleted file mode 100644
index edfe42808..000000000
--- a/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMFunctionSyntaxChecker_h
-#define WASMFunctionSyntaxChecker_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#define UNUSED 0
-
-namespace JSC {
-
-class WASMFunctionSyntaxChecker {
-public:
- typedef int Expression;
- typedef int Statement;
- typedef int ExpressionList;
- struct MemoryAddress {
- MemoryAddress(void*) { }
- MemoryAddress(int, uint32_t) { }
- };
- typedef int JumpTarget;
- enum class JumpCondition { Zero, NonZero };
-
- void startFunction(const Vector<WASMType>& arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
- {
- m_numberOfLocals = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
- }
-
- void endFunction()
- {
- ASSERT(!m_tempStackTop);
- }
-
- int buildSetLocal(WASMOpKind opKind, uint32_t, int, WASMType)
- {
- if (opKind == WASMOpKind::Statement)
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildSetGlobal(WASMOpKind opKind, uint32_t, int, WASMType)
- {
- if (opKind == WASMOpKind::Statement)
- m_tempStackTop--;
- return UNUSED;
- }
-
- void buildReturn(int, WASMExpressionType returnType)
- {
- if (returnType != WASMExpressionType::Void)
- m_tempStackTop--;
- }
-
- int buildImmediateI32(uint32_t)
- {
- m_tempStackTop++;
- updateTempStackHeight();
- return UNUSED;
- }
-
- int buildImmediateF32(float)
- {
- m_tempStackTop++;
- updateTempStackHeight();
- return UNUSED;
- }
-
- int buildImmediateF64(double)
- {
- m_tempStackTop++;
- updateTempStackHeight();
- return UNUSED;
- }
-
- int buildGetLocal(uint32_t, WASMType)
- {
- m_tempStackTop++;
- updateTempStackHeight();
- return UNUSED;
- }
-
- int buildGetGlobal(uint32_t, WASMType)
- {
- m_tempStackTop++;
- updateTempStackHeight();
- return UNUSED;
- }
-
- int buildConvertType(int, WASMExpressionType, WASMExpressionType, WASMTypeConversion)
- {
- return UNUSED;
- }
-
- int buildLoad(const MemoryAddress&, WASMExpressionType, WASMMemoryType, MemoryAccessConversion)
- {
- return UNUSED;
- }
-
- int buildStore(WASMOpKind opKind, const MemoryAddress&, WASMExpressionType, WASMMemoryType, int)
- {
- m_tempStackTop -= 2;
- if (opKind == WASMOpKind::Expression)
- m_tempStackTop++;
- return UNUSED;
- }
-
- int buildUnaryI32(int, WASMOpExpressionI32)
- {
- return UNUSED;
- }
-
- int buildUnaryF32(int, WASMOpExpressionF32)
- {
- return UNUSED;
- }
-
- int buildUnaryF64(int, WASMOpExpressionF64)
- {
- return UNUSED;
- }
-
- int buildBinaryI32(int, int, WASMOpExpressionI32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildBinaryF32(int, int, WASMOpExpressionF32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildBinaryF64(int, int, WASMOpExpressionF64)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildRelationalI32(int, int, WASMOpExpressionI32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildRelationalF32(int, int, WASMOpExpressionI32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildRelationalF64(int, int, WASMOpExpressionI32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildMinOrMaxI32(int, int, WASMOpExpressionI32)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildMinOrMaxF64(int, int, WASMOpExpressionF64)
- {
- m_tempStackTop--;
- return UNUSED;
- }
-
- int buildCallInternal(uint32_t, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- size_t argumentCount = signature.arguments.size();
- updateTempStackHeightForCall(argumentCount);
- m_tempStackTop -= argumentCount;
- if (returnType != WASMExpressionType::Void) {
- m_tempStackTop++;
- updateTempStackHeight();
- }
- return UNUSED;
- }
-
- int buildCallImport(uint32_t, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- size_t argumentCount = signature.arguments.size();
- updateTempStackHeightForCall(argumentCount);
- m_tempStackTop -= argumentCount;
- if (returnType != WASMExpressionType::Void) {
- m_tempStackTop++;
- updateTempStackHeight();
- }
- return UNUSED;
- }
-
- int buildCallIndirect(uint32_t, int, int, const WASMSignature& signature, WASMExpressionType returnType)
- {
- size_t argumentCount = signature.arguments.size();
- updateTempStackHeightForCall(argumentCount);
- m_tempStackTop -= argumentCount + 1;
- if (returnType != WASMExpressionType::Void)
- m_tempStackTop++;
- return UNUSED;
- }
-
- void appendExpressionList(int&, int) { }
-
- void discard(int)
- {
- m_tempStackTop--;
- }
-
- void linkTarget(const int&) { }
- void jumpToTarget(const int&) { }
- void jumpToTargetIf(JumpCondition, int, const int&)
- {
- m_tempStackTop--;
- }
-
- void startLoop() { }
- void endLoop() { }
- void startSwitch() { }
- void endSwitch() { }
- void startLabel() { }
- void endLabel() { }
-
- int breakTarget() { return UNUSED; }
- int continueTarget() { return UNUSED; }
- int breakLabelTarget(uint32_t) { return UNUSED; }
- int continueLabelTarget(uint32_t) { return UNUSED; }
-
- void buildSwitch(int, const Vector<int64_t>&, const Vector<int>&, const int&)
- {
- m_tempStackTop--;
- }
-
- unsigned stackHeight()
- {
- return m_numberOfLocals + m_tempStackHeight;
- }
-
-private:
- void updateTempStackHeight()
- {
- if (m_tempStackTop > m_tempStackHeight)
- m_tempStackHeight = m_tempStackTop;
- }
-
- void updateTempStackHeightForCall(size_t argumentCount)
- {
- // Boxed arguments + this argument + call frame header + maximum padding.
- m_tempStackTop += argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
- updateTempStackHeight();
- m_tempStackTop -= argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
- }
-
- unsigned m_numberOfLocals;
- unsigned m_tempStackTop { 0 };
- unsigned m_tempStackHeight { 0 };
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMFunctionSyntaxChecker_h
diff --git a/Source/JavaScriptCore/wasm/WASMModuleParser.cpp b/Source/JavaScriptCore/wasm/WASMModuleParser.cpp
deleted file mode 100644
index 8ce35f483..000000000
--- a/Source/JavaScriptCore/wasm/WASMModuleParser.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WASMModuleParser.h"
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "JSArrayBuffer.h"
-#include "JSCInlines.h"
-#include "JSWASMModule.h"
-#include "StrongInlines.h"
-#include "WASMConstants.h"
-#include "WASMFunctionParser.h"
-#include <wtf/MathExtras.h>
-
-#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return; } while (0)
-#define READ_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_STRING_OR_FAIL(result, errorMessage) do { if (!m_reader.readString(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_EXPRESSION_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readExpressionType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define READ_EXPORT_FORMAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readExportFormat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
-#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return; } while (0)
-
-namespace JSC {
-
-WASMModuleParser::WASMModuleParser(VM& vm, JSGlobalObject* globalObject, const SourceCode& source, JSObject* imports, JSArrayBuffer* arrayBuffer)
- : m_vm(vm)
- , m_globalObject(vm, globalObject)
- , m_source(source)
- , m_imports(vm, imports)
- , m_reader(static_cast<WebAssemblySourceProvider*>(source.provider())->data())
- , m_module(vm, JSWASMModule::create(vm, globalObject->wasmModuleStructure(), arrayBuffer))
-{
-}
-
-JSWASMModule* WASMModuleParser::parse(ExecState* exec, String& errorMessage)
-{
- parseModule(exec);
- if (!m_errorMessage.isNull()) {
- errorMessage = m_errorMessage;
- return nullptr;
- }
- return m_module.get();
-}
-
-void WASMModuleParser::parseModule(ExecState* exec)
-{
- uint32_t magicNumber;
- READ_UINT32_OR_FAIL(magicNumber, "Cannot read the magic number.");
- FAIL_IF_FALSE(magicNumber == wasmMagicNumber, "The magic number is incorrect.");
-
- uint32_t outputSizeInASMJS;
- READ_UINT32_OR_FAIL(outputSizeInASMJS, "Cannot read the output size in asm.js format.");
-
- parseConstantPoolSection();
- PROPAGATE_ERROR();
- parseSignatureSection();
- PROPAGATE_ERROR();
- parseFunctionImportSection(exec);
- PROPAGATE_ERROR();
- parseGlobalSection(exec);
- PROPAGATE_ERROR();
- parseFunctionDeclarationSection();
- PROPAGATE_ERROR();
- parseFunctionPointerTableSection();
- PROPAGATE_ERROR();
- parseFunctionDefinitionSection();
- PROPAGATE_ERROR();
- parseExportSection();
- PROPAGATE_ERROR();
-
- FAIL_IF_FALSE(!m_module->arrayBuffer() || m_module->arrayBuffer()->impl()->byteLength() < (1u << 31), "The ArrayBuffer's length must be less than 2^31.");
-}
-
-void WASMModuleParser::parseConstantPoolSection()
-{
- uint32_t numberOfI32Constants;
- uint32_t numberOfF32Constants;
- uint32_t numberOfF64Constants;
- READ_COMPACT_UINT32_OR_FAIL(numberOfI32Constants, "Cannot read the number of int32 constants.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfF32Constants, "Cannot read the number of float32 constants.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfF64Constants, "Cannot read the number of float64 constants.");
- m_module->i32Constants().reserveInitialCapacity(numberOfI32Constants);
- m_module->f32Constants().reserveInitialCapacity(numberOfF32Constants);
- m_module->f64Constants().reserveInitialCapacity(numberOfF64Constants);
-
- for (uint32_t i = 0; i < numberOfI32Constants; ++i) {
- uint32_t constant;
- READ_COMPACT_UINT32_OR_FAIL(constant, "Cannot read an int32 constant.");
- m_module->i32Constants().uncheckedAppend(constant);
- }
- for (uint32_t i = 0; i < numberOfF32Constants; ++i) {
- float constant;
- READ_FLOAT_OR_FAIL(constant, "Cannot read a float32 constant.");
- m_module->f32Constants().uncheckedAppend(constant);
- }
- for (uint32_t i = 0; i < numberOfF64Constants; ++i) {
- double constant;
- READ_DOUBLE_OR_FAIL(constant, "Cannot read a float64 constant.");
- m_module->f64Constants().uncheckedAppend(constant);
- }
-}
-
-void WASMModuleParser::parseSignatureSection()
-{
- uint32_t numberOfSignatures;
- READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
- m_module->signatures().reserveInitialCapacity(numberOfSignatures);
- for (uint32_t signatureIndex = 0; signatureIndex < numberOfSignatures; ++signatureIndex) {
- WASMSignature signature;
- READ_EXPRESSION_TYPE_OR_FAIL(signature.returnType, "Cannot read the return type.");
- uint32_t argumentCount;
- READ_COMPACT_UINT32_OR_FAIL(argumentCount, "Cannot read the number of arguments.");
- signature.arguments.reserveInitialCapacity(argumentCount);
- for (uint32_t argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
- WASMType type;
- READ_TYPE_OR_FAIL(type, "Cannot read the type of an argument.");
- signature.arguments.uncheckedAppend(type);
- }
- m_module->signatures().uncheckedAppend(signature);
- }
-}
-
-void WASMModuleParser::parseFunctionImportSection(ExecState* exec)
-{
- uint32_t numberOfFunctionImports;
- uint32_t numberOfFunctionImportSignatures;
- READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImports, "Cannot read the number of function imports.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, "Cannot read the number of function import signatures.");
- m_module->functionImports().reserveInitialCapacity(numberOfFunctionImports);
- m_module->functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);
- m_module->importedFunctions().reserveInitialCapacity(numberOfFunctionImports);
-
- for (uint32_t functionImportIndex = 0; functionImportIndex < numberOfFunctionImports; ++functionImportIndex) {
- WASMFunctionImport functionImport;
- READ_STRING_OR_FAIL(functionImport.functionName, "Cannot read the function import name.");
- m_module->functionImports().uncheckedAppend(functionImport);
-
- uint32_t numberOfSignatures;
- READ_COMPACT_UINT32_OR_FAIL(numberOfSignatures, "Cannot read the number of signatures.");
- FAIL_IF_FALSE(numberOfSignatures <= numberOfFunctionImportSignatures - m_module->functionImportSignatures().size(), "The number of signatures is incorrect.");
-
- for (uint32_t i = 0; i < numberOfSignatures; ++i) {
- WASMFunctionImportSignature functionImportSignature;
- READ_COMPACT_UINT32_OR_FAIL(functionImportSignature.signatureIndex, "Cannot read the signature index.");
- FAIL_IF_FALSE(functionImportSignature.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
- functionImportSignature.functionImportIndex = functionImportIndex;
- m_module->functionImportSignatures().uncheckedAppend(functionImportSignature);
- }
-
- JSValue value;
- getImportedValue(exec, functionImport.functionName, value);
- PROPAGATE_ERROR();
- FAIL_IF_FALSE(value.isFunction(), "\"" + functionImport.functionName + "\" is not a function.");
- JSFunction* function = jsCast<JSFunction*>(value.asCell());
- m_module->importedFunctions().uncheckedAppend(WriteBarrier<JSFunction>(m_vm, m_module.get(), function));
- }
- FAIL_IF_FALSE(m_module->functionImportSignatures().size() == numberOfFunctionImportSignatures, "The number of function import signatures is incorrect.");
-}
-
-void WASMModuleParser::parseGlobalSection(ExecState* exec)
-{
- uint32_t numberOfInternalI32GlobalVariables;
- uint32_t numberOfInternalF32GlobalVariables;
- uint32_t numberOfInternalF64GlobalVariables;
- uint32_t numberOfImportedI32GlobalVariables;
- uint32_t numberOfImportedF32GlobalVariables;
- uint32_t numberOfImportedF64GlobalVariables;
- READ_COMPACT_UINT32_OR_FAIL(numberOfInternalI32GlobalVariables, "Cannot read the number of internal int32 global variables.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF32GlobalVariables, "Cannot read the number of internal float32 global variables.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfInternalF64GlobalVariables, "Cannot read the number of internal float64 global variables.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfImportedI32GlobalVariables, "Cannot read the number of imported int32 global variables.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF32GlobalVariables, "Cannot read the number of imported float32 global variables.");
- READ_COMPACT_UINT32_OR_FAIL(numberOfImportedF64GlobalVariables, "Cannot read the number of imported float64 global variables.");
- uint32_t numberOfGlobalVariables = numberOfInternalI32GlobalVariables + numberOfInternalF32GlobalVariables + numberOfInternalF64GlobalVariables +
- numberOfImportedI32GlobalVariables + numberOfImportedF32GlobalVariables + numberOfImportedF64GlobalVariables;
-
- Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
- globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
- Vector<JSWASMModule::GlobalVariable>& globalVariables = m_module->globalVariables();
- globalVariables.reserveInitialCapacity(numberOfGlobalVariables);
- for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i) {
- globalVariableTypes.uncheckedAppend(WASMType::I32);
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0));
- }
- for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i) {
- globalVariableTypes.uncheckedAppend(WASMType::F32);
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0f));
- }
- for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i) {
- globalVariableTypes.uncheckedAppend(WASMType::F64);
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0));
- }
- for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
- String importName;
- READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
- globalVariableTypes.uncheckedAppend(WASMType::I32);
- JSValue value;
- getImportedValue(exec, importName, value);
- PROPAGATE_ERROR();
- FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(value.toInt32(exec)));
- }
- for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
- String importName;
- READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
- globalVariableTypes.uncheckedAppend(WASMType::F32);
- JSValue value;
- getImportedValue(exec, importName, value);
- PROPAGATE_ERROR();
- FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(static_cast<float>(value.toNumber(exec))));
- }
- for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
- String importName;
- READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
- globalVariableTypes.uncheckedAppend(WASMType::F64);
- JSValue value;
- getImportedValue(exec, importName, value);
- PROPAGATE_ERROR();
- FAIL_IF_FALSE(value.isPrimitive() && !value.isSymbol(), "\"" + importName + "\" is not a primitive or is a Symbol.");
- globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(value.toNumber(exec)));
- }
-}
-
-void WASMModuleParser::parseFunctionDeclarationSection()
-{
- uint32_t numberOfFunctionDeclarations;
- READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, "Cannot read the number of function declarations.");
- m_module->functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
- m_module->functions().reserveInitialCapacity(numberOfFunctionDeclarations);
- m_module->functionStartOffsetsInSource().reserveInitialCapacity(numberOfFunctionDeclarations);
- m_module->functionStackHeights().reserveInitialCapacity(numberOfFunctionDeclarations);
- for (uint32_t i = 0; i < numberOfFunctionDeclarations; ++i) {
- WASMFunctionDeclaration functionDeclaration;
- READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, "Cannot read the signature index.");
- FAIL_IF_FALSE(functionDeclaration.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
- m_module->functionDeclarations().uncheckedAppend(functionDeclaration);
- }
-}
-
-void WASMModuleParser::parseFunctionPointerTableSection()
-{
- uint32_t numberOfFunctionPointerTables;
- READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionPointerTables, "Cannot read the number of function pointer tables.");
- m_module->functionPointerTables().reserveInitialCapacity(numberOfFunctionPointerTables);
- for (uint32_t i = 0; i < numberOfFunctionPointerTables; ++i) {
- WASMFunctionPointerTable functionPointerTable;
- READ_COMPACT_UINT32_OR_FAIL(functionPointerTable.signatureIndex, "Cannot read the signature index.");
- FAIL_IF_FALSE(functionPointerTable.signatureIndex < m_module->signatures().size(), "The signature index is incorrect.");
- uint32_t numberOfFunctions;
- READ_COMPACT_UINT32_OR_FAIL(numberOfFunctions, "Cannot read the number of functions of a function pointer table.");
- FAIL_IF_FALSE(hasOneBitSet(numberOfFunctions), "The number of functions must be a power of two.");
- functionPointerTable.functionIndices.reserveInitialCapacity(numberOfFunctions);
- functionPointerTable.functions.reserveInitialCapacity(numberOfFunctions);
- for (uint32_t j = 0; j < numberOfFunctions; ++j) {
- uint32_t functionIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read a function index of a function pointer table.");
- FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
- FAIL_IF_FALSE(m_module->functionDeclarations()[functionIndex].signatureIndex == functionPointerTable.signatureIndex, "The signature of the function doesn't match that of the function pointer table.");
- functionPointerTable.functionIndices.uncheckedAppend(functionIndex);
- }
- m_module->functionPointerTables().uncheckedAppend(functionPointerTable);
- }
-}
-
-void WASMModuleParser::parseFunctionDefinitionSection()
-{
- for (size_t functionIndex = 0; functionIndex < m_module->functionDeclarations().size(); ++functionIndex) {
- parseFunctionDefinition(functionIndex);
- PROPAGATE_ERROR();
- }
-
- for (WASMFunctionPointerTable& functionPointerTable : m_module->functionPointerTables()) {
- for (size_t i = 0; i < functionPointerTable.functionIndices.size(); ++i)
- functionPointerTable.functions.uncheckedAppend(m_module->functions()[functionPointerTable.functionIndices[i]].get());
- }
-}
-
-void WASMModuleParser::parseFunctionDefinition(size_t functionIndex)
-{
- unsigned startOffsetInSource = m_reader.offset();
- unsigned endOffsetInSource;
- unsigned stackHeight;
- String errorMessage;
- if (!WASMFunctionParser::checkSyntax(m_module.get(), m_source, functionIndex, startOffsetInSource, endOffsetInSource, stackHeight, errorMessage)) {
- m_errorMessage = errorMessage;
- return;
- }
- m_reader.setOffset(endOffsetInSource);
-
- WebAssemblyExecutable* webAssemblyExecutable = WebAssemblyExecutable::create(m_vm, m_source, m_module.get(), functionIndex);
- JSFunction* function = JSFunction::create(m_vm, webAssemblyExecutable, m_globalObject.get());
- m_module->functions().uncheckedAppend(WriteBarrier<JSFunction>(m_vm, m_module.get(), function));
- m_module->functionStartOffsetsInSource().uncheckedAppend(startOffsetInSource);
- m_module->functionStackHeights().uncheckedAppend(stackHeight);
-}
-
-void WASMModuleParser::parseExportSection()
-{
- WASMExportFormat exportFormat;
- READ_EXPORT_FORMAT_OR_FAIL(exportFormat, "Cannot read the export format.");
- switch (exportFormat) {
- case WASMExportFormat::Default: {
- uint32_t functionIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
- FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
- // FIXME: Export the function.
- break;
- }
- case WASMExportFormat::Record: {
- uint32_t numberOfExports;
- READ_COMPACT_UINT32_OR_FAIL(numberOfExports, "Cannot read the number of exports.");
- for (uint32_t exportIndex = 0; exportIndex < numberOfExports; ++exportIndex) {
- String exportName;
- READ_STRING_OR_FAIL(exportName, "Cannot read the function export name.");
- uint32_t functionIndex;
- READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
- FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
- Identifier identifier = Identifier::fromString(&m_vm, exportName);
- m_module->putDirect(m_vm, identifier, m_module->functions()[functionIndex].get());
- }
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-void WASMModuleParser::getImportedValue(ExecState* exec, const String& importName, JSValue& value)
-{
- FAIL_IF_FALSE(m_imports, "Accessing property of non-object.");
- Identifier identifier = Identifier::fromString(&m_vm, importName);
- PropertySlot slot(m_imports.get(), PropertySlot::InternalMethodType::Get);
- if (!m_imports->getPropertySlot(exec, identifier, slot))
- FAIL_WITH_MESSAGE("Can't find a property named \"" + importName + '"');
- FAIL_IF_FALSE(slot.isValue(), "\"" + importName + "\" is not a data property.");
- // We only retrieve data properties. So, this does not cause any user-observable effect.
- value = slot.getValue(exec, identifier);
-}
-
-JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode& source, JSObject* imports, JSArrayBuffer* arrayBuffer, String& errorMessage)
-{
- WASMModuleParser moduleParser(exec->vm(), exec->lexicalGlobalObject(), source, imports, arrayBuffer);
- return moduleParser.parse(exec, errorMessage);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WASMModuleParser.h b/Source/JavaScriptCore/wasm/WASMModuleParser.h
deleted file mode 100644
index 5017bc1ce..000000000
--- a/Source/JavaScriptCore/wasm/WASMModuleParser.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMModuleParser_h
-#define WASMModuleParser_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "Strong.h"
-#include "WASMReader.h"
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
-class ExecState;
-class JSArrayBuffer;
-class JSGlobalObject;
-class JSWASMModule;
-class SourceCode;
-class VM;
-
-class WASMModuleParser {
-public:
- WASMModuleParser(VM&, JSGlobalObject*, const SourceCode&, JSObject* imports, JSArrayBuffer*);
- JSWASMModule* parse(ExecState*, String& errorMessage);
-
-private:
- void parseModule(ExecState*);
- void parseConstantPoolSection();
- void parseSignatureSection();
- void parseFunctionImportSection(ExecState*);
- void parseGlobalSection(ExecState*);
- void parseFunctionDeclarationSection();
- void parseFunctionPointerTableSection();
- void parseFunctionDefinitionSection();
- void parseFunctionDefinition(size_t functionIndex);
- void parseExportSection();
- void getImportedValue(ExecState*, const String& importName, JSValue&);
-
- VM& m_vm;
- Strong<JSGlobalObject> m_globalObject;
- const SourceCode& m_source;
- Strong<JSObject> m_imports;
- WASMReader m_reader;
- Strong<JSWASMModule> m_module;
- String m_errorMessage;
-};
-
-JS_EXPORT_PRIVATE JSWASMModule* parseWebAssembly(ExecState*, const SourceCode&, JSObject* imports, JSArrayBuffer*, String& errorMessage);
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMModuleParser_h
diff --git a/Source/JavaScriptCore/wasm/WASMReader.cpp b/Source/JavaScriptCore/wasm/WASMReader.cpp
deleted file mode 100644
index f6ac8e2fc..000000000
--- a/Source/JavaScriptCore/wasm/WASMReader.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * =========================================================================
- *
- * Copyright (c) 2015 by the repository authors of
- * WebAssembly/polyfill-prototype-1.
- *
- * 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.
- */
-
-#include "config.h"
-#include "WASMReader.h"
-
-#if ENABLE(WEBASSEMBLY)
-
-#include <wtf/text/StringBuilder.h>
-
-#define CHECK_READ(length) do { if (m_cursor + length > m_buffer.end()) return false; } while (0)
-
-namespace JSC {
-
-bool WASMReader::readUInt32(uint32_t& result)
-{
- CHECK_READ(4);
- result = m_cursor[0] | m_cursor[1] << 8 | m_cursor[2] << 16 | m_cursor[3] << 24;
- m_cursor += 4;
- return true;
-}
-
-bool WASMReader::readFloat(float& result)
-{
- CHECK_READ(4);
- union {
- uint8_t bytes[4];
- float floatValue;
- } u = {
-#if CPU(BIG_ENDIAN)
- { m_cursor[3], m_cursor[2], m_cursor[1], m_cursor[0] }
-#else
- { m_cursor[0], m_cursor[1], m_cursor[2], m_cursor[3] }
-#endif
- };
- result = u.floatValue;
- m_cursor += 4;
- return true;
-}
-
-bool WASMReader::readDouble(double& result)
-{
- CHECK_READ(8);
- union {
- uint8_t bytes[8];
- double doubleValue;
- } u = {
-#if CPU(BIG_ENDIAN)
- { m_cursor[7], m_cursor[6], m_cursor[5], m_cursor[4], m_cursor[3], m_cursor[2], m_cursor[1], m_cursor[0] }
-#else
- { m_cursor[0], m_cursor[1], m_cursor[2], m_cursor[3], m_cursor[4], m_cursor[5], m_cursor[6], m_cursor[7] }
-#endif
- };
- result = u.doubleValue;
- m_cursor += 8;
- return true;
-}
-
-bool WASMReader::readCompactInt32(uint32_t& result)
-{
- uint32_t sum = 0;
- unsigned shift = 0;
- do {
- CHECK_READ(1);
- uint8_t byte = *m_cursor++;
- if (byte < 0x80) {
- sum |= byte << shift;
- int signExtend = (32 - 7) - shift;
- if (signExtend > 0)
- result = int32_t(sum) << signExtend >> signExtend;
- else
- result = int32_t(sum);
- return true;
- }
- sum |= (byte & firstSevenBitsMask) << shift;
- shift += 7;
- } while (shift < 35);
- return false;
-}
-
-bool WASMReader::readCompactUInt32(uint32_t& result)
-{
- uint32_t sum = 0;
- unsigned shift = 0;
- do {
- CHECK_READ(1);
- uint32_t byte = *m_cursor++;
- if (byte < 0x80) {
- if ((shift == 28 && byte >= 0x10) || (shift && !byte))
- return false;
- result = sum | (byte << shift);
- return true;
- }
- sum |= (byte & firstSevenBitsMask) << shift;
- shift += 7;
- } while (shift < 35);
- return false;
-}
-
-bool WASMReader::readString(String& result)
-{
- StringBuilder builder;
- while (true) {
- CHECK_READ(1);
- char c = *m_cursor++;
- if (!c)
- break;
- builder.append(c);
- }
- result = builder.toString();
- return true;
-}
-
-bool WASMReader::readType(WASMType& result)
-{
- return readByte<WASMType>(result, static_cast<uint8_t>(WASMType::NumberOfTypes));
-}
-
-bool WASMReader::readExpressionType(WASMExpressionType& result)
-{
- return readByte<WASMExpressionType>(result, static_cast<uint8_t>(WASMExpressionType::NumberOfExpressionTypes));
-}
-
-bool WASMReader::readExportFormat(WASMExportFormat& result)
-{
- return readByte<WASMExportFormat>(result, static_cast<uint8_t>(WASMExportFormat::NumberOfExportFormats));
-}
-
-template <class T> bool WASMReader::readByte(T& result, uint8_t numberOfValues)
-{
- CHECK_READ(1);
- uint8_t byte = *m_cursor++;
- if (byte >= numberOfValues)
- return false;
- result = T(byte);
- return true;
-}
-
-bool WASMReader::readOpStatement(bool& hasImmediate, WASMOpStatement& op, WASMOpStatementWithImmediate& opWithImmediate, uint8_t& immediate)
-{
- return readOp(hasImmediate, op, opWithImmediate, immediate,
- static_cast<uint8_t>(WASMOpStatement::NumberOfWASMOpStatements),
- static_cast<uint8_t>(WASMOpStatementWithImmediate::NumberOfWASMOpStatementWithImmediates));
-}
-
-bool WASMReader::readOpExpressionI32(bool& hasImmediate, WASMOpExpressionI32& op, WASMOpExpressionI32WithImmediate& opWithImmediate, uint8_t& immediate)
-{
- return readOp(hasImmediate, op, opWithImmediate, immediate,
- static_cast<uint8_t>(WASMOpExpressionI32::NumberOfWASMOpExpressionI32s),
- static_cast<uint8_t>(WASMOpExpressionI32WithImmediate::NumberOfWASMOpExpressionI32WithImmediates));
-}
-
-bool WASMReader::readOpExpressionF32(bool& hasImmediate, WASMOpExpressionF32& op, WASMOpExpressionF32WithImmediate& opWithImmediate, uint8_t& immediate)
-{
- return readOp(hasImmediate, op, opWithImmediate, immediate,
- static_cast<uint8_t>(WASMOpExpressionF32::NumberOfWASMOpExpressionF32s),
- static_cast<uint8_t>(WASMOpExpressionF32WithImmediate::NumberOfWASMOpExpressionF32WithImmediates));
-}
-
-bool WASMReader::readOpExpressionF64(bool& hasImmediate, WASMOpExpressionF64& op, WASMOpExpressionF64WithImmediate& opWithImmediate, uint8_t& immediate)
-{
- return readOp(hasImmediate, op, opWithImmediate, immediate,
- static_cast<uint8_t>(WASMOpExpressionF64::NumberOfWASMOpExpressionF64s),
- static_cast<uint8_t>(WASMOpExpressionF64WithImmediate::NumberOfWASMOpExpressionF64WithImmediates));
-}
-
-bool WASMReader::readOpExpressionVoid(WASMOpExpressionVoid& op)
-{
- return readByte<WASMOpExpressionVoid>(op,
- static_cast<uint8_t>(WASMOpExpressionVoid::NumberOfWASMOpExpressionVoids));
-}
-
-bool WASMReader::readVariableTypes(bool& hasImmediate, WASMVariableTypes& variableTypes, WASMVariableTypesWithImmediate& variableTypesWithImmediate, uint8_t& immediate)
-{
- return readOp(hasImmediate, variableTypes, variableTypesWithImmediate, immediate,
- static_cast<uint8_t>(WASMVariableTypes::NumberOfVariableTypes),
- static_cast<uint8_t>(WASMVariableTypesWithImmediate::NumberOfVariableTypesWithImmediates));
-}
-
-template <class T, class TWithImmediate>
-bool WASMReader::readOp(bool& hasImmediate, T& op, TWithImmediate& opWithImmediate, uint8_t& immediate, uint8_t numberOfValues, uint8_t numberOfValuesWithImmediate)
-{
- CHECK_READ(1);
- uint8_t byte = *m_cursor++;
-
- if (!(byte & hasImmediateInOpFlag)) {
- if (byte >= numberOfValues)
- return false;
- hasImmediate = false;
- op = T(byte);
- return true;
- }
-
- uint8_t byteWithoutImmediate = (byte >> immediateBits) & (opWithImmediateLimit - 1);
- if (byteWithoutImmediate >= numberOfValuesWithImmediate)
- return false;
- hasImmediate = true;
- opWithImmediate = TWithImmediate(byteWithoutImmediate);
- immediate = byte & (immediateLimit - 1);
- return true;
-}
-
-bool WASMReader::readSwitchCase(WASMSwitchCase& result)
-{
- return readByte<WASMSwitchCase>(result, static_cast<uint8_t>(WASMSwitchCase::NumberOfSwitchCases));
-}
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WASMReader.h b/Source/JavaScriptCore/wasm/WASMReader.h
deleted file mode 100644
index 83dc29681..000000000
--- a/Source/JavaScriptCore/wasm/WASMReader.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WASMReader_h
-#define WASMReader_h
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "WASMConstants.h"
-#include "WASMFormat.h"
-#include <wtf/Vector.h>
-
-namespace JSC {
-
-class WASMReader {
-public:
- WASMReader(const Vector<uint8_t>& buffer)
- : m_buffer(buffer)
- , m_cursor(buffer.data())
- {
- }
-
- unsigned offset() const { return m_cursor - m_buffer.data(); }
- void setOffset(unsigned offset) { m_cursor = m_buffer.data() + offset; }
-
- bool readUInt32(uint32_t& result);
- bool readFloat(float& result);
- bool readDouble(double& result);
- bool readCompactInt32(uint32_t& result);
- bool readCompactUInt32(uint32_t& result);
- bool readString(String& result);
- bool readType(WASMType& result);
- bool readExpressionType(WASMExpressionType& result);
- bool readExportFormat(WASMExportFormat& result);
- bool readOpStatement(bool& hasImmediate, WASMOpStatement&, WASMOpStatementWithImmediate&, uint8_t& immediate);
- bool readOpExpressionI32(bool& hasImmediate, WASMOpExpressionI32&, WASMOpExpressionI32WithImmediate&, uint8_t& immediate);
- bool readOpExpressionF32(bool& hasImmediate, WASMOpExpressionF32&, WASMOpExpressionF32WithImmediate&, uint8_t& immediate);
- bool readOpExpressionF64(bool& hasImmediate, WASMOpExpressionF64&, WASMOpExpressionF64WithImmediate&, uint8_t& immediate);
- bool readOpExpressionVoid(WASMOpExpressionVoid&);
- bool readVariableTypes(bool& hasImmediate, WASMVariableTypes&, WASMVariableTypesWithImmediate&, uint8_t& immediate);
- bool readSwitchCase(WASMSwitchCase& result);
-
-private:
- static const uint32_t firstSevenBitsMask = 0x7f;
-
- template <class T> bool readByte(T& result, uint8_t numberOfValues);
- template <class T, class TWithImmediate> bool readOp(bool& hasImmediate, T&, TWithImmediate&, uint8_t& immediate, uint8_t numberOfValues, uint8_t numberOfValuesWithImmediate);
-
- const Vector<uint8_t>& m_buffer;
- const uint8_t* m_cursor;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
-
-#endif // WASMReader_h