gfx/graphite2/src/direct_machine.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

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 direct threaded interpreter implmentation for machine.h
michael@0 28 // Author: Tim Eves
michael@0 29
michael@0 30 // Build either this interpreter or the call_machine implementation.
michael@0 31 // The direct threaded interpreter is relies upon a gcc feature called
michael@0 32 // labels-as-values so is only portable to compilers that support the
michael@0 33 // extension (gcc only as far as I know) however it should build on any
michael@0 34 // architecture gcc supports.
michael@0 35 // This is twice as fast as the call threaded model and is likely faster on
michael@0 36 // inorder processors with short pipelines and little branch prediction such
michael@0 37 // as the ARM and possibly Atom chips.
michael@0 38
michael@0 39
michael@0 40 #include <cassert>
michael@0 41 #include <cstring>
michael@0 42 #include "inc/Machine.h"
michael@0 43 #include "inc/Segment.h"
michael@0 44 #include "inc/Slot.h"
michael@0 45 #include "inc/Rule.h"
michael@0 46
michael@0 47 #define STARTOP(name) name: {
michael@0 48 #define ENDOP }; goto *((sp - sb)/Machine::STACK_MAX ? &&end : *++ip);
michael@0 49 #define EXIT(status) { push(status); goto end; }
michael@0 50
michael@0 51 #define do_(name) &&name
michael@0 52
michael@0 53
michael@0 54 using namespace graphite2;
michael@0 55 using namespace vm;
michael@0 56
michael@0 57 namespace {
michael@0 58
michael@0 59 const void * direct_run(const bool get_table_mode,
michael@0 60 const instr * program,
michael@0 61 const byte * data,
michael@0 62 Machine::stack_t * stack,
michael@0 63 slotref * & __map,
michael@0 64 SlotMap * __smap=0)
michael@0 65 {
michael@0 66 // We need to define and return to opcode table from within this function
michael@0 67 // other inorder to take the addresses of the instruction bodies.
michael@0 68 #include "inc/opcode_table.h"
michael@0 69 if (get_table_mode)
michael@0 70 return opcode_table;
michael@0 71
michael@0 72 // Declare virtual machine registers
michael@0 73 const instr * ip = program;
michael@0 74 const byte * dp = data;
michael@0 75 Machine::stack_t * sp = stack + Machine::STACK_GUARD,
michael@0 76 * const sb = sp;
michael@0 77 SlotMap & smap = *__smap;
michael@0 78 Segment & seg = smap.segment;
michael@0 79 slotref is = *__map,
michael@0 80 * map = __map,
michael@0 81 * const mapb = smap.begin()+smap.context();
michael@0 82 int8 flags = 0;
michael@0 83
michael@0 84 // start the program
michael@0 85 goto **ip;
michael@0 86
michael@0 87 // Pull in the opcode definitions
michael@0 88 #include "inc/opcodes.h"
michael@0 89
michael@0 90 end:
michael@0 91 __map = map;
michael@0 92 *__map = is;
michael@0 93 return sp;
michael@0 94 }
michael@0 95
michael@0 96 }
michael@0 97
michael@0 98 const opcode_t * Machine::getOpcodeTable() throw()
michael@0 99 {
michael@0 100 slotref * dummy;
michael@0 101 return static_cast<const opcode_t *>(direct_run(true, 0, 0, 0, dummy, 0));
michael@0 102 }
michael@0 103
michael@0 104
michael@0 105 Machine::stack_t Machine::run(const instr * program,
michael@0 106 const byte * data,
michael@0 107 slotref * & is)
michael@0 108 {
michael@0 109 assert(program != 0);
michael@0 110
michael@0 111 const stack_t *sp = static_cast<const stack_t *>(
michael@0 112 direct_run(false, program, data, _stack, is, &_map));
michael@0 113 const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
michael@0 114 check_final_stack(sp);
michael@0 115 return ret;
michael@0 116 }
michael@0 117

mercurial