From 648027bec248a7b000741a507b507f6d89941ce5 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 5 Jul 2010 22:26:04 +0000 Subject: asy 2.00 git-svn-id: svn://tug.org/texlive/trunk@19250 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/utils/asymptote/coder.cc | 66 ++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 12 deletions(-) (limited to 'Build/source/utils/asymptote/coder.cc') diff --git a/Build/source/utils/asymptote/coder.cc b/Build/source/utils/asymptote/coder.cc index 6b08408ab2c..f2d3b4d6833 100644 --- a/Build/source/utils/asymptote/coder.cc +++ b/Build/source/utils/asymptote/coder.cc @@ -13,6 +13,7 @@ #include "coder.h" #include "genv.h" #include "entry.h" +#include "builtin.h" using namespace sym; using namespace types; @@ -37,7 +38,7 @@ vm::lambda *newLambda(string name) { // The dummy environment of the global environment. // Used purely for global variables and static code blocks of file // level modules. -coder::coder(string name, modifier sord) +coder::coder(position pos, string name, modifier sord) : level(new frame(name, 0, 0)), recordLevel(0), recordType(0), @@ -49,14 +50,14 @@ coder::coder(string name, modifier sord) perm(DEFAULT_PERM), program(new vm::program), numLabels(0), - curPos(nullPos) + curPos(pos) { sord_stack.push(sord); encodeAllocInstruction(); } // Defines a new function environment. -coder::coder(string name, function *t, coder *parent, +coder::coder(position pos, string name, function *t, coder *parent, modifier sord, bool reframe) : level(reframe ? new frame(name, parent->getFrame(), @@ -72,7 +73,7 @@ coder::coder(string name, function *t, coder *parent, perm(DEFAULT_PERM), program(new vm::program), numLabels(0), - curPos(nullPos) + curPos(pos) { sord_stack.push(sord); encodeAllocInstruction(); @@ -80,7 +81,7 @@ coder::coder(string name, function *t, coder *parent, // Start encoding the body of the record. The function being encoded // is the record's initializer. -coder::coder(record *t, coder *parent, modifier sord) +coder::coder(position pos, record *t, coder *parent, modifier sord) : level(t->getLevel()), recordLevel(t->getLevel()), recordType(t), @@ -92,20 +93,20 @@ coder::coder(record *t, coder *parent, modifier sord) perm(DEFAULT_PERM), program(new vm::program), numLabels(0), - curPos(nullPos) + curPos(pos) { sord_stack.push(sord); encodeAllocInstruction(); } -coder coder::newFunction(string name, function *t, modifier sord) +coder coder::newFunction(position pos, string name, function *t, modifier sord) { - return coder(name, t, this, sord); + return coder(pos, name, t, this, sord); } -coder coder::newCodelet() +coder coder::newCodelet(position pos) { - return coder("", new function(primVoid()), this, + return coder(pos, "", new function(primVoid()), this, DEFAULT_DYNAMIC, false); } @@ -120,9 +121,9 @@ record *coder::newRecord(symbol id) return r; } -coder coder::newRecordInit(record *r, modifier sord) +coder coder::newRecordInit(position pos, record *r, modifier sord) { - return coder(r, this, sord); + return coder(pos, r, this, sord); } #ifdef DEBUG_BLTIN @@ -136,6 +137,34 @@ void assertBltinLookup(inst::opcode op, item it) #endif +void coder::encodePop() +{ + if (isStatic() && !isTopLevel()) { + assert(parent); + parent->encodePop(); + } + else { +#ifdef COMBO + vm::program::label end = program->end(); + --end; + inst& lastInst = *end; + if (lastInst.op == inst::varsave) { + lastInst.op = inst::varpop; + return; + } + if (lastInst.op == inst::fieldsave) { + lastInst.op = inst::fieldpop; + return; + } + // TODO: push+pop into no op. +#endif + + // No combo applicable. Just encode a usual pop. + encode(inst::pop); + } +} + + bool coder::encode(frame *f) { frame *toplevel = getFrame(); @@ -223,6 +252,19 @@ void coder::useLabel(inst::opcode op, Int label) if (isStatic()) return parent->useLabel(op,label); +#ifdef COMBO + if (op == inst::cjmp || op == inst::njmp) { + inst& last = program->back(); + if (last.op == inst::builtin) { + bltin f = vm::get(last); + if (f == run::intLess && op == inst::njmp) { + program->pop_back(); + op = inst::gejmp; + } + } + } +#endif + std::map::iterator p = defs.find(label); if (p != defs.end()) { encode(op,p->second); -- cgit v1.2.3