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/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
6 #include "src/objects.h" | 6 #include "src/objects.h" |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/wasm/decoder.h" | 9 #include "src/wasm/decoder.h" |
10 #include "src/wasm/module-decoder.h" | 10 #include "src/wasm/module-decoder.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 case kDeclGlobals: { | 155 case kDeclGlobals: { |
156 int length; | 156 int length; |
157 uint32_t globals_count = consume_u32v(&length, "globals count"); | 157 uint32_t globals_count = consume_u32v(&length, "globals count"); |
158 module->globals.reserve(SafeReserve(globals_count)); | 158 module->globals.reserve(SafeReserve(globals_count)); |
159 // Decode globals. | 159 // Decode globals. |
160 for (uint32_t i = 0; i < globals_count; i++) { | 160 for (uint32_t i = 0; i < globals_count; i++) { |
161 if (failed()) break; | 161 if (failed()) break; |
162 TRACE("DecodeGlobal[%d] module+%d\n", i, | 162 TRACE("DecodeGlobal[%d] module+%d\n", i, |
163 static_cast<int>(pc_ - start_)); | 163 static_cast<int>(pc_ - start_)); |
164 module->globals.push_back({0, MachineType::Int32(), 0, false}); | 164 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
165 WasmGlobal* global = &module->globals.back(); | 165 WasmGlobal* global = &module->globals.back(); |
166 DecodeGlobalInModule(global); | 166 DecodeGlobalInModule(global); |
167 } | 167 } |
168 break; | 168 break; |
169 } | 169 } |
170 case kDeclDataSegments: { | 170 case kDeclDataSegments: { |
171 int length; | 171 int length; |
172 uint32_t data_segments_count = | 172 uint32_t data_segments_count = |
173 consume_u32v(&length, "data segments count"); | 173 consume_u32v(&length, "data segments count"); |
174 module->data_segments.reserve(SafeReserve(data_segments_count)); | 174 module->data_segments.reserve(SafeReserve(data_segments_count)); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 | 245 |
246 const byte* sigpos = pc_; | 246 const byte* sigpos = pc_; |
247 import->sig_index = consume_u32v(&length, "signature index"); | 247 import->sig_index = consume_u32v(&length, "signature index"); |
248 | 248 |
249 if (import->sig_index >= module->signatures.size()) { | 249 if (import->sig_index >= module->signatures.size()) { |
250 error(sigpos, "invalid signature index"); | 250 error(sigpos, "invalid signature index"); |
251 } else { | 251 } else { |
252 import->sig = module->signatures[import->sig_index]; | 252 import->sig = module->signatures[import->sig_index]; |
253 } | 253 } |
254 const byte* pos = pc_; | 254 const byte* pos = pc_; |
255 import->module_name_offset = consume_string("import module name"); | 255 import->module_name_offset = consume_string( |
256 if (import->module_name_offset == 0) { | 256 &import->module_name_length, "import module name"); |
| 257 if (import->module_name_length == 0) { |
257 error(pos, "import module name cannot be NULL"); | 258 error(pos, "import module name cannot be NULL"); |
258 } | 259 } |
259 import->function_name_offset = | 260 import->function_name_offset = consume_string( |
260 consume_string("import function name"); | 261 &import->function_name_length, "import function name"); |
261 } | 262 } |
262 break; | 263 break; |
263 } | 264 } |
264 case kDeclExportTable: { | 265 case kDeclExportTable: { |
265 // Declares an export table. | 266 // Declares an export table. |
266 CheckForPreviousSection(sections, kDeclFunctions, true); | 267 CheckForPreviousSection(sections, kDeclFunctions, true); |
267 int length; | 268 int length; |
268 uint32_t export_table_count = | 269 uint32_t export_table_count = |
269 consume_u32v(&length, "export table count"); | 270 consume_u32v(&length, "export table count"); |
270 module->export_table.reserve(SafeReserve(export_table_count)); | 271 module->export_table.reserve(SafeReserve(export_table_count)); |
271 // Decode export table. | 272 // Decode export table. |
272 for (uint32_t i = 0; i < export_table_count; i++) { | 273 for (uint32_t i = 0; i < export_table_count; i++) { |
273 if (failed()) break; | 274 if (failed()) break; |
274 TRACE("DecodeExportTable[%d] module+%d\n", i, | 275 TRACE("DecodeExportTable[%d] module+%d\n", i, |
275 static_cast<int>(pc_ - start_)); | 276 static_cast<int>(pc_ - start_)); |
276 | 277 |
277 module->export_table.push_back({0, 0}); | 278 module->export_table.push_back({0, 0}); |
278 WasmExport* exp = &module->export_table.back(); | 279 WasmExport* exp = &module->export_table.back(); |
279 | 280 |
280 const byte* sigpos = pc_; | 281 const byte* sigpos = pc_; |
281 exp->func_index = consume_u32v(&length, "function index"); | 282 exp->func_index = consume_u32v(&length, "function index"); |
282 if (exp->func_index >= module->functions.size()) { | 283 if (exp->func_index >= module->functions.size()) { |
283 error(sigpos, sigpos, | 284 error(sigpos, sigpos, |
284 "function index %u out of bounds (%d functions)", | 285 "function index %u out of bounds (%d functions)", |
285 exp->func_index, | 286 exp->func_index, |
286 static_cast<int>(module->functions.size())); | 287 static_cast<int>(module->functions.size())); |
287 } | 288 } |
288 exp->name_offset = consume_string("export name"); | 289 exp->name_offset = consume_string(&exp->name_length, "export name"); |
289 } | 290 } |
290 break; | 291 break; |
291 } | 292 } |
292 case kMaxModuleSectionCode: | 293 case kMaxModuleSectionCode: |
293 UNREACHABLE(); // Already skipped unknown sections. | 294 UNREACHABLE(); // Already skipped unknown sections. |
294 } | 295 } |
295 } | 296 } |
296 | 297 |
297 return toResult(module); | 298 return toResult(module); |
298 } | 299 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 error(pc_ - 1, nullptr, "%s section already present", name); | 338 error(pc_ - 1, nullptr, "%s section already present", name); |
338 } | 339 } |
339 } | 340 } |
340 | 341 |
341 // Decodes a single anonymous function starting at {start_}. | 342 // Decodes a single anonymous function starting at {start_}. |
342 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 343 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
343 WasmFunction* function) { | 344 WasmFunction* function) { |
344 pc_ = start_; | 345 pc_ = start_; |
345 function->sig = consume_sig(); // read signature | 346 function->sig = consume_sig(); // read signature |
346 function->name_offset = 0; // ---- name | 347 function->name_offset = 0; // ---- name |
| 348 function->name_length = 0; // ---- name length |
347 function->code_start_offset = off(pc_); // ---- code start | 349 function->code_start_offset = off(pc_); // ---- code start |
348 function->code_end_offset = off(limit_); // ---- code end | 350 function->code_end_offset = off(limit_); // ---- code end |
349 function->exported = false; // ---- exported | 351 function->exported = false; // ---- exported |
350 function->external = false; // ---- external | 352 function->external = false; // ---- external |
351 | 353 |
352 if (ok()) VerifyFunctionBody(0, module_env, function); | 354 if (ok()) VerifyFunctionBody(0, module_env, function); |
353 | 355 |
354 FunctionResult result; | 356 FunctionResult result; |
355 result.CopyFrom(result_); // Copy error code and location. | 357 result.CopyFrom(result_); // Copy error code and location. |
356 result.val = function; | 358 result.val = function; |
357 return result; | 359 return result; |
358 } | 360 } |
359 | 361 |
360 // Decodes a single function signature at {start}. | 362 // Decodes a single function signature at {start}. |
361 FunctionSig* DecodeFunctionSignature(const byte* start) { | 363 FunctionSig* DecodeFunctionSignature(const byte* start) { |
362 pc_ = start; | 364 pc_ = start; |
363 FunctionSig* result = consume_sig(); | 365 FunctionSig* result = consume_sig(); |
364 return ok() ? result : nullptr; | 366 return ok() ? result : nullptr; |
365 } | 367 } |
366 | 368 |
367 private: | 369 private: |
368 Zone* module_zone; | 370 Zone* module_zone; |
369 ModuleResult result_; | 371 ModuleResult result_; |
370 ModuleOrigin origin_; | 372 ModuleOrigin origin_; |
371 | 373 |
372 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } | 374 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } |
373 | 375 |
374 // Decodes a single global entry inside a module starting at {pc_}. | 376 // Decodes a single global entry inside a module starting at {pc_}. |
375 void DecodeGlobalInModule(WasmGlobal* global) { | 377 void DecodeGlobalInModule(WasmGlobal* global) { |
376 global->name_offset = consume_string("global name"); | 378 global->name_offset = consume_string(&global->name_length, "global name"); |
377 global->type = mem_type(); | 379 global->type = mem_type(); |
378 global->offset = 0; | 380 global->offset = 0; |
379 global->exported = consume_u8("exported") != 0; | 381 global->exported = consume_u8("exported") != 0; |
380 } | 382 } |
381 | 383 |
382 // Decodes a single function entry inside a module starting at {pc_}. | 384 // Decodes a single function entry inside a module starting at {pc_}. |
383 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function, | 385 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function, |
384 bool verify_body = true) { | 386 bool verify_body = true) { |
385 byte decl_bits = consume_u8("function decl"); | 387 byte decl_bits = consume_u8("function decl"); |
386 | 388 |
387 const byte* sigpos = pc_; | 389 const byte* sigpos = pc_; |
388 function->sig_index = consume_u16("signature index"); | 390 function->sig_index = consume_u16("signature index"); |
389 | 391 |
390 if (function->sig_index >= module->signatures.size()) { | 392 if (function->sig_index >= module->signatures.size()) { |
391 return error(sigpos, "invalid signature index"); | 393 return error(sigpos, "invalid signature index"); |
392 } else { | 394 } else { |
393 function->sig = module->signatures[function->sig_index]; | 395 function->sig = module->signatures[function->sig_index]; |
394 } | 396 } |
395 | 397 |
396 TRACE(" +%d <function attributes:%s%s%s%s%s>\n", | 398 TRACE(" +%d <function attributes:%s%s%s%s%s>\n", |
397 static_cast<int>(pc_ - start_), | 399 static_cast<int>(pc_ - start_), |
398 decl_bits & kDeclFunctionName ? " name" : "", | 400 decl_bits & kDeclFunctionName ? " name" : "", |
399 decl_bits & kDeclFunctionImport ? " imported" : "", | 401 decl_bits & kDeclFunctionImport ? " imported" : "", |
400 decl_bits & kDeclFunctionLocals ? " locals" : "", | 402 decl_bits & kDeclFunctionLocals ? " locals" : "", |
401 decl_bits & kDeclFunctionExport ? " exported" : "", | 403 decl_bits & kDeclFunctionExport ? " exported" : "", |
402 (decl_bits & kDeclFunctionImport) == 0 ? " body" : ""); | 404 (decl_bits & kDeclFunctionImport) == 0 ? " body" : ""); |
403 | 405 |
404 if (decl_bits & kDeclFunctionName) { | 406 if (decl_bits & kDeclFunctionName) { |
405 function->name_offset = consume_string("function name"); | 407 function->name_offset = |
| 408 consume_string(&function->name_length, "function name"); |
406 } | 409 } |
407 | 410 |
408 function->exported = decl_bits & kDeclFunctionExport; | 411 function->exported = decl_bits & kDeclFunctionExport; |
409 | 412 |
410 // Imported functions have no locals or body. | 413 // Imported functions have no locals or body. |
411 if (decl_bits & kDeclFunctionImport) { | 414 if (decl_bits & kDeclFunctionImport) { |
412 function->external = true; | 415 function->external = true; |
413 return; | 416 return; |
414 } | 417 } |
415 | 418 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 // Reads a single 32-bit unsigned integer interpreted as an offset, checking | 501 // Reads a single 32-bit unsigned integer interpreted as an offset, checking |
499 // the offset is within bounds and advances. | 502 // the offset is within bounds and advances. |
500 uint32_t consume_offset(const char* name = nullptr) { | 503 uint32_t consume_offset(const char* name = nullptr) { |
501 uint32_t offset = consume_u32(name ? name : "offset"); | 504 uint32_t offset = consume_u32(name ? name : "offset"); |
502 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 505 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
503 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 506 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
504 } | 507 } |
505 return offset; | 508 return offset; |
506 } | 509 } |
507 | 510 |
508 // Reads a single 32-bit unsigned integer interpreted as an offset into the | 511 // Reads a length-prefixed string, checking that it is within bounds. Returns |
509 // data and validating the string there and advances. | 512 // the offset of the string, and the length as an out parameter. |
510 uint32_t consume_string(const char* name = nullptr) { | 513 uint32_t consume_string(uint32_t* length, const char* name = nullptr) { |
511 // TODO(titzer): validate string | 514 int varint_length; |
512 return consume_offset(name ? name : "string"); | 515 *length = consume_u32v(&varint_length, "string length"); |
| 516 uint32_t offset = static_cast<uint32_t>(pc_ - start_); |
| 517 consume_bytes(*length); |
| 518 return offset; |
513 } | 519 } |
514 | 520 |
515 // Reads a single 8-bit integer, interpreting it as a local type. | 521 // Reads a single 8-bit integer, interpreting it as a local type. |
516 LocalType consume_local_type() { | 522 LocalType consume_local_type() { |
517 byte val = consume_u8("local type"); | 523 byte val = consume_u8("local type"); |
518 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 524 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
519 switch (t) { | 525 switch (t) { |
520 case kLocalVoid: | 526 case kLocalVoid: |
521 return kAstStmt; | 527 return kAstStmt; |
522 case kLocalI32: | 528 case kLocalI32: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 if (function_start > function_end) return FunctionError("start > end"); | 642 if (function_start > function_end) return FunctionError("start > end"); |
637 if (size > kMaxFunctionSize) | 643 if (size > kMaxFunctionSize) |
638 return FunctionError("size > maximum function size"); | 644 return FunctionError("size > maximum function size"); |
639 WasmFunction* function = new WasmFunction(); | 645 WasmFunction* function = new WasmFunction(); |
640 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 646 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
641 return decoder.DecodeSingleFunction(module_env, function); | 647 return decoder.DecodeSingleFunction(module_env, function); |
642 } | 648 } |
643 } // namespace wasm | 649 } // namespace wasm |
644 } // namespace internal | 650 } // namespace internal |
645 } // namespace v8 | 651 } // namespace v8 |
OLD | NEW |