w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Code.cpp
Go to the documentation of this file.
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 #include <cassert>
33 #include <cstddef>
34 #include <cstdlib>
35 #include <cstring>
36 #include "graphite2/Segment.h"
37 #include "inc/Code.h"
38 #include "inc/Face.h"
39 #include "inc/GlyphFace.h"
40 #include "inc/GlyphCache.h"
41 #include "inc/Machine.h"
42 #include "inc/Rule.h"
43 #include "inc/Silf.h"
44 
45 #include <cstdio>
46 
47 #ifdef NDEBUG
48 #ifdef __GNUC__
49 #pragma GCC diagnostic ignored "-Wunused-parameter"
50 #endif
51 #endif
52 
53 
54 using namespace graphite2;
55 using namespace vm;
56 
57 namespace {
58 
59 inline bool is_return(const instr i) {
60  const opcode_t * opmap = Machine::getOpcodeTable();
61  const instr pop_ret = *opmap[POP_RET].impl,
62  ret_zero = *opmap[RET_ZERO].impl,
63  ret_true = *opmap[RET_TRUE].impl;
64  return i == pop_ret || i == ret_zero || i == ret_true;
65 }
66 
67 struct context
68 {
69  context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false;}
70  struct {
71  uint8 changed:1,
72  referenced:1;
73  } flags;
74  uint8 codeRef;
75 };
76 
77 } // end namespace
78 
79 
81 {
82 public:
83  struct limits;
84  static const int NUMCONTEXTS = 256;
85 
86  decoder(limits & lims, Code &code, enum passtype pt) throw();
87 
88  bool load(const byte * bc_begin, const byte * bc_end);
89  void apply_analysis(instr * const code, instr * code_end);
90  byte max_ref() { return _max_ref; }
91  int out_index() const { return _out_index; }
92 
93 private:
94  void set_ref(int index) throw();
95  void set_noref(int index) throw();
96  void set_changed(int index) throw();
97  opcode fetch_opcode(const byte * bc);
98  void analyse_opcode(const opcode, const int8 * const dp) throw();
99  bool emit_opcode(opcode opc, const byte * & bc);
100  bool validate_opcode(const byte opc, const byte * const bc);
101  bool valid_upto(const uint16 limit, const uint16 x) const throw();
102  bool test_context() const throw();
103  bool test_ref(int8 index) const throw();
104  bool test_attr(attrCode attr) const throw();
105  void failure(const status_t s) const throw() { _code.failure(s); }
106 
107  Code & _code;
108  int _out_index;
110  instr * _instr;
111  byte * _data;
112  limits & _max;
113  enum passtype _passtype;
114  int _stack_depth;
115  bool _in_ctxt_item;
116  int16 _slotref;
117  context _contexts[NUMCONTEXTS];
118  byte _max_ref;
119 };
120 
121 
123 {
124  const byte * bytecode;
125  const uint8 pre_context;
126  const uint16 rule_length,
127  classes,
128  glyf_attrs,
129  features;
130  const byte attrid[gr_slatMax];
131 };
132 
133 inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw()
134 : _code(code),
135  _out_index(code._constraint ? 0 : lims.pre_context),
136  _out_length(code._constraint ? 1 : lims.rule_length),
137  _instr(code._code), _data(code._data), _max(lims), _passtype(pt),
138  _stack_depth(0),
139  _in_ctxt_item(false),
140  _slotref(0),
141  _max_ref(0)
142 { }
143 
144 
145 
146 Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
147  uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face,
148  enum passtype pt, byte * * const _out)
149  : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), _status(loaded),
150  _constraint(is_constraint), _modify(false), _delete(false), _own(_out==0)
151 {
152 #ifdef GRAPHITE2_TELEMETRY
153  telemetry::category _code_cat(face.tele.code);
154 #endif
155  assert(bytecode_begin != 0);
156  if (bytecode_begin == bytecode_end)
157  {
158  // ::new (this) Code();
159  return;
160  }
161  assert(bytecode_end > bytecode_begin);
162  const opcode_t * op_to_fn = Machine::getOpcodeTable();
163 
164  // Allocate code and data target buffers, these sizes are a worst case
165  // estimate. Once we know their real sizes the we'll shrink them.
166  if (_out) _code = reinterpret_cast<instr *>(*_out);
167  else _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin, 1, is_constraint ? 0 : rule_length)));
168  _data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
169 
170  if (!_code || !_data) {
171  failure(alloc_failed);
172  return;
173  }
174 
175  decoder::limits lims = {
176  bytecode_end,
177  pre_context,
178  rule_length,
179  silf.numClasses(),
180  face.glyphs().numAttrs(),
181  face.numFeatures(),
182  {1,1,1,1,1,1,1,1,
183  1,1,1,1,1,1,1,255,
184  1,1,1,1,1,1,1,1,
185  1,1,1,1,1,1,0,0,
186  0,0,0,0,0,0,0,0,
187  0,0,0,0,0,0,0,0,
188  0,0,0,0,0,0,0, silf.numUser()}
189  };
190 
191  decoder dec(lims, *this, pt);
192  if(!dec.load(bytecode_begin, bytecode_end))
193  return;
194 
195  // Is this an empty program?
196  if (_instr_count == 0)
197  {
198  release_buffers();
199  ::new (this) Code();
200  return;
201  }
202 
203  // When we reach the end check we've terminated it correctly
204  if (!is_return(_code[_instr_count-1])) {
205  failure(missing_return);
206  return;
207  }
208 
209  assert((_constraint && immutable()) || !_constraint);
210  dec.apply_analysis(_code, _code + _instr_count);
211  _max_ref = dec.max_ref();
212 
213  // Now we know exactly how much code and data the program really needs
214  // realloc the buffers to exactly the right size so we don't waste any
215  // memory.
216  assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_instr_count));
217  assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_data_size));
218  memmove(_code + (_instr_count+1), _data, _data_size*sizeof(byte));
219  size_t const total_sz = ((_instr_count+1) + (_data_size + sizeof(instr)-1)/sizeof(instr))*sizeof(instr);
220  if (_out)
221  *_out += total_sz;
222  else
223  {
224  instr * const old_code = _code;
225  _code = static_cast<instr *>(realloc(_code, total_sz));
226  if (!_code) free(old_code);
227  }
228  _data = reinterpret_cast<byte *>(_code + (_instr_count+1));
229 
230  if (!_code)
231  {
232  failure(alloc_failed);
233  return;
234  }
235 
236  // Make this RET_ZERO, we should never reach this but just in case ...
237  _code[_instr_count] = op_to_fn[RET_ZERO].impl[_constraint];
238 
239 #ifdef GRAPHITE2_TELEMETRY
240  telemetry::count_bytes(_data_size + (_instr_count+1)*sizeof(instr));
241 #endif
242 }
243 
244 Machine::Code::~Code() throw ()
245 {
246  if (_own)
247  release_buffers();
248 }
249 
250 
251 bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
252 {
253  _max.bytecode = bc_end;
254  while (bc < bc_end)
255  {
256  const opcode opc = fetch_opcode(bc++);
257  if (opc == vm::MAX_OPCODE)
258  return false;
259 
260  analyse_opcode(opc, reinterpret_cast<const int8 *>(bc));
261 
262  if (!emit_opcode(opc, bc))
263  return false;
264  }
265 
266  return bool(_code);
267 }
268 
269 // Validation check and fixups.
270 //
271 
273 {
274  const byte opc = *bc++;
275 
276  // Do some basic sanity checks based on what we know about the opcode
277  if (!validate_opcode(opc, bc)) return MAX_OPCODE;
278 
279  // And check its arguments as far as possible
280  switch (opcode(opc))
281  {
282  case NOP :
283  break;
284  case PUSH_BYTE :
285  case PUSH_BYTEU :
286  case PUSH_SHORT :
287  case PUSH_SHORTU :
288  case PUSH_LONG :
289  ++_stack_depth;
290  break;
291  case ADD :
292  case SUB :
293  case MUL :
294  case DIV :
295  case MIN_ :
296  case MAX_ :
297  case AND :
298  case OR :
299  case EQUAL :
300  case NOT_EQ :
301  case LESS :
302  case GTR :
303  case LESS_EQ :
304  case GTR_EQ :
305  case BITOR :
306  case BITAND :
307  if (--_stack_depth <= 0)
308  failure(underfull_stack);
309  break;
310  case NEG :
311  case TRUNC8 :
312  case TRUNC16 :
313  case NOT :
314  case BITNOT :
315  case BITSET :
316  if (_stack_depth <= 0)
317  failure(underfull_stack);
318  break;
319  case COND :
320  _stack_depth -= 2;
321  if (_stack_depth <= 0)
322  failure(underfull_stack);
323  break;
324  case NEXT_N : // runtime checked
325  break;
326  case NEXT :
327  case COPY_NEXT :
328  ++_out_index;
329  if (_out_index < -1 || _out_index > _out_length || _slotref > _max.rule_length)
330  failure(out_of_range_data);
331  break;
332  case PUT_GLYPH_8BIT_OBS :
333  valid_upto(_max.classes, bc[0]);
334  test_context();
335  break;
336  case PUT_SUBS_8BIT_OBS :
337  test_ref(int8(bc[0]));
338  valid_upto(_max.classes, bc[1]);
339  valid_upto(_max.classes, bc[2]);
340  test_context();
341  break;
342  case PUT_COPY :
343  test_ref(int8(bc[0]));
344  test_context();
345  break;
346  case INSERT :
348  failure(invalid_opcode);
349  ++_out_length;
350  if (_out_index < 0) ++_out_index;
351  if (_out_index < -1 || _out_index >= _out_length)
352  failure(out_of_range_data);
353  break;
354  case DELETE :
356  failure(invalid_opcode);
358  failure(out_of_range_data);
359  --_out_index;
360  --_out_length;
361  if (_out_index < -1 || _out_index > _out_length)
362  failure(out_of_range_data);
363  break;
364  case ASSOC :
365  if (bc[0] == 0)
366  failure(out_of_range_data);
367  for (uint8 num = bc[0]; num; --num)
368  test_ref(int8(bc[num]));
369  test_context();
370  break;
371  case CNTXT_ITEM :
373  if (bc + 2 + bc[1] >= _max.bytecode) failure(jump_past_end);
374  if (_in_ctxt_item) failure(nested_context_item);
375  break;
376  case ATTR_SET :
377  case ATTR_ADD :
378  case ATTR_SUB :
379  case ATTR_SET_SLOT :
380  if (--_stack_depth < 0)
381  failure(underfull_stack);
382  valid_upto(gr_slatMax, bc[0]);
383  if (attrCode(bc[0]) == gr_slatUserDefn) // use IATTR for user attributes
384  failure(out_of_range_data);
385  test_attr(attrCode(bc[0]));
386  test_context();
387  break;
388  case IATTR_SET_SLOT :
389  if (--_stack_depth < 0)
390  failure(underfull_stack);
391  if (valid_upto(gr_slatMax, bc[0]))
392  valid_upto(_max.attrid[bc[0]], bc[1]);
393  test_attr(attrCode(bc[0]));
394  test_context();
395  break;
396  case PUSH_SLOT_ATTR :
397  ++_stack_depth;
398  valid_upto(gr_slatMax, bc[0]);
399  test_ref(int8(bc[1]));
400  if (attrCode(bc[0]) == gr_slatUserDefn) // use IATTR for user attributes
401  failure(out_of_range_data);
402  test_attr(attrCode(bc[0]));
403  break;
404  case PUSH_GLYPH_ATTR_OBS :
405  case PUSH_ATT_TO_GATTR_OBS :
406  ++_stack_depth;
408  test_ref(int8(bc[1]));
409  break;
411  case PUSH_GLYPH_METRIC :
412  ++_stack_depth;
414  test_ref(int8(bc[1]));
415  // level: dp[2] no check necessary
416  break;
417  case PUSH_FEAT :
418  ++_stack_depth;
419  valid_upto(_max.features, bc[0]);
420  test_ref(int8(bc[1]));
421  break;
422  case PUSH_ISLOT_ATTR :
423  ++_stack_depth;
424  if (valid_upto(gr_slatMax, bc[0]))
425  {
426  test_ref(int8(bc[1]));
427  valid_upto(_max.attrid[bc[0]], bc[2]);
428  }
429  test_attr(attrCode(bc[0]));
430  break;
431  case PUSH_IGLYPH_ATTR :// not implemented
432  ++_stack_depth;
433  break;
434  case POP_RET :
435  if (--_stack_depth < 0)
436  failure(underfull_stack);
438  // no break
439  case RET_ZERO :
440  case RET_TRUE :
441  break;
442  case IATTR_SET :
443  case IATTR_ADD :
444  case IATTR_SUB :
445  if (--_stack_depth < 0)
446  failure(underfull_stack);
447  if (valid_upto(gr_slatMax, bc[0]))
448  valid_upto(_max.attrid[bc[0]], bc[1]);
449  test_attr(attrCode(bc[0]));
450  test_context();
451  break;
452  case PUSH_PROC_STATE : // dummy: dp[0] no check necessary
453  case PUSH_VERSION :
454  ++_stack_depth;
455  break;
456  case PUT_SUBS :
457  test_ref(int8(bc[0]));
458  valid_upto(_max.classes, uint16(bc[1]<< 8) | bc[2]);
459  valid_upto(_max.classes, uint16(bc[3]<< 8) | bc[4]);
460  test_context();
461  break;
462  case PUT_SUBS2 : // not implemented
463  case PUT_SUBS3 : // not implemented
464  break;
465  case PUT_GLYPH :
466  valid_upto(_max.classes, uint16(bc[0]<< 8) | bc[1]);
467  test_context();
468  break;
469  case PUSH_GLYPH_ATTR :
471  ++_stack_depth;
472  valid_upto(_max.glyf_attrs, uint16(bc[0]<< 8) | bc[1]);
473  test_ref(int8(bc[2]));
474  break;
475  case SET_FEAT :
476  valid_upto(_max.features, bc[0]);
477  test_ref(int8(bc[1]));
478  break;
479  default:
480  failure(invalid_opcode);
481  break;
482  }
483 
484  return bool(_code) ? opcode(opc) : MAX_OPCODE;
485 }
486 
487 
488 void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8 * arg) throw()
489 {
490  switch (opc)
491  {
492  case DELETE :
493  _code._delete = true;
494  break;
495  case ASSOC :
496  set_changed(0);
497 // for (uint8 num = arg[0]; num; --num)
498 // _analysis.set_noref(num);
499  break;
500  case PUT_GLYPH_8BIT_OBS :
501  case PUT_GLYPH :
502  _code._modify = true;
503  set_changed(0);
504  break;
505  case ATTR_SET :
506  case ATTR_ADD :
507  case ATTR_SUB :
508  case ATTR_SET_SLOT :
509  case IATTR_SET_SLOT :
510  case IATTR_SET :
511  case IATTR_ADD :
512  case IATTR_SUB :
513  set_noref(0);
514  break;
515  case NEXT :
516  case COPY_NEXT :
517  ++_slotref;
518  _contexts[_slotref] = context(uint8(_code._instr_count+1));
519  // if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
520  break;
521  case INSERT :
522  if (_slotref >= 0) --_slotref;
523  _code._modify = true;
524  break;
525  case PUT_SUBS_8BIT_OBS : // slotref on 1st parameter
526  case PUT_SUBS :
527  _code._modify = true;
528  set_changed(0);
530  // no break
531  case PUT_COPY :
532  if (arg[0] != 0) { set_changed(0); _code._modify = true; }
533  set_ref(arg[0]);
534  break;
535  case PUSH_GLYPH_ATTR_OBS :
536  case PUSH_SLOT_ATTR :
537  case PUSH_GLYPH_METRIC :
538  case PUSH_ATT_TO_GATTR_OBS :
540  case PUSH_ISLOT_ATTR :
541  case PUSH_FEAT :
542  case SET_FEAT :
543  set_ref(arg[1]);
544  break;
546  case PUSH_GLYPH_ATTR :
547  set_ref(arg[2]);
548  break;
549  default:
550  break;
551  }
552 }
553 
554 
555 bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
556 {
557  const opcode_t * op_to_fn = Machine::getOpcodeTable();
558  const opcode_t & op = op_to_fn[opc];
559  if (op.impl[_code._constraint] == 0)
560  {
561  failure(unimplemented_opcode_used);
562  return false;
563  }
564 
565  const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
566 
567  // Add this instruction
568  *_instr++ = op.impl[_code._constraint];
569  ++_code._instr_count;
570 
571  // Grab the parameters
572  if (param_sz) {
573  memcpy(_data, bc, param_sz * sizeof(byte));
574  bc += param_sz;
575  _data += param_sz;
576  _code._data_size += param_sz;
577  }
578 
579  // recursively decode a context item so we can split the skip into
580  // instruction and data portions.
581  if (opc == CNTXT_ITEM)
582  {
583  assert(_out_index == 0);
584  _in_ctxt_item = true;
586  _slotref = int8(_data[-2]);
588 
589  const size_t ctxt_start = _code._instr_count;
590  byte & instr_skip = _data[-1];
591  byte & data_skip = *_data++;
592  ++_code._data_size;
593  const byte *curr_end = _max.bytecode;
594 
595  if (load(bc, bc + instr_skip))
596  {
597  bc += instr_skip;
598  data_skip = instr_skip - byte(_code._instr_count - ctxt_start);
599  instr_skip = byte(_code._instr_count - ctxt_start);
600  _max.bytecode = curr_end;
601 
602  _out_length = 1;
603  _out_index = 0;
604  _slotref = 0;
605  _in_ctxt_item = false;
606  }
607  else
608  {
609  _out_index = 0;
610  _slotref = 0;
611  return false;
612  }
613  }
614 
615  return bool(_code);
616 }
617 
618 
619 void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end)
620 {
621  // insert TEMP_COPY commands for slots that need them (that change and are referenced later)
622  int tempcount = 0;
623  if (_code._constraint) return;
624 
625  const instr temp_copy = Machine::getOpcodeTable()[TEMP_COPY].impl[0];
626  for (const context * c = _contexts, * const ce = c + _slotref; c < ce; ++c)
627  {
628  if (!c->flags.referenced || !c->flags.changed) continue;
629 
630  instr * const tip = code + c->codeRef + tempcount;
631  memmove(tip+1, tip, (code_end - tip) * sizeof(instr));
632  *tip = temp_copy;
633  ++code_end;
634  ++tempcount;
635  _code._delete = true;
636  }
637 
638  _code._instr_count = code_end - code;
639 }
640 
641 
642 inline
643 bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc)
644 {
645  if (opc >= MAX_OPCODE)
646  {
647  failure(invalid_opcode);
648  return false;
649  }
650  const opcode_t & op = Machine::getOpcodeTable()[opc];
651  if (op.impl[_code._constraint] == 0)
652  {
653  failure(unimplemented_opcode_used);
654  return false;
655  }
656  if (op.param_sz == VARARGS && bc >= _max.bytecode)
657  {
658  failure(arguments_exhausted);
659  return false;
660  }
661  const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
662  if (bc - 1 + param_sz >= _max.bytecode)
663  {
664  failure(arguments_exhausted);
665  return false;
666  }
667  return true;
668 }
669 
670 
671 bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) const throw()
672 {
673  const bool t = (limit != 0) && (x < limit);
674  if (!t) failure(out_of_range_data);
675  return t;
676 }
677 
678 inline
679 bool Machine::Code::decoder::test_ref(int8 index) const throw()
680 {
681  if (_code._constraint && !_in_ctxt_item)
682  {
683  if (index > 0 || -index > _max.pre_context)
684  {
685  failure(out_of_range_data);
686  return false;
687  }
688  }
689  else
690  {
691  if (_max.rule_length == 0
693  || (_slotref + _max.pre_context + index < 0))
694  {
695  failure(out_of_range_data);
696  return false;
697  }
698  }
699  return true;
700 }
701 
702 bool Machine::Code::decoder::test_context() const throw()
703 {
704  if (_out_index >= _out_length || _out_index < 0 || _slotref >= NUMCONTEXTS - 1)
705  {
706  failure(out_of_range_data);
707  return false;
708  }
709  return true;
710 }
711 
713 {
714 #if 0 // This code is coming but causes backward compatibility problems.
716  {
717  if (attr != gr_slatBreak && attr != gr_slatDir && attr != gr_slatUserDefn
718  && attr != gr_slatCompRef)
719  {
720  failure(out_of_range_data);
721  return false;
722  }
723  }
724 #endif
725  return true;
726 }
727 
728 inline
729 void Machine::Code::failure(const status_t s) throw() {
730  release_buffers();
731  _status = s;
732 }
733 
734 
735 inline
736 void Machine::Code::decoder::set_ref(int index) throw() {
737  if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
738  _contexts[index + _slotref].flags.referenced = true;
740 }
741 
742 
743 inline
744 void Machine::Code::decoder::set_noref(int index) throw() {
745  if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
747 }
748 
749 
750 inline
751 void Machine::Code::decoder::set_changed(int index) throw() {
752  if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
753  _contexts[index + _slotref].flags.changed= true;
755 }
756 
757 
758 void Machine::Code::release_buffers() throw()
759 {
760  if (_own)
761  free(_code);
762  _code = 0;
763  _data = 0;
764  _own = false;
765 }
766 
767 
769 {
770 // assert(_own);
771  assert(*this); // Check we are actually runnable
772 
773  if (m.slotMap().size() <= size_t(_max_ref + m.slotMap().context())
774  || m.slotMap()[_max_ref + m.slotMap().context()] == 0)
775  {
776  m._status = Machine::slot_offset_out_bounds;
777  return 1;
778 // return m.run(_code, _data, map);
779  }
780 
781  return m.run(_code, _data, map);
782 }
int ptrdiff_t
Definition: CPAL.d:3845
NEXT
Definition: action.c:17
int code
Definition: aftopl.c:52
#define limits
#define bool
Definition: autosp.c:101
#define BITSET(p, n)
Definition: cairo-mempool.c:47
static void dec(struct edge *e, int h)
static const int NUMCONTEXTS
Definition: Code.cpp:84
void set_noref(int index)
decoder(limits &lims, Code &code, enum passtype pt)
context _contexts[NUMCONTEXTS]
Definition: Code.cpp:117
int out_index() const
Definition: Code.cpp:91
void set_changed(int index)
bool valid_upto(const uint16 limit, const uint16 x) const
void set_ref(int index)
void analyse_opcode(const opcode, const int8 *const dp)
bool test_ref(int8 index) const
Definition: Code.cpp:679
bool emit_opcode(opcode opc, const byte *&bc)
bool test_attr(attrCode attr) const
Definition: Code.cpp:712
opcode fetch_opcode(const byte *bc)
enum passtype _passtype
Definition: Code.cpp:113
bool validate_opcode(const byte opc, const byte *const bc)
void apply_analysis(instr *const code, instr *code_end)
bool load(const byte *bc_begin, const byte *bc_end)
void failure(const status_t s) const
Definition: Code.cpp:105
bool test_context() const
uint16 numClasses() const
Definition: Silf.h:95
uint8 numUser() const
Definition: Silf.h:82
#define free(a)
Definition: decNumber.cpp:310
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define bc
Definition: gsftopk.c:501
#define memmove(d, s, n)
Definition: gsftopk.c:65
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define byte
Definition: in_pcx.cpp:28
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_Face face
Definition: cffdrivr.c:659
#define const
Definition: ftzconf.h:91
#define false
Definition: ftrandom.c:52
#define Code
Definition: deflate.h:80
int num
Definition: disdvi.c:621
void * new(uint32_t size)
Definition: mem.c:34
#define DIV
Definition: mpost.c:318
#define NEG
Definition: mpost.c:319
#define malloc
Definition: alloca.c:91
#define NOP
Definition: tif_getimage.c:684
unsigned short uint16
Definition: tiff.h:62
short int16
Definition: tiff.h:61
long int32
Definition: tiff.h:67
unsigned char uint8
Definition: tiff.h:60
char int8
Definition: tiff.h:58
#define int8
Definition: unibasics.h:54
#define uint8
Definition: unibasics.h:53
#define realloc
Definition: glob.c:206
float x
Definition: cordic.py:15
dictionary ce
void * instr
Definition: Machine.h:79
@ PUSH_GLYPH_METRIC
Definition: Machine.h:110
@ PUT_SUBS_8BIT_OBS
Definition: Machine.h:101
@ PUSH_GLYPH_ATTR
Definition: Machine.h:120
@ IATTR_SET_SLOT
Definition: Machine.h:108
@ PUSH_ATT_TO_GLYPH_ATTR
Definition: Machine.h:120
@ PUT_GLYPH_8BIT_OBS
Definition: Machine.h:101
@ PUSH_ATT_TO_GLYPH_METRIC
Definition: Machine.h:111
@ PUSH_ATT_TO_GATTR_OBS
Definition: Machine.h:111
@ PUSH_IGLYPH_ATTR
Definition: Machine.h:114
@ PUSH_GLYPH_ATTR_OBS
Definition: Machine.h:109
@ PUSH_SLOT_ATTR
Definition: Machine.h:109
@ PUSH_ISLOT_ATTR
Definition: Machine.h:112
@ PUSH_PROC_STATE
Definition: Machine.h:118
Definition: bits.h:30
@ kgmetDescent
Definition: GlyphFace.h:40
gr_attrCode attrCode
Definition: Slot.h:37
passtype
Definition: Code.h:44
@ PASS_TYPE_POSITIONING
Definition: Code.h:48
def ref(x)
Definition: pdf-org.py:104
#define DELETE(fn, ptr)
Definition: otfcc-alloc.h:76
boolean changed
Definition: parse_ofm.c:90
#define INSERT(b, p, a)
Definition: paths.c:415
#define EQUAL
Definition: pbmtomacp.c:18
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define VARARGS
Definition: ppmtoeyuv.c:66
gr_attrCode
Definition: Segment.h:63
@ gr_slatMax
not implemented
Definition: Segment.h:164
@ gr_slatCompRef
Ligature component reference (not implemented)
Definition: Segment.h:95
@ gr_slatUserDefn
User defined attribute, see subattr for user attr number.
Definition: Segment.h:127
@ gr_slatBreak
Line break breakweight for this glyph.
Definition: Segment.h:93
@ gr_slatDir
bidi directionality of this glyph (not implemented)
Definition: Segment.h:97
Machine::Code Code
Definition: Pass.cpp:43
#define map
#define flags
#define GR_FALLTHROUGH
Definition: Main.h:193
RETTYPE mp_ptr mp_size_t mp_srcptr dp
Definition: sec_div.c:70
@ MUL
Definition: strexpr.c:18
@ SUB
Definition: strexpr.c:18
@ ADD
Definition: strexpr.c:18
const byte attrid[gr_slatMax]
Definition: Code.cpp:130
Definition: inftrees.h:24
Definition: mendex.h:20
Definition: sh.h:1226
Definition: dvips.h:235
m
Definition: tex4ht.c:3990
int run(char *cmd)
Definition: texdocc.c:233
PATTERN * pt
Definition: vlna.c:74
#define limit(x)
Definition: yuvsplittoppm.c:26
#define return(val)