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
1 /* GRAPHITE2 LICENSING
3 Copyright 2010, SIL International
4 All rights reserved.
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.
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.
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.
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 call threaded interpreter implmentation for machine.h
28 // Author: Tim Eves
30 // Build either this interpreter or the direct_machine implementation.
31 // The call threaded interpreter is portable across compilers and
32 // architectures as well as being useful to debug (you can set breakpoints on
33 // opcodes) but is slower that the direct threaded interpreter by a factor of 2
35 #include <cassert>
36 #include <cstring>
37 #include <graphite2/Segment.h>
38 #include "inc/Machine.h"
39 #include "inc/Segment.h"
40 #include "inc/Slot.h"
41 #include "inc/Rule.h"
43 // Disable the unused parameter warning as th compiler is mistaken since dp
44 // is always updated (even if by 0) on every opcode.
45 #ifdef __GNUC__
46 #pragma GCC diagnostic ignored "-Wunused-parameter"
47 #endif
49 #define registers const byte * & dp, vm::Machine::stack_t * & sp, \
50 vm::Machine::stack_t * const sb, regbank & reg
52 // These are required by opcodes.h and should not be changed
53 #define STARTOP(name) bool name(registers) REGPARM(4);\
54 bool name(registers) {
55 #define ENDOP return (sp - sb)/Machine::STACK_MAX==0; \
56 }
58 #define EXIT(status) { push(status); return false; }
60 // This is required by opcode_table.h
61 #define do_(name) instr(name)
64 using namespace graphite2;
65 using namespace vm;
67 struct regbank {
68 slotref is;
69 slotref * map;
70 SlotMap & smap;
71 slotref * const map_base;
72 const instr * & ip;
73 int8 flags;
74 };
76 typedef bool (* ip_t)(registers);
78 // Pull in the opcode definitions
79 // We pull these into a private namespace so these otherwise common names dont
80 // pollute the toplevel namespace.
81 namespace {
82 #define smap reg.smap
83 #define seg smap.segment
84 #define is reg.is
85 #define ip reg.ip
86 #define map reg.map
87 #define mapb reg.map_base
88 #define flags reg.flags
90 #include "inc/opcodes.h"
92 #undef smap
93 #undef seg
94 #undef is
95 #undef ip
96 #undef map
97 #undef mapb
98 #undef flags
99 }
101 Machine::stack_t Machine::run(const instr * program,
102 const byte * data,
103 slotref * & map)
105 {
106 assert(program != 0);
108 // Declare virtual machine registers
109 const instr * ip = program-1;
110 const byte * dp = data;
111 stack_t * sp = _stack + Machine::STACK_GUARD,
112 * const sb = sp;
113 regbank reg = {*map, map, _map, _map.begin()+_map.context(), ip, 0};
115 // Run the program
116 while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
117 const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
119 check_final_stack(sp);
120 map = reg.map;
121 *map = reg.is;
122 return ret;
123 }
125 // Pull in the opcode table
126 namespace {
127 #include "inc/opcode_table.h"
128 }
130 const opcode_t * Machine::getOpcodeTable() throw()
131 {
132 return opcode_table;
133 }