11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2013 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/tools/profile_reset/jtl_compiler.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <limits> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <map> 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <numeric> 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profile_resetter/jtl_foundation.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/tools/profile_reset/jtl_parser.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace jtl = jtl_foundation; 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Serializes symbols into byte-code in a streaming manner. 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ByteCodeWriter { 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci explicit ByteCodeWriter(std::string* output) : output_(output) {} 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ~ByteCodeWriter() {} 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); } 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void WriteUint32(uint32 value) { 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (int i = 0; i < 4; ++i) { 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output_->push_back(static_cast<char>(value & 0xFFu)); 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci value >>= 8; 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void WriteOpCode(uint8 op_code) { WriteUint8(op_code); } 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void WriteHash(const std::string& hash) { 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(jtl::Hasher::IsHash(hash)); 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *output_ += hash; 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); } 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string* output_; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter); 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Encapsulates meta-data about all instructions, and is capable of transcoding 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// each instruction from a parsed text-based format to byte-code. 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass InstructionSet { 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InstructionSet() { 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Define each instruction in this list. 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Note: 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // - Instructions ending in "hash" will write their 'HashString' arguments 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // directly into the byte-code. 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // - Instructions ending in "hashed" will first hash their 'String' 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // arguments, and will write this hash to the byte-code. 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("go", jtl::NAVIGATE, Arguments(String))); 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments())); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments())); 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(String, Bool))); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_hash", 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::STORE_HASH, Arguments(String, HashString))); 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_hashed", 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::STORE_HASH, Arguments(String, String))); 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_node_bool", 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::STORE_NODE_BOOL, Arguments(String))); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_node_hash", 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::STORE_NODE_HASH, Arguments(String))); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("store_node_registerable_domain_hash", 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::STORE_NODE_REGISTERABLE_DOMAIN_HASH, 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(String))); 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool))); 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_hashed", 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_NODE_HASH, Arguments(String))); 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_hashed_not", 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_NODE_HASH_NOT, Arguments(String))); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_stored_bool", 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_STORED_BOOL, 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(String, Bool, Bool))); 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_stored_hashed", 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_STORED_HASH, 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(String, String, String))); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_to_stored_bool", 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_NODE_TO_STORED_BOOL, 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(String))); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_to_stored_hash", 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_NODE_TO_STORED_HASH, 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(String))); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("compare_substring_hashed", 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::COMPARE_NODE_SUBSTRING, 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Arguments(StringPattern))); 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments())); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci JtlCompiler::CompileError::ErrorCode TranscodeInstruction( 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::ListValue& arguments, 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ends_sentence, 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const jtl::Hasher& hasher, 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ByteCodeWriter* target) const { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (instruction_map_.count(name) == 0) 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_OPERATION_NAME; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Instruction& instruction(instruction_map_.at(name)); 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (instruction.argument_types.size() != arguments.GetSize()) 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT; 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteOpCode(instruction.op_code); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < arguments.GetSize(); ++i) { 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (instruction.argument_types[i]) { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case Bool: { 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool value = false; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!arguments.GetBoolean(i, &value)) 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteBool(value); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case String: { 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string value; 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!arguments.GetString(i, &value)) 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteHash(hasher.GetHash(value)); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case StringPattern: { 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string value; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!arguments.GetString(i, &value)) 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (value.empty() || 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci value.size() > std::numeric_limits<uint32>::max()) 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteHash(hasher.GetHash(value)); 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteUint32(static_cast<uint32>(value.size())); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 pattern_sum = std::accumulate( 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci value.begin(), value.end(), static_cast<uint32>(0u)); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteUint32(pattern_sum); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case HashString: { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string hash_value; 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!arguments.GetString(i, &hash_value) || 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !jtl::Hasher::IsHash(hash_value)) 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteHash(hash_value); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ends_sentence) 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci target->WriteOpCode(jtl::END_OF_SENTENCE); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return JtlCompiler::CompileError::ERROR_NONE; 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The possible types of an operation's argument. 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enum ArgumentType { 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci None, 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Bool, 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci String, 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StringPattern, 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HashString 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Encapsulates meta-data about one instruction. 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct Instruction { 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Instruction() : op_code(jtl::END_OF_SENTENCE) {} 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Instruction(const char* name, 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl_foundation::OpCodes op_code, 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<ArgumentType>& argument_types) 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : name(name), op_code(op_code), argument_types(argument_types) {} 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string name; 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::OpCodes op_code; 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<ArgumentType> argument_types; 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None, 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ArgumentType arg2_type = None, 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ArgumentType arg3_type = None) { 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<ArgumentType> result; 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (arg1_type != None) 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci result.push_back(arg1_type); 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (arg2_type != None) 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci result.push_back(arg2_type); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (arg3_type != None) 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci result.push_back(arg3_type); 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result; 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void Add(const Instruction& instruction) { 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci instruction_map_[instruction.name] = instruction; 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<std::string, Instruction> instruction_map_; 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(InstructionSet); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool JtlCompiler::Compile(const std::string& source_code, 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& hash_seed, 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string* output_bytecode, 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompileError* error_details) { 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(output_bytecode); 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InstructionSet instruction_set; 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ByteCodeWriter bytecode_writer(output_bytecode); 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jtl::Hasher hasher(hash_seed); 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string compacted_source_code; 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<size_t> newline_indices; 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t mismatched_quotes_line; 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!JtlParser::RemoveCommentsAndAllWhitespace(source_code, 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &compacted_source_code, 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &newline_indices, 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &mismatched_quotes_line)) { 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_details) { 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->context = ""; // No meaningful intra-line context here. 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->line_number = mismatched_quotes_line; 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->error_code = CompileError::MISMATCHED_DOUBLE_QUOTES; 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci JtlParser parser(compacted_source_code, newline_indices); 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (!parser.HasFinished()) { 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string operation_name; 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ListValue arguments; 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool ends_sentence = false; 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!parser.ParseNextOperation( 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &operation_name, &arguments, &ends_sentence)) { 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_details) { 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->context = parser.GetLastContext(); 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->line_number = parser.GetLastLineNumber(); 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->error_code = CompileError::PARSING_ERROR; 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CompileError::ErrorCode error_code = instruction_set.TranscodeInstruction( 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci operation_name, arguments, ends_sentence, hasher, &bytecode_writer); 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_code != CompileError::ERROR_NONE) { 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_details) { 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->context = parser.GetLastContext(); 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->line_number = parser.GetLastLineNumber(); 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_details->error_code = error_code; 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 253