tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

call_machine.cpp (4272B)


      1 /*  GRAPHITE2 LICENSING
      2 
      3    Copyright 2010, SIL International
      4    All rights reserved.
      5 
      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.
     10 
     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.
     15 
     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.
     21 
     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
     29 
     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
     34 
     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"
     42 
     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
     48 
     49 #define registers           const byte * & dp, vm::Machine::stack_t * & sp, \
     50                            vm::Machine::stack_t * const sb, regbank & reg
     51 
     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                            }
     57 
     58 #define EXIT(status)        { push(status); return false; }
     59 
     60 // This is required by opcode_table.h
     61 #define do_(name)           instr(name)
     62 
     63 
     64 using namespace graphite2;
     65 using namespace vm;
     66 
     67 struct regbank  {
     68    slotref         is;
     69    slotref *       map;
     70    SlotMap       & smap;
     71    slotref * const map_base;
     72    const instr * & ip;
     73    uint8           direction;
     74    int8            flags;
     75    Machine::status_t & status;
     76 };
     77 
     78 typedef bool        (* ip_t)(registers);
     79 
     80 // Pull in the opcode definitions
     81 // We pull these into a private namespace so these otherwise common names dont
     82 // pollute the toplevel namespace.
     83 namespace {
     84 #define smap    reg.smap
     85 #define seg     smap.segment
     86 #define is      reg.is
     87 #define ip      reg.ip
     88 #define map     reg.map
     89 #define mapb    reg.map_base
     90 #define flags   reg.flags
     91 #define dir     reg.direction
     92 #define status  reg.status
     93 
     94 #include "inc/opcodes.h"
     95 
     96 #undef smap
     97 #undef seg
     98 #undef is
     99 #undef ip
    100 #undef map
    101 #undef mapb
    102 #undef flags
    103 #undef dir
    104 }
    105 
    106 Machine::stack_t  Machine::run(const instr   * program,
    107                               const byte    * data,
    108                               slotref     * & map)
    109 
    110 {
    111    assert(program != 0);
    112 
    113    // Declare virtual machine registers
    114    const instr   * ip = program-1;
    115    const byte    * dp = data;
    116    stack_t       * sp = _stack + Machine::STACK_GUARD,
    117            * const sb = sp;
    118    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0, _status};
    119 
    120    // Run the program
    121    while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
    122    const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
    123 
    124    check_final_stack(sp);
    125    map = reg.map;
    126    *map = reg.is;
    127    return ret;
    128 }
    129 
    130 // Pull in the opcode table
    131 namespace {
    132 #include "inc/opcode_table.h"
    133 }
    134 
    135 const opcode_t * Machine::getOpcodeTable() throw()
    136 {
    137    return opcode_table;
    138 }