1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/graphite2/src/inc/Code.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +/* GRAPHITE2 LICENSING 1.5 + 1.6 + Copyright 2010, SIL International 1.7 + All rights reserved. 1.8 + 1.9 + This library is free software; you can redistribute it and/or modify 1.10 + it under the terms of the GNU Lesser General Public License as published 1.11 + by the Free Software Foundation; either version 2.1 of License, or 1.12 + (at your option) any later version. 1.13 + 1.14 + This program is distributed in the hope that it will be useful, 1.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + Lesser General Public License for more details. 1.18 + 1.19 + You should also have received a copy of the GNU Lesser General Public 1.20 + License along with this library in the file named "LICENSE". 1.21 + If not, write to the Free Software Foundation, 51 Franklin Street, 1.22 + Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 1.23 + internet at http://www.fsf.org/licenses/lgpl.html. 1.24 + 1.25 +Alternatively, the contents of this file may be used under the terms of the 1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public 1.27 +License, as published by the Free Software Foundation, either version 2 1.28 +of the License or (at your option) any later version. 1.29 +*/ 1.30 +// This class represents loaded graphite stack machine code. It performs 1.31 +// basic sanity checks, on the incoming code to prevent more obvious problems 1.32 +// from crashing graphite. 1.33 +// Author: Tim Eves 1.34 + 1.35 +#pragma once 1.36 + 1.37 +#include <cassert> 1.38 +#include <graphite2/Types.h> 1.39 +#include "inc/Main.h" 1.40 +#include "inc/Machine.h" 1.41 + 1.42 +namespace graphite2 { 1.43 + 1.44 +class Silf; 1.45 +class Face; 1.46 + 1.47 +namespace vm { 1.48 + 1.49 +class Machine::Code 1.50 +{ 1.51 +public: 1.52 + enum status_t 1.53 + { 1.54 + loaded, 1.55 + alloc_failed, 1.56 + invalid_opcode, 1.57 + unimplemented_opcode_used, 1.58 + out_of_range_data, 1.59 + jump_past_end, 1.60 + arguments_exhausted, 1.61 + missing_return, 1.62 + nested_context_item 1.63 + }; 1.64 + 1.65 +private: 1.66 + class decoder; 1.67 + 1.68 + instr * _code; 1.69 + byte * _data; 1.70 + size_t _data_size, 1.71 + _instr_count; 1.72 + byte _max_ref; 1.73 + mutable status_t _status; 1.74 + bool _constraint, 1.75 + _modify, 1.76 + _delete; 1.77 + mutable bool _own; 1.78 + 1.79 + void release_buffers() throw (); 1.80 + void failure(const status_t) throw(); 1.81 + 1.82 +public: 1.83 + Code() throw(); 1.84 + Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end, 1.85 + uint8 pre_context, uint16 rule_length, const Silf &, const Face &); 1.86 + Code(const Machine::Code &) throw(); 1.87 + ~Code() throw(); 1.88 + 1.89 + Code & operator=(const Code &rhs) throw(); 1.90 + operator bool () const throw(); 1.91 + status_t status() const throw(); 1.92 + bool constraint() const throw(); 1.93 + size_t dataSize() const throw(); 1.94 + size_t instructionCount() const throw(); 1.95 + bool immutable() const throw(); 1.96 + bool deletes() const throw(); 1.97 + size_t maxRef() const throw(); 1.98 + 1.99 + int32 run(Machine &m, slotref * & map) const; 1.100 + 1.101 + CLASS_NEW_DELETE; 1.102 +}; 1.103 + 1.104 +inline Machine::Code::Code() throw() 1.105 +: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), 1.106 + _status(loaded), _constraint(false), _modify(false),_delete(false), 1.107 + _own(false) 1.108 +{ 1.109 +} 1.110 + 1.111 +inline Machine::Code::Code(const Machine::Code &obj) throw () 1.112 + : _code(obj._code), 1.113 + _data(obj._data), 1.114 + _data_size(obj._data_size), 1.115 + _instr_count(obj._instr_count), 1.116 + _max_ref(obj._max_ref), 1.117 + _status(obj._status), 1.118 + _constraint(obj._constraint), 1.119 + _modify(obj._modify), 1.120 + _delete(obj._delete), 1.121 + _own(obj._own) 1.122 +{ 1.123 + obj._own = false; 1.124 +} 1.125 + 1.126 +inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() { 1.127 + if (_instr_count > 0) 1.128 + release_buffers(); 1.129 + _code = rhs._code; 1.130 + _data = rhs._data; 1.131 + _data_size = rhs._data_size; 1.132 + _instr_count = rhs._instr_count; 1.133 + _status = rhs._status; 1.134 + _constraint = rhs._constraint; 1.135 + _modify = rhs._modify; 1.136 + _delete = rhs._delete; 1.137 + _own = rhs._own; 1.138 + rhs._own = false; 1.139 + return *this; 1.140 +} 1.141 + 1.142 +inline Machine::Code::operator bool () const throw () { 1.143 + return _code && status() == loaded; 1.144 +} 1.145 + 1.146 +inline Machine::Code::status_t Machine::Code::status() const throw() { 1.147 + return _status; 1.148 +} 1.149 + 1.150 +inline bool Machine::Code::constraint() const throw() { 1.151 + return _constraint; 1.152 +} 1.153 + 1.154 +inline size_t Machine::Code::dataSize() const throw() { 1.155 + return _data_size; 1.156 +} 1.157 + 1.158 +inline size_t Machine::Code::instructionCount() const throw() { 1.159 + return _instr_count; 1.160 +} 1.161 + 1.162 +inline bool Machine::Code::immutable() const throw() 1.163 +{ 1.164 + return !(_delete || _modify); 1.165 +} 1.166 + 1.167 +inline bool Machine::Code::deletes() const throw() 1.168 +{ 1.169 + return _delete; 1.170 +} 1.171 + 1.172 +inline size_t Machine::Code::maxRef() const throw() 1.173 +{ 1.174 + return _max_ref; 1.175 +} 1.176 + 1.177 +} // namespace vm 1.178 +} // namespace graphite2