Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: src/asmjs/asm-parser.h

Issue 2757693003: [wasm][asm.js] Asm.js -> wasm custom parser. (Closed)
Patch Set: fix Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/asmjs/asm-js.cc ('k') | src/asmjs/asm-parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_ASMJS_ASM_PARSER_H_
6 #define V8_ASMJS_ASM_PARSER_H_
7
8 #include <list>
9 #include <string>
10 #include <vector>
11
12 #include "src/asmjs/asm-scanner.h"
13 #include "src/asmjs/asm-typer.h"
14 #include "src/asmjs/asm-types.h"
15 #include "src/wasm/signature-map.h"
16 #include "src/wasm/wasm-module-builder.h"
17 #include "src/zone/zone-containers.h"
18
19 namespace v8 {
20 namespace internal {
21 namespace wasm {
22
23 // A custom parser + validator + wasm converter for asm.js:
24 // http://asmjs.org/spec/latest/
25 // This parser intentionally avoids the portion of JavaScript parsing
26 // that are not required to determine if code is valid asm.js code.
27 // * It is mostly one pass.
28 // * It bails out on unexpected input.
29 // * It assumes strict ordering insofar as permitted by asm.js validation rules.
30 // * It relies on a custom scanner that provides de-duped identifiers in two
31 // scopes (local + module wide).
32 class AsmJsParser {
33 public:
34 explicit AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script,
35 int start, int end);
36 bool Run();
37 const char* failure_message() const { return failure_message_.c_str(); }
38 int failure_location() const { return failure_location_; }
39 WasmModuleBuilder* module_builder() { return module_builder_; }
40 const AsmTyper::StdlibSet* stdlib_uses() const { return &stdlib_uses_; }
41
42 private:
43 // clang-format off
44 enum class VarKind {
45 kUnused,
46 kLocal,
47 kGlobal,
48 kSpecial,
49 kFunction,
50 kTable,
51 kImportedFunction,
52 #define V(_unused0, Name, _unused1, _unused2) kMath##Name,
53 STDLIB_MATH_FUNCTION_LIST(V)
54 #undef V
55 #define V(Name) kMath##Name,
56 STDLIB_MATH_VALUE_LIST(V)
57 #undef V
58 };
59 // clang-format on
60
61 struct FunctionImportInfo {
62 std::string name;
63 SignatureMap cache;
64 std::vector<uint32_t> cache_index;
65 };
66
67 struct VarInfo {
68 AsmType* type;
69 WasmFunctionBuilder* function_builder;
70 FunctionImportInfo* import;
71 int32_t mask;
72 uint32_t index;
73 VarKind kind;
74 bool mutable_variable;
75 bool function_defined;
76
77 VarInfo();
78 void DeclareGlobalImport(AsmType* type, uint32_t index);
79 void DeclareStdlibFunc(VarKind kind, AsmType* type);
80 };
81
82 struct GlobalImport {
83 std::string import_name;
84 uint32_t import_index;
85 uint32_t global_index;
86 bool needs_init;
87 };
88
89 enum class BlockKind { kRegular, kLoop, kOther };
90
91 struct BlockInfo {
92 BlockKind kind;
93 AsmJsScanner::token_t label;
94 };
95
96 Zone* zone_;
97 AsmJsScanner scanner_;
98 WasmModuleBuilder* module_builder_;
99 WasmFunctionBuilder* current_function_builder_;
100 AsmType* return_type_;
101 std::uintptr_t stack_limit_;
102 AsmTyper::StdlibSet stdlib_uses_;
103 std::list<FunctionImportInfo> function_import_info_;
104 ZoneVector<VarInfo> global_var_info_;
105 ZoneVector<VarInfo> local_var_info_;
106
107 int function_temp_locals_offset_;
108 int function_temp_locals_used_;
109
110 // Error Handling related
111 bool failed_;
112 std::string failure_message_;
113 int failure_location_;
114
115 // Module Related.
116 AsmJsScanner::token_t stdlib_name_;
117 AsmJsScanner::token_t foreign_name_;
118 AsmJsScanner::token_t heap_name_;
119
120 static const AsmJsScanner::token_t kTokenNone = 0;
121
122 // Track if parsing a heap assignment.
123 bool inside_heap_assignment_;
124 AsmType* heap_access_type_;
125
126 ZoneVector<BlockInfo> block_stack_;
127
128 // Types used for stdlib function and their set up.
129 AsmType* stdlib_dq2d_;
130 AsmType* stdlib_dqdq2d_;
131 AsmType* stdlib_fq2f_;
132 AsmType* stdlib_i2s_;
133 AsmType* stdlib_ii2s_;
134 AsmType* stdlib_minmax_;
135 AsmType* stdlib_abs_;
136 AsmType* stdlib_ceil_like_;
137 AsmType* stdlib_fround_;
138
139 // When making calls, the return type is needed to lookup signatures.
140 // For +callsite(..) or fround(callsite(..)) use this value to pass
141 // along the coercion.
142 AsmType* call_coercion_;
143
144 // Used to track the last label we've seen so it can be matched to later
145 // statements it's attached to.
146 AsmJsScanner::token_t pending_label_;
147
148 // Global imports.
149 // NOTE: Holds the strings referenced in wasm-module-builder for imports.
150 ZoneLinkedList<GlobalImport> global_imports_;
151
152 Zone* zone() { return zone_; }
153
154 inline bool Peek(AsmJsScanner::token_t token) {
155 return scanner_.Token() == token;
156 }
157
158 inline bool Check(AsmJsScanner::token_t token) {
159 if (scanner_.Token() == token) {
160 scanner_.Next();
161 return true;
162 } else {
163 return false;
164 }
165 }
166
167 inline bool CheckForZero() {
168 if (scanner_.IsUnsigned() && scanner_.AsUnsigned() == 0) {
169 scanner_.Next();
170 return true;
171 } else {
172 return false;
173 }
174 }
175
176 inline bool CheckForDouble(double* value) {
177 if (scanner_.IsDouble()) {
178 *value = scanner_.AsDouble();
179 scanner_.Next();
180 return true;
181 } else {
182 return false;
183 }
184 }
185
186 inline bool CheckForUnsigned(uint64_t* value) {
187 if (scanner_.IsUnsigned()) {
188 *value = scanner_.AsUnsigned();
189 scanner_.Next();
190 return true;
191 } else {
192 return false;
193 }
194 }
195
196 inline bool CheckForUnsignedBelow(uint64_t limit, uint64_t* value) {
197 if (scanner_.IsUnsigned() && scanner_.AsUnsigned() < limit) {
198 *value = scanner_.AsUnsigned();
199 scanner_.Next();
200 return true;
201 } else {
202 return false;
203 }
204 }
205
206 inline AsmJsScanner::token_t Consume() {
207 AsmJsScanner::token_t ret = scanner_.Token();
208 scanner_.Next();
209 return ret;
210 }
211
212 void SkipSemicolon();
213
214 VarInfo* GetVarInfo(AsmJsScanner::token_t token);
215 uint32_t VarIndex(VarInfo* info);
216 void DeclareGlobal(VarInfo* info, bool mutable_variable, AsmType* type,
217 ValueType vtype,
218 const WasmInitExpr& init = WasmInitExpr());
219
220 int32_t TempVariable(int i);
221
222 void AddGlobalImport(std::string name, AsmType* type, ValueType vtype,
223 bool mutable_variable, VarInfo* info);
224
225 // Use to set up block stack layers (including synthetic ones for if-else).
226 // Begin/Loop/End below are implemented with these plus code generation.
227 void BareBegin(BlockKind kind = BlockKind::kOther,
228 AsmJsScanner::token_t label = 0);
229 void BareEnd();
230 int FindContinueLabelDepth(AsmJsScanner::token_t label);
231 int FindBreakLabelDepth(AsmJsScanner::token_t label);
232
233 // Use to set up actual wasm blocks/loops.
234 void Begin(AsmJsScanner::token_t label = 0);
235 void Loop(AsmJsScanner::token_t label = 0);
236 void End();
237
238 void InitializeStdlibTypes();
239
240 FunctionSig* ConvertSignature(AsmType* return_type,
241 const std::vector<AsmType*>& params);
242
243 // 6.1 ValidateModule
244 void ValidateModule();
245 void ValidateModuleParameters();
246 void ValidateModuleVars();
247 void ValidateModuleVar(bool mutable_variable);
248 bool ValidateModuleVarImport(VarInfo* info, bool mutable_variable);
249 void ValidateModuleVarStdlib(VarInfo* info);
250 void ValidateModuleVarNewStdlib(VarInfo* info);
251 void ValidateModuleVarFloat(VarInfo* info, bool mutable_variable);
252
253 void ValidateExport(); // 6.2 ValidateExport
254 void ValidateFunctionTable(); // 6.3 ValidateFunctionTable
255 void ValidateFunction(); // 6.4 ValidateFunction
256 void ValidateFunctionParams(std::vector<AsmType*>* params);
257 void ValidateFunctionLocals(size_t param_count,
258 std::vector<ValueType>* locals);
259 void ValidateStatement(); // ValidateStatement
260 void Block(); // 6.5.1 Block
261 void ExpressionStatement(); // 6.5.2 ExpressionStatement
262 void EmptyStatement(); // 6.5.3 EmptyStatement
263 void IfStatement(); // 6.5.4 IfStatement
264 void ReturnStatement(); // 6.5.5 ReturnStatement
265 bool IterationStatement(); // 6.5.6 IterationStatement
266 void WhileStatement(); // 6.5.6 IterationStatement - while
267 void DoStatement(); // 6.5.6 IterationStatement - do
268 void ForStatement(); // 6.5.6 IterationStatement - for
269 void BreakStatement(); // 6.5.7 BreakStatement
270 void ContinueStatement(); // 6.5.8 ContinueStatement
271 void LabelledStatement(); // 6.5.9 LabelledStatement
272 void SwitchStatement(); // 6.5.10 SwitchStatement
273 void ValidateCase(); // 6.6. ValidateCase
274 void ValidateDefault(); // 6.7 ValidateDefault
275 AsmType* ValidateExpression(); // 6.8 ValidateExpression
276 AsmType* Expression(AsmType* expect); // 6.8.1 Expression
277 AsmType* NumericLiteral(); // 6.8.2 NumericLiteral
278 AsmType* Identifier(); // 6.8.3 Identifier
279 AsmType* CallExpression(); // 6.8.4 CallExpression
280 AsmType* MemberExpression(); // 6.8.5 MemberExpression
281 AsmType* AssignmentExpression(); // 6.8.6 AssignmentExpression
282 AsmType* UnaryExpression(); // 6.8.7 UnaryExpression
283 AsmType* MultiplicativeExpression(); // 6.8.8 MultaplicativeExpression
284 AsmType* AdditiveExpression(); // 6.8.9 AdditiveExpression
285 AsmType* ShiftExpression(); // 6.8.10 ShiftExpression
286 AsmType* RelationalExpression(); // 6.8.11 RelationalExpression
287 AsmType* EqualityExpression(); // 6.8.12 EqualityExpression
288 AsmType* BitwiseANDExpression(); // 6.8.13 BitwiseANDExpression
289 AsmType* BitwiseXORExpression(); // 6.8.14 BitwiseXORExpression
290 AsmType* BitwiseORExpression(); // 6.8.15 BitwiseORExpression
291 AsmType* ConditionalExpression(); // 6.8.16 ConditionalExpression
292 AsmType* ParenthesizedExpression(); // 6.8.17 ParenthesiedExpression
293 AsmType* ValidateCall(); // 6.9 ValidateCall
294 bool PeekCall(); // 6.9 ValidateCall - helper
295 void ValidateHeapAccess(); // 6.10 ValidateHeapAccess
296 void ValidateFloatCoercion(); // 6.11 ValidateFloatCoercion
297
298 void GatherCases(std::vector<int32_t>* cases);
299 };
300
301 } // namespace wasm
302 } // namespace internal
303 } // namespace v8
304 #endif
OLDNEW
« no previous file with comments | « src/asmjs/asm-js.cc ('k') | src/asmjs/asm-parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698