diff options
| author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
|---|---|---|
| committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
| commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
| tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/wasm/WASMFunctionParser.cpp | |
| parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
| download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz | |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/wasm/WASMFunctionParser.cpp')
| -rw-r--r-- | Source/JavaScriptCore/wasm/WASMFunctionParser.cpp | 1225 |
1 files changed, 0 insertions, 1225 deletions
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) |
