Nombas Homepage

Scripting

Products

Purchase

Download

Support

Company

Nombas > SE:ISDK DevSpace > Errata > Integration SDK 4.30x Errata

 

Integration SDK 4.30x Errata
Fixes Affecting Users of the ScriptEase ISDKs

  • 4.30f API - latest update: January 27, 2005
  • 4.30a API - latest update: September 19, 2000



API Errata, version 4.30g (may apply to earlier versions)
  New, August 3, 2004



API Errata, version 4.30f (may apply to earlier versions)
  New, January 27, 2005



API Errata, version 4.30e (may apply to earlier versions)
  New, March 7, 2002


API Errata, version 4.30d (may apply to earlier versions)
  New, October 6, 2001



API Errata, version 4.30c (may apply to earlier versions)
  New, April 6, 2001

API Errata, version 4.30b (may apply to earlier versions)
  New, May 4, 2001


API Errata, version 4.30a (may apply to earlier versions)
  New, September 19, 2000


The Details

for 4.30g -- (may apply to earlier versions)

  • function object's call() and apply() methods do not properly handle thrown errors
    (for ISDK/C 4.40f)

Bug: When calling a function object's call() or apply() methods, any errors thrown from within that function get handled by the default error handler for the application instead of being processed by any applicable catch blocks. For instance, the following script produces unexpected results:

   function myThrower()
   {
      throw new Error("test error");
   }

   try
   {
      myThrower.call();
   }
   catch ( e )
   {
      Clib.printf("test error was caught by try/catch block");
   }

Fix: In srclib/ecma/seobject.c, function Ecma_Function_call(), around line 428, replace the following block of code:

   jseCallFunction(jsecontext,thisVar,stack,&returnVar,thisArg);

   if( returnVar!=NULL )
      jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);

with this one:

   if ( jseCallFunctionEx(jsecontext,thisVar,stack,&returnVar,thisArg,JSE_FUNC_TRAP_ERRORS) )
   {
      if( returnVar!=NULL )
      {
         jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);
      }
   }
   else
   {
      if( returnVar!=NULL )
      {
         jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);
      }
      jseLibSetErrorFlag(jsecontext);
   }

Also around line 502 of the same file, in function Ecma_Function_apply(), replace the following block of code:

   if( jseCallFunction(jsecontext,thisVar,stack,&returnVar,thisArg) )
      jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);

with this one:

   if ( jseCallFunctionEx(jsecontext,thisVar,stack,&returnVar,thisArg,JSE_FUNC_TRAP_ERRORS) )
   {
      if( returnVar!=NULL )
      {
         jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);
      }
   }
   else
   {
      if( returnVar!=NULL )
      {
         jseReturnVar(jsecontext,returnVar,jseRetCopyToTempVar);
      }
      jseLibSetErrorFlag(jsecontext);
   }

  • string.concat() fails when strings are zero-length
    (for ISDK/C 4.40f)

Bug: If the strings in string.concat() are all zero-length, then a memory allocation failure is reported..

Fix: In srclib/ecma/seobject.c, function Ecma_String_concat(), att "+1" to this line (around line 4032):

   tempResult = HugeReMalloc(result,BYTECOUNT_FROM_STRLEN(result,length)+BYTECOUNT_FROM_STRLEN(str,strlength));

to this:

   tempResult = HugeReMalloc(result,BYTECOUNT_FROM_STRLEN(result,length)+BYTECOUNT_FROM_STRLEN(str,strlength)+1);

  • Math.random() is not very random on systems with 16-bit integers
    (for ISDK/C 4.30g)

Bug: On systems compiled with 16-bit integers, Math.random() always generates numbers very close to 0.0 or 1.0 (e.g. 0.0545345 or 0.992322), and not well-spread between 0 and 1.

Fix: In srclib/ecma/mathobj.c, function Ecma_Math_random(), change this line:

   int r[5];

to this:

   uword32 r[5];

  • memory growth and performance loss with AtErrorFunc callback
    (for ISDK/C 4.30g)

Bug: If you have supplied an AtErrorFunc callback, and script throws many errors that are caught by the AtErrorFunc callback, then the script engine memory use will increase over time and performance will suffer.

Fix: In srccore/secode.c, function secodeInterpret(), "case seReturnThrow:" add the following line just before the "jseVariable var = SEAPI_RETURN..." statement (at about line 1957):

   seAPIVar mark = call->tempvars;

and then at the end of this block, following the call to AtErrorFunc, add this line:

   CALL_KILL_TEMPVARS(call,mark);

Similarly, in srccore/util.c, function ErrorVPrintf(), add the following line just before the "jseVariable var = SEAPI_RETURN..." statement (at about line 1873):

   seAPIVar mark = call->tempvars;

and then at the end of this block, following the call to AtErrorFunc, add this line:

   CALL_KILL_TEMPVARS(call,mark);

  • memory leak with array.toSource
    (for ISDK/C 4.30g)

Bug: A memory buffer remains unreleased for each call to Array.prototype.toSource. This would happen any time ToSource is applied to an instance of an Array, or to any object containing an instance of an Array.

Fix: In srclib/ecma/seobject.c, function Ecma_Array_toSource, the following should be added as the last line of the function at about line 1846:

   jseDestroyVariable(jsecontext,ret);

  • during script compilation peephole optimizer accesses invalid memory
    (for ISDK/C 4.30g)

Problem: The peephole optimizer can access invalid memory during script compilation. In rare circumstance this may cause a crash.

Fix: In srccore/expressn.c, function secompileDelete, at about line 859 change this statement:

   memmove( sptr, sptr+size, elementMoveCount * sizeof(secodeelem) );

to

   memmove( This->opcodes+offsetTo, This->opcodes+offsetFrom,
            elementMoveCount * sizeof(secodeelem) );

A few lines further down, in the function secompilePeephole(), at about line 871 remove the "StartOpcodes" local variable and add these local variables instead:

   uint i, nxti;

and then at about line 1075 replace this block

   /* The array can move and its size can change, so need
    * to recalculate ending point each iteration.
    */
   StartOpcodes=This->opcodes;
   for( sptr = StartOpcodes; sptr < This->opcodes + This->opcodesUsed; )
   {

with this block

   /* The array can move and its size can change, so need
    * to recalculate ending point each iteration.
    */
   for( i = 0; i<This->opcodesUsed; )
   {
      sptr = This->opcodes + i;
      nxti = i+1+SECODE_DATUM_SIZE(*sptr);

and later in the same function, at about line 943, is an secompileDelete statement followed by a reference to SE_GLOBAL_NOTDIRECTXLAT. Insert a line between those two statement so it now reads:

   secompileDelete(This,sptr,&targetted,-change);
   sptr = This->opcodes + i;
   if ( SE_GLOBAL_NOTDIRECTXLAT <= c )

and finally, in this same function (at about line 1098) replace this line

   sptr = nxt;

with this line

   i = nxti;

  • Alignment errors with Clib *printf and *scanf floating-point on HP-UX
    (for ISDK/C 4.30g)

Bug: If a call to the Clib *printf or *scanf methods (e.g. Clib.sprintf) contains non-floating-point data types following a floating-point type, data alignment may be incorrect and invalid data or crashes will result. This problem appears only on HPUX systems.

Fix: Replace srclib/clib/sefmtio.c with the file at ftp://ftp.nombas.com/pub/isdkeval/se430/sefmtio.c

  • when converting numbers to strings, rounding will not occur in some locales
    (for ISDK/C 4.30g)

Bug: In locales that use a comma to separate fractional parts of floating-point numbers (e.g. 3,145). JSE_NUMTOSTRING_ROUNDING will not round.

Fix: In srcmisc/utilstr.c, function EcmaNumberToString(), at around line 801, this statement:

   if ( NULL == (decimal=strchr_jsechar((jsecharptr)buffer,'.')) )

should become:

   if ( NULL == (decimal=strchr_jsechar((jsecharptr)buffer,'.'))
     && NULL == (decimal=strchr_jsechar((jsecharptr)buffer,',')) )

  • Stack corruption on %s error messages
    (for ISDK/C 4.30g)

Bug: If an error messages is generated with a format string containing the "%s" formatting type, and if the string that %s refers to is very long, then an assert will be generated (in debug mode), or a stack-overwrite will likely cause a crash (in release mode). For example, this script would cause such a crash:

   var bigstr = "func";
   for (var i = 0; i < 5000; i++ )
      bigstr += "x";
   bigstr += "()";
   eval(bigstr);

This can also be a problem if you are using %s in any of your jseLibErrorPrintf() calls but are not limiting the length of string arguments.

Fix: Edit the files srccore/textcore.h and srclib/common/setxtlib.h and change all occurences of "%s" in those files to be "%.30s". If you are using a build that relies on our implementation of jse_vsprintf in srcmisc/utilstr.c (if your system does not supply a native implementation of vsprintf) then contact http://support.nombas.com/ for a replacement function.

  • SElib.dynamicLink() expects string lengths to remain constant
    (for ISDK/C 4.30g)

Bug: If a DLL (or shared object or code fragment) receives a string datum from SElib.dynamicLink() and changes the data in that string so that its length is shorter than the original string, we will assume the length has not changed and store data beyond the end of the string into the passed parameter. In Unicode and ASCII builds this will just leave the string length incorrect. In MBCS builds this could potentially cause a failure if the data beyond the null character is invalid MBCS sequences.

Fix: In srclib/common/sedyna.c, function CallDynamicFunction(), at about line 248 change the statement from:

   jsePutStringLength(jsecontext,v,(jsecharptr )data,BufferLengths[i]);

to:

   jsePutString(jsecontext,v,(jsecharptr )data);

  • bad error message, or crash, when "goto" statement is not followed by a label
    (for ISDK/C 4.30g)

Bug: If a goto is compiled, but is not followed by a proper label, then the error message will be invalid, may display garbage, and may crash.

Fix: In srccore/statemnt.c, function secompileStatement(), in the "case seTokGoto:" change line 993 from:

   callQuit(call,textcoreGOTO_LABEL_NOT_FOUND);

to:

   callQuit(call,textcoreNOT_LOOP_LABEL);

  • "goto" is not standard EcmaScript
    (for ISDK/C 4.30g)

Issue: ScriptEase implements the "goto" statement, but most other EcmaScript implementations do not recognize the keyword.

Fix: To disable the "goto" keyword, change this line at about line 263 of srccore/codeprt2.c from:

   { textcoreGotoKeyword, seTokGoto },

to:

   #if !defined(JSE_DISABLE_GOTO)
   { textcoreGotoKeyword, seTokGoto },
   #endif

Then, if you want to disable the "goto" keyword, compile with JSE_DISABLE_GOTO defined.

  • COMOBJ leaks resources
    (for ISDK/C 4.30g)

Bug: COMOBJ can leaks resources when working with type libraries and pass-by-ref COM objects. Over time total memory use will grow.

Fix: Replace srclib/comobj/* code with files found at ftp://ftp.nombas.com/pub/isdkeval/se430/comobj_2003_03_20.zip


for 4.30f -- (may apply to earlier versions)

  • string.replace() crashes when only one argument is passed in
    (for ISDK/C 4.30f)

Bug: When a script calls String.replace() with only argument, the engine may crash due to uninitialized memory.

Fix: In srclib/ecma/seobject.c, within the funciton string_replace_helper(), replace this line:

   jseVariable replacement = argv[1];

with this line:

   jseVariable replacement = ( argc == 2 ) ? argv[1] : NULL;

  • comobj times miscalculate DST
    (for ISDK/C 4.30f)

Bug: In converting times between a script and a COM object, the daylight-savings time calculation may be off by one hour.

Fix: In srclib/comobj/comobj.cpp, function COMObj_put() and in function oleGenericDispatcher() replace this line (at about line 873 and 1061, respectively)

   UnixTimeToSystemTime((time_t)system_time, &st);

with this block:

   time_t tmp = (time_t)system_time;
   struct tm * localUnixTime = localtime(&tmp);

   st.wYear = (localUnixTime->tm_year + 1900);
   st.wMonth = localUnixTime->tm_mon+1;
   st.wDayOfWeek = localUnixTime->tm_wday;
   st.wDay = localUnixTime->tm_mday;
   st.wHour = localUnixTime->tm_hour;
   st.wMinute = localUnixTime->tm_min;
   st.wSecond = localUnixTime->tm_sec;

then in function CreateReturnedVariant() replace this line (at about line 635):

   time_t t = SystemTimeToUnixTime(&st);

with this block:

   time_t t;
   struct tm gm;

   /* Construct a tm structure based on the SYSTEMTIME structure */
   gm.tm_year = (st.wYear - 1900);
   gm.tm_mon = st.wMonth-1;
   gm.tm_wday = st.wDayOfWeek;
   gm.tm_mday = st.wDay;
   gm.tm_hour = st.wHour;
   gm.tm_min = st.wMinute;
   gm.tm_sec = st.wSecond;
   gm.tm_isdst = -1;

   /* Get the time_t */
   t = mktime(&gm);

  • stack corruption with long mode parameter to Clib.fopen() and Clib.freopen()
    (for ISDK/C 4.30f)

Bug: If the mode parameter to Clib.fopen() or Clib.freopen() parameter is longer than 18 characters, a stack buffer overflow will occur.

Fix: In srclib/sestdio.c, functions Clib_fopen() and Clib.freopen() change this line (at about line 634 and 705)

   strcpy_jsechar((jsecharptr)NewMode,Mode);

to this

   memset(NewMode,0,sizeof(NewMode));
   strncpy_jsechar((jsecharptr)NewMode,Mode,sizeof(NewMode)/sizeof(NewMode[0])-2);

  • array sort return invalid when array.length==1
    (for ISDK/C 4.30f)

Bug: If array.length==1, then array.sort() will return undefined.

Fix: In srclib/ecma/seobject.c, function Ecma_Array_sort(), the code (near line 1144) for "<=1" elements should be changed to:

   if( num_items <= 1 )
   {
      jseReturnVar(jsecontext,thisvar,jseRetCopyToTempVar);
      return;
   }

  • Number toPrecision() incorrect
    (for ISDK/C 5.00e) Updated Dec 11, 2002

Bug: Number.prototype.toPrecision(precision) is converting precision digits beyond the decimal, when it should be converting precision-1 digits.

Fix: In srclib/ecma/seobject.c, function Ecma_Number_toSomething(), at about line 2287 the entire toPrecision block should be replaced with this code:

   else
   {
      jsenumber abs_x = JSE_FP_FABS(x);
      assert( _toPrecision == toWhat );
      /* field width must be an int */
      /* if x>=pow(10,-6) && x<pow(10,f), use fixed-point notation
       * otherwise, use exponential notation */
      if( JSE_FP_LTE(JSE_FP_POW(JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(-6)),abs_x) &&
          JSE_FP_LT(abs_x, JSE_FP_POW(JSE_FP_CAST_FROM_SLONG(10),JSE_FP_CAST_FROM_SLONG(f))) )
      {
         jsenumber f10 = JSE_FP_LOG10(abs_x);
         sint d10 = (sint)JSE_FP_CAST_TO_SLONG(f10);
         f -= d10;
         if ( !jseIsNegative(f10) )
            f--;
         JSE_FP_DTOSTR(x,(int)f,buffer,UNISTR("f"));
      }
      else
      {
         JSE_FP_DTOSTR(x,(int)f-1,buffer,UNISTR("e"));
      }
   }

  • jsePutString() may overwrite previous results if JSE_C_EXTENSIONS is disabled
    (for ISDK/C 4.30f)

Bug: If compiling with JSE_C_EXTENSIONS 0, then when jsePutString() or similar calls are used to assign to a variable (especially via dynamic callbacsk as in the RegExp global object), existing string data may be overwritten.

Fix: In srccore/jselib.c, function GenericPutDataPtr(), at about line 1790 this block of code:

         if( SEVAR_GET_TYPE(val)==VString && (SEVAR_GET_STRING(val).data->constant
   #     if JSE_C_EXTENSIONS==1
                                           ||  !callLocalCBehavior(call)
   #     endif
                                           ) )

should be replaced with this code

      if( SEVAR_GET_TYPE(val)==VString
   #   if JSE_C_EXTENSIONS==1
       && (SEVAR_GET_STRING(val).data->constant || !callLocalCBehavior(call))
   #   endif
        )

  • string.replace crashes or consumes all memory when replacing with null string
    (for ISDK/C 4.30f)

Bug: When using string.replace() to delete a character from a string, by replacing it with "", the call may crash or use too much memory.

Fix: In srclib/ecma/seobject.c, function add_string(), add this statement as the first line of the function (at about line 4128):

   if ( !add_len ) return;

  • invalid_regexp_instance.toString() crash
    (for ISDK/C 4.30f)

Bug: Calling the RegExp toString operator on an object that is not a valid RegExp instance will crash. E.G. RegExp.prototype.toString()

Fix: In srclib/ecma/seregexp.c, function RegExp_toString, at about line 139 change this code:

   orig = jseGetString(jsecontext,tmp,&len);

to this

   len = 0;
   orig = tmp ? jseGetString(jsecontext,tmp,&len) : UNISTR("");

for 4.30f -- (may apply to earlier versions)

  • sedbc bugs with long binary data
    (for ISDK/C 4.30f)

Problem: SEDBC can crash when reading from or writing to database columns representing any of the large binary data types.

Fix: In srclib/sedbc/jse_rfx.c, function jseFieldExchange_LongString(), case rf_value, at about line 2742 is a call to SQLBindParameter passing the 8th paramater as "&value". That parameter should be "value". (I.E. value instead of the address of value.)

  • string.split() incorrect if regular expression used as separator
    (for ISDK/C 4.30f)

Bug: String.prototype.split(separator) returns the wrong results when separator is a regular expression and does not match the first character of the string.

Fix: In srclib/ecma/seobject.c, function Ecma_String_split(), at about line 3633 (just after the second call to SplitMatch) this of code:

   /* step 14 */
   JSE_POINTER_UINDEX e = 0;
   jseVariable tmp2,tmp = jseGetIndexMember(jsecontext,z,0);
   if( tmp )

should be changed to:

   /* step 14 */
   JSE_POINTER_UINDEX e;
   jseVariable tmp2,tmp;
   if ( R && 0!=jseGetIntegerDatum(jsecontext,z,index_MEMBER) )
   {
      jseDestroyVariable(jsecontext,z);
      q++;
      continue;
   }
   e = 0;
   tmp = jseGetIndexMember(jsecontext,z,0);
   if( tmp )

  • useCache field of Call structure may not be initialized
    (for ISDK/C 4.30f)

Problem: The call->useCache field is not initialized for new levels of interpret. This has not been shown to cause any run-time errors, yet.

Fix: In srccore/call.c, function ecode.c, function callInterpret(), just after the call structure has been allocated (at about line 1039), initialize the useChache field with this statement

   call->useCache = False;

  • func.prototype undefined if #define JSE_AUTO_OBJECT 0
    (for ISDK/C 4.30f)

Problem: If compiling with the JSE_AUTO_OBJECT options off (i.e. #define JSE_AUTO_OBJECT 0) a script such as this one:

   function foo() {} foo.prototype.bar = 0; 

will generate this error

   ConversionError 1616: Undefined and Null types cannot be converted to an object.

Fix: In srccore/secode.c, function do_op_member, replace this line at about line 236:

   #     if !defined(JSE_AUTO_OBJECT) || JSE_AUTO_OBJECT!=0
         if( to_object )
{ if( SEVAR_GET_TYPE(tmp)==VUndefined ) { /* transform it into an object */ SEVAR_INIT_BLANK_OBJECT(call,tmp); sevarPutValueEx(call,obj,mem,tmp,False); } } # endif

with this code

   if( to_object  &&  SEVAR_GET_TYPE(tmp)==VUndefined )
   {
      # if defined(JSE_AUTO_OBJECT) && JSE_AUTO_OBJECT==0
      /* we have saved space by not putting a .protoype on all functions,
       * but they should have one if needed, so create it if it's accessed.
       */
      if ( mem==GLOBAL_STRING(call,orig_prototype_entry) && NULL!=SEVAR_GET_OBJECT(obj)->func )
      # endif
      {
         /* transform it into an object */
         SEVAR_INIT_BLANK_OBJECT(call,tmp);
         sevarPutValueEx(call,obj,mem,tmp,False);
      }
   }

  • parseInt() treating characters ":;<=>?@" as digits 3 through 9
    (for ISDK/C 4.30f)

Problem: When evaluating a string, parseInt() is treating the characters from ":" to "@" (\x3A to \x40) as the digits 3 through 9.

Fix: In srclib/ecma/ecmamisc.c, function Ecma_parseInt, replace this line at about line 160:

   val = toupper_jsechar(JSECHARPTR_GETC(str))-'A'+10;

with this:

   if ( (val = toupper_jsechar(JSECHARPTR_GETC(str))-'A'+10) < 10 ) break;

  • Documentation incorrect about lifetime of jseGetInternalString()
    (for ISDK/C 4.30f)

Problem: The documentation for the function jseGetInternalString(), states:

   The returned pointer is valid as long as
   the jseString it is obtained from is valid.

Fix: That statement is not correct, and should instead be:

   The text represented by many sestring values
   is internally stored in a compact format, and
   so the string returned by this call may be
   stored in a temporary location; the returned
   pointer is guaranteed to be valid only until
   the next call into the script-engine API.

  • string slice() function is not accepting zero parameters
    (for ISDK/C 4.30f)

Problem: String.prototype.slice() will report an error if it is passed no parameters. Instead, it should treat calls to string.slice() as string.slice(0).

Fix: In srclib/ecma/seobject.c, at about line 4946, change this line:

   JSE_PROTOMETH( UNISTR("slice"), Ecma_String_slice, 1, 2, jseDontEnum, jseFunc_Secure ),

to this

   JSE_PROTOMETH( UNISTR("slice"), Ecma_String_slice, 0, 2, jseDontEnum, jseFunc_Secure ),

and in function Ecma_String_slice() at about line 4005 change this line:

   start = jseGetLong(jsecontext,jseStart);

to this

   start = jseFuncVarCount(jsecontext) ? jseGetLong(jsecontext,jseStart) : 0;

and change the line at about 4052 from

   JSE_FUNC_VAR_NEED(jseStart,jsecontext,0,JSE_VN_CONVERT(JSE_VN_ANY,JSE_VN_NUMBER));

to

   if ( 0 != jseFuncVarCount(jsecontext) )
      JSE_FUNC_VAR_NEED(jseStart,jsecontext,0,JSE_VN_CONVERT(JSE_VN_ANY,JSE_VN_NUMBER));

  • setting array length to 0 does not remove all indexed properties
    (for ISDK/C 4.30f)

Bug: Setting the length property of an Array instance to zero does not remove the properties, although it does set the length to 0.

Fix: In srccore/var.c, function sevarSetArrayLength(), at about line 303 change the initialization of maxi to be:

   jsenumber maxi = JSE_FP_SUB(JSE_FP_CAST_FROM_ULONG(Length),jseOne);


for 4.30e -- (may apply to earlier versions)

  • String replace may skip matches if replacement string is null-string (i.e. "")
    (for ISDK/C 4.30e)

Bug: If the replacement expression in a string replace() method is the zero-length string, then characters may be skipped in performing the replacement. For example, this script would fail the test:

   var str = '6 abcdef';
   var rtn = str.replace(/[^0-9\.]/g,'');
   Test.assert( rtn == "6" );  // in error would be "6acf"

Fix: In srclib/ecma/seobject.c, function string_search_helper(), replace the block of code beginning with "/* The return from exec should be an object" with the code found at ftp://ftp.nombas.com/pub/isdkeval/se430/string_search_helper.txt

  • rare crashes on memory overwrites using the dynamicBuffer routines
    (for ISDK/C 4.30e)

Bug: Code may overwrite one byte beyond allocated memory when using the dynamicbuffer functions.

Fix: In srclib/common/selibutl.c, function dynamicBufferAppend(), at about line 133 change this line:

   if( buf->used + length > buf->allocated )

to this:

   if( buf->used + length >= buf->allocated )

and at about line 137 change this line:

   } while( buf->used + length > buf->allocated );

to this:

   } while( buf->used + length >= buf->allocated );

and in function function dynamicBufferAppendLength(), at about line 151 change this line:

   if( buf->used + length > buf->allocated )

to this:

   if( buf->used + length >= buf->allocated )

and at about line 155 change this line:

   } while( buf->used + length > buf->allocated );

to this:

   } while( buf->used + length >= buf->allocated );

  • Problems with array lengths and numeric indices that are large or non-integer
    (for ISDK/C 4.30e)

Bug: There are many problems with handling array and object members that are either very large (e.g. obj[2147483650]) or are non-integer numbers (e.g. obj[3.14159], obj[1e34]). There are also related problems with setting an array length to a very large number (e.g. array.length=2147483650).

Fix: The number of changes needed to fix these problems in such a way that they would work on all build types (fp, fpemul, nofp) without a loss of performance was very large. Because the number of changes was so large we recommend that you update to version 4.30f. However, if you must apply these changes to 4.30e, follow the instructions at ftp://ftp.nombas.com/pub/isdkeval/se430/numidx.txt

  • Foo.prototype.constructor not assigned correctly for all builtin objects
    (for ISDK/C 4.30e)

Bug: For all builtin objects, this statement should be true: Foo.prototype.constructor==Foo. For example Boolean.prototype.constructor==Boolean and Number.prototype.constructor==Number.

Fix: In srclib/ecma/*.c locate all of the lines like this (where instead of "Foo" find "Function", "Object", "Array", "Boolean", "Number", "String", "Buffer", and "Date"):

   JSE_PROTOMETH( CONSTRUCTOR_PROPERTY, Ecma_Array_builtin, 0, 0, jseDontEnum,
                  jseFunc_Secure ), 

and replace those lines with the following:

   JSE_VARASSIGN( UNISTR("prototype._constructor"), ARRAY_PROPERTY, jseDontEnum ),

Finally, the RegExp object is missing this relationship, and so add a statement like the above to the wrapper list in srclib/ecma/seregexp.c.

  • Array split() error for negative starting point
    (for ISDK/C 4.30e)

Bug: Array split() is not handling negative start values correctly. This error shows up in different ways with different compilers, but the following example would fail on all systems:

   var a = [1,2,3,4,5,6];
   var b = a.splice(-100,1);
   Test.assert( a == "2,3,4,5,6" );  // wrongly returns "1,2,3,4,5"
   Test.assert( b == "1" );          // wrongly returns ""

Fix: In src/lib/ecma/seobject.c, function Ecma_Array_splice(), at about line 1633 change the code from:

   start = (slong) max( length + start, 0 );

to

   start = (slong) max( (slong)length + start, 0 );

  • Math.min(+0,-0) wrongly returns +0
    (for ISDK/C 4.30e)

Bug: Math.min() is not returning -0 when comparing -0 against +0.

Fix: In src/lib/ecma/mathobj.c, function Ecma_Math_min(), at about line 380 change the comparison from:

   if( JSE_FP_LT(current,minval) )

to

   if( JSE_FP_LT(current,minval) || ( jseIsNegZero(current) && jseIsZero(minval) ) )

  • Clib.localtime() and Clib.gmtime() crash on out-of-range dates
    (for ISDK/C 4.30e)

Bug: Script calls to Clib.localtime() or Clib.gmtime() crash if the input time is out of the range of standard C library time routines.

Fix: In srclib/clib/setime.c, function GenericTimeLib(), at about line 324 just after any of the ConversionFunc functions will have been called, insert this code:

   if ( t == NULL )
   {
      jseReturnVar(jsecontext,jseCreateVariable(jsecontext,jseTypeNull),jseRetTempVar);
      return;
   }

  • Number toString(with_radix) method is not handling NaN, Infinity, and -Infinity
    (for ISDK/C 4.30e)

Bug: Converting an instance of a Number object toString, using a radix (e.g. (new Number(foo)).toString(16);) does not produce correct results if the number is NaN, Infinity, or -Infinity.

Fix: In src/lib/ecma/seobject.c, function Ecma_Number_toString(), at about line 2254 cahnge the JSE_NUMBER_TO_STRINGWITHRADIX code to be this:

   if ( 0 < jseFuncVarCount(jsecontext) )
   {
      slong radix = JSE_FP_CAST_TO_SLONG(jseGetIntegerDatum(jsecontext,jseFuncVar(jsecontext,0),NULL));
      if ( radix==10  ||  !jseIsFinite(num) )
         EcmaNumberToStringWithRadix(jsebuffer,num);
      else
         EcmaNumberToStringWithRadix(num,(sint)radix,buffer);
   }

  • Invalid date computation on negative month
    (for ISDK/C 4.30e)

Bug: Date calculations are incorrect, and can trigger debugger asserts, if month is negative. For example, the following script should set the month to October (month 9) and year to 1980, but instead it sets the month to January (month 0) and year to 1981.

   var foo = new Date("12:00 February 4, 1982");
   foo.setUTCMonth(-15);

Fix: In src/lib/ecma/sedate.c, function MakeDay(), insert code between lines 640 and 642 add code so those lines become:

   r6 = m%12;
   if ( r6 < 0 )
   {
      r6 += 12;
      r5--;
   }
   t = TimeFromYear(r5);

  • Math.round() returns -0 instead of +0 from -0.5 to -0
    (for ISDK/C 4.30e)

Bug: Math.round(val) should return -0 for -0.5 <= val <= -0, according to section 15.8.2.15 of the ECMAScript specification, but is returning +0.

Fix: In srclib/ecma/mathobj.c, function Ecma_Math_round, the "if" statement and block should be changed to:

   if ( jseIsFinite(val) && !jseIsZero(val) )
   {
      jsenumber half = JSE_FP_DIV(jseOne,JSE_FP_CAST_FROM_SLONG(2));
      /* exception to standard math if between -0.5 and -0, inclusive */
      if ( JSE_FP_LT(val,jseZero)  &&  JSE_FP_LTE(JSE_FP_NEGATE(half),val) )
         val = jseNegZero;
      else
         val = JSE_FP_FLOOR(JSE_FP_ADD(val,half));
   }

  • Crash if reporting invalid data type while generating an error message
    (for ISDK/C 4.30e)

Bug: If a method is called during error handling, and that method has a data type or conversion error, then the program will crash. For example, in the following example "msg" is the wrong data type and while rerporing this error the program will crash:

   function TypeError(msg)
   {
      Error.apply(this, msg);
      return this;
   }
   TypeError(null);

Fix: In srccore/call.c, function callGetVarNeed(), after the call to callError() (at about line 1652), add this statement:

   CALL_SET_ERROR(call,FlowError);

  • Array .length should not be deletable
    (for ISDK/C 4.30e)

Bug: The .length property of any instance of an array should have the DontEnum attribute.

Fix: In srclib/ecma/seobject.c, function CreateNewObject(), at about line 3023 change

   jseSetAttributes(jsecontext,t2,jseDontEnum);

to

   jseSetAttributes(jsecontext,t2,jseDontEnum||jseDontDelete);

  • properties of the arguments object should be DontEnum
    (for ISDK/C 4.30e)

Bug: callee, length, and numbered members of the arguments object are enumerable, should be DontEnum.

Fix: In srccore/call.c, function callCreateArguments(), there are 3 calls assigning 'mem = SEOBJ_CREATE_MEMBER(...)' In all 3 cases, add the following line right after:

   mem->attributes = jseDontEnum;

  • use of undefined global variables do not always report error
    (for ISDK/C 4.30e)

Bug: When a variable that has not been declared or initialized is used to pass to a function, or is automatically assumed to be a function, e.g.:

   new String(blah);         // undeclared variable "blah" passed to a funcion
   var zoo = "" + blah.foo;  // undeclared variables treated as an object

no error message is generated.

Fix: In srccore/secode.c, function secodeInterpret(), within the case for sePushGlobal, sePushGlobalAsObject, and sePushGlobalParam, at about line 1309 is this large block of code:

   if( t==sePushGlobal )
   {
      callQuit(call,textcoreVAR_TYPE_UNKNOWN,GetStringTableEntry(call,mem,NULL));
      break;
   }
   else
   {
      jsebool do_it = FALSE;
      ...etc...
      STACK_POP;
   }

replace that entire block with these two lines:

   if( jseOptReqVarKeyword & call->Global->ExternalLinkParms.options )
      callQuit(call,textcoreFUNC_OR_VAR_NOT_DECLARED,mem);
   else
      callQuit(call,textcoreVAR_TYPE_UNKNOWN,GetStringTableEntry(call,mem,NULL));
   break;

This change will cause error reports if you are using the non-ECMA compile-time option JSE_AUTO_OBJECT and are relying on scripts such as those above to automatically create object variables. One consequence of this is that the non-Ecma function defined() will cease to functions as expected in pre-processor statements such as

   #if defined(Clib.puts) 

This should only be a problem if you use the JSE_CONDITIONAL_COMPILE option. In future releases SE:ISDK will move processing of defined() into the pre-processor for JSE_CONDITIONAL_COMPILE builds. If you need this pre-processor code ask Nombas Tech Support, or change defined() to use typeof(). For example, the above statement would become

   #if typeof(Clib)!="undefined" && typeof(Clib.puts)!="undefined"

  • arguments object not updating function arguments
    (for ISDK/C 4.30e)

Bug: If changes are made to a member of the arguments object, those changes are not being reflected in the argument itself. I.E., this example will not update parm_y after arguments[1] has been changed:

   function foo(parm_x,parm_y,parm_z)
   {
      arguments[1] = "new value";  // parm_y is not changed
   }

Fix: In srccore/var.c, function sevarPutValueEx((), at about line 780, insert within this block of code:

   IF_OPERATOR_NOT_OVERLOADED(call,tmpvar,val,seAssignLocal)
   {
      SEVAR_COPY(&(smem->value),val);
   }

this additional code:

   IF_OPERATOR_NOT_OVERLOADED(call,tmpvar,val,seAssignLocal)
   {
      /****** begin additional code ******/
      if( SEVAR_GET_TYPE(&(smem->value))==VReference )
      {
         mem = smem->value.data.ref_val.reference;
         SEVAR_INIT_OBJECT(obj,smem->value.data.ref_val.base);
         goto top;
      }
      else if( SEVAR_GET_TYPE(&(smem->value))==VReferenceIndex )
      {
         mem = smem->value.data.ref_val.reference;
         is_index = True;
         SEVAR_INIT_OBJECT(obj,smem->value.data.ref_val.base);
         goto top;
      }
      /****** end additional code ******/
      SEVAR_COPY(&(smem->value),val);
   }

  • invalid assert for operator overloading on unary operators
    (for ISDK/C 4.30e)

Bug: If overloading unary operators with jseSetObjectCallbacks, and NDEBUG is not defined, and invalid assert will be triggered.

Fix: In srccore/varutil.c, function seobjCallDynamicProperty(), at about line 2534, replace this block of code:

      if( off_flag==OFF_PUT_PROP
   #   if defined(JSE_OPERATOR_OVERLOADING) && (0!=JSE_OPERATOR_OVERLOADING)
       || off_flag==OFF_OPERATOR_PROP
   #   endif
       || off_flag==OFF_DEFAULTVALUE_PROP )
      {
         assert( Parameter2!=NULL );
      }

with this block:

      if( off_flag==OFF_PUT_PROP
       || off_flag==OFF_DEFAULTVALUE_PROP )
      {
         assert( Parameter2!=NULL );
      }
   #  if defined(JSE_OPERATOR_OVERLOADING) && (0!=JSE_OPERATOR_OVERLOADING)
      else if ( off_flag==OFF_OPERATOR_PROP )
      {
         /* Parameter2 may or may not be NULL for overloading (because it may be
          * two operators, or a unary operator. No test.
          */
      }
   #  endif

  • 'new' operator accepting non-Object return values
    (for ISDK/C 4.30e)

Bug: If a constructor returns a variable that is not an object then that return value is not being ignored, although it should be. For example, in the following example foo should be set to a new Object and not 834.

   function foomaker()
   {
      return 834;
   }
   var foo = new foomaker();

Fix: In srccore/call.c, function callReturnFromFunction(), at about line 771 replace this line:

   if( SEVAR_GET_TYPE(tmp)==VUndefined )

with this block:

   if ( SEVAR_GET_TYPE(tmp)!=VObject  &&  SEVAR_GET_TYPE(OLD_RETURN)==VObject )

  • jseCallFunction return variable may be NULL with JSE_FUNC_TRAP_ERRORS
    (for ISDK/C 4.30e)

Bug: In jseCallFunction() and jseCallFunctionEx(), if the JSE_FUNC_TRAP_ERROS flag is used and returnVar is not NULL then *returnVar is supposed to be assign to some non-NULL value. But in some cases (usually if a parameter is not a valid function) this will return with a non-NULL *returnVar

Fix: In srccore/jselib.c, function jseCallFunctionEx(), at about line 2612 replace this block:

   #  if ( 0 < JSE_API_ASSERTLEVEL )
   if ( NULL == func )
   {
      STACK_POPX(2);
      SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
      END_TIMING(call);
      return False;
   }
   #  endif

with this block:

   if (  NULL == func )
   {
      STACK_POPX(2);
   #  if ( 0 < JSE_API_ASSERTLEVEL )
         SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
   #  endif
      END_TIMING(call);
      goto illegal_params;
   }

then at about line 2577 replace this block:

   # if JSE_NAMED_PARAMS==1
   if( SEVAR_GET_TYPE(var)!=VObject )
   {
      SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
      END_TIMING(call);
      return False;
   }
   #endif

with this:

   if( SEVAR_GET_TYPE(var)!=VObject )
   {
   #  if ( 0 < JSE_API_ASSERTLEVEL )
         SetLastApiError( UNISTR("%s: parameter 2 not a function"),ThisFuncName );
   #  endif
      END_TIMING(call);
      goto illegal_params;
   }

Next, replace the remaining three instances of "return False" to instead be "goto illegal_params".

Finally, at this block of code at the end of the function, after "return retbool";

 illegal_params:
   *retvar = NULL;
   {
      jseVariable func = jseGetMember(call,NULL,UNISTR("Error"));

      if( func )
      {
         jseStack stack;
         jseVariable param;

         stack = jseCreateStack(call);
         /* pass 1 parameter, the string */
         param = jseCreateVariable(call,jseTypeString);
         jsePutString(call,param,UNISTR("API parameters are invalid"));
         jsePush(call,stack,param,TRUE);

         if( !jseCallFunction(call,func,stack,retvar,NULL) )
         {
            if( *retvar!=NULL )
            {
               jseDestroyVariable(call,*retvar);
               *retvar = NULL;
            }
         }
         jseDestroyStack(call,stack);
      }
   }

   if( *retvar==NULL )
   {
      *retvar = jseCreateVariable(call,jseTypeString);
      jsePutString(call,*retvar,UNISTR("API parameters are invalid"));
   }
   return FALSE;

  • insufficient checks on bad dates
    (for ISDK/C 4.30e)

Bug: Some of the functions in the Date object are not testing against invalid dates. The results may be incorrrect, assertioins may be triggered, or floating-point exceptions may be triggered.

Fix: In srclib/ecma/sedate.c, a few locations need jseIsFinite() tests against the internal date representation. In function SetYearMonDay(), add a test after the call to jseGetNumber() at about line 1967 so it reads:

   t = jseGetNumber(jsecontext,
                    jseMember(jsecontext,thisvar,DATE_VALUE_PROPERTY,jseTypeNumber));
   if ( !jseIsFinite(t) )
      return;

and in SetHourMinSecMilli() add a test after jseGetNumber() at about line 1823 so it reads:

   t = jseGetNumber(jsecontext,
                    jseMember(jsecontext,thisvar,DATE_VALUE_PROPERTY,jseTypeNumber));
   if ( !jseIsFinite(t) )
      return;

and in Ecma_Date_toSystem() add a test after jseGetNumberDatum() at about line 1275 so it reads

   units = jseGetNumberDatum(jsecontext,thisvar,DATE_VALUE_PROPERTY);
   if ( !jseIsFinite(units) )
      return NULL;

  • compound assignment (/=, *=, %=, +=, -=, <<=, &=, ^=, |=) ignoring with() blocks
    (for ISDK/C 4.30e)

Bug: The object for a with(object) block is ignored when evaluating the initial variable while evaluating a compound assignment.

Fix: In srccore/expressn.c, function secompileGetValueKeep(), at about line 2333, this statement

   if( this->with_depth )

should instead be this:

   if( !this->with_depth )

  • invalid name accessing local parameters in a with() block
    (for ISDK/C 4.30e)

Bug: When accessing a variable in a with block, the wrong variable name is used when testing a variable against the with object if the variables is an argument to the function (and not the first argument). In some cases this will lead to accessing the wrong name. If this with object has a get or hasproperty callback this may cause a program crash. The following example demonstrates where this may fail:

   function foo(argument1,argument2,argument3)
   {
      var local1, local2, local3;
      with ( someObject )
      {
         local1 = local2;      // OK
         local1 = local3;      // OK
         local1 = argument1;   // OK
         local1 = argument2;   // FAIL
         local1 = argument3;   // FAIL
      }
   }

Fix: In srccore/secode.c, function callWithCatchEntry(), at about line 365, change this line:

   [ (index<=0) ? index : ((struct LocalFunction *)FUNCPTR)->InputParameterCount+index-1];

to this

   [ (index<=0) ? -index : ((struct LocalFunction *)FUNCPTR)->InputParameterCount+index-1];

Note that just a single "-" was added.

  • MSVC6 memory allocation bugs
    (for ISDK/C 4.30e)

Bug: Problems with Microsoft's C++ in Microsoft Visual C++ 6.0, can cause heap allocation errors and memory overwrites that can cause crashes that are extremely erratic and hard to reproduce.

Fix: If you are using MSVC6, download and install the Visual Studio 6.0 Service Pack 5 from http://msdn.microsoft.com/vstudio/sp/vs6sp5/

  • aboutopt.jse doesn't work
    (for ISDK/C 4.30e)

Bug: tools/aboutopt.jse isn't working with any of the samples. When a finer grain was added to what functions could be added/removed, we did not update aboutopt. Also, it wasn't clear how to execute the abotopt.jse scripts.

Fix: Updated files for aboutopt.jse may be downloaded from ftp://ftp.nombas.com/pub/isdkeval/se430/aboutopt.zip. This aboutopt.jse can be execute frim the compiled SIMPLE1 sample, with a statement such as:

   W32Simp1.exe tools\aboutopt.jse seisdk\samples\simple1\jseopt.h __JSE_WIN32__ _MSC_VER JSE_ASCII

  • terminating execution from within a "try" block will cause memory leaks
    (for ISDK/C 4.30e)

Bug: If execution is terminated while a script is within a try block, such as if the jseMayIContinue callback function returns False or by calling jseLibSetExitFlag(), then some allocated memory will not be freed and the system may crash.

Fix: In srccore/call.c, function callDelete(), add this to the local variables at the beginning of the function:

   struct TryBlock *loop;

and add this block to the end of the function, just before the jseMustFree(call) statement at about line 1252:

   for( loop = call->tries;loop!=NULL; )
   {
      struct TryBlock *prev = loop->prev;
   
      jseMustFree(loop);
      loop = prev;
   }

and in srccore/secode.c, function secodeInterpret(), 19 lines beyond the "handle_finally:" label, replace these lines (at about line 626):

   if( CALL_QUIT(call) )
      call->stackptr = call->tries->sptr;

with these:

   if( call->state==FlowError )
      call->stackptr = call->tries->sptr;

  • seObjHasProperty causing floating-point overflow if not handled by callback
    (for ISDK/C 4.30e)

Bug: On some systems, if an object has a hasProp callback that returns -1, or if the dynamic object does not have a hasProp, then a floating-point overflow exception can occur.

Fix: In srccore/varutil.c, function seobjHasProperty(), at line 2985change this line:

   ret = (jsebool)JSE_FP_CAST_TO_SLONG(SEVAR_GET_NUMBER_VALUE(value));

to this:

   if ( handled )
      ret = (jsebool)JSE_FP_CAST_TO_SLONG(SEVAR_GET_NUMBER_VALUE(value));

  • "+Infinity and "-Infinity" converted to NaN if JSE_FLOATING_POINT==0
    (for ISDK/C 4.30e)

Bug: If building in integer-only mode (i.e. #define JSE_FLOATING_POINT 0), "+Infinity" and "-Infinity" will be read incorrectly and converted to NaN.

Fix: In srccore/util.c, function convertStringToNumber(), there are two places with this block of code (line 2003 and 2010):

   #           if (0!=JSE_FLOATING_POINT)
                  lenParsed++;
   #           endif

in both cases the conditionals should be removed, so the above blocks are replaced with the single line:

               lenParsed++;

  • stack variable overwrite when jseMayIContinueFunc returns False
    (for ISDK/C 4.30e)

Bug: When your jseMayIContinueFunc() callback returns False, a variable within the virtual-machine stack may be wrongly assigned as undefined. This could lead to a variable being freed prematurely.

Fix: In srccore/jselib.c.c, function jseInterpret(), at about line 662, replace these lines:

               seVar tmp = STACK_PUSH;

               SEVAR_INIT_UNDEFINED(tmp);

with this

   #           define call newc
               seVar tmp = STACK_PUSH;
               SEVAR_INIT_UNDEFINED(tmp);
   #           undef call

 

  • memory leak, and possible crash, using the #link statement
    (for ISDK/C 4.30e)

Bug: Memory leaks and possible crashes using the #link statement. The memory leak fix is for Unix only, but the possible crash in running out of memory applies to all systems.

Fix: In srccore/extlib.c, function extensionFindLibPath(), at about line 499, replace this line:

   if( !Success )

with this

 if( !Success && FileName!=NULL )

and extensionLibraryStartup(), at about line 597 replace this block

   #if defined(__JSE_UNIX__)
      {
         jsechar buffer[256];
         jse_sprintf(buffer,"lib%s",LibraryName);
         FullLibraryPath = extensionFindLibPath(this,buffer,call);
      }
      assert( sizeof_jsechar('\0') == sizeof(jsecharptrdatum) );
      if( FullLibraryPath==NULL || *((jsecharptrdatum*)FullLibraryPath)=='\0' )
   #endif
         FullLibraryPath = extensionFindLibPath(this,LibraryName, call);

with this block

   #if defined(__JSE_UNIX__)
      {
         jsechar buffer[256];
         jse_sprintf(buffer,"lib%s",LibraryName);
         FullLibraryPath = extensionFindLibPath(this,buffer,call);
      }
      assert( sizeof_jsechar('\0') == sizeof(jsecharptrdatum) );
      if( FullLibraryPath==NULL || *((jsecharptrdatum*)FullLibraryPath)=='\0' )
      {
         if( FullLibraryPath!=NULL ) jseMustFree(FullLibraryPath);
         FullLibraryPath = extensionFindLibPath(this,LibraryName, call);
      }
   #else
      FullLibraryPath = extensionFindLibPath(this,LibraryName, call);
   #endif

and then at about line 611, replace this block

   callError(call,textcoreLINK_LIBRARY_NOT_EXISTS,LibraryName);
   jseMustFree(FullLibraryPath);
   return False;

with this

     callError(call,textcoreLINK_LIBRARY_NOT_EXISTS,LibraryName);
   if( FullLibraryPath ) jseMustFree(FullLibraryPath);
   return False;

 


for 4.30d -- (may apply to earlier versions)

  • ToNumber() returns incorrect values for "+" and "-"
    (for ISDK/C 4.30d)

    Bug: When ToNumber() is called with either "+" or "-" as its argument, the return value should be NaN. Instead, ToNumber() is returning Infinity and -Infinity, respectively.

    Fix: In srccore/util.c, function convertStringToNumber(), at about line 1947, change this code:

       if ( lenParsed == lenStr )
       {
          val = neg ? jseNegInfinity : jseInfinity ;
       }

    to this

       if ( lenParsed == lenStr && 2<lenStr )

  • Object comparisons with wrong hint - Date comparisons fail
    (for ISDK/C 4.30d)

    Bug: Object comparison (<, <=, >, >=) are not correctly following the hint logic specified in section 11.8.5 (The Abstract Relational Comparison Algorithm) of the ECMAScript specification. When objects are converted to a primitive value for comparison they should be give "hint Number". This would only show up as a problem for any object that does not have number as its default primitive; the Date object is such an example, and so the following test fails for the date object because it is comparing as a string (the default Date primitive type) instead of as a Nuimber (the hint type for comparison).

  •    newer = new Date("Thu Oct 4 15:54:25 2001");
       older = new Date("Tue Sep 25 15:54:25 2001");
       Test.assert( older < newer ); // fails because comparing as string

    Fix: In srccore/varutil.c, function sevarECMACompareLess(), change the first two instances of this code (at lines 760 and 769):

       sevarConvert(call,tmp,jseToPrimitive);

    to this

       sevarConvertToPrimitive(call,tmp,VNumber);

  • function.arguments deprecated
    (for ISDK/C 4.30d)

    Warning: The arguments property of a Function object is an old leftover from erly javascript, and has been deprecated in current EcmaScript standards. For most applications function.arguments is a drawback because it may lock in varaibles longer than is wanted and may slow overall execution. Unles you are writing a web browser that must support very old javascript, we recommend disabling function.arguments (note, the arguments object remains valid).

Fix: In srccore/secode.h, add the following lines where other compile-time options are being defined (around line 100):

   #if !defined(JSE_FUNCTION_ARGUMENTS)
      /* by default, function.arguments is off.  It's archaic and requires way too
       * many links to constantly be created.
       */
   #  define JSE_FUNCTION_ARGUMENTS 0
   #endif

In srccore/var.c, function seobjGetMemberStruct(), at about line 918 enclose the very first block in a conditional like this:

   #  if JSE_FUNCTION_ARGUMENTS==1
      /* If this is 'arguments', recreate appropriate arguments object
       * for this item. callCreateVariableObject will recreate it for
       * this function if need be. This makes sure the latest 'arguments'
       * are here while deferring building until needed.
       */
      if( Name==call->Global->global_strings[arguments_entry] &&
          SEOBJ_GET_FUNCTION(this)!=NULL )
      {
         callCreateVariableObject(call,SEOBJ_GET_FUNCTION(this),0);
      }
   #  endif 

And in srccore/call.c, function callCreateVariableObject(), at about line 982, wrap two statements within a conditional like this:

   #        if JSE_FUNCTION_ARGUMENTS==1
            {
               seObjectMem tmp2;
               tmp2 = seobjNewMember(call,SEVAR_GET_OBJECT(FUNCVAR),
                                     GLOBAL_STRING(call,arguments_entry),&found);
               SEVAR_INIT_OBJECT(&(tmp2->value),SEVAR_GET_OBJECT(&(tmp->value)));
            }
   #        endif 

and remove the original declaration for tmp2 from the top of that function.

function.arguments is now disabled. To enable it, recompile with #define JSE_FUNCTION_ARGUMENTS 1

  • toString on functions concatenates some identifiers
    (for ISDK/C 4.30d)

    Bug: When a function is being converted to a string, a required space may not be displayed after some variables. For example, this code:

  • function blah()
    {
       for (var prop in obj);
    }
    display("" + blah);

may produce this output (note that "prop" and "in" have become concatenated):

function blah()
{
   for (var propin obj);
}

Fix: In srccore/function.c, function functionTextAsVariable(), at about line 283, change the seTokIdentifier to add a space after each identifier, as in:

else if( type==seTokIdentifier )
{
   growingAddTo(&buff,GetStringTableEntry(call,tokGetName(c),NULL));
   growingAddTo(&buff,UNISTR(" "));
}

  • rare GC problem on dynamic objects
    (for ISDK/C 4.30d)

    Problem: In very rare circumstances, a garbage-collection may occur during manipulation of a dynamic object callback that could invalidate an internal stack variable. This has never been found to happen in the field, but new internal debugging code has detected the possibility.

    Fix: In srccore/secode.c, function secodeInterpret(), within "case sePreIncLocal:", at about line 758 are these statements:

    c_lhs = STACK_PUSH;
    c_rhs = STACK_PUSH;

    which should be followed by these statements:

    SEVAR_INIT_UNDEFINED(c_lhs);
    SEVAR_INIT_UNDEFINED(c_rhs);
    

    and in srccore/jselib.c, function jseCallFunctionEx(), at about line 2534, this statement:

    onstack = STACK_PUSH;

    should be followed by this statement:

    SEVAR_INIT_UNDEFINED(onstack);
               

  • get callback may crash during seobjHasProperty()
    (for ISDK/C 4.30d)

    Bug: dynamic get callback crash when called during seobjHasProperty() to determine if the propery exists.

    Fix: In srccore/varutil.c, function seobjHasProperty(), locate this block of code, at about line 2978, beginnning with this text

{
   /* either no dynamic _hasProperty (!handled) or
    * _hasProperty says 'yes it has the property' and

and replace the block with this code:

{
   /* either no dynamic _hasProperty (!handled) or
    * _hasProperty says 'yes it has the property' and
    * dest is not NULL, so we need to retrieve the property
    * In either case, we have to do a dynamic get because we
    * need the value
    */
   seVar rhs = STACK_PUSH;

   SEVAR_INIT_OBJECT(rhs,obj);

   if( dest==NULL ) dest = rhs;

   if( seobjCallDynamicProperty(call,obj,OFF_GET_PROP,propname,False,dest) )
   {
      /* If hasProperty says yes, then undefined means undefined. Otherwise,
       * Undefined is the only way to differentiate a has it from does not
       * have it.
       */
      jsebool ret = (SEVAR_GET_TYPE(dest)!=VUndefined) || handled;
      if( ret && ref )
      {
         SEVAR_INIT_REFERENCE(dest,obj,propname);
      }
      STACK_POP;
      return ret;
   }
   if ( dest==rhs ) dest = NULL;
   STACK_POP;
   /* fallthru because not valid */
}

also note in related incident that in this same function

    if( dest!=NULL ) assert( sevarIsValid(call,dest) );

was changed to

    assert( dest==NULL || sevarIsValid(call,dest) );

  • C++ compilation errors for seuni.h
    (for ISDK/C 4.30d)

Problem: SEUNI.H causes compilation errors for some C++ compilers.

Fix: Lines in srcmisc/seuni.h have been re-ordered so the __cplusplus statements surround only the statements and not other include files. This updated seuni.h may be downloaded from ftp://ftp.nombas.com/pub/isdkeval/se430/seuni.h.

  • altering "arguments" causes assertion failure
    (for ISDK/C 4.30d)

Problem: Using "var" or assigning to the "arguments" variable will cause an assertion failure in !NDEBUG versions.

Fix: In srccore/call.c, function callCreateVariableObject(), at about line 977, replace this code:

tmp = SEOBJ_CREATE_MEMBER(call,tmpobj,GLOBAL_STRING(call,arguments_entry));

with this code:

tmp = seobjNewMember(call,tmpobj,GLOBAL_STRING(call,arguments_entry),&found);
if ( found ) return;

  • jseCallStackInfo() can crash using Variable object
    (for ISDK/C 4.30d)

Problem: using jseCallStackInfo() to access a Variable object of a script function in the stack can crash.

Fix: In srccore/call.h, find callCreateVariableObject() (about line 979) and add a final 'depth' parameter, as in:

callCreateVariableObject(struct Call *call,struct Function *func,uint depth);

also in srccore/call.c, find callCreateVariableObject() function (near line 827), and add the final 'depth' parameter, as in:

   void NEAR_CALL
callCreateVariableObject(struct Call *call,struct Function *lookfunc,uint depth)

find this code in callCreateVariableObject() (near line 848)

/* Find the enclosing local function */
while( !FUNCTION_IS_LOCAL(func_orig) || (lookfunc!=NULL && lookfunc!=func_orig) )

and replace with this code

/* Find the enclosing local function */
while( !FUNCTION_IS_LOCAL(func_orig) || (lookfunc!=NULL && lookfunc!=func_orig) || depth-->0 )

In srccore/jselib.c, function jseCallStackInfo(), at about line 2904, after this line

TIMING(call,se);

add this line

callCreateVariableObject(call,NULL,depth);

All other calls to callCreateVariableObject() should receive 0 (zero) as the last parameter.

  • eval() does not propogate the "this" of its caller
    (for ISDK/C 4.30d)

Problem: eval() does not propogate the 'this' of its caller.


Fix: In srclib/ecma/ecmamisc.c, the Ecma_eval() wrapper function at about line 58, change
the reference to JSE_INTERPRET_KEEPTHIS in the jseInterpret
call to JSE_INTERPRET_PARENTTHIS.


In incjse/jselib.h, add the following definition. Put it near the
existing JSE_INTERPRET_XXX definitions, near line 1546:

#define JSE_INTERPRET_PARENTTHIS 0x100
/* Use the 'this' variable from the calling function */

In srccore/interprt.c, interpretInit() near line 306, there is a call to RunCompiledCode() that looks like this:

RunCompiledCode(InterpretCall,argc,argv,CallMain,
                (HowToInterpret & JSE_INTERPRET_KEEPTHIS)?
                   SEVAR_GET_OBJECT(CALL_THIS):
                   CALL_GLOBAL(InterpretCall),HowToInterpret);

change this to:

{
   seObject this_obj = NULL;

   if( (HowToInterpret&JSE_INTERPRET_KEEPTHIS)!=0
    && FRAME!=NULL )
   {
      this_obj = SEVAR_GET_OBJECT(CALL_THIS);
   }
   if( this_obj==NULL
    && (HowToInterpret&JSE_INTERPRET_PARENTTHIS)!=0 )
   {
      if( FRAME!=NULL )
      {
         STACKPTR old_frame;
         uword16 old_num_args;

         old_num_args = (uword16)SEVAR_GET_STORAGE_LONG(OLD_ARGS);
         old_frame = SEVAR_GET_STORAGE_PTR(OLD_FRAME);

         if( old_frame )
         {
            this_obj = SEVAR_GET_OBJECT(old_frame-(THIS_OFFSET+old_num_args));
         }
      }
   }
   if( this_obj==NULL )
   {
      this_obj = CALL_GLOBAL(InterpretCall);
   }
   RunCompiledCode(InterpretCall,argc,argv,CallMain,
                   this_obj,HowToInterpret);
   }

  • jseGarbageCollect() can call recursively, corrupting data
    (for ISDK/C 4.30d)

Problem: jseGarbageCollect(...,JSE_GARBAGE_COLLECT), if called within an action of the garbage collector itself, can tigger recursive GC that will corrupt data.

Fix: In srccore/util.c, function jseGarbageCollect(), at about line 332, replace the code for "case JSE_GARBAGE_COLLECT" with this code:

case JSE_GARBAGE_COLLECT:
   garbageCollect(jsecontext);
   break;

  • Errors during jseCallFunction set "trapped=True" in jseAtErrorFunc()
    (for ISDK/C 4.30d)

Problem: Errors in code executed via jseCallFunction() always have 'trapped = TRUE' in the jseAtErrorFunc callback.

Fix: In srccore\call.h, add to the end of the 'struct Global_' definition (near line 627):

STACKPTR call_func_mark;

In srccore\call.c:~1493, in the function 'callErrorTrapped', change this line:

if( !tries->incatch && tries->catch!=(ADDR_TYPE)-1 )

to:

if( !tries->incatch && tries->catch!=(ADDR_TYPE)-1
 && ( call->Global->call_func_mark==NULL
   || tries->fptr>call->Global->call_func_mark ) )

In srccore\jselib.c function jseCallFunctionEx() line 2562, get rid of this line:

call->mustPrintError = False;

and replace it with:

call_func_mark_save = call->Global->call_func_mark;
call->Global->call_func_mark = FRAME;
if( flags&JSE_FUNC_TRAP_ERRORS )
   call->mustPrintError = FALSE;

then right after the 'callFunctionFully()' (the next line in the file), add:

call->Global->call_func_mark = call_func_mark_save;

at the top of that same function, add the local variable:

STACKPTR call_func_mark_save;

In srccore/util.c:~1836, function callPrintError(), find this line:

seVar loc = STACK_PUSH;

Remove the initialization (i.e. alter this line) to make:

seVar loc;

and add:

loc = STACK_PUSH;

after this line:

if( call->errorPrinted ) return;

  • static Array initializer is not instanceof Object
    (for ISDK/C 4.30d)

Bug: When an Array object is initialized with a static Array Initialiser, as in this code:

var foo = [ 1, 2, 3 ];

is is recognized as "instanceof Array" but is not recognized as "instanceof Object".

Fix: In srccore/secode.c, function secodeInterpret(), "case seInstanceof:", at about line 2057 is this comment:

/* at any rate, this is the last chance. */

to fix this bug, insert the following code ahead of that comment, so it reads:

/* finally, all objects inherit from Object */
else if ( call->PrototypeCache.Object
       == functionPrototype->data.object_val.obj )
   result = True;

/* at any rate, this is the last chance. */ 

  • empty Object initializer creates an Array object; should be an Object object
    (for ISDK/C 4.30d)

Bug: When an object is initialized with the empty set, as in this code:

var foo = { };

it is initialized as a type Array object, although it should be an Object object.

Fix: In srccore/expressn.c, function secompileObject(), at about line 1529, change this line:

if( tokType(&tok)!=':' )

to this

if( tokType(&tok)!=':' && tokType(this->token)!='}' )

  • infinite loop if accessing dynamic callback object reports an error
    (for ISDK/C 4.30d)

Bug: A dynamic member is passed to a function. If the dynamic object is implemented via callbacks, and the dynamic member access results in an error (i.e. the callback uses jseLibErrorPrintf), an infinite loop and crash results.

Fix: In srccore/varutil.c, the function seobjCallDynamicProperty() locate these lines at about line 2648:

CALL_KILL_TEMPVARS(call,mark);


if( done || CALL_QUIT(call) ) return True;

Right between them add the following code:

if( CALL_QUIT(call) && result!=NULL )
{
   SEVAR_INIT_UNDEFINED(result);
}

  • "continue" within "switch" statement jumps to wrong condition
    (for ISDK/C 4.30d)

Bug: The "continue" statement, when within a "switch" block, will associate its condition with the "switch" statement instead of the enclosing loop.

Fix: In srccore/secode.h, at about line 666, add this to the "loopTracker" structure:

jsebool is_switch;

and at line 776 change the prototype to:

secompileNewLoop(struct secompile *handle,struct gotoItem *label,jsebool is_switch);

Then in srccore/statement.c, all calls to secompileNewLoop() get a third False parameter, except for the one in secompileSwitch() which adds True as its third parameter (at about line 444).

Then in srccore/expressn.c, at about line 574, change the secompileNewLoop code to this:

   void NEAR_CALL
secompileNewLoop(struct secompile *this,struct gotoItem *label,jsebool is_switch)
{
   struct loopTracker *t = looptrackerNew();
   t->next = this->loopTrack;
   this->loopTrack = t;
   t->is_switch = is_switch;

   if( label!=NULL ) label->loop = t;
}

and at about line 621 change secompileAddContinue() to this:

   jsebool NEAR_CALL
secompileAddContinue(struct secompile *this,struct loopTracker *it)
{
   if( it==NULL )
   {
      it = this->loopTrack;
      while( it!=NULL && (it->is_switch) )
         it = it->next;
   }

   /* add a continue (goto), but mark it so it can be back-filled later
    * when we figure out where break goes to!
    */
   if( it==NULL )
   {
      callQuit(this->call,textcoreBAD_BREAK);
      return False;
   }
   looptrackerAddContinue(it,secompileCurrentItem(this));
   secompileAddItem(this,seTransfer,(ADDR_TYPE)0);
   return True;
}

and, finally, in srccore/statemnt.c, function secompileStatement(), within the "case seTokContinue", at about line 943, change this code:

it = this->gotoTrack->labels[x].loop;
if( it==NULL )
{

to this

it = this->gotoTrack->labels[x].loop;
if( it==NULL || (it->is_switch && !isbreak) )
{

  • "var foo" keyword in jseInterpret() or eval() makes "foo" undefined
    (for ISDK/C 4.30d)

Error: The "var" statement in jseInterp() or eval() calls is always resetting the variable to undefined even when it already exists in scope.

Fix: In srrccore/varutil.c near the beginning of function seobjHasProperty(), at about line 2918, change this line

assert( sevarIsValid(call,dest) );

to this line

// old version: if( dest!=NULL ) assert( sevarIsValid(call,dest) );
assert( dest==NULL || sevarIsValid(call,dest) );

and in srccore/call.c in function callFunction(), at line 564, change this block

else
{
   SEVAR_INIT_UNDEFINED(tmp);
}
SEVAR_DO_PUT(call,loc,tmp);
/* no need to set the attributes directly, the variable object

to this block

else
{
   SEVAR_INIT_UNDEFINED(tmp);
}
assert( SEVAR_GET_TYPE(loc)==VReference );
if( SEVAR_GET_TYPE(tmp)!=VUndefined ||
    !seobjHasProperty(call,
           loc->data.ref_val.base,
           loc->data.ref_val.reference,
           NULL,
           FALSE) )
{
   SEVAR_DO_PUT(call,loc,tmp);
} 
/* no need to set the attributes directly, the variable object

  • api jseString table growing without bounds - slowing callbacks
    (for ISDK/C 4.30d)

Bug: The api jseString table (which holds strings visible to callbacks) may be growing without bounds, causing overall system performance (especially of callbacks) to degrade over time.

Fix: In srccore/util.c, at about line 312, replace the callRemoveApiStringEntry() function with the one found at ftp://ftp.nombas.com/pub/isdkeval/se430/callremoveapistringentry.c

  • "var" within jseInterpret() or eval() may not use local variables
    (for ISDK/C 4.30d)

Bug: Caching of global variables may prevent the "var" keyword when used within jseInterpret (or as often found in eval(), which uses jseInterpret()) may prevent the variable from being recognized as a local variable. For example, in this script:

var foo = "global";

funky();
function funky()
{
   var what = foo + "variable";
   eval("var foo = \"local\"";);
   what = foo + "variable";
}

the value for variable "what" may be "globalvariable", showing that global varible caching has prevented "foo" from being recognized as a local variable after the call to eval().

Fix: In srccore/call.c, in function CreateVariableObject(), at about line 886, change this code:

/* check if already built */
if( old_fptr )
{
   if( SEVAR_GET_STORAGE_PTR(old_fptr-VAROBJ_OFFSET)!=NULL ) return;
}
else
{
   if( call->VariableObject!=NULL ) return;
}

to this:

/* check if already built */
if( old_fptr )
{
   SEVAR_INIT_BOOLEAN(old_fptr-USE_CACHE_OFFSET,FALSE);
   if( SEVAR_GET_STORAGE_PTR(old_fptr-VAROBJ_OFFSET)!=NULL ) return;
}
else
{
   call->useCache = FALSE;
   if( call->VariableObject!=NULL ) return;
}

  • JSE_HTML_COMMENT_STYLE too strict with end comments
    (for ISDK/C 4.30d)

Problem: HTML browsers frequenly hide code from non-Ecmascript-aware old browsers by hiding linkes within the "<!--" and "//-->" tags. When compiling the ScriptEase:ISDK with "#define JSE_HTML_COMMENT_STYLE 1" the engine will recognize the "<!--" as the begin comment. But it turns out that many pages are being written with "-->" as the end comment, instead of "//-->" as the rules state; these pages generate a parsing error with SE:ISDK.

Fix: In srccore/call.h, within the definition of "struct CompileStatus_", add this code at about line 353:

#if defined(JSE_HTML_COMMENT_STYLE) && (JSE_HTML_COMMENT_STYLE==1)
   sint paren_group_depth; /* track depth within ((())) */
#endif

In srccore/code.c, function tokGetNext(), line 351 begins a block of "case" statements begging with this:

 case UNICHR('%'): case UNICHR('&'): case UNICHR('^'):

remove the two statements (line 359) for the characters '(' and ')' and move them to the top of the case block, so that case blocks begins at line 351 with this code:

case UNICHR('('): case UNICHR(')'):
   #if defined(JSE_HTML_COMMENT_STYLE) && (JSE_HTML_COMMENT_STYLE==1)
      call->Global->CompileStatus.paren_group_depth += ( theChar == UNICHR('(') ) ? 1 : -1 ;
   # endif

In the same function, at line 286, replace this code:

case UNICHR('-'): Type = seTokDecrement; break;

with:

case UNICHR('-'):
   #if defined(JSE_HTML_COMMENT_STYLE) && (JSE_HTML_COMMENT_STYLE==1)
      /* comments in HTML are supposed to look like "// -->" but sometimes
       * the code-writers forget that, and so HTML parsers commonly recognize
       * this error (because there's no valid "-->" outside of () scoping.
       */
      if ( '>' == JSECHARPTR_GETC(JSECHARPTR_NEXT(call->Global->CompileStatus.srcptr))
        && 0 == call->Global->CompileStatus.paren_group_depth            )
      {
         goto EndOfSourceLine;
      }
   #endif
   Type = seTokDecrement; break;

Finally, in srccore/code.c, function CompileFromText(), at line and agin in the same function, at about line 87 (just after ...NowCompiling++) add this:

#if defined(JSE_HTML_COMMENT_STYLE) && (JSE_HTML_COMMENT_STYLE==1)
   call->Global->CompileStatus.paren_group_depth = 0;
endif

  • jseVariable not freed when string.replace() fails
    (for ISDK/C 4.30d)

Problem: If there is an error parsing a regular-expression entry of String.prototype.replace(), then a variable may remain unfreed. An example of a script causing this error is this:

var s = "foo?"; s.replace( "?", "bar" );

Fix: In srclib/ecma/seobject.c, function string_search_helper(), there are two places where the function can return without freeing the "String" variable. At about line 4368, replace this code:

jseDestroyStack(jsecontext,stack);
return NULL;

with this:

jseDestroyStack(jsecontext,stack);
jseDestroyVariable(jsecontext,string);
return NULL;

and at about line 4399 replace this code:

if( jseQuitFlagged(jsecontext) ) return NULL; 

with this:

if( jseQuitFlagged(jsecontext) )
{
   jseDestroyVariable(jsecontext,string);
   return NULL;
}

  • continue statement in do/while skips while
    (for ISDK/C 4.30d)

Problem: continue used in a do/while loop not doing the while condition test, always going to top of loop

Fix: In srccore/statemnt.c function secompileDo(), at the top of the function (about line 124) add this new local variable:

ADDR_TYPE cont_addr; 

In the middle of the function, right before this existing line (line 148):

secompileAddItem(this,seContinueFunc,this->prevLineNumber);

add:

cont_addr = secompileCurrentItem(this); 

finally, at the bottom of the function, change this line (line 166):

secompileEndLoop(this,secompileCurrentItem(this),top_of_loop,label);

to:

secompileEndLoop(this,secompileCurrentItem(this),cont_addr,label);          

  • jseCreateVariable parameters not pass-by-reference
    (for ISDK/C 4.30d)

Problem: When passing non-reference variables (i.e. ones created with jseCreateVariable as opposed to gotten via jseMember/et al) to a function by reference using jseCallFunction, the variables are not updated.

Fix: In srccore/jselib.c, at about line 2434, replace the entire jseCallFunctionEx/jseReallyCallFunctionEx routine with the one found at ftp://ftp.nombas.com/pub/isdkeval/se430/jsecallfunction.c

  • C++ compilation errors for JSE_FLOATING_POINT==0
    (for ISDK/C 4.30d)

Problem: When compiling C++ files that defined JSE_FLOATING_POINT 0 there may be compile-time errors such as "missing end of file" or "missplaced }".

Fix: In incjse/sefp.h at about line 57 change the order of a few statements so that:

#  ifdef __cplusplus
      extern "C" {
#  endif
#  if (0!=JSE_FLOATING_POINT)

is instead

#  if (0!=JSE_FLOATING_POINT)
#  ifdef __cplusplus
      extern "C" {
#  endif

 


for 4.30c -- (may apply to earlier versions)

  • Unicode characters byte-swapped with pre-compiled source
    (for ISDK/C 4.30c)

Bug: With some compilers and options, unicode character can be byte-swapped while reading in from buffers created with jseCreateCodeTokenBuffer().

Fix: In srccore/token.c, function tokenReadString() at line 460 replace this code:

c = (jsechar) (tokenReadByte(this) | (tokenReadByte(this) << 8));

with

c = (jsechar) tokenReadByte(this);
c |= (jsechar) (tokenReadByte(this) << 8 );

  • multiple interprets multiply add filenames, use memory
    (for ISDK/C 4.30c)

Problem: If JSE_GETFILENAMELIST is not disabled, then each time a file is interpreted it will add names to the global list of files. These names are never removed from the list until jseTerminateExternalLink() is called. The result is that if a long-running promise repeatedly interprets then it will continue to use a little extra memory each time, and that memory is not freed until jseTerminateExternalLink().

Fix: These problem will not be fixed until the 4.40 release, and so if you are running many many interprets and this is a problem rebuild with "#define JSE_GETFILENAMELIST 0" Built in the way the only API functions missing will be jseGetFileNameList().

  • compilation of large scripts slow on some systems
    (for ISDK/C 4.30c)

Problem: On systems with inefficient memory allocators compilation of large scripts, and saving compiled scripts with jseCreateCodeTokenBuffer(), can be extremely slow.

Fix: In srccore/expressn.c, function secompileAddItem() at line 216, replace this line:

This->opcodesAlloced += 100; 

with this:

This->opcodesAlloced *= 2;

and replace the structures and functions in srccore/token.h and srccore/token.c with those found at ftp://ftp.nombas.com/pub/isdkeval/se430/token.txt

  • Buffer Object incorrectly detected
    (for ISDK/C 4.30c)

Bug: Library functions attempting to determine if a variable
is a Buffer Object will get incorrect False returns.

Fix: In srclib/common/sedyna.c, function isBufferObject() change line 41 from:

temp = jseGetMember(jsecontext,var,UNISTR("class"));

to:

temp = jseGetMember(jsecontext,var, CLASS_PROPERTY);

  • 16-bit Borland Compiler crashes
    (for ISDK/C 4.30c)

Problem: Many operations can crash on 16-bit builds created with the Borland compiler, due to invalid shortcuts when comparing segmented memory pointers.

Fix: This is fixed in the 4.30d release.

  • potential crash during eval() and other jseInterpret
    (for ISDK/C 4.30c)

Bug: Using jseInterpret can cause a crash if garbage collection hits at the wrong time. eval() uses this call underneath, so it will happen most often in eval().

Fix: in srccore/call.c, the function callInterpret(), line 1059, delete these two lines:

call->ScopeChain = NULL; /* for if we collect trying to allocate one */
call->ScopeChain = seobjNewUnordered(call);

Next, in the same function, at the top of the function, line 997 locate:

call = jseMustMalloc(struct Call,sizeof(struct Call));
#  if ( 2 <= JSE_API_ASSERTLEVEL )
   call->cookie = (uword8) jseContext_cookie;
#  endif

right after these lines, add:

call->ScopeChain = seobjNewUnordered(this);

  • jseObjectCallbacks destructors called twice
    (for ISDK/C 4.30c)

Bug: destructors declared using the object callbacks (rather than by the "_delete" member) can be called twice.

Fix: srccore/garbage.c, function destructors(), after this code at line 815

todestroy->flags &= ~HAS_DELETE_PROP;

add this:

#if JSE_DYNAMIC_OBJS!=0
   todestroy->callbacks = NULL;
#endif

  • Compilation error message not terminated when end-quote missing
    (for ISDK/C 4.30c)

Bug: If a long literal string is missing its end-quote then the error message generated will not be null-terminated.

Fix: In srccore/codeprt2.c, function CompileStringToken, insert a memcpy line between these two lines at 189

jsechar ErrorBuf[80];
strncpy_jsechar((jsecharptr)ErrorBuf,src,(sizeof(ErrorBuf)/sizeof(jsechar))-1);

resulting in

jsechar ErrorBuf[80];
memset(ErrorBuf,0,sizeof(ErrorBuf));
strncpy_jsechar((jsecharptr)ErrorBuf,src,(sizeof(ErrorBuf)/sizeof(jsechar))-1);

so the buffer will always be null-terminated.

  • Cannot compile headers from C++
    (for ISDK/C 4.30c)

Error: C++ compilers fail on some header files.

Fix: in srcapp/sesecure.h and srclib/selib/selib.h add these lines to the end of the file:

#ifdef __cplusplus
   extern "C" {
#endif 

  • jseStrings invalid if more than 100 are used
    (for ISDK/C 4.30c)

Bug: using too many API jseStrings at once breaks (over 100).

Fix: There were many changes in call.h, util.c, garbage.c, and jselib.c to fix this. Those changes will be released with 4.30d. A workaround for this is to increase the value in srccore/util.c function callApiStringEntry() at line 259 from 100 to the maximum number of strings your system will use.

  • MBCS errors on little-endian processors
    (for ISDK/C 4.30c)

Problem: assert failure when printing an error in a context that has already had an error printed. This can happen when atexit/destructors are called, and there is a consistent problem in them such as not enough stack space.

Fix: In srccore/util.c, function callPrintError() at line 1781 change

call->state = 0;

/* Just convert the error to a string and print it */

if( call->errorPrinted ) return;

to

/* Just convert the error to a string and print it */

if( call->errorPrinted ) return;

call->state = 0;

  • MBCS errors on little-endian processors
    (for ISDK/C 4.30c)

Bug: Some of the built-in macros and function do not handle MBCS characters correctly on little-endian processors.

Fix: In srcmisc/seuni.h at line 345 replace this:

size_t sizeof_jsechar(jsechar c);

with

#define sizeof_jsechar(jsechar c) ( ((uint)c < 256) ? 1 : 2 )

and in srcmisc/utilstr.c t line 218 remove the sizeof_jsechar() function, and at line 283 replace the JSECHARPTR_PUTC() function with this:

void JSECHARPTR_PUTC(jsecharptr str, jsechar c)
{
   assert( (uword32)c < 0x10000 );
   if ( 255 < (uint)c )
   {
      *((unsigned char *)str)++ = c >> 8;
   }
   *(unsigned char *)str = c & 0xFF;
}

  • JSE_ONE_STRING_TABLE not supported
    (for ISDK/C 4.30c)

Problem: Compile-time option JSE_ONE_STRING_TABLE is not supported in the 4.30c release with multiple jsecontext's.

Fix: Disabling JSE_ONE_STRING_TABLE will work fine if your contexts are not sharing VarName's. If you must use JSE_ONE_STRING_TABLE then in srccore/util.c, function callCleanupGlobal() the block beginning with

for( i = 0; i < hashSize; i++ )

at about line 904 should be within the same JSE_ONE_STRING_TABLE ifdefs as the lines preceding and following that block. Furthermore, this same block of code should be added to the freeGlobalStringTable() function.

  • jseInterpret finds old globals before new globals
    (for ISDK/C 4.30c)

Error: When using jseInterpret and seeing old variables, old globals appear before new globals rather than after them.

Fix: In srccore/call.c:374, remove this block:

if( CALL_GLOBAL(call->prev)!=CALL_GLOBAL(call) )
{
   seObjectMem mem = SEOBJ_CREATE_MEMBER(call,call->ScopeChain,NULL);
   SEVAR_INIT_OBJECT(&(mem->value),CALL_GLOBAL(call));
}

in srccore/call.c:441, remove this block:

#                 if JSE_CACHE_GLOBAL_VARS==1
                     /* actually copied something before the global in the
                      * scope chain, so cannot use cache.
                      */
                     call->useCache = False;
#                 endif

then right after that last block there are 4 closing '}'s:

               }
            }
         }
      }
Change that to:
               }
            }
         }

         if( call->ScopeChain->used!=0 &&
             CALL_GLOBAL(call)!=CALL_GLOBAL(call->prev))
         {
            /* we can see old scope chain entries, should not take
             * precedence over the new global object, so add that
             * to the scope chain now.
             */
            seObjectMem mem = SEOBJ_CREATE_MEMBER(call,call->ScopeChain,NULL);
            SEVAR_INIT_OBJECT(&(mem->value),CALL_GLOBAL(call));
         }
      } 

  • stack-space test misses local variables
    (for ISDK/C 4.30c)

Bug: local variable stack space not properly accounted for when determining if a function will run out of stack space.

Fix: In srccore/call.c, function callFunction(), at about line 255 change this code:

if ( isinit )
{
   /* locals go in global object for init function, not on stack */

to this:

if ( !isinit )
{
   /* locals go in global object for init function, not on stack */

  • Compilation error for incomplete regular expressions
    (for ISDK/C 4.30c)

Bug: Compilation error if unfinished regular expression (e.g. "/a") appears at the end of a file or text.

Fix: in CODEPRT2.C, function CompileRegExpLiteral() change the two instances (lines 65 and 76) of

if( c=='\r' || c=='\n' )

to be

if( c=='\r' || c=='\n' || c=='\0' )

  • current token being referenced on failure
    (for ISDK/C 4.30c)

Problem: If there is an error during the compilation of a function, SECOMPILE_CURRENT_TOKEN() is still called even though the tokens used for that function may be 0.

Fix: in srccore/expressn.c, function secompileFunctionBody() at the beginning (line 1311) change this line:

jsebool success = False;

to be

jsebool success = init_func;

and in the same function around line 1471 put this line

*next_token = *SECOMPILE_CURRENT_TOKEN(&This);

within "if(success)" so it becomes

if ( success ) *next_token = *SECOMPILE_CURRENT_TOKEN(&This);

  • Debugger crashes for some error messages
    (for ISDK/C 4.30c)

Problem: The debugger would crash on most errors messages thrown in a script using the "throw" keyword.

Fix: The problem was due to some string handling of the error message in sedbgw32\jsedbug.cpp that didn't check the return of some string parsing functions, due to an assumption regarding the format of the error text. This would result in a null pointer exception at runtime. Proper checking of those function returns has been inserted, and new builds (4.30d) of the debugger will include this fix.

  • MBCS errors with MSVC6 built-in functions
    (for ISDK/C 4.30c)

Bug: On MSVC6 builds, using the default Microsoft MBCS macros and library translations, there are errors with getting and putting two-byte characters.

Fix: In srcmisc\seuni.h, make the macro for sizeof_jsechar() at about line 345, be this:

#define sizeof_jsechar(c) ( ((uint)(c) < 256) ? 1 : 2 )

and in the same file change the JSECHARPTR_PUTC() macro, at about line 336, to this function declaration:

void JSECHARPTR_PUTC(jsecharptr ptr, jsechar c);

Also in srcmsic\seuni.h, for MSVC6 the macro for JSECHARPTR_GETC(), at about line 335, should be this:

#define JSECHARPTR_GETC(JSECHAR) \
           ((jsechar)_mbsnextc((unsigned char *)(JSECHAR)))

Then in srcmisc/utilstr.c, in the MBCS section, after line 215, add this function:

void JSECHARPTR_PUTC(jsecharptr str, jsechar c)
{
   assert( (uword32)c < 0x10000 ); /* if wrong then expand */
   if ( 255 < (uint)c )
   {
      *(unsigned char *)str = c >> 8;
      str = (jsecharptr)(((char *)str) + 1);
   }
   *(unsigned char *)str = c & 0xFF;
}

  • Memory leak for MBCS cfunction string insertion
    (for ISDK/C 4.30c)

Bug: If JSE_C_EXTENSIONS and JSE_MBCS are both enabled, and if the script is within a cfunction performance an operation that must insert a character into a string (e.g. str[4]='c'), then some memory will not be freed.

Fix: In srccore/var.c, function seobjPutIntoString(), at about line 433 where the string data is assigned with this line:

str->data.string_val.data->data = tmp;

insert a statement to free the previous pointer, so it is:

jseMustFree(str->data.string_val.data->data);
str->data.string_val.data->data = tmp;

  • MBCS and UNICODE data not freed in regular expressions library
    (for ISDK/C 4.30c)

Bug: An allocated string may remain unfreed when using regular expressions in unicode and MBCS builds.

Fix: In srclib/ecma/seregexp.c function RegExp_ExecOrCallOrTest(), at about line 621, this line

FreeJsecharString(asciiInput);

should be

FreeAsciiString(asciiInput);

  • Comparisons of MBCS strings may be incorrect
    (for ISDK/C 4.30c)

Bug: If two MBCS string are of a different physical length, comparisons may not include all characters, and so the results may be incorrect.

Fix: In srccore/varutil.c function sevarECMACompareEquality(), step 11 at about line 1056 insert code between these lines:

                           lx *= sizeof(jsechar);
#                 endif

resulting in this code:

                           lx *= sizeof(jsechar);
#                 elif defined(JSE_MBCS) && (0!=JSE_MBCS)
                        lx = BYTECOUNT_FROM_STRLEN(sx,lx);
                        if( lx!=BYTECOUNT_FROM_STRLEN(sy,ly) )
                           result = FALSE;
                        else
#                 endif

Also srcmisc/utilstr.c, function jsecharCompare(), line 355, extend the preprocessor directive for JSE_UNICODE so it also include JSE_MBCS, as in:

#if (defined(JSE_UNICODE) && (0!=JSE_UNICODE)) \
 || (defined(JSE_MBCS) && (0!=JSE_MBCS))

  • alignment problem terminating MBCS strings with null character
    (for ISDK/C 4.30c)

Bug: On systems with word-alignment restrictions the final null character for MBCS systems may cause abort.

Fix: In srccore/garbage.c, function sestrCreate(), at about line 1256 this line

*(jsechar *)(((ubyte *)newmem)+bytelen) = '\0';

should be

*(jsecharptrdatum *)(((ubyte *)newmem)+bytelen) = '\0';

Also, in srccore/extlib.c, function extensionLibraryStartup() this line

FullLibraryPath[0]=='\0'

should be

JSECHARPTR_GETC(FullLibraryPath)=='\0'

  • string concatenation errors in MBCS builds
    (for ISDK/C 4.30c)

Bug: In MBCS builds, any operation which causes string concatenation, such as "what"+"up" can use too much memory, create invalid results, or crash.

Fix: In srccore/varutil.c function ConcatenateStrings(), at about line 61 this code

JSE_POINTER_UINDEX bytelen2 = BYTECOUNT_FROM_STRLEN(mem1,len2);

should be

JSE_POINTER_UINDEX bytelen2 = BYTECOUNT_FROM_STRLEN(mem2,len2);

 


for 4.30b -- (may apply to earlier version)

  • Adding global _get does not remove global cache
    (for ISDK/C 4.30b)

Problem: assigning an _get to the global doesn't turn off the global cache for the executing function. Thus, the _get is not called everytime, but rather the value is cached.

Fix: In srccore/varutil.c, function seobjCreateMemberGeneric(), at line 1359 find this section:

{
this->flags |= DynamicHashListFromName(name)->HasFlag;
if( name!=global->global_strings[prototype_entry] )
this->flags |= OBJ_IS_DYNAMIC;
}

and change it to this, just adding the last if-statement:

{
   this->flags |= DynamicHashListFromName(name)->HasFlag;
   if( name!=global->global_strings[prototype_entry] )
      this->flags |= OBJ_IS_DYNAMIC;
   if( name==global->global_strings[get_entry]
&& this==call->GlobalObject ) call->useCache = False; }

and in the same file and fucntion at line 1372 change this block:

else if( name==global->global_strings[get_entry] )
{
   this->flags |= HAS_GET_PROP|OBJ_IS_DYNAMIC;
}
is changed to this block:
else if( name==global->global_strings[get_entry] )
{
   if( this==call->GlobalObject )
      call->useCache = False;
this->flags |= HAS_GET_PROP|OBJ_IS_DYNAMIC; }

  • Crash using VariableObject on sub-interprets
    (for ISDK/C 4.30b)

Bug: In some conditions, when calling an interpret() function from within another interpret, the program will crash while accessing VariableObject.

Fix: In srccore/call.c, function callInterpret(), at about line 1023, this code fragment:

&& this->prev!=NULL

should be changed to:

&& this->VariableObject!=NULL

  • SEOBJ_DYNAMIC_UNDEFINED logic incorrect
    (for ISDK/C 4.30b)

Error: There are a couple of problems with the logic in the SEOBJ_DYNAMIC_UNDEFINED behavior in the seobjCallDynamicProperty() function. First, if the property exists but is jseTypeUndefined the dynamic functions were not being called. Second, the _prototype chain was not be checked in those cases where it should be.

Fix: This logic has been fixed in 4.30c in srccore/varutil.c function seobjCallDynamicProperty() by rewriting the block that begins:

if( (obj->flags & SEOBJ_DYNAMIC_UNDEFINED)!=0

  • Warnings missing about long-lived temporary variables
    (for ISDK/C 4.30b)

Problem: Previous releases had a !NDEBUG message generated in the JSEDEBUG.LOG file to help track down long-lived temporary variables.

Fix: In srccore/jselib.c, function seapiCopyAndReturn(), at about line 360, before this line:

if( call->tempvars!=NULL )

add this code:

#ifndef NDEBUG
if ( call->prev==NULL && FRAME == NULL )
   DebugPrintf(UNISTR("temporary variable reference created ")\
               UNISTR("on non-wrapper frame.\n")\
               UNISTR("This can be inefficient. Use \"create\" or ")\
               UNISTR("\"jseCreateVar\" version of call.\n"));
#endif

  • source string memory not released in run compiled code
    (for ISDK/C 4.30b)

Problem: When interpreting from compiled code, memory used for strings in the source text are not freed after the code is loaded.

Fix: Update to 4.30c, and #define the new preprocessor directive TOKEN_STRINGTABLE_HACK to workaround this problem.

  • HashListFromName() can crash memory-segment environments
    (for ISDK/C 4.30b)

Error: In segmented-memory environments (such as win16), HashListFromName() macro may cause crashes if applied to numeric entries.

Fix: In util.c, functions LockedStringTableEntry(), GrabStringTableEntry(), and ReleaseStringTableEntry(), move HashListFromName() macro to follow checks on whether a VarName is odd (i.e. is a numeric entry).

  • NO_DEFAULT_VALUE message fails in MBCS builds
    (for ISDK/C 4.30b)

Problem: Dynamic object enumeration is broken when using jseGetNextMember and our 'create undefined placeholder members' method.

Fix: Many small changes are required to fix this problem. Upgrade to 4.30c.

  • NO_DEFAULT_VALUE message fails in MBCS builds
    (for ISDK/C 4.30b)

Bug: NO_DEFAULT_VALUE builds string incorrectly for MBCS builds

Fix: in srccore/varutil.c function sevarDefaultValue() near the end of the function replace this code:

if ( FindNames(call,this,JSECHARPTR_NEXT((jsecharptr)VarName),
               sizeof(VarName)/sizeof(VarName[0])-5,UNISTR("")) )
{
   VarName[0] = '(';
   strcat_jsechar((jsecharptr)VarName,UNISTR(") "));
}

with this code

JSECHARPTR_PUTC(VarName,'(');
if ( FindNames(call,this,JSECHARPTR_NEXT((jsecharptr)VarName),
               sizeof(VarName)/sizeof(VarName[0])-5,UNISTR("")) )
   strcat_jsechar((jsecharptr)VarName,UNISTR(") "));
else
   JSECHARPTR_PUTC(VarName,'\0');

  • "++" and "--" are reversed when printing function variables
    (for ISDK/C 4.30b)

Bug: When converting a function to text, as in ToSource on a function, the decrement will appear as "++" and increment will appear as "--".

Fix: In srccore/function.c, tok_text table, at about line 114, the '++' and '--' entries in the table are swapped. '--' should be before '++' not the other way around.

  • assert failures concatenting C-strings
    (for ISDK/C 4.30b)

    Problem: if you generate a C-function string that is offsetted, such as 'var a = "foobar"+3;', and then use that in a string concatenation, you'll get assert failures and wrong results.

    Fix: In srccore/varutil.c, replace the ConcatenateStrings() function with the code released in 4.30c.

  • DYN_DEFAULT global variable invalid if no JSE_OPERATOR_OVERLOADING
    (for ISDK/C 4.30b)

    Error: DYN_DEFAULT global variable invalid if no JSE_OPERATOR_OVERLOADING

    Fix: in srccore/call.c, function callNewGlobalVariable() move this chunk of code:

    if( call->prev==NULL )
    {
       call->DynamicDefault = seobjNew(call);
    }
    else
    {
       assert( call->DynamicDefault==call->prev->DynamicDefault);
       assert( call->DynamicDefault!=NULL );
    }

    in front of this line (instead of inside the block)

    # if defined(JSE_OPERATOR_OVERLOADING) && (0!=JSE_OPERATOR_OVERLOADING)

  • DescribeInvalidVar() overruns stack
    (for ISDK/C 4.30b)

    Error: DescribeInvalidVar() may overrun stack for MBCS or UNICODE.

    Fix: In srccore.util.c, function DescribeInvalidVar(), replace one instance of:

    sizeof(BadDesc->VariableWanted)

with

    sizeof(BadDesc->VariableWanted)/sizeof(jsechar)

and replace one instance of

    sizeof(BadDesc->VariableName)

with

sizeof(BadDesc->VariableName)/sizeof(jsechar)

  • Iterating through activation object for pass-by-reference crashes
    (for ISDK/C 4.30b)

    Bug: If a script function has pass-by-reference parameters, or is a cfunction, and if you iterate through the results of jseActivationObject() via jseGetNextMember(), you'll get asserts and crashes.

    Fix: In srccore/jselib.c, function seapiGetValue, at about line 179 is this code:

    SEVAR_COPY(&(var->last_access),&(var->value));
    SEVAR_DEREFERENCE(call,&(var->last_access));

    which should be replaced with this:

    SEVAR_COPY(&(var->last_access),&(var->value));
    if ( var->last_access.type==VReferenceIndex
      && !SEOBJ_IS_DYNAMIC(var->last_access.data.ref_val.base) )
    {
       SEVAR_COPY(&(var->last_access),
          seobjIndexMember(call,var->last_access.data.ref_val.base,
             (MemCountUInt)(JSE_POINTER_UINT)
             (var->last_access.data.ref_val.reference)));
    }
    SEVAR_DEREFERENCE(call,&(var->last_access));

  • Invalid assert() in MBCS builds
    (for ISDK/C 4.30b)

    Problem: Invalid assert() in MBCS version of sevarDuplicateString().

    Fix: In srccore/garbage.c, function sevarDuplicateString(), at about line 1161 is this assert statement:

    assert( '\0' == JSECHARPTR_GETC(JSECHARPTR_OFFSET((jsecharptr)newmem,len)) );            

That assert statement should be removed.

  • Many problems in ScriptEase local and remote debugger
    (for ISDK/C 4.30b)

    Errors: There were many problems with the 4.30b debugger, including invalid display of null variables, invalid display of variable types, breakpoint colors inconsistent, no distinction between step-into/stop-over/step-out, and other sever and cosmetic problems.

    Fix: Download SE:ISDK/C 4.30b, which includes the improved debugger.

  • seBreakpointTest() misses global code after #include
    (for ISDK/C 4.30b)

    Error: After stepping into code within an #include statement, and then returning to global code in the main file, the internal lines still report that they are in the #included file.

    Fix: In srccore/statemnt.c, function secompileStatement() at about line 776, add this block before the "break;" statement for "case seTokFunction: case seTokCFunction:"

    {
       uword8 tmp;
       VarName file = GrabStringTableEntry(
          this->call,
          this->call->Global->CompileStatus.CompilingFileName,
          strlen_jsechar(this->call->Global->CompileStatus.CompilingFileName),
          &tmp);
       secompileAddItem(this,seFilename,file);
       ReleaseStringTableEntry(file,tmp);
    }

  • Cannot set Array length to zero
    (for ISDK/C 4.30b)

    Bug: Setting Array length to 0 makes the length property go to 1.

    Fix: In srccore/varutil.c, function seobjDeleteMember(), change this
    code at about line 2321 change this line

    MaxIdx = 0;

    to

    MaxIdx = -1;

  • jseOptReqVarKeyword ignored in some cases
    (for ISDK/C 4.30b)

    Bug: 'cannot assign to lvalue' is wrongly reported in certain cases when working with objects with a dynamic _get. This may also present as "with" not working on object returned by _get().

    Fix: In srccore/secode.c, case sePushGlobalParam, at about line 1324 modify this code:

    if( !callFindAnyVariable(call,mem,False,(t!=sePushGlobal)) )
    {
       if( t==sePushGlobal )

with a conditional check as follows:

 if( !callFindAnyVariable(call,mem,False,(t!=sePushGlobal)) )
 {
    if( jseOptReqVarKeyword & call->Global->ExternalLinkParms.options )
    {
       callQuit(call,textcoreFUNC_OR_VAR_NOT_DECLARED,mem);
      break;
   }
   if( t==sePushGlobal )

  • get and put not called on cached global variables
    (for ISDK/C 4.30b)

    Problem: dynamic globals are being cached, when the dynamic property ought to be called for each access.

  • Fix: In srccore/call.c function callFunction (near line 343) find this block:
/* If not using same global, turn off cache */
if( CALL_GLOBAL(call)!=call->GlobalObject )
   call->useCache = False; 

and replace with this block:

    /* If not using same global, turn off cache */
    /* turn off cache if dynamic as well */
    if( CALL_GLOBAL(call)!=call->GlobalObject ||
        SEOBJ_IS_DYNAMIC(call->GlobalObject) )
       call->useCache = False; 

  • jseInterpret() error if MayIContinue only returns False
    (for ISDK/C 4.30b)

    Error: If MayIContinue() callback returns False, without setting an error message, then jseInterpret() return status is inconsistent.

    Fix: To match future behavior, have your MayIContinue function first call

jseLibErrorPrintf(jsecontext,"!InternalError 8001: do not continue");            

before returning False

  • remote debugging hangs while transferring large files
    (for ISDK/C 4.30b)

    Error: The proxy may hang during the "connecting..." message while debugging large files. The size that becomes a problem may depend on the relative speed of the two systems and their communication link.

    Fix: If this is a problem on your system then send a message to isdk_support requesting updates to these files: srcdbg/debugme.c, srcdbg/proxy.c, and proxy/winproxy.cpp.

  • jseLocateSource() is never returning NULL
    (for ISDK/C 4.30b)

    Problem: jseLocateSource() should return NULL when interpreting text that has no associated filename, such as when interpreting in-line code or when processing "#if" statements. Instead the function is returning "no filename".

    Fix: In srccore/util.c, function jseLocateSource(), add this as the last statement before "return FileName;".

    if ( FileName && !strcmp_jsechar(FileName,"no filename") )
       FileName = NULL;

  • jseFuncVarNeed() error if offset exceeds parameter count
    (for ISDK/C 4.30b)

    Bug: jseFuncVarNeed behavior is undefined if the requested parameter offset exceeds the number of parameters passed to the funcion.

    Fix: In srccore\jselib.c function jseFuncVarNeed() change this line:

    wSEVar dest = STACK_PUSH;

    to this

    wSEVar dest;

    and after the "assert( call->next==NULL );" statement add this code:

    if( call->num_args <= parameterOffset )
    {
       callError(call,textcoreFUNCPARAM_NOT_PASSED,1 + parameterOffset,
                 callCurrentName(call));
                 return NULL;
    }
    dest = STACK_PUSH;

  • jseGetFunction not finding inherited methods
    (for ISDK/C 4.30b)

    Bug: jseGetFunction() is not searching ._prototype chains to locate named functions.

    Fix: In srccore\jselib.c function jselibFindFunction() replace this line:

    ret = seobjGetMember(call,look,funcname);

    with these two lines:

    seObjectMem retMem = seobjChildMemberStruct(call,look,funcname);
    ret = retMem ? &(retMem->value) : NULL ;

  • embedded function error if not last local variable
    (for ISDK/C 4.30b)

    Problem: when saving call chain for embedded functions, when the function embedded is not the last local variable declared, it was not working correctly.

    Fix: In srccore/call.c, function callFunction() before this line (at about line 476)

    /* all variables are initialized...

insert this block of code (remember, this goes before the preceding comment):

/* First pass, make space for locals */
if( !isinit )
{
   for( count = 0;count<lfunc->num_locals;count++ )
   {
      seVar newloc = STACK_PUSH;
      SEVAR_INIT_UNDEFINED(newloc);
   }
}

further in the same function, at about line 556, replace this block:

else
{
   /* make space for the local variable on the stack */
   seVar v = STACK_PUSH;
   if( if_func!=NULL )
   {
      SEVAR_INIT_OBJECT(v,if_func);
      v->data.object_val.savedScopeChain =
      SEVAR_GET_OBJECT(&(call->new_scope_chain));
   }
   else
   {
      SEVAR_INIT_UNDEFINED(v);
   }
}

with this:

    else if( if_func!=NULL )
    {
       seVar v = CALL_LOCAL(count+1);
       seVar tmp = STACK_PUSH;
       SEVAR_INIT_OBJECT(tmp,if_func);
       tmp->data.object_val.savedScopeChain =
       SEVAR_GET_OBJECT(&(call->new_scope_chain));
       SEVAR_DO_PUT(call,v,tmp);
       STACK_POP;
    }

  • "cannot assign to lvalue" or apply "with" error on dynamic _get
    (for ISDK/C 4.30b)

    Bug: 'cannot assign to lvalue' is wrongly reported in certain cases when working with objects with a dynamic _get. This may also present as "with" not working on object returned by _get().

    Fix: In srccore/varutil.c, function seobjHasProperty, change this code (if your code does not look like this see Object with _get but no _hasProperty always has the property):

    if( seobjCallDynamicProperty(call,obj,OFF_GET_PROP,propname,False,dest) )
    {
       jsebool ret = (SEVAR_GET_TYPE(dest)!=VUndefined) || handled;
       STACK_POP;
       return ret;
    }

    to this code (the difference is the added "if" block):

    if( seobjCallDynamicProperty(call,obj,OFF_GET_PROP,propname,False,dest) )
    {
       jsebool ret = (SEVAR_GET_TYPE(dest)!=VUndefined) || handled;
       STACK_POP;
       if( ret && ref )
       {
          SEVAR_INIT_REFERENCE(dest,obj,propname);
       }
       return ret;
    }

  • jseInterpret() may load functions into the wrong global space
    (for ISDK/C 4.30b)

    Bug: If jseInterpret() is called from within a library wrapper function, and if JSE_MULTIPLE_GLOBAL is enabled, then those properties and function loaded with jseInterpret() may not be attached to the correct global.

    Fix: In srccore\call.c, function callInterpret(), change this line:

    call->GlobalObject = this->GlobalObject;

    to this:

    call->GlobalObject = CALL_GLOBAL(this);

    and in srccore\call.h, update the JSE_MULTIPLE_GLOBAL version of the CALL_SET_GLOBAL() macro to be this:

    # define CALL_SET_GLOBAL(c,g) \
         if ( (c)->funcptr && (c)->funcptr->global_object ) \
            (c)->funcptr->global_object=(g); \
         else \
            (c)->GlobalObject = (g)

  • variables of type undefined not initialized in scope chain
    (for ISDK/C 4.30b)

    Bug: Variables in the scope chain that should be of type undefined may not be initialized.

    Fix: In srccore/call.c, function 'callFunction' line 526, are these statements:

GetDotNamedVar(call,loc,ourname,False);
if( if_func!=NULL )

this "else" block should be added to follow that "if" block:

else
{
   SEVAR_INIT_UNDEFINED(tmp);
   SEVAR_DO_PUT(call,loc,tmp);
}

  • JSE_GROWABLE_STACK is not recommended
    (for ISDK/C 4.30b)

    Problem: JSE_GROWABLE_STACK options is buggy and doesn't provide much savings in memory or performance.

    Fix: We recommend disabling JSE_GROWABLE_STACK in all cases. It is already off by default unless JSE_MIN_MEMORY is enabled. To disable in all cases simply comment out this line:

    # define JSE_GROWABLE_STACK 1

    so that it is:

    /* # define JSE_GROWABLE_STACK 1 */

  • jseCallStackInfo can crash
    (for ISDK/C 4.30b)

    Bug: jseCallStackInfo may crash.

    Fix: In srccore/jselib.c function jseCallStackInfo() change this line:

    MemCountUInt scope_chain_loc = call->ScopeChain->used-1;

    to:

    sint scope_chain_loc = (sint)call->ScopeChain->used-1;

    and change this line:

    if( scope_chain_loc>=call->ScopeChain->used ||

    to:

    if( scope_chain_loc>=(sint)call->ScopeChain->used ||

  • "return" and "throw" problems with auto-semicolon insertion
    (for ISDK/C 4.30b)

    Error: Automatic insertion of semicolon misplaced with some "throw" and "return" statements.

    Fix: In srccore/textcore.h:329, add:

    TC_RESOURCE(textcoreTHROW_NO_NEWLINE,SYNTAX_EXCEPTION,"1223",
       "Throw expression must appear on the same line as the throw statement.")

    In srccore/statement.c:779, change the beginning of the case 'seTokThrow' to:

    case seTokThrow:
    {
       struct tok tok;
       tokLookAhead(this->call,this->locfunc,&tok);
       /* handle 'no line terminator here' in the production */
       if( tokType(&tok)==seTokEOL )
       {
          callQuit(this->call,textcoreTHROW_NO_NEWLINE);
          success = False;
          break;
       }

    same file, line 814, change the if test which looks like this:

    if( tokType(&tok)==seTokEOL )

    to this:

    if( tokType(&tok)==seTokEOL || tokType(&tok)=='}' )

  • functions called implicitly may have wrong "this" variable
    (for ISDK/C 4.30b)

    Bug: Functions called implicitly may have the wrong 'this'. In other words, if you do:

    var a = new Object();
    a.foo = <some function>;
    with( a )
       foo();

    That is supposed to work like you did 'a.foo()', and therefore 'a' should be the 'this' value for 'foo'. This errata fixes the problem with this not working.

    Fix: In srccore\secode.h, find the END_SEOP_32BITS and make it and the next line into these 3: This just means adding the middle value and renumbering the last one.

    #define END_SEOP_32BITS seBitAnd
    #define seThisAndValue 107
    #define NUM_SECODES 108

    In srccore\expressn.c, right after this line:

    { "seBitAnd", 0, 0 },

    add this line:

    { "seThisAndValue", 0, 0 },

    in same file (expressn.c), line 1922, add this:

    else if( this->expr.type==EXPR_GLOBAL )
    {
       secompileAddItem(this,sePushGlobalParam,this->expr.name);
       secompileAddItem(this,seThisAndValue);
       this->expr.type = EXPR_STACKTOP;
    }

    it should appear as a new else-arm in the existing code. Here is
    the block before and after with it, so you can make sure to put it
    in the right place:

    else if( this->expr.type==EXPR_STACKTOP )
    {
       /* top of stack is expression, we need to
        * get the 'this' (global object) underneath
        * it on the stack.
        */
       secompileAddItem(this,sePushGlobalObject);
       secompileAddItem(this,seSwap);
    }
    else if( this->expr.type==EXPR_GLOBAL )
    {
       secompileAddItem(this,sePushGlobalParam,this->expr.name);
       secompileAddItem(this,seThisAndValue);
       this->expr.type = EXPR_STACKTOP;
    }
    else
    {
       secompileAddItem(this,sePushGlobalObject);
    }

    finally, at the end of secode.c, right before this block (the very
    bottom of the file):

    #        ifndef NDEBUG
                /* catch bad opcodes */
             default: assert( False ); break;
    #        endif

    add this:

    case seThisAndValue:
    {
       seVar lhs = STACK0;
       seVar rhs = STACK_PUSH;
    
       SEVAR_COPY(rhs,lhs);
       SEVAR_DEREFERENCE(call,rhs);
       if( SEVAR_GET_TYPE(lhs)==VReference )
          SEVAR_INIT_OBJECT(lhs,lhs->data.ref_val.base);
       else
          SEVAR_INIT_OBJECT(lhs,CALL_GLOBAL(call));
       break;
    } 

  • jseSetGlobalObject() corrupts the internal opcode stack
    (for ISDK/C 4.30b)

    Bug: jseGlobalObject() can mess up the internal stack, causing weird bugs.

    Fix: In srccore/util.c, function jseGlobalObjectEx(), the old version never did a STACK_POP for its STACK_PUSH, so change the final line of jseGlobalObjectEx() from:

    return SEAPI_RETURN(call,g,(flags & jseCreateVar)?True:False,
                        UNISTR("jseGlobalObjectEx"));

to this code:

    {
       jseVariable ret;
       ret = SEAPI_RETURN(call,g,(flags & jseCreateVar)?True:False,
                          UNISTR("jseGlobalObjectEx"));
       STACK_POP;
       return ret;
    }

  • Dynamic get/put ignored when converting properties to objects
    (for ISDK/C 4.30b)

    Bug: Dynamic get/put was being ignored in some cases involving auto-conversion to object. For example, in the statement "foo.goo.zoo" where "foo" is a dynamic object, get/put are ignore if "goo" is auto-converted to be an object.

    Fix: In srccore/secode.c replace function do_op_member(() with the code found at ftp://ftp.nombas.com/pub/isdkeval/se430/do_op_member.c

  • Object with _get but no _hasProperty always has the property
    (for ISDK/C 4.30b)

    Problem: For a dynamic object with a get but no hasProperty in the scope chain, undefined was being accepted as 'has the property', so that object ALWAYS was considered to have the property.

    Fix: In srccore/varutil.c, function seobjHasProperty() change this code:

    if( dest==NULL ) dest = rhs;
    if( sevarGetValue(call,rhs,propname,dest) )
    {
       if( ref && dest!=rhs )
       {
          SEVAR_INIT_REFERENCE(dest,obj,propname);
       }
       STACK_POP;
       return True;
    }
    else
    {
       return False;
    }

to this code:

    if( seobjCallDynamicProperty(call,obj,OFF_GET_PROP,propname,False,dest) )
    {
       jsebool ret = (SEVAR_GET_TYPE(dest)!=VUndefined) || handled;
       STACK_POP;
       return ret;
    }
    STACK_POP;

and remove "else" from this line:

    else if( (it = seobjChildMember(call,obj,propname))!=NULL ) 

  • jseSetGlobal fails when combined with with jseFunc_NoGlobalSwitch
    (for ISDK/C 4.30b)

    Bug: If you're in a wrapper function that is not flagged with jseFunc_NoGlobalSwitch, and if jseSetGlobal() is called, the global variable will not really change:

    Fix: In CALL.H change the CALL_SET_GLOBAL macro to this:

    #if 0 != JSE_MULTIPLE_GLOBAL
    
    # define CALL_SET_GLOBAL(c,g) \
         if ( (c)->funcptr && (c)->funcptr->global_object ) \
            (c)->funcptr->global_object=(g); \
         else \
            (c)->GlobalObject = (g)
    #else
    # define CALL_SET_GLOBAL(c,g) ((c)->GlobalObject = (g))
    #endif 

  • function.arguments is not always available
    (for ISDK/C 4.30b)

    Problem: The "function.arguments" syntax is not part of the ECMAScript specification. But many JavaScript books describe this feature and most browsers implement it, so your users may expect this capability.

    Fix: First, change every existing instance of

    callCreateVariableObject(XXX)

    to

    callCreateVariableObjext(XXX,NULL)

    Then in srccore/var.c, add this code to the very beginning of function seobjGetMemberStructEx().

    if( Name==call->Global->global_strings[arguments_entry]
     && SEOBJ_GET_FUNCTION(this)!=NULL )
    {
       callCreateVariableObject(call,SEOBJ_GET_FUNCTION(this));
    }

    Finally, in srccore/call.c replace function callCreateVariableObject() with the code found at ftp://ftp.nombas.com/pub/isdkeval/se430/callcreatevariableobject.c and change the prototype in call.h accordingly.

  • assert() failure when global variable has dynamic _put
    (for ISDK/C 4.30b)

    Bug: If the global variable has a dynamic _put function or put callback then there can be problems, first indicated by this assert statement in the callFunction() function of call.c

    assert( SEVAR_GET_TYPE(&(call->new_scope_chain))==VUndefined );

    Fix: In CALL.H change this block of code

    # define FUNC_OFFSET 7
    # define THIS_OFFSET 8
    # define USE_CACHE_OFFSET 6
    # define OLD_USE_CACHE (FRAME-USE_CACHE_OFFSET)
    #else
    # define FUNC_OFFSET 6
    # define THIS_OFFSET 7

    to this

    # define FUNC_OFFSET 8
    # define THIS_OFFSET 9
    # define USE_CACHE_OFFSET 7
    # define OLD_USE_CACHE (FRAME-USE_CACHE_OFFSET)
    #else
    # define FUNC_OFFSET 7
    # define THIS_OFFSET 8

    then add these to lines to that same section of CALL.H

    #define NEW_SCOPE_OFFSET 6
    #define OLD_NEW_SCOPE (FRAME-NEW_SCOPE_OFFSET)

    then change this line

    # define PARAM_START RETURN_OFFSET

    to this

    # define PARAM_START NEW_SCOPE_OFFSET

    this in CALL.C callFunction() get rid of the first assert:

    assert( SEVAR_GET_TYPE(&(call->new_scope_chain))==VUndefined );

    then find this block

    #  if defined(JSE_CACHE_GLOBAL_VARS) && JSE_CACHE_GLOBAL_VARS==1
       tmp = STACK_PUSH;
       SEVAR_INIT_STORAGE_LONG(tmp,(ulong)call->useCache);
    #  endif

    and add right after that:

    tmp = STACK_PUSH;
    SEVAR_COPY(tmp,&(call->new_scope_chain));

    finally, in CALL.C callReturnFromFunction() just before this line

    call->iptr = SEVAR_GET_STORAGE_PTR(OLD_IPTR);

    add this line (remember, just before the previous line)

    SEVAR_COPY(&(call->new_scope_chain),OLD_NEW_SCOPE); 

 


for 4.30a --

  • wrong global variable cached if function uses different global
    (for ISDK/C 4.30a)

    Bug: The wrong global variable cache is used when a function is called
    that switches the global.

    Fix: In call.c function callFunction(), at about line 341, after this line

       call->useCache = ((FUNCVAR)->data.object_val.savedScopeChain == NULL);

    add

       if( CALL_GLOBAL(call)!=call->GlobalObject )
          call->useCache = False;

  • destructor not using object callback delete
    (for ISDK/C 4.30a)

    Bug: Object destructors are ignoring the deleteFunc member of the jseObjectCallbacks structure.

    Fix: This is fixed in release 4.30b

  • dynamic _put is ignored when creating members on the global object
    (for ISDK/C 4.30a)

    Bug: If the global object has a dynamic _put function then that _put functions is ignored while creating global variables.

    Fix: This is fixed in release 4.30b.

  • crash reading compiled cfunction if cfunction is disabled
    (for ISDK/C 4.30a)

    Bug: If a script is compiled (tokenized) by a version that supports
    the "cfunction" option, then it may crash when executed by a version
    that does not support the "cfunction" option.

    Fix: In srccore/loclfunc.c function localTokenRead() at about line 325 this
    block:

       #  else
          func = localNew(call,varname,dest);
       #  endif

    needs to be:

       #  else
          (void)tokenReadByte(tDst);
          func = localNew(call,varname,dest);
       #  endif

  • secode-stack overflow on functions with very many parameters
    (for ISDK/C 4.30a)

    Bug: A large number of parameters to a function call can overflow the secode stack and get past our stack space check. This only affects functions with about 80+ parameters.

    Fix: Release 4.30b fixes this problem.

  • garbage-collection bit clashes with object-mark bit
    (for ISDK/C 4.30a)

    Error: The mark bit used for recursive functions clashes with the same bit used for garbage collection. This may cause many assert() failures in debug builds, especially in compiled code buffers.

    Fix: In the 4.30b release the new flags SEOBJ_FLAG_BIT has been added to distinguish these recursive markers from the garbage-collector flags.

  • minimum-memory options should release more memory
    (for ISDK/C 4.30a)

    Error: Some options related to minimizing memory use (JSE_MIN_MEMORY, JSE_CREATEFUNCTIONTEXTVARIABLE, JSE_COMPACT_LIBFUNCS) are not freeing all possible memory.

    Fix: 4.30b release contains all of the fixes to these problems. Memory use can be minimized with these compile-time options.

  • construction of incomplete error objects can crash
    (for ISDK/C 4.30a)

    Bug: If an error object is used to report a problem, and if that error object has an invalid constructor method, then a crash may occur while generating the error in unusual circumstanstances (such as if the global variable has a _put function).

    Fix: This fix involves many changes to calls to and in sevarCallConstructor(). Upgrade to 4.30b to obtain all of these fixes.

  • jseBreakpointTest fails for JSE_PACK_SECODES
    (for ISDK/C 4.30a)

    Bug: If #define JSE_PACK_SECODES 1 (the default for non-aligned JSE_MIN_MEMORY builds, then the jseBreakpointTest may fail or crash.

    Fix: In srccore/brktest.c function callBreakpointTest() the two references to "c[1]" should be changed. In the first instance change "(VarName)c[1]" to "SECODE_GET_ONLY(c+1,VarName)" and change "(uint)c[1]" to "SECODE_GET_ONLY(c+1,CONST_TYPE)".

  • _get ignoring return of jseTypeUndefined
    (for ISDK/C 4.30a)

    Error: If an object's _get function or jseObjectCallbacks->get function returns a variable of jseTypeUndefined then it will treat the variables is if it doesn't exist.

    Fix: In varutil.c in function seobjHasProperty() at about line 2901 change this code:

       ret = SEVAR_GET_TYPE(dest)!=VUndefined;

    to

       ret = True; 

  • jseArgvLibraryFunction's not receiving the argc parameter
    (for ISDK/C 4.30a)

    Bug: With some callback methods (e.g. win16 DLL), wrapper functions tagged with jseFunc_ArgvStyle are not receiving the argc parameter.

    Fix: In call.c, function callFunction(), at about line 630, replace:

       (void *)call,locals); 

with

   (void *)call,call->num_args,locals);

  • RegExp object overwrites Object.prototype._class
    (for ISDK/C 4.30a)

    Bug: Calling the RegExp constructor will overwrite Object.prototype._class, so that all objects seem to belong to the RegExp class.

    Fix: In srclib/ecma/seregexp.c, at about line 220, change

       tempMember = jseMemberEx(jsecontext,regexpObject,CLASS_PROPERTY,
                                jseTypeString,jseCreateVar);

    to

       tempMember = jseMemberEx(jsecontext,regexpObject,CLASS_PROPERTY,
                                jseTypeString,jseCreateVar|jseDontSearchPrototype);           

  • program may crash when #include file not found
    (for ISDK/C 4.30a)

    Bug: Systems with memory protection on static data may crash when processing an #include statement if the file cannot be found.

    Fix: in source.c, at about line 751, this block:

       if ( !sourceNextLine(*source,call,False,&success) )
       {
          /* nothing was read at all */
          JSECHARPTR_PUTC((*source)->MemoryPtr,0);
       }

    should be changed to

       if ( !sourceNextLine(*source,call,False,&success) )
       {
          /* nothing was read at all */
          (*source)->MemoryPtr = UNISTR("");
       }

  • ToSource() returns incorrect value when used on hex value "\xFF"
    (for ISDK/C 4.30a)

    Problem: Calling:

       ToSource("\xFF")
    returns:
       "\xffffffff"
    instead of:
       "\xff"
    Fix: Change lines 219 and 220 of srclib/common/selibutl.c from:
   jsechar theChar = JSECHARPTR_GETC(current);
   jsechar buf[10]; 

to

   ujsechar theChar = JSECHARPTR_GETC(current);
   ujsechar buf[10];

  • Functions returning last-expression if no return statement
    (for ISDK/C 4.30a)

    Problem: Functions with no explicit "return" statement are returning the results of the last evaluation in that function. They should be returning undefined.

    Fix: in EXPRESSN.C function secompileFunctionBody(), at about line 1382 is a block of code like this:

       found = False;
    /* Return the last thing evaluated. Can't just check the last
    * entry, because it could be an extension value for a previous
    * opcode.
    */
    for( i=0;i<This.opcodesUsed;i++ )
    {
    .... lots more code ...
    }
    if( !found )
    secompileAddItem(&This,sePushUndefined);
    /* if we fall off the end of the function */
    secompileAddItem(&This,seReturn);

    that code should be within another if block, so it becomes:

       if( LOCAL_TEST_IF_INIT_FUNCTION(locfunc,This.call) )
    {
    found = False;
    /* Return the last thing evaluated. Can't just check the last
    * entry, because it could be an extension value for a previous
    * opcode.
    */
    for( i=0;i<This.opcodesUsed;i++ )
    {
    .... lots more code ...
    }
    if( !found )
    secompileAddItem(&This,sePushUndefined);
    }
    else
    {
    secompileAddItem(&This,sePushUndefined);
    }
    /* if we fall off the end of the function */
    secompileAddItem(&This,seReturn);

  • Not reporting when variable is freed twice
    (for ISDK/C 4.30a)

    Problem: When running in debug mode (JSE_TRACKVARS==1) the engine will not detect and report when a variable has been freed twice.

    Fix: In srccore/jselib.c function seapiDeleteVar(), at about line 265, add this line:

       var->alreadyFreed = True;
    before this line:
       if( var->prev==NULL )
  • jseGetVariableName() crashes when getting "global" variable
    (for ISDK/C 4.30a)

    Bug: jseGetVariableName() can crash when the global variable is being sought.

    Fix: In srccore/varutil.c, FindNames() function at about line 209, change the 'look in locals' section to the following:

       /* look in locals */
   if( call->VariableObject==NULL ) callCreateVariableObject(call);
   if( call->VariableObject )
   {
      SEVAR_INIT_OBJECT(tmp,call->VariableObject);
      if( IsThisTheVariable(call,tmp,me,NULL,Buffer,BufferLength,False) )
         FoundName = True;
   }

In srccore/util.c, jseGetVariableName(), at about line 2628, change the one main line in the function to the following:

   return FindNames(call,seapiGetValue(call,variableToFind),
                    buffer,bufferSize,UNISTR(""));

  • jseNewFunctions breaks default prototypes
    (for ISDK/C 4.30a)

    Bug: jseNewFunctions breaks existing default prototypes, causing such Ecma stuff as String, Function, and Array to not work.

    Fix:

      1. call.c, take the InitGlobalPrototype function and
         make it not static. Add a prototype for it to call.h,
         I put it at line 936.
      2. call.c, 1199, the lines that set the 4 prototypes
         by calling InitGlobalPrototype must be moved. Grab
         them and move them to util.c, 979. That's inside
         an if-block, currently that calls InitializeBuiltInVariables.
         Move the stuff _before_ that call, but inside the
         if block.
      3. The block refers to a variable 'call', replace those
         all with 'this'.
      4. Change the if-block's test to not test against
         jseNewGlobalObject, but rather jseNewLibrary.
    
      With comments, the new if-block looks like this:
    
       if( success && (NewContextSettings & jseNewLibrary)!=0 )
       {
          /* If we are initializing new libraries, we also want to
           * initialize our builtin ECMA stuff as well.
           */
          this->ObjectPrototype = InitGlobalPrototype(this,
             LockedStringTableEntry(this,OBJECT_PROPERTY,
                (stringLengthType)strlen_jsechar(OBJECT_PROPERTY)));
          this->FunctionPrototype = InitGlobalPrototype(this,
             LockedStringTableEntry(this,FUNCTION_PROPERTY,
                (stringLengthType)strlen_jsechar(FUNCTION_PROPERTY)));
          this->ArrayPrototype =
             InitGlobalPrototype(this,GLOBAL_STRING(this,array_entry));
          this->StringPrototype = InitGlobalPrototype(this,
             LockedStringTableEntry(this,STRING_PROPERTY,
                (stringLengthType)strlen_jsechar(STRING_PROPERTY)));
    
          /* We initialize the builtin variables into each global else we
           * will not have them in sub-interprets
           */
          InitializeBuiltinVariables(this);
       }
    

    Because the order of the initialization has changed,
    InitGlobalPrototype can add its stuff to existing objects,
    while it thinks that it will allways create the objects.
    Here is the new version (it replaces the one in
    srccore\call.c):

         seObject
      InitGlobalPrototype(struct Call *call,VarName name)
      {
         seObjectMem v;
         jsebool found;
    
         /* Create 'name', for example 'Object'. Make that
          * don't enum as all builtin objects should be that way.
          */
         v = seobjNewMember(call,CALL_GLOBAL(call),name,&found);
         v->attributes = jseDontEnum;
         if( v->value.type!=VObject )
            SEVAR_INIT_BLANK_OBJECT(call,&(v->value));
    
         /* Make '.prototype' of that object and return it.
          */
         v = seobjNewMember(call,SEVAR_GET_OBJECT(&(v->value)),
                            GLOBAL_STRING(call,orig_prototype_entry),&found);
         if( v->value.type!=VObject )
            SEVAR_INIT_BLANK_OBJECT(call,&(v->value));
         v->attributes = jseDontEnum | jseDontDelete | jseReadOnly;
    
         return SEVAR_GET_OBJECT(&(v->value));
      }
    

  • jse_special_math name-mangled in C++ compilers
    (for ISDK/C 4.30a)

    Problem: Some C++ compilers will not recognize jse_special_math, which is used to resolve jseInfinity, jseNaN, and other special numbers.

    Fix: In INCJSE/SEFP.H, wrap the lines that defined jse_special_math in an exern "C" { } block, starting at about line 58 and ending at about line 70

  • multiple/redundant calls to _get
    (for ISDK/C 4.30a)

    Problem: When a dynamic object is defined with a _get method or get callback, that get may be called extra times when evaluating properties of that dynamic object. This should not be a serious problem, in that all calls to _get are expected to work, but it is inefficient.

    Fix: In VARUTIL.C, function seobjHasProperty(), at about line 2856 change this:
     
          jsebool handled;
     
    to
     
          jsebool handled = False;
     
    and at about line 2889, is this section of code:
     
          if( SEOBJ_HAS_GET(obj) )
          {
             /* got to do a dynamic get */
             ...block of code...
     
    change that to:
     
          if( SEOBJ_HAS_GET(obj) )
          {
             if( ref && dest!=NULL )
             {
                SEVAR_INIT_REFERENCE(dest,obj,propname);
                return True;
             }
             else
             {
                /* got to do a dynamic get */
                ...block of code...
             }
     

  • Function constructor resets global variable
    (for ISDK/C 4.30a)

    Problem: With JSE_MULTIPLE_GLOBAL the function constructor (Ecma_Function_construct) and eval() function (Ecma_eval) are not always setting the global variable correctly for the functions being added or called.

    Fix: Many small changes are required in the following files:

    JSELIB.H - after the jseFunc_ArgvStyle value, add this line
     
          # define jseFunc_NoGlobalSwitch 0x10
     
    ECMAMISC.C - in function Ecma_eval the #if block following this comment
     
          /* Run with the same global the old function had */
     
    is no longer required. instead change
     
          JSE_LIBMETHOD( UNISTR("eval"), Ecma_eval, 1, 1,
              jseDontEnum, jseFunc_Secure ),
     
    to
     
          JSE_LIBMETHOD( UNISTR("eval"), Ecma_eval, 1, 1,
             jseDontEnum, jseFunc_NoGlobalSwitch | jseFunc_Secure ),
     
    SEOBJECT.C, change
     
          JSE_LIBOBJECT( FUNCTION_PROPERTY, Ecma_Function_construct, 0, -1,
             jseDontEnum, jseFunc_Secure ),
     
    to
     
          JSE_LIBOBJECT( FUNCTION_PROPERTY, Ecma_Function_construct, 0, -1,
             jseDontEnum, jseFunc_NoGlobalSwitch | jseFunc_Secure ),
     
    CALL.H: change first definition of CALL_GLOBAL to
     
          #define CALL_GLOBAL(c) (((c)->funcptr && (c)->funcptr->global_object) \
             ? (c)->funcptr->global_object : (c)->GlobalObject)
     
    JSELIB.C, function jseCallStackInfo replace
     
          SEVAR_INIT_OBJECT(tmp,funcptr->global_object);
     
    with
     
          SEVAR_INIT_OBJECT(tmp,
             funcptr->global_object?funcptr->global_object:call->GlobalObject);
     
    and replace
     
          SEVAR_INIT_OBJECT(&(mem->value),funcptr->global_object);
     
    with
     
          SEVAR_INIT_OBJECT(&(mem->value),
             funcptr->global_object?funcptr->global_object:call->GlobalObject);
     
    GARBAGE.C: function mark_function() change
     
          assert( func->global_object!=NULL );
     
    to
     
          if ( func->global_object!=NULL )
     
    UTIL.C has 3 calls to functionInit(), after each of these 3 calls
    add these statements (leaving "iFuncDesc->" of of the third
    instance):
     
          # if 0 != JSE_MULTIPLE_GLOBAL
             if ( 0 != (iFuncDesc->FuncAttributes & jseFunc_NoGlobalSwitch) )
                this->function.global_object = NULL;
          # endif
     

  • srccore\jseopt\jseopt.h file missing
    (for ISDK/C 4.30a)

    Problem: The file srccore\jseopt\jseopt.h is missing from some releases. This may cause errors locating "jseopt.h" while compiling the core interpreter libraries.

    Fix: Create the file srccore\jseopt\jseopt.h containing this text:
      
          #define _JSEOPT_H
      
    This is just a default JSEOPT.H file. If you are modifying options for your application it is best to make a new JSEOPT.H file and have both your application and the libraries refer to the same file.

  • string constants updated by c-function behavior
    (for ISDK/C 4.30a)

    Bug: string constants can are overwritten by function assignments in a c-function. For example, in the following statement the original "foo" will be overwritten.
      
          var foo = "foo";
          Clib.strcat(foo,"hoo");
      
    Fix: In jselib.c:1418, between
      
           val = seapiGetValue(call,variable);
      
    and
      
          if( val!=NULL && SEVAR_GET_TYPE(val)==vType )
      
    add
      
          if( SEVAR_GET_TYPE(val)==VString && SEVAR_GET_STRING(val).data->constant )
          {
             sevarDuplicateString(call,val);
          }
      
    so it now looks like:
      
          val = seapiGetValue(call,variable);
          if( SEVAR_GET_TYPE(val)==VString && SEVAR_GET_STRING(val).data->constant )
          {
             sevarDuplicateString(call,val);
          }
          if( val!=NULL && SEVAR_GET_TYPE(val)==vType )
      

  • Opcode errors in JSE_MIN_MEMORY builds
    (for ISDK/C 4.30a)

    Bug: May be errors in executing VM bytecodes when compiling with #define JSE_MIN_MEMORY 1.

    Fix: At expressn.c:1403
      
          This.opcodes[j+1]>i )
      
    Should be
      
          SECODE_GET_ONLY(This.opcodes+j+1,CONST_TYPE)>i )
      
    and at garbage.c:288, mark_call() in the #else part of the GROWABLE_STACK #if
      
          for( i=0;i<call->stackptr;i++ )
      
    should be changed to
      
          for( i=0;i<=call->stackptr;i++ )
      

  • Incorrect !Finite() behavior when performing floating-point math on big-endian systems
    (for ISDK/C 4.30a)

    Problem: Incorrect and unexpected behavior when performing floating-point math on big-endian systems. These behaviors include IsNaN()/ IsNegZero()/IsNegInfinity() returning incorrect values and arithmetic operations failing on large positive and negative numbers.

    Fix: In SEFP.H, line 91, change:
     
           # if BIG_ENDIAN == True
     
    to:
     
          # if SE_BIG_ENDIAN == True
     

  • Errors with strings and JSE_MBCS builds
    (for ISDK/C 4.30a)

    Bug: Data writing problem when JSE_MBCS is defined.

    Fix: jselib.c,genericPutDataptr line 1459.
     
          memcpy(newdata-(minidx*sizeof(jsechar)),data,
          s2 = BYTECOUNT_FROM_STRLEN((const jsecharptr)data,actual_size));
     
    should be changed to:
     
          memcpy(newdata+s1,data,
          s2 = BYTECOUNT_FROM_STRLEN((const jsecharptr)data,actual_size));
     
    and around line 1510 the block:
     
          # if defined(JSE_MBCS) && (JSE_MBCS!=0)
             /* recalculate physical length */
             /* NYI: MBCS byte length probably can be done better in
              * the individual cases above */
             val->data.string_val.data->bytelength =
                BYTECOUNT_FROM_STRLEN(val->data.string_val.data->data,
                       val->data.string_val.data->length);
          # endif
     
    has to be moved inside the closing brace right above it. There are several blocks closed here, move it inside the outermost, i.e. take the _last_ brace only and move it past the block, not any of the inner braces.

  • Casting warnings for new jseArgvLibFunc() functions
    (for ISDK/C 4.30a)

    Problem: Compilers will produce warnings using the argc parameter of the new jseArgvLibFunc(), requiring (uint) casts.

    Fix: In jselib.h for the new argv function "int argc" was changed to "uint argc" to prevent casting problems in some compilers. This must be changed in all instance in jselib.h

  • Error reading pre-compiled bytecodes for JSE_MIN_MEMORY
    (for ISDK/C 4.30a)

    Bug: Error reading pre-compiled bytecodes when JSE_MIN_MEMORY is defined.

    Fix: token.c, line 640:
     
          if( SECODE_DATUM_SIZE(*sptr)==1 &&
          *sptr>=SE_START_GOTO_CODES && *sptr<=SE_END_GOTO_CODES )
     
    get rid of the first test, that is wrong, it should just be:
     
          if( *sptr>=SE_START_GOTO_CODES && *sptr<=SE_END_GOTO_CODES )
     

  • Garbage collector can miss variables in sub-interprets
    (for ISDK/C 4.30a)

    Bug: Garbage collector can miss marking variables when called from unusual
    levels of sub-interpret.

    Fix: GARBAGE.C, function garbageCollect(), add this line to the top
    of the function:
     
           while( call->next ) call = call->next;

   

Home | Scripting | Products | Purchase | Download | Support | Company

Copyright ©2001, Nombas, Inc. All Rights Reserved.
Questions? Visit
http://support.nombas.com/