123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "courgette/courgette_flow.h"
- #include <stdarg.h>
- #include <memory>
- #include "base/check.h"
- #include "base/files/file_path.h"
- #include "base/memory/ptr_util.h"
- #include "base/notreached.h"
- #include "base/strings/stringprintf.h"
- #include "courgette/assembly_program.h"
- #include "courgette/disassembler.h"
- #include "courgette/encoded_program.h"
- #include "courgette/program_detector.h"
- namespace courgette {
- /******** CourgetteFlow::Data ********/
- CourgetteFlow::Data::Data() = default;
- CourgetteFlow::Data::~Data() = default;
- /******** CourgetteFlow ********/
- CourgetteFlow::CourgetteFlow() = default;
- CourgetteFlow::~CourgetteFlow() = default;
- // static
- const char* CourgetteFlow::name(Group group) {
- switch (group) {
- case ONLY:
- return "input";
- case OLD:
- return "'old' input";
- case NEW:
- return "'new' input";
- default:
- NOTREACHED();
- break;
- }
- return nullptr;
- }
- CourgetteFlow::Data* CourgetteFlow::data(Group group) {
- switch (group) {
- case ONLY:
- return &data_only_;
- case OLD:
- return &data_old_;
- case NEW:
- return &data_new_;
- default:
- NOTREACHED();
- break;
- }
- return nullptr;
- }
- bool CourgetteFlow::ok() {
- return status_ == C_OK;
- }
- bool CourgetteFlow::failed() {
- return status_ != C_OK;
- }
- Status CourgetteFlow::status() {
- return status_;
- }
- const std::string& CourgetteFlow::message() {
- return message_;
- }
- void CourgetteFlow::ReadSourceStreamSetFromBuffer(Group group,
- const BasicBuffer& buffer) {
- if (failed())
- return;
- Data* d = data(group);
- if (!check(d->sources.Init(buffer.data(), buffer.length()),
- C_GENERAL_ERROR)) {
- setMessage("Cannot read %s as SourceStreamSet.", name(group));
- }
- }
- void CourgetteFlow::ReadDisassemblerFromBuffer(Group group,
- const BasicBuffer& buffer) {
- if (failed())
- return;
- Data* d = data(group);
- d->disassembler = DetectDisassembler(buffer.data(), buffer.length());
- if (!check(d->disassembler.get() != nullptr, C_INPUT_NOT_RECOGNIZED))
- setMessage("Cannot detect program for %s.", name(group));
- }
- void CourgetteFlow::ReadEncodedProgramFromSourceStreamSet(
- Group group,
- SourceStreamSet* opt_sources /* nullptr */) {
- if (failed())
- return;
- Data* d = data(group);
- SourceStreamSet* sources = opt_sources ? opt_sources : &d->sources;
- if (!check(ReadEncodedProgram(sources, &d->encoded)))
- setMessage("Cannot read %s as encoded program.", name(group));
- }
- void CourgetteFlow::CreateAssemblyProgramFromDisassembler(Group group,
- bool annotate) {
- if (failed())
- return;
- Data* d = data(group);
- d->program = d->disassembler->CreateProgram(annotate);
- if (!check(d->program.get() != nullptr, C_DISASSEMBLY_FAILED))
- setMessage("Cannot create AssemblyProgram for %s.", name(group));
- }
- void CourgetteFlow::CreateEncodedProgramFromDisassemblerAndAssemblyProgram(
- Group group) {
- if (failed())
- return;
- Data* d = data(group);
- d->encoded = std::make_unique<EncodedProgram>();
- if (!check(d->disassembler->DisassembleAndEncode(d->program.get(),
- d->encoded.get()))) {
- setMessage("Cannot disassemble to form EncodedProgram for %s.",
- name(group));
- }
- }
- void CourgetteFlow::WriteSinkStreamFromSinkStreamSet(Group group,
- SinkStream* sink) {
- DCHECK(sink);
- if (failed())
- return;
- if (!check(data(group)->sinks.CopyTo(sink), C_GENERAL_ERROR))
- setMessage("Cannnot combine serialized streams for %s.", name(group));
- }
- void CourgetteFlow::WriteSinkStreamSetFromEncodedProgram(
- Group group,
- SinkStreamSet* opt_sinks /* nullptr */) {
- if (failed())
- return;
- Data* d = data(group);
- SinkStreamSet* sinks = opt_sinks ? opt_sinks : &d->sinks;
- if (!check(WriteEncodedProgram(d->encoded.get(), sinks)))
- setMessage("Cannot serialize encoded %s.", name(group));
- }
- void CourgetteFlow::WriteExecutableFromEncodedProgram(Group group,
- SinkStream* sink) {
- DCHECK(sink);
- if (failed())
- return;
- if (!check(Assemble(data(group)->encoded.get(), sink)))
- setMessage("Cannot assemble %s.", name(group));
- }
- void CourgetteFlow::AdjustNewAssemblyProgramToMatchOld() {
- if (failed())
- return;
- if (!check(Adjust(*data_old_.program, data_new_.program.get())))
- setMessage("Cannot adjust %s to match %s.", name(OLD), name(NEW));
- }
- void CourgetteFlow::DestroyDisassembler(Group group) {
- if (failed())
- return;
- data(group)->disassembler.reset();
- }
- void CourgetteFlow::DestroyAssemblyProgram(Group group) {
- if (failed())
- return;
- data(group)->program.reset();
- }
- void CourgetteFlow::DestroyEncodedProgram(Group group) {
- if (failed())
- return;
- data(group)->encoded.reset();
- }
- bool CourgetteFlow::check(Status new_status) {
- if (new_status == C_OK)
- return true;
- status_ = new_status;
- return false;
- }
- bool CourgetteFlow::check(bool success, Status failure_mode) {
- if (success)
- return true;
- status_ = failure_mode;
- return false;
- }
- void CourgetteFlow::setMessage(const char* format, ...) {
- va_list args;
- va_start(args, format);
- message_ = base::StringPrintV(format, args);
- va_end(args);
- }
- } // namespace courgette
|