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

Side by Side Diff: test/cctest/interpreter/generate-bytecode-expectations.cc

Issue 1737623002: [Interpreter] Multiple input files for generate-bytecode-expectations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: ERROR reporting macro. 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 <cstring> 5 #include <cstring>
6 #include <fstream> 6 #include <fstream>
7 #include <vector>
7 8
8 #include "test/cctest/interpreter/bytecode-expectations-printer.h" 9 #include "test/cctest/interpreter/bytecode-expectations-printer.h"
9 10
10 #include "include/libplatform/libplatform.h" 11 #include "include/libplatform/libplatform.h"
11 #include "include/v8.h" 12 #include "include/v8.h"
12 13
13 #include "src/base/logging.h" 14 #include "src/base/logging.h"
14 #include "src/base/smart-pointers.h" 15 #include "src/base/smart-pointers.h"
15 #include "src/compiler.h" 16 #include "src/compiler.h"
16 #include "src/interpreter/interpreter.h" 17 #include "src/interpreter/interpreter.h"
17 18
18 using v8::internal::interpreter::BytecodeExpectationsPrinter; 19 using v8::internal::interpreter::BytecodeExpectationsPrinter;
19 20
21 #define ERROR(MESSAGE) (((std::cerr << "ERROR: ") << MESSAGE) << '\n')
Stefano Sanfilippo 2016/02/25 13:25:33 Using a macro instead of a function allows the fol
22
20 namespace { 23 namespace {
21 24
22 class ProgramOptions final { 25 class ProgramOptions final {
23 public: 26 public:
24 static ProgramOptions FromCommandLine(int argc, char** argv); 27 static ProgramOptions FromCommandLine(int argc, char** argv);
25 28
26 ProgramOptions() 29 ProgramOptions()
27 : parsing_failed_(false), 30 : parsing_failed_(false),
28 print_help_(false), 31 print_help_(false),
29 read_raw_js_snippet_(false), 32 read_raw_js_snippet_(false),
(...skipping 20 matching lines...) Expand all
50 } 53 }
51 bool rebaseline() const { return rebaseline_; } 54 bool rebaseline() const { return rebaseline_; }
52 bool wrap() const { return wrap_; } 55 bool wrap() const { return wrap_; }
53 bool execute() const { return execute_; } 56 bool execute() const { return execute_; }
54 bool top_level() const { return top_level_; } 57 bool top_level() const { return top_level_; }
55 bool legacy_const() const { return legacy_const_; } 58 bool legacy_const() const { return legacy_const_; }
56 bool do_expressions() const { return do_expressions_; } 59 bool do_expressions() const { return do_expressions_; }
57 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const { 60 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const {
58 return const_pool_type_; 61 return const_pool_type_;
59 } 62 }
60 std::string input_filename() const { return input_filename_; } 63 std::vector<std::string> input_filenames() const { return input_filenames_; }
61 std::string output_filename() const { return output_filename_; } 64 std::string output_filename() const { return output_filename_; }
62 std::string test_function_name() const { return test_function_name_; } 65 std::string test_function_name() const { return test_function_name_; }
63 66
64 private: 67 private:
65 bool parsing_failed_; 68 bool parsing_failed_;
66 bool print_help_; 69 bool print_help_;
67 bool read_raw_js_snippet_; 70 bool read_raw_js_snippet_;
68 bool read_from_stdin_; 71 bool read_from_stdin_;
69 bool rebaseline_; 72 bool rebaseline_;
70 bool wrap_; 73 bool wrap_;
71 bool execute_; 74 bool execute_;
72 bool top_level_; 75 bool top_level_;
73 bool legacy_const_; 76 bool legacy_const_;
74 bool do_expressions_; 77 bool do_expressions_;
75 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_; 78 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_;
76 std::string input_filename_; 79 std::vector<std::string> input_filenames_;
77 std::string output_filename_; 80 std::string output_filename_;
78 std::string test_function_name_; 81 std::string test_function_name_;
79 }; 82 };
80 83
81 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator { 84 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
82 public: 85 public:
83 void* Allocate(size_t length) override { 86 void* Allocate(size_t length) override {
84 void* data = AllocateUninitialized(length); 87 void* data = AllocateUninitialized(length);
85 if (data != nullptr) memset(data, 0, length); 88 if (data != nullptr) memset(data, 0, length);
86 return data; 89 return data;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 options.top_level_ = true; 170 options.top_level_ = true;
168 } else if (strcmp(argv[i], "--legacy-const") == 0) { 171 } else if (strcmp(argv[i], "--legacy-const") == 0) {
169 options.legacy_const_ = true; 172 options.legacy_const_ = true;
170 } else if (strcmp(argv[i], "--do-expressions") == 0) { 173 } else if (strcmp(argv[i], "--do-expressions") == 0) {
171 options.do_expressions_ = true; 174 options.do_expressions_ = true;
172 } else if (strncmp(argv[i], "--output=", 9) == 0) { 175 } else if (strncmp(argv[i], "--output=", 9) == 0) {
173 options.output_filename_ = argv[i] + 9; 176 options.output_filename_ = argv[i] + 9;
174 } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) { 177 } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) {
175 options.test_function_name_ = argv[i] + 21; 178 options.test_function_name_ = argv[i] + 21;
176 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with -- 179 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with --
177 if (!options.input_filename_.empty()) { 180 options.input_filenames_.push_back(argv[i]);
178 std::cerr << "ERROR: More than one input file specified\n";
179 options.parsing_failed_ = true;
180 break;
181 }
182 options.input_filename_ = argv[i];
183 } else { 181 } else {
184 std::cerr << "ERROR: Unknonwn option " << argv[i] << "\n"; 182 ERROR("Unknonwn option " << argv[i]);
185 options.parsing_failed_ = true; 183 options.parsing_failed_ = true;
186 break; 184 break;
187 } 185 }
188 } 186 }
189 187
190 return options; 188 return options;
191 } 189 }
192 190
193 bool ProgramOptions::Validate() const { 191 bool ProgramOptions::Validate() const {
194 if (parsing_failed_) return false; 192 if (parsing_failed_) return false;
195 if (print_help_) return true; 193 if (print_help_) return true;
196 194
197 if (const_pool_type_ == 195 if (const_pool_type_ ==
198 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) { 196 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) {
199 std::cerr << "ERROR: Unknown constant pool type.\n"; 197 ERROR("Unknown constant pool type.");
200 return false; 198 return false;
201 } 199 }
202 200
203 if (!read_from_stdin_ && input_filename_.empty()) { 201 if (!read_from_stdin_ && input_filenames_.empty()) {
204 std::cerr << "ERROR: No input file specified.\n"; 202 ERROR("No input file specified.");
205 return false; 203 return false;
206 } 204 }
207 205
208 if (read_from_stdin_ && !input_filename_.empty()) { 206 if (read_from_stdin_ && !input_filenames_.empty()) {
209 std::cerr << "ERROR: Reading from stdin, but input files supplied.\n"; 207 ERROR("Reading from stdin, but input files supplied.");
210 return false; 208 return false;
211 } 209 }
212 210
213 if (rebaseline_ && read_raw_js_snippet_) { 211 if (rebaseline_ && read_raw_js_snippet_) {
214 std::cerr << "ERROR: Cannot use --rebaseline on a raw JS snippet.\n"; 212 ERROR("Cannot use --rebaseline on a raw JS snippet.");
213 return false;
214 }
215
216 if (rebaseline_ && !output_filename_.empty()) {
217 ERROR("Output file cannot be specified together with --rebaseline.");
218 return false;
219 }
220
221 if (rebaseline_ && read_from_stdin_) {
222 ERROR("Cannot --rebaseline when input is --stdin.");
223 return false;
224 }
225
226 if (input_filenames_.size() > 1 && !rebaseline_ && !read_raw_js_snippet()) {
227 ERROR("Multiple input files, but no --rebaseline or --raw-js specified.");
215 return false; 228 return false;
216 } 229 }
217 230
218 if (top_level_ && !test_function_name_.empty()) { 231 if (top_level_ && !test_function_name_.empty()) {
219 std::cerr << "ERROR: test function name specified while processing " 232 ERROR("Test function name specified while processing top level code.");
220 "top level code.\n";
221 return false; 233 return false;
222 } 234 }
223 235
224 return true; 236 return true;
225 } 237 }
226 238
227 void ProgramOptions::UpdateFromHeader(std::istream& stream) { 239 void ProgramOptions::UpdateFromHeader(std::istream& stream) {
228 std::string line; 240 std::string line;
229 241
230 // Skip to the beginning of the options header 242 // Skip to the beginning of the options header
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 } else { 365 } else {
354 std::string snippet; 366 std::string snippet;
355 while (ReadNextSnippet(body_stream, &snippet)) { 367 while (ReadNextSnippet(body_stream, &snippet)) {
356 snippet_list->push_back(UnescapeString(snippet)); 368 snippet_list->push_back(UnescapeString(snippet));
357 } 369 }
358 } 370 }
359 } 371 }
360 372
361 void GenerateExpectationsFile(std::ostream& stream, // NOLINT 373 void GenerateExpectationsFile(std::ostream& stream, // NOLINT
362 const std::vector<std::string>& snippet_list, 374 const std::vector<std::string>& snippet_list,
363 const ProgramOptions& options, 375 const V8InitializationScope& platform,
364 const char* exec_path) { 376 const ProgramOptions& options) {
365 V8InitializationScope platform(exec_path); 377 v8::Isolate::Scope isolate_scope(platform.isolate());
366 { 378 v8::HandleScope handle_scope(platform.isolate());
367 v8::Isolate::Scope isolate_scope(platform.isolate()); 379 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
368 v8::HandleScope handle_scope(platform.isolate()); 380 v8::Context::Scope context_scope(context);
369 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
370 v8::Context::Scope context_scope(context);
371 381
372 BytecodeExpectationsPrinter printer(platform.isolate(), 382 BytecodeExpectationsPrinter printer(platform.isolate(),
373 options.const_pool_type()); 383 options.const_pool_type());
374 printer.set_wrap(options.wrap()); 384 printer.set_wrap(options.wrap());
375 printer.set_execute(options.execute()); 385 printer.set_execute(options.execute());
376 printer.set_top_level(options.top_level()); 386 printer.set_top_level(options.top_level());
377 if (!options.test_function_name().empty()) { 387 if (!options.test_function_name().empty()) {
378 printer.set_test_function_name(options.test_function_name()); 388 printer.set_test_function_name(options.test_function_name());
379 } 389 }
380 390
381 if (options.legacy_const()) i::FLAG_legacy_const = true; 391 if (options.legacy_const()) i::FLAG_legacy_const = true;
382 if (options.do_expressions()) i::FLAG_harmony_do_expressions = true; 392 if (options.do_expressions()) i::FLAG_harmony_do_expressions = true;
383 393
384 stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; 394 stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n";
385 options.PrintHeader(stream); 395 options.PrintHeader(stream);
386 for (const std::string& snippet : snippet_list) { 396 for (const std::string& snippet : snippet_list) {
387 printer.PrintExpectation(stream, snippet); 397 printer.PrintExpectation(stream, snippet);
388 }
389 } 398 }
390 } 399 }
391 400
392 void PrintUsage(const char* exec_path) { 401 void PrintUsage(const char* exec_path) {
393 std::cerr 402 std::cerr
394 << "\nUsage: " << exec_path 403 << "\nUsage: " << exec_path
395 << " [OPTIONS]... [INPUT FILE]\n\n" 404 << " [OPTIONS]... [INPUT FILES]...\n\n"
396 "Options:\n" 405 "Options:\n"
397 " --help Print this help message.\n" 406 " --help Print this help message.\n"
398 " --raw-js Read raw JavaScript, instead of the output format.\n" 407 " --raw-js Read raw JavaScript, instead of the output format.\n"
399 " --stdin Read from standard input instead of file.\n" 408 " --stdin Read from standard input instead of file.\n"
400 " --rebaseline Rebaseline input snippet file.\n" 409 " --rebaseline Rebaseline input snippet file.\n"
401 " --no-wrap Do not wrap the snippet in a function.\n" 410 " --no-wrap Do not wrap the snippet in a function.\n"
402 " --no-execute Do not execute after compilation.\n" 411 " --no-execute Do not execute after compilation.\n"
403 " --test-function-name=foo " 412 " --test-function-name=foo "
404 "Specify the name of the test function.\n" 413 "Specify the name of the test function.\n"
405 " --top-level Process top level code, not the top-level function." 414 " --top-level Process top level code, not the top-level function.\n"
406 " --legacy-const Enable legacy_const flag.\n" 415 " --legacy-const Enable legacy_const flag.\n"
407 " --do-expressions Enable harmony_do_expressions flag.\n" 416 " --do-expressions Enable harmony_do_expressions flag.\n"
408 " --output=file.name\n" 417 " --output=file.name\n"
409 " Specify the output file. If not specified, output goes to " 418 " Specify the output file. If not specified, output goes to "
410 "stdout.\n" 419 "stdout.\n"
411 " --pool-type=(number|string|mixed)\n" 420 " --pool-type=(number|string|mixed)\n"
412 " Specify the type of the entries in the constant pool " 421 " Specify the type of the entries in the constant pool "
413 "(default: mixed).\n" 422 "(default: mixed).\n"
414 "\n" 423 "\n"
415 "When using --rebaseline, flags --no-wrap, --no-execute, " 424 "When using --rebaseline, flags --no-wrap, --no-execute, "
416 "--test-function-name\nand --pool-type will be overridden by the " 425 "--test-function-name\nand --pool-type will be overridden by the "
417 "options specified in the input file\nheader.\n\n" 426 "options specified in the input file\nheader.\n\n"
418 "Each raw JavaScript file is interpreted as a single snippet.\n\n" 427 "Each raw JavaScript file is interpreted as a single snippet.\n\n"
419 "This tool is intended as a help in writing tests.\n" 428 "This tool is intended as a help in writing tests.\n"
420 "Please, DO NOT blindly copy and paste the output " 429 "Please, DO NOT blindly copy and paste the output "
421 "into the test suite.\n"; 430 "into the test suite.\n";
422 } 431 }
423 432
433 int DoRebaseline(const V8InitializationScope& platform,
434 const ProgramOptions& base_options) {
435 DCHECK(base_options.rebaseline());
436 for (const std::string& input_filename : base_options.input_filenames()) {
437 std::cerr << "Updating " << input_filename << '\n';
438
439 std::ifstream input_stream(input_filename);
440 if (!input_stream.is_open()) {
441 ERROR("Could not open " << input_filename << " for reading.");
442 return 2;
443 }
444
445 ProgramOptions options = base_options;
446 options.UpdateFromHeader(input_stream);
447 CHECK(options.Validate());
448
449 std::vector<std::string> snippet_list;
450 ExtractSnippets(&snippet_list, input_stream, false);
451
452 std::ofstream output_stream(input_filename);
453 if (!output_stream.is_open()) {
454 ERROR("Could not open " << input_filename << " for writing.");
455 return 3;
456 }
457
458 GenerateExpectationsFile(output_stream, snippet_list, platform, options);
459 }
460 return 0;
461 }
462
463 int DoRawJS(const V8InitializationScope& platform,
464 const ProgramOptions& options) {
465 DCHECK(options.read_raw_js_snippet());
466
467 std::vector<std::string> snippet_list;
468
469 if (options.read_from_stdin()) {
470 snippet_list.push_back(ReadRawJSSnippet(std::cin));
471 } else {
472 for (const std::string& input_filename : options.input_filenames()) {
473 std::cerr << "Reading " << input_filename << '\n';
474
475 std::ifstream input_stream(input_filename.c_str());
476 if (!input_stream.is_open()) {
477 ERROR("Could not open " << input_filename << " for reading.");
478 return 2;
479 }
480
481 snippet_list.push_back(ReadRawJSSnippet(input_stream));
482 }
483 }
484
485 std::ofstream output_file_handle;
486 if (!options.write_to_stdout()) {
487 output_file_handle.open(options.output_filename().c_str());
488 if (!output_file_handle.is_open()) {
489 ERROR("Could not open " << options.output_filename() << " for writing.");
490 return 3;
491 }
492 }
493 std::ostream& output_stream =
494 options.write_to_stdout() ? std::cout : output_file_handle;
495
496 GenerateExpectationsFile(output_stream, snippet_list, platform, options);
497
498 return 0;
499 }
500
501 int DoDefault(const V8InitializationScope& platform,
502 const ProgramOptions& options) {
503 std::ifstream input_file_handle;
504 if (!options.read_from_stdin()) {
505 const char* input_filename = options.input_filenames().front().c_str();
506 input_file_handle.open(input_filename);
507 if (!input_file_handle.is_open()) {
508 ERROR("Could not open " << input_filename << " for reading.");
509 return 2;
510 }
511 }
512 std::istream& input_stream =
513 options.read_from_stdin() ? std::cin : input_file_handle;
514
515 std::vector<std::string> snippet_list;
516 ExtractSnippets(&snippet_list, input_stream, false);
517
518 std::ofstream output_file_handle;
519 if (!options.write_to_stdout()) {
520 output_file_handle.open(options.output_filename().c_str());
521 if (!output_file_handle.is_open()) {
522 ERROR("Could not open " << options.output_filename() << " for writing.");
523 return 3;
524 }
525 }
526 std::ostream& output_stream =
527 options.write_to_stdout() ? std::cout : output_file_handle;
528
529 GenerateExpectationsFile(output_stream, snippet_list, platform, options);
530
531 return 0;
532 }
533
424 } // namespace 534 } // namespace
425 535
426 int main(int argc, char** argv) { 536 int main(int argc, char** argv) {
427 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); 537 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv);
428 538
429 if (!options.Validate() || options.print_help()) { 539 if (!options.Validate() || options.print_help()) {
430 PrintUsage(argv[0]); 540 PrintUsage(argv[0]);
431 return options.print_help() ? 0 : 1; 541 return options.print_help() ? 0 : 1;
432 } 542 }
433 543
434 std::ifstream input_file_handle; 544 V8InitializationScope platform(argv[0]);
435 if (!options.read_from_stdin()) { 545
436 input_file_handle.open(options.input_filename().c_str()); 546 if (options.read_raw_js_snippet()) {
437 if (!input_file_handle.is_open()) { 547 return DoRawJS(platform, options);
438 std::cerr << "ERROR: Could not open '" << options.input_filename() 548 } else if (options.rebaseline()) {
439 << "' for reading.\n"; 549 return DoRebaseline(platform, options);
440 return 2; 550 } else {
441 } 551 return DoDefault(platform, options);
442 } 552 }
443 std::istream& input_stream =
444 options.read_from_stdin() ? std::cin : input_file_handle;
445
446 if (options.rebaseline()) {
447 options.UpdateFromHeader(input_stream);
448 CHECK(options.Validate());
449 }
450
451 std::vector<std::string> snippet_list;
452 ExtractSnippets(&snippet_list, input_stream, options.read_raw_js_snippet());
453
454 std::ofstream output_file_handle;
455 if (!options.write_to_stdout()) {
456 output_file_handle.open(options.rebaseline()
457 ? options.input_filename().c_str()
458 : options.output_filename().c_str());
459 if (!output_file_handle.is_open()) {
460 std::cerr << "ERROR: Could not open '" << options.output_filename()
461 << "' for writing.\n";
462 return 3;
463 }
464 }
465 std::ostream& output_stream =
466 options.write_to_stdout() ? std::cout : output_file_handle;
467
468 GenerateExpectationsFile(output_stream, snippet_list, options, argv[0]);
469 } 553 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698