Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
*
4
* Copyright 2015 Mozilla Foundation
5
*
6
* Licensed under the Apache License, Version 2.0 (the "License");
7
* you may not use this file except in compliance with the License.
8
* You may obtain a copy of the License at
9
*
11
*
12
* Unless required by applicable law or agreed to in writing, software
13
* distributed under the License is distributed on an "AS IS" BASIS,
14
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
* See the License for the specific language governing permissions and
16
* limitations under the License.
17
*/
18
19
#ifndef wasm_binary_h
20
#define wasm_binary_h
21
22
namespace js {
23
namespace wasm {
24
25
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
26
static const uint32_t EncodingVersion = 0x01;
27
28
enum class SectionId {
29
Custom = 0,
30
Type = 1,
31
Import = 2,
32
Function = 3,
33
Table = 4,
34
Memory = 5,
35
Global = 6,
36
Export = 7,
37
Start = 8,
38
Elem = 9,
39
Code = 10,
40
Data = 11,
41
DataCount = 12,
42
GcFeatureOptIn = 42 // Arbitrary, but fits in 7 bits
43
};
44
45
// WebAssembly type encodings are all single-byte negative SLEB128s, hence:
46
// forall tc:TypeCode. ((tc & SLEB128SignMask) == SLEB128SignBit
47
static const uint8_t SLEB128SignMask = 0xc0;
48
static const uint8_t SLEB128SignBit = 0x40;
49
50
enum class TypeCode {
51
52
// If more "simple primitive" (non-reference, non-constructor,
53
// non-special-purpose) types are added here then you MUST update
54
// LowestPrimitiveTypeCode, below.
55
56
I32 = 0x7f, // SLEB128(-0x01)
57
I64 = 0x7e, // SLEB128(-0x02)
58
F32 = 0x7d, // SLEB128(-0x03)
59
F64 = 0x7c, // SLEB128(-0x04)
60
61
// A function pointer with any signature
62
FuncRef = 0x70, // SLEB128(-0x10)
63
64
// A reference to any type.
65
AnyRef = 0x6f,
66
67
// Type constructor for reference types.
68
Ref = 0x6e,
69
70
// Type constructor for function types
71
Func = 0x60, // SLEB128(-0x20)
72
73
// Type constructor for structure types - unofficial
74
Struct = 0x50, // SLEB128(-0x30)
75
76
// The 'empty' case of blocktype.
77
BlockVoid = 0x40, // SLEB128(-0x40)
78
79
// Type designator for null - unofficial, will not appear in the binary format
80
NullRef = 0x39,
81
82
Limit = 0x80
83
};
84
85
// This is the lowest-valued TypeCode that is a primitive type, used in
86
// UnpackTypeCodeTypeAbstracted(). If primitive typecodes are added below any
87
// reference typecode then the logic in that function MUST change.
88
89
static constexpr TypeCode LowestPrimitiveTypeCode = TypeCode::F64;
90
91
enum class FuncTypeIdDescKind { None, Immediate, Global };
92
93
// A wasm::Trap represents a wasm-defined trap that can occur during execution
94
// which triggers a WebAssembly.RuntimeError. Generated code may jump to a Trap
95
// symbolically, passing the bytecode offset to report as the trap offset. The
96
// generated jump will be bound to a tiny stub which fills the offset and
97
// then jumps to a per-Trap shared stub at the end of the module.
98
99
enum class Trap {
100
// The Unreachable opcode has been executed.
101
Unreachable,
102
// An integer arithmetic operation led to an overflow.
103
IntegerOverflow,
104
// Trying to coerce NaN to an integer.
105
InvalidConversionToInteger,
106
// Integer division by zero.
107
IntegerDivideByZero,
108
// Out of bounds on wasm memory accesses.
109
OutOfBounds,
110
// Unaligned on wasm atomic accesses; also used for non-standard ARM
111
// unaligned access faults.
112
UnalignedAccess,
113
// call_indirect to null.
114
IndirectCallToNull,
115
// call_indirect signature mismatch.
116
IndirectCallBadSig,
117
// Dereference null pointer in operation on (Ref T)
118
NullPointerDereference,
119
120
// The internal stack space was exhausted. For compatibility, this throws
121
// the same over-recursed error as JS.
122
StackOverflow,
123
124
// The wasm execution has potentially run too long and the engine must call
125
// CheckForInterrupt(). This trap is resumable.
126
CheckInterrupt,
127
128
// Signal an error that was reported in C++ code.
129
ThrowReported,
130
131
Limit
132
};
133
134
// The representation of a null reference value throughout the compiler.
135
136
static const intptr_t NULLREF_VALUE = intptr_t((void*)nullptr);
137
138
enum class DefinitionKind {
139
Function = 0x00,
140
Table = 0x01,
141
Memory = 0x02,
142
Global = 0x03
143
};
144
145
enum class GlobalTypeImmediate { IsMutable = 0x1, AllowedMask = 0x1 };
146
147
enum class MemoryTableFlags {
148
Default = 0x0,
149
HasMaximum = 0x1,
150
IsShared = 0x2,
151
};
152
153
enum class MemoryMasks { AllowUnshared = 0x1, AllowShared = 0x3 };
154
155
enum class DataSegmentKind {
156
Active = 0x00,
157
Passive = 0x01,
158
ActiveWithMemoryIndex = 0x02
159
};
160
161
enum class ElemSegmentKind : uint32_t {
162
Active = 0x0,
163
Passive = 0x1,
164
ActiveWithTableIndex = 0x2,
165
Declared = 0x3,
166
};
167
168
enum class ElemSegmentPayload : uint32_t {
169
ExternIndex = 0x0,
170
ElemExpression = 0x4,
171
};
172
173
enum class Op {
174
// Control flow operators
175
Unreachable = 0x00,
176
Nop = 0x01,
177
Block = 0x02,
178
Loop = 0x03,
179
If = 0x04,
180
Else = 0x05,
181
End = 0x0b,
182
Br = 0x0c,
183
BrIf = 0x0d,
184
BrTable = 0x0e,
185
Return = 0x0f,
186
187
// Call operators
188
Call = 0x10,
189
CallIndirect = 0x11,
190
191
// Parametric operators
192
Drop = 0x1a,
193
SelectNumeric = 0x1b,
194
SelectTyped = 0x1c,
195
196
// Variable access
197
GetLocal = 0x20,
198
SetLocal = 0x21,
199
TeeLocal = 0x22,
200
GetGlobal = 0x23,
201
SetGlobal = 0x24,
202
TableGet = 0x25, // Reftypes,
203
TableSet = 0x26, // per proposal as of February 2019
204
205
// Memory-related operators
206
I32Load = 0x28,
207
I64Load = 0x29,
208
F32Load = 0x2a,
209
F64Load = 0x2b,
210
I32Load8S = 0x2c,
211
I32Load8U = 0x2d,
212
I32Load16S = 0x2e,
213
I32Load16U = 0x2f,
214
I64Load8S = 0x30,
215
I64Load8U = 0x31,
216
I64Load16S = 0x32,
217
I64Load16U = 0x33,
218
I64Load32S = 0x34,
219
I64Load32U = 0x35,
220
I32Store = 0x36,
221
I64Store = 0x37,
222
F32Store = 0x38,
223
F64Store = 0x39,
224
I32Store8 = 0x3a,
225
I32Store16 = 0x3b,
226
I64Store8 = 0x3c,
227
I64Store16 = 0x3d,
228
I64Store32 = 0x3e,
229
MemorySize = 0x3f,
230
MemoryGrow = 0x40,
231
232
// Constants
233
I32Const = 0x41,
234
I64Const = 0x42,
235
F32Const = 0x43,
236
F64Const = 0x44,
237
238
// Comparison operators
239
I32Eqz = 0x45,
240
I32Eq = 0x46,
241
I32Ne = 0x47,
242
I32LtS = 0x48,
243
I32LtU = 0x49,
244
I32GtS = 0x4a,
245
I32GtU = 0x4b,
246
I32LeS = 0x4c,
247
I32LeU = 0x4d,
248
I32GeS = 0x4e,
249
I32GeU = 0x4f,
250
I64Eqz = 0x50,
251
I64Eq = 0x51,
252
I64Ne = 0x52,
253
I64LtS = 0x53,
254
I64LtU = 0x54,
255
I64GtS = 0x55,
256
I64GtU = 0x56,
257
I64LeS = 0x57,
258
I64LeU = 0x58,
259
I64GeS = 0x59,
260
I64GeU = 0x5a,
261
F32Eq = 0x5b,
262
F32Ne = 0x5c,
263
F32Lt = 0x5d,
264
F32Gt = 0x5e,
265
F32Le = 0x5f,
266
F32Ge = 0x60,
267
F64Eq = 0x61,
268
F64Ne = 0x62,
269
F64Lt = 0x63,
270
F64Gt = 0x64,
271
F64Le = 0x65,
272
F64Ge = 0x66,
273
274
// Numeric operators
275
I32Clz = 0x67,
276
I32Ctz = 0x68,
277
I32Popcnt = 0x69,
278
I32Add = 0x6a,
279
I32Sub = 0x6b,
280
I32Mul = 0x6c,
281
I32DivS = 0x6d,
282
I32DivU = 0x6e,
283
I32RemS = 0x6f,
284
I32RemU = 0x70,
285
I32And = 0x71,
286
I32Or = 0x72,
287
I32Xor = 0x73,
288
I32Shl = 0x74,
289
I32ShrS = 0x75,
290
I32ShrU = 0x76,
291
I32Rotl = 0x77,
292
I32Rotr = 0x78,
293
I64Clz = 0x79,
294
I64Ctz = 0x7a,
295
I64Popcnt = 0x7b,
296
I64Add = 0x7c,
297
I64Sub = 0x7d,
298
I64Mul = 0x7e,
299
I64DivS = 0x7f,
300
I64DivU = 0x80,
301
I64RemS = 0x81,
302
I64RemU = 0x82,
303
I64And = 0x83,
304
I64Or = 0x84,
305
I64Xor = 0x85,
306
I64Shl = 0x86,
307
I64ShrS = 0x87,
308
I64ShrU = 0x88,
309
I64Rotl = 0x89,
310
I64Rotr = 0x8a,
311
F32Abs = 0x8b,
312
F32Neg = 0x8c,
313
F32Ceil = 0x8d,
314
F32Floor = 0x8e,
315
F32Trunc = 0x8f,
316
F32Nearest = 0x90,
317
F32Sqrt = 0x91,
318
F32Add = 0x92,
319
F32Sub = 0x93,
320
F32Mul = 0x94,
321
F32Div = 0x95,
322
F32Min = 0x96,
323
F32Max = 0x97,
324
F32CopySign = 0x98,
325
F64Abs = 0x99,
326
F64Neg = 0x9a,
327
F64Ceil = 0x9b,
328
F64Floor = 0x9c,
329
F64Trunc = 0x9d,
330
F64Nearest = 0x9e,
331
F64Sqrt = 0x9f,
332
F64Add = 0xa0,
333
F64Sub = 0xa1,
334
F64Mul = 0xa2,
335
F64Div = 0xa3,
336
F64Min = 0xa4,
337
F64Max = 0xa5,
338
F64CopySign = 0xa6,
339
340
// Conversions
341
I32WrapI64 = 0xa7,
342
I32TruncSF32 = 0xa8,
343
I32TruncUF32 = 0xa9,
344
I32TruncSF64 = 0xaa,
345
I32TruncUF64 = 0xab,
346
I64ExtendSI32 = 0xac,
347
I64ExtendUI32 = 0xad,
348
I64TruncSF32 = 0xae,
349
I64TruncUF32 = 0xaf,
350
I64TruncSF64 = 0xb0,
351
I64TruncUF64 = 0xb1,
352
F32ConvertSI32 = 0xb2,
353
F32ConvertUI32 = 0xb3,
354
F32ConvertSI64 = 0xb4,
355
F32ConvertUI64 = 0xb5,
356
F32DemoteF64 = 0xb6,
357
F64ConvertSI32 = 0xb7,
358
F64ConvertUI32 = 0xb8,
359
F64ConvertSI64 = 0xb9,
360
F64ConvertUI64 = 0xba,
361
F64PromoteF32 = 0xbb,
362
363
// Reinterpretations
364
I32ReinterpretF32 = 0xbc,
365
I64ReinterpretF64 = 0xbd,
366
F32ReinterpretI32 = 0xbe,
367
F64ReinterpretI64 = 0xbf,
368
369
// Sign extension
370
I32Extend8S = 0xc0,
371
I32Extend16S = 0xc1,
372
I64Extend8S = 0xc2,
373
I64Extend16S = 0xc3,
374
I64Extend32S = 0xc4,
375
376
// GC ops
377
RefNull = 0xd0,
378
RefIsNull = 0xd1,
379
RefFunc = 0xd2,
380
381
RefEq = 0xf0, // Unofficial + experimental
382
383
FirstPrefix = 0xfc,
384
MiscPrefix = 0xfc,
385
ThreadPrefix = 0xfe,
386
MozPrefix = 0xff,
387
388
Limit = 0x100
389
};
390
391
inline bool IsPrefixByte(uint8_t b) { return b >= uint8_t(Op::FirstPrefix); }
392
393
// Opcodes in the "miscellaneous" opcode space.
394
enum class MiscOp {
395
// Saturating float-to-int conversions
396
I32TruncSSatF32 = 0x00,
397
I32TruncUSatF32 = 0x01,
398
I32TruncSSatF64 = 0x02,
399
I32TruncUSatF64 = 0x03,
400
I64TruncSSatF32 = 0x04,
401
I64TruncUSatF32 = 0x05,
402
I64TruncSSatF64 = 0x06,
403
I64TruncUSatF64 = 0x07,
404
405
// Bulk memory operations, per proposal as of February 2019.
406
MemInit = 0x08,
407
DataDrop = 0x09,
408
MemCopy = 0x0a,
409
MemFill = 0x0b,
410
TableInit = 0x0c,
411
ElemDrop = 0x0d,
412
TableCopy = 0x0e,
413
414
// Reftypes, per proposal as of February 2019.
415
TableGrow = 0x0f,
416
TableSize = 0x10,
417
TableFill = 0x11,
418
419
// Structure operations. Note, these are unofficial.
420
StructNew = 0x50,
421
StructGet = 0x51,
422
StructSet = 0x52,
423
StructNarrow = 0x53,
424
425
Limit
426
};
427
428
// Opcodes from threads proposal as of June 30, 2017
429
enum class ThreadOp {
430
// Wait and wake
431
Wake = 0x00,
432
I32Wait = 0x01,
433
I64Wait = 0x02,
434
Fence = 0x03,
435
436
// Load and store
437
I32AtomicLoad = 0x10,
438
I64AtomicLoad = 0x11,
439
I32AtomicLoad8U = 0x12,
440
I32AtomicLoad16U = 0x13,
441
I64AtomicLoad8U = 0x14,
442
I64AtomicLoad16U = 0x15,
443
I64AtomicLoad32U = 0x16,
444
I32AtomicStore = 0x17,
445
I64AtomicStore = 0x18,
446
I32AtomicStore8U = 0x19,
447
I32AtomicStore16U = 0x1a,
448
I64AtomicStore8U = 0x1b,
449
I64AtomicStore16U = 0x1c,
450
I64AtomicStore32U = 0x1d,
451
452
// Read-modify-write operations
453
I32AtomicAdd = 0x1e,
454
I64AtomicAdd = 0x1f,
455
I32AtomicAdd8U = 0x20,
456
I32AtomicAdd16U = 0x21,
457
I64AtomicAdd8U = 0x22,
458
I64AtomicAdd16U = 0x23,
459
I64AtomicAdd32U = 0x24,
460
461
I32AtomicSub = 0x25,
462
I64AtomicSub = 0x26,
463
I32AtomicSub8U = 0x27,
464
I32AtomicSub16U = 0x28,
465
I64AtomicSub8U = 0x29,
466
I64AtomicSub16U = 0x2a,
467
I64AtomicSub32U = 0x2b,
468
469
I32AtomicAnd = 0x2c,
470
I64AtomicAnd = 0x2d,
471
I32AtomicAnd8U = 0x2e,
472
I32AtomicAnd16U = 0x2f,
473
I64AtomicAnd8U = 0x30,
474
I64AtomicAnd16U = 0x31,
475
I64AtomicAnd32U = 0x32,
476
477
I32AtomicOr = 0x33,
478
I64AtomicOr = 0x34,
479
I32AtomicOr8U = 0x35,
480
I32AtomicOr16U = 0x36,
481
I64AtomicOr8U = 0x37,
482
I64AtomicOr16U = 0x38,
483
I64AtomicOr32U = 0x39,
484
485
I32AtomicXor = 0x3a,
486
I64AtomicXor = 0x3b,
487
I32AtomicXor8U = 0x3c,
488
I32AtomicXor16U = 0x3d,
489
I64AtomicXor8U = 0x3e,
490
I64AtomicXor16U = 0x3f,
491
I64AtomicXor32U = 0x40,
492
493
I32AtomicXchg = 0x41,
494
I64AtomicXchg = 0x42,
495
I32AtomicXchg8U = 0x43,
496
I32AtomicXchg16U = 0x44,
497
I64AtomicXchg8U = 0x45,
498
I64AtomicXchg16U = 0x46,
499
I64AtomicXchg32U = 0x47,
500
501
// CompareExchange
502
I32AtomicCmpXchg = 0x48,
503
I64AtomicCmpXchg = 0x49,
504
I32AtomicCmpXchg8U = 0x4a,
505
I32AtomicCmpXchg16U = 0x4b,
506
I64AtomicCmpXchg8U = 0x4c,
507
I64AtomicCmpXchg16U = 0x4d,
508
I64AtomicCmpXchg32U = 0x4e,
509
510
Limit
511
};
512
513
enum class MozOp {
514
// ------------------------------------------------------------------------
515
// These operators are emitted internally when compiling asm.js and are
516
// rejected by wasm validation. They are prefixed by MozPrefix.
517
518
// asm.js-specific operators. They start at 1 so as to check for
519
// uninitialized (zeroed) storage.
520
TeeGlobal = 0x01,
521
I32Min,
522
I32Max,
523
I32Neg,
524
I32BitNot,
525
I32Abs,
526
F32TeeStoreF64,
527
F64TeeStoreF32,
528
I32TeeStore8,
529
I32TeeStore16,
530
I64TeeStore8,
531
I64TeeStore16,
532
I64TeeStore32,
533
I32TeeStore,
534
I64TeeStore,
535
F32TeeStore,
536
F64TeeStore,
537
F64Mod,
538
F64Sin,
539
F64Cos,
540
F64Tan,
541
F64Asin,
542
F64Acos,
543
F64Atan,
544
F64Exp,
545
F64Log,
546
F64Pow,
547
F64Atan2,
548
549
// asm.js-style call_indirect with the callee evaluated first.
550
OldCallDirect,
551
OldCallIndirect,
552
553
Limit
554
};
555
556
struct OpBytes {
557
// b0 is a byte value but has a 16-bit representation to allow for a full
558
// 256-value range plus a sentinel Limit value.
559
uint16_t b0;
560
// b1 is a LEB128 value but 32 bits is enough for now.
561
uint32_t b1;
562
563
explicit OpBytes(Op x) {
564
b0 = uint16_t(x);
565
b1 = 0;
566
}
567
OpBytes() = default;
568
};
569
570
static const char NameSectionName[] = "name";
571
static const char SourceMappingURLSectionName[] = "sourceMappingURL";
572
573
enum class NameType { Module = 0, Function = 1, Local = 2 };
574
575
enum class FieldFlags { Mutable = 0x01, AllowedMask = 0x01 };
576
577
// These limits are agreed upon with other engines for consistency.
578
579
static const unsigned MaxTypes = 1000000;
580
static const unsigned MaxFuncs = 1000000;
581
static const unsigned MaxTables =
582
100000; // TODO: get this into the shared limits spec
583
static const unsigned MaxImports = 100000;
584
static const unsigned MaxExports = 100000;
585
static const unsigned MaxGlobals = 1000000;
586
static const unsigned MaxDataSegments = 100000;
587
static const unsigned MaxElemSegments = 10000000;
588
static const unsigned MaxTableLength = 10000000;
589
static const unsigned MaxLocals = 50000;
590
static const unsigned MaxParams = 1000;
591
// The actual maximum results may be `1` if multi-value is not enabled. Check
592
// `env->funcMaxResults()` to get the correct value for a module.
593
static const unsigned MaxResults = 1000;
594
static const unsigned MaxStructFields = 1000;
595
static const unsigned MaxMemoryMaximumPages = 65536;
596
static const unsigned MaxStringBytes = 100000;
597
static const unsigned MaxModuleBytes = 1024 * 1024 * 1024;
598
static const unsigned MaxFunctionBytes = 7654321;
599
600
// These limits pertain to our WebAssembly implementation only.
601
602
static const unsigned MaxTableInitialLength = 10000000;
603
static const unsigned MaxBrTableElems = 1000000;
604
static const unsigned MaxMemoryInitialPages = 16384;
605
static const unsigned MaxCodeSectionBytes = MaxModuleBytes;
606
607
// FIXME: Temporary limit to function result counts. Replace with MaxResults:
608
// bug 1585909.
609
610
static const unsigned MaxFuncResults = 1;
611
612
// A magic value of the FramePointer to indicate after a return to the entry
613
// stub that an exception has been caught and that we should throw.
614
615
static const unsigned FailFP = 0xbad;
616
617
// Asserted by Decoder::readVarU32.
618
619
static const unsigned MaxVarU32DecodedBytes = 5;
620
621
} // namespace wasm
622
} // namespace js
623
624
#endif // wasm_binary_h