Remove remaining references to LLVM, and make sure comments refer to the backend...
[WebKit-https.git] / Source / JavaScriptCore / wasm / WASMFunctionParser.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WASMFunctionParser.h"
28
29 #if ENABLE(WEBASSEMBLY)
30
31 #include "JSCJSValueInlines.h"
32 #include "JSWASMModule.h"
33 #include "WASMFunctionCompiler.h"
34 #include "WASMFunctionB3IRGenerator.h"
35 #include "WASMFunctionSyntaxChecker.h"
36
37 #define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
38 #define FAIL_WITH_MESSAGE(errorMessage) do {  m_errorMessage = errorMessage; return 0; } while (0)
39 #define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
40 #define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
41 #define READ_COMPACT_INT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
42 #define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
43 #define READ_EXPRESSION_TYPE_OR_FAIL(result, errorMessage) do { if (!m_reader.readExpressionType(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
44 #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)
45 #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)
46 #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)
47 #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)
48 #define READ_OP_EXPRESSION_VOID_OR_FAIL(op, errorMessage) do { if (!m_reader.readOpExpressionVoid(op)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
49 #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)
50 #define READ_SWITCH_CASE_OR_FAIL(result, errorMessage) do { if (!m_reader.readSwitchCase(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
51 #define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
52
53 #define UNUSED 0
54
55 namespace JSC {
56
57 static String nameOfType(WASMType type)
58 {
59     switch (type) {
60     case WASMType::I32:
61         return "int32";
62     case WASMType::F32:
63         return "float32";
64     case WASMType::F64:
65         return "float64";
66     default:
67         RELEASE_ASSERT_NOT_REACHED();
68     }
69 }
70
71 bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage)
72 {
73     WASMFunctionParser parser(module, source, functionIndex);
74     WASMFunctionSyntaxChecker syntaxChecker;
75     parser.m_reader.setOffset(startOffsetInSource);
76     parser.parseFunction(syntaxChecker);
77     if (!parser.m_errorMessage.isNull()) {
78         errorMessage = parser.m_errorMessage;
79         return false;
80     }
81     endOffsetInSource = parser.m_reader.offset();
82     stackHeight = syntaxChecker.stackHeight();
83     return true;
84 }
85
86 void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode& source, size_t functionIndex)
87 {
88     WASMFunctionParser parser(module, source, functionIndex);
89     WASMFunctionCompiler compiler(vm, codeBlock, module, module->functionStackHeights()[functionIndex]);
90     parser.m_reader.setOffset(module->functionStartOffsetsInSource()[functionIndex]);
91     parser.parseFunction(compiler);
92     ASSERT(parser.m_errorMessage.isNull());
93 }
94
95 template <class Context>
96 bool WASMFunctionParser::parseFunction(Context& context)
97 {
98     const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[m_functionIndex].signatureIndex];
99
100     m_returnType = signature.returnType;
101
102     parseLocalVariables();
103     PROPAGATE_ERROR();
104
105     const Vector<WASMType>& arguments = signature.arguments;
106     for (size_t i = 0; i < arguments.size(); ++i)
107         m_localTypes.append(arguments[i]);
108     for (uint32_t i = 0; i < m_numberOfI32LocalVariables; ++i)
109         m_localTypes.append(WASMType::I32);
110     for (uint32_t i = 0; i < m_numberOfF32LocalVariables; ++i)
111         m_localTypes.append(WASMType::F32);
112     for (uint32_t i = 0; i < m_numberOfF64LocalVariables; ++i)
113         m_localTypes.append(WASMType::F64);
114
115     context.startFunction(arguments, m_numberOfI32LocalVariables, m_numberOfF32LocalVariables, m_numberOfF64LocalVariables);
116
117     parseBlockStatement(context);
118     PROPAGATE_ERROR();
119
120     context.endFunction();
121     return true;
122 }
123
124 bool WASMFunctionParser::parseLocalVariables()
125 {
126     m_numberOfI32LocalVariables = 0;
127     m_numberOfF32LocalVariables = 0;
128     m_numberOfF64LocalVariables = 0;
129
130     bool hasImmediate;
131     WASMVariableTypes variableTypes;
132     WASMVariableTypesWithImmediate variableTypesWithImmediate;
133     uint8_t immediate;
134     READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, "Cannot read the types of local variables.");
135     if (!hasImmediate) {
136         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::I32))
137             READ_COMPACT_UINT32_OR_FAIL(m_numberOfI32LocalVariables, "Cannot read the number of int32 local variables.");
138         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F32))
139             READ_COMPACT_UINT32_OR_FAIL(m_numberOfF32LocalVariables, "Cannot read the number of float32 local variables.");
140         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F64))
141             READ_COMPACT_UINT32_OR_FAIL(m_numberOfF64LocalVariables, "Cannot read the number of float64 local variables.");
142     } else
143         m_numberOfI32LocalVariables = immediate;
144     return true;
145 }
146
147 template <class Context>
148 ContextStatement WASMFunctionParser::parseStatement(Context& context)
149 {
150     bool hasImmediate;
151     WASMOpStatement op;
152     WASMOpStatementWithImmediate opWithImmediate;
153     uint8_t immediate;
154     READ_OP_STATEMENT_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the statement opcode.");
155     if (!hasImmediate) {
156         switch (op) {
157         case WASMOpStatement::SetLocal:
158             parseSetLocal(context, WASMOpKind::Statement, WASMExpressionType::Void);
159             break;
160         case WASMOpStatement::SetGlobal:
161             parseSetGlobal(context, WASMOpKind::Statement, WASMExpressionType::Void);
162             break;
163         case WASMOpStatement::I32Store8:
164             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset);
165             break;
166         case WASMOpStatement::I32StoreWithOffset8:
167             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset);
168             break;
169         case WASMOpStatement::I32Store16:
170             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset);
171             break;
172         case WASMOpStatement::I32StoreWithOffset16:
173             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset);
174             break;
175         case WASMOpStatement::I32Store32:
176             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
177             break;
178         case WASMOpStatement::I32StoreWithOffset32:
179             parseStore(context, WASMOpKind::Statement, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
180             break;
181         case WASMOpStatement::F32Store:
182             parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
183             break;
184         case WASMOpStatement::F32StoreWithOffset:
185             parseStore(context, WASMOpKind::Statement, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
186             break;
187         case WASMOpStatement::F64Store:
188             parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
189             break;
190         case WASMOpStatement::F64StoreWithOffset:
191             parseStore(context, WASMOpKind::Statement, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
192             break;
193         case WASMOpStatement::CallInternal:
194             parseCallInternal(context, WASMOpKind::Statement, WASMExpressionType::Void);
195             break;
196         case WASMOpStatement::CallIndirect:
197             parseCallIndirect(context, WASMOpKind::Statement, WASMExpressionType::Void);
198             break;
199         case WASMOpStatement::CallImport:
200             parseCallImport(context, WASMOpKind::Statement, WASMExpressionType::Void);
201             break;
202         case WASMOpStatement::Return:
203             parseReturnStatement(context);
204             break;
205         case WASMOpStatement::Block:
206             parseBlockStatement(context);
207             break;
208         case WASMOpStatement::If:
209             parseIfStatement(context);
210             break;
211         case WASMOpStatement::IfElse:
212             parseIfElseStatement(context);
213             break;
214         case WASMOpStatement::While:
215             parseWhileStatement(context);
216             break;
217         case WASMOpStatement::Do:
218             parseDoStatement(context);
219             break;
220         case WASMOpStatement::Label:
221             parseLabelStatement(context);
222             break;
223         case WASMOpStatement::Break:
224             parseBreakStatement(context);
225             break;
226         case WASMOpStatement::BreakLabel:
227             parseBreakLabelStatement(context);
228             break;
229         case WASMOpStatement::Continue:
230             parseContinueStatement(context);
231             break;
232         case WASMOpStatement::ContinueLabel:
233             parseContinueLabelStatement(context);
234             break;
235         case WASMOpStatement::Switch:
236             parseSwitchStatement(context);
237             break;
238         default:
239             ASSERT_NOT_REACHED();
240         }
241     } else {
242         switch (opWithImmediate) {
243         case WASMOpStatementWithImmediate::SetLocal:
244             parseSetLocal(context, WASMOpKind::Statement, WASMExpressionType::Void, immediate);
245             break;
246         case WASMOpStatementWithImmediate::SetGlobal:
247             parseSetGlobal(context, WASMOpKind::Statement, WASMExpressionType::Void, immediate);
248             break;
249         default:
250             ASSERT_NOT_REACHED();
251         }
252     }
253     return UNUSED;
254 }
255
256 template <class Context>
257 ContextStatement WASMFunctionParser::parseReturnStatement(Context& context)
258 {
259     ContextExpression expression = 0;
260     if (m_returnType != WASMExpressionType::Void) {
261         expression = parseExpression(context, m_returnType);
262         PROPAGATE_ERROR();
263     }
264     context.buildReturn(expression, m_returnType);
265     return UNUSED;
266 }
267
268 template <class Context>
269 ContextStatement WASMFunctionParser::parseBlockStatement(Context& context)
270 {
271     uint32_t numberOfStatements;
272     READ_COMPACT_UINT32_OR_FAIL(numberOfStatements, "Cannot read the number of statements.");
273     for (uint32_t i = 0; i < numberOfStatements; ++i) {
274         parseStatement(context);
275         PROPAGATE_ERROR();
276     }
277     return UNUSED;
278 }
279
280 template <class Context>
281 ContextStatement WASMFunctionParser::parseIfStatement(Context& context)
282 {
283     ContextJumpTarget end;
284
285     ContextExpression expression = parseExpressionI32(context);
286     PROPAGATE_ERROR();
287
288     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, end);
289
290     parseStatement(context);
291     PROPAGATE_ERROR();
292
293     context.linkTarget(end);
294     return UNUSED;
295 }
296
297 template <class Context>
298 ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context)
299 {
300     ContextJumpTarget elseTarget;
301     ContextJumpTarget end;
302
303     ContextExpression expression = parseExpressionI32(context);
304     PROPAGATE_ERROR();
305
306     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, elseTarget);
307
308     parseStatement(context);
309     PROPAGATE_ERROR();
310
311     context.jumpToTarget(end);
312     context.linkTarget(elseTarget);
313
314     parseStatement(context);
315     PROPAGATE_ERROR();
316
317     context.linkTarget(end);
318     return UNUSED;
319 }
320
321 template <class Context>
322 ContextStatement WASMFunctionParser::parseWhileStatement(Context& context)
323 {
324     context.startLoop();
325     context.linkTarget(context.continueTarget());
326
327     ContextExpression expression = parseExpressionI32(context);
328     PROPAGATE_ERROR();
329
330     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, context.breakTarget());
331
332     m_breakScopeDepth++;
333     m_continueScopeDepth++;
334     parseStatement(context);
335     PROPAGATE_ERROR();
336     m_continueScopeDepth--;
337     m_breakScopeDepth--;
338
339     context.jumpToTarget(context.continueTarget());
340
341     context.linkTarget(context.breakTarget());
342     context.endLoop();
343     return UNUSED;
344 }
345
346 template <class Context>
347 ContextStatement WASMFunctionParser::parseDoStatement(Context& context)
348 {
349     context.startLoop();
350
351     ContextJumpTarget topOfLoop;
352     context.linkTarget(topOfLoop);
353
354     m_breakScopeDepth++;
355     m_continueScopeDepth++;
356     parseStatement(context);
357     PROPAGATE_ERROR();
358     m_continueScopeDepth--;
359     m_breakScopeDepth--;
360
361     context.linkTarget(context.continueTarget());
362
363     ContextExpression expression = parseExpressionI32(context);
364     PROPAGATE_ERROR();
365
366     context.jumpToTargetIf(Context::JumpCondition::NonZero, expression, topOfLoop);
367
368     context.linkTarget(context.breakTarget());
369     context.endLoop();
370     return UNUSED;
371 }
372
373 template <class Context>
374 ContextStatement WASMFunctionParser::parseLabelStatement(Context& context)
375 {
376     context.startLabel();
377     m_labelDepth++;
378     parseStatement(context);
379     PROPAGATE_ERROR();
380     m_labelDepth--;
381     context.endLabel();
382     return UNUSED;
383 }
384
385 template <class Context>
386 ContextStatement WASMFunctionParser::parseBreakStatement(Context& context)
387 {
388     FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement.");
389     context.jumpToTarget(context.breakTarget());
390     return UNUSED;
391 }
392
393 template <class Context>
394 ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& context)
395 {
396     uint32_t labelIndex;
397     READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
398     FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
399     context.jumpToTarget(context.breakLabelTarget(labelIndex));
400     return UNUSED;
401 }
402
403 template <class Context>
404 ContextStatement WASMFunctionParser::parseContinueStatement(Context& context)
405 {
406     FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement.");
407     context.jumpToTarget(context.continueTarget());
408     return UNUSED;
409 }
410
411 template <class Context>
412 ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& context)
413 {
414     uint32_t labelIndex;
415     READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
416     FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
417     context.jumpToTarget(context.continueLabelTarget(labelIndex));
418     return UNUSED;
419 }
420
421 template <class Context>
422 ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context)
423 {
424     context.startSwitch();
425     uint32_t numberOfCases;
426     READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases.");
427     ContextExpression expression = parseExpressionI32(context);
428     PROPAGATE_ERROR();
429
430     ContextJumpTarget compare;
431     context.jumpToTarget(compare);
432
433     Vector<int64_t> cases;
434     Vector<ContextJumpTarget> targets;
435     cases.reserveInitialCapacity(numberOfCases);
436     targets.reserveInitialCapacity(numberOfCases);
437     bool hasDefault = false;
438     ContextJumpTarget defaultTarget;
439
440     m_breakScopeDepth++;
441     for (uint32_t i = 0; i < numberOfCases; ++i) {
442         WASMSwitchCase switchCase;
443         READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case.");
444         switch (switchCase) {
445         case WASMSwitchCase::CaseWithNoStatements:
446         case WASMSwitchCase::CaseWithStatement:
447         case WASMSwitchCase::CaseWithBlockStatement: {
448             uint32_t value;
449             READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case.");
450             cases.uncheckedAppend(value);
451             ContextJumpTarget target;
452             context.linkTarget(target);
453             targets.uncheckedAppend(target);
454             if (switchCase == WASMSwitchCase::CaseWithStatement) {
455                 parseStatement(context);
456                 PROPAGATE_ERROR();
457             } else if (switchCase == WASMSwitchCase::CaseWithBlockStatement) {
458                 parseBlockStatement(context);
459                 PROPAGATE_ERROR();
460             }
461             break;
462         }
463         case WASMSwitchCase::DefaultWithNoStatements:
464         case WASMSwitchCase::DefaultWithStatement:
465         case WASMSwitchCase::DefaultWithBlockStatement: {
466             FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case.");
467             hasDefault = true;
468             context.linkTarget(defaultTarget);
469             if (switchCase == WASMSwitchCase::DefaultWithStatement) {
470                 parseStatement(context);
471                 PROPAGATE_ERROR();
472             } else if (switchCase == WASMSwitchCase::DefaultWithBlockStatement) {
473                 parseBlockStatement(context);
474                 PROPAGATE_ERROR();
475             }
476             break;
477         }
478         default:
479             ASSERT_NOT_REACHED();
480         }
481     }
482     if (!hasDefault)
483         context.linkTarget(defaultTarget);
484
485     m_breakScopeDepth--;
486
487     context.jumpToTarget(context.breakTarget());
488     context.linkTarget(compare);
489
490     context.buildSwitch(expression, cases, targets, defaultTarget);
491
492     context.linkTarget(context.breakTarget());
493     context.endSwitch();
494     return UNUSED;
495 }
496
497 template <class Context>
498 ContextExpression WASMFunctionParser::parseExpression(Context& context, WASMExpressionType expressionType)
499 {
500     switch (expressionType) {
501     case WASMExpressionType::I32:
502         return parseExpressionI32(context);
503     case WASMExpressionType::F32:
504         return parseExpressionF32(context);
505     case WASMExpressionType::F64:
506         return parseExpressionF64(context);
507     case WASMExpressionType::Void:
508         return parseExpressionVoid(context);
509     default:
510         RELEASE_ASSERT_NOT_REACHED();
511     }
512 }
513
514 template <class Context>
515 ContextExpression WASMFunctionParser::parseExpressionI32(Context& context)
516 {
517     bool hasImmediate;
518     WASMOpExpressionI32 op;
519     WASMOpExpressionI32WithImmediate opWithImmediate;
520     uint8_t immediate;
521     READ_OP_EXPRESSION_I32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the int32 expression opcode.");
522     if (!hasImmediate) {
523         switch (op) {
524         case WASMOpExpressionI32::ConstantPoolIndex:
525             return parseConstantPoolIndexExpressionI32(context);
526         case WASMOpExpressionI32::Immediate:
527             return parseImmediateExpressionI32(context);
528         case WASMOpExpressionI32::GetLocal:
529             return parseGetLocalExpression(context, WASMType::I32);
530         case WASMOpExpressionI32::GetGlobal:
531             return parseGetGlobalExpression(context, WASMType::I32);
532         case WASMOpExpressionI32::SetLocal:
533             return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::I32);
534         case WASMOpExpressionI32::SetGlobal:
535             return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::I32);
536         case WASMOpExpressionI32::SLoad8:
537             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend);
538         case WASMOpExpressionI32::SLoadWithOffset8:
539             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend);
540         case WASMOpExpressionI32::ULoad8:
541             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend);
542         case WASMOpExpressionI32::ULoadWithOffset8:
543             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend);
544         case WASMOpExpressionI32::SLoad16:
545             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::SignExtend);
546         case WASMOpExpressionI32::SLoadWithOffset16:
547             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::SignExtend);
548         case WASMOpExpressionI32::ULoad16:
549             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset, MemoryAccessConversion::ZeroExtend);
550         case WASMOpExpressionI32::ULoadWithOffset16:
551             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset, MemoryAccessConversion::ZeroExtend);
552         case WASMOpExpressionI32::Load32:
553             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
554         case WASMOpExpressionI32::LoadWithOffset32:
555             return parseLoad(context, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
556         case WASMOpExpressionI32::Store8:
557             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::NoOffset);
558         case WASMOpExpressionI32::StoreWithOffset8:
559             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I8, MemoryAccessOffsetMode::WithOffset);
560         case WASMOpExpressionI32::Store16:
561             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::NoOffset);
562         case WASMOpExpressionI32::StoreWithOffset16:
563             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I16, MemoryAccessOffsetMode::WithOffset);
564         case WASMOpExpressionI32::Store32:
565             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::NoOffset);
566         case WASMOpExpressionI32::StoreWithOffset32:
567             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::I32, WASMMemoryType::I32, MemoryAccessOffsetMode::WithOffset);
568         case WASMOpExpressionI32::CallInternal:
569             return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::I32);
570         case WASMOpExpressionI32::CallIndirect:
571             return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::I32);
572         case WASMOpExpressionI32::CallImport:
573             return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::I32);
574         case WASMOpExpressionI32::Conditional:
575             return parseConditional(context, WASMExpressionType::I32);
576         case WASMOpExpressionI32::Comma:
577             return parseComma(context, WASMExpressionType::I32);
578         case WASMOpExpressionI32::FromF32:
579             return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
580         case WASMOpExpressionI32::FromF64:
581             return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
582         case WASMOpExpressionI32::Negate:
583         case WASMOpExpressionI32::BitNot:
584         case WASMOpExpressionI32::CountLeadingZeros:
585         case WASMOpExpressionI32::LogicalNot:
586         case WASMOpExpressionI32::Abs:
587             return parseUnaryExpressionI32(context, op);
588         case WASMOpExpressionI32::Add:
589         case WASMOpExpressionI32::Sub:
590         case WASMOpExpressionI32::Mul:
591         case WASMOpExpressionI32::SDiv:
592         case WASMOpExpressionI32::UDiv:
593         case WASMOpExpressionI32::SMod:
594         case WASMOpExpressionI32::UMod:
595         case WASMOpExpressionI32::BitOr:
596         case WASMOpExpressionI32::BitAnd:
597         case WASMOpExpressionI32::BitXor:
598         case WASMOpExpressionI32::LeftShift:
599         case WASMOpExpressionI32::ArithmeticRightShift:
600         case WASMOpExpressionI32::LogicalRightShift:
601             return parseBinaryExpressionI32(context, op);
602         case WASMOpExpressionI32::EqualI32:
603         case WASMOpExpressionI32::NotEqualI32:
604         case WASMOpExpressionI32::SLessThanI32:
605         case WASMOpExpressionI32::ULessThanI32:
606         case WASMOpExpressionI32::SLessThanOrEqualI32:
607         case WASMOpExpressionI32::ULessThanOrEqualI32:
608         case WASMOpExpressionI32::SGreaterThanI32:
609         case WASMOpExpressionI32::UGreaterThanI32:
610         case WASMOpExpressionI32::SGreaterThanOrEqualI32:
611         case WASMOpExpressionI32::UGreaterThanOrEqualI32:
612             return parseRelationalI32ExpressionI32(context, op);
613         case WASMOpExpressionI32::EqualF32:
614         case WASMOpExpressionI32::NotEqualF32:
615         case WASMOpExpressionI32::LessThanF32:
616         case WASMOpExpressionI32::LessThanOrEqualF32:
617         case WASMOpExpressionI32::GreaterThanF32:
618         case WASMOpExpressionI32::GreaterThanOrEqualF32:
619             return parseRelationalF32ExpressionI32(context, op);
620         case WASMOpExpressionI32::EqualF64:
621         case WASMOpExpressionI32::NotEqualF64:
622         case WASMOpExpressionI32::LessThanF64:
623         case WASMOpExpressionI32::LessThanOrEqualF64:
624         case WASMOpExpressionI32::GreaterThanF64:
625         case WASMOpExpressionI32::GreaterThanOrEqualF64:
626             return parseRelationalF64ExpressionI32(context, op);
627         case WASMOpExpressionI32::SMin:
628         case WASMOpExpressionI32::UMin:
629         case WASMOpExpressionI32::SMax:
630         case WASMOpExpressionI32::UMax:
631             return parseMinOrMaxExpressionI32(context, op);
632         default:
633             ASSERT_NOT_REACHED();
634         }
635     } else {
636         switch (opWithImmediate) {
637         case WASMOpExpressionI32WithImmediate::ConstantPoolIndex:
638             return parseConstantPoolIndexExpressionI32(context, immediate);
639         case WASMOpExpressionI32WithImmediate::Immediate:
640             return parseImmediateExpressionI32(context, immediate);
641         case WASMOpExpressionI32WithImmediate::GetLocal:
642             return parseGetLocalExpression(context, WASMType::I32, immediate);
643         default:
644             ASSERT_NOT_REACHED();
645         }
646     }
647     return 0;
648 }
649
650 template <class Context>
651 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context, uint32_t constantPoolIndex)
652 {
653     FAIL_IF_FALSE(constantPoolIndex < m_module->i32Constants().size(), "The constant pool index is incorrect.");
654     return context.buildImmediateI32(m_module->i32Constants()[constantPoolIndex]);
655 }
656
657 template <class Context>
658 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context)
659 {
660     uint32_t constantPoolIndex;
661     READ_COMPACT_UINT32_OR_FAIL(constantPoolIndex, "Cannot read the constant pool index.");
662     return parseConstantPoolIndexExpressionI32(context, constantPoolIndex);
663 }
664
665 template <class Context>
666 ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context, uint32_t immediate)
667 {
668     return context.buildImmediateI32(immediate);
669 }
670
671 template <class Context>
672 ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context)
673 {
674     uint32_t immediate;
675     READ_COMPACT_UINT32_OR_FAIL(immediate, "Cannot read the immediate.");
676     return parseImmediateExpressionI32(context, immediate);
677 }
678
679 template <class Context>
680 ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op)
681 {
682     ContextExpression expression = parseExpressionI32(context);
683     PROPAGATE_ERROR();
684     return context.buildUnaryI32(expression, op);
685 }
686
687 template <class Context>
688 ContextExpression WASMFunctionParser::parseBinaryExpressionI32(Context& context, WASMOpExpressionI32 op)
689 {
690     ContextExpression left = parseExpressionI32(context);
691     PROPAGATE_ERROR();
692     ContextExpression right = parseExpressionI32(context);
693     PROPAGATE_ERROR();
694     return context.buildBinaryI32(left, right, op);
695 }
696
697 template <class Context>
698 ContextExpression WASMFunctionParser::parseRelationalI32ExpressionI32(Context& context, WASMOpExpressionI32 op)
699 {
700     ContextExpression left = parseExpressionI32(context);
701     PROPAGATE_ERROR();
702     ContextExpression right = parseExpressionI32(context);
703     PROPAGATE_ERROR();
704     return context.buildRelationalI32(left, right, op);
705 }
706
707 template <class Context>
708 ContextExpression WASMFunctionParser::parseRelationalF32ExpressionI32(Context& context, WASMOpExpressionI32 op)
709 {
710     ContextExpression left = parseExpressionF32(context);
711     PROPAGATE_ERROR();
712     ContextExpression right = parseExpressionF32(context);
713     PROPAGATE_ERROR();
714     return context.buildRelationalF32(left, right, op);
715 }
716
717 template <class Context>
718 ContextExpression WASMFunctionParser::parseRelationalF64ExpressionI32(Context& context, WASMOpExpressionI32 op)
719 {
720     ContextExpression left = parseExpressionF64(context);
721     PROPAGATE_ERROR();
722     ContextExpression right = parseExpressionF64(context);
723     PROPAGATE_ERROR();
724     return context.buildRelationalF64(left, right, op);
725 }
726
727 template <class Context>
728 ContextExpression WASMFunctionParser::parseMinOrMaxExpressionI32(Context& context, WASMOpExpressionI32 op)
729 {
730     uint32_t numberOfArguments;
731     READ_COMPACT_UINT32_OR_FAIL(numberOfArguments, "Cannot read the number of arguments to min/max.");
732     FAIL_IF_FALSE(numberOfArguments >= 2, "Min/max must be passed at least 2 arguments.");
733     ContextExpression current = parseExpressionI32(context);
734     PROPAGATE_ERROR();
735     for (uint32_t i = 1; i < numberOfArguments; ++i) {
736         ContextExpression expression = parseExpressionI32(context);
737         PROPAGATE_ERROR();
738         current = context.buildMinOrMaxI32(current, expression, op);
739     }
740     return current;
741 }
742
743 template <class Context>
744 ContextExpression WASMFunctionParser::parseExpressionF32(Context& context)
745 {
746     bool hasImmediate;
747     WASMOpExpressionF32 op;
748     WASMOpExpressionF32WithImmediate opWithImmediate;
749     uint8_t immediate;
750     READ_OP_EXPRESSION_F32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float32 expression opcode.");
751     if (!hasImmediate) {
752         switch (op) {
753         case WASMOpExpressionF32::ConstantPoolIndex:
754             return parseConstantPoolIndexExpressionF32(context);
755         case WASMOpExpressionF32::Immediate:
756             return parseImmediateExpressionF32(context);
757         case WASMOpExpressionF32::GetLocal:
758             return parseGetLocalExpression(context, WASMType::F32);
759         case WASMOpExpressionF32::GetGlobal:
760             return parseGetGlobalExpression(context, WASMType::F32);
761         case WASMOpExpressionF32::SetLocal:
762             return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::F32);
763         case WASMOpExpressionF32::SetGlobal:
764             return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::F32);
765         case WASMOpExpressionF32::Load:
766             return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
767         case WASMOpExpressionF32::LoadWithOffset:
768             return parseLoad(context, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
769         case WASMOpExpressionF32::Store:
770             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::NoOffset);
771         case WASMOpExpressionF32::StoreWithOffset:
772             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F32, WASMMemoryType::F32, MemoryAccessOffsetMode::WithOffset);
773         case WASMOpExpressionF32::CallInternal:
774             return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::F32);
775         case WASMOpExpressionF32::CallIndirect:
776             return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::F32);
777         case WASMOpExpressionF32::Conditional:
778             return parseConditional(context, WASMExpressionType::F32);
779         case WASMOpExpressionF32::Comma:
780             return parseComma(context, WASMExpressionType::F32);
781         case WASMOpExpressionF32::FromS32:
782             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertSigned);
783         case WASMOpExpressionF32::FromU32:
784             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertUnsigned);
785         case WASMOpExpressionF32::FromF64:
786             return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::F32, WASMTypeConversion::Demote);
787         case WASMOpExpressionF32::Negate:
788         case WASMOpExpressionF32::Abs:
789         case WASMOpExpressionF32::Ceil:
790         case WASMOpExpressionF32::Floor:
791         case WASMOpExpressionF32::Sqrt:
792             return parseUnaryExpressionF32(context, op);
793         case WASMOpExpressionF32::Add:
794         case WASMOpExpressionF32::Sub:
795         case WASMOpExpressionF32::Mul:
796         case WASMOpExpressionF32::Div:
797             return parseBinaryExpressionF32(context, op);
798         default:
799             ASSERT_NOT_REACHED();
800         }
801     } else {
802         switch (opWithImmediate) {
803         case WASMOpExpressionF32WithImmediate::ConstantPoolIndex:
804             return parseConstantPoolIndexExpressionF32(context, immediate);
805         case WASMOpExpressionF32WithImmediate::GetLocal:
806             return parseGetLocalExpression(context, WASMType::F32, immediate);
807         default:
808             ASSERT_NOT_REACHED();
809         }
810     }
811     return 0;
812 }
813
814 template <class Context>
815 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context, uint32_t constantIndex)
816 {
817     FAIL_IF_FALSE(constantIndex < m_module->f32Constants().size(), "The constant pool index is incorrect.");
818     return context.buildImmediateF32(m_module->f32Constants()[constantIndex]);
819 }
820
821 template <class Context>
822 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context)
823 {
824     uint32_t constantIndex;
825     READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant pool index.");
826     return parseConstantPoolIndexExpressionF32(context, constantIndex);
827 }
828
829 template <class Context>
830 ContextExpression WASMFunctionParser::parseImmediateExpressionF32(Context& context)
831 {
832     float immediate;
833     READ_FLOAT_OR_FAIL(immediate, "Cannot read the immediate.");
834     return context.buildImmediateF32(immediate);
835 }
836
837 template <class Context>
838 ContextExpression WASMFunctionParser::parseUnaryExpressionF32(Context& context, WASMOpExpressionF32 op)
839 {
840     ContextExpression expression = parseExpressionF32(context);
841     PROPAGATE_ERROR();
842     return context.buildUnaryF32(expression, op);
843 }
844
845 template <class Context>
846 ContextExpression WASMFunctionParser::parseBinaryExpressionF32(Context& context, WASMOpExpressionF32 op)
847 {
848     ContextExpression left = parseExpressionF32(context);
849     PROPAGATE_ERROR();
850     ContextExpression right = parseExpressionF32(context);
851     PROPAGATE_ERROR();
852     return context.buildBinaryF32(left, right, op);
853 }
854
855 template <class Context>
856 ContextExpression WASMFunctionParser::parseExpressionF64(Context& context)
857 {
858     bool hasImmediate;
859     WASMOpExpressionF64 op;
860     WASMOpExpressionF64WithImmediate opWithImmediate;
861     uint8_t immediate;
862     READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float64 expression opcode.");
863     if (!hasImmediate) {
864         switch (op) {
865         case WASMOpExpressionF64::ConstantPoolIndex:
866             return parseConstantPoolIndexExpressionF64(context);
867         case WASMOpExpressionF64::Immediate:
868             return parseImmediateExpressionF64(context);
869         case WASMOpExpressionF64::GetLocal:
870             return parseGetLocalExpression(context, WASMType::F64);
871         case WASMOpExpressionF64::GetGlobal:
872             return parseGetGlobalExpression(context, WASMType::F64);
873         case WASMOpExpressionF64::SetLocal:
874             return parseSetLocal(context, WASMOpKind::Expression, WASMExpressionType::F64);
875         case WASMOpExpressionF64::SetGlobal:
876             return parseSetGlobal(context, WASMOpKind::Expression, WASMExpressionType::F64);
877         case WASMOpExpressionF64::Load:
878             return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
879         case WASMOpExpressionF64::LoadWithOffset:
880             return parseLoad(context, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
881         case WASMOpExpressionF64::Store:
882             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::NoOffset);
883         case WASMOpExpressionF64::StoreWithOffset:
884             return parseStore(context, WASMOpKind::Expression, WASMExpressionType::F64, WASMMemoryType::F64, MemoryAccessOffsetMode::WithOffset);
885         case WASMOpExpressionF64::CallInternal:
886             return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::F64);
887         case WASMOpExpressionF64::CallImport:
888             return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::F64);
889         case WASMOpExpressionF64::CallIndirect:
890             return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::F64);
891         case WASMOpExpressionF64::Conditional:
892             return parseConditional(context, WASMExpressionType::F64);
893         case WASMOpExpressionF64::Comma:
894             return parseComma(context, WASMExpressionType::F64);
895         case WASMOpExpressionF64::FromS32:
896             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertSigned);
897         case WASMOpExpressionF64::FromU32:
898             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertUnsigned);
899         case WASMOpExpressionF64::FromF32:
900             return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::F64, WASMTypeConversion::Promote);
901         case WASMOpExpressionF64::Negate:
902         case WASMOpExpressionF64::Abs:
903         case WASMOpExpressionF64::Ceil:
904         case WASMOpExpressionF64::Floor:
905         case WASMOpExpressionF64::Sqrt:
906         case WASMOpExpressionF64::Cos:
907         case WASMOpExpressionF64::Sin:
908         case WASMOpExpressionF64::Tan:
909         case WASMOpExpressionF64::ACos:
910         case WASMOpExpressionF64::ASin:
911         case WASMOpExpressionF64::ATan:
912         case WASMOpExpressionF64::Exp:
913         case WASMOpExpressionF64::Ln:
914             return parseUnaryExpressionF64(context, op);
915         case WASMOpExpressionF64::Add:
916         case WASMOpExpressionF64::Sub:
917         case WASMOpExpressionF64::Mul:
918         case WASMOpExpressionF64::Div:
919         case WASMOpExpressionF64::Mod:
920         case WASMOpExpressionF64::ATan2:
921         case WASMOpExpressionF64::Pow:
922             return parseBinaryExpressionF64(context, op);
923         case WASMOpExpressionF64::Min:
924         case WASMOpExpressionF64::Max:
925             return parseMinOrMaxExpressionF64(context, op);
926         default:
927             ASSERT_NOT_REACHED();
928         }
929     } else {
930         switch (opWithImmediate) {
931         case WASMOpExpressionF64WithImmediate::ConstantPoolIndex:
932             return parseConstantPoolIndexExpressionF64(context, immediate);
933         case WASMOpExpressionF64WithImmediate::GetLocal:
934             return parseGetLocalExpression(context, WASMType::F64, immediate);
935         default:
936             ASSERT_NOT_REACHED();
937         }
938     }
939     return 0;
940 }
941
942 template <class Context>
943 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context, uint32_t constantIndex)
944 {
945     FAIL_IF_FALSE(constantIndex < m_module->f64Constants().size(), "The constant index is incorrect.");
946     return context.buildImmediateF64(m_module->f64Constants()[constantIndex]);
947 }
948
949 template <class Context>
950 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context)
951 {
952     uint32_t constantIndex;
953     READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
954     return parseConstantPoolIndexExpressionF64(context, constantIndex);
955 }
956
957 template <class Context>
958 ContextExpression WASMFunctionParser::parseImmediateExpressionF64(Context& context)
959 {
960     double immediate;
961     READ_DOUBLE_OR_FAIL(immediate, "Cannot read the immediate.");
962     return context.buildImmediateF64(immediate);
963 }
964
965 template <class Context>
966 ContextExpression WASMFunctionParser::parseUnaryExpressionF64(Context& context, WASMOpExpressionF64 op)
967 {
968     ContextExpression expression = parseExpressionF64(context);
969     PROPAGATE_ERROR();
970     return context.buildUnaryF64(expression, op);
971 }
972
973 template <class Context>
974 ContextExpression WASMFunctionParser::parseBinaryExpressionF64(Context& context, WASMOpExpressionF64 op)
975 {
976     ContextExpression left = parseExpressionF64(context);
977     PROPAGATE_ERROR();
978     ContextExpression right = parseExpressionF64(context);
979     PROPAGATE_ERROR();
980     return context.buildBinaryF64(left, right, op);
981 }
982
983 template <class Context>
984 ContextExpression WASMFunctionParser::parseMinOrMaxExpressionF64(Context& context, WASMOpExpressionF64 op)
985 {
986     uint32_t numberOfArguments;
987     READ_COMPACT_UINT32_OR_FAIL(numberOfArguments, "Cannot read the number of arguments to min/max.");
988     FAIL_IF_FALSE(numberOfArguments >= 2, "Min/max must be passed at least 2 arguments.");
989     ContextExpression current = parseExpressionF64(context);
990     PROPAGATE_ERROR();
991     for (uint32_t i = 1; i < numberOfArguments; ++i) {
992         ContextExpression expression = parseExpressionF64(context);
993         PROPAGATE_ERROR();
994         current = context.buildMinOrMaxF64(current, expression, op);
995     }
996     return current;
997 }
998
999 template <class Context>
1000 ContextExpression WASMFunctionParser::parseExpressionVoid(Context& context)
1001 {
1002     WASMOpExpressionVoid op;
1003     READ_OP_EXPRESSION_VOID_OR_FAIL(op, "Cannot read the void expression opcode.");
1004     switch (op) {
1005     case WASMOpExpressionVoid::CallInternal:
1006         return parseCallInternal(context, WASMOpKind::Expression, WASMExpressionType::Void);
1007     case WASMOpExpressionVoid::CallIndirect:
1008         return parseCallIndirect(context, WASMOpKind::Expression, WASMExpressionType::Void);
1009     case WASMOpExpressionVoid::CallImport:
1010         return parseCallImport(context, WASMOpKind::Expression, WASMExpressionType::Void);
1011     default:
1012         RELEASE_ASSERT_NOT_REACHED();
1013     }
1014 }
1015
1016 template <class Context>
1017 ContextExpression WASMFunctionParser::parseGetLocalExpression(Context& context, WASMType type, uint32_t localIndex)
1018 {
1019     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local index is incorrect.");
1020     FAIL_IF_FALSE(m_localTypes[localIndex] == type, "Expected a local of type " + nameOfType(type) + '.');
1021     return context.buildGetLocal(localIndex, type);
1022 }
1023
1024 template <class Context>
1025 ContextExpression WASMFunctionParser::parseGetLocalExpression(Context& context, WASMType type)
1026 {
1027     uint32_t localIndex;
1028     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1029     return parseGetLocalExpression(context, type, localIndex);
1030 }
1031
1032 template <class Context>
1033 ContextExpression WASMFunctionParser::parseGetGlobalExpression(Context& context, WASMType type)
1034 {
1035     uint32_t globalIndex;
1036     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1037     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1038     FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == type, "Expected a global of type " + nameOfType(type) + '.');
1039     return context.buildGetGlobal(globalIndex, type);
1040 }
1041
1042 template <class Context>
1043 ContextExpression WASMFunctionParser::parseSetLocal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, uint32_t localIndex)
1044 {
1045     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
1046     WASMType type = m_localTypes[localIndex];
1047     if (opKind == WASMOpKind::Expression)
1048         FAIL_IF_FALSE(expressionType == WASMExpressionType(type), "The type doesn't match.");
1049     ContextExpression expression = parseExpression(context, WASMExpressionType(type));
1050     PROPAGATE_ERROR();
1051     return context.buildSetLocal(opKind, localIndex, expression, type);
1052 }
1053
1054 template <class Context>
1055 ContextExpression WASMFunctionParser::parseSetLocal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType)
1056 {
1057     uint32_t localIndex;
1058     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1059     return parseSetLocal(context, opKind, expressionType, localIndex);
1060 }
1061
1062 template <class Context>
1063 ContextExpression WASMFunctionParser::parseSetGlobal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, uint32_t globalIndex)
1064 {
1065     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1066     WASMType type = m_module->globalVariableTypes()[globalIndex];
1067     if (opKind == WASMOpKind::Expression)
1068         FAIL_IF_FALSE(expressionType == WASMExpressionType(type), "The type doesn't match.");
1069     ContextExpression expression = parseExpression(context, WASMExpressionType(type));
1070     PROPAGATE_ERROR();
1071     return context.buildSetGlobal(opKind, globalIndex, expression, type);
1072 }
1073
1074 template <class Context>
1075 ContextExpression WASMFunctionParser::parseSetGlobal(Context& context, WASMOpKind opKind, WASMExpressionType expressionType)
1076 {
1077     uint32_t globalIndex;
1078     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1079     return parseSetGlobal(context, opKind, expressionType, globalIndex);
1080 }
1081
1082 template <class Context>
1083 ContextMemoryAddress WASMFunctionParser::parseMemoryAddress(Context& context, MemoryAccessOffsetMode offsetMode)
1084 {
1085     uint32_t offset = 0;
1086     if (offsetMode == MemoryAccessOffsetMode::WithOffset)
1087         READ_COMPACT_UINT32_OR_FAIL(offset, "Cannot read the address offset.");
1088     ContextExpression index = parseExpressionI32(context);
1089     PROPAGATE_ERROR();
1090     return ContextMemoryAddress(index, offset);
1091 }
1092
1093 template <class Context>
1094 ContextExpression WASMFunctionParser::parseLoad(Context& context, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode, MemoryAccessConversion conversion)
1095 {
1096     FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided.");
1097     const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode);
1098     PROPAGATE_ERROR();
1099     return context.buildLoad(memoryAddress, expressionType, memoryType, conversion);
1100 }
1101
1102 template <class Context>
1103 ContextExpression WASMFunctionParser::parseStore(Context& context, WASMOpKind opKind, WASMExpressionType expressionType, WASMMemoryType memoryType, MemoryAccessOffsetMode offsetMode)
1104 {
1105     FAIL_IF_FALSE(m_module->arrayBuffer(), "An ArrayBuffer is not provided.");
1106     const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, offsetMode);
1107     PROPAGATE_ERROR();
1108
1109     ContextExpression value = parseExpression(context, expressionType);
1110     PROPAGATE_ERROR();
1111     return context.buildStore(opKind, memoryAddress, expressionType, memoryType, value);
1112 }
1113
1114 template <class Context>
1115 ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments)
1116 {
1117     ContextExpressionList argumentList;
1118     for (size_t i = 0; i < arguments.size(); ++i) {
1119         ContextExpression expression = parseExpression(context, WASMExpressionType(arguments[i]));
1120         PROPAGATE_ERROR();
1121         context.appendExpressionList(argumentList, expression);
1122     }
1123     return argumentList;
1124 }
1125
1126 template <class Context>
1127 ContextExpression WASMFunctionParser::parseCallInternal(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
1128 {
1129     uint32_t functionIndex;
1130     READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
1131     FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
1132     const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[functionIndex].signatureIndex];
1133     if (opKind == WASMOpKind::Expression)
1134         FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1135
1136     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1137     PROPAGATE_ERROR();
1138     return context.buildCallInternal(functionIndex, argumentList, signature, returnType);
1139 }
1140
1141 template <class Context>
1142 ContextExpression WASMFunctionParser::parseCallIndirect(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
1143 {
1144     uint32_t functionPointerTableIndex;
1145     READ_COMPACT_UINT32_OR_FAIL(functionPointerTableIndex, "Cannot read the function pointer table index.");
1146     FAIL_IF_FALSE(functionPointerTableIndex < m_module->functionPointerTables().size(), "The function pointer table index is incorrect.");
1147     const WASMFunctionPointerTable& functionPointerTable = m_module->functionPointerTables()[functionPointerTableIndex];
1148     const WASMSignature& signature = m_module->signatures()[functionPointerTable.signatureIndex];
1149     if (opKind == WASMOpKind::Expression)
1150         FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1151
1152     ContextExpression index = parseExpressionI32(context);
1153     PROPAGATE_ERROR();
1154
1155     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1156     PROPAGATE_ERROR();
1157     return context.buildCallIndirect(functionPointerTableIndex, index, argumentList, signature, returnType);
1158 }
1159
1160 template <class Context>
1161 ContextExpression WASMFunctionParser::parseCallImport(Context& context, WASMOpKind opKind, WASMExpressionType returnType)
1162 {
1163     uint32_t functionImportSignatureIndex;
1164     READ_COMPACT_UINT32_OR_FAIL(functionImportSignatureIndex, "Cannot read the function import signature index.");
1165     FAIL_IF_FALSE(functionImportSignatureIndex < m_module->functionImportSignatures().size(), "The function import signature index is incorrect.");
1166     const WASMFunctionImportSignature& functionImportSignature = m_module->functionImportSignatures()[functionImportSignatureIndex];
1167     const WASMSignature& signature = m_module->signatures()[functionImportSignature.signatureIndex];
1168     if (opKind == WASMOpKind::Expression)
1169         FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1170
1171     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1172     PROPAGATE_ERROR();
1173     return context.buildCallImport(functionImportSignature.functionImportIndex, argumentList, signature, returnType);
1174 }
1175
1176 template <class Context>
1177 ContextExpression WASMFunctionParser::parseConditional(Context& context, WASMExpressionType expressionType)
1178 {
1179     ContextJumpTarget elseTarget;
1180     ContextJumpTarget end;
1181
1182     ContextExpression condition = parseExpressionI32(context);
1183     PROPAGATE_ERROR();
1184
1185     context.jumpToTargetIf(Context::JumpCondition::Zero, condition, elseTarget);
1186
1187     parseExpression(context, expressionType);
1188     PROPAGATE_ERROR();
1189     
1190     context.jumpToTarget(end);
1191     context.linkTarget(elseTarget);
1192
1193     // We use discard() here to decrement the stack top in the baseline JIT.
1194     context.discard(UNUSED);
1195     parseExpression(context, expressionType);
1196     PROPAGATE_ERROR();
1197     
1198     context.linkTarget(end);
1199     return UNUSED;
1200 }
1201
1202 template <class Context>
1203 ContextExpression WASMFunctionParser::parseComma(Context& context, WASMExpressionType expressionType)
1204 {
1205     WASMExpressionType leftExpressionType;
1206     READ_EXPRESSION_TYPE_OR_FAIL(leftExpressionType, "Cannot read the expression type.");
1207     ContextExpression leftExpression = parseExpression(context, leftExpressionType);
1208     PROPAGATE_ERROR();
1209     if (leftExpressionType != WASMExpressionType::Void)
1210         context.discard(leftExpression);
1211     return parseExpression(context, expressionType);
1212 }
1213
1214 template <class Context>
1215 ContextExpression WASMFunctionParser::parseConvertType(Context& context, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion conversion)
1216 {
1217     ContextExpression expression = parseExpression(context, fromType);
1218     PROPAGATE_ERROR();
1219
1220     return context.buildConvertType(expression, fromType, toType, conversion);
1221 }
1222
1223 } // namespace JSC
1224
1225 #endif // ENABLE(WEBASSEMBLY)