📄 mal_instruction.mx
字号:
else setProperty(getProps(mb,i), name, op, cst->vtype, VALget(cst));}@+ Reverse programmingSince MAL programs can be created on the fly by linked-in querycompilers, or transformed by optimizers, it becomesmandatory to be able to produce textual correct MAL programsfrom its internal representation.No guarantee is given to produce the exact input for a reversedMAL program, except that the output can be fed back forinterpretation. Provided, the code did not produce an error.The hiddenInstruction operator assumes a sufficiently large blockto leave information on the signature behind.@c#define advance(X) while(*(X))(X)++;strtypechkName(int i){ switch (i) { default: case TYPE_ERROR: return " error"; case TYPE_UNKNOWN: return " unknown"; case TYPE_DYNAMIC: return " dynamic"; case TYPE_BIND: return " bind"; case TYPE_RESOLVED: return ""; }}strrecognizedCall(MalBlkPtr mb, InstrPtr p, str s){ int i; str tpe; if( p->retc > 1) *s++= '('; for (i = 0; i < p->retc; i++) if (p->argv[i] >= 0) { str nme; char nmebuf[PATHLENGTH]; tpe = getTypeName(getArgType(mb, p, i)); if (isTmpVar(mb, getArg(p, i)) || isTypeVar(mb, getArg(p, i))) { snprintf(nmebuf, PATHLENGTH, "%c%d", TMPMARKER, getVarTmp(mb, getArg(p, i))); nme = nmebuf; } else nme = getArgName(mb, p, i); sprintf(s, "%s:%s%s", (nme ? nme : "nil"), tpe, (i<p->retc-1?", ":"")); advance(s); GDKfree(tpe); } if( p->retc > 1) *s++= ')'; sprintf(s," := %s.%s(", getModuleId(p),getFunctionId(p)); advance(s); for (i = p->retc; i < p->argc; i++) if (p->argv[i] >= 0) { str nme; char nmebuf[PATHLENGTH]; tpe = getTypeName(getArgType(mb, p, i)); if (isTmpVar(mb, getArg(p, i)) || isTypeVar(mb, getArg(p, i))) { snprintf(nmebuf, PATHLENGTH, "%c%d", TMPMARKER, getVarTmp(mb, getArg(p, i))); nme = nmebuf; } else nme = getArgName(mb, p, i); sprintf(s, "%s:%s%s", (nme ? nme : "nil"), tpe, (i<p->argc-1?", ":"")); advance(s); GDKfree(tpe); } advance(s); *s++= ')'; *s=0; return s;}strhiddenInstructionArgs(MalBlkPtr mb, InstrPtr p, str s){ int i; str tpe; sprintf(s, "\t# %d %s%s ", getPC(mb, p), ((p->blk && p->blk->binding) ? p->blk->binding : ""), typechkName(p->typechk)); advance(s); for (i = 0; i < p->argc; i++) if (p->argv[i] >= 0) { str nme; char nmebuf[PATHLENGTH]; if (i == p->retc) { sprintf(s, "<-"); advance(s); } tpe = getTypeName(getArgType(mb, p, i)); if (isTmpVar(mb, getArg(p, i)) || isTypeVar(mb, getArg(p, i))) { snprintf(nmebuf, PATHLENGTH, "%c%d", TMPMARKER, getVarTmp(mb, getArg(p, i))); nme = nmebuf; } else nme = getArgName(mb, p, i); sprintf(s, "(%s:%s)", (nme ? nme : "nil"), tpe); advance(s); GDKfree(tpe); } advance(s); if (p->jump) sprintf(s, " jump %d", p->jump); advance(s); return s;}@-It receives the space to store the definitionThe MAL profiler dumps some performance data at thebeginning of each line.@= performanceData#ifdef MALprofiler if( mb->profiler ){ int pc= getPC(mb,p); double avg= (mb->profiler[pc].ticks+0.0)/mb->profiler[pc].counter; sprintf(t,"[%7ld, %5.2f] ",mb->profiler[pc].counter,avg); } advance(t);#endif@-@= showParam tpe= getTypeName(getArgType(mb,p,i)); if( flg & LIST_MAL_PROPS ){ ps= getProps(mb,getArg(p,i)); pstring= propertySet2str(ps); } else pstring= GDKstrdup(""); advance(t); sprintf(t,"%s:%s%s",getArgName(mb,p,i),tpe,pstring); advance(t); if( i<p->@1-1) sprintf(t,","); if(pstring) { GDKfree(pstring); pstring=0;} GDKfree(tpe);@cstrfcnClass(InstrPtr p){ return operatorName(p->token);}strfcnDefinition(MalBlkPtr mb, InstrPtr p, str s, int flg){ int i; str t, tpe, pstring; PropertySet ps = 0; ps = getProps(mb,getArg(p, 0)); pstring = propertySet2str(ps); t = s; sprintf(t, "%s%s ", (flg ? "" : "#"), fcnClass(p)); advance(t); if (getModuleId(p)) sprintf(t, "%s.", getModuleId(p)); else sprintf(t, "user."); advance(t); if( pstring ) sprintf(t, "%s%s(", getFunctionId(p),pstring); else sprintf(t, "%s(", getFunctionId(p)); for (i = p->retc; i < p->argc; i++) { @:showParam(argc)@} advance(t); if (p->varargs & VARARGS) sprintf(t, "..."); advance(t); if (p->retc == 1) { tpe = getTypeName(getArgType(mb, p, 0)); sprintf(t, "):%s", tpe); GDKfree(tpe); advance(t); } else { sprintf(t, ") ("); t += 3; for (i = 0; i < p->retc; i++) { @:showParam(retc)@} if (p->varargs & VARRETS) sprintf(t, "..."); advance(t); *t++ = ')'; } if (mb->binding) sprintf(t, " address %s;", mb->binding); else sprintf(t, ";");#ifdef DEBUG_MAL_INSTR if (flg & LIST_MAL_TYPE) { advance(t); hiddenInstructionArgs(mb, p, t);/* advance(t); if( mb->typefixed) sprintf(t," typefixed"); if( mb->flowfixed) sprintf(t," flowfixed");*/ }#endif return s;}@-@= tabulate for(;tab>0;tab--) *t++= ' '; *t= 0; advance(t);@-Variables and MAL blocks, and instructions can be associated with aproperty list. At least for debugging purposes, the latest known valueshould be displayed.@= propertyList {char *tmp= propertySet2str(ps); strcat(t,tmp); GDKfree(tmp);} advance(t);@cstroperatorName(int i){ switch (i) { case ASSIGNsymbol: return ":="; case BARRIERsymbol: return "barrier"; case REDOsymbol: return "redo"; case LEAVEsymbol: return "leave"; case EXITsymbol: return "exit"; case RETURNsymbol: return "return"; case YIELDsymbol: return "yield"; case CATCHsymbol: return "catch"; case RAISEsymbol: return "raise"; case ENDsymbol: return "end"; case FUNCTIONsymbol: return "function"; case FACTORYsymbol: return "factory"; case COMMANDsymbol: return "command"; case PATTERNsymbol: return "pattern"; } return "Undefined";}strinstruction2str(MalBlkPtr mb, InstrPtr p, int flg){ int i, tab = 4; size_t len = 0; str s, t, nme; int low, high; char nmebuf[PATHLENGTH]; PropertySet ps = 0; str pstring = 0; len = 8196; s = GDKmalloc(len); if (flg) { s[0] = 0; t = s; } else { s[0] = '#'; if (p->typechk == TYPE_UNKNOWN) { s[1] = '!'; /* error */ s[2] = 0; t = s + 2; } else { s[1] = 0; t = s + 1; } } /* @:performanceData@ */ if (isTmpVar(mb, getArg(p, 0))) { if (isVarUsed(mb, getDestVar(p))) { snprintf(nmebuf, PATHLENGTH, "%c%d", TMPMARKER, getVarTmp(mb, getArg(p, 0))); } else nmebuf[0] = 0; nme = nmebuf; } else nme = getArgName(mb, p, 0); advance(t); if (p->token == REMsymbol) { /* do nothing */ } else if (p->barrier) { if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == RAISEsymbol) { @:tabulate@ } sprintf(t, "%s ", operatorName(p->barrier)); advance(t); } else if (!functionStart(p) && !functionExit(p)) @:tabulate@ switch (p->token) { case NOOPsymbol: case FCNcall: case FACcall: case PATcall: case CMDcall: case ASSIGNsymbol: if (p->argc <= 1 && getFunctionId(p) == NULL) { if( flg & LIST_MAL_PROPS ){ ps = getProps(mb,getArg(p, 0)); pstring = propertySet2str(ps); } else pstring = GDKstrdup(""); if (getVar(mb, getArg(p, 0))->isudftype) { str tpe = getTypeName(getVarType(mb, getArg(p, 0))); sprintf(t, "%s:%s%s ", nme, tpe, pstring); GDKfree(tpe); } else sprintf(t, "%s%s", nme, pstring); advance(t); if (pstring) GDKfree(pstring); } else { for (i = 0; i < p->retc; i++) if( !getVarTmp(mb, getArg(p,i)) || isVarUsed(mb, getArg(p,i)) ) break; if( i == p->retc) goto nolhs; /* display multi-assignment */ if (p->retc > 1) *t++ = '('; for (i = 0; i < p->retc; i++) { if( flg & LIST_MAL_PROPS ){ ps = getProps(mb,getArg(p, i)); pstring = propertySet2str(ps); } else pstring= GDKstrdup(""); if (getVar(mb, getArg(p, i))->isudftype) { str tpe = getTypeName(getVarType(mb, getArg(p, i))); sprintf(t, "%s:%s%s ", getArgName(mb, p, i), tpe, pstring); GDKfree(tpe); } else sprintf(t, "%s%s", getArgName(mb, p, i), pstring); if (pstring) GDKfree(pstring); advance(t); if (i < p->retc - 1) *t++ = ','; } if (p->retc > 1) *t++ = ')'; else *t++ = ' '; if (p->argc > p->retc || getFunctionId(p)) { sprintf(t, ":= "); t += 3; } *t = 0; nolhs:; } break; case ENDsymbol: sprintf(t, "end %s", getFunctionId(getInstrPtr(mb, 0))); break; case COMMANDsymbol: case FUNCTIONsymbol: case FACTORYsymbol: case PATTERNsymbol: return fcnDefinition(mb, p, s, flg); case REMsymbol: if(getVar(mb, getArg(p, 0))->value.val.sval) sprintf(t, "#%s ", getVar(mb, getArg(p, 0))->value.val.sval); else sprintf(t, "# "); break; default: sprintf(t, " ?%d? ", p->token); } advance(t); low = p->retc; high = p->argc; if (getModuleId(p)) sprintf(t, "%s.", getModuleId(p)); advance(t); if (getFunctionId(p)) { sprintf(t, "%s(", getFunctionId(p)); } else if (p->argc > p->retc + 1) sprintf(t, "("); for (i = low; i < high; i++) { advance(t); if (i + 1 == high && p->varargs & VARARGS) { sprintf(t, "..."); break; } if (isConstant(mb, getArg(p, i))) { str cv = NULL; VALformat(&cv, &getVar(mb, getArg(p, i))->value); if (strlen(cv) > ((size_t) len) - (t - s)) { char *ns = (char *) GDKmalloc(len = strlen(cv) + len + 2); *t = 0; strcpy(ns, s); t = ns + (t - s); GDKfree(s); s = ns; } strcat(t, cv); GDKfree(cv); advance(t); } else { if( ! isTypeVar(mb,getArg(p,i)) ){ if (isTmpVar(mb, getArg(p, i))) { if( ! isTypeVar(mb,getArg(p,i)) ) sprintf(t, "%c%d", TMPMARKER, getVarTmp(mb, getArg(p, i))); advance(t); } else sprintf(t, "%s", mb->var[getArg(p, i)]->name); } }@-Dump the type and value information.@c advance(t); if (!isTmpVar(mb, getArg(p, i)) && idcmp("bat", getArgName(mb, p, i)) == 0) { str hprop = 0, tprop = 0; str d1 = getTypeName(getHeadType(getArgType(mb, p, i))); str d2 = getTypeName(getTailType(getArgType(mb, p, i))); sprintf(t, ":bat[:%s%s,:%s%s]", d1, hprop, d2, tprop); GDKfree(d1); GDKfree(d2); advance(t); } else if ( isTypeVar(mb, getArg(p, i)) || ( isConstant(mb, getArg(p, i)) && ( getVar(mb, getArg(p, i))->isudftype || ATOMcmp(getArgType(mb,p,i), ATOMnilptr(getArgType(mb,p,i)), VALptr(&getVar(mb, getArg(p, i))->value) ) == 0 ) )) { char *tnme = getTypeName(getArgType(mb, p, i)); sprintf(t, ":%s", tnme); GDKfree(tnme); advance(t); } if (i + 1 < high) sprintf(t, ","); } advance(t); if (getFunctionId(p) || p->argc > p->retc + 1) sprintf(t, ")"); advance(t); if (p->token != REMsymbol) sprintf(t, ";"); if (flg & LIST_MAL_TYPE) { advance(t); t = hiddenInstructionArgs(mb, p, t); } advance(t); /* sprintf(t,"\n"); */ if (t > s + len) GDKfatal("instruction2str:"); return s;}strfunction2str(MalBlkPtr mb, int flg){ str ps, *txt; int i, *len, totlen = 0; txt = GDKmalloc(sizeof(str) * mb->stop); len = GDKmalloc(sizeof(int) * mb->stop); for (i = 0; i < mb->stop; i++) { txt[i] = instruction2str(mb, getInstrPtr(mb, i), flg); totlen += len[i] = strlen(txt[i]); } ps = GDKmalloc(totlen + mb->stop + 1); totlen = 0; for (i = 0; i < mb->stop; i++) { strncpy(ps + totlen,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -