Path: blob/master/thirdparty/graphite/src/inc/Code.h
10279 views
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later1// Copyright 2010, SIL International, All rights reserved.23// This class represents loaded graphite stack machine code. It performs4// basic sanity checks, on the incoming code to prevent more obvious problems5// from crashing graphite.6// Author: Tim Eves78#pragma once910#include <cassert>11#include <graphite2/Types.h>12#include "inc/Main.h"13#include "inc/Machine.h"1415namespace graphite2 {1617class Silf;18class Face;1920enum passtype {21PASS_TYPE_UNKNOWN = 0,22PASS_TYPE_LINEBREAK,23PASS_TYPE_SUBSTITUTE,24PASS_TYPE_POSITIONING,25PASS_TYPE_JUSTIFICATION26};2728namespace vm {2930class Machine::Code31{32public:33enum status_t34{35loaded,36alloc_failed,37invalid_opcode,38unimplemented_opcode_used,39out_of_range_data,40jump_past_end,41arguments_exhausted,42missing_return,43nested_context_item,44underfull_stack45};4647private:48class decoder;4950instr * _code;51byte * _data;52size_t _data_size,53_instr_count;54byte _max_ref;55mutable status_t _status;56bool _constraint,57_modify,58_delete;59mutable bool _own;6061void release_buffers() throw ();62void failure(const status_t) throw();6364public:65static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);6667Code() throw();68Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,69uint8 pre_context, uint16 rule_length, const Silf &, const Face &,70enum passtype pt, byte * * const _out = 0);71Code(const Machine::Code &) throw();72~Code() throw();7374Code & operator=(const Code &rhs) throw();75operator bool () const throw() { return _code && status() == loaded; }76status_t status() const throw() { return _status; }77bool constraint() const throw() { return _constraint; }78size_t dataSize() const throw() { return _data_size; }79size_t instructionCount() const throw() { return _instr_count; }80bool immutable() const throw() { return !(_delete || _modify); }81bool deletes() const throw() { return _delete; }82size_t maxRef() const throw() { return _max_ref; }83void externalProgramMoved(ptrdiff_t) throw();8485int32 run(Machine &m, slotref * & map) const;8687CLASS_NEW_DELETE;88};8990inline91size_t Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)92{93// max is: all codes are instructions + 1 for each rule + max tempcopies94// allocate space for separate maximal code and data then merge them later95return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * sizeof(byte);96}979899inline Machine::Code::Code() throw()100: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),101_status(loaded), _constraint(false), _modify(false), _delete(false),102_own(false)103{104}105106inline Machine::Code::Code(const Machine::Code &obj) throw ()107: _code(obj._code),108_data(obj._data),109_data_size(obj._data_size),110_instr_count(obj._instr_count),111_max_ref(obj._max_ref),112_status(obj._status),113_constraint(obj._constraint),114_modify(obj._modify),115_delete(obj._delete),116_own(obj._own)117{118obj._own = false;119}120121inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() {122if (_instr_count > 0)123release_buffers();124_code = rhs._code;125_data = rhs._data;126_data_size = rhs._data_size;127_instr_count = rhs._instr_count;128_status = rhs._status;129_constraint = rhs._constraint;130_modify = rhs._modify;131_delete = rhs._delete;132_own = rhs._own;133rhs._own = false;134return *this;135}136137inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()138{139if (_code && !_own)140{141_code += dist / signed(sizeof(instr));142_data += dist;143}144}145146} // namespace vm147} // namespace graphite2148149150