From 86ef38c2e60d578ed51867442e4fa0617e91ba32 Mon Sep 17 00:00:00 2001 From: Bert Wesarg Date: Wed, 17 Sep 2008 18:23:45 +0200 Subject: [PATCH] refcount for Program use a refcount to free only macro programs not in use. Put the program into the stack frame window, so we can release the program if we return from that frame. parse-define.patch: * enable FreeProgram() again define_macro.patch: * enable FreeProgram() again B.W. Patch: +refcount-for-Program.patch Patch: !parse-define.patch Patch: !define_macro.patch --- GlobalSymTable.patch | 32 ++--- InterpretDebug-mods.patch | 48 +++---- InterpretDebug4.diff | 106 +++++---------- RSunderlineStyle.diff | 8 +- SUBR_TAG.patch | 26 ++-- Symbol-embed-name.patch | 6 +- UnderlineStyle.diff | 4 +- anonArrayNamedArgs7.diff | 132 ++++++++----------- consolidate-ops.patch | 2 +- core-typeof-syntax.patch | 34 ++--- define_macro.patch | 17 +-- escape_literal_macro.patch | 2 +- interpret_c-macro-cleanup.patch | 86 ++++++------- macroSemicolons.diff | 4 +- parse-define.patch | 41 +++--- pos_line_convert.patch | 2 +- refcount-for-Program.patch | 277 ++++++++++++++++++++++++++++++++++++++++ relativeFileNormalization.diff | 2 +- series | 1 + setWindowTitleFormat.diff | 2 +- stringToNum.diff | 2 +- timer_macros.patch | 2 +- 22 files changed, 525 insertions(+), 311 deletions(-) create mode 100644 refcount-for-Program.patch diff --git a/GlobalSymTable.patch b/GlobalSymTable.patch index 0d6841f..abd1aa6 100644 --- a/GlobalSymTable.patch +++ b/GlobalSymTable.patch @@ -27,7 +27,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c static rbTreeNode *arrayEmptyAllocator(void); static rbTreeNode *arrayAllocateNode(rbTreeNode *src); static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src); -@@ -139,12 +142,15 @@ static void stackdumpInternal(int n, int +@@ -136,12 +139,15 @@ static void stackdumpInternal(int n, int #else /* #ifndef DEBUG_STACK */ #define STACKDUMP(n, x) #define DISASM_RT(i, n) @@ -45,20 +45,20 @@ diff --quilt old/source/interpret.c new/source/interpret.c static char *AllocatedStrings = NULL; typedef struct SparseArrayEntryWrapperTag { -@@ -312,11 +318,11 @@ Program *FinishCreatingProgram(Accumulat - return newProg; +@@ -313,11 +319,11 @@ Program *FinishCreatingProgram(Accumulat } void FreeProgram(Program *prog) { -- freeSymbolTable(prog->localSymList); -+ freeSymbolList(prog->localSymList); - XtFree((char *)prog->code); - XtFree((char *)prog); + if (--prog->refcount == 0) { +- freeSymbolTable(prog->localSymList); ++ freeSymbolList(prog->localSymList); + XtFree((char *)prog->code); + XtFree((char *)prog); + } } - /* -@@ -737,18 +743,18 @@ void SetMacroFocusWindow(WindowInfo *win +@@ -710,18 +716,18 @@ void SetMacroFocusWindow(WindowInfo *win /* ** install an array iteration symbol @@ -80,7 +80,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c value.val.arrayPtr = NULL; return(InstallSymbol(symbolName, LOCAL_SYM, value)); } -@@ -757,54 +763,80 @@ Symbol *InstallIteratorSymbol(void) +@@ -730,54 +736,80 @@ Symbol *InstallIteratorSymbol(void) ** Lookup a constant string by its value. This allows reuse of string ** constants and fixing a leak in the interpreter. */ @@ -175,7 +175,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** install symbol name in symbol table -@@ -817,16 +849,16 @@ Symbol *InstallSymbol(const char *name, +@@ -790,16 +822,16 @@ Symbol *InstallSymbol(const char *name, s = malloc(sizeof(Symbol) + strlen(name)); strcpy(s->name, name); s->type = type; @@ -194,7 +194,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -886,12 +918,11 @@ Symbol *PromoteToGlobal(Symbol *sym) +@@ -859,12 +891,11 @@ Symbol *PromoteToGlobal(Symbol *sym) Don't use MACRO_FUNCTION_SYM as type, because in macro.c:readCheckMacroString() we use ProgramFree() for the .val.prog, but this symbol has no program attached and ProgramFree() is not NULL @@ -208,7 +208,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1110,10 +1141,11 @@ static void MarkArrayContentsAsUsed(Spar +@@ -1083,10 +1114,11 @@ static void MarkArrayContentsAsUsed(Spar void GarbageCollectStrings(void) { SparseArrayEntryWrapper *nextAP, *thisAP; @@ -220,7 +220,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c for (p = AllocatedStrings; p != NULL; p = *((char **)p)) { *(p + sizeof(char *)) = 0; } -@@ -1123,19 +1155,21 @@ void GarbageCollectStrings(void) +@@ -1096,19 +1128,21 @@ void GarbageCollectStrings(void) thisAP->inUse = 0; } @@ -250,7 +250,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* Collect all of the strings which remain unreferenced */ next = AllocatedStrings; -@@ -1198,21 +1232,46 @@ static void restoreContext(RestartData * +@@ -1171,21 +1205,46 @@ static void restoreContext(RestartData * PC = context->pc; InitiatingWindow = context->runWindow; FocusWindow = context->focusWindow; @@ -301,7 +301,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c ((StackP - (n)) >= TheStack) #define POP_CHECK(n) \ -@@ -4571,12 +4630,12 @@ static void disasmInternal(Inst *inst, i +@@ -4544,12 +4603,12 @@ static void disasmInternal(Inst *inst, i if (inst[i].func == OpFns[j]) { printd(" %*s", (int)opLen, opNames[j]); if (j == OP_PUSH_SYM || j == OP_ASSIGN) { diff --git a/InterpretDebug-mods.patch b/InterpretDebug-mods.patch index 4115527..a379aa9 100644 --- a/InterpretDebug-mods.patch +++ b/InterpretDebug-mods.patch @@ -2,16 +2,16 @@ Subject: modifications to the InterpretDebug patch --- - source/interpret.c | 119 +++++++++++++++++++++++++++++++++-------------------- + source/interpret.c | 117 ++++++++++++++++++++++++++++++++++------------------- source/interpret.h | 5 +- source/parse.y | 14 ++---- source/userCmds.c | 4 - - 4 files changed, 86 insertions(+), 56 deletions(-) + 4 files changed, 86 insertions(+), 54 deletions(-) diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -115,25 +115,25 @@ static const char *tagToStr(enum typeTag +@@ -112,25 +112,25 @@ static const char *tagToStr(enum typeTag #if defined(DEBUG_ASSEMBLY) || defined(DEBUG_STACK) #define DEBUG_DISASSEMBLER @@ -41,7 +41,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #define DISASM_RT(i, n) #endif /* #ifndef DEBUG_STACK */ -@@ -162,10 +162,12 @@ static Symbol *LocalSymList = NULL; /* +@@ -159,10 +159,12 @@ static Symbol *LocalSymList = NULL; /* static Inst Prog[PROGRAM_SIZE]; /* the program */ static Inst *ProgP; /* next free spot for code gen. */ static Inst *LoopStack[LOOP_STACK_SIZE]; /* addresses of break, cont stmts */ @@ -54,7 +54,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c static DataValue *StackP; /* next free spot on stack */ static DataValue *FrameP; /* frame pointer (start of local variables for the current subroutine invocation) */ -@@ -252,22 +254,24 @@ void InitMacroGlobals(void) +@@ -251,22 +253,24 @@ void InitMacroGlobals(void) /* ** Start collecting instructions for a program. Clears the program @@ -80,7 +80,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** Finish up the program under construction, and return it (code and ** symbol table) as a package that ExecuteMacro can execute. This -@@ -277,41 +281,39 @@ Program *FinishCreatingProgram(Accumulat +@@ -276,41 +280,41 @@ Program *FinishCreatingProgram(Accumulat { Program *newProg; int progLen, fpOffset = 0; @@ -94,6 +94,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c newProg->localSymList = LocalSymList; - newProg->name = NULL; + strcpy(newProg->name, ProgramName); + newProg->refcount = 1; /* Local variables' values are stored on the stack. Here we assign frame pointer offsets to them. */ @@ -116,17 +117,16 @@ diff --quilt old/source/interpret.c new/source/interpret.c void FreeProgram(Program *prog) { - freeSymbolTable(prog->localSymList); - XtFree((char *)prog->code); -- if (prog->name) { + if (--prog->refcount == 0) { + freeSymbolTable(prog->localSymList); + XtFree((char *)prog->code); - XtFree((char *)prog->name); -- } - XtFree((char *)prog); + XtFree((char *)prog); + } } /* - ** Add an operator (instruction) to the end of the current program -@@ -3084,11 +3086,11 @@ static void arrayDisposeNode(rbTreeNode +@@ -3066,11 +3070,11 @@ static void arrayDisposeNode(rbTreeNode src->color = -1; } @@ -139,7 +139,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** insert a DataValue into an array, allocate the array if needed ** keyStr must be a string that was allocated with AllocString() -@@ -3793,32 +3795,50 @@ int outPrintd() +@@ -3764,32 +3768,50 @@ int outPrintd() #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */ static void dumpVal(DataValue dv) { @@ -199,7 +199,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (!dv.val.inst) { printd(""); } -@@ -3840,61 +3860,70 @@ static void disasmInternal(Inst *inst, i +@@ -3811,61 +3833,70 @@ static void disasmInternal(Inst *inst, i #define OP(name, fn) #name, #include "ops.h" #undef OP @@ -283,7 +283,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c inst[i+3].value, &inst[i+3] + inst[i+3].value); i += 3; } -@@ -3902,41 +3931,45 @@ static void disasmInternal(Inst *inst, i +@@ -3873,41 +3904,45 @@ static void disasmInternal(Inst *inst, i j == OP_ARRAY_DELETE || j == OP_ARRAY_ASSIGN || j == OP_ANONARRAY_INDEX_VAL || @@ -337,7 +337,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #endif /* #ifdef DEBUG_DISASSEMBLER */ #ifdef DEBUG_STACK /* for run-time stack dumping */ -@@ -4060,11 +4093,11 @@ static void stackdumpInternal(int n, int +@@ -4032,11 +4067,11 @@ static void stackdumpInternal(int n, int printd("--------------Stack base--------------\n"); #else if (outpt < TheStack) @@ -353,12 +353,12 @@ diff --quilt old/source/interpret.c new/source/interpret.c diff --quilt old/source/interpret.h new/source/interpret.h --- old/source/interpret.h +++ new/source/interpret.h -@@ -105,11 +105,11 @@ typedef struct SymbolRec { - } Symbol; +@@ -106,11 +106,11 @@ typedef struct SymbolRec { typedef struct ProgramTag { Symbol *localSymList; Inst *code; + unsigned refcount; - char *name; + char name[1]; } Program; @@ -366,7 +366,7 @@ diff --quilt old/source/interpret.h new/source/interpret.h /* Information needed to re-start a preempted macro */ typedef struct { DataValue *stack; -@@ -125,10 +125,11 @@ typedef struct AccumulatorDataTag { +@@ -126,10 +126,11 @@ typedef struct AccumulatorDataTag { Symbol *localSymList; Inst prog[PROGRAM_SIZE]; Inst *progP; @@ -378,7 +378,7 @@ diff --quilt old/source/interpret.h new/source/interpret.h void InitMacroGlobals(void); SparseArrayEntry *arrayIterateFirst(DataValue *theArray); -@@ -141,11 +142,11 @@ unsigned ArraySize(DataValue *theArray); +@@ -142,11 +143,11 @@ unsigned ArraySize(DataValue *theArray); Boolean ArrayGet(DataValue* theArray, char* keyStr, DataValue* theValue); int ArrayCopy(DataValue *dstArray, DataValue *srcArray); @@ -394,7 +394,7 @@ diff --quilt old/source/interpret.h new/source/interpret.h diff --quilt old/source/parse.y new/source/parse.y --- old/source/parse.y +++ new/source/parse.y -@@ -181,11 +181,11 @@ define: DEFINE { +@@ -178,11 +178,11 @@ define: DEFINE { /* newly created sym, or we overwrite a local sym */; } else { yyerror("try to override built-in subroutine"); YYERROR; @@ -407,7 +407,7 @@ diff --quilt old/source/parse.y new/source/parse.y ADD_OP(OP_RETURN_NO_VAL); Program *prog = FinishCreatingProgram($1); XtFree((char *)$1); -@@ -601,13 +601,15 @@ blank: /* nothing */ +@@ -598,13 +598,15 @@ blank: /* nothing */ Program *ParseMacro(char *expr, char **msg, char **stoppedAt, int allowDefine, const char *name) { @@ -425,7 +425,7 @@ diff --quilt old/source/parse.y new/source/parse.y AllowDefine = allowDefine; /* call yyparse to parse the string and check for success. If the parse -@@ -624,16 +626,10 @@ Program *ParseMacro(char *expr, char **m +@@ -621,16 +623,10 @@ Program *ParseMacro(char *expr, char **m /* get the newly created program */ prog = FinishCreatingProgram(acc); diff --git a/InterpretDebug4.diff b/InterpretDebug4.diff index 5e55751..7743578 100644 --- a/InterpretDebug4.diff +++ b/InterpretDebug4.diff @@ -42,7 +42,7 @@ being invoked or which file is being interpreted when an error occurs. --- - source/interpret.c | 413 ++++++++++++++++++++++++++++++++++++++++++-------- + source/interpret.c | 403 ++++++++++++++++++++++++++++++++++++++++++-------- source/interpret.h | 2 source/macro.c | 9 - source/nedit.c | 4 @@ -50,8 +50,8 @@ being invoked or which file is being interpreted when an error occurs. source/parse.y | 10 + source/parse_noyacc.c | 9 - source/smartIndent.c | 22 +- - source/userCmds.c | 49 +++-- - 9 files changed, 421 insertions(+), 100 deletions(-) + source/userCmds.c | 49 +++--- + 9 files changed, 410 insertions(+), 101 deletions(-) diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c @@ -70,7 +70,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #include #include #include -@@ -105,21 +107,25 @@ static const char *tagToStr(enum typeTag +@@ -102,21 +104,25 @@ static const char *tagToStr(enum typeTag /*#define DEBUG_ASSEMBLY*/ /*#define DEBUG_STACK*/ @@ -96,7 +96,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #else /* #ifndef DEBUG_STACK */ #define STACKDUMP(n, x) #define DISASM_RT(i, n) -@@ -173,17 +179,21 @@ static int (*OpFns[])() = { +@@ -170,18 +176,22 @@ static int (*OpFns[])() = { #include "ops.h" #undef OP }; @@ -107,11 +107,13 @@ diff --quilt old/source/interpret.c new/source/interpret.c #define FP_ARG_COUNT_INDEX (-2) -#define FP_OLD_FP_INDEX (-3) -#define FP_RET_PC_INDEX (-4) --#define FP_TO_ARGS_DIST (4) /* should be 0 - (above index) */ +-#define FP_PROG_INDEX (-5) +-#define FP_TO_ARGS_DIST (5) /* should be 0 - (above index) */ +#define FP_FUNCTION_NAME (-3) /* !! */ +#define FP_SYMBOL_TABLE (-4) /* !! */ +#define FP_OLD_FP_INDEX (-5) +#define FP_RET_PC_INDEX (-6) ++#define FP_PROG_INDEX (-7) + +#define FP_TO_ARGS_DIST (0 - FP_RET_PC_INDEX) /* should be 0 - (above index) */ + @@ -121,35 +123,33 @@ diff --quilt old/source/interpret.c new/source/interpret.c #define FP_GET_ARG_COUNT(xFrameP) (FP_GET_ITEM(xFrameP, FP_ARG_COUNT_INDEX).val.n) #define FP_GET_OLD_FP(xFrameP) ((FP_GET_ITEM(xFrameP, FP_OLD_FP_INDEX)).val.dataval) #define FP_GET_RET_PC(xFrameP) ((FP_GET_ITEM(xFrameP, FP_RET_PC_INDEX)).val.inst) + #define FP_GET_PROG(xFrameP) ((FP_GET_ITEM(xFrameP, FP_PROG_INDEX)).val.prog) #define FP_ARG_START_INDEX(xFrameP) (-(FP_GET_ARG_COUNT(xFrameP) + FP_TO_ARGS_DIST)) - #define FP_GET_ARG_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN + FP_ARG_START_INDEX(xFrameP))) -@@ -266,10 +276,11 @@ Program *FinishCreatingProgram(Accumulat +@@ -265,10 +275,11 @@ Program *FinishCreatingProgram(Accumulat newProg = (Program *)XtMalloc(sizeof(Program)); progLen = ((char *)ProgP) - ((char *)Prog); newProg->code = (Inst *)XtMalloc(progLen); memcpy(newProg->code, Prog, progLen); newProg->localSymList = LocalSymList; + newProg->name = NULL; + newProg->refcount = 1; /* Local variables' values are stored on the stack. Here we assign frame pointer offsets to them. */ for (s = newProg->localSymList; s != NULL; s = s->next) - s->value.val.n = fpOffset++; -@@ -288,10 +299,13 @@ Program *FinishCreatingProgram(Accumulat - +@@ -289,10 +300,11 @@ Program *FinishCreatingProgram(Accumulat void FreeProgram(Program *prog) { - freeSymbolTable(prog->localSymList); - XtFree((char *)prog->code); -+ if (prog->name) { + if (--prog->refcount == 0) { + freeSymbolTable(prog->localSymList); + XtFree((char *)prog->code); + XtFree((char *)prog->name); -+ } - XtFree((char *)prog); + XtFree((char *)prog); + } } /* - ** Add an operator (instruction) to the end of the current program -@@ -469,10 +483,19 @@ int ExecuteMacro(WindowInfo *window, Pro +@@ -475,10 +487,19 @@ int ExecuteMacro(WindowInfo *window, Pro context->stackP->tag = NO_TAG; context->stackP++; @@ -169,27 +169,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c context->stackP++; *(context->stackP++) = noValue; /* cached arg array */ -@@ -572,10 +595,19 @@ void RunMacroAsSubrCall(Program *prog) - - StackP->tag = NO_TAG; - StackP->val.dataval = FrameP; /* old FrameP */ - StackP++; - -+ StackP->tag = NO_TAG; -+ StackP->val.sym = NULL; /* symbol table */ -+ StackP++; -+ -+ StackP->tag = STRING_TAG; -+ StackP->val.str.rep = ""; -+ StackP->val.str.len = strlen(StackP->val.str.rep); -+ StackP++; -+ - StackP->tag = NO_TAG; /* nArgs */ - StackP->val.n = 0; - StackP++; - - *(StackP++) = noValue; /* cached arg array */ -@@ -596,10 +628,19 @@ void RunMacroAsSubrCall(Program *prog) +@@ -578,10 +599,19 @@ void RunMacroAsSubrCall(Program *prog) StackP->tag = NO_TAG; StackP->val.dataval = FrameP; /* old FrameP */ @@ -209,7 +189,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c StackP++; *(StackP++) = noValue; /* cached arg array */ -@@ -1398,11 +1439,11 @@ static int pushArgArray(void) +@@ -1380,11 +1410,11 @@ static int pushArgArray(void) DISASM_RT(PC-1, 1); STACKDUMP(0, 3); @@ -222,17 +202,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c resultArray->val.arrayPtr = ArrayNew(); for (argNum = 0; argNum < nArgs; ++argNum) { -@@ -2160,26 +2201,36 @@ static int callSubroutine(void) - ** Push all of the required information to resume, and make space on the - ** stack for local variables (and initialize them), on top of the argument - ** values which are already there. - */ - if (sym->type == MACRO_FUNCTION_SYM) { -+ prog = sym->value.val.prog; -+ - StackP->tag = NO_TAG; /* return PC */ - StackP->val.inst = PC; - StackP++; +@@ -2157,10 +2187,19 @@ static int callSubroutine(void) StackP->tag = NO_TAG; /* old FrameP */ StackP->val.dataval = FrameP; @@ -252,15 +222,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c StackP++; *(StackP++) = noValue; /* cached arg array */ - - FrameP = StackP; -- prog = sym->value.val.prog; - PC = prog->code; - for (s = prog->localSymList; s != NULL; s = s->next) { - FP_GET_SYM_VAL(FrameP, s) = noValue; - StackP++; - } -@@ -2710,11 +2761,11 @@ static int arrayRef(void) +@@ -2704,11 +2743,11 @@ static int arrayRef(void) nDim = PC->value; PC++; @@ -273,7 +235,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c errNum = makeArrayKeyFromArgs(nDim, &keyString, 0); if (errNum != STAT_OK) { return(errNum); -@@ -2761,11 +2812,11 @@ static int arrayAssign(void) +@@ -2755,11 +2794,11 @@ static int arrayAssign(void) nDim = PC->value; PC++; @@ -286,7 +248,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c POP(srcValue); errNum = makeArrayKeyFromArgs(nDim, &keyString, 0); -@@ -2799,13 +2850,13 @@ static int arrayAssign(void) +@@ -2793,13 +2832,13 @@ static int arrayAssign(void) /* ** for use with assign-op operators (eg a[i,j] += k @@ -302,7 +264,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c { int errNum; DataValue srcArray, valueItem, moveExpr; -@@ -2816,11 +2867,11 @@ static int arrayRefAndAssignSetup(void) +@@ -2810,11 +2849,11 @@ static int arrayRefAndAssignSetup(void) PC++; nDim = PC->value; PC++; @@ -315,7 +277,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c POP(moveExpr); } -@@ -3081,20 +3132,75 @@ static int errCheck(const char *s) +@@ -3064,20 +3103,75 @@ static int errCheck(const char *s) else return STAT_OK; } @@ -392,7 +354,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c int StringToNum(const char *string, int *number) { -@@ -3140,167 +3246,352 @@ static const char *tagToStr(enum typeTag +@@ -3123,168 +3217,353 @@ static const char *tagToStr(enum typeTag return ""; } } @@ -704,12 +666,14 @@ diff --quilt old/source/interpret.c new/source/interpret.c - case FP_ARG_COUNT_INDEX: pos = "NArgs"; break; /* number of arguments */ - case FP_OLD_FP_INDEX: pos = "OldFP"; break; - case FP_RET_PC_INDEX: pos = "RetPC"; break; +- case FP_PROG_INDEX: pos = "Prog"; break; + case FP_ARG_ARRAY_INDEX: pos = "args[]"; break; /* argument array */ + case FP_ARG_COUNT_INDEX: pos = "NArgs"; break; /* num. arguments */ + case FP_FUNCTION_NAME: pos = "FnName"; break; + case FP_SYMBOL_TABLE: pos = "FnSyms"; break; + case FP_OLD_FP_INDEX: pos = "OldFP"; break; + case FP_RET_PC_INDEX: pos = "RetPC"; break; ++ case FP_PROG_INDEX: pos = "Prog"; break; default: - if (offset < -FP_TO_ARGS_DIST && offset >= -FP_TO_ARGS_DIST - nArgs) { + if (offset < -FP_TO_ARGS_DIST && @@ -775,7 +739,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c + stackdumpframe(arrow, outpt, FrameP, StackP, '*'); + printd("Stack ----->\n"); +#endif /* #ifdef DEBUG_STACK_HEADFIRST */ - } ++} + +static void stackdump(int n, int extra) +{ @@ -790,7 +754,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c + + outPrintd(); + fflush(stdout); -+} + } + #endif /* ifdef DEBUG_STACK */ diff --quilt old/source/interpret.h new/source/interpret.h @@ -808,12 +772,12 @@ diff --quilt old/source/interpret.h new/source/interpret.h typedef struct SparseArrayEntryTag { rbTreeNode nodePtrs; /* MUST BE FIRST ENTRY */ -@@ -104,10 +105,11 @@ typedef struct SymbolRec { - } Symbol; +@@ -105,10 +106,11 @@ typedef struct SymbolRec { typedef struct ProgramTag { Symbol *localSymList; Inst *code; + unsigned refcount; + char *name; } Program; @@ -913,7 +877,7 @@ diff --quilt old/source/parse.h new/source/parse.h diff --quilt old/source/parse.y new/source/parse.y --- old/source/parse.y +++ new/source/parse.y -@@ -620,14 +620,16 @@ blank: /* nothing */ +@@ -617,14 +617,16 @@ blank: /* nothing */ ** executed using ExecuteProgram. Returns program on success, or NULL ** on failure. If the command failed, the error message is returned ** as a pointer to a static string in msg, and the length of the string up @@ -931,7 +895,7 @@ diff --quilt old/source/parse.y new/source/parse.y /* whether we allow the "define" keyword */ AllowDefine = allowDefine; -@@ -646,10 +648,16 @@ Program *ParseMacro(char *expr, char **m +@@ -643,10 +645,16 @@ Program *ParseMacro(char *expr, char **m /* get the newly created program */ prog = FinishCreatingProgram(acc); diff --git a/RSunderlineStyle.diff b/RSunderlineStyle.diff index 497b48d..2436bbc 100644 --- a/RSunderlineStyle.diff +++ b/RSunderlineStyle.diff @@ -73,7 +73,7 @@ diff --quilt old/source/macro.c new/source/macro.c { "rangeset_get_by_name", rangesetGetByNameMS }, { "get_pattern_by_name", getPatternByNameMS }, { "get_pattern_at_pos", getPatternAtPosMS }, -@@ -5728,11 +5731,11 @@ static int rangesetInvertMS(WindowInfo * +@@ -5725,11 +5728,11 @@ static int rangesetInvertMS(WindowInfo * static int rangesetInfoMS(WindowInfo *window, DataValue *argList, int nArgs, DataValue *result, char **errMsg) { @@ -86,7 +86,7 @@ diff --quilt old/source/macro.c new/source/macro.c int label = 0; if (nArgs != 1) -@@ -5745,11 +5748,12 @@ static int rangesetInfoMS(WindowInfo *wi +@@ -5742,11 +5745,12 @@ static int rangesetInfoMS(WindowInfo *wi if (rangesetTable != NULL) { rangeset = RangesetFetch(rangesetTable, label); @@ -100,7 +100,7 @@ diff --quilt old/source/macro.c new/source/macro.c result->tag = ARRAY_TAG; result->val.arrayPtr = ArrayNew(); -@@ -5779,11 +5783,19 @@ static int rangesetInfoMS(WindowInfo *wi +@@ -5776,11 +5780,19 @@ static int rangesetInfoMS(WindowInfo *wi element.tag = STRING_TAG; if (!AllocNStringCpy(&element.val.str, mode)) M_FAILURE("Failed to allocate array value \"mode\" in %s"); @@ -121,7 +121,7 @@ diff --quilt old/source/macro.c new/source/macro.c /* ** Built-in macro subroutine for finding the extent of a range in a set. -@@ -5952,10 +5964,64 @@ static int rangesetSetColorMS(WindowInfo +@@ -5949,10 +5961,64 @@ static int rangesetSetColorMS(WindowInfo result->tag = NO_TAG; return True; } diff --git a/SUBR_TAG.patch b/SUBR_TAG.patch index 48e9f4a..9ea5d44 100644 --- a/SUBR_TAG.patch +++ b/SUBR_TAG.patch @@ -27,7 +27,7 @@ The define() macro returns also a pointer to the just created function: diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -110,10 +110,11 @@ static int doFreeProg(void); +@@ -107,10 +107,11 @@ static SparseArrayEntry *allocateSparseA /* is the intepreter in the special typeof() mode? */ static int inTypeOfMode; @@ -39,7 +39,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /*#define DEBUG_STACK*/ #if defined(DEBUG_ASSEMBLY) || defined(DEBUG_STACK) -@@ -131,11 +132,11 @@ static void disasmInternal(Inst *inst, i +@@ -128,11 +129,11 @@ static void disasmInternal(Inst *inst, i #endif /* #ifndef DEBUG_ASSEMBLY */ #ifdef DEBUG_STACK /* for run-time instruction and stack trace */ @@ -52,7 +52,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #define STACKDUMP(n, x) #define DISASM_RT(i, n) #endif /* #ifndef DEBUG_STACK */ -@@ -339,10 +340,11 @@ int AddSym(Symbol *sym, char **msg) +@@ -341,10 +342,11 @@ int AddSym(Symbol *sym, char **msg) { if (ProgP >= &Prog[PROGRAM_SIZE]) { *msg = "macro too large"; @@ -64,7 +64,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c return 1; } -@@ -814,10 +816,11 @@ Symbol *InstallSymbol(const char *name, +@@ -787,10 +789,11 @@ Symbol *InstallSymbol(const char *name, s = (Symbol *)malloc(sizeof(Symbol)); s->name = (char *)malloc(strlen(name)+1); /* +1 for '\0' */ strcpy(s->name, name); @@ -76,7 +76,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c LocalSymList = s; } else { s->next = GlobalSymList; -@@ -838,11 +841,11 @@ Symbol *InstallSymbol(const char *name, +@@ -811,11 +814,11 @@ Symbol *InstallSymbol(const char *name, */ Symbol *PromoteToGlobal(Symbol *sym) { @@ -89,7 +89,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* Remove sym from the local symbol list */ if (sym == LocalSymList) LocalSymList = sym->next; -@@ -1395,10 +1398,15 @@ static int pushSymVal(void) +@@ -1368,10 +1371,15 @@ static int pushSymVal(void) char *errMsg; if (!(s->value.val.subr)(FocusWindow, NULL, 0, &symVal, &errMsg)) { @@ -105,7 +105,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (symVal.tag == NO_TAG && !inTypeOfMode) { return execError("variable not set: %s", s->name); } -@@ -2524,14 +2532,28 @@ static int callSubroutineFromSymbol(Symb +@@ -2497,14 +2505,28 @@ static int callSubroutineFromSymbol(Symb int i; static DataValue noValue = {NO_TAG, {0}}; Program *prog; @@ -134,7 +134,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c */ if (sym->type == C_FUNCTION_SYM) { DataValue result; -@@ -4106,10 +4128,13 @@ static int typeOfOut(void) +@@ -4090,10 +4112,13 @@ static int typeOfOut(void) retVal.val.str.rep = PERM_ALLOC_STR("STRING"); break; case ARRAY_TAG: @@ -148,7 +148,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (PC->func == fetchRetVal) { PUSH(retVal); -@@ -4339,16 +4364,43 @@ static const char *tagToStr(enum typeTag +@@ -4312,16 +4337,43 @@ static const char *tagToStr(enum typeTag return ""; case STRING_TAG: return ""; @@ -192,7 +192,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c static int printdPos = 0; static int printdSize = 0; -@@ -4463,10 +4515,13 @@ static void dumpVal(DataValue dv) +@@ -4436,10 +4488,13 @@ static void dumpVal(DataValue dv) } break; case ARRAY_TAG: @@ -295,9 +295,9 @@ diff --quilt old/source/macro.c new/source/macro.c return wrongNArgsErr(errMsg); } if (!readStringArg(argList[0], &name, stringStorage[0], errMsg)) { -@@ -3838,15 +3845,19 @@ static int defineMS(WindowInfo *window, - */ - /* FreeProgram(sym->value.val.prog); */ +@@ -3835,15 +3842,19 @@ static int defineMS(WindowInfo *window, + } + FreeProgram(sym->value.val.prog); sym->value.val.prog = prog; } } else { diff --git a/Symbol-embed-name.patch b/Symbol-embed-name.patch index d150e46..e00beb2 100644 --- a/Symbol-embed-name.patch +++ b/Symbol-embed-name.patch @@ -11,7 +11,7 @@ This safes a malloc/free pair. diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -811,12 +811,12 @@ Symbol *LookupSymbol(const char *name) +@@ -784,12 +784,12 @@ Symbol *LookupSymbol(const char *name) */ Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value) { @@ -26,7 +26,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c s->value = value; s->added = 0; if (type == LOCAL_SYM) { -@@ -1203,15 +1203,14 @@ static void restoreContext(RestartData * +@@ -1176,15 +1176,14 @@ static void restoreContext(RestartData * static void freeSymbolTable(Symbol *symTab) { Symbol *s; @@ -46,7 +46,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* true, if you can pop n values */ #define OK_TO_POP(n) \ ((StackP - (n)) >= TheStack) -@@ -2777,18 +2776,30 @@ int OverlayRoutineFromSymbol(Symbol *sym +@@ -2755,18 +2754,30 @@ int OverlayRoutineFromSymbol(Symbol *sym ** executed in the caller's context from a function in macro.c. */ diff --git a/UnderlineStyle.diff b/UnderlineStyle.diff index 4127b98..b5888e0 100644 --- a/UnderlineStyle.diff +++ b/UnderlineStyle.diff @@ -246,7 +246,7 @@ diff --quilt old/source/highlightData.h new/source/highlightData.h diff --quilt old/source/macro.c new/source/macro.c --- old/source/macro.c +++ new/source/macro.c -@@ -5956,11 +5956,12 @@ static int rangesetSetModeMS(WindowInfo +@@ -5953,11 +5953,12 @@ static int rangesetSetModeMS(WindowInfo ** (patCode >= 0). ** From the name we obtain: ** ["color"] Foreground color name of style @@ -260,7 +260,7 @@ diff --quilt old/source/macro.c new/source/macro.c ** ["back_rgb"] RGB representation of background color of style ** ["extent"] Forward distance from position over which style applies ** We only supply the style name if the includeName parameter is set: -@@ -6050,10 +6051,16 @@ static int fillStyleResult(DataValue *re +@@ -6047,10 +6048,16 @@ static int fillStyleResult(DataValue *re DV.val.n = FontOfNamedStyleIsItalic(styleName); if (!ArrayInsert(result, PERM_ALLOC_STR("italic"), &DV)) { M_ARRAY_INSERT_FAILURE(); diff --git a/anonArrayNamedArgs7.diff b/anonArrayNamedArgs7.diff index 847cf8a..4666292 100644 --- a/anonArrayNamedArgs7.diff +++ b/anonArrayNamedArgs7.diff @@ -58,11 +58,11 @@ ArrayGet() function or iterate over entries as required. --- - doc/help.etx | 100 +++++++++-- - source/interpret.c | 478 +++++++++++++++++++++++++++++++++++++++++++---------- + doc/help.etx | 100 ++++++++++- + source/interpret.c | 476 +++++++++++++++++++++++++++++++++++++++++++---------- source/ops.h | 8 source/parse.y | 97 ++++++++++ - 4 files changed, 586 insertions(+), 97 deletions(-) + 4 files changed, 585 insertions(+), 96 deletions(-) diff --quilt old/doc/help.etx new/doc/help.etx --- old/doc/help.etx @@ -231,7 +231,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c static int execError(const char *s1, const char *s2); static rbTreeNode *arrayEmptyAllocator(void); static rbTreeNode *arrayAllocateNode(rbTreeNode *src); -@@ -178,19 +181,19 @@ static int (*OpFns[])() = { +@@ -175,20 +178,20 @@ static int (*OpFns[])() = { #define OP(name, fn) fn, #include "ops.h" #undef OP @@ -244,13 +244,15 @@ diff --quilt old/source/interpret.c new/source/interpret.c -#define FP_SYMBOL_TABLE (-4) /* !! */ -#define FP_OLD_FP_INDEX (-5) -#define FP_RET_PC_INDEX (-6) +-#define FP_PROG_INDEX (-7) +/* Stack-> symN-sym0(FP), nArgs, oldFP, retPC, argArray, argN-arg1, next, ... */ +#define FP_ARG_COUNT_INDEX (-1) +#define FP_FUNCTION_NAME (-2) /* !! */ +#define FP_SYMBOL_TABLE (-3) /* !! */ +#define FP_OLD_FP_INDEX (-4) +#define FP_RET_PC_INDEX (-5) -+#define FP_ARG_ARRAY_INDEX (-6) ++#define FP_PROG_INDEX (-6) ++#define FP_ARG_ARRAY_INDEX (-7) -#define FP_TO_ARGS_DIST (0 - FP_RET_PC_INDEX) /* should be 0 - (above index) */ +#define FP_TO_ARGS_DIST (0 - FP_ARG_ARRAY_INDEX) /* should be 0 - (above index) */ @@ -304,11 +306,11 @@ diff --quilt old/source/interpret.c new/source/interpret.c + if (!haveNamedArgs) + *(context->stackP++) = noValue; /* cached arg array */ - context->stackP->val.subr = NULL; /* return PC */ + context->stackP->val.prog = NULL; /* prog, nothing to be free */ context->stackP->tag = NO_TAG; context->stackP++; - -@@ -492,16 +503,14 @@ int ExecuteMacro(WindowInfo *window, Pro + +@@ -496,16 +507,14 @@ int ExecuteMacro(WindowInfo *window, Pro context->stackP->tag = STRING_TAG; context->stackP->val.str.rep = prog->name ? prog->name : ""; context->stackP->val.str.len = strlen(context->stackP->val.str.rep); @@ -327,10 +329,10 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* Initialize and make room on the stack for local variables */ for (s = prog->localSymList; s != NULL; s = s->next) { FP_GET_SYM_VAL(context->frameP, s) = noValue; -@@ -575,22 +584,30 @@ static Inst freeProgCode[] = { - { doFreeProg }, - { returnNoVal } - }; +@@ -574,23 +583,31 @@ int ContinueMacro(RestartData *continuat + } + } + } /* +** Set up a new stack frame, with no caller arguments, in the current context, @@ -348,47 +350,18 @@ diff --quilt old/source/interpret.c new/source/interpret.c Symbol *s; static DataValue noValue = {NO_TAG, {0}}; -+ /* if (!OK_TO_PUSH(9)) return MACRO_ERROR; */ -+ - /* setup a intermediate frame, to release the prog after finishing */ -+ *(StackP++) = noValue; /* cached arg array */ -+ - StackP->tag = NO_TAG; - StackP->val.inst = PC; /* return PC */ - StackP++; - - StackP->tag = NO_TAG; -@@ -604,26 +621,26 @@ void RunMacroAsSubrCall(Program *prog) - StackP->tag = STRING_TAG; - StackP->val.str.rep = ""; - StackP->val.str.len = strlen(StackP->val.str.rep); - StackP++; - -- StackP->tag = NO_TAG; /* nArgs */ -+ StackP->tag = INT_TAG; /* nArgs */ - StackP->val.n = 0; - StackP++; - -- *(StackP++) = noValue; /* cached arg array */ -- - FrameP = StackP; - PC = freeProgCode; - - /* push prog onto the stack */ - StackP->tag = NO_TAG; - StackP->val.prog = prog; - StackP++; - /* See subroutine "callSubroutine" for a description of the stack frame for a subroutine call */ ++ /* if (!OK_TO_PUSH(5)) return MACRO_ERROR; */ ++ + *(StackP++) = noValue; /* cached arg array */ + StackP->tag = NO_TAG; - StackP->val.inst = PC; /* return PC */ + StackP->val.prog = prog; /* prog */ StackP++; - + StackP->tag = NO_TAG; -@@ -637,22 +654,22 @@ void RunMacroAsSubrCall(Program *prog) +@@ -608,22 +625,22 @@ void RunMacroAsSubrCall(Program *prog) StackP->tag = STRING_TAG; StackP->val.str.rep = prog->name ? prog->name : ""; StackP->val.str.len = strlen(StackP->val.str.rep); @@ -414,7 +387,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c void FreeRestartData(RestartData *context) { XtFree((char *)context->stack); -@@ -1443,16 +1460,19 @@ static int pushArgArray(void) +@@ -1414,16 +1431,19 @@ static int pushArgArray(void) nArgs = FP_GET_ARG_COUNT(FrameP); resultArray = &FP_GET_ARG_ARRAY(FrameP); if (resultArray->tag != ARRAY_TAG) { @@ -435,7 +408,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } PUSH(*resultArray); return STAT_OK; -@@ -1504,10 +1524,278 @@ static int pushArraySymVal(void) +@@ -1475,10 +1495,278 @@ static int pushArraySymVal(void) return STAT_OK; } @@ -714,7 +687,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c ** Before: Prog-> [symbol], next, ... ** TheStack-> [value], next, ... ** After: Prog-> symbol, [next], ... -@@ -2139,53 +2427,62 @@ static int concat(void) +@@ -2110,53 +2398,62 @@ static int concat(void) } /* @@ -786,14 +759,23 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (result.tag == NO_TAG) { return execError("%s does not return a value", sym->name); } -@@ -2201,42 +2498,46 @@ static int callSubroutine(void) +@@ -2172,47 +2469,51 @@ static int callSubroutine(void) ** Push all of the required information to resume, and make space on the ** stack for local variables (and initialize them), on top of the argument ** values which are already there. */ if (sym->type == MACRO_FUNCTION_SYM) { -- prog = sym->value.val.prog; + PUSH_CHECK(5 + !haveNamedArgs); ++ + prog = sym->value.val.prog; + ++ if (!haveNamedArgs) ++ *(StackP++) = noValue; /* push dummy named arg array */ ++ + prog->refcount++; + StackP->tag = NO_TAG; /* prog */ + StackP->val.prog = prog; + StackP++; - StackP->tag = NO_TAG; /* return PC */ - StackP->val.inst = PC; @@ -815,20 +797,9 @@ diff --quilt old/source/interpret.c new/source/interpret.c - StackP->tag = NO_TAG; /* nArgs */ - StackP->val.n = nArgs; - StackP++; -+ prog = sym->value.val.prog; -+ -+ if (!haveNamedArgs) -+ *(StackP++) = noValue; /* push dummy named arg array */ -+ -+ StackP->tag = NO_TAG; /* return PC */ -+ StackP->val.inst = PC; -+ StackP++; - +- - *(StackP++) = noValue; /* cached arg array */ -+ StackP->tag = NO_TAG; /* old FrameP */ -+ StackP->val.dataval = FrameP; -+ StackP++; - +- - FrameP = StackP; - PC = prog->code; - for (s = prog->localSymList; s != NULL; s = s->next) { @@ -836,6 +807,14 @@ diff --quilt old/source/interpret.c new/source/interpret.c - StackP++; - } - return STAT_OK; ++ StackP->tag = NO_TAG; /* return PC */ ++ StackP->val.inst = PC; ++ StackP++; ++ ++ StackP->tag = NO_TAG; /* old FrameP */ ++ StackP->val.dataval = FrameP; ++ StackP++; ++ + StackP->tag = NO_TAG; + StackP->val.sym = prog->localSymList; /* symbol table */ + StackP++; @@ -845,7 +824,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c + StackP->val.str.len = strlen(sym->name); + StackP++; + -+ StackP->tag = INT_TAG; /* nArgs */ ++ StackP->tag = NO_TAG; /* nArgs */ + StackP->val.n = nArgs; + StackP++; + @@ -862,7 +841,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** Call an action routine */ -@@ -2244,11 +2545,17 @@ static int callSubroutine(void) +@@ -2220,11 +2521,17 @@ static int callSubroutine(void) String *argList; Cardinal numArgs = nArgs; XKeyEvent key_event; @@ -881,7 +860,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c (to stop shell commands from putting up their own separate banner) */ disp=XtDisplay(InitiatingWindow->shell); win=XtWindow(InitiatingWindow->shell); -@@ -2305,11 +2612,11 @@ static int returnVal(void) +@@ -2281,11 +2588,11 @@ static int returnVal(void) } /* @@ -894,7 +873,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c */ static int returnValOrNone(int valOnStack) { -@@ -2382,38 +2689,30 @@ static int branch(void) +@@ -2364,38 +2671,30 @@ static int branch(void) ** After: either: Prog-> branchDest, [next], ... ** After: or: Prog-> branchDest, next, ..., (branchdest)[next] */ @@ -942,7 +921,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** Ignore the address following the instruction and continue. Why? So -@@ -3400,11 +3699,18 @@ static void disasmInternal(Inst *inst, i +@@ -3371,11 +3670,18 @@ static void disasmInternal(Inst *inst, i else if (j == OP_CONCAT) { printd("nExpr=%d", inst[i+1].value); ++i; @@ -962,7 +941,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c else if (j == OP_BEGIN_ARRAY_ITER) { printd("%s in", inst[i+1].sym->name); ++i; -@@ -3414,12 +3720,16 @@ static void disasmInternal(Inst *inst, i +@@ -3385,12 +3691,16 @@ static void disasmInternal(Inst *inst, i inst[i+1].sym->name, inst[i+2].sym->name, inst[i+3].value, &inst[i+3] + inst[i+3].value); @@ -981,7 +960,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } else if (j == OP_ARRAY_REF_ASSIGN_SETUP) { printd("binOp=%s ", inst[i+1].value ? "true" : "false"); -@@ -3451,11 +3761,11 @@ static void disasm(Inst *inst, int nInst +@@ -3422,11 +3732,11 @@ static void disasm(Inst *inst, int nInst outPrintd(); } #endif /* #ifdef DEBUG_DISASSEMBLER */ @@ -994,7 +973,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c { DataValue *baseF = &FP_GET_ITEM(fp, FP_OLD_FP_INDEX); DataValue *oldFP = baseF ? baseF->val.dataval : NULL; -@@ -3508,16 +3818,16 @@ static void stackdumpframe(DataValue *ar +@@ -3479,17 +3789,17 @@ static void stackdumpframe(DataValue *ar (dv == arg1) ? "----" : (dv == fnNm) ? "====" : ""; printd("%4.4s", leadIn); @@ -1006,6 +985,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c case FP_SYMBOL_TABLE: pos = "FnSyms"; break; case FP_OLD_FP_INDEX: pos = "OldFP"; break; case FP_RET_PC_INDEX: pos = "RetPC"; break; + case FP_PROG_INDEX: pos = "Prog"; break; + case FP_ARG_ARRAY_INDEX: pos = "args[]"; break; /* argument array */ default: if (offset < -FP_TO_ARGS_DIST && @@ -1028,7 +1008,7 @@ diff --quilt old/source/parse.y new/source/parse.y %type operassign incrdecr %token '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ %token INCR DECR -@@ -318,11 +318,11 @@ simpstmt: /* simple variable assignmen +@@ -315,11 +315,11 @@ simpstmt: /* simple variable assignmen ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(0); ADD_IMMED(1); ADD_OP($1); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1); @@ -1041,7 +1021,7 @@ diff --quilt old/source/parse.y new/source/parse.y } ; -@@ -344,10 +344,63 @@ arglist: blank expr bla +@@ -341,10 +341,63 @@ arglist: blank expr bla | arglist ',' blank expr blank { $$ = $1 + 1; } ; catlist: numexpr %prec CONCAT { $$ = 1; } @@ -1105,7 +1085,7 @@ diff --quilt old/source/parse.y new/source/parse.y ADD_OP(OP_CONCAT); ADD_IMMED($1); } } -@@ -383,21 +436,58 @@ field: FIELD { +@@ -380,21 +433,58 @@ field: FIELD { ; arrayexpr: numexpr { $$ = GetPC(); @@ -1165,7 +1145,7 @@ diff --quilt old/source/parse.y new/source/parse.y ADD_OP(OP_ARRAY_REF); ADD_IMMED($3); } | numexpr dot field { -@@ -475,10 +565,11 @@ or: OR { +@@ -472,10 +562,11 @@ or: OR { } ; dot: '.' %prec '.' { diff --git a/consolidate-ops.patch b/consolidate-ops.patch index e481a22..5103fc5 100644 --- a/consolidate-ops.patch +++ b/consolidate-ops.patch @@ -178,7 +178,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #define FP_ARG_ARRAY_CACHE_INDEX (-1) #define FP_ARG_COUNT_INDEX (-2) #define FP_OLD_FP_INDEX (-3) -@@ -3027,54 +2987,14 @@ static void dumpVal(DataValue dv) +@@ -3043,54 +3003,14 @@ static void dumpVal(DataValue dv) #endif /* #ifdef DEBUG_DISASSEMBLER */ #ifdef DEBUG_DISASSEMBLER /* For debugging code generation */ diff --git a/core-typeof-syntax.patch b/core-typeof-syntax.patch index 867adde..e4ef46b 100644 --- a/core-typeof-syntax.patch +++ b/core-typeof-syntax.patch @@ -33,12 +33,12 @@ should suffice for this. diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -106,10 +106,13 @@ static void arrayDisposeNode(rbTreeNode +@@ -103,10 +103,13 @@ static rbTreeNode *arrayAllocateNode(rbT + static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src); + static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right); + static void arrayDisposeNode(rbTreeNode *src); static SparseArrayEntry *allocateSparseArrayEntry(void); - /* for internal use only */ - static int doFreeProg(void); - +/* is the intepreter in the special typeof() mode? */ +static int inTypeOfMode; + @@ -47,7 +47,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /*#define DEBUG_ASSEMBLY*/ /*#define DEBUG_STACK*/ -@@ -1394,11 +1397,11 @@ static int pushSymVal(void) +@@ -1367,11 +1370,11 @@ static int pushSymVal(void) &symVal, &errMsg)) { return execError(errMsg, s->name); } @@ -60,7 +60,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c PUSH(symVal); -@@ -1522,11 +1525,11 @@ static int pushArraySymVal(void) +@@ -1495,11 +1498,11 @@ static int pushArraySymVal(void) if (initEmpty && dataPtr->tag == NO_TAG) { dataPtr->tag = ARRAY_TAG; dataPtr->val.arrayPtr = ArrayNew(); @@ -73,7 +73,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c PUSH(*dataPtr); -@@ -2489,13 +2492,10 @@ static int callSubroutineFromSymbol(Symb +@@ -2462,13 +2465,10 @@ static int callSubroutineFromSymbol(Symb PreemptRequest = False; /* NB nArgs < 0 implies presence of named args array in last position */ if (!sym->value.val.subr(FocusWindow, StackP, nArgs, &result, &errMsg)) @@ -87,7 +87,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } return PreemptRequest ? STAT_PREEMPT : STAT_OK; } -@@ -2588,11 +2588,12 @@ static int callSubroutineFromSymbol(Symb +@@ -2566,11 +2566,12 @@ static int callSubroutineFromSymbol(Symb PreemptRequest = False; sym->value.val.xtproc(FocusWindow->lastFocus, (XEvent *)&key_event, argList, &numArgs); @@ -101,7 +101,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* Calling a non subroutine symbol */ -@@ -2824,18 +2825,16 @@ static int returnValOrNone(int valOnStac +@@ -2808,18 +2809,16 @@ static int returnValOrNone(int valOnStac PUSH(retVal); } else { PUSH(noValue); @@ -125,7 +125,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* NULL return PC indicates end of program */ return PC == NULL ? STAT_DONE : STAT_OK; } -@@ -3579,10 +3578,59 @@ static int deleteArrayElement(void) +@@ -3563,10 +3562,59 @@ static int deleteArrayElement(void) return(execError("attempt to delete from non-array", NULL)); } return(STAT_OK); @@ -180,11 +180,11 @@ diff --quilt old/source/interpret.c new/source/interpret.c + return STAT_OK; +} + - static int doFreeProg(void) - { - DataValue progDV; - - POP(progDV); + /* + ** checks errno after operations which can set it. If an error occured, + ** creates appropriate error messages and returns false + */ + static int errCheck(const char *s) diff --quilt old/source/parse.y new/source/parse.y --- old/source/parse.y +++ new/source/parse.y @@ -201,7 +201,7 @@ diff --quilt old/source/parse.y new/source/parse.y %type arglistopt arglist catlist fnarglsopt fnarglist fnarg %type cond comastmts comastmtlst for while do else and or arrayexpr mark %type evalsym -@@ -347,11 +347,16 @@ arglist: blank expr bla +@@ -344,11 +344,16 @@ arglist: blank expr bla catlist: numexpr %prec CONCAT { $$ = 1; } | catlist numexpr %prec CONCAT { $$ = $1 + 1; } ; @@ -219,7 +219,7 @@ diff --quilt old/source/parse.y new/source/parse.y } | SYMBOL '(' blank '=' blank expr blank ')' { /* a single array replaces the argument list */ -@@ -705,10 +710,11 @@ static int yylex(void) +@@ -702,10 +707,11 @@ static int yylex(void) if (!strcmp(symName, "return")) return RETURN; if (!strcmp(symName, "in")) return IN; if (!strcmp(symName, "$args")) return ARG_LOOKUP; diff --git a/define_macro.patch b/define_macro.patch index 678ceee..6e9eed6 100644 --- a/define_macro.patch +++ b/define_macro.patch @@ -8,10 +8,10 @@ only macro functions, no action routines nor c functions. --- doc/help.etx | 5 ++ - source/highlightData.c | 2 - source/macro.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ - source/parse.y | 2 - 4 files changed, 107 insertions(+), 2 deletions(-) + source/highlightData.c | 2 - + source/macro.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ + source/parse.y | 2 - + 4 files changed, 104 insertions(+), 2 deletions(-) diff --quilt old/source/macro.c new/source/macro.c --- old/source/macro.c @@ -42,7 +42,7 @@ diff --quilt old/source/macro.c new/source/macro.c static const BuiltInSubrName SpecialVars[] = { { "$cursor", cursorMV }, -@@ -3607,10 +3611,106 @@ static int callMS(WindowInfo *window, Da +@@ -3607,10 +3611,103 @@ static int callMS(WindowInfo *window, Da return False; } return OverlayRoutineFromSymbol(sym, nArgs, 1); @@ -129,10 +129,7 @@ diff --quilt old/source/macro.c new/source/macro.c + *errMsg = "Try to override a non macro function."; + return False; + } -+ /* its unsafe to free the old program, -+ ** maybe it is currently in use -+ */ -+ /* FreeProgram(sym->value.val.prog); */ ++ FreeProgram(sym->value.val.prog); + sym->value.val.prog = prog; + } + } else { @@ -187,7 +184,7 @@ diff --quilt old/doc/help.etx new/doc/help.etx diff --quilt old/source/parse.y new/source/parse.y --- old/source/parse.y +++ new/source/parse.y -@@ -884,11 +884,11 @@ static int yylex(void) +@@ -881,11 +881,11 @@ static int yylex(void) if (!strcmp(symName, "continue")) return CONTINUE; if (!strcmp(symName, "return")) return RETURN; if (!strcmp(symName, "in")) return IN; diff --git a/escape_literal_macro.patch b/escape_literal_macro.patch index d939c30..426711a 100644 --- a/escape_literal_macro.patch +++ b/escape_literal_macro.patch @@ -38,7 +38,7 @@ diff --quilt old/source/macro.c new/source/macro.c static const BuiltInSubrName SpecialVars[] = { { "$cursor", cursorMV }, -@@ -3966,10 +3969,58 @@ static int timerRemoveMS(WindowInfo *win +@@ -3963,10 +3966,58 @@ static int timerRemoveMS(WindowInfo *win } return True; diff --git a/interpret_c-macro-cleanup.patch b/interpret_c-macro-cleanup.patch index 6646044..de90b5d 100644 --- a/interpret_c-macro-cleanup.patch +++ b/interpret_c-macro-cleanup.patch @@ -10,12 +10,12 @@ Use 'do { } while (0)' syntax for macros and consolidate num/string conversion. diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -137,10 +137,12 @@ static void arrayDisposeNode(rbTreeNode +@@ -134,10 +134,12 @@ static rbTreeNode *arrayAllocateNode(rbT + static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src); + static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right); + static void arrayDisposeNode(rbTreeNode *src); static SparseArrayEntry *allocateSparseArrayEntry(void); - /* for internal use only */ - static int doFreeProg(void); - +static const char *tagToStr(enum typeTags tag); + /*#define DEBUG_ASSEMBLY*/ @@ -23,7 +23,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c #if defined(DEBUG_ASSEMBLY) || defined(DEBUG_STACK) #define DEBUG_DISASSEMBLER -@@ -178,11 +180,11 @@ static SparseArrayEntryWrapper *Allocate +@@ -175,11 +177,11 @@ static SparseArrayEntryWrapper *Allocate /* Message strings used in macros (so they don't get repeated every time the macros are used */ @@ -36,7 +36,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c static Symbol *LocalSymList = NULL; /* symbols local to the program */ static Inst Prog[PROGRAM_SIZE]; /* the program */ static Inst *ProgP; /* next free spot for code gen. */ -@@ -1107,102 +1109,156 @@ static void freeSymbolTable(Symbol *symT +@@ -1089,102 +1091,156 @@ static void freeSymbolTable(Symbol *symT symTab = s->next; free((char *)s); } @@ -267,7 +267,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c ** copy a symbol's value onto the stack ** Before: Prog-> [Sym], next, ... ** TheStack-> next, ... -@@ -1248,11 +1304,11 @@ static int pushSymVal(void) +@@ -1230,11 +1286,11 @@ static int pushSymVal(void) return execError("reading non-variable: %s", s->name); if (symVal.tag == NO_TAG) { return execError("variable not set: %s", s->name); @@ -280,7 +280,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } static int pushArgVal(void) -@@ -1260,11 +1316,11 @@ static int pushArgVal(void) +@@ -1242,11 +1298,11 @@ static int pushArgVal(void) int nArgs, argNum; DISASM_RT(PC-1, 1); @@ -293,7 +293,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (argNum >= nArgs || argNum < 0) { char argStr[TYPE_INT_STR_SIZE(argNum)]; sprintf(argStr, "%d", argNum + 1); -@@ -1351,11 +1407,11 @@ static int pushArraySymVal(void) +@@ -1333,11 +1389,11 @@ static int pushArraySymVal(void) if (dataPtr->tag == NO_TAG) { return execError("variable not set: %s", sym->name); @@ -306,7 +306,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1395,11 +1451,11 @@ static int assign(void) +@@ -1377,11 +1433,11 @@ static int assign(void) } else { dataPtr = &sym->value; @@ -319,7 +319,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c ArrayCopy(dataPtr, &value); } else { -@@ -1418,12 +1474,12 @@ static int dupStack(void) +@@ -1400,12 +1456,12 @@ static int dupStack(void) DataValue value; DISASM_RT(PC-1, 1); @@ -334,7 +334,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1440,20 +1496,20 @@ static int add(void) +@@ -1422,20 +1478,20 @@ static int add(void) int n1, n2; DISASM_RT(PC-1, 1); @@ -359,7 +359,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c while (leftIter || rightIter) { Boolean insertResult = True; -@@ -1483,20 +1539,20 @@ static int add(void) +@@ -1465,20 +1521,20 @@ static int add(void) } if (!insertResult) { return(execError("array insertion failure", NULL)); @@ -384,7 +384,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1512,20 +1568,20 @@ static int subtract(void) +@@ -1494,20 +1550,20 @@ static int subtract(void) int n1, n2; DISASM_RT(PC-1, 1); @@ -409,7 +409,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c while (leftIter) { Boolean insertResult = True; -@@ -1549,20 +1605,20 @@ static int subtract(void) +@@ -1531,20 +1587,20 @@ static int subtract(void) } if (!insertResult) { return(execError("array insertion failure", NULL)); @@ -434,7 +434,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1574,78 +1630,78 @@ static int subtract(void) +@@ -1556,78 +1612,78 @@ static int subtract(void) ** Before: TheStack-> value, next, ... ** After: TheStack-> resValue, next, ... */ @@ -527,7 +527,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** verify that compares are between integers and/or strings only ** Before: TheStack-> value1, value2, next, ... -@@ -1657,12 +1713,12 @@ static int eq(void) +@@ -1639,12 +1695,12 @@ static int eq(void) DataValue v1, v2; DISASM_RT(PC-1, 1); @@ -542,7 +542,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } else if (v1.tag == STRING_TAG && v2.tag == STRING_TAG) { v1.val.n = !strcmp(v1.val.str.rep, v2.val.str.rep); -@@ -1687,11 +1743,11 @@ static int eq(void) +@@ -1669,11 +1725,11 @@ static int eq(void) } else { return(execError("incompatible types to compare", NULL)); @@ -555,7 +555,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* negated eq() call */ static int ne(void) -@@ -1713,20 +1769,20 @@ static int bitAnd(void) +@@ -1695,20 +1751,20 @@ static int bitAnd(void) int n1, n2; DISASM_RT(PC-1, 1); @@ -580,7 +580,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c while (leftIter && rightIter) { Boolean insertResult = True; int compareResult = arrayEntryCompare((rbTreeNode *)leftIter, (rbTreeNode *)rightIter); -@@ -1744,20 +1800,20 @@ static int bitAnd(void) +@@ -1726,20 +1782,20 @@ static int bitAnd(void) } if (!insertResult) { return(execError("array insertion failure", NULL)); @@ -605,7 +605,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } /* -@@ -1773,20 +1829,20 @@ static int bitOr(void) +@@ -1755,20 +1811,20 @@ static int bitOr(void) int n1, n2; DISASM_RT(PC-1, 1); @@ -630,7 +630,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c while (leftIter || rightIter) { Boolean insertResult = True; -@@ -1815,37 +1871,37 @@ static int bitOr(void) +@@ -1797,37 +1853,37 @@ static int bitOr(void) } if (!insertResult) { return(execError("array insertion failure", NULL)); @@ -675,7 +675,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** raise one number to the power of another ** Before: TheStack-> raisedBy, number, next, ... -@@ -1856,12 +1912,12 @@ static int power(void) +@@ -1838,12 +1894,12 @@ static int power(void) int n1, n2, n3; DISASM_RT(PC-1, 1); @@ -690,7 +690,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c Note: We're not really wanting rounded results, we merely want to deal with this simple issue. So, 2^-2 = .5, but we don't want to round this to 1. This is mainly intended to deal with -@@ -1885,11 +1941,11 @@ static int power(void) +@@ -1867,11 +1923,11 @@ static int power(void) else { /* round to nearest integer for positive values*/ n3 = (int)(pow((double)n1, (double)n2) + (double)0.5); @@ -703,7 +703,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** concatenate two top items on the stack -@@ -1902,18 +1958,18 @@ static int concat(void) +@@ -1884,18 +1940,18 @@ static int concat(void) int len1, len2; DISASM_RT(PC-1, 1); @@ -725,7 +725,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** Call a subroutine or function (user defined or built-in). Args are the -@@ -1964,11 +2020,11 @@ static int callSubroutine(void) +@@ -1946,11 +2002,11 @@ static int callSubroutine(void) return execError(errMsg, sym->name); if (PC->func == fetchRetVal) { if (result.tag == NO_TAG) { @@ -738,10 +738,10 @@ diff --quilt old/source/interpret.c new/source/interpret.c return PreemptRequest ? STAT_PREEMPT : STAT_OK; } -@@ -2031,11 +2087,11 @@ static int callSubroutine(void) +@@ -2019,11 +2075,11 @@ static int callSubroutine(void) key_event.window=key_event.root=key_event.subwindow=win; - argList = XtCalloc(nArgs, sizeof(*argList)); + argList = (String *)XtCalloc(nArgs, sizeof(*argList)); /* pop arguments off the stack and put them in the argument list */ for (i=nArgs-1; i>=0; i--) { - POP_STRING(argList[i]) @@ -751,7 +751,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* Call the action routine and check for preemption */ PreemptRequest = False; sym->value.val.xtproc(FocusWindow->lastFocus, -@@ -2088,11 +2144,11 @@ static int returnValOrNone(int valOnStac +@@ -2077,11 +2133,11 @@ static int returnValOrNone(int valOnStac DISASM_RT(PC-1, 1); STACKDUMP(StackP - FrameP + FP_GET_ARG_COUNT(FrameP) + FP_TO_ARGS_DIST, 3); @@ -764,8 +764,8 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* get stored return information */ nArgs = FP_GET_ARG_COUNT(FrameP); newFrameP = FP_GET_OLD_FP(FrameP); -@@ -2105,17 +2161,17 @@ static int returnValOrNone(int valOnStac - FrameP = newFrameP; +@@ -2099,17 +2155,17 @@ static int returnValOrNone(int valOnStac + } /* push returned value, if requsted */ if (PC == NULL) { @@ -785,7 +785,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c return execError( "using return value of %s which does not return a value", ((PC-2)->sym->name)); -@@ -2155,11 +2211,11 @@ static int branchTrue(void) +@@ -2149,11 +2205,11 @@ static int branchTrue(void) Inst *addr; DISASM_RT(PC-1, 2); @@ -798,7 +798,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (value) PC = addr; -@@ -2171,11 +2227,11 @@ static int branchFalse(void) +@@ -2165,11 +2221,11 @@ static int branchFalse(void) Inst *addr; DISASM_RT(PC-1, 2); @@ -811,7 +811,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c if (!value) PC = addr; -@@ -2250,11 +2306,11 @@ static int makeArrayKeyFromArgs(int nArg +@@ -2244,11 +2300,11 @@ static int makeArrayKeyFromArgs(int nArg int keyLength = 0; int i; @@ -824,7 +824,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } else if (tmpVal.tag == STRING_TAG) { keyLength += tmpVal.val.str.len; -@@ -2267,11 +2323,11 @@ static int makeArrayKeyFromArgs(int nArg +@@ -2261,11 +2317,11 @@ static int makeArrayKeyFromArgs(int nArg (*keyString)[0] = 0; for (i = nArgs - 1; i >= 0; --i) { if (i != nArgs - 1) { @@ -837,7 +837,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } else if (tmpVal.tag == STRING_TAG) { strcat(*keyString, tmpVal.val.str.rep); -@@ -2280,11 +2336,11 @@ static int makeArrayKeyFromArgs(int nArg +@@ -2274,11 +2330,11 @@ static int makeArrayKeyFromArgs(int nArg return(execError("can only index array with string or int.", NULL)); } } @@ -850,7 +850,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c return(STAT_OK); } -@@ -2504,26 +2560,26 @@ static int arrayRef(void) +@@ -2498,26 +2554,26 @@ static int arrayRef(void) errNum = makeArrayKeyFromArgs(nDim, &keyString, 0); if (errNum != STAT_OK) { return(errNum); @@ -881,7 +881,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c else { return(execError("operator [] on non-array", NULL)); } -@@ -2550,18 +2606,18 @@ static int arrayAssign(void) +@@ -2544,18 +2600,18 @@ static int arrayAssign(void) DISASM_RT(PC-2, 1); STACKDUMP(nDim, 3); @@ -902,7 +902,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c return(execError("cannot assign array element of non-array", NULL)); } if (srcValue.tag == ARRAY_TAG) { -@@ -2605,27 +2661,27 @@ static int arrayRefAndAssignSetup(void) +@@ -2599,27 +2655,27 @@ static int arrayRefAndAssignSetup(void) DISASM_RT(PC-3, 3); STACKDUMP(nDim + 1, 3); @@ -934,7 +934,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c } else { return(execError("operator [] on non-array", NULL)); -@@ -2658,11 +2714,11 @@ static int beginArrayIter(void) +@@ -2652,11 +2708,11 @@ static int beginArrayIter(void) STACKDUMP(1, 3); iterator = PC->sym; @@ -947,7 +947,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator); } else { -@@ -2770,33 +2826,33 @@ static int inArray(void) +@@ -2764,33 +2820,33 @@ static int inArray(void) int inResult = 0; DISASM_RT(PC-1, 1); @@ -986,7 +986,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c /* ** remove a given key from an array unless nDim is 0, then all keys are removed -@@ -2826,11 +2882,11 @@ static int deleteArrayElement(void) +@@ -2820,11 +2876,11 @@ static int deleteArrayElement(void) if (errNum != STAT_OK) { return(errNum); } @@ -999,7 +999,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c ArrayDelete(&theArray, keyString); } else { -@@ -2909,10 +2965,26 @@ int StringToNum(const char *string, int +@@ -2892,10 +2948,26 @@ int StringToNum(const char *string, int } } return True; diff --git a/macroSemicolons.diff b/macroSemicolons.diff index d15a938..0ba4966 100644 --- a/macroSemicolons.diff +++ b/macroSemicolons.diff @@ -28,7 +28,7 @@ diff --quilt old/source/parse.y new/source/parse.y %left CONCAT %left OR %left AND -@@ -185,11 +186,14 @@ define: DEFINE { +@@ -182,11 +183,14 @@ define: DEFINE { $4->type = MACRO_FUNCTION_SYM; $4->value.tag = NO_TAG; $4->value.val.prog = prog; @@ -44,7 +44,7 @@ diff --quilt old/source/parse.y new/source/parse.y } | IF '(' cond ')' blank block else blank block %prec ELSE { SET_BR_OFF($3, ($7+1)); SET_BR_OFF($7, GetPC()); -@@ -211,26 +215,26 @@ stmt: simpstmt '\n' blank +@@ -208,26 +212,26 @@ stmt: simpstmt '\n' blank blank block { ADD_OP(OP_BRANCH); ADD_BR_OFF($5+2); SET_BR_OFF($5+5, GetPC()); diff --git a/parse-define.patch b/parse-define.patch index 57f5fd6..eb6c9a7 100644 --- a/parse-define.patch +++ b/parse-define.patch @@ -26,15 +26,15 @@ ChangeLog: --- - source/interpret.c | 24 +++++--- + source/interpret.c | 24 ++++++-- source/interpret.h | 16 ++++- - source/macro.c | 147 +++++++++------------------------------------------ + source/macro.c | 144 +++++++++------------------------------------------ source/nedit.c | 2 source/parse.h | 2 - source/parse.y | 78 ++++++++++++++++++++++----- + source/parse.y | 75 +++++++++++++++++++++----- source/smartIndent.c | 8 +- source/userCmds.c | 4 - - 8 files changed, 131 insertions(+), 150 deletions(-) + 8 files changed, 128 insertions(+), 147 deletions(-) diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c @@ -54,7 +54,7 @@ diff --quilt old/source/interpret.c new/source/interpret.c returning to allow other things to run */ /* Temporary markers placed in a branch address location to designate -@@ -237,42 +234,55 @@ void InitMacroGlobals(void) +@@ -237,23 +234,30 @@ void InitMacroGlobals(void) /* ** Start collecting instructions for a program. Clears the program @@ -88,11 +88,12 @@ diff --quilt old/source/interpret.c new/source/interpret.c int progLen, fpOffset = 0; Symbol *s; - newProg = (Program *)XtMalloc(sizeof(Program)); +@@ -261,19 +265,25 @@ Program *FinishCreatingProgram(void) progLen = ((char *)ProgP) - ((char *)Prog); newProg->code = (Inst *)XtMalloc(progLen); memcpy(newProg->code, Prog, progLen); newProg->localSymList = LocalSymList; + newProg->refcount = 1; - LocalSymList = NULL; /* Local variables' values are stored on the stack. Here we assign @@ -131,7 +132,7 @@ diff --quilt old/source/interpret.h new/source/interpret.h C_FUNCTION_SYM, MACRO_FUNCTION_SYM, ACTION_ROUTINE_SYM}; enum operations { -@@ -113,10 +116,19 @@ typedef struct { +@@ -114,10 +117,19 @@ typedef struct { Inst *pc; WindowInfo *runWindow; WindowInfo *focusWindow; @@ -151,7 +152,7 @@ diff --quilt old/source/interpret.h new/source/interpret.h SparseArrayEntry *arrayIterateFirst(DataValue *theArray); SparseArrayEntry *arrayIterateNext(SparseArrayEntry *iterator); SparseArrayEntry *ArrayNew(void); -@@ -127,22 +139,22 @@ unsigned ArraySize(DataValue *theArray); +@@ -128,22 +140,22 @@ unsigned ArraySize(DataValue *theArray); Boolean ArrayGet(DataValue* theArray, char* keyStr, DataValue* theValue); int ArrayCopy(DataValue *dstArray, DataValue *srcArray); @@ -192,7 +193,7 @@ diff --quilt old/source/macro.c new/source/macro.c "NEdit internal error, learn/replay macro syntax error: %s\n", errMsg); return; -@@ -849,133 +849,40 @@ int CheckMacroString(Widget dialogParent +@@ -849,130 +849,40 @@ int CheckMacroString(Widget dialogParent ** returns a pointer to the error location in the string. */ static int readCheckMacroString(Widget dialogParent, char *string, @@ -255,10 +256,7 @@ diff --quilt old/source/macro.c new/source/macro.c - sym = InstallSymbol(subrName, MACRO_FUNCTION_SYM, subrPtr); - } else { - if (sym->type == MACRO_FUNCTION_SYM) -- /* its unsafe to free the old program, -- ** maybe it is currently in use -- */ -- /* FreeProgram(sym->value.val.prog) */; +- FreeProgram(sym->value.val.prog); - else - sym->type = MACRO_FUNCTION_SYM; - sym->value.val.prog = prog; @@ -350,7 +348,7 @@ diff --quilt old/source/macro.c new/source/macro.c } /* -@@ -1231,11 +1138,11 @@ void DoMacro(WindowInfo *window, const c +@@ -1228,11 +1138,11 @@ void DoMacro(WindowInfo *window, const c strncpy(tMacro, macro, macroLen); tMacro[macroLen] = '\n'; tMacro[macroLen+1] = '\0'; @@ -363,7 +361,7 @@ diff --quilt old/source/macro.c new/source/macro.c XtFree(tMacro); return; } -@@ -1495,11 +1402,11 @@ selEnd += $text_length - startLength\n}\ +@@ -1492,11 +1402,11 @@ selEnd += $text_length - startLength\n}\ sprintf(loopedCmd, loopMacro, command); else sprintf(loopedCmd, loopMacro, how, command); @@ -446,7 +444,7 @@ diff --quilt old/source/parse.y new/source/parse.y | blank '{' blank stmts '}' { ADD_OP(OP_RETURN_NO_VAL); return 0; } -@@ -122,17 +126,63 @@ program: blank stmts { +@@ -122,17 +126,60 @@ program: blank stmts { } | error { return 1; @@ -483,10 +481,7 @@ diff --quilt old/source/parse.y new/source/parse.y + ** and this is questionable. + */ + if ($4->type == MACRO_FUNCTION_SYM) { -+ /* its unsafe to free the old program, -+ ** maybe it is currently in use -+ */ -+ /* FreeProgram($4->value.val.prog) */; ++ FreeProgram($4->value.val.prog); + } + else if ($4->type == LOCAL_SYM || + $4->type == GLOBAL_SYM) { @@ -511,7 +506,7 @@ diff --quilt old/source/parse.y new/source/parse.y SET_BR_OFF($3, GetPC()); } | IF '(' cond ')' blank block else blank block %prec ELSE { -@@ -472,29 +522,35 @@ blank: /* nothing */ +@@ -472,29 +519,35 @@ blank: /* nothing */ ** executed using ExecuteProgram. Returns program on success, or NULL ** on failure. If the command failed, the error message is returned ** as a pointer to a static string in msg, and the length of the string up @@ -551,7 +546,7 @@ diff --quilt old/source/parse.y new/source/parse.y *msg = ""; *stoppedAt = InPtr; return prog; -@@ -548,13 +604,12 @@ static int yylex(void) +@@ -548,13 +601,12 @@ static int yylex(void) if ((yylval.sym=LookupSymbol(name)) == NULL) yylval.sym = InstallSymbol(name, CONST_SYM, value); return NUMBER; @@ -567,7 +562,7 @@ diff --quilt old/source/parse.y new/source/parse.y if ((s=matchesActionRoutine(&InPtr)) == NULL) { char symName[MAX_SYM_LEN+1], *p = symName; *p++ = *InPtr++; -@@ -573,14 +628,11 @@ static int yylex(void) +@@ -573,14 +625,11 @@ static int yylex(void) if (!strcmp(symName, "continue")) return CONTINUE; if (!strcmp(symName, "return")) return RETURN; if (!strcmp(symName, "in")) return IN; diff --git a/pos_line_convert.patch b/pos_line_convert.patch index ba5e3d8..87cfed7 100644 --- a/pos_line_convert.patch +++ b/pos_line_convert.patch @@ -112,7 +112,7 @@ diff --quilt old/source/macro.c new/source/macro.c static const BuiltInSubrName SpecialVars[] = { { "$cursor", cursorMV }, -@@ -6321,10 +6335,206 @@ static int dictcompleteMS(WindowInfo *wi +@@ -6318,10 +6332,206 @@ static int dictcompleteMS(WindowInfo *wi return True; } diff --git a/refcount-for-Program.patch b/refcount-for-Program.patch new file mode 100644 index 0000000..b01b3e2 --- /dev/null +++ b/refcount-for-Program.patch @@ -0,0 +1,277 @@ +--- + + source/interpret.c | 76 ++++++++++++++++++++--------------------------------- + source/interpret.h | 1 + source/macro.c | 5 --- + 3 files changed, 32 insertions(+), 50 deletions(-) + +diff --quilt old/source/interpret.c new/source/interpret.c +--- old/source/interpret.c ++++ new/source/interpret.c +@@ -134,13 +134,10 @@ static rbTreeNode *arrayAllocateNode(rbT + static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src); + static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right); + static void arrayDisposeNode(rbTreeNode *src); + static SparseArrayEntry *allocateSparseArrayEntry(void); + +-/* for internal use only */ +-static int doFreeProg(void); +- + /*#define DEBUG_ASSEMBLY*/ + /*#define DEBUG_STACK*/ + + #if defined(DEBUG_ASSEMBLY) || defined(DEBUG_STACK) + #define DEBUG_DISASSEMBLER +@@ -216,16 +213,18 @@ static int (*OpFns[N_OPS])() = {returnNo + /* Stack-> symN-sym0(FP), argArray, nArgs, oldFP, retPC, argN-arg1, next, ... */ + #define FP_ARG_ARRAY_CACHE_INDEX (-1) + #define FP_ARG_COUNT_INDEX (-2) + #define FP_OLD_FP_INDEX (-3) + #define FP_RET_PC_INDEX (-4) +-#define FP_TO_ARGS_DIST (4) /* should be 0 - (above index) */ ++#define FP_PROG_INDEX (-5) ++#define FP_TO_ARGS_DIST (5) /* should be 0 - (above index) */ + #define FP_GET_ITEM(xFrameP,xIndex) (*(xFrameP + xIndex)) + #define FP_GET_ARG_ARRAY_CACHE(xFrameP) (FP_GET_ITEM(xFrameP, FP_ARG_ARRAY_CACHE_INDEX)) + #define FP_GET_ARG_COUNT(xFrameP) (FP_GET_ITEM(xFrameP, FP_ARG_COUNT_INDEX).val.n) + #define FP_GET_OLD_FP(xFrameP) ((FP_GET_ITEM(xFrameP, FP_OLD_FP_INDEX)).val.dataval) + #define FP_GET_RET_PC(xFrameP) ((FP_GET_ITEM(xFrameP, FP_RET_PC_INDEX)).val.inst) ++#define FP_GET_PROG(xFrameP) ((FP_GET_ITEM(xFrameP, FP_PROG_INDEX)).val.prog) + #define FP_ARG_START_INDEX(xFrameP) (-(FP_GET_ARG_COUNT(xFrameP) + FP_TO_ARGS_DIST)) + #define FP_GET_ARG_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN + FP_ARG_START_INDEX(xFrameP))) + #define FP_GET_SYM_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN)) + #define FP_GET_SYM_VAL(xFrameP,xSym) (FP_GET_SYM_N(xFrameP, xSym->value.val.n)) + +@@ -298,10 +297,11 @@ Program *FinishCreatingProgram(void) + newProg = (Program *)XtMalloc(sizeof(Program)); + progLen = ((char *)ProgP) - ((char *)Prog); + newProg->code = (Inst *)XtMalloc(progLen); + memcpy(newProg->code, Prog, progLen); + newProg->localSymList = LocalSymList; ++ newProg->refcount = 1; + LocalSymList = NULL; + + /* Local variables' values are stored on the stack. Here we assign + frame pointer offsets to them. */ + for (s = newProg->localSymList; s != NULL; s = s->next) +@@ -312,13 +312,15 @@ Program *FinishCreatingProgram(void) + return newProg; + } + + void FreeProgram(Program *prog) + { +- freeSymbolTable(prog->localSymList); +- XtFree((char *)prog->code); +- XtFree((char *)prog); ++ if (--prog->refcount == 0) { ++ freeSymbolTable(prog->localSymList); ++ XtFree((char *)prog->code); ++ XtFree((char *)prog); ++ } + } + + /* + ** Add an operator (instruction) to the end of the current program + */ +@@ -489,10 +491,14 @@ int ExecuteMacro(WindowInfo *window, Pro + + /* Push arguments and call information onto the stack */ + for (i=0; istackP++) = args[i]; + ++ context->stackP->val.prog = NULL; /* prog, nothing to be free */ ++ context->stackP->tag = NO_TAG; ++ context->stackP++; ++ + context->stackP->val.subr = NULL; /* return PC */ + context->stackP->tag = NO_TAG; + context->stackP++; + + *(context->stackP++) = noValue; /* old FrameP */ +@@ -572,15 +578,10 @@ int ContinueMacro(RestartData *continuat + return MACRO_TIME_LIMIT; + } + } + } + +-static Inst freeProgCode[] = { +- { doFreeProg }, +- { returnNoVal } +-}; +- + /* + ** If a macro is already executing, and requests that another macro be run, + ** this can be called instead of ExecuteMacro to run it in the same context + ** as if it were a subroutine. This saves the caller from maintaining + ** separate contexts, and serializes processing of the two macros without +@@ -589,35 +590,16 @@ static Inst freeProgCode[] = { + void RunMacroAsSubrCall(Program *prog) + { + Symbol *s; + static DataValue noValue = {NO_TAG, {0}}; + +- /* setup a intermediate frame, to release the prog after finishing */ +- StackP->tag = NO_TAG; +- StackP->val.inst = PC; /* return PC */ +- StackP++; +- +- StackP->tag = NO_TAG; +- StackP->val.dataval = FrameP; /* old FrameP */ +- StackP++; +- +- StackP->tag = NO_TAG; /* nArgs */ +- StackP->val.n = 0; +- StackP++; +- +- *(StackP++) = noValue; /* cached arg array */ +- +- FrameP = StackP; +- PC = freeProgCode; +- +- /* push prog onto the stack */ ++ /* See subroutine "callSubroutine" for a description of the stack frame ++ for a subroutine call */ + StackP->tag = NO_TAG; +- StackP->val.prog = prog; ++ StackP->val.prog = prog; /* prog */ + StackP++; + +- /* See subroutine "callSubroutine" for a description of the stack frame +- for a subroutine call */ + StackP->tag = NO_TAG; + StackP->val.inst = PC; /* return PC */ + StackP++; + + StackP->tag = NO_TAG; +@@ -1978,10 +1960,17 @@ static int callSubroutine(void) + ** Push all of the required information to resume, and make space on the + ** stack for local variables (and initialize them), on top of the argument + ** values which are already there. + */ + if (sym->type == MACRO_FUNCTION_SYM) { ++ prog = sym->value.val.prog; ++ ++ prog->refcount++; ++ StackP->tag = NO_TAG; /* prog */ ++ StackP->val.prog = prog; ++ StackP++; ++ + StackP->tag = NO_TAG; /* return PC */ + StackP->val.inst = PC; + StackP++; + + StackP->tag = NO_TAG; /* old FrameP */ +@@ -1993,11 +1982,10 @@ static int callSubroutine(void) + StackP++; + + *(StackP++) = noValue; /* cached arg array */ + + FrameP = StackP; +- prog = sym->value.val.prog; + PC = prog->code; + for (s = prog->localSymList; s != NULL; s = s->next) { + FP_GET_SYM_VAL(FrameP, s) = noValue; + StackP++; + } +@@ -2081,10 +2069,11 @@ static int returnVal(void) + static int returnValOrNone(int valOnStack) + { + DataValue retVal; + static DataValue noValue = {NO_TAG, {0}}; + DataValue *newFrameP; ++ Program *prog; + int nArgs; + + DISASM_RT(PC-1, 1); + STACKDUMP(StackP - FrameP + FP_GET_ARG_COUNT(FrameP) + FP_TO_ARGS_DIST, 3); + +@@ -2095,16 +2084,21 @@ static int returnValOrNone(int valOnStac + + /* get stored return information */ + nArgs = FP_GET_ARG_COUNT(FrameP); + newFrameP = FP_GET_OLD_FP(FrameP); + PC = FP_GET_RET_PC(FrameP); ++ prog = FP_GET_PROG(FrameP); + + /* pop past local variables */ + StackP = FrameP; + /* pop past function arguments */ + StackP -= (FP_TO_ARGS_DIST + nArgs); + FrameP = newFrameP; ++ ++ if (prog) { ++ FreeProgram(prog); ++ } + + /* push returned value, if requsted */ + if (PC == NULL) { + if (valOnStack) { + PUSH(retVal); +@@ -2841,21 +2835,10 @@ static int deleteArrayElement(void) + return(execError("attempt to delete from non-array", NULL)); + } + return(STAT_OK); + } + +-static int doFreeProg(void) +-{ +- DataValue progDV; +- +- POP(progDV); +- +- FreeProgram(progDV.val.prog); +- +- return STAT_OK; +-} +- + /* + ** checks errno after operations which can set it. If an error occured, + ** creates appropriate error messages and returns false + */ + static int errCheck(const char *s) +@@ -3091,10 +3074,11 @@ static void stackdump(int n, int extra) + case 0: pos = "FrameP"; break; /* first local symbol value */ + case FP_ARG_ARRAY_CACHE_INDEX: pos = "args"; break; /* arguments array */ + case FP_ARG_COUNT_INDEX: pos = "NArgs"; break; /* number of arguments */ + case FP_OLD_FP_INDEX: pos = "OldFP"; break; + case FP_RET_PC_INDEX: pos = "RetPC"; break; ++ case FP_PROG_INDEX: pos = "Prog"; break; + default: + if (offset < -FP_TO_ARGS_DIST && offset >= -FP_TO_ARGS_DIST - nArgs) { + sprintf(pos = buffer, STACK_DUMP_ARG_PREFIX "%d", + offset + FP_TO_ARGS_DIST + nArgs + 1); + } +diff --quilt old/source/interpret.h new/source/interpret.h +--- old/source/interpret.h ++++ new/source/interpret.h +@@ -103,10 +103,11 @@ typedef struct SymbolRec { + } Symbol; + + typedef struct ProgramTag { + Symbol *localSymList; + Inst *code; ++ unsigned refcount; + } Program; + + /* Information needed to re-start a preempted macro */ + typedef struct { + DataValue *stack; +diff --quilt old/source/macro.c new/source/macro.c +--- old/source/macro.c ++++ new/source/macro.c +@@ -894,14 +894,11 @@ static int readCheckMacroString(Widget d + subrPtr.val.prog = prog; + subrPtr.tag = NO_TAG; + sym = InstallSymbol(subrName, MACRO_FUNCTION_SYM, subrPtr); + } else { + if (sym->type == MACRO_FUNCTION_SYM) +- /* its unsafe to free the old program, +- ** maybe it is currently in use +- */ +- /* FreeProgram(sym->value.val.prog) */; ++ FreeProgram(sym->value.val.prog); + else + sym->type = MACRO_FUNCTION_SYM; + sym->value.val.prog = prog; + } + } diff --git a/relativeFileNormalization.diff b/relativeFileNormalization.diff index 0a2f8e7..3d6f376 100644 --- a/relativeFileNormalization.diff +++ b/relativeFileNormalization.diff @@ -269,7 +269,7 @@ diff --quilt old/source/macro.c new/source/macro.c result->tag = INT_TAG; result->val.n = False; return True; -@@ -5183,11 +5292,11 @@ static int neditHomeMV(WindowInfo *windo +@@ -5180,11 +5289,11 @@ static int neditHomeMV(WindowInfo *windo DataValue *result, char **errMsg) { const char *neditRCName = GetRCFileName(NEDIT_RC); diff --git a/series b/series index 4dae39f..67826f2 100644 --- a/series +++ b/series @@ -8,6 +8,7 @@ remove-argument-limit-from-action-routines.patch fix-memleak-in-readCheckMacroString.patch disable-FreeProgram.patch FreeProgram-after-RunMacroAsSubrCall.patch +refcount-for-Program.patch move-Show-Tooltips-item-into-Tabbed-Editing-menu.patch shell-in-help-output.patch parse_c-build-dependencies.patch diff --git a/setWindowTitleFormat.diff b/setWindowTitleFormat.diff index 2191c4a..cf11c18 100644 --- a/setWindowTitleFormat.diff +++ b/setWindowTitleFormat.diff @@ -76,7 +76,7 @@ diff --quilt old/source/macro.c new/source/macro.c static const BuiltInSubrName SpecialVars[] = { { "$cursor", cursorMV }, -@@ -3721,10 +3724,84 @@ static int defineMS(WindowInfo *window, +@@ -3718,10 +3721,84 @@ static int defineMS(WindowInfo *window, } return True; diff --git a/stringToNum.diff b/stringToNum.diff index 122ff76..67879ca 100644 --- a/stringToNum.diff +++ b/stringToNum.diff @@ -11,7 +11,7 @@ It seems a shame to scan a string twice, as the older version does. diff --quilt old/source/interpret.c new/source/interpret.c --- old/source/interpret.c +++ new/source/interpret.c -@@ -4281,37 +4281,56 @@ static int execError(const char *s1, con +@@ -4254,37 +4254,56 @@ static int execError(const char *s1, con sprintf(msg, s1, s2); ErrMsg = stackDumpStr(FrameP, msg, &err, &errlen); return STAT_ERROR; diff --git a/timer_macros.patch b/timer_macros.patch index 81856e6..fa95f93 100644 --- a/timer_macros.patch +++ b/timer_macros.patch @@ -55,7 +55,7 @@ diff --quilt old/source/macro.c new/source/macro.c static const BuiltInSubrName SpecialVars[] = { { "$cursor", cursorMV }, -@@ -3798,10 +3805,171 @@ static int setWindowTitleMS(WindowInfo * +@@ -3795,10 +3802,171 @@ static int setWindowTitleMS(WindowInfo * window->titleFormat = newFmt; UpdateWindowTitle(window); return True; -- 2.11.4.GIT