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

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

Issue 2049513003: [wasm] Support undefined indirect table entries, behind a flag. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Replaced instances of "i++" with "++i". Created 4 years, 6 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
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/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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 module->min_mem_pages = consume_u32v(&length, "min memory"); 150 module->min_mem_pages = consume_u32v(&length, "min memory");
151 module->max_mem_pages = consume_u32v(&length, "max memory"); 151 module->max_mem_pages = consume_u32v(&length, "max memory");
152 module->mem_export = consume_u8("export memory") != 0; 152 module->mem_export = consume_u8("export memory") != 0;
153 break; 153 break;
154 } 154 }
155 case WasmSection::Code::Signatures: { 155 case WasmSection::Code::Signatures: {
156 int length; 156 int length;
157 uint32_t signatures_count = consume_u32v(&length, "signatures count"); 157 uint32_t signatures_count = consume_u32v(&length, "signatures count");
158 module->signatures.reserve(SafeReserve(signatures_count)); 158 module->signatures.reserve(SafeReserve(signatures_count));
159 // Decode signatures. 159 // Decode signatures.
160 for (uint32_t i = 0; i < signatures_count; i++) { 160 for (uint32_t i = 0; i < signatures_count; ++i) {
161 if (failed()) break; 161 if (failed()) break;
162 TRACE("DecodeSignature[%d] module+%d\n", i, 162 TRACE("DecodeSignature[%d] module+%d\n", i,
163 static_cast<int>(pc_ - start_)); 163 static_cast<int>(pc_ - start_));
164 FunctionSig* s = consume_sig(); 164 FunctionSig* s = consume_sig();
165 module->signatures.push_back(s); 165 module->signatures.push_back(s);
166 } 166 }
167 break; 167 break;
168 } 168 }
169 case WasmSection::Code::FunctionSignatures: { 169 case WasmSection::Code::FunctionSignatures: {
170 int length; 170 int length;
171 uint32_t functions_count = consume_u32v(&length, "functions count"); 171 uint32_t functions_count = consume_u32v(&length, "functions count");
172 module->functions.reserve(SafeReserve(functions_count)); 172 module->functions.reserve(SafeReserve(functions_count));
173 for (uint32_t i = 0; i < functions_count; i++) { 173 for (uint32_t i = 0; i < functions_count; ++i) {
174 module->functions.push_back({nullptr, // sig 174 module->functions.push_back({nullptr, // sig
175 i, // func_index 175 i, // func_index
176 0, // sig_index 176 0, // sig_index
177 0, // name_offset 177 0, // name_offset
178 0, // name_length 178 0, // name_length
179 0, // code_start_offset 179 0, // code_start_offset
180 0}); // code_end_offset 180 0}); // code_end_offset
181 WasmFunction* function = &module->functions.back(); 181 WasmFunction* function = &module->functions.back();
182 function->sig_index = consume_sig_index(module, &function->sig); 182 function->sig_index = consume_sig_index(module, &function->sig);
183 } 183 }
184 break; 184 break;
185 } 185 }
186 case WasmSection::Code::FunctionBodies: { 186 case WasmSection::Code::FunctionBodies: {
187 int length; 187 int length;
188 const byte* pos = pc_; 188 const byte* pos = pc_;
189 uint32_t functions_count = consume_u32v(&length, "functions count"); 189 uint32_t functions_count = consume_u32v(&length, "functions count");
190 if (functions_count != module->functions.size()) { 190 if (functions_count != module->functions.size()) {
191 error(pos, pos, "function body count %u mismatch (%u expected)", 191 error(pos, pos, "function body count %u mismatch (%u expected)",
192 functions_count, 192 functions_count,
193 static_cast<uint32_t>(module->functions.size())); 193 static_cast<uint32_t>(module->functions.size()));
194 break; 194 break;
195 } 195 }
196 for (uint32_t i = 0; i < functions_count; i++) { 196 for (uint32_t i = 0; i < functions_count; ++i) {
197 WasmFunction* function = &module->functions[i]; 197 WasmFunction* function = &module->functions[i];
198 int length; 198 int length;
199 uint32_t size = consume_u32v(&length, "body size"); 199 uint32_t size = consume_u32v(&length, "body size");
200 function->code_start_offset = pc_offset(); 200 function->code_start_offset = pc_offset();
201 function->code_end_offset = pc_offset() + size; 201 function->code_end_offset = pc_offset() + size;
202 202
203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", 203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body",
204 size); 204 size);
205 pc_ += size; 205 pc_ += size;
206 if (pc_ > limit_) { 206 if (pc_ > limit_) {
207 error(pc_, "function body extends beyond end of file"); 207 error(pc_, "function body extends beyond end of file");
208 } 208 }
209 } 209 }
210 break; 210 break;
211 } 211 }
212 case WasmSection::Code::Names: { 212 case WasmSection::Code::Names: {
213 int length; 213 int length;
214 const byte* pos = pc_; 214 const byte* pos = pc_;
215 uint32_t functions_count = consume_u32v(&length, "functions count"); 215 uint32_t functions_count = consume_u32v(&length, "functions count");
216 if (functions_count != module->functions.size()) { 216 if (functions_count != module->functions.size()) {
217 error(pos, pos, "function name count %u mismatch (%u expected)", 217 error(pos, pos, "function name count %u mismatch (%u expected)",
218 functions_count, 218 functions_count,
219 static_cast<uint32_t>(module->functions.size())); 219 static_cast<uint32_t>(module->functions.size()));
220 break; 220 break;
221 } 221 }
222 222
223 for (uint32_t i = 0; i < functions_count; i++) { 223 for (uint32_t i = 0; i < functions_count; ++i) {
224 WasmFunction* function = &module->functions[i]; 224 WasmFunction* function = &module->functions[i];
225 function->name_offset = 225 function->name_offset =
226 consume_string(&function->name_length, false); 226 consume_string(&function->name_length, false);
227 227
228 uint32_t local_names_count = 228 uint32_t local_names_count =
229 consume_u32v(&length, "local names count"); 229 consume_u32v(&length, "local names count");
230 for (uint32_t j = 0; j < local_names_count; j++) { 230 for (uint32_t j = 0; j < local_names_count; j++) {
231 uint32_t unused = 0; 231 uint32_t unused = 0;
232 uint32_t offset = consume_string(&unused, false); 232 uint32_t offset = consume_string(&unused, false);
233 USE(unused); 233 USE(unused);
234 USE(offset); 234 USE(offset);
235 } 235 }
236 } 236 }
237 break; 237 break;
238 } 238 }
239 case WasmSection::Code::Globals: { 239 case WasmSection::Code::Globals: {
240 int length; 240 int length;
241 uint32_t globals_count = consume_u32v(&length, "globals count"); 241 uint32_t globals_count = consume_u32v(&length, "globals count");
242 module->globals.reserve(SafeReserve(globals_count)); 242 module->globals.reserve(SafeReserve(globals_count));
243 // Decode globals. 243 // Decode globals.
244 for (uint32_t i = 0; i < globals_count; i++) { 244 for (uint32_t i = 0; i < globals_count; ++i) {
245 if (failed()) break; 245 if (failed()) break;
246 TRACE("DecodeGlobal[%d] module+%d\n", i, 246 TRACE("DecodeGlobal[%d] module+%d\n", i,
247 static_cast<int>(pc_ - start_)); 247 static_cast<int>(pc_ - start_));
248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); 248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false});
249 WasmGlobal* global = &module->globals.back(); 249 WasmGlobal* global = &module->globals.back();
250 DecodeGlobalInModule(global); 250 DecodeGlobalInModule(global);
251 } 251 }
252 break; 252 break;
253 } 253 }
254 case WasmSection::Code::DataSegments: { 254 case WasmSection::Code::DataSegments: {
255 int length; 255 int length;
256 uint32_t data_segments_count = 256 uint32_t data_segments_count =
257 consume_u32v(&length, "data segments count"); 257 consume_u32v(&length, "data segments count");
258 module->data_segments.reserve(SafeReserve(data_segments_count)); 258 module->data_segments.reserve(SafeReserve(data_segments_count));
259 // Decode data segments. 259 // Decode data segments.
260 for (uint32_t i = 0; i < data_segments_count; i++) { 260 for (uint32_t i = 0; i < data_segments_count; ++i) {
261 if (failed()) break; 261 if (failed()) break;
262 TRACE("DecodeDataSegment[%d] module+%d\n", i, 262 TRACE("DecodeDataSegment[%d] module+%d\n", i,
263 static_cast<int>(pc_ - start_)); 263 static_cast<int>(pc_ - start_));
264 module->data_segments.push_back({0, // dest_addr 264 module->data_segments.push_back({0, // dest_addr
265 0, // source_offset 265 0, // source_offset
266 0, // source_size 266 0, // source_size
267 false}); // init 267 false}); // init
268 WasmDataSegment* segment = &module->data_segments.back(); 268 WasmDataSegment* segment = &module->data_segments.back();
269 DecodeDataSegmentInModule(module, segment); 269 DecodeDataSegmentInModule(module, segment);
270 } 270 }
271 break; 271 break;
272 } 272 }
273 case WasmSection::Code::FunctionTablePad: {
274 if (!FLAG_wasm_jit_prototype) {
275 error("FunctionTablePad section without jiting enabled");
276 }
277 // An indirect function table requires functions first.
278 int length;
279 module->indirect_table_size =
280 consume_u32v(&length, "indirect entry count");
281 if (module->indirect_table_size > 0 &&
282 module->indirect_table_size < module->function_table.size()) {
283 error("more predefined indirect entries than table can hold");
284 }
285 break;
286 }
273 case WasmSection::Code::FunctionTable: { 287 case WasmSection::Code::FunctionTable: {
274 // An indirect function table requires functions first. 288 // An indirect function table requires functions first.
275 CheckForFunctions(module, section); 289 CheckForFunctions(module, section);
276 int length; 290 int length;
277 uint32_t function_table_count = 291 uint32_t function_table_count =
278 consume_u32v(&length, "function table count"); 292 consume_u32v(&length, "function table count");
279 module->function_table.reserve(SafeReserve(function_table_count)); 293 module->function_table.reserve(SafeReserve(function_table_count));
280 // Decode function table. 294 // Decode function table.
281 for (uint32_t i = 0; i < function_table_count; i++) { 295 for (uint32_t i = 0; i < function_table_count; ++i) {
282 if (failed()) break; 296 if (failed()) break;
283 TRACE("DecodeFunctionTable[%d] module+%d\n", i, 297 TRACE("DecodeFunctionTable[%d] module+%d\n", i,
284 static_cast<int>(pc_ - start_)); 298 static_cast<int>(pc_ - start_));
285 uint16_t index = consume_u32v(&length); 299 uint16_t index = consume_u32v(&length);
286 if (index >= module->functions.size()) { 300 if (index >= module->functions.size()) {
287 error(pc_ - 2, "invalid function index"); 301 error(pc_ - 2, "invalid function index");
288 break; 302 break;
289 } 303 }
290 module->function_table.push_back(index); 304 module->function_table.push_back(index);
291 } 305 }
306 if (module->indirect_table_size > 0 &&
307 module->indirect_table_size < module->function_table.size()) {
308 error("more predefined indirect entries than table can hold");
309 }
292 break; 310 break;
293 } 311 }
294 case WasmSection::Code::StartFunction: { 312 case WasmSection::Code::StartFunction: {
295 // Declares a start function for a module. 313 // Declares a start function for a module.
296 CheckForFunctions(module, section); 314 CheckForFunctions(module, section);
297 if (module->start_function_index >= 0) { 315 if (module->start_function_index >= 0) {
298 error("start function already declared"); 316 error("start function already declared");
299 break; 317 break;
300 } 318 }
301 WasmFunction* func; 319 WasmFunction* func;
302 const byte* pos = pc_; 320 const byte* pos = pc_;
303 module->start_function_index = consume_func_index(module, &func); 321 module->start_function_index = consume_func_index(module, &func);
304 if (func && func->sig->parameter_count() > 0) { 322 if (func && func->sig->parameter_count() > 0) {
305 error(pos, "invalid start function: non-zero parameter count"); 323 error(pos, "invalid start function: non-zero parameter count");
306 break; 324 break;
307 } 325 }
308 break; 326 break;
309 } 327 }
310 case WasmSection::Code::ImportTable: { 328 case WasmSection::Code::ImportTable: {
311 int length; 329 int length;
312 uint32_t import_table_count = 330 uint32_t import_table_count =
313 consume_u32v(&length, "import table count"); 331 consume_u32v(&length, "import table count");
314 module->import_table.reserve(SafeReserve(import_table_count)); 332 module->import_table.reserve(SafeReserve(import_table_count));
315 // Decode import table. 333 // Decode import table.
316 for (uint32_t i = 0; i < import_table_count; i++) { 334 for (uint32_t i = 0; i < import_table_count; ++i) {
317 if (failed()) break; 335 if (failed()) break;
318 TRACE("DecodeImportTable[%d] module+%d\n", i, 336 TRACE("DecodeImportTable[%d] module+%d\n", i,
319 static_cast<int>(pc_ - start_)); 337 static_cast<int>(pc_ - start_));
320 338
321 module->import_table.push_back({nullptr, // sig 339 module->import_table.push_back({nullptr, // sig
322 0, // sig_index 340 0, // sig_index
323 0, // module_name_offset 341 0, // module_name_offset
324 0, // module_name_length 342 0, // module_name_length
325 0, // function_name_offset 343 0, // function_name_offset
326 0}); // function_name_length 344 0}); // function_name_length
(...skipping 12 matching lines...) Expand all
339 break; 357 break;
340 } 358 }
341 case WasmSection::Code::ExportTable: { 359 case WasmSection::Code::ExportTable: {
342 // Declares an export table. 360 // Declares an export table.
343 CheckForFunctions(module, section); 361 CheckForFunctions(module, section);
344 int length; 362 int length;
345 uint32_t export_table_count = 363 uint32_t export_table_count =
346 consume_u32v(&length, "export table count"); 364 consume_u32v(&length, "export table count");
347 module->export_table.reserve(SafeReserve(export_table_count)); 365 module->export_table.reserve(SafeReserve(export_table_count));
348 // Decode export table. 366 // Decode export table.
349 for (uint32_t i = 0; i < export_table_count; i++) { 367 for (uint32_t i = 0; i < export_table_count; ++i) {
350 if (failed()) break; 368 if (failed()) break;
351 TRACE("DecodeExportTable[%d] module+%d\n", i, 369 TRACE("DecodeExportTable[%d] module+%d\n", i,
352 static_cast<int>(pc_ - start_)); 370 static_cast<int>(pc_ - start_));
353 371
354 module->export_table.push_back({0, // func_index 372 module->export_table.push_back({0, // func_index
355 0, // name_offset 373 0, // name_offset
356 0}); // name_length 374 0}); // name_length
357 WasmExport* exp = &module->export_table.back(); 375 WasmExport* exp = &module->export_table.back();
358 376
359 WasmFunction* func; 377 WasmFunction* func;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 byte form = consume_u8("type form"); 700 byte form = consume_u8("type form");
683 if (form != kWasmFunctionTypeForm) { 701 if (form != kWasmFunctionTypeForm) {
684 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", 702 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x",
685 kWasmFunctionTypeForm, form); 703 kWasmFunctionTypeForm, form);
686 return nullptr; 704 return nullptr;
687 } 705 }
688 int length; 706 int length;
689 // parse parameter types 707 // parse parameter types
690 uint32_t param_count = consume_u32v(&length, "param count"); 708 uint32_t param_count = consume_u32v(&length, "param count");
691 std::vector<LocalType> params; 709 std::vector<LocalType> params;
692 for (uint32_t i = 0; i < param_count; i++) { 710 for (uint32_t i = 0; i < param_count; ++i) {
693 LocalType param = consume_local_type(); 711 LocalType param = consume_local_type();
694 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); 712 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type");
695 params.push_back(param); 713 params.push_back(param);
696 } 714 }
697 715
698 // parse return types 716 // parse return types
699 const byte* pt = pc_; 717 const byte* pt = pc_;
700 uint32_t return_count = consume_u32v(&length, "return count"); 718 uint32_t return_count = consume_u32v(&length, "return count");
701 if (return_count > kMaxReturnCount) { 719 if (return_count > kMaxReturnCount) {
702 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, 720 error(pt, pt, "return count of %u exceeds maximum of %u", return_count,
703 kMaxReturnCount); 721 kMaxReturnCount);
704 return nullptr; 722 return nullptr;
705 } 723 }
706 std::vector<LocalType> returns; 724 std::vector<LocalType> returns;
707 for (uint32_t i = 0; i < return_count; i++) { 725 for (uint32_t i = 0; i < return_count; ++i) {
708 LocalType ret = consume_local_type(); 726 LocalType ret = consume_local_type();
709 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); 727 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type");
710 returns.push_back(ret); 728 returns.push_back(ret);
711 } 729 }
712 730
713 // FunctionSig stores the return types first. 731 // FunctionSig stores the return types first.
714 LocalType* buffer = 732 LocalType* buffer =
715 module_zone->NewArray<LocalType>(param_count + return_count); 733 module_zone->NewArray<LocalType>(param_count + return_count);
716 uint32_t b = 0; 734 uint32_t b = 0;
717 for (uint32_t i = 0; i < return_count; i++) buffer[b++] = returns[i]; 735 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i];
718 for (uint32_t i = 0; i < param_count; i++) buffer[b++] = params[i]; 736 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i];
719 737
720 return new (module_zone) FunctionSig(return_count, param_count, buffer); 738 return new (module_zone) FunctionSig(return_count, param_count, buffer);
721 } 739 }
722 }; 740 };
723 741
724 // Helpers for nice error messages. 742 // Helpers for nice error messages.
725 class ModuleError : public ModuleResult { 743 class ModuleError : public ModuleResult {
726 public: 744 public:
727 explicit ModuleError(const char* msg) { 745 explicit ModuleError(const char* msg) {
728 error_code = kError; 746 error_code = kError;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 if (!code_section.start()) decoder.error("no code section"); 856 if (!code_section.start()) decoder.error("no code section");
839 857
840 int length; 858 int length;
841 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); 859 uint32_t functions_count = decoder.consume_u32v(&length, "functions count");
842 FunctionOffsets table; 860 FunctionOffsets table;
843 // Take care of invalid input here. 861 // Take care of invalid input here.
844 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) 862 if (functions_count < static_cast<unsigned>(code_section.length()) / 2)
845 table.reserve(functions_count); 863 table.reserve(functions_count);
846 int section_offset = static_cast<int>(code_section.start() - module_start); 864 int section_offset = static_cast<int>(code_section.start() - module_start);
847 DCHECK_LE(0, section_offset); 865 DCHECK_LE(0, section_offset);
848 for (uint32_t i = 0; i < functions_count && decoder.ok(); i++) { 866 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) {
849 uint32_t size = decoder.consume_u32v(&length, "body size"); 867 uint32_t size = decoder.consume_u32v(&length, "body size");
850 int offset = static_cast<int>(section_offset + decoder.pc_offset()); 868 int offset = static_cast<int>(section_offset + decoder.pc_offset());
851 table.push_back(std::make_pair(offset, static_cast<int>(size))); 869 table.push_back(std::make_pair(offset, static_cast<int>(size)));
852 DCHECK(table.back().first >= 0 && table.back().second >= 0); 870 DCHECK(table.back().first >= 0 && table.back().second >= 0);
853 decoder.consume_bytes(size); 871 decoder.consume_bytes(size);
854 } 872 }
855 if (decoder.more()) decoder.error("unexpected additional bytes"); 873 if (decoder.more()) decoder.error("unexpected additional bytes");
856 874
857 return decoder.toResult(std::move(table)); 875 return decoder.toResult(std::move(table));
858 } 876 }
859 877
860 } // namespace wasm 878 } // namespace wasm
861 } // namespace internal 879 } // namespace internal
862 } // namespace v8 880 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/encoder.cc ('k') | src/wasm/switch-logic.cc » ('j') | src/wasm/wasm-module.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698