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 "JSWASMModule.h"
32#include "WASMCodeGenerator.h"
33#include "WASMConstants.h"
34#include "WASMSyntaxChecker.h"
35
36#define UNUSED 1 // FIXME: Should depend on the context!
37
38#define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
39#define FAIL_WITH_MESSAGE(errorMessage) do { m_errorMessage = errorMessage; return 0; } while (0)
40#define READ_UINT32_OR_FAIL(x, errorMessage) do { if (!m_reader.readUInt32(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
41#define READ_FLOAT_OR_FAIL(x, errorMessage) do { if (!m_reader.readFloat(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
42#define READ_DOUBLE_OR_FAIL(x, errorMessage) do { if (!m_reader.readDouble(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
43#define READ_STRING_OR_FAIL(x, errorMessage) do { if (!m_reader.readString(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
44#define READ_COMPACT_UINT32_OR_FAIL(x, errorMessage) do { if (!m_reader.readCompactUInt32(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
45#define READ_COMPACT_INT32_OR_FAIL(x, errorMessage) do { if (!m_reader.readCompactInt32(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
46#define READ_EXPRESSION_TYPE_OR_FAIL(x, errorMessage) do { if (!m_reader.readExpressionType(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
47#define READ_SWITCH_CASE_OR_FAIL(x, errorMessage) do { if (!m_reader.readSwitchCase(x)) FAIL_WITH_MESSAGE(errorMessage); } while (0)
48#define FAIL_IF_FALSE(condition, errorMessage) do {\
49 if (!(condition))\
50 FAIL_WITH_MESSAGE(errorMessage);\
51} while (0)
52
53namespace JSC {
54
55bool WASMFunctionParser::checkSyntax(const JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned& endOffsetInSource, unsigned& stackHeight, String& errorMessage)
56{
57 WASMFunctionParser parser(module, source);
58 WASMSyntaxChecker syntaxChecker;
59 parser.parseFunction(syntaxChecker, functionIndex, startOffsetInSource);
60 if (!parser.m_errorMessage.isNull()) {
61 errorMessage = parser.m_errorMessage;
62 return false;
63 }
64 endOffsetInSource = parser.m_reader.index();
65 stackHeight = syntaxChecker.maxStackTop();
66 return true;
67}
68
69void WASMFunctionParser::generateCode(VM* vm, CodeBlock* codeBlock, const JSWASMModule* module, const SourceCode& source, size_t functionIndex, unsigned startOffsetInSource, unsigned stackHeight)
70{
71 WASMFunctionParser parser(module, source);
72 WASMCodeGenerator codeGenerator(vm, codeBlock, module, stackHeight);
73 parser.parseFunction(codeGenerator, functionIndex, startOffsetInSource);
74}
75
76template <class Context>
77bool WASMFunctionParser::parseFunction(Context& context, size_t functionIndex, unsigned startOffsetInSource)
78{
79 m_reader.setIndex(startOffsetInSource);
80
81 const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[functionIndex].signatureIndex];
82
83 m_returnType = signature.returnType;
84
85 parseLocalVariables();
86 PROPAGATE_ERROR();
87
88 initializeLocalTypes(signature);
89 context.startFunction(signature, m_numberOfI32Vars, m_numberOfF32Vars, m_numberOfF64Vars);
90
91 parseStatementList(context);
92 PROPAGATE_ERROR();
93
94 context.endFunction();
95
96 return true;
97}
98
99void WASMFunctionParser::initializeLocalTypes(const WASMSignature& signature)
100{
101 const Vector<WASMType>& arguments = signature.arguments;
102 for (size_t argIndex = 0; argIndex < arguments.size(); ++argIndex)
103 m_localTypes.append(arguments[argIndex]);
104
105 for (uint32_t i = 0; i < m_numberOfI32Vars; ++i)
106 m_localTypes.append(WASMType::I32);
107 for (uint32_t i = 0; i < m_numberOfF32Vars; ++i)
108 m_localTypes.append(WASMType::F32);
109 for (uint32_t i = 0; i < m_numberOfF64Vars; ++i)
110 m_localTypes.append(WASMType::F64);
111}
112
113bool WASMFunctionParser::parseLocalVariables()
114{
115 m_numberOfI32Vars = 0;
116 m_numberOfF32Vars = 0;
117 m_numberOfF64Vars = 0;
118
119 WASMVarTypes varTypes;
120 WASMVarTypesWithImmediate varTypesWithImmediate;
121 uint8_t immediate;
122 if (m_reader.readCode(&varTypes, &varTypesWithImmediate, &immediate)) {
123 if (varTypes & WASMVarTypes::I32)
124 READ_COMPACT_UINT32_OR_FAIL(m_numberOfI32Vars, "Cannot read the number of int32 local variables.");
125 if (varTypes & WASMVarTypes::F32)
126 READ_COMPACT_UINT32_OR_FAIL(m_numberOfF32Vars, "Cannot read the number of float32 local variables.");
127 if (varTypes & WASMVarTypes::F64)
128 READ_COMPACT_UINT32_OR_FAIL(m_numberOfF64Vars, "Cannot read the number of float64 local variables.");
129 } else
130 m_numberOfI32Vars = immediate;
131 return true;
132}
133
134template <class Context>
135ContextStatement WASMFunctionParser::parseStatement(Context& context)
136{
137 WASMOpStatement op;
138 WASMOpStatementWithImmediate opWithImmediate;
139 uint8_t immediate;
140 if (m_reader.readCode(&op, &opWithImmediate, &immediate)) {
141 switch (op) {
142 case WASMOpStatement::SetLocal:
143 parseSetLocalStatement(context);
144 break;
145 case WASMOpStatement::SetGlobal:
146 parseSetGlobalStatement(context);
147 break;
148 case WASMOpStatement::I32Store8:
149 case WASMOpStatement::I32StoreOffset8:
150 case WASMOpStatement::I32Store16:
151 case WASMOpStatement::I32StoreOffset16:
152 case WASMOpStatement::I32Store32:
153 case WASMOpStatement::I32StoreOffset32:
154 case WASMOpStatement::F32Store:
155 case WASMOpStatement::F32StoreOffset:
156 case WASMOpStatement::F64Store:
157 case WASMOpStatement::F64StoreOffset:
158 parseStoreStatement(context, op);
159 break;
160 case WASMOpStatement::CallInternal:
161 parseCallInternalStatement(context);
162 break;
163 case WASMOpStatement::CallIndirect:
164 parseCallIndirectStatement(context);
165 break;
166 case WASMOpStatement::CallImport:
167 parseCallImportStatement(context);
168 break;
169 case WASMOpStatement::Return:
170 parseReturnStatement(context);
171 break;
172 case WASMOpStatement::Block:
173 parseBlockStatement(context);
174 break;
175 case WASMOpStatement::IfThen:
176 parseIfStatement(context);
177 break;
178 case WASMOpStatement::IfElse:
179 parseIfElseStatement(context);
180 break;
181 case WASMOpStatement::While:
182 parseWhileStatement(context);
183 break;
184 case WASMOpStatement::Do:
185 parseDoStatement(context);
186 break;
187 case WASMOpStatement::Label:
188 parseLabelStatement(context);
189 break;
190 case WASMOpStatement::Break:
191 parseBreakStatement(context);
192 break;
193 case WASMOpStatement::BreakLabel:
194 parseBreakLabelStatement(context);
195 break;
196 case WASMOpStatement::Continue:
197 parseContinueStatement(context);
198 break;
199 case WASMOpStatement::ContinueLabel:
200 parseContinueLabelStatement(context);
201 break;
202 case WASMOpStatement::Switch:
203 parseSwitchStatement(context);
204 break;
205 default:
206 printf("op = %d\n", (int)op);
207 RELEASE_ASSERT_NOT_REACHED();
208 }
209 } else {
210 switch (opWithImmediate) {
211 case WASMOpStatementWithImmediate::SetLocal:
212 parseSetLocalStatement(context, immediate);
213 break;
214 case WASMOpStatementWithImmediate::SetGlobal:
215 parseSetGlobalStatement(context, immediate);
216 break;
217 default:
218 ASSERT_NOT_REACHED();
219 }
220 }
221 return UNUSED;
222}
223
224template <class Context>
225ContextStatement WASMFunctionParser::parseSetLocalStatement(Context& context, uint32_t localIndex)
226{
227 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
228 WASMType type = m_localTypes[localIndex];
229 ContextExpression expression = parseExpression(context, WASMExpressionType(type));
230 context.setLocal(localIndex, expression, type);
231 return UNUSED;
232}
233
234template <class Context>
235ContextStatement WASMFunctionParser::parseSetLocalStatement(Context& context)
236{
237 uint32_t localIndex;
238 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
239 parseSetLocalStatement(context, localIndex);
240 return UNUSED;
241}
242
243template <class Context>
244ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context, uint32_t globalIndex)
245{
246 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
247 WASMType type = m_module->globalVariableTypes()[globalIndex];
248 ContextExpression expression = parseExpression(context, WASMExpressionType(type));
249 PROPAGATE_ERROR();
250 context.createSetGlobal(globalIndex, expression, type, false);
251 return UNUSED;
252}
253
254template <class Context>
255ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context)
256{
257 uint32_t globalIndex;
258 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
259 parseSetGlobalStatement(context, globalIndex);
260 return UNUSED;
261}
262
263template <class Context>
264ContextStatement WASMFunctionParser::parseStoreStatement(Context& context, WASMOpStatement op)
265{
266 WASMExpressionType expressionType;
267 WASMMemoryType memoryType;
268 bool hasOffset;
269 switch (op) {
270 case WASMOpStatement::I32Store8:
271 expressionType = WASMExpressionType::I32;
272 memoryType = WASMMemoryType::I8;
273 hasOffset = false;
274 break;
275 case WASMOpStatement::I32StoreOffset8:
276 expressionType = WASMExpressionType::I32;
277 memoryType = WASMMemoryType::I8;
278 hasOffset = true;
279 break;
280 case WASMOpStatement::I32Store16:
281 expressionType = WASMExpressionType::I32;
282 memoryType = WASMMemoryType::I16;
283 hasOffset = false;
284 break;
285 case WASMOpStatement::I32StoreOffset16:
286 expressionType = WASMExpressionType::I32;
287 memoryType = WASMMemoryType::I16;
288 hasOffset = true;
289 break;
290 case WASMOpStatement::I32Store32:
291 expressionType = WASMExpressionType::I32;
292 memoryType = WASMMemoryType::I32;
293 hasOffset = false;
294 break;
295 case WASMOpStatement::I32StoreOffset32:
296 expressionType = WASMExpressionType::I32;
297 memoryType = WASMMemoryType::I32;
298 hasOffset = true;
299 break;
300 case WASMOpStatement::F32Store:
301 expressionType = WASMExpressionType::F32;
302 memoryType = WASMMemoryType::F32;
303 hasOffset = false;
304 break;
305 case WASMOpStatement::F32StoreOffset:
306 expressionType = WASMExpressionType::F32;
307 memoryType = WASMMemoryType::F32;
308 hasOffset = true;
309 break;
310 case WASMOpStatement::F64Store:
311 expressionType = WASMExpressionType::F64;
312 memoryType = WASMMemoryType::F64;
313 hasOffset = false;
314 break;
315 case WASMOpStatement::F64StoreOffset:
316 expressionType = WASMExpressionType::F64;
317 memoryType = WASMMemoryType::F64;
318 hasOffset = true;
319 break;
320 default:
321 ASSERT_NOT_REACHED();
322 }
323
324 parseStore(context, hasOffset, expressionType, memoryType, false);
325 return UNUSED;
326}
327
328template <class Context>
329ContextStatement WASMFunctionParser::parseCallInternalStatement(Context& context)
330{
331 parseCallInternal(context, false, WASMExpressionType::Void);
332 return UNUSED;
333}
334
335template <class Context>
336ContextStatement WASMFunctionParser::parseCallIndirectStatement(Context& context)
337{
338 parseCallIndirect(context, false, WASMExpressionType::Void);
339 return UNUSED;
340}
341
342template <class Context>
343ContextStatement WASMFunctionParser::parseCallImportStatement(Context& context)
344{
345 parseCallImport(context, false, WASMExpressionType::Void);
346 return UNUSED;
347}
348
349template <class Context>
350ContextStatement WASMFunctionParser::parseReturnStatement(Context& context)
351{
352 ContextExpression expression;
353 if (m_returnType != WASMExpressionType::Void) {
354 expression = parseExpression(context, m_returnType);
355 PROPAGATE_ERROR();
356 } else
357 expression = 0;
358 context.returnStatement(expression, m_returnType);
359 return UNUSED;
360}
361
362template <class Context>
363ContextStatement WASMFunctionParser::parseStatementList(Context& context)
364{
365 uint32_t numberOfStatements;
366 READ_COMPACT_UINT32_OR_FAIL(numberOfStatements, "Cannot read the number of statements.");
367 for (uint32_t i = 0; i < numberOfStatements; ++i) {
368 parseStatement(context);
369 PROPAGATE_ERROR();
370 }
371 return UNUSED;
372}
373
374template <class Context>
375ContextStatement WASMFunctionParser::parseBlockStatement(Context& context)
376{
377 parseStatementList(context);
378 return UNUSED;
379}
380
381template <class Context>
382ContextStatement WASMFunctionParser::parseIfStatement(Context& context)
383{
384 ContextExpression condition = parseExpressionI32(context);
385 PROPAGATE_ERROR();
386 ContextJump end = context.jitBranchIfZero(condition);
387 parseStatement(context);
388 PROPAGATE_ERROR();
389 context.jitLinkJump(end);
390 return UNUSED;
391}
392
393template <class Context>
394ContextStatement WASMFunctionParser::parseIfElseStatement(Context& context)
395{
396 ContextExpression condition = parseExpressionI32(context);
397 PROPAGATE_ERROR();
398 ContextJump elseJump = context.jitBranchIfZero(condition);
399 parseStatement(context);
400 PROPAGATE_ERROR();
401 ContextJump end = context.jitJump();
402 context.jitLinkJump(elseJump);
403 parseStatement(context);
404 PROPAGATE_ERROR();
405 context.jitLinkJump(end);
406 return UNUSED;
407}
408
409template <class Context>
410ContextStatement WASMFunctionParser::parseWhileStatement(Context& context)
411{
412 context.startLoop();
413 context.linkContinue();
414
415 ContextLabel start = context.jitLabel();
416 ContextExpression condition = parseExpressionI32(context);
417 PROPAGATE_ERROR();
418 ContextJump jumpToEnd = context.jitBranchIfZero(condition);
419
420 m_breakScopeDepth++;
421 m_continueScopeDepth++;
422 parseStatement(context);
423 PROPAGATE_ERROR();
424 m_continueScopeDepth--;
425 m_breakScopeDepth--;
426
427 context.jitJump(start);
428 context.jitLinkJump(jumpToEnd);
429
430 context.linkBreak();
431 context.endLoop();
432 return UNUSED;
433}
434
435template <class Context>
436ContextStatement WASMFunctionParser::parseDoStatement(Context& context)
437{
438 context.startLoop();
439
440 ContextLabel start = context.jitLabel();
441
442 m_breakScopeDepth++;
443 m_continueScopeDepth++;
444 parseStatement(context);
445 PROPAGATE_ERROR();
446 m_continueScopeDepth--;
447 m_breakScopeDepth--;
448
449 context.linkContinue();
450
451 ContextExpression condition = parseExpressionI32(context);
452 PROPAGATE_ERROR();
453 ContextJump jumpToStart = context.jitBranchIfNonZero(condition);
454 context.jitLinkJumpToLabel(jumpToStart, start);
455
456 context.linkBreak();
457 context.endLoop();
458 return UNUSED;
459}
460
461template <class Context>
462ContextStatement WASMFunctionParser::parseLabelStatement(Context& context)
463{
464 context.startLabel();
465 m_labelDepth++;
466 parseStatement(context);
467 m_labelDepth--;
468 context.endLabel();
469 return UNUSED;
470}
471
472template <class Context>
473ContextStatement WASMFunctionParser::parseBreakStatement(Context& context)
474{
475 FAIL_IF_FALSE(m_breakScopeDepth, "'break' is only valid inside a switch or loop statement.");
476 context.breakStatement();
477 return UNUSED;
478}
479
480template <class Context>
481ContextStatement WASMFunctionParser::parseBreakLabelStatement(Context& context)
482{
483 uint32_t labelIndex;
484 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
485 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
486 context.breakLabelStatement(labelIndex);
487 return UNUSED;
488}
489
490template <class Context>
491ContextStatement WASMFunctionParser::parseContinueStatement(Context& context)
492{
493 FAIL_IF_FALSE(m_continueScopeDepth, "'continue' is only valid inside a loop statement.");
494 context.continueStatement();
495 return UNUSED;
496}
497
498template <class Context>
499ContextStatement WASMFunctionParser::parseContinueLabelStatement(Context& context)
500{
501 uint32_t labelIndex;
502 READ_COMPACT_UINT32_OR_FAIL(labelIndex, "Cannot read the label index.");
503 FAIL_IF_FALSE(labelIndex < m_labelDepth, "The label index is incorrect.");
504 context.continueLabelStatement(labelIndex);
505 return UNUSED;
506}
507
508template <class Context>
509ContextStatement WASMFunctionParser::parseSwitchStatement(Context& context)
510{
511 context.startSwitch();
512
513 uint32_t numberOfCases;
514 READ_COMPACT_UINT32_OR_FAIL(numberOfCases, "Cannot read the number of cases.");
515 ContextExpression test = parseExpressionI32(context);
516 PROPAGATE_ERROR();
517
518 ContextJump table = context.jitJump();
519
520 Vector<int32_t> cases;
521 bool hasDefault = false;
522 Vector<ContextLabel> labels; // TODO: use ContextLabelList
523 cases.reserveInitialCapacity(numberOfCases);
524 labels.reserveInitialCapacity(numberOfCases);
525
526 m_breakScopeDepth++;
527 for (uint32_t i = 0; i < numberOfCases; ++i) {
528 WASMSwitchCase switchCase;
529 READ_SWITCH_CASE_OR_FAIL(switchCase, "Cannot read the switch case.");
530 switch (switchCase) {
531 case WASMSwitchCase::Case0:
532 case WASMSwitchCase::Case1:
533 case WASMSwitchCase::CaseN: {
534 uint32_t value;
535 READ_COMPACT_INT32_OR_FAIL(value, "Cannot read the value of the switch case.");
536 cases.append(value);
537 labels.append(context.jitLabel());
538 if (switchCase == WASMSwitchCase::Case1) {
539 parseStatement(context);
540 PROPAGATE_ERROR();
541 } else if (switchCase == WASMSwitchCase::CaseN) {
542 parseStatementList(context);
543 PROPAGATE_ERROR();
544 }
545 break;
546 }
547 case WASMSwitchCase::Default0:
548 case WASMSwitchCase::Default1:
549 case WASMSwitchCase::DefaultN: {
550 FAIL_IF_FALSE(i == numberOfCases - 1, "The default case must be the last case.");
551 labels.append(context.jitLabel());
552 hasDefault = true;
553 if (switchCase == WASMSwitchCase::Default1) {
554 parseStatement(context);
555 PROPAGATE_ERROR();
556 } else if (switchCase == WASMSwitchCase::DefaultN) {
557 parseStatementList(context);
558 PROPAGATE_ERROR();
559 }
560 break;
561 }
562 default:
563 ASSERT_NOT_REACHED();
564 }
565 }
566 m_breakScopeDepth--;
567
568 ContextJump end = context.jitJump();
569 context.jitLinkJump(table);
570
571 context.generateSwitchTable(test, cases, hasDefault, labels);
572
573 context.jitLinkJump(end);
574
575 context.linkBreak();
576 context.endSwitch();
577 return UNUSED;
578}
579
580template <class Context>
581ContextExpression WASMFunctionParser::parseExpression(Context& context, WASMExpressionType expressionType)
582{
583 switch (expressionType) {
584 case WASMExpressionType::I32:
585 return parseExpressionI32(context);
586 case WASMExpressionType::F32:
587 return parseExpressionF32(context);
588 case WASMExpressionType::F64:
589 return parseExpressionF64(context);
590 case WASMExpressionType::Void:
591 return parseExpressionVoid(context);
592 default:
593 ASSERT_NOT_REACHED();
594 }
595}
596
597template <class Context>
598ContextExpression WASMFunctionParser::parseExpressionI32(Context& context)
599{
600 WASMOpExpressionI32 op;
601 WASMOpExpressionI32WithImmediate opWithImmediate;
602 uint8_t immediate;
603
604 if (m_reader.readCode(&op, &opWithImmediate, &immediate)) {
605 switch (op) {
606 case WASMOpExpressionI32::LitPool:
607 return parseLiteralPoolExpressionI32(context);
608 case WASMOpExpressionI32::LitImm:
609 return parseLiteralImmediateExpressionI32(context);
610 case WASMOpExpressionI32::GetLocal:
611 return parseGetLocalExpressionI32(context);
612 case WASMOpExpressionI32::GetGlobal:
613 return parseGetGlobalExpressionI32(context);
614 case WASMOpExpressionI32::SetLocal:
615 return parseSetLocalExpressionI32(context);
616 case WASMOpExpressionI32::SetGlobal:
617 return parseSetGlobalExpressionI32(context);
618 case WASMOpExpressionI32::SLoad8:
619 case WASMOpExpressionI32::SLoadOffset8:
620 case WASMOpExpressionI32::ULoad8:
621 case WASMOpExpressionI32::ULoadOffset8:
622 case WASMOpExpressionI32::SLoad16:
623 case WASMOpExpressionI32::SLoadOffset16:
624 case WASMOpExpressionI32::ULoad16:
625 case WASMOpExpressionI32::ULoadOffset16:
626 case WASMOpExpressionI32::Load32:
627 case WASMOpExpressionI32::LoadOffset32:
628 return parseLoadExpressionI32(context, op);
629 case WASMOpExpressionI32::Store8:
630 case WASMOpExpressionI32::StoreOffset8:
631 case WASMOpExpressionI32::Store16:
632 case WASMOpExpressionI32::StoreOffset16:
633 case WASMOpExpressionI32::Store32:
634 case WASMOpExpressionI32::StoreOffset32:
635 return parseStoreExpressionI32(context, op);
636 case WASMOpExpressionI32::CallInternal:
637 return parseCallInternalExpressionI32(context);
638 case WASMOpExpressionI32::CallIndirect:
639 return parseCallIndirectExpressionI32(context);
640 case WASMOpExpressionI32::CallImport:
641 return parseCallImportExpressionI32(context);
642 case WASMOpExpressionI32::Conditional:
643 return parseConditionalExpressionI32(context);
644 case WASMOpExpressionI32::Comma:
645 return parseCommaExpressionI32(context);
646 case WASMOpExpressionI32::FromF64:
647 return parseFromF64ExpressionI32(context);
648 case WASMOpExpressionI32::Neg:
649 case WASMOpExpressionI32::BitNot:
650 case WASMOpExpressionI32::Clz:
651 case WASMOpExpressionI32::LogicNot:
652 case WASMOpExpressionI32::Abs:
653 return parseUnaryExpressionI32(context, op);
654 case WASMOpExpressionI32::Add:
655 case WASMOpExpressionI32::Sub:
656 case WASMOpExpressionI32::Mul:
657 case WASMOpExpressionI32::SDiv:
658 case WASMOpExpressionI32::UDiv:
659 case WASMOpExpressionI32::SMod:
660 case WASMOpExpressionI32::UMod:
661 case WASMOpExpressionI32::BitOr:
662 case WASMOpExpressionI32::BitAnd:
663 case WASMOpExpressionI32::BitXor:
664 case WASMOpExpressionI32::LeftShift:
665 case WASMOpExpressionI32::ArithmeticRightShift:
666 case WASMOpExpressionI32::LogicalRightShift:
667 return parseBinaryExpressionI32(context, op);
668 case WASMOpExpressionI32::EqualI32:
669 case WASMOpExpressionI32::NotEqualI32:
670 case WASMOpExpressionI32::SLessThanI32:
671 case WASMOpExpressionI32::ULessThanI32:
672 case WASMOpExpressionI32::SLessThanOrEqualI32:
673 case WASMOpExpressionI32::ULessThanOrEqualI32:
674 case WASMOpExpressionI32::SGreaterThanI32:
675 case WASMOpExpressionI32::UGreaterThanI32:
676 case WASMOpExpressionI32::SGreaterThanOrEqualI32:
677 case WASMOpExpressionI32::UGreaterThanOrEqualI32:
678 return parseRelationalI32ExpressionI32(context, op);
679 case WASMOpExpressionI32::EqualF64:
680 case WASMOpExpressionI32::NotEqualF64:
681 case WASMOpExpressionI32::LessThanF64:
682 case WASMOpExpressionI32::LessThanOrEqualF64:
683 case WASMOpExpressionI32::GreaterThanF64:
684 case WASMOpExpressionI32::GreaterThanOrEqualF64:
685 return parseRelationalF64ExpressionI32(context, op);
686 case WASMOpExpressionI32::SMin:
687 case WASMOpExpressionI32::UMin:
688 case WASMOpExpressionI32::SMax:
689 case WASMOpExpressionI32::UMax:
690 // return parseMinOrMaxExpressionI32(context, op);
691 default:
692 FAIL_WITH_MESSAGE("Unsupported instruction.");
693 }
694 } else {
695 switch (opWithImmediate) {
696 case WASMOpExpressionI32WithImmediate::LitPool:
697 return parseLiteralPoolExpressionI32(context, immediate);
698 case WASMOpExpressionI32WithImmediate::LitImm:
699 return parseLiteralImmediateExpressionI32(context, immediate);
700 case WASMOpExpressionI32WithImmediate::GetLocal:
701 return parseGetLocalExpressionI32(context, immediate);
702 default:
703 FAIL_WITH_MESSAGE("Unsupported instruction.");
704 }
705 }
706}
707
708template <class Context>
709ContextExpression WASMFunctionParser::parseLiteralPoolExpressionI32(Context& context, uint32_t constantIndex)
710{
711 FAIL_IF_FALSE(constantIndex < m_module->i32Constants().size(), "The constant index is incorrect.");
712 return context.createLiteralPoolExpressionI32(constantIndex);
713}
714
715template <class Context>
716ContextExpression WASMFunctionParser::parseLiteralPoolExpressionI32(Context& context)
717{
718 uint32_t constantIndex;
719 READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
720 return parseLiteralPoolExpressionI32(context, constantIndex);
721}
722
723template <class Context>
724ContextExpression WASMFunctionParser::parseLiteralImmediateExpressionI32(Context& context, uint32_t immediate)
725{
726 return context.createLiteralImmediateExpressionI32(immediate);
727}
728
729template <class Context>
730ContextExpression WASMFunctionParser::parseLiteralImmediateExpressionI32(Context& context)
731{
732 uint32_t immediate;
733 READ_COMPACT_UINT32_OR_FAIL(immediate, "Cannot read the immediate.");
734 return context.createLiteralImmediateExpressionI32(immediate);
735}
736
737template <class Context>
738ContextExpression WASMFunctionParser::parseGetLocalExpressionI32(Context& context, uint32_t localIndex)
739{
740 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
741 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::I32, "Expected a local variable of type int32.");
742 return context.createGetLocalExpressionI32(localIndex);
743}
744
745template <class Context>
746ContextExpression WASMFunctionParser::parseGetLocalExpressionI32(Context& context)
747{
748 uint32_t localIndex;
749 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
750 return parseGetLocalExpressionI32(context, localIndex);
751}
752
753template <class Context>
754ContextExpression WASMFunctionParser::parseGetGlobalExpressionI32(Context& context)
755{
756 uint32_t globalIndex;
757 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
758 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
759 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::I32, "Expected a global variable of type int32.");
760 return context.createGetGlobalExpressionI32(globalIndex);
761}
762
763template <class Context>
764ContextExpression WASMFunctionParser::parseSetLocalExpressionI32(Context& context)
765{
766 uint32_t localIndex;
767 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
768 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
769 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::I32, "Expected a local variable of type int32.");
770 ContextExpression expression = parseExpressionI32(context);
771 PROPAGATE_ERROR();
772 return context.createSetLocalExpressionI32(localIndex, expression);
773}
774
775template <class Context>
776ContextExpression WASMFunctionParser::parseSetGlobalExpressionI32(Context& context)
777{
778 uint32_t globalIndex;
779 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
780 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
781 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::I32, "Expected a global variable of type int32.");
782 ContextExpression expression = parseExpressionI32(context);
783 PROPAGATE_ERROR();
784 return context.createSetGlobal(globalIndex, expression, WASMType::I32, true);
785}
786
787template <class Context>
788ContextExpression WASMFunctionParser::parseLoadExpressionI32(Context& context, WASMOpExpressionI32 op)
789{
790 WASMMemoryType memoryType;
791 bool hasOffset;
792 bool signExtended = false;
793 switch (op) {
794 case WASMOpExpressionI32::SLoad8:
795 memoryType = WASMMemoryType::I8;
796 hasOffset = false;
797 signExtended = true;
798 break;
799 case WASMOpExpressionI32::SLoadOffset8:
800 memoryType = WASMMemoryType::I8;
801 hasOffset = true;
802 signExtended = true;
803 break;
804 case WASMOpExpressionI32::ULoad8:
805 memoryType = WASMMemoryType::I8;
806 hasOffset = false;
807 signExtended = false;
808 break;
809 case WASMOpExpressionI32::ULoadOffset8:
810 memoryType = WASMMemoryType::I8;
811 hasOffset = true;
812 signExtended = false;
813 break;
814 case WASMOpExpressionI32::SLoad16:
815 memoryType = WASMMemoryType::I16;
816 hasOffset = false;
817 signExtended = true;
818 break;
819 case WASMOpExpressionI32::SLoadOffset16:
820 memoryType = WASMMemoryType::I16;
821 hasOffset = true;
822 signExtended = true;
823 break;
824 case WASMOpExpressionI32::ULoad16:
825 memoryType = WASMMemoryType::I16;
826 hasOffset = false;
827 signExtended = false;
828 break;
829 case WASMOpExpressionI32::ULoadOffset16:
830 memoryType = WASMMemoryType::I16;
831 hasOffset = true;
832 signExtended = false;
833 break;
834 case WASMOpExpressionI32::Load32:
835 memoryType = WASMMemoryType::I32;
836 hasOffset = false;
837 break;
838 case WASMOpExpressionI32::LoadOffset32:
839 memoryType = WASMMemoryType::I32;
840 hasOffset = true;
841 break;
842 default:
843 ASSERT_NOT_REACHED();
844 }
845 return parseLoad(context, hasOffset, WASMExpressionType::I32, memoryType, signExtended);
846}
847
848template <class Context>
849ContextExpression WASMFunctionParser::parseStoreExpressionI32(Context& context, WASMOpExpressionI32 op)
850{
851 WASMMemoryType memoryType;
852 bool hasOffset;
853 switch (op) {
854 case WASMOpExpressionI32::Store8:
855 memoryType = WASMMemoryType::I8;
856 hasOffset = false;
857 break;
858 case WASMOpExpressionI32::StoreOffset8:
859 memoryType = WASMMemoryType::I8;
860 hasOffset = true;
861 break;
862 case WASMOpExpressionI32::Store16:
863 memoryType = WASMMemoryType::I16;
864 hasOffset = false;
865 break;
866 case WASMOpExpressionI32::StoreOffset16:
867 memoryType = WASMMemoryType::I16;
868 hasOffset = true;
869 break;
870 case WASMOpExpressionI32::Store32:
871 memoryType = WASMMemoryType::I32;
872 hasOffset = false;
873 break;
874 case WASMOpExpressionI32::StoreOffset32:
875 memoryType = WASMMemoryType::I32;
876 hasOffset = true;
877 break;
878 default:
879 ASSERT_NOT_REACHED();
880 }
881 return parseStore(context, hasOffset, WASMExpressionType::I32, memoryType, true);
882}
883
884template <class Context>
885ContextExpression WASMFunctionParser::parseCallInternalExpressionI32(Context& context)
886{
887 return parseCallInternal(context, true, WASMExpressionType::I32);
888}
889
890template <class Context>
891ContextExpression WASMFunctionParser::parseCallIndirectExpressionI32(Context& context)
892{
893 return parseCallIndirect(context, true, WASMExpressionType::I32);
894}
895
896template <class Context>
897ContextExpression WASMFunctionParser::parseCallImportExpressionI32(Context& context)
898{
899 return parseCallImport(context, true, WASMExpressionType::I32);
900}
901
902template <class Context>
903ContextExpression WASMFunctionParser::parseConditionalExpressionI32(Context& context)
904{
905 ContextExpression expression = parseExpressionI32(context);
906 PROPAGATE_ERROR();
907 ContextJump els = context.jitBranchIfZero(expression);
908 parseExpressionI32(context);
909 PROPAGATE_ERROR();
910 ContextJump end = context.jitJump();
911 context.jitLinkJump(els);
912 context.pop();
913 parseExpressionI32(context);
914 PROPAGATE_ERROR();
915 context.jitLinkJump(end);
916 return UNUSED;
917}
918
919template <class Context>
920ContextExpression WASMFunctionParser::parseCommaExpressionI32(Context& context)
921{
922
923 WASMExpressionType expressionType;
924 READ_EXPRESSION_TYPE_OR_FAIL(expressionType, "Cannot read the expression type.");
925 parseExpression(context, expressionType);
926 PROPAGATE_ERROR();
927 if (expressionType != WASMExpressionType::Void)
928 context.pop();
929 parseExpressionI32(context);
930 return UNUSED;
931}
932
933template <class Context>
934ContextExpression WASMFunctionParser::parseFromF64ExpressionI32(Context& context)
935{
936 ContextExpression expression = parseExpressionF64(context);
937 PROPAGATE_ERROR();
938 return context.createFromF64ExpressionI32(expression);
939}
940
941template <class Context>
942ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op)
943{
944 ContextExpression expression = parseExpressionI32(context);
945 PROPAGATE_ERROR();
946 return context.createUnaryExpressionI32(expression, op);
947}
948
949template <class Context>
950ContextExpression WASMFunctionParser::parseBinaryExpressionI32(Context& context, WASMOpExpressionI32 op)
951{
952 ContextExpression expression1 = parseExpressionI32(context);
953 PROPAGATE_ERROR();
954 ContextExpression expression2 = parseExpressionI32(context);
955 PROPAGATE_ERROR();
956 return context.createBinaryExpressionI32(expression1, expression2, op);
957}
958
959template <class Context>
960ContextExpression WASMFunctionParser::parseRelationalI32ExpressionI32(Context& context, WASMOpExpressionI32 op)
961{
962 ContextExpression expression1 = parseExpressionI32(context);
963 PROPAGATE_ERROR();
964 ContextExpression expression2 = parseExpressionI32(context);
965 PROPAGATE_ERROR();
966 return context.createRelationalI32ExpressionI32(expression1, expression2, op);
967}
968
969template <class Context>
970ContextExpression WASMFunctionParser::parseRelationalF64ExpressionI32(Context& context, WASMOpExpressionI32 op)
971{
972 ContextExpression expression1 = parseExpressionF64(context);
973 PROPAGATE_ERROR();
974 ContextExpression expression2 = parseExpressionF64(context);
975 PROPAGATE_ERROR();
976 return context.createRelationalF64ExpressionI32(expression1, expression2, op);
977}
978
979// template <class Context>
980// ContextExpression WASMFunctionParser::parseMinOrMaxExpressionI32(Context& context, WASMOpExpressionI32 op)
981// {
982// uint32_t numberOfArguments;
983// READ_COMPACT_UINT32_OR_FAIL(numberOfArguments, "Cannot read the number of arguments to min/max.");
984// FAIL_IF_FALSE(numberOfArguments > 0, "The number of arguments must be greater than 0.");
985// for (uint32_t i = 0; i < numberOfArguments; ++i) {
986// }
987// ContextExpression expression = parseExpressionI32(context);
988// PROPAGATE_ERROR();
989// }
990
991template <class Context>
992ContextExpression WASMFunctionParser::parseExpressionF32(Context& context)
993{
994 WASMOpExpressionF32 op;
995 WASMOpExpressionF32WithImmediate opWithImmediate;
996 uint8_t immediate;
997
998 if (m_reader.readCode(&op, &opWithImmediate, &immediate)) {
999 switch (op) {
1000 case WASMOpExpressionF32::LitPool:
1001 return parseLiteralPoolExpressionF32(context);
1002 case WASMOpExpressionF32::LitImm:
1003 return parseLiteralImmediateExpressionF32(context);
1004 case WASMOpExpressionF32::GetLocal:
1005 return parseGetLocalExpressionF32(context);
1006 case WASMOpExpressionF32::GetGlobal:
1007 return parseGetGlobalExpressionF32(context);
1008 case WASMOpExpressionF32::SetLocal:
1009 return parseSetLocalExpressionF32(context);
1010 case WASMOpExpressionF32::SetGlobal:
1011 return parseSetGlobalExpressionF32(context);
1012 case WASMOpExpressionF32::Load:
1013 case WASMOpExpressionF32::LoadOffset:
1014 case WASMOpExpressionF32::Store:
1015 case WASMOpExpressionF32::StoreOffset:
1016 case WASMOpExpressionF32::CallInternal:
1017 case WASMOpExpressionF32::CallIndirect:
1018 case WASMOpExpressionF32::Conditional:
1019 case WASMOpExpressionF32::Comma:
1020 case WASMOpExpressionF32::FromS32:
1021 case WASMOpExpressionF32::FromU32:
1022 printf("op2 = %d\n", (int)op);
1023 RELEASE_ASSERT_NOT_REACHED();
1024 case WASMOpExpressionF32::FromF64:
1025 return parseFromF64ExpressionF32(context);
1026 case WASMOpExpressionF32::Neg:
1027 case WASMOpExpressionF32::Add:
1028 case WASMOpExpressionF32::Sub:
1029 case WASMOpExpressionF32::Mul:
1030 case WASMOpExpressionF32::Div:
1031 case WASMOpExpressionF32::Abs:
1032 case WASMOpExpressionF32::Ceil:
1033 case WASMOpExpressionF32::Floor:
1034 case WASMOpExpressionF32::Sqrt:
1035 default:
1036 printf("op3 = %d\n", (int)op);
1037 RELEASE_ASSERT_NOT_REACHED();
1038 }
1039 } else {
1040 switch (opWithImmediate) {
1041 case WASMOpExpressionF32WithImmediate::LitPool:
1042 return parseLiteralPoolExpressionF32(context, immediate);
1043 case WASMOpExpressionF32WithImmediate::GetLocal:
1044 return parseGetLocalExpressionF32(context, immediate);
1045 default:
1046 ASSERT_NOT_REACHED();
1047 }
1048 }
1049}
1050
1051template <class Context>
1052ContextExpression WASMFunctionParser::parseLiteralPoolExpressionF32(Context& context, uint32_t constantIndex)
1053{
1054 FAIL_IF_FALSE(constantIndex < m_module->f32Constants().size(), "The constant index is incorrect.");
1055 return context.createLiteralPoolExpressionF32(constantIndex);
1056}
1057
1058template <class Context>
1059ContextExpression WASMFunctionParser::parseLiteralPoolExpressionF32(Context& context)
1060{
1061 uint32_t constantIndex;
1062 READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
1063 return parseLiteralPoolExpressionF32(context, constantIndex);
1064}
1065
1066template <class Context>
1067ContextExpression WASMFunctionParser::parseLiteralImmediateExpressionF32(Context& context)
1068{
1069 float immediate;
1070 READ_FLOAT_OR_FAIL(immediate, "Cannot read the immediate.");
1071 return context.createLiteralImmediateExpressionF32(immediate);
1072}
1073
1074template <class Context>
1075ContextExpression WASMFunctionParser::parseGetLocalExpressionF32(Context& context, uint32_t localIndex)
1076{
1077 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
1078 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F32, "Expected a local variable of type float64.");
1079 return context.createGetLocalExpressionF32(localIndex);
1080}
1081
1082template <class Context>
1083ContextExpression WASMFunctionParser::parseGetLocalExpressionF32(Context& context)
1084{
1085 uint32_t localIndex;
1086 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1087 return parseGetLocalExpressionF32(context, localIndex);
1088}
1089
1090template <class Context>
1091ContextExpression WASMFunctionParser::parseGetGlobalExpressionF32(Context& context)
1092{
1093 uint32_t globalIndex;
1094 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1095 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1096 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F32, "Expected a global variable of type float32.");
1097 return context.createGetGlobalExpressionF32(globalIndex);
1098}
1099
1100template <class Context>
1101ContextExpression WASMFunctionParser::parseSetLocalExpressionF32(Context& context)
1102{
1103 uint32_t localIndex;
1104 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1105 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
1106 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F32, "Expected a local variable of type float32.");
1107 ContextExpression expression = parseExpressionF32(context);
1108 PROPAGATE_ERROR();
1109 return context.createSetLocalExpressionF32(localIndex, expression);
1110}
1111
1112template <class Context>
1113ContextExpression WASMFunctionParser::parseSetGlobalExpressionF32(Context& context)
1114{
1115 uint32_t globalIndex;
1116 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1117 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1118 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F32, "Expected a global variable of type float32.");
1119 ContextExpression expression = parseExpressionF32(context);
1120 PROPAGATE_ERROR();
1121 return context.createSetGlobal(globalIndex, expression, WASMType::F32, true);
1122}
1123
1124template <class Context>
1125ContextExpression WASMFunctionParser::parseLoadExpressionF32(Context& context)
1126{
1127 return parseLoad(context, false, WASMExpressionType::F32, WASMMemoryType::F32, false);
1128}
1129
1130template <class Context>
1131ContextExpression WASMFunctionParser::parseLoadWithOffsetExpressionF32(Context& context)
1132{
1133 return parseLoad(context, true, WASMExpressionType::F32, WASMMemoryType::F32, false);
1134}
1135
1136template <class Context>
1137ContextExpression WASMFunctionParser::parseStoreExpressionF32(Context& context)
1138{
1139 return parseStore(context, false, WASMExpressionType::F32, WASMMemoryType::F32, true);
1140}
1141
1142template <class Context>
1143ContextExpression WASMFunctionParser::parseStoreWithOffsetExpressionF32(Context& context)
1144{
1145 return parseStore(context, true, WASMExpressionType::F32, WASMMemoryType::F32, true);
1146}
1147
1148template <class Context>
1149ContextExpression WASMFunctionParser::parseFromF64ExpressionF32(Context& context)
1150{
1151 ContextExpression expression = parseExpressionF64(context);
1152 PROPAGATE_ERROR();
1153 return context.createFromF64ExpressionF32(expression);
1154}
1155
1156template <class Context>
1157ContextExpression WASMFunctionParser::parseExpressionF64(Context& context)
1158{
1159 WASMOpExpressionF64 op;
1160 WASMOpExpressionF64WithImmediate opWithImmediate;
1161 uint8_t immediate;
1162
1163 if (m_reader.readCode(&op, &opWithImmediate, &immediate)) {
1164 switch (op) {
1165 case WASMOpExpressionF64::LitPool:
1166 return parseLiteralPoolExpressionF64(context);
1167 case WASMOpExpressionF64::LitImm:
1168 return parseLiteralImmediateExpressionF64(context);
1169 case WASMOpExpressionF64::GetLocal:
1170 return parseGetLocalExpressionF64(context);
1171 case WASMOpExpressionF64::GetGlobal:
1172 return parseGetGlobalExpressionF64(context);
1173 case WASMOpExpressionF64::SetLocal:
1174 return parseSetLocalExpressionF64(context);
1175 case WASMOpExpressionF64::SetGlobal:
1176 return parseSetGlobalExpressionF64(context);
1177 case WASMOpExpressionF64::Load:
1178 return parseLoadExpressionF64(context);
1179 case WASMOpExpressionF64::LoadOffset:
1180 return parseLoadWithOffsetExpressionF64(context);
1181 case WASMOpExpressionF64::Store:
1182 return parseStoreExpressionF64(context);
1183 case WASMOpExpressionF64::StoreOffset:
1184 return parseStoreWithOffsetExpressionF64(context);
1185 case WASMOpExpressionF64::CallInternal:
1186 return parseCallInternalExpressionF64(context);
1187 case WASMOpExpressionF64::CallIndirect:
1188 return parseCallIndirectExpressionF64(context);
1189 case WASMOpExpressionF64::CallImport:
1190 return parseCallImportExpressionF64(context);
1191 case WASMOpExpressionF64::Conditional:
1192 return parseConditionalExpressionF64(context);
1193 case WASMOpExpressionF64::Comma:
1194 return parseCommaExpressionF64(context);
1195 case WASMOpExpressionF64::FromS32:
1196 return parseFromS32ExpressionF64(context);
1197 case WASMOpExpressionF64::FromU32:
1198 return parseFromU32ExpressionF64(context);
1199 case WASMOpExpressionF64::Neg:
1200 case WASMOpExpressionF64::Abs:
1201 case WASMOpExpressionF64::Ceil:
1202 case WASMOpExpressionF64::Floor:
1203 case WASMOpExpressionF64::Sqrt:
1204 case WASMOpExpressionF64::Cos:
1205 case WASMOpExpressionF64::Sin:
1206 case WASMOpExpressionF64::Tan:
1207 case WASMOpExpressionF64::ACos:
1208 case WASMOpExpressionF64::ASin:
1209 case WASMOpExpressionF64::ATan:
1210 case WASMOpExpressionF64::Exp:
1211 case WASMOpExpressionF64::Ln:
1212 return parseUnaryExpressionF64(context, op);
1213 case WASMOpExpressionF64::Add:
1214 case WASMOpExpressionF64::Sub:
1215 case WASMOpExpressionF64::Mul:
1216 case WASMOpExpressionF64::Div:
1217 case WASMOpExpressionF64::ATan2:
1218 case WASMOpExpressionF64::Pow:
1219 return parseBinaryExpressionF64(context, op);
1220 default:
1221 FAIL_WITH_MESSAGE("Unsupported instruction.");
1222 }
1223 } else {
1224 switch (opWithImmediate) {
1225 case WASMOpExpressionF64WithImmediate::LitPool:
1226 return parseLiteralPoolExpressionF64(context, immediate);
1227 case WASMOpExpressionF64WithImmediate::GetLocal:
1228 return parseGetLocalExpressionF64(context, immediate);
1229 default:
1230 FAIL_WITH_MESSAGE("Unsupported instruction.");
1231 }
1232 }
1233}
1234
1235template <class Context>
1236ContextExpression WASMFunctionParser::parseLiteralPoolExpressionF64(Context& context, uint32_t constantIndex)
1237{
1238 FAIL_IF_FALSE(constantIndex < m_module->f64Constants().size(), "The constant index is incorrect.");
1239 return context.createLiteralPoolExpressionF64(constantIndex);
1240}
1241
1242template <class Context>
1243ContextExpression WASMFunctionParser::parseLiteralPoolExpressionF64(Context& context)
1244{
1245 uint32_t constantIndex;
1246 READ_COMPACT_UINT32_OR_FAIL(constantIndex, "Cannot read the constant index.");
1247 return parseLiteralPoolExpressionF64(context, constantIndex);
1248}
1249
1250template <class Context>
1251ContextExpression WASMFunctionParser::parseLiteralImmediateExpressionF64(Context& context)
1252{
1253 double immediate;
1254 READ_DOUBLE_OR_FAIL(immediate, "Cannot read the immediate.");
1255 return context.createLiteralImmediateExpressionF64(immediate);
1256}
1257
1258template <class Context>
1259ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context, uint32_t localIndex)
1260{
1261 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
1262 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F64, "Expected a local variable of type float64.");
1263 return context.createGetLocalExpressionF64(localIndex);
1264}
1265
1266template <class Context>
1267ContextExpression WASMFunctionParser::parseGetLocalExpressionF64(Context& context)
1268{
1269 uint32_t localIndex;
1270 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1271 return parseGetLocalExpressionF64(context, localIndex);
1272}
1273
1274template <class Context>
1275ContextExpression WASMFunctionParser::parseGetGlobalExpressionF64(Context& context)
1276{
1277 uint32_t globalIndex;
1278 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1279 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1280 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F64, "Expected a global variable of type float64.");
1281 return context.createGetGlobalExpressionF64(globalIndex);
1282}
1283
1284template <class Context>
1285ContextExpression WASMFunctionParser::parseSetLocalExpressionF64(Context& context)
1286{
1287 uint32_t localIndex;
1288 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
1289 FAIL_IF_FALSE(localIndex < m_localTypes.size(), "The local variable index is incorrect.");
1290 FAIL_IF_FALSE(m_localTypes[localIndex] == WASMType::F64, "Expected a local variable of type float64.");
1291 ContextExpression expression = parseExpressionF64(context);
1292 PROPAGATE_ERROR();
1293 return context.createSetLocalExpressionF64(localIndex, expression);
1294}
1295
1296template <class Context>
1297ContextExpression WASMFunctionParser::parseSetGlobalExpressionF64(Context& context)
1298{
1299 uint32_t globalIndex;
1300 READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
1301 FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
1302 FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F64, "Expected a global variable of type float64.");
1303 ContextExpression expression = parseExpressionF64(context);
1304 PROPAGATE_ERROR();
1305 return context.createSetGlobal(globalIndex, expression, WASMType::F64, true);
1306}
1307
1308template <class Context>
1309ContextExpression WASMFunctionParser::parseLoadExpressionF64(Context& context)
1310{
1311 return parseLoad(context, false, WASMExpressionType::F64, WASMMemoryType::F64, false);
1312}
1313
1314template <class Context>
1315ContextExpression WASMFunctionParser::parseLoadWithOffsetExpressionF64(Context& context)
1316{
1317 return parseLoad(context, true, WASMExpressionType::F64, WASMMemoryType::F64, false);
1318}
1319
1320template <class Context>
1321ContextExpression WASMFunctionParser::parseStoreExpressionF64(Context& context)
1322{
1323 return parseStore(context, false, WASMExpressionType::F64, WASMMemoryType::F64, true);
1324}
1325
1326template <class Context>
1327ContextExpression WASMFunctionParser::parseStoreWithOffsetExpressionF64(Context& context)
1328{
1329 return parseStore(context, true, WASMExpressionType::F64, WASMMemoryType::F64, true);
1330}
1331
1332template <class Context>
1333ContextExpression WASMFunctionParser::parseCallInternalExpressionF64(Context& context)
1334{
1335 return parseCallInternal(context, true, WASMExpressionType::F64);
1336}
1337
1338template <class Context>
1339ContextExpression WASMFunctionParser::parseCallIndirectExpressionF64(Context& context)
1340{
1341 return parseCallIndirect(context, true, WASMExpressionType::F64);
1342}
1343
1344template <class Context>
1345ContextExpression WASMFunctionParser::parseCallImportExpressionF64(Context& context)
1346{
1347 return parseCallImport(context, true, WASMExpressionType::F64);
1348}
1349
1350template <class Context>
1351ContextExpression WASMFunctionParser::parseConditionalExpressionF64(Context& context)
1352{
1353ContextExpression expression = parseExpressionI32(context);
1354 PROPAGATE_ERROR();
1355 ContextJump els = context.jitBranchIfZero(expression);
1356 parseExpressionF64(context);
1357 PROPAGATE_ERROR();
1358 ContextJump end = context.jitJump();
1359 context.jitLinkJump(els);
1360 context.pop();
1361 parseExpressionF64(context);
1362 PROPAGATE_ERROR();
1363 context.jitLinkJump(end);
1364 return UNUSED;
1365}
1366
1367template <class Context>
1368ContextExpression WASMFunctionParser::parseCommaExpressionF64(Context& context)
1369{
1370 WASMExpressionType expressionType;
1371 READ_EXPRESSION_TYPE_OR_FAIL(expressionType, "Cannot read the expression type.");
1372 parseExpression(context, expressionType);
1373 PROPAGATE_ERROR();
1374 if (expressionType != WASMExpressionType::Void)
1375 context.pop();
1376 parseExpressionF64(context);
1377 PROPAGATE_ERROR();
1378 return UNUSED;
1379}
1380
1381template <class Context>
1382ContextExpression WASMFunctionParser::parseFromS32ExpressionF64(Context& context)
1383{
1384 ContextExpression expression = parseExpressionI32(context);
1385 PROPAGATE_ERROR();
1386 return context.createFromS32ExpressionF64(expression);
1387}
1388
1389template <class Context>
1390ContextExpression WASMFunctionParser::parseFromU32ExpressionF64(Context& context)
1391{
1392 ContextExpression expression = parseExpressionI32(context);
1393 PROPAGATE_ERROR();
1394 return context.createFromU32ExpressionF64(expression);
1395}
1396
1397template <class Context>
1398ContextExpression WASMFunctionParser::parseUnaryExpressionF64(Context& context, WASMOpExpressionF64 op)
1399{
1400 ContextExpression expression = parseExpressionF64(context);
1401 PROPAGATE_ERROR();
1402 return context.createUnaryExpressionF64(expression, op);
1403}
1404
1405template <class Context>
1406ContextExpression WASMFunctionParser::parseBinaryExpressionF64(Context& context, WASMOpExpressionF64 op)
1407{
1408 ContextExpression expression1 = parseExpressionF64(context);
1409 PROPAGATE_ERROR();
1410 ContextExpression expression2 = parseExpressionF64(context);
1411 PROPAGATE_ERROR();
1412 return context.createBinaryExpressionF64(expression1, expression2, op);
1413}
1414
1415template <class Context>
1416ContextExpression WASMFunctionParser::parseExpressionVoid(Context& context)
1417{
1418 WASMOpExpressionVoid op;
1419 op = m_reader.readOpExpressionVoid(); // FIXME
1420 switch (op) {
1421 case WASMOpExpressionVoid::CallInternal:
1422 return parseCallInternalExpressionVoid(context);
1423 case WASMOpExpressionVoid::CallIndirect:
1424 return parseCallIndirectExpressionVoid(context);
1425 case WASMOpExpressionVoid::CallImport:
1426 return parseCallImportExpressionVoid(context);
1427 default:
1428 RELEASE_ASSERT_NOT_REACHED();
1429 }
1430}
1431
1432template <class Context>
1433ContextExpression WASMFunctionParser::parseCallInternalExpressionVoid(Context& context)
1434{
1435 return parseCallInternal(context, true, WASMExpressionType::Void);
1436}
1437
1438template <class Context>
1439ContextExpression WASMFunctionParser::parseCallIndirectExpressionVoid(Context& context)
1440{
1441 return parseCallIndirect(context, true, WASMExpressionType::Void);
1442}
1443
1444template <class Context>
1445ContextExpression WASMFunctionParser::parseCallImportExpressionVoid(Context& context)
1446{
1447 return parseCallImport(context, true, WASMExpressionType::Void);
1448}
1449
1450template <class Context>
1451ContextMemoryAddress WASMFunctionParser::parseMemoryAddress(Context& context, bool hasOffset)
1452{
1453 uint32_t offset = 0;
1454 if (hasOffset)
1455 READ_COMPACT_UINT32_OR_FAIL(offset, "Cannot read the offset.");
1456
1457 bool hasImmediateIndex;
1458 uint32_t immediateIndex;
1459 ContextExpression indexExpression;
1460 if (m_reader.ifI32Literal(m_module->i32Constants(), &immediateIndex)) {
1461 hasImmediateIndex = true;
1462 indexExpression = 0;
1463 } else {
1464 hasImmediateIndex = false;
1465 indexExpression = parseExpressionI32(context);
1466 PROPAGATE_ERROR();
1467 }
1468 return ContextMemoryAddress(hasImmediateIndex, immediateIndex, indexExpression, offset);
1469}
1470
1471template <class Context>
1472ContextExpression WASMFunctionParser::parseLoad(Context& context, bool hasOffset, WASMExpressionType expressionType, WASMMemoryType memoryType, bool signExtended)
1473{
1474 const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, hasOffset);
1475 PROPAGATE_ERROR();
1476
1477 return context.createLoad(memoryAddress, expressionType, memoryType, signExtended);
1478}
1479
1480template <class Context>
1481ContextExpression WASMFunctionParser::parseStore(Context& context, bool hasOffset, WASMExpressionType expressionType, WASMMemoryType memoryType, bool isExpression)
1482{
1483 const ContextMemoryAddress& memoryAddress = parseMemoryAddress(context, hasOffset);
1484 PROPAGATE_ERROR();
1485
1486 ContextExpression value = parseExpression(context, expressionType);
1487 PROPAGATE_ERROR();
1488
1489 return context.createStore(memoryAddress, expressionType, memoryType, value, isExpression);
1490}
1491
1492template <class Context>
1493ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments)
1494{
1495 for (size_t i = 0; i < arguments.size(); ++i) {
1496 parseExpression(context, WASMExpressionType(arguments[i]));
1497 PROPAGATE_ERROR();
1498 }
1499 return UNUSED;
1500}
1501
1502template <class Context>
1503ContextExpression WASMFunctionParser::parseCallInternal(Context& context, bool isExpression, WASMExpressionType returnType)
1504{
1505 uint32_t functionIndex;
1506 READ_COMPACT_UINT32_OR_FAIL(functionIndex, "Cannot read the function index.");
1507 FAIL_IF_FALSE(functionIndex < m_module->functionDeclarations().size(), "The function index is incorrect.");
1508 const WASMSignature& signature = m_module->signatures()[m_module->functionDeclarations()[functionIndex].signatureIndex];
1509 if (isExpression)
1510 FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1511
1512 parseCallArguments(context, signature.arguments);
1513 PROPAGATE_ERROR();
1514 return context.createCallInternal(functionIndex, signature, returnType);
1515}
1516
1517template <class Context>
1518ContextExpression WASMFunctionParser::parseCallIndirect(Context& context, bool isExpression, WASMExpressionType returnType)
1519{
1520 uint32_t functionPointerTableIndex;
1521 READ_COMPACT_UINT32_OR_FAIL(functionPointerTableIndex, "Cannot read the function pointer table index.");
1522 FAIL_IF_FALSE(functionPointerTableIndex < m_module->functionPointerTables().size(), "The function pointer table index is incorrect.");
1523 const WASMFunctionPointerTable& functionPointerTable = m_module->functionPointerTables()[functionPointerTableIndex];
1524 const WASMSignature& signature = m_module->signatures()[functionPointerTable.signatureIndex];
1525 if (isExpression)
1526 FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1527
1528 ContextExpression elementIndex = parseExpressionI32(context);
1529 PROPAGATE_ERROR();
1530
1531 parseCallArguments(context, signature.arguments);
1532 PROPAGATE_ERROR();
1533 return context.createCallIndirect(functionPointerTableIndex, elementIndex, signature, returnType);
1534}
1535
1536template <class Context>
1537ContextExpression WASMFunctionParser::parseCallImport(Context& context, bool isExpression, WASMExpressionType returnType)
1538{
1539 uint32_t functionImportSignatureIndex;
1540 READ_COMPACT_UINT32_OR_FAIL(functionImportSignatureIndex, "Cannot read the function import signature index.");
1541 FAIL_IF_FALSE(functionImportSignatureIndex < m_module->functionImportSignatures().size(), "The function import signature index is incorrect.");
1542 const WASMFunctionImportSignature& functionImportSignature = m_module->functionImportSignatures()[functionImportSignatureIndex];
1543 const WASMSignature& signature = m_module->signatures()[functionImportSignature.signatureIndex];
1544 if (isExpression)
1545 FAIL_IF_FALSE(signature.returnType == returnType, "Wrong return type.");
1546
1547 parseCallArguments(context, signature.arguments);
1548 PROPAGATE_ERROR();
1549 return context.createCallImport(functionImportSignatureIndex, signature, returnType);
1550}
1551
1552} // namespace JSC
1553
1554#endif // ENABLE(WEBASSEMBLY)