OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
6 | 6 |
7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 case WasmSection::Code::Memory: { | 144 case WasmSection::Code::Memory: { |
145 module->min_mem_pages = consume_u32v("min memory"); | 145 module->min_mem_pages = consume_u32v("min memory"); |
146 module->max_mem_pages = consume_u32v("max memory"); | 146 module->max_mem_pages = consume_u32v("max memory"); |
147 module->mem_export = consume_u8("export memory") != 0; | 147 module->mem_export = consume_u8("export memory") != 0; |
148 break; | 148 break; |
149 } | 149 } |
150 case WasmSection::Code::Signatures: { | 150 case WasmSection::Code::Signatures: { |
151 uint32_t signatures_count = consume_u32v("signatures count"); | 151 uint32_t signatures_count = consume_u32v("signatures count"); |
152 module->signatures.reserve(SafeReserve(signatures_count)); | 152 module->signatures.reserve(SafeReserve(signatures_count)); |
153 // Decode signatures. | 153 // Decode signatures. |
154 for (uint32_t i = 0; i < signatures_count; ++i) { | 154 for (uint32_t i = 0; ok() && i < signatures_count; ++i) { |
155 if (failed()) break; | |
156 TRACE("DecodeSignature[%d] module+%d\n", i, | 155 TRACE("DecodeSignature[%d] module+%d\n", i, |
157 static_cast<int>(pc_ - start_)); | 156 static_cast<int>(pc_ - start_)); |
158 FunctionSig* s = consume_sig(); | 157 FunctionSig* s = consume_sig(); |
159 module->signatures.push_back(s); | 158 module->signatures.push_back(s); |
160 } | 159 } |
161 break; | 160 break; |
162 } | 161 } |
163 case WasmSection::Code::FunctionSignatures: { | 162 case WasmSection::Code::FunctionSignatures: { |
164 uint32_t functions_count = consume_u32v("functions count"); | 163 uint32_t functions_count = consume_u32v("functions count"); |
165 module->functions.reserve(SafeReserve(functions_count)); | 164 module->functions.reserve(SafeReserve(functions_count)); |
166 for (uint32_t i = 0; i < functions_count; ++i) { | 165 for (uint32_t i = 0; ok() && i < functions_count; ++i) { |
167 if (failed()) break; | |
168 module->functions.push_back({nullptr, // sig | 166 module->functions.push_back({nullptr, // sig |
169 i, // func_index | 167 i, // func_index |
170 0, // sig_index | 168 0, // sig_index |
171 0, // name_offset | 169 0, // name_offset |
172 0, // name_length | 170 0, // name_length |
173 0, // code_start_offset | 171 0, // code_start_offset |
174 0}); // code_end_offset | 172 0}); // code_end_offset |
175 WasmFunction* function = &module->functions.back(); | 173 WasmFunction* function = &module->functions.back(); |
176 function->sig_index = consume_sig_index(module, &function->sig); | 174 function->sig_index = consume_sig_index(module, &function->sig); |
177 } | 175 } |
178 break; | 176 break; |
179 } | 177 } |
180 case WasmSection::Code::FunctionBodies: { | 178 case WasmSection::Code::FunctionBodies: { |
181 const byte* pos = pc_; | 179 const byte* pos = pc_; |
182 uint32_t functions_count = consume_u32v("functions count"); | 180 uint32_t functions_count = consume_u32v("functions count"); |
183 if (functions_count != module->functions.size()) { | 181 if (functions_count != module->functions.size()) { |
184 error(pos, pos, "function body count %u mismatch (%u expected)", | 182 error(pos, pos, "function body count %u mismatch (%u expected)", |
185 functions_count, | 183 functions_count, |
186 static_cast<uint32_t>(module->functions.size())); | 184 static_cast<uint32_t>(module->functions.size())); |
187 break; | 185 break; |
188 } | 186 } |
189 for (uint32_t i = 0; i < functions_count; ++i) { | 187 for (uint32_t i = 0; ok() && i < functions_count; ++i) { |
190 WasmFunction* function = &module->functions[i]; | 188 WasmFunction* function = &module->functions[i]; |
191 uint32_t size = consume_u32v("body size"); | 189 uint32_t size = consume_u32v("body size"); |
192 function->code_start_offset = pc_offset(); | 190 function->code_start_offset = pc_offset(); |
193 function->code_end_offset = pc_offset() + size; | 191 function->code_end_offset = pc_offset() + size; |
194 | 192 |
195 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 193 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
196 size); | 194 size); |
197 pc_ += size; | 195 pc_ += size; |
198 if (pc_ > limit_) { | 196 if (pc_ > limit_) { |
199 error(pc_, "function body extends beyond end of file"); | 197 error(pc_, "function body extends beyond end of file"); |
200 } | 198 } |
201 } | 199 } |
202 break; | 200 break; |
203 } | 201 } |
204 case WasmSection::Code::Names: { | 202 case WasmSection::Code::Names: { |
205 const byte* pos = pc_; | 203 const byte* pos = pc_; |
206 uint32_t functions_count = consume_u32v("functions count"); | 204 uint32_t functions_count = consume_u32v("functions count"); |
207 if (functions_count != module->functions.size()) { | 205 if (functions_count != module->functions.size()) { |
208 error(pos, pos, "function name count %u mismatch (%u expected)", | 206 error(pos, pos, "function name count %u mismatch (%u expected)", |
209 functions_count, | 207 functions_count, |
210 static_cast<uint32_t>(module->functions.size())); | 208 static_cast<uint32_t>(module->functions.size())); |
211 break; | 209 break; |
212 } | 210 } |
213 | 211 |
214 for (uint32_t i = 0; i < functions_count; ++i) { | 212 for (uint32_t i = 0; ok() && i < functions_count; ++i) { |
215 WasmFunction* function = &module->functions[i]; | 213 WasmFunction* function = &module->functions[i]; |
216 function->name_offset = | 214 function->name_offset = |
217 consume_string(&function->name_length, false); | 215 consume_string(&function->name_length, false); |
218 | 216 |
219 uint32_t local_names_count = consume_u32v("local names count"); | 217 uint32_t local_names_count = consume_u32v("local names count"); |
220 for (uint32_t j = 0; j < local_names_count; j++) { | 218 for (uint32_t j = 0; ok() && j < local_names_count; j++) { |
221 uint32_t unused = 0; | 219 uint32_t unused = 0; |
222 uint32_t offset = consume_string(&unused, false); | 220 uint32_t offset = consume_string(&unused, false); |
223 USE(unused); | 221 USE(unused); |
224 USE(offset); | 222 USE(offset); |
225 } | 223 } |
226 } | 224 } |
227 break; | 225 break; |
228 } | 226 } |
229 case WasmSection::Code::Globals: { | 227 case WasmSection::Code::Globals: { |
230 uint32_t globals_count = consume_u32v("globals count"); | 228 uint32_t globals_count = consume_u32v("globals count"); |
231 module->globals.reserve(SafeReserve(globals_count)); | 229 module->globals.reserve(SafeReserve(globals_count)); |
232 // Decode globals. | 230 // Decode globals. |
233 for (uint32_t i = 0; i < globals_count; ++i) { | 231 for (uint32_t i = 0; ok() && i < globals_count; ++i) { |
234 if (failed()) break; | |
235 TRACE("DecodeGlobal[%d] module+%d\n", i, | 232 TRACE("DecodeGlobal[%d] module+%d\n", i, |
236 static_cast<int>(pc_ - start_)); | 233 static_cast<int>(pc_ - start_)); |
237 // Add an uninitialized global and pass a pointer to it. | 234 // Add an uninitialized global and pass a pointer to it. |
238 module->globals.push_back({0, 0, kAstStmt, 0, false}); | 235 module->globals.push_back({0, 0, kAstStmt, 0, false}); |
239 WasmGlobal* global = &module->globals.back(); | 236 WasmGlobal* global = &module->globals.back(); |
240 DecodeGlobalInModule(global); | 237 DecodeGlobalInModule(global); |
241 } | 238 } |
242 break; | 239 break; |
243 } | 240 } |
244 case WasmSection::Code::DataSegments: { | 241 case WasmSection::Code::DataSegments: { |
245 uint32_t data_segments_count = consume_u32v("data segments count"); | 242 uint32_t data_segments_count = consume_u32v("data segments count"); |
246 module->data_segments.reserve(SafeReserve(data_segments_count)); | 243 module->data_segments.reserve(SafeReserve(data_segments_count)); |
247 // Decode data segments. | 244 // Decode data segments. |
248 for (uint32_t i = 0; i < data_segments_count; ++i) { | 245 for (uint32_t i = 0; ok() && i < data_segments_count; ++i) { |
249 if (failed()) break; | |
250 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 246 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
251 static_cast<int>(pc_ - start_)); | 247 static_cast<int>(pc_ - start_)); |
252 module->data_segments.push_back({0, // dest_addr | 248 module->data_segments.push_back({0, // dest_addr |
253 0, // source_offset | 249 0, // source_offset |
254 0, // source_size | 250 0, // source_size |
255 false}); // init | 251 false}); // init |
256 WasmDataSegment* segment = &module->data_segments.back(); | 252 WasmDataSegment* segment = &module->data_segments.back(); |
257 DecodeDataSegmentInModule(module, segment); | 253 DecodeDataSegmentInModule(module, segment); |
258 } | 254 } |
259 break; | 255 break; |
260 } | 256 } |
261 case WasmSection::Code::FunctionTable: { | 257 case WasmSection::Code::FunctionTable: { |
262 // An indirect function table requires functions first. | 258 // An indirect function table requires functions first. |
263 CheckForFunctions(module, section); | 259 CheckForFunctions(module, section); |
264 // Assume only one table for now. | 260 // Assume only one table for now. |
265 static const uint32_t kSupportedTableCount = 1; | 261 static const uint32_t kSupportedTableCount = 1; |
266 module->function_tables.reserve(SafeReserve(kSupportedTableCount)); | 262 module->function_tables.reserve(SafeReserve(kSupportedTableCount)); |
267 // Decode function table. | 263 // Decode function table. |
268 for (uint32_t i = 0; i < kSupportedTableCount; ++i) { | 264 for (uint32_t i = 0; ok() && i < kSupportedTableCount; ++i) { |
269 if (failed()) break; | |
270 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 265 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
271 static_cast<int>(pc_ - start_)); | 266 static_cast<int>(pc_ - start_)); |
272 module->function_tables.push_back({0, 0, std::vector<uint16_t>()}); | 267 module->function_tables.push_back({0, 0, std::vector<uint16_t>()}); |
273 DecodeFunctionTableInModule(module, &module->function_tables[i]); | 268 DecodeFunctionTableInModule(module, &module->function_tables[i]); |
274 } | 269 } |
275 break; | 270 break; |
276 } | 271 } |
277 case WasmSection::Code::StartFunction: { | 272 case WasmSection::Code::StartFunction: { |
278 // Declares a start function for a module. | 273 // Declares a start function for a module. |
279 CheckForFunctions(module, section); | 274 CheckForFunctions(module, section); |
280 if (module->start_function_index >= 0) { | 275 if (module->start_function_index >= 0) { |
281 error("start function already declared"); | 276 error("start function already declared"); |
282 break; | 277 break; |
283 } | 278 } |
284 WasmFunction* func; | 279 WasmFunction* func; |
285 const byte* pos = pc_; | 280 const byte* pos = pc_; |
286 module->start_function_index = consume_func_index(module, &func); | 281 module->start_function_index = consume_func_index(module, &func); |
287 if (func && func->sig->parameter_count() > 0) { | 282 if (func && func->sig->parameter_count() > 0) { |
288 error(pos, "invalid start function: non-zero parameter count"); | 283 error(pos, "invalid start function: non-zero parameter count"); |
289 break; | 284 break; |
290 } | 285 } |
291 break; | 286 break; |
292 } | 287 } |
293 case WasmSection::Code::ImportTable: { | 288 case WasmSection::Code::ImportTable: { |
294 uint32_t import_table_count = consume_u32v("import table count"); | 289 uint32_t import_table_count = consume_u32v("import table count"); |
295 module->import_table.reserve(SafeReserve(import_table_count)); | 290 module->import_table.reserve(SafeReserve(import_table_count)); |
296 // Decode import table. | 291 // Decode import table. |
297 for (uint32_t i = 0; i < import_table_count; ++i) { | 292 for (uint32_t i = 0; ok() && i < import_table_count; ++i) { |
298 if (failed()) break; | |
299 TRACE("DecodeImportTable[%d] module+%d\n", i, | 293 TRACE("DecodeImportTable[%d] module+%d\n", i, |
300 static_cast<int>(pc_ - start_)); | 294 static_cast<int>(pc_ - start_)); |
301 | 295 |
302 module->import_table.push_back({nullptr, // sig | 296 module->import_table.push_back({nullptr, // sig |
303 0, // sig_index | 297 0, // sig_index |
304 0, // module_name_offset | 298 0, // module_name_offset |
305 0, // module_name_length | 299 0, // module_name_length |
306 0, // function_name_offset | 300 0, // function_name_offset |
307 0}); // function_name_length | 301 0}); // function_name_length |
308 WasmImport* import = &module->import_table.back(); | 302 WasmImport* import = &module->import_table.back(); |
309 | 303 |
310 import->sig_index = consume_sig_index(module, &import->sig); | 304 import->sig_index = consume_sig_index(module, &import->sig); |
311 const byte* pos = pc_; | 305 const byte* pos = pc_; |
312 import->module_name_offset = | 306 import->module_name_offset = |
313 consume_string(&import->module_name_length, true); | 307 consume_string(&import->module_name_length, true); |
314 if (import->module_name_length == 0) { | 308 if (import->module_name_length == 0) { |
315 error(pos, "import module name cannot be NULL"); | 309 error(pos, "import module name cannot be NULL"); |
316 } | 310 } |
317 import->function_name_offset = | 311 import->function_name_offset = |
318 consume_string(&import->function_name_length, true); | 312 consume_string(&import->function_name_length, true); |
319 } | 313 } |
320 break; | 314 break; |
321 } | 315 } |
322 case WasmSection::Code::ExportTable: { | 316 case WasmSection::Code::ExportTable: { |
323 // Declares an export table. | 317 // Declares an export table. |
324 CheckForFunctions(module, section); | 318 CheckForFunctions(module, section); |
325 uint32_t export_table_count = consume_u32v("export table count"); | 319 uint32_t export_table_count = consume_u32v("export table count"); |
326 module->export_table.reserve(SafeReserve(export_table_count)); | 320 module->export_table.reserve(SafeReserve(export_table_count)); |
327 // Decode export table. | 321 // Decode export table. |
328 for (uint32_t i = 0; i < export_table_count; ++i) { | 322 for (uint32_t i = 0; ok() && i < export_table_count; ++i) { |
329 if (failed()) break; | |
330 TRACE("DecodeExportTable[%d] module+%d\n", i, | 323 TRACE("DecodeExportTable[%d] module+%d\n", i, |
331 static_cast<int>(pc_ - start_)); | 324 static_cast<int>(pc_ - start_)); |
332 | 325 |
333 module->export_table.push_back({0, // func_index | 326 module->export_table.push_back({0, // func_index |
334 0, // name_offset | 327 0, // name_offset |
335 0}); // name_length | 328 0}); // name_length |
336 WasmExport* exp = &module->export_table.back(); | 329 WasmExport* exp = &module->export_table.back(); |
337 | 330 |
338 WasmFunction* func; | 331 WasmFunction* func; |
339 exp->func_index = consume_func_index(module, &func); | 332 exp->func_index = consume_func_index(module, &func); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 // Decodes a single function table inside a module starting at {pc_}. | 504 // Decodes a single function table inside a module starting at {pc_}. |
512 void DecodeFunctionTableInModule(WasmModule* module, | 505 void DecodeFunctionTableInModule(WasmModule* module, |
513 WasmIndirectFunctionTable* table) { | 506 WasmIndirectFunctionTable* table) { |
514 table->size = consume_u32v("function table entry count"); | 507 table->size = consume_u32v("function table entry count"); |
515 table->max_size = table->size; | 508 table->max_size = table->size; |
516 | 509 |
517 if (table->max_size != table->size) { | 510 if (table->max_size != table->size) { |
518 error("invalid table maximum size"); | 511 error("invalid table maximum size"); |
519 } | 512 } |
520 | 513 |
521 for (uint32_t i = 0; i < table->size; ++i) { | 514 for (uint32_t i = 0; ok() && i < table->size; ++i) { |
522 uint16_t index = consume_u32v(); | 515 uint16_t index = consume_u32v(); |
523 if (index >= module->functions.size()) { | 516 if (index >= module->functions.size()) { |
524 error(pc_ - sizeof(index), "invalid function index"); | 517 error(pc_ - sizeof(index), "invalid function index"); |
525 break; | 518 break; |
526 } | 519 } |
527 table->values.push_back(index); | 520 table->values.push_back(index); |
528 } | 521 } |
529 } | 522 } |
530 | 523 |
531 // Calculate individual global offsets and total size of globals table. | 524 // Calculate individual global offsets and total size of globals table. |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 decoder.consume_bytes(size); | 814 decoder.consume_bytes(size); |
822 } | 815 } |
823 if (decoder.more()) decoder.error("unexpected additional bytes"); | 816 if (decoder.more()) decoder.error("unexpected additional bytes"); |
824 | 817 |
825 return decoder.toResult(std::move(table)); | 818 return decoder.toResult(std::move(table)); |
826 } | 819 } |
827 | 820 |
828 } // namespace wasm | 821 } // namespace wasm |
829 } // namespace internal | 822 } // namespace internal |
830 } // namespace v8 | 823 } // namespace v8 |
OLD | NEW |