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

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: Unifying Do* functions. 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 REPORT_ERROR(MESSAGE) (((std::cerr << "ERROR: ") << MESSAGE) << '\n')
rmcilroy 2016/02/25 15:48:23 Don't make this a #define, use a helper function i
Stefano Sanfilippo 2016/02/25 16:34:43 I used a macro instead of a function to enable the
rmcilroy 2016/02/25 16:39:07 How about just using v8/base/logging FATAL instead
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),
30 read_from_stdin_(false), 33 read_from_stdin_(false),
31 rebaseline_(false), 34 rebaseline_(false),
32 wrap_(true), 35 wrap_(true),
33 execute_(true), 36 execute_(true),
34 top_level_(false), 37 top_level_(false),
35 legacy_const_(false), 38 legacy_const_(false),
36 do_expressions_(false), 39 do_expressions_(false),
40 verbose_(false),
37 const_pool_type_( 41 const_pool_type_(
38 BytecodeExpectationsPrinter::ConstantPoolType::kMixed) {} 42 BytecodeExpectationsPrinter::ConstantPoolType::kMixed) {}
39 43
40 bool Validate() const; 44 bool Validate() const;
41 void UpdateFromHeader(std::istream& stream); // NOLINT 45 void UpdateFromHeader(std::istream& stream); // NOLINT
42 void PrintHeader(std::ostream& stream) const; // NOLINT 46 void PrintHeader(std::ostream& stream) const; // NOLINT
43 47
44 bool parsing_failed() const { return parsing_failed_; } 48 bool parsing_failed() const { return parsing_failed_; }
45 bool print_help() const { return print_help_; } 49 bool print_help() const { return print_help_; }
46 bool read_raw_js_snippet() const { return read_raw_js_snippet_; } 50 bool read_raw_js_snippet() const { return read_raw_js_snippet_; }
47 bool read_from_stdin() const { return read_from_stdin_; } 51 bool read_from_stdin() const { return read_from_stdin_; }
48 bool write_to_stdout() const { 52 bool write_to_stdout() const {
49 return output_filename_.empty() && !rebaseline_; 53 return output_filename_.empty() && !rebaseline_;
50 } 54 }
51 bool rebaseline() const { return rebaseline_; } 55 bool rebaseline() const { return rebaseline_; }
52 bool wrap() const { return wrap_; } 56 bool wrap() const { return wrap_; }
53 bool execute() const { return execute_; } 57 bool execute() const { return execute_; }
54 bool top_level() const { return top_level_; } 58 bool top_level() const { return top_level_; }
55 bool legacy_const() const { return legacy_const_; } 59 bool legacy_const() const { return legacy_const_; }
56 bool do_expressions() const { return do_expressions_; } 60 bool do_expressions() const { return do_expressions_; }
61 bool verbose() const { return verbose_; }
57 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const { 62 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type() const {
58 return const_pool_type_; 63 return const_pool_type_;
59 } 64 }
60 std::string input_filename() const { return input_filename_; } 65 std::vector<std::string> input_filenames() const { return input_filenames_; }
61 std::string output_filename() const { return output_filename_; } 66 std::string output_filename() const { return output_filename_; }
62 std::string test_function_name() const { return test_function_name_; } 67 std::string test_function_name() const { return test_function_name_; }
63 68
64 private: 69 private:
65 bool parsing_failed_; 70 bool parsing_failed_;
66 bool print_help_; 71 bool print_help_;
67 bool read_raw_js_snippet_; 72 bool read_raw_js_snippet_;
68 bool read_from_stdin_; 73 bool read_from_stdin_;
69 bool rebaseline_; 74 bool rebaseline_;
70 bool wrap_; 75 bool wrap_;
71 bool execute_; 76 bool execute_;
72 bool top_level_; 77 bool top_level_;
73 bool legacy_const_; 78 bool legacy_const_;
74 bool do_expressions_; 79 bool do_expressions_;
80 bool verbose_;
75 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_; 81 BytecodeExpectationsPrinter::ConstantPoolType const_pool_type_;
76 std::string input_filename_; 82 std::vector<std::string> input_filenames_;
77 std::string output_filename_; 83 std::string output_filename_;
78 std::string test_function_name_; 84 std::string test_function_name_;
79 }; 85 };
80 86
81 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator { 87 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
82 public: 88 public:
83 void* Allocate(size_t length) override { 89 void* Allocate(size_t length) override {
84 void* data = AllocateUninitialized(length); 90 void* data = AllocateUninitialized(length);
85 if (data != nullptr) memset(data, 0, length); 91 if (data != nullptr) memset(data, 0, length);
86 return data; 92 return data;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } else if (strcmp(argv[i], "--no-wrap") == 0) { 168 } else if (strcmp(argv[i], "--no-wrap") == 0) {
163 options.wrap_ = false; 169 options.wrap_ = false;
164 } else if (strcmp(argv[i], "--no-execute") == 0) { 170 } else if (strcmp(argv[i], "--no-execute") == 0) {
165 options.execute_ = false; 171 options.execute_ = false;
166 } else if (strcmp(argv[i], "--top-level") == 0) { 172 } else if (strcmp(argv[i], "--top-level") == 0) {
167 options.top_level_ = true; 173 options.top_level_ = true;
168 } else if (strcmp(argv[i], "--legacy-const") == 0) { 174 } else if (strcmp(argv[i], "--legacy-const") == 0) {
169 options.legacy_const_ = true; 175 options.legacy_const_ = true;
170 } else if (strcmp(argv[i], "--do-expressions") == 0) { 176 } else if (strcmp(argv[i], "--do-expressions") == 0) {
171 options.do_expressions_ = true; 177 options.do_expressions_ = true;
178 } else if (strcmp(argv[i], "--verbose") == 0) {
179 options.verbose_ = true;
172 } else if (strncmp(argv[i], "--output=", 9) == 0) { 180 } else if (strncmp(argv[i], "--output=", 9) == 0) {
173 options.output_filename_ = argv[i] + 9; 181 options.output_filename_ = argv[i] + 9;
174 } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) { 182 } else if (strncmp(argv[i], "--test-function-name=", 21) == 0) {
175 options.test_function_name_ = argv[i] + 21; 183 options.test_function_name_ = argv[i] + 21;
176 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with -- 184 } else if (strncmp(argv[i], "--", 2) != 0) { // It doesn't start with --
177 if (!options.input_filename_.empty()) { 185 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 { 186 } else {
184 std::cerr << "ERROR: Unknonwn option " << argv[i] << "\n"; 187 REPORT_ERROR("Unknonwn option " << argv[i]);
185 options.parsing_failed_ = true; 188 options.parsing_failed_ = true;
186 break; 189 break;
187 } 190 }
188 } 191 }
189 192
190 return options; 193 return options;
191 } 194 }
192 195
193 bool ProgramOptions::Validate() const { 196 bool ProgramOptions::Validate() const {
194 if (parsing_failed_) return false; 197 if (parsing_failed_) return false;
195 if (print_help_) return true; 198 if (print_help_) return true;
196 199
197 if (const_pool_type_ == 200 if (const_pool_type_ ==
198 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) { 201 BytecodeExpectationsPrinter::ConstantPoolType::kUnknown) {
199 std::cerr << "ERROR: Unknown constant pool type.\n"; 202 REPORT_ERROR("Unknown constant pool type.");
200 return false; 203 return false;
201 } 204 }
202 205
203 if (!read_from_stdin_ && input_filename_.empty()) { 206 if (!read_from_stdin_ && input_filenames_.empty()) {
204 std::cerr << "ERROR: No input file specified.\n"; 207 REPORT_ERROR("No input file specified.");
205 return false; 208 return false;
206 } 209 }
207 210
208 if (read_from_stdin_ && !input_filename_.empty()) { 211 if (read_from_stdin_ && !input_filenames_.empty()) {
209 std::cerr << "ERROR: Reading from stdin, but input files supplied.\n"; 212 REPORT_ERROR("Reading from stdin, but input files supplied.");
210 return false; 213 return false;
211 } 214 }
212 215
213 if (rebaseline_ && read_raw_js_snippet_) { 216 if (rebaseline_ && read_raw_js_snippet_) {
214 std::cerr << "ERROR: Cannot use --rebaseline on a raw JS snippet.\n"; 217 REPORT_ERROR("Cannot use --rebaseline on a raw JS snippet.");
218 return false;
219 }
220
221 if (rebaseline_ && !output_filename_.empty()) {
222 REPORT_ERROR("Output file cannot be specified together with --rebaseline.");
223 return false;
224 }
225
226 if (rebaseline_ && read_from_stdin_) {
227 REPORT_ERROR("Cannot --rebaseline when input is --stdin.");
228 return false;
229 }
230
231 if (input_filenames_.size() > 1 && !rebaseline_ && !read_raw_js_snippet()) {
232 REPORT_ERROR(
233 "Multiple input files, but no --rebaseline or --raw-js specified.");
215 return false; 234 return false;
216 } 235 }
217 236
218 if (top_level_ && !test_function_name_.empty()) { 237 if (top_level_ && !test_function_name_.empty()) {
219 std::cerr << "ERROR: test function name specified while processing " 238 REPORT_ERROR(
220 "top level code.\n"; 239 "Test function name specified while processing top level code.");
221 return false; 240 return false;
222 } 241 }
223 242
224 return true; 243 return true;
225 } 244 }
226 245
227 void ProgramOptions::UpdateFromHeader(std::istream& stream) { 246 void ProgramOptions::UpdateFromHeader(std::istream& stream) {
228 std::string line; 247 std::string line;
229 248
230 // Skip to the beginning of the options header 249 // Skip to the beginning of the options header
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 } else { 372 } else {
354 std::string snippet; 373 std::string snippet;
355 while (ReadNextSnippet(body_stream, &snippet)) { 374 while (ReadNextSnippet(body_stream, &snippet)) {
356 snippet_list->push_back(UnescapeString(snippet)); 375 snippet_list->push_back(UnescapeString(snippet));
357 } 376 }
358 } 377 }
359 } 378 }
360 379
361 void GenerateExpectationsFile(std::ostream& stream, // NOLINT 380 void GenerateExpectationsFile(std::ostream& stream, // NOLINT
362 const std::vector<std::string>& snippet_list, 381 const std::vector<std::string>& snippet_list,
363 const ProgramOptions& options, 382 const V8InitializationScope& platform,
364 const char* exec_path) { 383 const ProgramOptions& options) {
365 V8InitializationScope platform(exec_path); 384 v8::Isolate::Scope isolate_scope(platform.isolate());
366 { 385 v8::HandleScope handle_scope(platform.isolate());
367 v8::Isolate::Scope isolate_scope(platform.isolate()); 386 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
368 v8::HandleScope handle_scope(platform.isolate()); 387 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 388
372 BytecodeExpectationsPrinter printer(platform.isolate(), 389 BytecodeExpectationsPrinter printer(platform.isolate(),
373 options.const_pool_type()); 390 options.const_pool_type());
374 printer.set_wrap(options.wrap()); 391 printer.set_wrap(options.wrap());
375 printer.set_execute(options.execute()); 392 printer.set_execute(options.execute());
376 printer.set_top_level(options.top_level()); 393 printer.set_top_level(options.top_level());
377 if (!options.test_function_name().empty()) { 394 if (!options.test_function_name().empty()) {
378 printer.set_test_function_name(options.test_function_name()); 395 printer.set_test_function_name(options.test_function_name());
379 } 396 }
380 397
381 if (options.legacy_const()) i::FLAG_legacy_const = true; 398 if (options.legacy_const()) i::FLAG_legacy_const = true;
382 if (options.do_expressions()) i::FLAG_harmony_do_expressions = true; 399 if (options.do_expressions()) i::FLAG_harmony_do_expressions = true;
383 400
384 stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; 401 stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n";
385 options.PrintHeader(stream); 402 options.PrintHeader(stream);
386 for (const std::string& snippet : snippet_list) { 403 for (const std::string& snippet : snippet_list) {
387 printer.PrintExpectation(stream, snippet); 404 printer.PrintExpectation(stream, snippet);
388 }
389 } 405 }
390 } 406 }
391 407
392 void PrintUsage(const char* exec_path) { 408 void PrintUsage(const char* exec_path) {
393 std::cerr 409 std::cerr
394 << "\nUsage: " << exec_path 410 << "\nUsage: " << exec_path
395 << " [OPTIONS]... [INPUT FILE]\n\n" 411 << " [OPTIONS]... [INPUT FILES]...\n\n"
396 "Options:\n" 412 "Options:\n"
397 " --help Print this help message.\n" 413 " --help Print this help message.\n"
414 " --verbose Emit messages about the progress of the tool.\n"
398 " --raw-js Read raw JavaScript, instead of the output format.\n" 415 " --raw-js Read raw JavaScript, instead of the output format.\n"
399 " --stdin Read from standard input instead of file.\n" 416 " --stdin Read from standard input instead of file.\n"
400 " --rebaseline Rebaseline input snippet file.\n" 417 " --rebaseline Rebaseline input snippet file.\n"
401 " --no-wrap Do not wrap the snippet in a function.\n" 418 " --no-wrap Do not wrap the snippet in a function.\n"
402 " --no-execute Do not execute after compilation.\n" 419 " --no-execute Do not execute after compilation.\n"
403 " --test-function-name=foo " 420 " --test-function-name=foo "
404 "Specify the name of the test function.\n" 421 "Specify the name of the test function.\n"
405 " --top-level Process top level code, not the top-level function." 422 " --top-level Process top level code, not the top-level function.\n"
406 " --legacy-const Enable legacy_const flag.\n" 423 " --legacy-const Enable legacy_const flag.\n"
407 " --do-expressions Enable harmony_do_expressions flag.\n" 424 " --do-expressions Enable harmony_do_expressions flag.\n"
408 " --output=file.name\n" 425 " --output=file.name\n"
409 " Specify the output file. If not specified, output goes to " 426 " Specify the output file. If not specified, output goes to "
410 "stdout.\n" 427 "stdout.\n"
411 " --pool-type=(number|string|mixed)\n" 428 " --pool-type=(number|string|mixed)\n"
412 " Specify the type of the entries in the constant pool " 429 " Specify the type of the entries in the constant pool "
413 "(default: mixed).\n" 430 "(default: mixed).\n"
414 "\n" 431 "\n"
415 "When using --rebaseline, flags --no-wrap, --no-execute, " 432 "When using --rebaseline, flags --no-wrap, --no-execute, "
416 "--test-function-name\nand --pool-type will be overridden by the " 433 "--test-function-name\nand --pool-type will be overridden by the "
417 "options specified in the input file\nheader.\n\n" 434 "options specified in the input file\nheader.\n\n"
418 "Each raw JavaScript file is interpreted as a single snippet.\n\n" 435 "Each raw JavaScript file is interpreted as a single snippet.\n\n"
419 "This tool is intended as a help in writing tests.\n" 436 "This tool is intended as a help in writing tests.\n"
420 "Please, DO NOT blindly copy and paste the output " 437 "Please, DO NOT blindly copy and paste the output "
421 "into the test suite.\n"; 438 "into the test suite.\n";
422 } 439 }
423 440
424 } // namespace 441 } // namespace
425 442
426 int main(int argc, char** argv) { 443 int main(int argc, char** argv) {
427 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv); 444 ProgramOptions options = ProgramOptions::FromCommandLine(argc, argv);
428 445
429 if (!options.Validate() || options.print_help()) { 446 if (!options.Validate() || options.print_help()) {
430 PrintUsage(argv[0]); 447 PrintUsage(argv[0]);
431 return options.print_help() ? 0 : 1; 448 return options.print_help() ? 0 : 1;
432 } 449 }
433 450
434 std::ifstream input_file_handle; 451 V8InitializationScope platform(argv[0]);
435 if (!options.read_from_stdin()) { 452
436 input_file_handle.open(options.input_filename().c_str()); 453 std::vector<std::string> snippet_list;
437 if (!input_file_handle.is_open()) { 454
438 std::cerr << "ERROR: Could not open '" << options.input_filename() 455 if (options.read_from_stdin()) {
439 << "' for reading.\n"; 456 ExtractSnippets(&snippet_list, std::cin, options.read_raw_js_snippet());
440 return 2; 457 } else {
458 for (const std::string& input_filename : options.input_filenames()) {
459 if (options.verbose()) {
460 std::cerr << "Processing " << input_filename << '\n';
461 }
462
463 std::ifstream input_stream(input_filename);
464 if (!input_stream.is_open()) {
465 REPORT_ERROR("Could not open " << input_filename << " for reading.");
466 return 2;
467 }
468
469 ProgramOptions updated_options = options;
470 if (options.rebaseline()) {
471 updated_options.UpdateFromHeader(input_stream);
472 CHECK(updated_options.Validate());
473 }
474
475 ExtractSnippets(&snippet_list, input_stream,
476 options.read_raw_js_snippet());
477
478 if (options.rebaseline()) {
479 std::ofstream output_stream(input_filename.c_str());
480 if (!output_stream.is_open()) {
481 REPORT_ERROR("Could not open " << input_filename << " for writing.");
482 return 3;
483 }
484
485 GenerateExpectationsFile(output_stream, snippet_list, platform,
486 updated_options);
rmcilroy 2016/02/25 15:48:23 Could you wrap all the code from 493-550 into a si
Stefano Sanfilippo 2016/02/25 16:34:43 Done.
487 snippet_list.clear();
488 }
441 } 489 }
442 } 490 }
443 std::istream& input_stream =
444 options.read_from_stdin() ? std::cin : input_file_handle;
445 491
446 if (options.rebaseline()) { 492 if (!options.rebaseline()) {
447 options.UpdateFromHeader(input_stream); 493 std::ofstream output_file_handle;
448 CHECK(options.Validate()); 494 if (!options.write_to_stdout()) {
495 output_file_handle.open(options.output_filename().c_str());
496 if (!output_file_handle.is_open()) {
497 REPORT_ERROR("Could not open " << options.output_filename()
498 << " for writing.");
499 return 3;
500 }
501 }
502 std::ostream& output_stream =
503 options.write_to_stdout() ? std::cout : output_file_handle;
504
505 GenerateExpectationsFile(output_stream, snippet_list, platform, options);
449 } 506 }
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 } 507 }
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