# Fixed bug in 'main.c'

## phimvt@lurac.latrobe.edu.au — 2000-11-24 05:35:31

    Fixed bug in    main.c

    The Joy prototype implementation had a serious bug that could cause

    a crash:

    LIBRA

        dup  ==  2 * .         (* legal attempt to re-define built-in "dup" *)

    Joy accepts this (as it is supposed to, even if it is not often

    a good idea to re-define a built-in). But now the call

        11   dup.

    produces a CRASH.

    The error occurred in the prototype as follows: The new definition

    will overwrite a pointer to the internal function dup_() by

    with a pointer to the code [2 *]. Then when the new dup is called

    it attempts to execute an internal function by that mangled

    pointer. But the mangled pointer does not point to any function,

    so the system crashes.

    To fix the problem, if in a definition a name is encountered

    that is in fact a built-in, a new symbol table node has to be

    created as if the new name had not been seen before. This

    new node creation already occurs when a name is being looked up.

    That same new node creation has to be used in definitions

    when an inbuilt is being redefined.

    The new node creation can now occur for two quite different

    reasons, so it was best to define a new function "enterglobal()".

    This new function is now called in two different places.

    1) Before function "lookup()", insert the new function "enterglobals()",

    whose body is essentially something that occurred already inside function

    "lookup()".

    2) In function "lookup()" replace those lines by a call to the

    new function "enterglobals()".

    3) In function "definition()" insert a conditional

            if (location < firstlibra)        /* if it is a builtin */

               enterglobals();                /* treat as if new */

    The VMS "DIFF-file gives the details:

    ************

    File DSK8B:[PHIMVT.JOY.C]MAIN.C-OLD;1

       25   PUBLIC void lookup()

    ******

    File DSK8B:[PHIMVT.JOY.C]MAIN.C;90

       25   PUBLIC void enterglobal()

       26   {

       27       location = symtabindex++;

       28   D(  printf("getsym, new: '%s'\n",id); )

       29       location->name = (char *) malloc(strlen(id) + 1);

       30       strcpy(location->name,id);

       31       location->u.body = NULL; /* may be assigned in definition */

       32       location->next = hashentry[hashvalue];

       33   D(  printf("entered %s at %d\n",id,LOC2INT(location)); )

       34       hashentry[hashvalue] = location;

       35   }

       36   PUBLIC void lookup()

    ************

    ************

    File DSK8B:[PHIMVT.JOY.C]MAIN.C-OLD;1

       41         { location = symtabindex++;

       42   D(	printf("getsym, new: '%s'\n",id); )

       43   	location->name = (char *) malloc(strlen(id) + 1);

       44   	strcpy(location->name,id);

       45   	location->u.body = NULL; /* may be assigned in definition */

       46   	location->next = hashentry[hashvalue];

       47   D(	printf("entered %s at %d\n",id,LOC2INT(location)); )

       48   	hashentry[hashvalue] = location; }

       49   }

    ******

    File DSK8B:[PHIMVT.JOY.C]MAIN.C;90

       52   	enterglobal();

       53   }

    ************

    ************

    File DSK8B:[PHIMVT.JOY.C]MAIN.C-OLD;1

       80       here = location; getsym();

    ******

    File DSK8B:[PHIMVT.JOY.C]MAIN.C;90

       84       if (location < firstlibra)

       85         { printf("warning: overwriting inbuilt '%s'\n",location->name);

       86   	enterglobal(); }

       87       here = location; getsym();

    ************

    Number of difference sections found: 3

    Number of difference records found: 22

    DIFFERENCES /IGNORE=()/MERGED=1/OUTPUT=DSK8B:[PHIMVT.JOY.C]MAIN.DIFFS;2-

        DSK8B:[PHIMVT.JOY.C]MAIN.C-OLD;1-

        DSK8B:[PHIMVT.JOY.C]MAIN.C;90