Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* GRAPHITE2 LICENSING |
michael@0 | 2 | |
michael@0 | 3 | Copyright 2010, SIL International |
michael@0 | 4 | All rights reserved. |
michael@0 | 5 | |
michael@0 | 6 | This library is free software; you can redistribute it and/or modify |
michael@0 | 7 | it under the terms of the GNU Lesser General Public License as published |
michael@0 | 8 | by the Free Software Foundation; either version 2.1 of License, or |
michael@0 | 9 | (at your option) any later version. |
michael@0 | 10 | |
michael@0 | 11 | This program is distributed in the hope that it will be useful, |
michael@0 | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
michael@0 | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
michael@0 | 14 | Lesser General Public License for more details. |
michael@0 | 15 | |
michael@0 | 16 | You should also have received a copy of the GNU Lesser General Public |
michael@0 | 17 | License along with this library in the file named "LICENSE". |
michael@0 | 18 | If not, write to the Free Software Foundation, 51 Franklin Street, |
michael@0 | 19 | Suite 500, Boston, MA 02110-1335, USA or visit their web page on the |
michael@0 | 20 | internet at http://www.fsf.org/licenses/lgpl.html. |
michael@0 | 21 | |
michael@0 | 22 | Alternatively, the contents of this file may be used under the terms of the |
michael@0 | 23 | Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public |
michael@0 | 24 | License, as published by the Free Software Foundation, either version 2 |
michael@0 | 25 | of the License or (at your option) any later version. |
michael@0 | 26 | */ |
michael@0 | 27 | // This class represents loaded graphite stack machine code. It performs |
michael@0 | 28 | // basic sanity checks, on the incoming code to prevent more obvious problems |
michael@0 | 29 | // from crashing graphite. |
michael@0 | 30 | // Author: Tim Eves |
michael@0 | 31 | |
michael@0 | 32 | #pragma once |
michael@0 | 33 | |
michael@0 | 34 | #include <cassert> |
michael@0 | 35 | #include <graphite2/Types.h> |
michael@0 | 36 | #include "inc/Main.h" |
michael@0 | 37 | #include "inc/Machine.h" |
michael@0 | 38 | |
michael@0 | 39 | namespace graphite2 { |
michael@0 | 40 | |
michael@0 | 41 | class Silf; |
michael@0 | 42 | class Face; |
michael@0 | 43 | |
michael@0 | 44 | namespace vm { |
michael@0 | 45 | |
michael@0 | 46 | class Machine::Code |
michael@0 | 47 | { |
michael@0 | 48 | public: |
michael@0 | 49 | enum status_t |
michael@0 | 50 | { |
michael@0 | 51 | loaded, |
michael@0 | 52 | alloc_failed, |
michael@0 | 53 | invalid_opcode, |
michael@0 | 54 | unimplemented_opcode_used, |
michael@0 | 55 | out_of_range_data, |
michael@0 | 56 | jump_past_end, |
michael@0 | 57 | arguments_exhausted, |
michael@0 | 58 | missing_return, |
michael@0 | 59 | nested_context_item |
michael@0 | 60 | }; |
michael@0 | 61 | |
michael@0 | 62 | private: |
michael@0 | 63 | class decoder; |
michael@0 | 64 | |
michael@0 | 65 | instr * _code; |
michael@0 | 66 | byte * _data; |
michael@0 | 67 | size_t _data_size, |
michael@0 | 68 | _instr_count; |
michael@0 | 69 | byte _max_ref; |
michael@0 | 70 | mutable status_t _status; |
michael@0 | 71 | bool _constraint, |
michael@0 | 72 | _modify, |
michael@0 | 73 | _delete; |
michael@0 | 74 | mutable bool _own; |
michael@0 | 75 | |
michael@0 | 76 | void release_buffers() throw (); |
michael@0 | 77 | void failure(const status_t) throw(); |
michael@0 | 78 | |
michael@0 | 79 | public: |
michael@0 | 80 | Code() throw(); |
michael@0 | 81 | Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end, |
michael@0 | 82 | uint8 pre_context, uint16 rule_length, const Silf &, const Face &); |
michael@0 | 83 | Code(const Machine::Code &) throw(); |
michael@0 | 84 | ~Code() throw(); |
michael@0 | 85 | |
michael@0 | 86 | Code & operator=(const Code &rhs) throw(); |
michael@0 | 87 | operator bool () const throw(); |
michael@0 | 88 | status_t status() const throw(); |
michael@0 | 89 | bool constraint() const throw(); |
michael@0 | 90 | size_t dataSize() const throw(); |
michael@0 | 91 | size_t instructionCount() const throw(); |
michael@0 | 92 | bool immutable() const throw(); |
michael@0 | 93 | bool deletes() const throw(); |
michael@0 | 94 | size_t maxRef() const throw(); |
michael@0 | 95 | |
michael@0 | 96 | int32 run(Machine &m, slotref * & map) const; |
michael@0 | 97 | |
michael@0 | 98 | CLASS_NEW_DELETE; |
michael@0 | 99 | }; |
michael@0 | 100 | |
michael@0 | 101 | inline Machine::Code::Code() throw() |
michael@0 | 102 | : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), |
michael@0 | 103 | _status(loaded), _constraint(false), _modify(false),_delete(false), |
michael@0 | 104 | _own(false) |
michael@0 | 105 | { |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | inline Machine::Code::Code(const Machine::Code &obj) throw () |
michael@0 | 109 | : _code(obj._code), |
michael@0 | 110 | _data(obj._data), |
michael@0 | 111 | _data_size(obj._data_size), |
michael@0 | 112 | _instr_count(obj._instr_count), |
michael@0 | 113 | _max_ref(obj._max_ref), |
michael@0 | 114 | _status(obj._status), |
michael@0 | 115 | _constraint(obj._constraint), |
michael@0 | 116 | _modify(obj._modify), |
michael@0 | 117 | _delete(obj._delete), |
michael@0 | 118 | _own(obj._own) |
michael@0 | 119 | { |
michael@0 | 120 | obj._own = false; |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() { |
michael@0 | 124 | if (_instr_count > 0) |
michael@0 | 125 | release_buffers(); |
michael@0 | 126 | _code = rhs._code; |
michael@0 | 127 | _data = rhs._data; |
michael@0 | 128 | _data_size = rhs._data_size; |
michael@0 | 129 | _instr_count = rhs._instr_count; |
michael@0 | 130 | _status = rhs._status; |
michael@0 | 131 | _constraint = rhs._constraint; |
michael@0 | 132 | _modify = rhs._modify; |
michael@0 | 133 | _delete = rhs._delete; |
michael@0 | 134 | _own = rhs._own; |
michael@0 | 135 | rhs._own = false; |
michael@0 | 136 | return *this; |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | inline Machine::Code::operator bool () const throw () { |
michael@0 | 140 | return _code && status() == loaded; |
michael@0 | 141 | } |
michael@0 | 142 | |
michael@0 | 143 | inline Machine::Code::status_t Machine::Code::status() const throw() { |
michael@0 | 144 | return _status; |
michael@0 | 145 | } |
michael@0 | 146 | |
michael@0 | 147 | inline bool Machine::Code::constraint() const throw() { |
michael@0 | 148 | return _constraint; |
michael@0 | 149 | } |
michael@0 | 150 | |
michael@0 | 151 | inline size_t Machine::Code::dataSize() const throw() { |
michael@0 | 152 | return _data_size; |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | inline size_t Machine::Code::instructionCount() const throw() { |
michael@0 | 156 | return _instr_count; |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | inline bool Machine::Code::immutable() const throw() |
michael@0 | 160 | { |
michael@0 | 161 | return !(_delete || _modify); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | inline bool Machine::Code::deletes() const throw() |
michael@0 | 165 | { |
michael@0 | 166 | return _delete; |
michael@0 | 167 | } |
michael@0 | 168 | |
michael@0 | 169 | inline size_t Machine::Code::maxRef() const throw() |
michael@0 | 170 | { |
michael@0 | 171 | return _max_ref; |
michael@0 | 172 | } |
michael@0 | 173 | |
michael@0 | 174 | } // namespace vm |
michael@0 | 175 | } // namespace graphite2 |