1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
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  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
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 #include "builtin/SIMD.h"
23 
24 namespace js {
25 namespace wasm {
26 
27 static const uint32_t MagicNumber        = 0x6d736100; // "\0asm"
28 static const uint32_t EncodingVersion    = 0x01;
29 
30 // 0xd is equivalent to 0x1 modulo unreachability validation rules, so to aid
31 // transition of toolchain, accept both for a short period of time.
32 static const uint32_t PrevEncodingVersion = 0x0d;
33 
34 enum class SectionId {
35     UserDefined                          = 0,
36     Type                                 = 1,
37     Import                               = 2,
38     Function                             = 3,
39     Table                                = 4,
40     Memory                               = 5,
41     Global                               = 6,
42     Export                               = 7,
43     Start                                = 8,
44     Elem                                 = 9,
45     Code                                 = 10,
46     Data                                 = 11
47 };
48 
49 static const char NameSectionName[] = "name";
50 
51 enum class TypeCode
52 {
53     I32                                  = 0x7f,  // SLEB128(-0x01)
54     I64                                  = 0x7e,  // SLEB128(-0x02)
55     F32                                  = 0x7d,  // SLEB128(-0x03)
56     F64                                  = 0x7c,  // SLEB128(-0x04)
57 
58     // Only emitted internally for asm.js, likely to get collapsed into I128
59     I8x16                                = 0x7b,
60     I16x8                                = 0x7a,
61     I32x4                                = 0x79,
62     F32x4                                = 0x78,
63     B8x16                                = 0x77,
64     B16x8                                = 0x76,
65     B32x4                                = 0x75,
66 
67     // A function pointer with any signature
68     AnyFunc                              = 0x70,  // SLEB128(-0x10)
69 
70     // Type constructor for function types
71     Func                                 = 0x60,  // SLEB128(-0x20)
72 
73     // Special code representing the block signature ()->()
74     BlockVoid                            = 0x40,  // SLEB128(-0x40)
75 
76     Limit                                = 0x80
77 };
78 
79 enum class ValType
80 {
81     I32                                  = uint8_t(TypeCode::I32),
82     I64                                  = uint8_t(TypeCode::I64),
83     F32                                  = uint8_t(TypeCode::F32),
84     F64                                  = uint8_t(TypeCode::F64),
85 
86     // ------------------------------------------------------------------------
87     // The rest of these types are currently only emitted internally when
88     // compiling asm.js and are rejected by wasm validation.
89 
90     I8x16                                = uint8_t(TypeCode::I8x16),
91     I16x8                                = uint8_t(TypeCode::I16x8),
92     I32x4                                = uint8_t(TypeCode::I32x4),
93     F32x4                                = uint8_t(TypeCode::F32x4),
94     B8x16                                = uint8_t(TypeCode::B8x16),
95     B16x8                                = uint8_t(TypeCode::B16x8),
96     B32x4                                = uint8_t(TypeCode::B32x4)
97 };
98 
99 typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector;
100 
101 enum class DefinitionKind
102 {
103     Function                             = 0x00,
104     Table                                = 0x01,
105     Memory                               = 0x02,
106     Global                               = 0x03
107 };
108 
109 enum class GlobalTypeImmediate
110 {
111     IsMutable                            = 0x1,
112     AllowedMask                          = 0x1
113 };
114 
115 enum class MemoryTableFlags
116 {
117     Default                              = 0x0
118 };
119 
120 enum class Op
121 {
122     // Control flow operators
123     Unreachable                          = 0x00,
124     Nop                                  = 0x01,
125     Block                                = 0x02,
126     Loop                                 = 0x03,
127     If                                   = 0x04,
128     Else                                 = 0x05,
129     End                                  = 0x0b,
130     Br                                   = 0x0c,
131     BrIf                                 = 0x0d,
132     BrTable                              = 0x0e,
133     Return                               = 0x0f,
134 
135     // Call operators
136     Call                                 = 0x10,
137     CallIndirect                         = 0x11,
138 
139     // Parametric operators
140     Drop                                 = 0x1a,
141     Select                               = 0x1b,
142 
143     // Variable access
144     GetLocal                             = 0x20,
145     SetLocal                             = 0x21,
146     TeeLocal                             = 0x22,
147     GetGlobal                            = 0x23,
148     SetGlobal                            = 0x24,
149 
150     // Memory-related operators
151     I32Load                              = 0x28,
152     I64Load                              = 0x29,
153     F32Load                              = 0x2a,
154     F64Load                              = 0x2b,
155     I32Load8S                            = 0x2c,
156     I32Load8U                            = 0x2d,
157     I32Load16S                           = 0x2e,
158     I32Load16U                           = 0x2f,
159     I64Load8S                            = 0x30,
160     I64Load8U                            = 0x31,
161     I64Load16S                           = 0x32,
162     I64Load16U                           = 0x33,
163     I64Load32S                           = 0x34,
164     I64Load32U                           = 0x35,
165     I32Store                             = 0x36,
166     I64Store                             = 0x37,
167     F32Store                             = 0x38,
168     F64Store                             = 0x39,
169     I32Store8                            = 0x3a,
170     I32Store16                           = 0x3b,
171     I64Store8                            = 0x3c,
172     I64Store16                           = 0x3d,
173     I64Store32                           = 0x3e,
174     CurrentMemory                        = 0x3f,
175     GrowMemory                           = 0x40,
176 
177     // Constants
178     I32Const                             = 0x41,
179     I64Const                             = 0x42,
180     F32Const                             = 0x43,
181     F64Const                             = 0x44,
182 
183     // Comparison operators
184     I32Eqz                               = 0x45,
185     I32Eq                                = 0x46,
186     I32Ne                                = 0x47,
187     I32LtS                               = 0x48,
188     I32LtU                               = 0x49,
189     I32GtS                               = 0x4a,
190     I32GtU                               = 0x4b,
191     I32LeS                               = 0x4c,
192     I32LeU                               = 0x4d,
193     I32GeS                               = 0x4e,
194     I32GeU                               = 0x4f,
195     I64Eqz                               = 0x50,
196     I64Eq                                = 0x51,
197     I64Ne                                = 0x52,
198     I64LtS                               = 0x53,
199     I64LtU                               = 0x54,
200     I64GtS                               = 0x55,
201     I64GtU                               = 0x56,
202     I64LeS                               = 0x57,
203     I64LeU                               = 0x58,
204     I64GeS                               = 0x59,
205     I64GeU                               = 0x5a,
206     F32Eq                                = 0x5b,
207     F32Ne                                = 0x5c,
208     F32Lt                                = 0x5d,
209     F32Gt                                = 0x5e,
210     F32Le                                = 0x5f,
211     F32Ge                                = 0x60,
212     F64Eq                                = 0x61,
213     F64Ne                                = 0x62,
214     F64Lt                                = 0x63,
215     F64Gt                                = 0x64,
216     F64Le                                = 0x65,
217     F64Ge                                = 0x66,
218 
219     // Numeric operators
220     I32Clz                               = 0x67,
221     I32Ctz                               = 0x68,
222     I32Popcnt                            = 0x69,
223     I32Add                               = 0x6a,
224     I32Sub                               = 0x6b,
225     I32Mul                               = 0x6c,
226     I32DivS                              = 0x6d,
227     I32DivU                              = 0x6e,
228     I32RemS                              = 0x6f,
229     I32RemU                              = 0x70,
230     I32And                               = 0x71,
231     I32Or                                = 0x72,
232     I32Xor                               = 0x73,
233     I32Shl                               = 0x74,
234     I32ShrS                              = 0x75,
235     I32ShrU                              = 0x76,
236     I32Rotl                              = 0x77,
237     I32Rotr                              = 0x78,
238     I64Clz                               = 0x79,
239     I64Ctz                               = 0x7a,
240     I64Popcnt                            = 0x7b,
241     I64Add                               = 0x7c,
242     I64Sub                               = 0x7d,
243     I64Mul                               = 0x7e,
244     I64DivS                              = 0x7f,
245     I64DivU                              = 0x80,
246     I64RemS                              = 0x81,
247     I64RemU                              = 0x82,
248     I64And                               = 0x83,
249     I64Or                                = 0x84,
250     I64Xor                               = 0x85,
251     I64Shl                               = 0x86,
252     I64ShrS                              = 0x87,
253     I64ShrU                              = 0x88,
254     I64Rotl                              = 0x89,
255     I64Rotr                              = 0x8a,
256     F32Abs                               = 0x8b,
257     F32Neg                               = 0x8c,
258     F32Ceil                              = 0x8d,
259     F32Floor                             = 0x8e,
260     F32Trunc                             = 0x8f,
261     F32Nearest                           = 0x90,
262     F32Sqrt                              = 0x91,
263     F32Add                               = 0x92,
264     F32Sub                               = 0x93,
265     F32Mul                               = 0x94,
266     F32Div                               = 0x95,
267     F32Min                               = 0x96,
268     F32Max                               = 0x97,
269     F32CopySign                          = 0x98,
270     F64Abs                               = 0x99,
271     F64Neg                               = 0x9a,
272     F64Ceil                              = 0x9b,
273     F64Floor                             = 0x9c,
274     F64Trunc                             = 0x9d,
275     F64Nearest                           = 0x9e,
276     F64Sqrt                              = 0x9f,
277     F64Add                               = 0xa0,
278     F64Sub                               = 0xa1,
279     F64Mul                               = 0xa2,
280     F64Div                               = 0xa3,
281     F64Min                               = 0xa4,
282     F64Max                               = 0xa5,
283     F64CopySign                          = 0xa6,
284 
285     // Conversions
286     I32WrapI64                           = 0xa7,
287     I32TruncSF32                         = 0xa8,
288     I32TruncUF32                         = 0xa9,
289     I32TruncSF64                         = 0xaa,
290     I32TruncUF64                         = 0xab,
291     I64ExtendSI32                        = 0xac,
292     I64ExtendUI32                        = 0xad,
293     I64TruncSF32                         = 0xae,
294     I64TruncUF32                         = 0xaf,
295     I64TruncSF64                         = 0xb0,
296     I64TruncUF64                         = 0xb1,
297     F32ConvertSI32                       = 0xb2,
298     F32ConvertUI32                       = 0xb3,
299     F32ConvertSI64                       = 0xb4,
300     F32ConvertUI64                       = 0xb5,
301     F32DemoteF64                         = 0xb6,
302     F64ConvertSI32                       = 0xb7,
303     F64ConvertUI32                       = 0xb8,
304     F64ConvertSI64                       = 0xb9,
305     F64ConvertUI64                       = 0xba,
306     F64PromoteF32                        = 0xbb,
307 
308     // Reinterpretations
309     I32ReinterpretF32                    = 0xbc,
310     I64ReinterpretF64                    = 0xbd,
311     F32ReinterpretI32                    = 0xbe,
312     F64ReinterpretI64                    = 0xbf,
313 
314     // ------------------------------------------------------------------------
315     // The rest of these operators are currently only emitted internally when
316     // compiling asm.js and are rejected by wasm validation.
317 
318     // asm.js-specific operators
319     TeeGlobal                            = 0xc8,
320     I32Min,
321     I32Max,
322     I32Neg,
323     I32BitNot,
324     I32Abs,
325     F32TeeStoreF64,
326     F64TeeStoreF32,
327     I32TeeStore8,
328     I32TeeStore16,
329     I64TeeStore8,
330     I64TeeStore16,
331     I64TeeStore32,
332     I32TeeStore,
333     I64TeeStore,
334     F32TeeStore,
335     F64TeeStore,
336     F64Mod,
337     F64Sin,
338     F64Cos,
339     F64Tan,
340     F64Asin,
341     F64Acos,
342     F64Atan,
343     F64Exp,
344     F64Log,
345     F64Pow,
346     F64Atan2,
347 
348     // asm.js-style call_indirect with the callee evaluated first.
349     OldCallIndirect,
350 
351     // Atomics
352     I32AtomicsCompareExchange,
353     I32AtomicsExchange,
354     I32AtomicsLoad,
355     I32AtomicsStore,
356     I32AtomicsBinOp,
357 
358     // SIMD
359 #define SIMD_OPCODE(TYPE, OP) TYPE##OP,
360 #define _(OP) SIMD_OPCODE(I8x16, OP)
361     FORALL_INT8X16_ASMJS_OP(_)
362     I8x16Constructor,
363     I8x16Const,
364 #undef _
365     // Unsigned I8x16 operations. These are the SIMD.Uint8x16 operations that
366     // behave differently from their SIMD.Int8x16 counterparts.
367     I8x16extractLaneU,
368     I8x16addSaturateU,
369     I8x16subSaturateU,
370     I8x16shiftRightByScalarU,
371     I8x16lessThanU,
372     I8x16lessThanOrEqualU,
373     I8x16greaterThanU,
374     I8x16greaterThanOrEqualU,
375 
376 #define SIMD_OPCODE(TYPE, OP) TYPE##OP,
377 #define _(OP) SIMD_OPCODE(I16x8, OP)
378     FORALL_INT16X8_ASMJS_OP(_)
379     I16x8Constructor,
380     I16x8Const,
381 #undef _
382     // Unsigned I16x8 operations. These are the SIMD.Uint16x8 operations that
383     // behave differently from their SIMD.Int16x8 counterparts.
384     I16x8extractLaneU,
385     I16x8addSaturateU,
386     I16x8subSaturateU,
387     I16x8shiftRightByScalarU,
388     I16x8lessThanU,
389     I16x8lessThanOrEqualU,
390     I16x8greaterThanU,
391     I16x8greaterThanOrEqualU,
392 
393 #define SIMD_OPCODE(TYPE, OP) TYPE##OP,
394 #define _(OP) SIMD_OPCODE(I32x4, OP)
395     FORALL_INT32X4_ASMJS_OP(_)
396     I32x4Constructor,
397     I32x4Const,
398 #undef _
399     // Unsigned I32x4 operations. These are the SIMD.Uint32x4 operations that
400     // behave differently from their SIMD.Int32x4 counterparts.
401     I32x4shiftRightByScalarU,
402     I32x4lessThanU,
403     I32x4lessThanOrEqualU,
404     I32x4greaterThanU,
405     I32x4greaterThanOrEqualU,
406     I32x4fromFloat32x4U,
407 #define _(OP) SIMD_OPCODE(F32x4, OP)
408     FORALL_FLOAT32X4_ASMJS_OP(_)
409     F32x4Constructor,
410     F32x4Const,
411 #undef _
412 
413 #define _(OP) SIMD_OPCODE(B8x16, OP)
414     FORALL_BOOL_SIMD_OP(_)
415     B8x16Constructor,
416     B8x16Const,
417 #undef _
418 #undef OPCODE
419 
420 #define _(OP) SIMD_OPCODE(B16x8, OP)
421     FORALL_BOOL_SIMD_OP(_)
422     B16x8Constructor,
423     B16x8Const,
424 #undef _
425 #undef OPCODE
426 
427 #define _(OP) SIMD_OPCODE(B32x4, OP)
428     FORALL_BOOL_SIMD_OP(_)
429     B32x4Constructor,
430     B32x4Const,
431 #undef _
432 #undef OPCODE
433 
434     Limit
435 };
436 
437 // Telemetry sample values for the JS_AOT_USAGE key, indicating whether asm.js
438 // or WebAssembly is used.
439 
440 enum class Telemetry
441 {
442     ASMJS = 0,
443     WASM = 1
444 };
445 
446 } // namespace wasm
447 } // namespace js
448 
449 #endif // wasm_binary_h
450