gfx/graphite2/src/inc/Machine.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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 general interpreter interface.
michael@0 28 // Author: Tim Eves
michael@0 29
michael@0 30 // Build one of direct_machine.cpp or call_machine.cpp to implement this
michael@0 31 // interface.
michael@0 32
michael@0 33 #pragma once
michael@0 34 #include <cstring>
michael@0 35 #include <graphite2/Types.h>
michael@0 36 #include "inc/Main.h"
michael@0 37
michael@0 38 #if defined(__GNUC__)
michael@0 39 #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ * 10) < 430
michael@0 40 #define HOT
michael@0 41 #if defined(__x86_64)
michael@0 42 #define REGPARM(n) __attribute__((regparm(n)))
michael@0 43 #else
michael@0 44 #define REGPARM(n)
michael@0 45 #endif
michael@0 46 #else
michael@0 47 #define HOT __attribute__((hot))
michael@0 48 #if defined(__x86_64)
michael@0 49 #define REGPARM(n) __attribute__((hot, regparm(n)))
michael@0 50 #else
michael@0 51 #define REGPARM(n)
michael@0 52 #endif
michael@0 53 #endif
michael@0 54 #else
michael@0 55 #define HOT
michael@0 56 #define REGPARM(n)
michael@0 57 #endif
michael@0 58
michael@0 59 namespace graphite2 {
michael@0 60
michael@0 61 // Forward declarations
michael@0 62 class Segment;
michael@0 63 class Slot;
michael@0 64 class SlotMap;
michael@0 65
michael@0 66
michael@0 67 namespace vm
michael@0 68 {
michael@0 69
michael@0 70
michael@0 71 typedef void * instr;
michael@0 72 typedef Slot * slotref;
michael@0 73
michael@0 74 enum {VARARGS = 0xff, MAX_NAME_LEN=32};
michael@0 75
michael@0 76 enum opcode {
michael@0 77 NOP = 0,
michael@0 78
michael@0 79 PUSH_BYTE, PUSH_BYTEU, PUSH_SHORT, PUSH_SHORTU, PUSH_LONG,
michael@0 80
michael@0 81 ADD, SUB, MUL, DIV,
michael@0 82 MIN_, MAX_,
michael@0 83 NEG,
michael@0 84 TRUNC8, TRUNC16,
michael@0 85
michael@0 86 COND,
michael@0 87
michael@0 88 AND, OR, NOT,
michael@0 89 EQUAL, NOT_EQ,
michael@0 90 LESS, GTR, LESS_EQ, GTR_EQ,
michael@0 91
michael@0 92 NEXT, NEXT_N, COPY_NEXT,
michael@0 93 PUT_GLYPH_8BIT_OBS, PUT_SUBS_8BIT_OBS, PUT_COPY,
michael@0 94 INSERT, DELETE,
michael@0 95 ASSOC,
michael@0 96 CNTXT_ITEM,
michael@0 97
michael@0 98 ATTR_SET, ATTR_ADD, ATTR_SUB,
michael@0 99 ATTR_SET_SLOT,
michael@0 100 IATTR_SET_SLOT,
michael@0 101 PUSH_SLOT_ATTR, PUSH_GLYPH_ATTR_OBS,
michael@0 102 PUSH_GLYPH_METRIC, PUSH_FEAT,
michael@0 103 PUSH_ATT_TO_GATTR_OBS, PUSH_ATT_TO_GLYPH_METRIC,
michael@0 104 PUSH_ISLOT_ATTR,
michael@0 105
michael@0 106 PUSH_IGLYPH_ATTR, // not implemented
michael@0 107
michael@0 108 POP_RET, RET_ZERO, RET_TRUE,
michael@0 109 IATTR_SET, IATTR_ADD, IATTR_SUB,
michael@0 110 PUSH_PROC_STATE, PUSH_VERSION,
michael@0 111 PUT_SUBS, PUT_SUBS2, PUT_SUBS3,
michael@0 112 PUT_GLYPH, PUSH_GLYPH_ATTR, PUSH_ATT_TO_GLYPH_ATTR,
michael@0 113 MAX_OPCODE,
michael@0 114 // private opcodes for internal use only, comes after all other on disk opcodes
michael@0 115 TEMP_COPY = MAX_OPCODE
michael@0 116 };
michael@0 117
michael@0 118 struct opcode_t
michael@0 119 {
michael@0 120 instr impl[2];
michael@0 121 uint8 param_sz;
michael@0 122 char name[MAX_NAME_LEN];
michael@0 123 };
michael@0 124
michael@0 125
michael@0 126 class Machine
michael@0 127 {
michael@0 128 public:
michael@0 129 typedef int32 stack_t;
michael@0 130 static size_t const STACK_ORDER = 10,
michael@0 131 STACK_MAX = 1 << STACK_ORDER,
michael@0 132 STACK_GUARD = 2;
michael@0 133
michael@0 134 class Code;
michael@0 135
michael@0 136 enum status_t {
michael@0 137 finished = 0,
michael@0 138 stack_underflow,
michael@0 139 stack_not_empty,
michael@0 140 stack_overflow,
michael@0 141 slot_offset_out_bounds
michael@0 142 };
michael@0 143
michael@0 144 Machine(SlotMap &) throw();
michael@0 145 static const opcode_t * getOpcodeTable() throw();
michael@0 146
michael@0 147 CLASS_NEW_DELETE;
michael@0 148
michael@0 149 SlotMap & slotMap() const throw();
michael@0 150 status_t status() const throw();
michael@0 151 operator bool () const throw();
michael@0 152
michael@0 153 private:
michael@0 154 void check_final_stack(const stack_t * const sp);
michael@0 155 stack_t run(const instr * program, const byte * data,
michael@0 156 slotref * & map) HOT;
michael@0 157
michael@0 158 SlotMap & _map;
michael@0 159 stack_t _stack[STACK_MAX + 2*STACK_GUARD];
michael@0 160 status_t _status;
michael@0 161 };
michael@0 162
michael@0 163 inline Machine::Machine(SlotMap & map) throw()
michael@0 164 : _map(map), _status(finished)
michael@0 165 {
michael@0 166 // Initialise stack guard +1 entries as the stack pointer points to the
michael@0 167 // current top of stack, hence the first push will never write entry 0.
michael@0 168 // Initialising the guard space like this is unnecessary and is only
michael@0 169 // done to keep valgrind happy during fuzz testing. Hopefully loop
michael@0 170 // unrolling will flatten this.
michael@0 171 for (size_t n = STACK_GUARD + 1; n; --n) _stack[n-1] = 0;
michael@0 172 }
michael@0 173
michael@0 174 inline SlotMap& Machine::slotMap() const throw()
michael@0 175 {
michael@0 176 return _map;
michael@0 177 }
michael@0 178
michael@0 179 inline Machine::status_t Machine::status() const throw()
michael@0 180 {
michael@0 181 return _status;
michael@0 182 }
michael@0 183
michael@0 184 inline void Machine::check_final_stack(const int32 * const sp)
michael@0 185 {
michael@0 186 stack_t const * const base = _stack + STACK_GUARD,
michael@0 187 * const limit = base + STACK_MAX;
michael@0 188 if (sp < base) _status = stack_underflow; // This should be impossible now.
michael@0 189 else if (sp >= limit) _status = stack_overflow; // So should this.
michael@0 190 else if (sp != base) _status = stack_not_empty;
michael@0 191 }
michael@0 192
michael@0 193 } // namespace vm
michael@0 194 } // namespace graphite2
michael@0 195
michael@0 196
michael@0 197

mercurial