f0c042526faecdf2474d8363ff724bdec90ce2b5
[WebKit-https.git] / Source / JavaScriptCore / wasm / WASMModuleParser.cpp
1 /*
2  * Copyright (C) 2016 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 "WASMModuleParser.h"
28
29 #if ENABLE(WEBASSEMBLY)
30
31 #include "WASMFormat.h"
32 #include "WASMOps.h"
33 #include "WASMSections.h"
34
35 namespace JSC { namespace WASM {
36
37 static const bool verbose = false;
38
39 bool ModuleParser::parse()
40 {
41     if (m_sourceLength < 8)
42         return false;
43     if (!consumeCharacter(0))
44         return false;
45     if (!consumeString("asm"))
46         return false;
47
48     // Skip the version number for now since we don't do anything with it.
49     uint32_t versionNumber;
50     if (!parseUInt32(versionNumber))
51         return false;
52
53     if (versionNumber != magicNumber)
54         return false;
55
56
57     if (verbose)
58         dataLogLn("Passed processing header.");
59
60     Sections::Section previousSection = Sections::Unknown;
61     while (m_offset < m_sourceLength) {
62         if (verbose)
63             dataLogLn("Starting to parse next section at offset: ", m_offset);
64         uint32_t sectionNameLength;
65         if (!parseVarUInt32(sectionNameLength))
66             return false;
67
68         // Make sure we can read up to the section's size.
69         if (m_offset + sectionNameLength + maxLEBByteLength >= m_sourceLength)
70             return false;
71
72         Sections::Section section = Sections::lookup(m_source.data() + m_offset, sectionNameLength);
73         if (!Sections::validateOrder(previousSection, section))
74             return false;
75         m_offset += sectionNameLength;
76
77         uint32_t sectionLength;
78         if (!parseVarUInt32(sectionLength))
79             return false;
80
81         unsigned end = m_offset + sectionLength;
82
83         switch (section) {
84         case Sections::End:
85             return true;
86
87         case Sections::FunctionTypes: {
88             if (verbose)
89                 dataLogLn("Parsing types.");
90             if (!parseFunctionTypes())
91                 return false;
92             break;
93         }
94
95         case Sections::Signatures: {
96             if (verbose)
97                 dataLogLn("Parsing function signatures.");
98             if (!parseFunctionSignatures())
99                 return false;
100             break;
101         }
102
103         case Sections::Definitions: {
104             if (verbose)
105                 dataLogLn("Parsing function definitions.");
106             if (!parseFunctionDefinitions())
107                 return false;
108             break;
109         }
110
111         case Sections::Unknown: {
112             if (verbose)
113                 dataLogLn("Unknown section, skipping.");
114             m_offset += sectionLength;
115             break;
116         }
117         }
118
119         if (verbose)
120             dataLogLn("Finished parsing section.");
121
122         if (end != m_offset)
123             return false;
124
125         previousSection = section;
126     }
127
128     // TODO
129     return true;
130 }
131
132 bool ModuleParser::parseFunctionTypes()
133 {
134     uint32_t count;
135     if (!parseVarUInt32(count))
136         return false;
137
138     if (verbose)
139         dataLogLn("count: ", count);
140
141     m_signatures.resize(count);
142
143     for (uint32_t i = 0; i < count; ++i) {
144         uint8_t type;
145         if (!parseUInt7(type))
146             return false;
147         if (type != 0x40) // Function type constant.
148             return false;
149
150         if (verbose)
151             dataLogLn("Got function type.");
152
153         uint32_t argumentCount;
154         if (!parseVarUInt32(argumentCount))
155             return false;
156
157         if (verbose)
158             dataLogLn("argumentCount: ", argumentCount);
159
160         Vector<Type> argumentTypes;
161         argumentTypes.resize(argumentCount);
162
163         for (unsigned i = 0; i < argumentCount; ++i) {
164             if (!parseUInt7(type) || !isValueType(static_cast<Type>(type)))
165                 return false;
166             argumentTypes[i] = static_cast<Type>(type);
167         }
168
169         if (!parseVarUInt1(type))
170             return false;
171         Type returnType;
172
173         if (verbose)
174             dataLogLn(type);
175
176         if (type) {
177             Type value;
178             if (!parseValueType(value))
179                 return false;
180             returnType = static_cast<Type>(value);
181         } else
182             returnType = Type::Void;
183
184         m_signatures[i] = { returnType, WTFMove(argumentTypes) };
185     }
186     return true;
187 }
188
189 bool ModuleParser::parseFunctionSignatures()
190 {
191     uint32_t count;
192     if (!parseVarUInt32(count))
193         return false;
194
195     m_functions.resize(count);
196
197     for (uint32_t i = 0; i < count; ++i) {
198         uint32_t typeNumber;
199         if (!parseVarUInt32(typeNumber))
200             return false;
201
202         if (typeNumber >= m_signatures.size())
203             return false;
204
205         m_functions[i].signature = &m_signatures[typeNumber];
206     }
207
208     return true;
209 }
210
211 bool ModuleParser::parseFunctionDefinitions()
212 {
213     uint32_t count;
214     if (!parseVarUInt32(count))
215         return false;
216
217     if (count != m_functions.size())
218         return false;
219
220     for (uint32_t i = 0; i < count; ++i) {
221         uint32_t functionSize;
222         if (!parseVarUInt32(functionSize))
223             return false;
224
225         FunctionInformation& info = m_functions[i];
226         info.start = m_offset;
227         info.end = m_offset + functionSize;
228         m_offset = info.end;
229     }
230
231     return true;
232 }
233
234 } } // namespace JSC::WASM
235
236 #endif // ENABLE(WEBASSEMBLY)