tor-browser

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

Code.h (5222B)


      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 class represents loaded graphite stack machine code.  It performs
     28 // basic sanity checks, on the incoming code to prevent more obvious problems
     29 // from crashing graphite.
     30 // Author: Tim Eves
     31 
     32 #pragma once
     33 
     34 #include <cassert>
     35 #include <graphite2/Types.h>
     36 #include "inc/Main.h"
     37 #include "inc/Machine.h"
     38 
     39 namespace graphite2 {
     40 
     41 class Silf;
     42 class Face;
     43 
     44 enum passtype {
     45    PASS_TYPE_UNKNOWN = 0,
     46    PASS_TYPE_LINEBREAK,
     47    PASS_TYPE_SUBSTITUTE,
     48    PASS_TYPE_POSITIONING,
     49    PASS_TYPE_JUSTIFICATION
     50 };
     51 
     52 namespace vm {
     53 
     54 class Machine::Code
     55 {
     56 public:
     57    enum status_t
     58    {
     59        loaded,
     60        alloc_failed,
     61        invalid_opcode,
     62        unimplemented_opcode_used,
     63        out_of_range_data,
     64        jump_past_end,
     65        arguments_exhausted,
     66        missing_return,
     67        nested_context_item,
     68        underfull_stack
     69    };
     70 
     71 private:
     72    class decoder;
     73 
     74    instr *     _code;
     75    byte  *     _data;
     76    size_t      _data_size,
     77                _instr_count;
     78    byte        _max_ref;
     79    mutable status_t _status;
     80    bool        _constraint,
     81                _modify,
     82                _delete;
     83    mutable bool _own;
     84 
     85    void release_buffers() throw ();
     86    void failure(const status_t) throw();
     87 
     88 public:
     89    static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);
     90 
     91    Code() throw();
     92    Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
     93         uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
     94         enum passtype pt, byte * * const _out = 0);
     95    Code(const Machine::Code &) throw();
     96    ~Code() throw();
     97 
     98    Code & operator=(const Code &rhs) throw();
     99    operator bool () const throw()                  { return _code && status() == loaded; }
    100    status_t      status() const throw()            { return _status; }
    101    bool          constraint() const throw()        { return _constraint; }
    102    size_t        dataSize() const throw()          { return _data_size; }
    103    size_t        instructionCount() const throw()  { return _instr_count; }
    104    bool          immutable() const throw()         { return !(_delete || _modify); }
    105    bool          deletes() const throw()           { return _delete; }
    106    size_t        maxRef() const throw()            { return _max_ref; }
    107    void          externalProgramMoved(ptrdiff_t) throw();
    108 
    109    int32 run(Machine &m, slotref * & map) const;
    110 
    111    CLASS_NEW_DELETE;
    112 };
    113 
    114 inline
    115 size_t  Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)
    116 {
    117    // max is: all codes are instructions + 1 for each rule + max tempcopies
    118    // allocate space for separate maximal code and data then merge them later
    119    return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * sizeof(byte);
    120 }
    121 
    122 
    123 inline Machine::Code::Code() throw()
    124 : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
    125  _status(loaded), _constraint(false), _modify(false), _delete(false),
    126  _own(false)
    127 {
    128 }
    129 
    130 inline Machine::Code::Code(const Machine::Code &obj) throw ()
    131 :  _code(obj._code),
    132    _data(obj._data),
    133    _data_size(obj._data_size),
    134    _instr_count(obj._instr_count),
    135    _max_ref(obj._max_ref),
    136    _status(obj._status),
    137    _constraint(obj._constraint),
    138    _modify(obj._modify),
    139    _delete(obj._delete),
    140    _own(obj._own)
    141 {
    142    obj._own = false;
    143 }
    144 
    145 inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() {
    146    if (_instr_count > 0)
    147        release_buffers();
    148    _code        = rhs._code;
    149    _data        = rhs._data;
    150    _data_size   = rhs._data_size;
    151    _instr_count = rhs._instr_count;
    152    _status      = rhs._status;
    153    _constraint  = rhs._constraint;
    154    _modify      = rhs._modify;
    155    _delete      = rhs._delete;
    156    _own         = rhs._own;
    157    rhs._own = false;
    158    return *this;
    159 }
    160 
    161 inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
    162 {
    163    if (_code && !_own)
    164    {
    165        _code += dist / signed(sizeof(instr));
    166        _data += dist;
    167    }
    168 }
    169 
    170 } // namespace vm
    171 } // namespace graphite2