11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/torque/torque-compiler.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <fstream> 81cb0ef41Sopenharmony_ci#include "src/torque/declarable.h" 91cb0ef41Sopenharmony_ci#include "src/torque/declaration-visitor.h" 101cb0ef41Sopenharmony_ci#include "src/torque/global-context.h" 111cb0ef41Sopenharmony_ci#include "src/torque/implementation-visitor.h" 121cb0ef41Sopenharmony_ci#include "src/torque/torque-parser.h" 131cb0ef41Sopenharmony_ci#include "src/torque/type-oracle.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_cinamespace torque { 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cinamespace { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_cibase::Optional<std::string> ReadFile(const std::string& path) { 221cb0ef41Sopenharmony_ci std::ifstream file_stream(path); 231cb0ef41Sopenharmony_ci if (!file_stream.good()) return base::nullopt; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci return std::string{std::istreambuf_iterator<char>(file_stream), 261cb0ef41Sopenharmony_ci std::istreambuf_iterator<char>()}; 271cb0ef41Sopenharmony_ci} 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_civoid ReadAndParseTorqueFile(const std::string& path) { 301cb0ef41Sopenharmony_ci SourceId source_id = SourceFileMap::AddSource(path); 311cb0ef41Sopenharmony_ci CurrentSourceFile::Scope source_id_scope(source_id); 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci // path might be either a normal file path or an encoded URI. 341cb0ef41Sopenharmony_ci auto maybe_content = ReadFile(SourceFileMap::AbsolutePath(source_id)); 351cb0ef41Sopenharmony_ci if (!maybe_content) { 361cb0ef41Sopenharmony_ci if (auto maybe_path = FileUriDecode(path)) { 371cb0ef41Sopenharmony_ci maybe_content = ReadFile(*maybe_path); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci if (!maybe_content) { 421cb0ef41Sopenharmony_ci Error("Cannot open file path/uri: ", path).Throw(); 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci ParseTorque(*maybe_content); 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_civoid CompileCurrentAst(TorqueCompilerOptions options) { 491cb0ef41Sopenharmony_ci GlobalContext::Scope global_context(std::move(CurrentAst::Get())); 501cb0ef41Sopenharmony_ci if (options.collect_language_server_data) { 511cb0ef41Sopenharmony_ci GlobalContext::SetCollectLanguageServerData(); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci if (options.collect_kythe_data) { 541cb0ef41Sopenharmony_ci GlobalContext::SetCollectKytheData(); 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci if (options.force_assert_statements) { 571cb0ef41Sopenharmony_ci GlobalContext::SetForceAssertStatements(); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci if (options.annotate_ir) { 601cb0ef41Sopenharmony_ci GlobalContext::SetAnnotateIR(); 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci TargetArchitecture::Scope target_architecture(options.force_32bit_output); 631cb0ef41Sopenharmony_ci TypeOracle::Scope type_oracle; 641cb0ef41Sopenharmony_ci CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace()); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // Two-step process of predeclaration + resolution allows to resolve type 671cb0ef41Sopenharmony_ci // declarations independent of the order they are given. 681cb0ef41Sopenharmony_ci PredeclarationVisitor::Predeclare(GlobalContext::ast()); 691cb0ef41Sopenharmony_ci PredeclarationVisitor::ResolvePredeclarations(); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci // Process other declarations. 721cb0ef41Sopenharmony_ci DeclarationVisitor::Visit(GlobalContext::ast()); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci // A class types' fields are resolved here, which allows two class fields to 751cb0ef41Sopenharmony_ci // mutually refer to each others. 761cb0ef41Sopenharmony_ci TypeOracle::FinalizeAggregateTypes(); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci std::string output_directory = options.output_directory; 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci ImplementationVisitor implementation_visitor; 811cb0ef41Sopenharmony_ci implementation_visitor.SetDryRun(output_directory.length() == 0); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci implementation_visitor.GenerateInstanceTypes(output_directory); 841cb0ef41Sopenharmony_ci implementation_visitor.BeginGeneratedFiles(); 851cb0ef41Sopenharmony_ci implementation_visitor.BeginDebugMacrosFile(); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci implementation_visitor.VisitAllDeclarables(); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci ReportAllUnusedMacros(); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci implementation_visitor.GenerateBuiltinDefinitionsAndInterfaceDescriptors( 921cb0ef41Sopenharmony_ci output_directory); 931cb0ef41Sopenharmony_ci implementation_visitor.GenerateVisitorLists(output_directory); 941cb0ef41Sopenharmony_ci implementation_visitor.GenerateBitFields(output_directory); 951cb0ef41Sopenharmony_ci implementation_visitor.GeneratePrintDefinitions(output_directory); 961cb0ef41Sopenharmony_ci implementation_visitor.GenerateClassDefinitions(output_directory); 971cb0ef41Sopenharmony_ci implementation_visitor.GenerateClassVerifiers(output_directory); 981cb0ef41Sopenharmony_ci implementation_visitor.GenerateClassDebugReaders(output_directory); 991cb0ef41Sopenharmony_ci implementation_visitor.GenerateEnumVerifiers(output_directory); 1001cb0ef41Sopenharmony_ci implementation_visitor.GenerateBodyDescriptors(output_directory); 1011cb0ef41Sopenharmony_ci implementation_visitor.GenerateExportedMacrosAssembler(output_directory); 1021cb0ef41Sopenharmony_ci implementation_visitor.GenerateCSATypes(output_directory); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci implementation_visitor.EndGeneratedFiles(); 1051cb0ef41Sopenharmony_ci implementation_visitor.EndDebugMacrosFile(); 1061cb0ef41Sopenharmony_ci implementation_visitor.GenerateImplementation(output_directory); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci if (GlobalContext::collect_language_server_data()) { 1091cb0ef41Sopenharmony_ci LanguageServerData::SetGlobalContext(std::move(GlobalContext::Get())); 1101cb0ef41Sopenharmony_ci LanguageServerData::SetTypeOracle(std::move(TypeOracle::Get())); 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci} // namespace 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ciTorqueCompilerResult CompileTorque(const std::string& source, 1171cb0ef41Sopenharmony_ci TorqueCompilerOptions options) { 1181cb0ef41Sopenharmony_ci SourceFileMap::Scope source_map_scope(options.v8_root); 1191cb0ef41Sopenharmony_ci CurrentSourceFile::Scope no_file_scope( 1201cb0ef41Sopenharmony_ci SourceFileMap::AddSource("dummy-filename.tq")); 1211cb0ef41Sopenharmony_ci CurrentAst::Scope ast_scope; 1221cb0ef41Sopenharmony_ci TorqueMessages::Scope messages_scope; 1231cb0ef41Sopenharmony_ci LanguageServerData::Scope server_data_scope; 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci TorqueCompilerResult result; 1261cb0ef41Sopenharmony_ci try { 1271cb0ef41Sopenharmony_ci ParseTorque(source); 1281cb0ef41Sopenharmony_ci CompileCurrentAst(options); 1291cb0ef41Sopenharmony_ci } catch (TorqueAbortCompilation&) { 1301cb0ef41Sopenharmony_ci // Do nothing. The relevant TorqueMessage is part of the 1311cb0ef41Sopenharmony_ci // TorqueMessages contextual. 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci result.source_file_map = SourceFileMap::Get(); 1351cb0ef41Sopenharmony_ci result.language_server_data = std::move(LanguageServerData::Get()); 1361cb0ef41Sopenharmony_ci result.messages = std::move(TorqueMessages::Get()); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci return result; 1391cb0ef41Sopenharmony_ci} 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ciTorqueCompilerResult CompileTorque(std::vector<std::string> files, 1421cb0ef41Sopenharmony_ci TorqueCompilerOptions options) { 1431cb0ef41Sopenharmony_ci SourceFileMap::Scope source_map_scope(options.v8_root); 1441cb0ef41Sopenharmony_ci CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid()); 1451cb0ef41Sopenharmony_ci CurrentAst::Scope ast_scope; 1461cb0ef41Sopenharmony_ci TorqueMessages::Scope messages_scope; 1471cb0ef41Sopenharmony_ci LanguageServerData::Scope server_data_scope; 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci TorqueCompilerResult result; 1501cb0ef41Sopenharmony_ci try { 1511cb0ef41Sopenharmony_ci for (const auto& path : files) { 1521cb0ef41Sopenharmony_ci ReadAndParseTorqueFile(path); 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci CompileCurrentAst(options); 1551cb0ef41Sopenharmony_ci } catch (TorqueAbortCompilation&) { 1561cb0ef41Sopenharmony_ci // Do nothing. The relevant TorqueMessage is part of the 1571cb0ef41Sopenharmony_ci // TorqueMessages contextual. 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci result.source_file_map = SourceFileMap::Get(); 1611cb0ef41Sopenharmony_ci result.language_server_data = std::move(LanguageServerData::Get()); 1621cb0ef41Sopenharmony_ci result.messages = std::move(TorqueMessages::Get()); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci return result; 1651cb0ef41Sopenharmony_ci} 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ciTorqueCompilerResult CompileTorqueForKythe( 1681cb0ef41Sopenharmony_ci std::vector<TorqueCompilationUnit> units, TorqueCompilerOptions options, 1691cb0ef41Sopenharmony_ci KytheConsumer* consumer) { 1701cb0ef41Sopenharmony_ci SourceFileMap::Scope source_map_scope(options.v8_root); 1711cb0ef41Sopenharmony_ci CurrentSourceFile::Scope unknown_source_file_scope(SourceId::Invalid()); 1721cb0ef41Sopenharmony_ci CurrentAst::Scope ast_scope; 1731cb0ef41Sopenharmony_ci TorqueMessages::Scope messages_scope; 1741cb0ef41Sopenharmony_ci LanguageServerData::Scope server_data_scope; 1751cb0ef41Sopenharmony_ci KytheData::Scope kythe_scope; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci KytheData::Get().SetConsumer(consumer); 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci TorqueCompilerResult result; 1801cb0ef41Sopenharmony_ci try { 1811cb0ef41Sopenharmony_ci for (const auto& unit : units) { 1821cb0ef41Sopenharmony_ci SourceId source_id = SourceFileMap::AddSource(unit.source_file_path); 1831cb0ef41Sopenharmony_ci CurrentSourceFile::Scope source_id_scope(source_id); 1841cb0ef41Sopenharmony_ci ParseTorque(unit.file_content); 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci CompileCurrentAst(options); 1871cb0ef41Sopenharmony_ci } catch (TorqueAbortCompilation&) { 1881cb0ef41Sopenharmony_ci // Do nothing. The relevant TorqueMessage is part of the 1891cb0ef41Sopenharmony_ci // TorqueMessages contextual. 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci result.source_file_map = SourceFileMap::Get(); 1931cb0ef41Sopenharmony_ci result.language_server_data = std::move(LanguageServerData::Get()); 1941cb0ef41Sopenharmony_ci result.messages = std::move(TorqueMessages::Get()); 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci return result; 1971cb0ef41Sopenharmony_ci} 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci} // namespace torque 2001cb0ef41Sopenharmony_ci} // namespace internal 2011cb0ef41Sopenharmony_ci} // namespace v8 202