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