176e6e353de8887a5523dda8494327c4e52b4799
[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 "WASMFunctionSyntaxChecker.h"
35
36 #define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
37 #define FAIL_WITH_MESSAGE(errorMessage) do {  m_errorMessage = errorMessage; return 0; } while (0)
38 #define READ_FLOAT_OR_FAIL(result, errorMessage) do { if (!m_reader.readFloat(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
39 #define READ_DOUBLE_OR_FAIL(result, errorMessage) do { if (!m_reader.readDouble(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
40 #define READ_COMPACT_INT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
41 #define READ_COMPACT_UINT32_OR_FAIL(result, errorMessage) do { if (!m_reader.readCompactUInt32(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
42 #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)
43 #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)
44 #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)
45 #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)
46 #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)
47 #define READ_SWITCH_CASE_OR_FAIL(result, errorMessage) do { if (!m_reader.readSwitchCase(result)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
48 #define FAIL_IF_FALSE(condition, errorMessage) do { if (!(condition)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
49
50 #define UNUSED 0
51
52 namespace JSC {
53
54 bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage)
55 {
56     WASMFunctionParser parser(module, source, functionIndex);
57     WASMFunctionSyntaxChecker syntaxChecker;
58     parser.m_reader.setOffset(startOffsetInSource);
59     parser.parseFunction(syntaxChecker);
60     if (!parser.m_errorMessage.isNull()) {
61         errorMessage = parser.m_errorMessage;
62         return false;
63     }
64     endOffsetInSource = parser.m_reader.offset();
65     stackHeight = syntaxChecker.stackHeight();
66     return true;
67 }
68
69 void WASMFunctionParser::compile(VM& vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode& source, size_t functionIndex)
70 {
71     WASMFunctionParser parser(module, source, functionIndex);
72     WASMFunctionCompiler compiler(vm, codeBlock, module, module->functionStackHeights()[functionIndex]);
73     parser.m_reader.setOffset(module->functionStartOffsetsInSource()[functionIndex]);
74     parser.parseFunction(compiler);
75     ASSERT(parser.m_errorMessage.isNull());
76 }
77
78 template <class Context>
79 bool WASMFunctionParser::parseFunction(Context& context)
80 {
81     const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[m_functionIndex].signatureIndex];
82
83     m_returnType = signature.returnType;
84
85     parseLocalVariables();
86     PROPAGATE_ERROR();
87
88     const Vector<WASMType>& arguments = signature.arguments;
89     for (size_t i = 0; i < arguments.size(); ++i)
90         m_localTypes.append(arguments[i]);
91     for (uint32_t i = 0; i < m_numberOfI32LocalVariables; ++i)
92         m_localTypes.append(WASMType::I32);
93     for (uint32_t i = 0; i < m_numberOfF32LocalVariables; ++i)
94         m_localTypes.append(WASMType::F32);
95     for (uint32_t i = 0; i < m_numberOfF64LocalVariables; ++i)
96         m_localTypes.append(WASMType::F64);
97
98     context.startFunction(arguments, m_numberOfI32LocalVariables, m_numberOfF32LocalVariables, m_numberOfF64LocalVariables);
99
100     parseBlockStatement(context);
101     PROPAGATE_ERROR();
102
103     context.endFunction();
104     return true;
105 }
106
107 bool WASMFunctionParser::parseLocalVariables()
108 {
109     m_numberOfI32LocalVariables = 0;
110     m_numberOfF32LocalVariables = 0;
111     m_numberOfF64LocalVariables = 0;
112
113     bool hasImmediate;
114     WASMVariableTypes variableTypes;
115     WASMVariableTypesWithImmediate variableTypesWithImmediate;
116     uint8_t immediate;
117     READ_VARIABLE_TYPES_OR_FAIL(hasImmediate, variableTypes, variableTypesWithImmediate, immediate, "Cannot read the types of local variables.");
118     if (!hasImmediate) {
119         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::I32))
120             READ_COMPACT_UINT32_OR_FAIL(m_numberOfI32LocalVariables, "Cannot read the number of int32 local variables.");
121         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F32))
122             READ_COMPACT_UINT32_OR_FAIL(m_numberOfF32LocalVariables, "Cannot read the number of float32 local variables.");
123         if (static_cast<uint8_t>(variableTypes) & static_cast<uint8_t>(WASMVariableTypes::F64))
124             READ_COMPACT_UINT32_OR_FAIL(m_numberOfF64LocalVariables, "Cannot read the number of float64 local variables.");
125     } else
126         m_numberOfI32LocalVariables = immediate;
127     return true;
128 }
129
130 template <class Context>
131 ContextStatement WASMFunctionParser::parseStatement(Context& context)
132 {
133     bool hasImmediate;
134     WASMOpStatement op;
135     WASMOpStatementWithImmediate opWithImmediate;
136     uint8_t immediate;
137     READ_OP_STATEMENT_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the statement opcode.");
138     if (!hasImmediate) {
139         switch (op) {
140         case WASMOpStatement::SetLocal:
141             parseSetLocalStatement(context);
142             break;
143         case WASMOpStatement::SetGlobal:
144             parseSetGlobalStatement(context);
145             break;
146         case WASMOpStatement::Return:
147             parseReturnStatement(context);
148             break;
149         case WASMOpStatement::Block:
150             parseBlockStatement(context);
151             break;
152         case WASMOpStatement::If:
153             parseIfStatement(context);
154             break;
155         case WASMOpStatement::IfElse:
156             parseIfElseStatement(context);
157             break;
158         case WASMOpStatement::While:
159             parseWhileStatement(context);
160             break;
161         case WASMOpStatement::Do:
162             parseDoStatement(context);
163             break;
164         case WASMOpStatement::Label:
165             parseLabelStatement(context);
166             break;
167         case WASMOpStatement::Break:
168             parseBreakStatement(context);
169             break;
170         case WASMOpStatement::BreakLabel:
171             parseBreakLabelStatement(context);
172             break;
173         case WASMOpStatement::Continue:
174             parseContinueStatement(context);
175             break;
176         case WASMOpStatement::ContinueLabel:
177             parseContinueLabelStatement(context);
178             break;
179         case WASMOpStatement::Switch:
180             parseSwitchStatement(context);
181             break;
182         case WASMOpStatement::I32Store8:
183         case WASMOpStatement::I32StoreWithOffset8:
184         case WASMOpStatement::I32Store16:
185         case WASMOpStatement::I32StoreWithOffset16:
186         case WASMOpStatement::I32Store32:
187         case WASMOpStatement::I32StoreWithOffset32:
188         case WASMOpStatement::F32Store:
189         case WASMOpStatement::F32StoreWithOffset:
190         case WASMOpStatement::F64Store:
191         case WASMOpStatement::F64StoreWithOffset:
192         case WASMOpStatement::CallInternal:
193         case WASMOpStatement::CallIndirect:
194         case WASMOpStatement::CallImport:
195             // FIXME: Implement these instructions.
196             FAIL_WITH_MESSAGE("Unsupported instruction.");
197         default:
198             ASSERT_NOT_REACHED();
199         }
200     } else {
201         switch (opWithImmediate) {
202         case WASMOpStatementWithImmediate::SetLocal:
203             parseSetLocalStatement(context, immediate);
204             break;
205         case WASMOpStatementWithImmediate::SetGlobal:
206             parseSetGlobalStatement(context, immediate);
207             break;
208         default:
209             ASSERT_NOT_REACHED();
210         }
211     }
212     return UNUSED;
213 }
214
215 template <class Context>
216 ContextStatement WASMFunctionParser::parseSetLocalStatement(Context& context, uint32_t localIndex)
217 {
218     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
219     WASMType type = m_localTypes[localIndex];
220     ContextExpression expression = parseExpression(context, WASMExpressionType(type));
221     PROPAGATE_ERROR();
222     context.buildSetLocal(localIndex, expression, type);
223     return UNUSED;
224 }
225
226 template <class Context>
227 ContextStatement WASMFunctionParser::parseSetLocalStatement(Context& context)
228 {
229     uint32_t localIndex;
230     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
231     return parseSetLocalStatement(context, localIndex);
232 }
233
234 template <class Context>
235 ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context, uint32_t globalIndex)
236 {
237     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
238     WASMType type = m_module->globalVariableTypes()[globalIndex];
239     ContextExpression expression = parseExpression(context, WASMExpressionType(type));
240     PROPAGATE_ERROR();
241     context.buildSetGlobal(globalIndex, expression, type);
242     return UNUSED;
243 }
244
245 template <class Context>
246 ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context)
247 {
248     uint32_t globalIndex;
249     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
250     return parseSetGlobalStatement(context, globalIndex);
251 }
252
253 template <class Context>
254 ContextStatement WASMFunctionParser::parseReturnStatement(Context& context)
255 {
256     ContextExpression expression = 0;
257     if (m_returnType != WASMExpressionType::Void) {
258         expression = parseExpression(context, m_returnType);
259         PROPAGATE_ERROR();
260     }
261     context.buildReturn(expression, m_returnType);
262     return UNUSED;
263 }
264
265 template <class Context>
266 ContextStatement WASMFunctionParser::parseBlockStatement(Context& context)
267 {
268     uint32_t numberOfStatements;
269     READ_COMPACT_UINT32_OR_FAIL(numberOfStatements, "Cannot read the number of statements.");
270     for (uint32_t i = 0; i < numberOfStatements; ++i) {
271         parseStatement(context);
272         PROPAGATE_ERROR();
273     }
274     return UNUSED;
275 }
276
277 template <class Context>
278 ContextStatement WASMFunctionParser::parseIfStatement(Context& context)
279 {
280     ContextJumpTarget end;
281
282     ContextExpression expression = parseExpressionI32(context);
283     PROPAGATE_ERROR();
284
285     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, end);
286
287     parseStatement(context);
288     PROPAGATE_ERROR();
289
290     context.linkTarget(end);
291     return UNUSED;
292 }
293
294 template <class Context>
295 ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context)
296 {
297     ContextJumpTarget elseTarget;
298     ContextJumpTarget end;
299
300     ContextExpression expression = parseExpressionI32(context);
301     PROPAGATE_ERROR();
302
303     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, elseTarget);
304
305     parseStatement(context);
306     PROPAGATE_ERROR();
307
308     context.jumpToTarget(end);
309     context.linkTarget(elseTarget);
310
311     parseStatement(context);
312     PROPAGATE_ERROR();
313
314     context.linkTarget(end);
315     return UNUSED;
316 }
317
318 template <class Context>
319 ContextStatement WASMFunctionParser::parseWhileStatement(Context& context)
320 {
321     context.startLoop();
322     context.linkTarget(context.continueTarget());
323
324     ContextExpression expression = parseExpressionI32(context);
325     PROPAGATE_ERROR();
326
327     context.jumpToTargetIf(Context::JumpCondition::Zero, expression, context.breakTarget());
328
329     m_breakScopeDepth++;
330     m_continueScopeDepth++;
331     parseStatement(context);
332     PROPAGATE_ERROR();
333     m_continueScopeDepth--;
334     m_breakScopeDepth--;
335
336     context.jumpToTarget(context.continueTarget());
337
338     context.linkTarget(context.breakTarget());
339     context.endLoop();
340     return UNUSED;
341 }
342
343 template <class Context>
344 ContextStatement WASMFunctionParser::parseDoStatement(Context& context)
345 {
346     context.startLoop();
347
348     ContextJumpTarget topOfLoop;
349     context.linkTarget(topOfLoop);
350
351     m_breakScopeDepth++;
352     m_continueScopeDepth++;
353     parseStatement(context);
354     PROPAGATE_ERROR();
355     m_continueScopeDepth--;
356     m_breakScopeDepth--;
357
358     context.linkTarget(context.continueTarget());
359
360     ContextExpression expression = parseExpressionI32(context);
361     PROPAGATE_ERROR();
362
363     context.jumpToTargetIf(Context::JumpCondition::NonZero, expression, topOfLoop);
364
365     context.linkTarget(context.breakTarget());
366     context.endLoop();
367     return UNUSED;
368 }
369
370 template <class Context>
371 ContextStatement WASMFunctionParser::parseLabelStatement(Context& context)
372 {
373     context.startLabel();
374     m_labelDepth++;
375     parseStatement(context);
376     PROPAGATE_ERROR();
377     m_labelDepth--;
378     context.endLabel();
379     return UNUSED;
380 }
381
382 template <class Context>
383 ContextStatement WASMFunctionParser::parseBreakStatement(Context& context)
384 {
385     FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement.");
386     context.jumpToTarget(context.breakTarget());
387     return UNUSED;
388 }
389
390 template <class Context>
391 ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& context)
392 {
393     uint32_t labelIndex;
394     READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
395     FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
396     context.jumpToTarget(context.breakLabelTarget(labelIndex));
397     return UNUSED;
398 }
399
400 template <class Context>
401 ContextStatement WASMFunctionParser::parseContinueStatement(Context& context)
402 {
403     FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement.");
404     context.jumpToTarget(context.continueTarget());
405     return UNUSED;
406 }
407
408 template <class Context>
409 ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& context)
410 {
411     uint32_t labelIndex;
412     READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
413     FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
414     context.jumpToTarget(context.continueLabelTarget(labelIndex));
415     return UNUSED;
416 }
417
418 template <class Context>
419 ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context)
420 {
421     context.startSwitch();
422     uint32_t numberOfCases;
423     READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases.");
424     ContextExpression expression = parseExpressionI32(context);
425     PROPAGATE_ERROR();
426
427     ContextJumpTarget compare;
428     context.jumpToTarget(compare);
429
430     Vector<int64_t> cases;
431     Vector<ContextJumpTarget> targets;
432     cases.reserveInitialCapacity(numberOfCases);
433     targets.reserveInitialCapacity(numberOfCases);
434     bool hasDefault = false;
435     ContextJumpTarget defaultTarget;
436
437     m_breakScopeDepth++;
438     for (uint32_t i = 0; i < numberOfCases; ++i) {
439         WASMSwitchCase switchCase;
440         READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case.");
441         switch (switchCase) {
442         case WASMSwitchCase::CaseWithNoStatements:
443         case WASMSwitchCase::CaseWithStatement:
444         case WASMSwitchCase::CaseWithBlockStatement: {
445             uint32_t value;
446             READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case.");
447             cases.uncheckedAppend(value);
448             ContextJumpTarget target;
449             context.linkTarget(target);
450             targets.uncheckedAppend(target);
451             if (switchCase == WASMSwitchCase::CaseWithStatement) {
452                 parseStatement(context);
453                 PROPAGATE_ERROR();
454             } else if (switchCase == WASMSwitchCase::CaseWithBlockStatement) {
455                 parseBlockStatement(context);
456                 PROPAGATE_ERROR();
457             }
458             break;
459         }
460         case WASMSwitchCase::DefaultWithNoStatements:
461         case WASMSwitchCase::DefaultWithStatement:
462         case WASMSwitchCase::DefaultWithBlockStatement: {
463             FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case.");
464             hasDefault = true;
465             context.linkTarget(defaultTarget);
466             if (switchCase == WASMSwitchCase::DefaultWithStatement) {
467                 parseStatement(context);
468                 PROPAGATE_ERROR();
469             } else if (switchCase == WASMSwitchCase::DefaultWithBlockStatement) {
470                 parseBlockStatement(context);
471                 PROPAGATE_ERROR();
472             }
473             break;
474         }
475         default:
476             ASSERT_NOT_REACHED();
477         }
478     }
479     if (!hasDefault)
480         context.linkTarget(defaultTarget);
481
482     m_breakScopeDepth--;
483
484     context.jumpToTarget(context.breakTarget());
485     context.linkTarget(compare);
486
487     context.buildSwitch(expression, cases, targets, defaultTarget);
488
489     context.linkTarget(context.breakTarget());
490     context.endSwitch();
491     return UNUSED;
492 }
493
494 template <class Context>
495 ContextExpression WASMFunctionParser::parseExpression(Context& context, WASMExpressionType expressionType)
496 {
497     switch (expressionType) {
498     case WASMExpressionType::I32:
499         return parseExpressionI32(context);
500     case WASMExpressionType::F32:
501         return parseExpressionF32(context);
502     case WASMExpressionType::F64:
503         return parseExpressionF64(context);
504     case WASMExpressionType::Void:
505         // FIXME: Implement these instructions.
506         FAIL_WITH_MESSAGE("Unsupported instruction.");
507     default:
508         ASSERT_NOT_REACHED();
509     }
510     return 0;
511 }
512
513 template <class Context>
514 ContextExpression WASMFunctionParser::parseExpressionI32(Context& context)
515 {
516     bool hasImmediate;
517     WASMOpExpressionI32 op;
518     WASMOpExpressionI32WithImmediate opWithImmediate;
519     uint8_t immediate;
520     READ_OP_EXPRESSION_I32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the int32 expression opcode.");
521     if (!hasImmediate) {
522         switch (op) {
523         case WASMOpExpressionI32::ConstantPoolIndex:
524             return parseConstantPoolIndexExpressionI32(context);
525         case WASMOpExpressionI32::Immediate:
526             return parseImmediateExpressionI32(context);
527         case WASMOpExpressionI32::GetLocal:
528             return parseGetLocalExpressionI32(context);
529         case WASMOpExpressionI32::GetGlobal:
530             return parseGetGlobalExpressionI32(context);
531         case WASMOpExpressionI32::CallInternal:
532             return parseCallInternal(context, WASMExpressionType::I32);
533         case WASMOpExpressionI32::CallIndirect:
534             return parseCallIndirect(context, WASMExpressionType::I32);
535         case WASMOpExpressionI32::CallImport:
536             return parseCallImport(context, WASMExpressionType::I32);
537         case WASMOpExpressionI32::FromF32:
538             return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
539         case WASMOpExpressionI32::FromF64:
540             return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::I32, WASMTypeConversion::ConvertSigned);
541         case WASMOpExpressionI32::Negate:
542         case WASMOpExpressionI32::BitNot:
543         case WASMOpExpressionI32::CountLeadingZeros:
544         case WASMOpExpressionI32::LogicalNot:
545         case WASMOpExpressionI32::Abs:
546             return parseUnaryExpressionI32(context, op);
547         case WASMOpExpressionI32::Add:
548         case WASMOpExpressionI32::Sub:
549         case WASMOpExpressionI32::Mul:
550         case WASMOpExpressionI32::SDiv:
551         case WASMOpExpressionI32::UDiv:
552         case WASMOpExpressionI32::SMod:
553         case WASMOpExpressionI32::UMod:
554         case WASMOpExpressionI32::BitOr:
555         case WASMOpExpressionI32::BitAnd:
556         case WASMOpExpressionI32::BitXor:
557         case WASMOpExpressionI32::LeftShift:
558         case WASMOpExpressionI32::ArithmeticRightShift:
559         case WASMOpExpressionI32::LogicalRightShift:
560             return parseBinaryExpressionI32(context, op);
561         case WASMOpExpressionI32::EqualI32:
562         case WASMOpExpressionI32::NotEqualI32:
563         case WASMOpExpressionI32::SLessThanI32:
564         case WASMOpExpressionI32::ULessThanI32:
565         case WASMOpExpressionI32::SLessThanOrEqualI32:
566         case WASMOpExpressionI32::ULessThanOrEqualI32:
567         case WASMOpExpressionI32::SGreaterThanI32:
568         case WASMOpExpressionI32::UGreaterThanI32:
569         case WASMOpExpressionI32::SGreaterThanOrEqualI32:
570         case WASMOpExpressionI32::UGreaterThanOrEqualI32:
571             return parseRelationalI32ExpressionI32(context, op);
572         case WASMOpExpressionI32::EqualF32:
573         case WASMOpExpressionI32::NotEqualF32:
574         case WASMOpExpressionI32::LessThanF32:
575         case WASMOpExpressionI32::LessThanOrEqualF32:
576         case WASMOpExpressionI32::GreaterThanF32:
577         case WASMOpExpressionI32::GreaterThanOrEqualF32:
578             return parseRelationalF32ExpressionI32(context, op);
579         case WASMOpExpressionI32::EqualF64:
580         case WASMOpExpressionI32::NotEqualF64:
581         case WASMOpExpressionI32::LessThanF64:
582         case WASMOpExpressionI32::LessThanOrEqualF64:
583         case WASMOpExpressionI32::GreaterThanF64:
584         case WASMOpExpressionI32::GreaterThanOrEqualF64:
585             return parseRelationalF64ExpressionI32(context, op);
586         case WASMOpExpressionI32::SetLocal:
587         case WASMOpExpressionI32::SetGlobal:
588         case WASMOpExpressionI32::SLoad8:
589         case WASMOpExpressionI32::SLoadWithOffset8:
590         case WASMOpExpressionI32::ULoad8:
591         case WASMOpExpressionI32::ULoadWithOffset8:
592         case WASMOpExpressionI32::SLoad16:
593         case WASMOpExpressionI32::SLoadWithOffset16:
594         case WASMOpExpressionI32::ULoad16:
595         case WASMOpExpressionI32::ULoadWithOffset16:
596         case WASMOpExpressionI32::Load32:
597         case WASMOpExpressionI32::LoadWithOffset32:
598         case WASMOpExpressionI32::Store8:
599         case WASMOpExpressionI32::StoreWithOffset8:
600         case WASMOpExpressionI32::Store16:
601         case WASMOpExpressionI32::StoreWithOffset16:
602         case WASMOpExpressionI32::Store32:
603         case WASMOpExpressionI32::StoreWithOffset32:
604         case WASMOpExpressionI32::Conditional:
605         case WASMOpExpressionI32::Comma:
606         case WASMOpExpressionI32::SMin:
607         case WASMOpExpressionI32::UMin:
608         case WASMOpExpressionI32::SMax:
609         case WASMOpExpressionI32::UMax:
610             // FIXME: Implement these instructions.
611             FAIL_WITH_MESSAGE("Unsupported instruction.");
612         default:
613             ASSERT_NOT_REACHED();
614         }
615     } else {
616         switch (opWithImmediate) {
617         case WASMOpExpressionI32WithImmediate::ConstantPoolIndex:
618             return parseConstantPoolIndexExpressionI32(context, immediate);
619         case WASMOpExpressionI32WithImmediate::Immediate:
620             return parseImmediateExpressionI32(context, immediate);
621         case WASMOpExpressionI32WithImmediate::GetLocal:
622             return parseGetLocalExpressionI32(context, immediate);
623         default:
624             ASSERT_NOT_REACHED();
625         }
626     }
627     return 0;
628 }
629
630 template <class Context>
631 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context, uint32_t constantPoolIndex)
632 {
633     FAIL_IF_FALSE(constantPoolIndex < m_module->i32Constants().size(), "The constant pool index is incorrect.");
634     return context.buildImmediateI32(m_module->i32Constants()[constantPoolIndex]);
635 }
636
637 template <class Context>
638 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionI32(Context& context)
639 {
640     uint32_t constantPoolIndex;
641     READ_COMPACT_UINT32_OR_FAIL(constantPoolIndex, "Cannot read the constant pool index.");
642     return parseConstantPoolIndexExpressionI32(context, constantPoolIndex);
643 }
644
645 template <class Context>
646 ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context, uint32_t immediate)
647 {
648     return context.buildImmediateI32(immediate);
649 }
650
651 template <class Context>
652 ContextExpression WASMFunctionParser::parseImmediateExpressionI32(Context& context)
653 {
654     uint32_t immediate;
655     READ_COMPACT_UINT32_OR_FAIL(immediate, "Cannot read the immediate.");
656     return parseImmediateExpressionI32(context, immediate);
657 }
658
659 template <class Context>
660 ContextExpression WASMFunctionParser::parseGetLocalExpressionI32(Context& context, uint32_t localIndex)
661 {
662     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local index is incorrect.");
663     FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::I32, "Expected a local of type int32.");
664     return context.buildGetLocal(localIndex, WASMType::I32);
665 }
666
667 template <class Context>
668 ContextExpression WASMFunctionParser::parseGetLocalExpressionI32(Context& context)
669 {
670     uint32_t localIndex;
671     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
672     return parseGetLocalExpressionI32(context, localIndex);
673 }
674
675 template <class Context>
676 ContextExpression WASMFunctionParser::parseGetGlobalExpressionI32(Context& context)
677 {
678     uint32_t globalIndex;
679     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
680     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
681     FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::I32, "Expected a global variable of type int32.");
682     return context.buildGetGlobal(globalIndex, WASMType::I32);
683 }
684
685 template <class Context>
686 ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op)
687 {
688     ContextExpression expression = parseExpressionI32(context);
689     PROPAGATE_ERROR();
690     return context.buildUnaryI32(expression, op);
691 }
692
693 template <class Context>
694 ContextExpression WASMFunctionParser::parseBinaryExpressionI32(Context& context, WASMOpExpressionI32 op)
695 {
696     ContextExpression left = parseExpressionI32(context);
697     PROPAGATE_ERROR();
698     ContextExpression right = parseExpressionI32(context);
699     PROPAGATE_ERROR();
700     return context.buildBinaryI32(left, right, op);
701 }
702
703 template <class Context>
704 ContextExpression WASMFunctionParser::parseRelationalI32ExpressionI32(Context& context, WASMOpExpressionI32 op)
705 {
706     ContextExpression left = parseExpressionI32(context);
707     PROPAGATE_ERROR();
708     ContextExpression right = parseExpressionI32(context);
709     PROPAGATE_ERROR();
710     return context.buildRelationalI32(left, right, op);
711 }
712
713 template <class Context>
714 ContextExpression WASMFunctionParser::parseRelationalF32ExpressionI32(Context& context, WASMOpExpressionI32 op)
715 {
716     ContextExpression left = parseExpressionF32(context);
717     PROPAGATE_ERROR();
718     ContextExpression right = parseExpressionF32(context);
719     PROPAGATE_ERROR();
720     return context.buildRelationalF32(left, right, op);
721 }
722
723 template <class Context>
724 ContextExpression WASMFunctionParser::parseRelationalF64ExpressionI32(Context& context, WASMOpExpressionI32 op)
725 {
726     ContextExpression left = parseExpressionF64(context);
727     PROPAGATE_ERROR();
728     ContextExpression right = parseExpressionF64(context);
729     PROPAGATE_ERROR();
730     return context.buildRelationalF64(left, right, op);
731 }
732
733 template <class Context>
734 ContextExpression WASMFunctionParser::parseExpressionF32(Context& context)
735 {
736     bool hasImmediate;
737     WASMOpExpressionF32 op;
738     WASMOpExpressionF32WithImmediate opWithImmediate;
739     uint8_t immediate;
740     READ_OP_EXPRESSION_F32_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float32 expression opcode.");
741     if (!hasImmediate) {
742         switch (op) {
743         case WASMOpExpressionF32::ConstantPoolIndex:
744             return parseConstantPoolIndexExpressionF32(context);
745         case WASMOpExpressionF32::Immediate:
746             return parseImmediateExpressionF32(context);
747         case WASMOpExpressionF32::GetLocal:
748             return parseGetLocalExpressionF32(context);
749         case WASMOpExpressionF32::GetGlobal:
750             return parseGetGlobalExpressionF32(context);
751         case WASMOpExpressionF32::CallInternal:
752             return parseCallInternal(context, WASMExpressionType::F32);
753         case WASMOpExpressionF32::CallIndirect:
754             return parseCallIndirect(context, WASMExpressionType::F32);
755         case WASMOpExpressionF32::FromS32:
756             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertSigned);
757         case WASMOpExpressionF32::FromU32:
758             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F32, WASMTypeConversion::ConvertUnsigned);
759         case WASMOpExpressionF32::FromF64:
760             return parseConvertType(context, WASMExpressionType::F64, WASMExpressionType::F32, WASMTypeConversion::Demote);
761         case WASMOpExpressionF32::Negate:
762         case WASMOpExpressionF32::Abs:
763         case WASMOpExpressionF32::Ceil:
764         case WASMOpExpressionF32::Floor:
765         case WASMOpExpressionF32::Sqrt:
766             return parseUnaryExpressionF32(context, op);
767         case WASMOpExpressionF32::Add:
768         case WASMOpExpressionF32::Sub:
769         case WASMOpExpressionF32::Mul:
770         case WASMOpExpressionF32::Div:
771             return parseBinaryExpressionF32(context, op);
772         case WASMOpExpressionF32::SetLocal:
773         case WASMOpExpressionF32::SetGlobal:
774         case WASMOpExpressionF32::Load:
775         case WASMOpExpressionF32::LoadWithOffset:
776         case WASMOpExpressionF32::Store:
777         case WASMOpExpressionF32::StoreWithOffset:
778         case WASMOpExpressionF32::Conditional:
779         case WASMOpExpressionF32::Comma:
780             // FIXME: Implement these instructions.
781             FAIL_WITH_MESSAGE("Unsupported instruction.");
782         default:
783             ASSERT_NOT_REACHED();
784         }
785     } else {
786         switch (opWithImmediate) {
787         case WASMOpExpressionF32WithImmediate::ConstantPoolIndex:
788             return parseConstantPoolIndexExpressionF32(context, immediate);
789         case WASMOpExpressionF32WithImmediate::GetLocal:
790             return parseGetLocalExpressionF32(context, immediate);
791         default:
792             ASSERT_NOT_REACHED();
793         }
794     }
795     return 0;
796 }
797
798 template <class Context>
799 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context, uint32_t constantIndex)
800 {
801     FAIL_IF_FALSE(constantIndex < m_module->f32Constants().size(), "The constant pool index is incorrect.");
802     return context.buildImmediateF32(m_module->f32Constants()[constantIndex]);
803 }
804
805 template <class Context>
806 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF32(Context& context)
807 {
808     uint32_t constantIndex;
809     READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant pool index.");
810     return parseConstantPoolIndexExpressionF32(context, constantIndex);
811 }
812
813 template <class Context>
814 ContextExpression WASMFunctionParser::parseImmediateExpressionF32(Context& context)
815 {
816     float immediate;
817     READ_FLOAT_OR_FAIL(immediate, "Cannot read the immediate.");
818     return context.buildImmediateF32(immediate);
819 }
820
821 template <class Context>
822 ContextExpression WASMFunctionParser::parseGetLocalExpressionF32(Context& context, uint32_t localIndex)
823 {
824     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local index is incorrect.");
825     FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F32, "Expected a local of type float32.");
826     return context.buildGetLocal(localIndex, WASMType::F32);
827 }
828
829 template <class Context>
830 ContextExpression WASMFunctionParser::parseGetLocalExpressionF32(Context& context)
831 {
832     uint32_t localIndex;
833     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
834     return parseGetLocalExpressionF32(context, localIndex);
835 }
836
837 template <class Context>
838 ContextExpression WASMFunctionParser::parseGetGlobalExpressionF32(Context& context)
839 {
840     uint32_t globalIndex;
841     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
842     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
843     FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F32, "Expected a global variable of type float32.");
844     return context.buildGetGlobal(globalIndex, WASMType::F32);
845 }
846
847 template <class Context>
848 ContextExpression WASMFunctionParser::parseUnaryExpressionF32(Context& context, WASMOpExpressionF32 op)
849 {
850     ContextExpression expression = parseExpressionF32(context);
851     PROPAGATE_ERROR();
852     return context.buildUnaryF32(expression, op);
853 }
854
855 template <class Context>
856 ContextExpression WASMFunctionParser::parseBinaryExpressionF32(Context& context, WASMOpExpressionF32 op)
857 {
858     ContextExpression left = parseExpressionF32(context);
859     PROPAGATE_ERROR();
860     ContextExpression right = parseExpressionF32(context);
861     PROPAGATE_ERROR();
862     return context.buildBinaryF32(left, right, op);
863 }
864
865 template <class Context>
866 ContextExpression WASMFunctionParser::parseExpressionF64(Context& context)
867 {
868     bool hasImmediate;
869     WASMOpExpressionF64 op;
870     WASMOpExpressionF64WithImmediate opWithImmediate;
871     uint8_t immediate;
872     READ_OP_EXPRESSION_F64_OR_FAIL(hasImmediate, op, opWithImmediate, immediate, "Cannot read the float64 expression opcode.");
873     if (!hasImmediate) {
874         switch (op) {
875         case WASMOpExpressionF64::ConstantPoolIndex:
876             return parseConstantPoolIndexExpressionF64(context);
877         case WASMOpExpressionF64::Immediate:
878             return parseImmediateExpressionF64(context);
879         case WASMOpExpressionF64::GetLocal:
880             return parseGetLocalExpressionF64(context);
881         case WASMOpExpressionF64::GetGlobal:
882             return parseGetGlobalExpressionF64(context);
883         case WASMOpExpressionF64::CallInternal:
884             return parseCallInternal(context, WASMExpressionType::F64);
885         case WASMOpExpressionF64::CallImport:
886             return parseCallImport(context, WASMExpressionType::F64);
887         case WASMOpExpressionF64::CallIndirect:
888             return parseCallIndirect(context, WASMExpressionType::F64);
889         case WASMOpExpressionF64::FromS32:
890             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertSigned);
891         case WASMOpExpressionF64::FromU32:
892             return parseConvertType(context, WASMExpressionType::I32, WASMExpressionType::F64, WASMTypeConversion::ConvertUnsigned);
893         case WASMOpExpressionF64::FromF32:
894             return parseConvertType(context, WASMExpressionType::F32, WASMExpressionType::F64, WASMTypeConversion::Promote);
895         case WASMOpExpressionF64::SetLocal:
896         case WASMOpExpressionF64::SetGlobal:
897         case WASMOpExpressionF64::Load:
898         case WASMOpExpressionF64::LoadWithOffset:
899         case WASMOpExpressionF64::Store:
900         case WASMOpExpressionF64::StoreWithOffset:
901         case WASMOpExpressionF64::Conditional:
902         case WASMOpExpressionF64::Comma:
903         case WASMOpExpressionF64::Negate:
904         case WASMOpExpressionF64::Add:
905         case WASMOpExpressionF64::Sub:
906         case WASMOpExpressionF64::Mul:
907         case WASMOpExpressionF64::Div:
908         case WASMOpExpressionF64::Mod:
909         case WASMOpExpressionF64::Min:
910         case WASMOpExpressionF64::Max:
911         case WASMOpExpressionF64::Abs:
912         case WASMOpExpressionF64::Ceil:
913         case WASMOpExpressionF64::Floor:
914         case WASMOpExpressionF64::Sqrt:
915         case WASMOpExpressionF64::Cos:
916         case WASMOpExpressionF64::Sin:
917         case WASMOpExpressionF64::Tan:
918         case WASMOpExpressionF64::ACos:
919         case WASMOpExpressionF64::ASin:
920         case WASMOpExpressionF64::ATan:
921         case WASMOpExpressionF64::ATan2:
922         case WASMOpExpressionF64::Exp:
923         case WASMOpExpressionF64::Ln:
924         case WASMOpExpressionF64::Pow:
925             // FIXME: Implement these instructions.
926             FAIL_WITH_MESSAGE("Unsupported instruction.");
927         default:
928             ASSERT_NOT_REACHED();
929         }
930     } else {
931         switch (opWithImmediate) {
932         case WASMOpExpressionF64WithImmediate::ConstantPoolIndex:
933             return parseConstantPoolIndexExpressionF64(context, immediate);
934         case WASMOpExpressionF64WithImmediate::GetLocal:
935             return parseGetLocalExpressionF64(context, immediate);
936         default:
937             ASSERT_NOT_REACHED();
938         }
939     }
940     return 0;
941 }
942
943 template <class Context>
944 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context, uint32_t constantIndex)
945 {
946     FAIL_IF_FALSE(constantIndex < m_module->f64Constants().size(), "The constant index is incorrect.");
947     return context.buildImmediateF64(m_module->f64Constants()[constantIndex]);
948 }
949
950 template <class Context>
951 ContextExpression WASMFunctionParser::parseConstantPoolIndexExpressionF64(Context& context)
952 {
953     uint32_t constantIndex;
954     READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
955     return parseConstantPoolIndexExpressionF64(context, constantIndex);
956 }
957
958 template <class Context>
959 ContextExpression WASMFunctionParser::parseImmediateExpressionF64(Context& context)
960 {
961     double immediate;
962     READ_DOUBLE_OR_FAIL(immediate, "Cannot read the immediate.");
963     return context.buildImmediateF64(immediate);
964 }
965
966 template <class Context>
967 ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context, uint32_t localIndex)
968 {
969     FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
970     FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F64, "Expected a local variable of type float64.");
971     return context.buildGetLocal(localIndex, WASMType::F64);
972 }
973
974 template <class Context>
975 ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context)
976 {
977     uint32_t localIndex;
978     READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
979     return parseGetLocalExpressionF64(context, localIndex);
980 }
981
982 template <class Context>
983 ContextExpression WASMFunctionParser::parseGetGlobalExpressionF64(Context& context)
984 {
985     uint32_t globalIndex;
986     READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
987     FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
988     FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F64, "Expected a global variable of type float64.");
989     return context.buildGetGlobal(globalIndex, WASMType::F64);
990 }
991
992 template <class Context>
993 ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments)
994 {
995     ContextExpressionList argumentList;
996     for (size_t i = 0; i < arguments.size(); ++i) {
997         ContextExpression expression = parseExpression(context, WASMExpressionType(arguments[i]));
998         PROPAGATE_ERROR();
999         context.appendExpressionList(argumentList, expression);
1000     }
1001     return argumentList;
1002 }
1003
1004 template <class Context>
1005 ContextExpression WASMFunctionParser::parseCallInternal(Context& context, WASMExpressionType returnType)
1006 {
1007     uint32_t functionIndex;
1008     READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
1009     FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
1010     const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[functionIndex].signatureIndex];
1011     FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1012
1013     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1014     PROPAGATE_ERROR();
1015     return context.buildCallInternal(functionIndex, argumentList, signature, returnType);
1016 }
1017
1018 template <class Context>
1019 ContextExpression WASMFunctionParser::parseCallIndirect(Context& context, WASMExpressionType returnType)
1020 {
1021     uint32_t functionPointerTableIndex;
1022     READ_COMPACT_UINT32_OR_FAIL(functionPointerTableIndex, "Cannot read the function pointer table index.");
1023     FAIL_IF_FALSE(functionPointerTableIndex < m_module->functionPointerTables().size(), "The function pointer table index is incorrect.");
1024     const WASMFunctionPointerTable& functionPointerTable = m_module->functionPointerTables()[functionPointerTableIndex];
1025     const WASMSignature& signature = m_module->signatures()[functionPointerTable.signatureIndex];
1026     FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1027
1028     ContextExpression index = parseExpressionI32(context);
1029     PROPAGATE_ERROR();
1030
1031     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1032     PROPAGATE_ERROR();
1033     return context.buildCallIndirect(functionPointerTableIndex, index, argumentList, signature, returnType);
1034 }
1035
1036 template <class Context>
1037 ContextExpression WASMFunctionParser::parseCallImport(Context& context, WASMExpressionType returnType)
1038 {
1039     uint32_t functionImportSignatureIndex;
1040     READ_COMPACT_UINT32_OR_FAIL(functionImportSignatureIndex, "Cannot read the function import signature index.");
1041     FAIL_IF_FALSE(functionImportSignatureIndex < m_module->functionImportSignatures().size(), "The function import signature index is incorrect.");
1042     const WASMFunctionImportSignature& functionImportSignature = m_module->functionImportSignatures()[functionImportSignatureIndex];
1043     const WASMSignature& signature = m_module->signatures()[functionImportSignature.signatureIndex];
1044     FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1045
1046     ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
1047     PROPAGATE_ERROR();
1048     return context.buildCallImport(functionImportSignature.functionImportIndex, argumentList, signature, returnType);
1049 }
1050
1051 template <class Context>
1052 ContextExpression WASMFunctionParser::parseConvertType(Context& context, WASMExpressionType fromType, WASMExpressionType toType, WASMTypeConversion conversion)
1053 {
1054     ContextExpression expression = parseExpression(context, fromType);
1055     PROPAGATE_ERROR();
1056
1057     return context.buildConvertType(expression, fromType, toType, conversion);
1058 }
1059
1060 } // namespace JSC
1061
1062 #endif // ENABLE(WEBASSEMBLY)