gfx/graphite2/src/call_machine.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/graphite2/src/call_machine.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,135 @@
     1.4 +/*  GRAPHITE2 LICENSING
     1.5 +
     1.6 +    Copyright 2010, SIL International
     1.7 +    All rights reserved.
     1.8 +
     1.9 +    This library is free software; you can redistribute it and/or modify
    1.10 +    it under the terms of the GNU Lesser General Public License as published
    1.11 +    by the Free Software Foundation; either version 2.1 of License, or
    1.12 +    (at your option) any later version.
    1.13 +
    1.14 +    This program is distributed in the hope that it will be useful,
    1.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 +    Lesser General Public License for more details.
    1.18 +
    1.19 +    You should also have received a copy of the GNU Lesser General Public
    1.20 +    License along with this library in the file named "LICENSE".
    1.21 +    If not, write to the Free Software Foundation, 51 Franklin Street, 
    1.22 +    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
    1.23 +    internet at http://www.fsf.org/licenses/lgpl.html.
    1.24 +
    1.25 +Alternatively, the contents of this file may be used under the terms of the
    1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
    1.27 +License, as published by the Free Software Foundation, either version 2
    1.28 +of the License or (at your option) any later version.
    1.29 +*/
    1.30 +// This call threaded interpreter implmentation for machine.h
    1.31 +// Author: Tim Eves
    1.32 +
    1.33 +// Build either this interpreter or the direct_machine implementation.
    1.34 +// The call threaded interpreter is portable across compilers and 
    1.35 +// architectures as well as being useful to debug (you can set breakpoints on 
    1.36 +// opcodes) but is slower that the direct threaded interpreter by a factor of 2
    1.37 +
    1.38 +#include <cassert>
    1.39 +#include <cstring>
    1.40 +#include <graphite2/Segment.h>
    1.41 +#include "inc/Machine.h"
    1.42 +#include "inc/Segment.h"
    1.43 +#include "inc/Slot.h"
    1.44 +#include "inc/Rule.h"
    1.45 +
    1.46 +// Disable the unused parameter warning as th compiler is mistaken since dp
    1.47 +// is always updated (even if by 0) on every opcode.
    1.48 +#ifdef __GNUC__
    1.49 +#pragma GCC diagnostic ignored "-Wunused-parameter"
    1.50 +#endif
    1.51 +
    1.52 +#define registers           const byte * & dp, vm::Machine::stack_t * & sp, \
    1.53 +                            vm::Machine::stack_t * const sb, regbank & reg
    1.54 +
    1.55 +// These are required by opcodes.h and should not be changed
    1.56 +#define STARTOP(name)       bool name(registers) REGPARM(4);\
    1.57 +                            bool name(registers) {
    1.58 +#define ENDOP                   return (sp - sb)/Machine::STACK_MAX==0; \
    1.59 +                            }
    1.60 +
    1.61 +#define EXIT(status)        { push(status); return false; }
    1.62 +
    1.63 +// This is required by opcode_table.h
    1.64 +#define do_(name)           instr(name)
    1.65 +
    1.66 +
    1.67 +using namespace graphite2;
    1.68 +using namespace vm;
    1.69 +
    1.70 +struct regbank  {
    1.71 +    slotref         is;
    1.72 +    slotref *       map;
    1.73 +    SlotMap       & smap;
    1.74 +    slotref * const map_base;
    1.75 +    const instr * & ip;
    1.76 +    int8            flags;
    1.77 +};
    1.78 +
    1.79 +typedef bool        (* ip_t)(registers);
    1.80 +
    1.81 +// Pull in the opcode definitions
    1.82 +// We pull these into a private namespace so these otherwise common names dont
    1.83 +// pollute the toplevel namespace.
    1.84 +namespace {
    1.85 +#define smap    reg.smap
    1.86 +#define seg     smap.segment
    1.87 +#define is      reg.is
    1.88 +#define ip      reg.ip
    1.89 +#define map     reg.map
    1.90 +#define mapb    reg.map_base
    1.91 +#define flags   reg.flags
    1.92 +
    1.93 +#include "inc/opcodes.h"
    1.94 +
    1.95 +#undef smap
    1.96 +#undef seg
    1.97 +#undef is
    1.98 +#undef ip
    1.99 +#undef map
   1.100 +#undef mapb
   1.101 +#undef flags
   1.102 +}
   1.103 +
   1.104 +Machine::stack_t  Machine::run(const instr   * program,
   1.105 +                               const byte    * data,
   1.106 +                               slotref     * & map)
   1.107 +
   1.108 +{
   1.109 +    assert(program != 0);
   1.110 +
   1.111 +    // Declare virtual machine registers
   1.112 +    const instr   * ip = program-1;
   1.113 +    const byte    * dp = data;
   1.114 +    stack_t       * sp = _stack + Machine::STACK_GUARD,
   1.115 +            * const sb = sp;
   1.116 +    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, 0};
   1.117 +
   1.118 +    // Run the program        
   1.119 +    while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
   1.120 +    const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
   1.121 +
   1.122 +    check_final_stack(sp);
   1.123 +    map = reg.map;
   1.124 +    *map = reg.is;
   1.125 +    return ret;
   1.126 +}
   1.127 +
   1.128 +// Pull in the opcode table
   1.129 +namespace {
   1.130 +#include "inc/opcode_table.h"
   1.131 +}
   1.132 +
   1.133 +const opcode_t * Machine::getOpcodeTable() throw()
   1.134 +{
   1.135 +    return opcode_table;
   1.136 +}
   1.137 +
   1.138 +

mercurial