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

Side by Side Diff: src/wasm/module-decoder.cc

Issue 1781523002: [wasm] All strings are length-prefixed and inline (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: comment Created 4 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/wasm/encoder.cc ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/wasm/encoder.cc ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698