Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/graphite/src/inc/Code.h
9906 views
1
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
2
// Copyright 2010, SIL International, All rights reserved.
3
4
// This class represents loaded graphite stack machine code. It performs
5
// basic sanity checks, on the incoming code to prevent more obvious problems
6
// from crashing graphite.
7
// Author: Tim Eves
8
9
#pragma once
10
11
#include <cassert>
12
#include <graphite2/Types.h>
13
#include "inc/Main.h"
14
#include "inc/Machine.h"
15
16
namespace graphite2 {
17
18
class Silf;
19
class Face;
20
21
enum passtype {
22
PASS_TYPE_UNKNOWN = 0,
23
PASS_TYPE_LINEBREAK,
24
PASS_TYPE_SUBSTITUTE,
25
PASS_TYPE_POSITIONING,
26
PASS_TYPE_JUSTIFICATION
27
};
28
29
namespace vm {
30
31
class Machine::Code
32
{
33
public:
34
enum status_t
35
{
36
loaded,
37
alloc_failed,
38
invalid_opcode,
39
unimplemented_opcode_used,
40
out_of_range_data,
41
jump_past_end,
42
arguments_exhausted,
43
missing_return,
44
nested_context_item,
45
underfull_stack
46
};
47
48
private:
49
class decoder;
50
51
instr * _code;
52
byte * _data;
53
size_t _data_size,
54
_instr_count;
55
byte _max_ref;
56
mutable status_t _status;
57
bool _constraint,
58
_modify,
59
_delete;
60
mutable bool _own;
61
62
void release_buffers() throw ();
63
void failure(const status_t) throw();
64
65
public:
66
static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);
67
68
Code() throw();
69
Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
70
uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
71
enum passtype pt, byte * * const _out = 0);
72
Code(const Machine::Code &) throw();
73
~Code() throw();
74
75
Code & operator=(const Code &rhs) throw();
76
operator bool () const throw() { return _code && status() == loaded; }
77
status_t status() const throw() { return _status; }
78
bool constraint() const throw() { return _constraint; }
79
size_t dataSize() const throw() { return _data_size; }
80
size_t instructionCount() const throw() { return _instr_count; }
81
bool immutable() const throw() { return !(_delete || _modify); }
82
bool deletes() const throw() { return _delete; }
83
size_t maxRef() const throw() { return _max_ref; }
84
void externalProgramMoved(ptrdiff_t) throw();
85
86
int32 run(Machine &m, slotref * & map) const;
87
88
CLASS_NEW_DELETE;
89
};
90
91
inline
92
size_t Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)
93
{
94
// max is: all codes are instructions + 1 for each rule + max tempcopies
95
// allocate space for separate maximal code and data then merge them later
96
return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * sizeof(byte);
97
}
98
99
100
inline Machine::Code::Code() throw()
101
: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
102
_status(loaded), _constraint(false), _modify(false), _delete(false),
103
_own(false)
104
{
105
}
106
107
inline Machine::Code::Code(const Machine::Code &obj) throw ()
108
: _code(obj._code),
109
_data(obj._data),
110
_data_size(obj._data_size),
111
_instr_count(obj._instr_count),
112
_max_ref(obj._max_ref),
113
_status(obj._status),
114
_constraint(obj._constraint),
115
_modify(obj._modify),
116
_delete(obj._delete),
117
_own(obj._own)
118
{
119
obj._own = false;
120
}
121
122
inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() {
123
if (_instr_count > 0)
124
release_buffers();
125
_code = rhs._code;
126
_data = rhs._data;
127
_data_size = rhs._data_size;
128
_instr_count = rhs._instr_count;
129
_status = rhs._status;
130
_constraint = rhs._constraint;
131
_modify = rhs._modify;
132
_delete = rhs._delete;
133
_own = rhs._own;
134
rhs._own = false;
135
return *this;
136
}
137
138
inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
139
{
140
if (_code && !_own)
141
{
142
_code += dist / signed(sizeof(instr));
143
_data += dist;
144
}
145
}
146
147
} // namespace vm
148
} // namespace graphite2
149
150