gfx/graphite2/src/inc/opcodes.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #pragma once
    28 // This file will be pulled into and integrated into a machine implmentation
    29 // DO NOT build directly and under no circumstances every #include headers in 
    30 // here or you will break the direct_machine.
    31 //
    32 // Implementers' notes
    33 // ==================
    34 // You have access to a few primitives and the full C++ code:
    35 //    declare_params(n) Tells the interpreter how many bytes of parameter
    36 //                      space to claim for this instruction uses and 
    37 //                      initialises the param pointer.  You *must* before the 
    38 //                      first use of param.
    39 //    use_params(n)     Claim n extra bytes of param space beyond what was 
    40 //                      claimed using delcare_param.
    41 //    param             A const byte pointer for the parameter space claimed by
    42 //                      this instruction.
    43 //    binop(op)         Implement a binary operation on the stack using the 
    44 //                      specified C++ operator.
    45 //    NOT_IMPLEMENTED   Any instruction body containing this will exit the 
    46 //                      program with an assertion error.  Instructions that are
    47 //                      not implemented should also be marked NILOP in the
    48 //                      opcodes tables this will cause the code class to spot
    49 //                      them in a live code stream and throw a runtime_error 
    50 //                      instead.
    51 //    push(n)           Push the value n onto the stack.
    52 //    pop()             Pop the top most value and return it.
    53 //
    54 //    You have access to the following named fast 'registers':
    55 //        sp        = The pointer to the current top of stack, the last value
    56 //                    pushed.
    57 //        seg       = A reference to the Segment this code is running over.
    58 //        is        = The current slot index
    59 //        isb       = The original base slot index at the start of this rule
    60 //        isf       = The first positioned slot
    61 //        isl       = The last positioned slot
    62 //        ip        = The current instruction pointer
    63 //        endPos    = Position of advance of last cluster
    66 // #define NOT_IMPLEMENTED     assert(false)
    67 #define NOT_IMPLEMENTED
    69 #define binop(op)           const int32 a = pop(); *sp = int32(*sp) op a
    70 #define use_params(n)       dp += n
    72 #define declare_params(n)   const byte * param = dp; \
    73                             use_params(n);
    75 #define push(n)             { *++sp = n; }
    76 #define pop()               (*sp--)
    77 #define slotat(x)           (map[(x)])
    78 #define DIE                 { is=seg.last(); EXIT(1); }
    79 #define POSITIONED          1
    81 STARTOP(nop)
    82     do {} while (0);
    83 ENDOP
    85 STARTOP(push_byte)
    86     declare_params(1);
    87     push(int8(*param));
    88 ENDOP
    90 STARTOP(push_byte_u)
    91     declare_params(1);
    92     push(uint8(*param));
    93 ENDOP
    95 STARTOP(push_short)
    96     declare_params(2);
    97     const int16 r   = int16(param[0]) << 8 
    98                     | uint8(param[1]);
    99     push(r);
   100 ENDOP
   102 STARTOP(push_short_u)
   103     declare_params(2);
   104     const uint16 r  = uint16(param[0]) << 8
   105                     | uint8(param[1]);
   106     push(r);
   107 ENDOP
   109 STARTOP(push_long)
   110     declare_params(4);
   111     const  int32 r  = int32(param[0]) << 24
   112                     | uint32(param[1]) << 16
   113                     | uint32(param[2]) << 8
   114                     | uint8(param[3]);
   115     push(r);
   116 ENDOP
   118 STARTOP(add)
   119     binop(+);
   120 ENDOP
   122 STARTOP(sub)
   123     binop(-);
   124 ENDOP
   126 STARTOP(mul)
   127     binop(*);
   128 ENDOP
   130 STARTOP(div_)
   131     if (*sp == 0) DIE;
   132     binop(/);
   133 ENDOP
   135 STARTOP(min_)
   136     const int32 a = pop(), b = *sp;
   137     if (a < b) *sp = a;
   138 ENDOP
   140 STARTOP(max_)
   141     const int32 a = pop(), b = *sp;
   142     if (a > b) *sp = a;
   143 ENDOP
   145 STARTOP(neg)
   146     *sp = uint32(-int32(*sp));
   147 ENDOP
   149 STARTOP(trunc8)
   150     *sp = uint8(*sp);
   151 ENDOP
   153 STARTOP(trunc16)
   154     *sp = uint16(*sp);
   155 ENDOP
   157 STARTOP(cond)
   158     const uint32 f = pop(), t = pop(), c = pop();
   159     push(c ? t : f);
   160 ENDOP
   162 STARTOP(and_)
   163     binop(&&);
   164 ENDOP
   166 STARTOP(or_)
   167     binop(||);
   168 ENDOP
   170 STARTOP(not_)
   171     *sp = !*sp;
   172 ENDOP
   174 STARTOP(equal)
   175     binop(==);
   176 ENDOP
   178 STARTOP(not_eq_)
   179     binop(!=);
   180 ENDOP
   182 STARTOP(less)
   183     binop(<);
   184 ENDOP
   186 STARTOP(gtr)
   187     binop(>);
   188 ENDOP
   190 STARTOP(less_eq)
   191     binop(<=);
   192 ENDOP
   194 STARTOP(gtr_eq)
   195     binop(>=);
   196 ENDOP
   198 STARTOP(next)
   199     if (map - &smap[0] >= int(smap.size())) DIE
   200     if (is)
   201     {
   202         if (is == smap.highwater())
   203             smap.highpassed(true);
   204         is = is->next();
   205     }
   206     ++map;
   207 ENDOP
   209 STARTOP(next_n)
   210     use_params(1);
   211     NOT_IMPLEMENTED;
   212     //declare_params(1);
   213     //const size_t num = uint8(*param);
   214 ENDOP
   216 //STARTOP(copy_next)
   217 //     if (is) is = is->next();
   218 //     ++map;
   219 // ENDOP
   221 STARTOP(put_glyph_8bit_obs)
   222     declare_params(1);
   223     const unsigned int output_class = uint8(*param);
   224     is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
   225 ENDOP
   227 STARTOP(put_subs_8bit_obs)
   228     declare_params(3);
   229     const int           slot_ref     = int8(param[0]);
   230     const unsigned int  input_class  = uint8(param[1]),
   231                         output_class = uint8(param[2]);
   232     uint16 index;
   233     slotref slot = slotat(slot_ref);
   234     if (slot)
   235     {
   236         index = seg.findClassIndex(input_class, slot->gid());
   237         is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
   238     }
   239 ENDOP
   241 STARTOP(put_copy)
   242     declare_params(1);
   243     const int  slot_ref = int8(*param);
   244     if (is && (slot_ref ||is != *map))
   245     {
   246         int16 *tempUserAttrs = is->userAttrs();
   247         slotref ref = slotat(slot_ref);
   248         if (ref)
   249         {
   250             memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
   251             Slot *prev = is->prev();
   252             Slot *next = is->next();
   253             memcpy(is, slotat(slot_ref), sizeof(Slot));
   254             is->userAttrs(tempUserAttrs);
   255             is->next(next);
   256             is->prev(prev);
   257             is->sibling(NULL);
   258         }
   259         is->markCopied(false);
   260         is->markDeleted(false);
   261     }
   262 ENDOP
   264 STARTOP(insert)
   265     Slot *newSlot = seg.newSlot();
   266     if (!newSlot) DIE;
   267     Slot *iss = is;
   268     while (iss && iss->isDeleted()) iss = iss->next();
   269     if (!iss)
   270     {
   271         if (seg.last())
   272         {
   273             seg.last()->next(newSlot);
   274             newSlot->prev(seg.last());
   275             newSlot->before(seg.last()->before());
   276             seg.last(newSlot);
   277         }
   278         else
   279         {
   280             seg.first(newSlot);
   281             seg.last(newSlot);
   282         }
   283     }
   284     else if (iss->prev())
   285     {
   286         iss->prev()->next(newSlot);
   287         newSlot->prev(iss->prev());
   288         newSlot->before(iss->prev()->after());
   289     }
   290     else
   291     {
   292         newSlot->prev(NULL);
   293         newSlot->before(iss->before());
   294         seg.first(newSlot);
   295     }
   296     newSlot->next(iss);
   297     if (iss)
   298     {
   299         iss->prev(newSlot);
   300         newSlot->originate(iss->original());
   301         newSlot->after(iss->before());
   302     }
   303     else if (newSlot->prev())
   304     {
   305         newSlot->originate(newSlot->prev()->original());
   306         newSlot->after(newSlot->prev()->after());
   307     }
   308     else
   309     {
   310         newSlot->originate(seg.defaultOriginal());
   311     }
   312     is = newSlot;
   313     seg.extendLength(1);
   314     if (map != &smap[-1]) 
   315         --map;
   316 ENDOP
   318 STARTOP(delete_)
   319     if (!is) DIE
   320     is->markDeleted(true);
   321     if (is->prev())
   322         is->prev()->next(is->next());
   323     else
   324         seg.first(is->next());
   326     if (is->next())
   327         is->next()->prev(is->prev());
   328     else
   329         seg.last(is->prev());
   331     if (is == smap.highwater())
   332             smap.highwater(is->next());
   333     if (is->prev())
   334         is = is->prev();
   335     seg.extendLength(-1);
   336 ENDOP
   338 STARTOP(assoc)
   339     declare_params(1);
   340     unsigned int  num = uint8(*param);
   341     const int8 *  assocs = reinterpret_cast<const int8 *>(param+1);
   342     use_params(num);
   343     int max = -1;
   344     int min = -1;
   346     while (num-- > 0)
   347     {
   348         int sr = *assocs++;
   349         slotref ts = slotat(sr);
   350         if (ts && (min == -1 || ts->before() < min)) min = ts->before();
   351         if (ts && ts->after() > max) max = ts->after();
   352     }
   353     if (min > -1)   // implies max > -1
   354     {
   355         is->before(min);
   356         is->after(max);
   357     }
   358 ENDOP
   360 STARTOP(cntxt_item)
   361     // It turns out this is a cunningly disguised condition forward jump.
   362     declare_params(3);    
   363     const int       is_arg = int8(param[0]);
   364     const size_t    iskip  = uint8(param[1]),
   365                     dskip  = uint8(param[2]);
   367     if (mapb + is_arg != map)
   368     {
   369         ip += iskip;
   370         dp += dskip;
   371         push(true);
   372     }
   373 ENDOP
   375 STARTOP(attr_set)
   376     declare_params(1);
   377     const attrCode      slat = attrCode(uint8(*param));
   378     const          int  val  = int(pop());
   379     is->setAttr(&seg, slat, 0, val, smap);
   380 ENDOP
   382 STARTOP(attr_add)
   383     declare_params(1);
   384     const attrCode      slat = attrCode(uint8(*param));
   385     const          int  val  = int(pop());
   386     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   387     {
   388         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   389         flags |= POSITIONED;
   390     }
   391     int res = is->getAttr(&seg, slat, 0);
   392     is->setAttr(&seg, slat, 0, val + res, smap);
   393 ENDOP
   395 STARTOP(attr_sub)
   396     declare_params(1);
   397     const attrCode      slat = attrCode(uint8(*param));
   398     const          int  val  = int(pop());
   399     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   400     {
   401         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   402         flags |= POSITIONED;
   403     }
   404     int res = is->getAttr(&seg, slat, 0);
   405     is->setAttr(&seg, slat, 0, res - val, smap);
   406 ENDOP
   408 STARTOP(attr_set_slot)
   409     declare_params(1);
   410     const attrCode      slat = attrCode(uint8(*param));
   411     const int offset = (map - smap.begin())*int(slat == gr_slatAttTo);
   412     const          int  val  = int(pop())  + offset;
   413     is->setAttr(&seg, slat, offset, val, smap);
   414 ENDOP
   416 STARTOP(iattr_set_slot)
   417     declare_params(2);
   418     const attrCode      slat = attrCode(uint8(param[0]));
   419     const size_t        idx  = uint8(param[1]);
   420     const          int  val  = int(pop())  + (map - smap.begin())*int(slat == gr_slatAttTo);
   421     is->setAttr(&seg, slat, idx, val, smap);
   422 ENDOP
   424 STARTOP(push_slot_attr)
   425     declare_params(2);
   426     const attrCode      slat     = attrCode(uint8(param[0]));
   427     const int           slot_ref = int8(param[1]);
   428     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   429     {
   430         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   431         flags |= POSITIONED;
   432     }
   433     slotref slot = slotat(slot_ref);
   434     if (slot)
   435     {
   436         int res = slot->getAttr(&seg, slat, 0);
   437         push(res);
   438     }
   439 ENDOP
   441 STARTOP(push_glyph_attr_obs)
   442     declare_params(2);
   443     const unsigned int  glyph_attr = uint8(param[0]);
   444     const int           slot_ref   = int8(param[1]);
   445     slotref slot = slotat(slot_ref);
   446     if (slot)
   447         push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
   448 ENDOP
   450 STARTOP(push_glyph_metric)
   451     declare_params(3);
   452     const unsigned int  glyph_attr  = uint8(param[0]);
   453     const int           slot_ref    = int8(param[1]);
   454     const signed int    attr_level  = uint8(param[2]);
   455     slotref slot = slotat(slot_ref);
   456     if (slot)
   457         push(seg.getGlyphMetric(slot, glyph_attr, attr_level));
   458 ENDOP
   460 STARTOP(push_feat)
   461     declare_params(2);
   462     const unsigned int  feat        = uint8(param[0]);
   463     const int           slot_ref    = int8(param[1]);
   464     slotref slot = slotat(slot_ref);
   465     if (slot)
   466     {
   467         uint8 fid = seg.charinfo(slot->original())->fid();
   468         push(seg.getFeature(fid, feat));
   469     }
   470 ENDOP
   472 STARTOP(push_att_to_gattr_obs)
   473     declare_params(2);
   474     const unsigned int  glyph_attr  = uint8(param[0]);
   475     const int           slot_ref    = int8(param[1]);
   476     slotref slot = slotat(slot_ref);
   477     if (slot)
   478     {
   479         slotref att = slot->attachedTo();
   480         if (att) slot = att;
   481         push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
   482     }
   483 ENDOP
   485 STARTOP(push_att_to_glyph_metric)
   486     declare_params(3);
   487     const unsigned int  glyph_attr  = uint8(param[0]);
   488     const int           slot_ref    = int8(param[1]);
   489     const signed int    attr_level  = uint8(param[2]);
   490     slotref slot = slotat(slot_ref);
   491     if (slot)
   492     {
   493         slotref att = slot->attachedTo();
   494         if (att) slot = att;
   495         push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level)));
   496     }
   497 ENDOP
   499 STARTOP(push_islot_attr)
   500     declare_params(3);
   501     const attrCode  slat     = attrCode(uint8(param[0]));
   502     const int           slot_ref = int8(param[1]),
   503                         idx      = uint8(param[2]);
   504     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   505     {
   506         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   507         flags |= POSITIONED;
   508     }
   509     slotref slot = slotat(slot_ref);
   510     if (slot)
   511     {
   512         int res = slot->getAttr(&seg, slat, idx);
   513         push(res);
   514     }
   515 ENDOP
   517 #if 0
   518 STARTOP(push_iglyph_attr) // not implemented
   519     NOT_IMPLEMENTED;
   520 ENDOP
   521 #endif
   523 STARTOP(pop_ret)
   524     const uint32 ret = pop();
   525     EXIT(ret);
   526 ENDOP
   528 STARTOP(ret_zero)
   529     EXIT(0);
   530 ENDOP
   532 STARTOP(ret_true)
   533     EXIT(1);
   534 ENDOP
   536 STARTOP(iattr_set)
   537     declare_params(2);
   538     const attrCode      slat = attrCode(uint8(param[0]));
   539     const size_t        idx  = uint8(param[1]);
   540     const          int  val  = int(pop());
   541     is->setAttr(&seg, slat, idx, val, smap);
   542 ENDOP
   544 STARTOP(iattr_add)
   545     declare_params(2);
   546     const attrCode      slat = attrCode(uint8(param[0]));
   547     const size_t        idx  = uint8(param[1]);
   548     const          int  val  = int(pop());
   549     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   550     {
   551         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   552         flags |= POSITIONED;
   553     }
   554     int res = is->getAttr(&seg, slat, idx);
   555     is->setAttr(&seg, slat, idx, val + res, smap);
   556 ENDOP
   558 STARTOP(iattr_sub)
   559     declare_params(2);
   560     const attrCode      slat = attrCode(uint8(param[0]));
   561     const size_t        idx  = uint8(param[1]);
   562     const          int  val  = int(pop());
   563     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
   564     {
   565         seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
   566         flags |= POSITIONED;
   567     }
   568     int res = is->getAttr(&seg, slat, idx);
   569     is->setAttr(&seg, slat, idx, res - val, smap);
   570 ENDOP
   572 STARTOP(push_proc_state)
   573     use_params(1);
   574     push(1);
   575 ENDOP
   577 STARTOP(push_version)
   578     push(0x00030000);
   579 ENDOP
   581 STARTOP(put_subs)
   582     declare_params(5);
   583     const int        slot_ref     = int8(param[0]);
   584     const unsigned int  input_class  = uint8(param[1]) << 8
   585                                      | uint8(param[2]);
   586     const unsigned int  output_class = uint8(param[3]) << 8
   587                                      | uint8(param[4]);
   588     slotref slot = slotat(slot_ref);
   589     if (slot)
   590     {
   591         int index = seg.findClassIndex(input_class, slot->gid());
   592         is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
   593     }
   594 ENDOP
   596 #if 0
   597 STARTOP(put_subs2) // not implemented
   598     NOT_IMPLEMENTED;
   599 ENDOP
   601 STARTOP(put_subs3) // not implemented
   602     NOT_IMPLEMENTED;
   603 ENDOP
   604 #endif
   606 STARTOP(put_glyph)
   607     declare_params(2);
   608     const unsigned int output_class  = uint8(param[0]) << 8
   609                                      | uint8(param[1]);
   610     is->setGlyph(&seg, seg.getClassGlyph(output_class, 0));
   611 ENDOP
   613 STARTOP(push_glyph_attr)
   614     declare_params(3);
   615     const unsigned int  glyph_attr  = uint8(param[0]) << 8
   616                                     | uint8(param[1]);
   617     const int           slot_ref    = int8(param[2]);
   618     slotref slot = slotat(slot_ref);
   619     if (slot)
   620         push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
   621 ENDOP
   623 STARTOP(push_att_to_glyph_attr)
   624     declare_params(3);
   625     const unsigned int  glyph_attr  = uint8(param[0]) << 8
   626                                     | uint8(param[1]);
   627     const int           slot_ref    = int8(param[2]);
   628     slotref slot = slotat(slot_ref);
   629     if (slot)
   630     {
   631         slotref att = slot->attachedTo();
   632         if (att) slot = att;
   633         push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
   634     }
   635 ENDOP
   637 STARTOP(temp_copy)
   638     slotref newSlot = seg.newSlot();
   639     if (!newSlot) DIE;
   640     int16 *tempUserAttrs = newSlot->userAttrs();
   641     memcpy(newSlot, is, sizeof(Slot));
   642     memcpy(tempUserAttrs, is->userAttrs(), seg.numAttrs() * sizeof(uint16));
   643     newSlot->userAttrs(tempUserAttrs);
   644     newSlot->markCopied(true);
   645     *map = newSlot;
   646 ENDOP

mercurial