зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1262846 - Update graphite2 library to release 1.3.8. r=jrmuizel
This commit is contained in:
Родитель
303bd1fd42
Коммит
c604c01f4a
|
@ -1,6 +1,3 @@
|
||||||
This directory contains the Graphite2 library release 1.3.7 from
|
This directory contains the Graphite2 library release 1.3.8 from
|
||||||
https://github.com/silnrsi/graphite/releases/download/1.3.7/graphite2-minimal-1.3.7.tgz
|
https://github.com/silnrsi/graphite/releases/download/1.3.8/graphite2-minimal-1.3.8.tgz
|
||||||
See gfx/graphite2/moz-gr-update.sh for update procedure.
|
See gfx/graphite2/moz-gr-update.sh for update procedure.
|
||||||
|
|
||||||
Also cherry-picked the post-1.3.7 commit 7dc29f3e4665b17f6e825957b707db6da36ae7d8
|
|
||||||
to keep our reftests happy (affects the PigLatin test font).
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#define GR2_VERSION_MAJOR 1
|
#define GR2_VERSION_MAJOR 1
|
||||||
#define GR2_VERSION_MINOR 3
|
#define GR2_VERSION_MINOR 3
|
||||||
#define GR2_VERSION_BUGFIX 7
|
#define GR2_VERSION_BUGFIX 8
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|
|
@ -97,7 +97,7 @@ private:
|
||||||
opcode fetch_opcode(const byte * bc);
|
opcode fetch_opcode(const byte * bc);
|
||||||
void analyse_opcode(const opcode, const int8 * const dp) throw();
|
void analyse_opcode(const opcode, const int8 * const dp) throw();
|
||||||
bool emit_opcode(opcode opc, const byte * & bc);
|
bool emit_opcode(opcode opc, const byte * & bc);
|
||||||
bool validate_opcode(const opcode opc, const byte * const bc);
|
bool validate_opcode(const byte opc, const byte * const bc);
|
||||||
bool valid_upto(const uint16 limit, const uint16 x) const throw();
|
bool valid_upto(const uint16 limit, const uint16 x) const throw();
|
||||||
bool test_context() const throw();
|
bool test_context() const throw();
|
||||||
bool test_ref(int8 index) const throw();
|
bool test_ref(int8 index) const throw();
|
||||||
|
@ -266,13 +266,13 @@ bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
|
||||||
|
|
||||||
opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
|
opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
|
||||||
{
|
{
|
||||||
const opcode opc = opcode(*bc++);
|
const byte opc = *bc++;
|
||||||
|
|
||||||
// Do some basic sanity checks based on what we know about the opcode
|
// Do some basic sanity checks based on what we know about the opcode
|
||||||
if (!validate_opcode(opc, bc)) return MAX_OPCODE;
|
if (!validate_opcode(opc, bc)) return MAX_OPCODE;
|
||||||
|
|
||||||
// And check it's arguments as far as possible
|
// And check it's arguments as far as possible
|
||||||
switch (opc)
|
switch (opcode(opc))
|
||||||
{
|
{
|
||||||
case NOP :
|
case NOP :
|
||||||
break;
|
break;
|
||||||
|
@ -470,7 +470,7 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bool(_code) ? opc : MAX_OPCODE;
|
return bool(_code) ? opcode(opc) : MAX_OPCODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -629,7 +629,7 @@ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc)
|
bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc)
|
||||||
{
|
{
|
||||||
if (opc >= MAX_OPCODE)
|
if (opc >= MAX_OPCODE)
|
||||||
{
|
{
|
||||||
|
@ -667,7 +667,17 @@ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) cons
|
||||||
inline
|
inline
|
||||||
bool Machine::Code::decoder::test_ref(int8 index) const throw()
|
bool Machine::Code::decoder::test_ref(int8 index) const throw()
|
||||||
{
|
{
|
||||||
return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
|
if (_code._constraint && !_in_ctxt_item)
|
||||||
|
{
|
||||||
|
if (index > 0 || -index > _max.pre_context)
|
||||||
|
{
|
||||||
|
failure(out_of_range_data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Machine::Code::decoder::test_context() const throw()
|
bool Machine::Code::decoder::test_context() const throw()
|
||||||
|
|
|
@ -829,9 +829,9 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
|
||||||
// Calculate the height of the glyph and how many horizontal slices to use.
|
// Calculate the height of the glyph and how many horizontal slices to use.
|
||||||
if (_maxy >= 1e37f)
|
if (_maxy >= 1e37f)
|
||||||
{
|
{
|
||||||
_maxy = ymax;
|
|
||||||
_miny = ymin;
|
|
||||||
_sliceWidth = margin / 1.5f;
|
_sliceWidth = margin / 1.5f;
|
||||||
|
_maxy = ymax + margin;
|
||||||
|
_miny = ymin - margin;
|
||||||
numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f); // +2 helps with rounding errors
|
numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f); // +2 helps with rounding errors
|
||||||
_edges.clear();
|
_edges.clear();
|
||||||
_edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
|
_edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
|
||||||
|
@ -841,7 +841,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
|
||||||
{
|
{
|
||||||
if (_miny != ymin)
|
if (_miny != ymin)
|
||||||
{
|
{
|
||||||
numSlices = int((ymin - _miny) / _sliceWidth - 1);
|
numSlices = int((ymin - margin - _miny) / _sliceWidth - 1);
|
||||||
_miny += numSlices * _sliceWidth;
|
_miny += numSlices * _sliceWidth;
|
||||||
if (numSlices < 0)
|
if (numSlices < 0)
|
||||||
_edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
|
_edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
|
||||||
|
@ -855,7 +855,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
|
||||||
}
|
}
|
||||||
if (_maxy != ymax)
|
if (_maxy != ymax)
|
||||||
{
|
{
|
||||||
numSlices = int((ymax - _miny) / _sliceWidth + 1);
|
numSlices = int((ymax + margin - _miny) / _sliceWidth + 1);
|
||||||
_maxy = numSlices * _sliceWidth + _miny;
|
_maxy = numSlices * _sliceWidth + _miny;
|
||||||
if (numSlices > (int)_edges.size())
|
if (numSlices > (int)_edges.size())
|
||||||
_edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
|
_edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
|
||||||
|
@ -935,28 +935,33 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
|
||||||
return false;
|
return false;
|
||||||
const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
|
const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
|
||||||
const float sx = slot->origin().x + currShift.x;
|
const float sx = slot->origin().x + currShift.x;
|
||||||
float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
|
float x = (sx + (rtl > 0 ? bb.tr.x : bb.bl.x)) * rtl;
|
||||||
// this isn't going to reduce _mingap so skip
|
// this isn't going to reduce _mingap so skip
|
||||||
if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
|
if (x < rtl * (_xbound - _mingap - currSpace))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const float sy = slot->origin().y + currShift.y;
|
const float sy = slot->origin().y + currShift.y;
|
||||||
int smin = max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
|
int smin = max(1, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1)) - 1;
|
||||||
int smax = min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
|
int smax = min((int)_edges.size() - 2, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1)) + 1;
|
||||||
|
if (smin > smax)
|
||||||
|
return false;
|
||||||
bool collides = false;
|
bool collides = false;
|
||||||
|
float below = smin > 0 ? _edges[smin-1] * rtl : 1e38f;
|
||||||
|
float here = _edges[smin] * rtl;
|
||||||
|
float above = smin < (int)_edges.size() - 1 ? _edges[smin+1] * rtl : 1e38f;
|
||||||
|
|
||||||
for (int i = smin; i <= smax; ++i)
|
for (int i = smin; i <= smax; ++i)
|
||||||
{
|
{
|
||||||
float t;
|
float t;
|
||||||
float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
|
float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
|
||||||
if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
|
if ( (x > here - _mingap - currSpace)
|
||||||
|
|| (x > below - _mingap - currSpace)
|
||||||
|
|| (x > above - _mingap - currSpace))
|
||||||
{
|
{
|
||||||
// 2 * currSpace to account for the space that is already separating them and the space we want to add
|
// 2 * currSpace to account for the space that is already separating them and the space we want to add
|
||||||
float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
|
float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) * rtl + 2 * currSpace;
|
||||||
t = rtl * (_edges[i] - m);
|
|
||||||
// Check slices above and below (if any).
|
// Check slices above and below (if any).
|
||||||
if (i < (int)_edges.size() - 1) t = min(t, rtl * (_edges[i+1] - m));
|
t = min(min(here, below), above) - m;
|
||||||
if (i > 0) t = min(t, rtl * (_edges[i-1] - m));
|
|
||||||
// _mingap is positive to shrink
|
// _mingap is positive to shrink
|
||||||
if (t < _mingap)
|
if (t < _mingap)
|
||||||
{
|
{
|
||||||
|
@ -965,13 +970,15 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
|
||||||
}
|
}
|
||||||
#if !defined GRAPHITE2_NTRACING
|
#if !defined GRAPHITE2_NTRACING
|
||||||
// Debugging - remember the closest neighboring edge for this slice.
|
// Debugging - remember the closest neighboring edge for this slice.
|
||||||
if (rtl * m > rtl * _nearEdges[i])
|
if (m > rtl * _nearEdges[i])
|
||||||
{
|
{
|
||||||
_slotNear[i] = slot;
|
_slotNear[i] = slot;
|
||||||
_nearEdges[i] = m;
|
_nearEdges[i] = m * rtl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
below = here; here = above;
|
||||||
|
above = i < (int)_edges.size() - 2 ? _edges[i+2] * rtl : 1e38f;
|
||||||
}
|
}
|
||||||
return collides; // note that true is not a necessarily reliable value
|
return collides; // note that true is not a necessarily reliable value
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,8 @@ GlyphCache::~GlyphCache()
|
||||||
|
|
||||||
const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
|
const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
|
||||||
{
|
{
|
||||||
|
if (glyphid >= numGlyphs())
|
||||||
|
return _glyphs[0];
|
||||||
const GlyphFace * & p = _glyphs[glyphid];
|
const GlyphFace * & p = _glyphs[glyphid];
|
||||||
if (p == 0 && _glyph_loader)
|
if (p == 0 && _glyph_loader)
|
||||||
{
|
{
|
||||||
|
@ -389,12 +391,14 @@ const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFa
|
||||||
gloce = be::peek<uint16>(gloc);
|
gloce = be::peek<uint16>(gloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glocs + 1 >= m_pGlat.size() || gloce > m_pGlat.size())
|
if (glocs >= m_pGlat.size() - 1 || gloce > m_pGlat.size())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const uint32 glat_version = be::peek<uint32>(m_pGlat);
|
const uint32 glat_version = be::peek<uint32>(m_pGlat);
|
||||||
if (glat_version >= 0x00030000)
|
if (glat_version >= 0x00030000)
|
||||||
{
|
{
|
||||||
|
if (glocs >= gloce)
|
||||||
|
return 0;
|
||||||
const byte * p = m_pGlat + glocs;
|
const byte * p = m_pGlat + glocs;
|
||||||
uint16 bmap = be::read<uint16>(p);
|
uint16 bmap = be::read<uint16>(p);
|
||||||
int num = bit_set_count((uint32)bmap);
|
int num = bit_set_count((uint32)bmap);
|
||||||
|
|
|
@ -100,7 +100,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
||||||
int numLevels = silf()->numJustLevels();
|
int numLevels = silf()->numJustLevels();
|
||||||
if (!numLevels)
|
if (!numLevels)
|
||||||
{
|
{
|
||||||
for (s = pSlot; s != end; s = s->next())
|
for (s = pSlot; s && s != end; s = s->nextSibling())
|
||||||
{
|
{
|
||||||
CharInfo *c = charinfo(s->before());
|
CharInfo *c = charinfo(s->before());
|
||||||
if (isWhitespace(c->unicodeChar()))
|
if (isWhitespace(c->unicodeChar()))
|
||||||
|
@ -113,7 +113,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
||||||
}
|
}
|
||||||
if (!icount)
|
if (!icount)
|
||||||
{
|
{
|
||||||
for (s = pSlot; s != end; s = s->nextSibling())
|
for (s = pSlot; s && s != end; s = s->nextSibling())
|
||||||
{
|
{
|
||||||
s->setJustify(this, 0, 3, 1);
|
s->setJustify(this, 0, 3, 1);
|
||||||
s->setJustify(this, 0, 2, 1);
|
s->setJustify(this, 0, 2, 1);
|
||||||
|
@ -124,7 +124,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<JustifyTotal> stats(numLevels);
|
Vector<JustifyTotal> stats(numLevels);
|
||||||
for (s = pFirst; s != end; s = s->nextSibling())
|
for (s = pFirst; s && s != end; s = s->nextSibling())
|
||||||
{
|
{
|
||||||
float w = s->origin().x / scale + s->advance() - base;
|
float w = s->origin().x / scale + s->advance() - base;
|
||||||
if (w > currWidth) currWidth = w;
|
if (w > currWidth) currWidth = w;
|
||||||
|
@ -139,13 +139,14 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
||||||
float error = 0.;
|
float error = 0.;
|
||||||
float diffpw;
|
float diffpw;
|
||||||
int tWeight = stats[i].weight();
|
int tWeight = stats[i].weight();
|
||||||
|
if (tWeight == 0) continue;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
error = 0.;
|
error = 0.;
|
||||||
diff = width - currWidth;
|
diff = width - currWidth;
|
||||||
diffpw = diff / tWeight;
|
diffpw = diff / tWeight;
|
||||||
tWeight = 0;
|
tWeight = 0;
|
||||||
for (s = pFirst; s != end; s = s->nextSibling()) // don't include final glyph
|
for (s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
|
||||||
{
|
{
|
||||||
int w = s->getJustify(this, i, 3);
|
int w = s->getJustify(this, i, 3);
|
||||||
float pref = diffpw * w + error;
|
float pref = diffpw * w + error;
|
||||||
|
|
|
@ -339,7 +339,7 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
|
||||||
*t = be::read<uint16>(states);
|
*t = be::read<uint16>(states);
|
||||||
if (e.test(*t >= m_numStates, E_BADSTATE))
|
if (e.test(*t >= m_numStates, E_BADSTATE))
|
||||||
{
|
{
|
||||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 24));
|
face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 8));
|
||||||
return face.error(e);
|
return face.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -861,7 +861,6 @@ bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
|
||||||
|
|
||||||
bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
|
bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
|
||||||
{
|
{
|
||||||
KernCollider kerncoll(dbgout);
|
|
||||||
Slot *start = seg->first();
|
Slot *start = seg->first();
|
||||||
float ymin = 1e38f;
|
float ymin = 1e38f;
|
||||||
float ymax = -1e38f;
|
float ymax = -1e38f;
|
||||||
|
@ -884,7 +883,7 @@ bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
|
||||||
ymin = min(y + bbox.bl.y, ymin);
|
ymin = min(y + bbox.bl.y, ymin);
|
||||||
if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
|
if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
|
||||||
== (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
|
== (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
|
||||||
resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
|
resolveKern(seg, s, start, dir, ymin, ymax, dbgout);
|
||||||
if (c->flags() & SlotCollision::COLL_END)
|
if (c->flags() & SlotCollision::COLL_END)
|
||||||
start = NULL;
|
start = NULL;
|
||||||
if (c->flags() & SlotCollision::COLL_START)
|
if (c->flags() & SlotCollision::COLL_START)
|
||||||
|
@ -1023,7 +1022,7 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
|
float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, int dir,
|
||||||
float &ymin, float &ymax, json *const dbgout) const
|
float &ymin, float &ymax, json *const dbgout) const
|
||||||
{
|
{
|
||||||
Slot *nbor; // neighboring slot
|
Slot *nbor; // neighboring slot
|
||||||
|
@ -1043,6 +1042,7 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
|
||||||
}
|
}
|
||||||
bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
|
bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
|
||||||
bool isInit = false;
|
bool isInit = false;
|
||||||
|
KernCollider coll(dbgout);
|
||||||
|
|
||||||
for (nbor = slotFix->next(); nbor; nbor = nbor->next())
|
for (nbor = slotFix->next(); nbor; nbor = nbor->next())
|
||||||
{
|
{
|
||||||
|
|
|
@ -184,7 +184,7 @@ inline Machine::status_t Machine::status() const throw()
|
||||||
return _status;
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Machine::check_final_stack(const int32 * const sp)
|
inline void Machine::check_final_stack(const stack_t * const sp)
|
||||||
{
|
{
|
||||||
stack_t const * const base = _stack + STACK_GUARD,
|
stack_t const * const base = _stack + STACK_GUARD,
|
||||||
* const limit = base + STACK_MAX;
|
* const limit = base + STACK_MAX;
|
||||||
|
|
|
@ -81,7 +81,7 @@ private:
|
||||||
bool collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
|
bool collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
|
||||||
bool resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
|
bool resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
|
||||||
int dir, bool &moved, bool &hasCol, json * const dbgout) const;
|
int dir, bool &moved, bool &hasCol, json * const dbgout) const;
|
||||||
float resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
|
float resolveKern(Segment *seg, Slot *slot, Slot *start, int dir,
|
||||||
float &ymin, float &ymax, json *const dbgout) const;
|
float &ymin, float &ymax, json *const dbgout) const;
|
||||||
|
|
||||||
const Silf * m_silf;
|
const Silf * m_silf;
|
||||||
|
|
|
@ -67,7 +67,8 @@ of the License or (at your option) any later version.
|
||||||
// #define NOT_IMPLEMENTED assert(false)
|
// #define NOT_IMPLEMENTED assert(false)
|
||||||
#define NOT_IMPLEMENTED
|
#define NOT_IMPLEMENTED
|
||||||
|
|
||||||
#define binop(op) const int32 a = pop(); *sp = int32(*sp) op a
|
#define binop(op) const uint32 a = pop(); *sp = uint32(*sp) op a
|
||||||
|
#define sbinop(op) const int32 a = pop(); *sp = int32(*sp) op a
|
||||||
#define use_params(n) dp += n
|
#define use_params(n) dp += n
|
||||||
|
|
||||||
#define declare_params(n) const byte * param = dp; \
|
#define declare_params(n) const byte * param = dp; \
|
||||||
|
@ -130,7 +131,7 @@ ENDOP
|
||||||
|
|
||||||
STARTOP(div_)
|
STARTOP(div_)
|
||||||
if (*sp == 0) DIE;
|
if (*sp == 0) DIE;
|
||||||
binop(/);
|
sbinop(/);
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(min_)
|
STARTOP(min_)
|
||||||
|
@ -181,19 +182,19 @@ STARTOP(not_eq_)
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(less)
|
STARTOP(less)
|
||||||
binop(<);
|
sbinop(<);
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(gtr)
|
STARTOP(gtr)
|
||||||
binop(>);
|
sbinop(>);
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(less_eq)
|
STARTOP(less_eq)
|
||||||
binop(<=);
|
sbinop(<=);
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(gtr_eq)
|
STARTOP(gtr_eq)
|
||||||
binop(>=);
|
sbinop(>=);
|
||||||
ENDOP
|
ENDOP
|
||||||
|
|
||||||
STARTOP(next)
|
STARTOP(next)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче