Nombas Homepage

Scripting

Products

Purchase

Download

Support

Company

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

 

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


API Errata, version 5.00f
  New, July 24, 2003

API Errata, version 5.00e
  New, February 14, 2003

API Errata, version 5.00d
  New, October 14, 2002


The Details

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

  • system can become corrupted if number of objects in use is greater than MARK_STACK_SIZE
    (for ISDK/Java 5.00f)
  • Bug: If the number of objects in use is greater than MARK_STACK_SIZE (defined in Call.jh) then memory may become corrupted. This is a rare oocurence and very difficult to duplicate. If you have experienced such corruption when running with very many objects, and if the problem is difficult to duplicate, then this may be the cause.

    Fix: In COM/Nombas/jse/Isdk/Garbage.jsrc, method mark(), this block near line 670:

       for( i=0;i<used;i++ )
       {
          SE_VAR var;
       
          var = mems[i];

    should become:

       for( i=0;i<used;i++ )
       {
          SE_VAR var;
          int vn = mems[i].name;
          if ( -1 != vn
               && StringTable.IsNormalStringTableEntry(vn)
               && (0 == (basecall.Global.stringTable.HashEntryFromVarName(vn).locks
                   & StringTable.SWEEP_BIT)) )
          {
             add_it = true;
             break;
          }
          
          var = mems[i];

  • cached prototypes (Array, Function, Object, String) miss __parent__ inheritance
    (for ISDK/Java 5.00f)
  • Bug: Some common objects have their Object.prototype object cached for faster access. These objects are Array, Function, Object, and String. When refreshing this "prototype cache" the real objects may not be found if inheritance is through the __parent__ chain instead of through standard _prototype chain. The resulting bug will usally be that statements that use these cached prototypes (e.g. new String(), "foo".toString()) will fail, while objects that do not use this cache (e.g. new Date()) will work.

    Fix: The method AssignGlobalPrototype() in COM/Nombas/jse/Isdk/Call.jsrc should be repleaced with the version found at ftp://ftp.nombas.com/pub/isdkeval/se500/assignglobalprototype_java.txt

  • try/catch grows internal stack
    (for ISDK/Java 5.00f)
  • Bug: Each try/catch will leave one element on the internal stack. The stack space is restored whenever the containing function returns. But if the function does not return then many try/catch blocks will eventually throw an out-of-stack error. For example, the following script would eventually exhause internal stack space:

      for ( ; ; )
      {
         try
         {
            throw "blah";
         }
         catch(e)
         {
         }
      }
    
    

    Fix: In COM/Nombas/jse/Isdk/Secode.jsrc, method ReasonToQuit(), remove all lines declaring or referencing the variable w_new_loc.

  • seCreateFiber() with JSE_SECURE uses unreleased memory
    (for ISDK/Java 5.00f)
  • Bug: If compiling with JSE_SECURE defined, then each call to seCreateFiber() creates objects that are not released until the top-level context is destroyed.

    Fix: The simplest fix is to remove JSE_SECURE from your JSEOPT.JH file. If compiling with JSE_TASK_SCHEDULER and JSE_SECURE then in COM/Nombas/jse/Isdk/Call.jsrc, method newSettings(), at about line 3758 replace this line:

       if( success && (this.prev == null||

    with:

       if( success && ((this.prev == null && this.fiber_prev == null) ||

  • Null Pointer Exceptions when working with fibers
    (for ISDK/Java 5.00f)
  • Bug: Destroying a fiber with seDestroyContext() causes Null Pointer Exceptions to be thrown when interpreting in sibling contexts.

    Fix: All of the following changes are to be made in COM/Nombas/jse/Isdk/Call.jsrc:

    At the beginning of the interpret(int, boolean, boolean) method, around line 3213, remove this line:

       call.Global.api_mark++; /* all temps here on are cleaned when this mark is cleaned */

    Next, in the delete() method around line 3436, replace this code:

       # if JSE_TRACKVARS==1
         if ( null == call.prev )
         {

    with this:

       # if JSE_TRACKVARS==1
         if ( null == call.prev
       #      if JSE_TASK_SCHEDULER==1
              && null == call.fiber_prev
       #      endif
             )
         {

    A little further down in the delete() method, around line 3468, remove this block of code:

       {
          boolean had_wrapper_temp = false;
          SE_VAR old_ret = null;
          byte old_state = FlowFlags.StateNormal;
    
          /* delete any remaining temp vars */
          SE500_CALL_KILL_TEMPVARS_GUTS(call);
    
    
          call.Global.api_mark--; /* no more temps will be at this level */
       } 

    A couple lines down, remove this block of code as well:

       /* Kill all remaining temp stuff */
       while( call.Global.api_local_temps.next!=null )
       {
          call.seTempFreeObject(call.Global.api_local_temps.next);
       }

    Finally, a few more lines down you will find a call to call.cleanupGlobal(). Insert this code directly before that call:

       boolean had_wrapper_temp = false;
       SE_VAR old_ret = null;
       byte old_state = FlowFlags.StateNormal;
    
       /* delete any remaining temp vars */
       SE500_CALL_KILL_TEMPVARS_GUTS(call);
    
    
    

  • Empty #defines ignored
    (for ISDK/Java 5.00f)

Bug: If a preprocessor macro is defined without a body the engine will not consider it 'defined'.

Fix: In COM/Nombas/jse/Isdk/SEDirective.jsrc, function() method of the DefineHandler class, around line 153 find this block:

   if ( WithinComment )
   {
      /* if ended within comment, then stop where that comment begins */
      end = BeginComment;
   }

and add this else block:

   else
   {
      end = i;
   }

  • The #ifdef and #ifndef preprocessor directives behave incorrectly
    (for ISDK/Java 5.00f)

Bug: The #ifdef and #ifndef directives rely on comparisons against the ECMAScript undefined value to determine if a symbol is defined. This behavior causes errors when the directive is applied to an empty macro. These directives now only test names in respect to whether or not they have been defined by #define, or are members of the SE.DEFINE object.

Fix: in COM/Nombas/jse/Isdk/Source.jsrc, method conditionalCompilationFilter(), around line 598 change this line:

   if ( !evaluateConditionalCompilation( call, SourceToEvaluate, \
   TextCore.CCD_ifdef==find,true) )

to this:

   if ( !evaluateIfDef( call, SourceToEvaluate, TextCore.CCD_ifdef==find ) )

Next, the sourceEvaluteIfDef() method needs to be added to the Source class in COM/Nombas/jse/Isdk/Source.jsrc. The source for this methodcan be found at ftp://ftp.nombas.com/pub/isdkeval/se500/ifdef.java

 

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

  • RegExp.$x and RegExp.lastParen not overwriting previous results with "undefined"
    (for ISDK/Java 5.00e)

  • Bug: When the results of a regular expression call should result in undefined for for RegExp.$1...RegExp.$9 or RegExp.lastParen, the results of the most-recent previous call are not over-written with undefined.

    Fix: In COM/Nombas/jse/libraries/SERegExp.jsrc, function RegExp_ExecOrCallOrTest(), the three calls to se.sePutUndefined(...) (at lines 609, 656, and 679) should be replaced with seMustPutUndefined(...).

  • Number toExponential() incorrect if fractionDigits not specified
    (for ISDK/Java 5.00e)
  • Bug: Number.prototype.toExponential(fractionDigits) is treating fractionDigits as 0 if unspecified. Instead toExponential() should use as many digits as necessary.

    Fix: In COM/Nombas/jse/libraries/ECMAObject.jsrc, function Ecma_Number_toSomething(), at about line 1825 a block of code should be added after f = 0; as follows:

        if ( _toExponential == toWhat )
        {
           String[] buffer = {null};
           int cptr = 0;
    
    
           /* convert using standard tostring rules */
           Utility.EcmaNumberToString(buffer,x);
    
           /* from buffer count how many digits are needed after the decimal,
            * that's all digits minus 1
            */
    
    
           if ( buffer[0].charAt(cptr) == '-' ) cptr++; /* skip any negative */
           int length = buffer[0].length();
    
           while ( cptr < length )
           {
              char c = buffer[0].charAt(cptr);
              cptr++;
              if ( '0' <= c && c <= '9' )
                 f++;
              else if ( '.' != c )
                 break;
           }
           f--;
         }

  • Number toPrecision() incorrect
    (for ISDK/Java 5.00e)
  • Bug: Number.prototype.toPrecision(precision) is converting precision digits beyond the decimal, when it should be converting precision-1 digits.

    Fix: In COM/Nombas/jse/libraries/ECMAObject.jsrc, function Ecma_Number_toSomething(), at about line 1943 the entire toPrecision block should be replaced with this code:

        else
        {
           senumber abs_x = Math.abs(x);
    
    
           /* field width must be an int */
           /* if x>=pow(10,-6) && < pow(10,f), use fixed-point notation
            * otherwise, use exponential notation */
           if( (Math.pow((senumber)10,(senumber)-6) > x= abs_x ) &&
             (abs_x < Math.pow((senumber)10,(senumber)f)) )
           {
              senumber f10 = Math.log(abs_x)/Math.log(10);
    
              int d10 = (int)f10;
              f -= d10;
              if ( !jseIsNegative(f10) )
                 f--;
    
              pattern = "0";
              if ( f > 0 )
              {
                 pattern += ".";
                 for ( int i = 0; i < f; i++ )
                    pattern = pattern + "0";
              }
              else
              {
                 pattern = "0.00";
              }
              form.applyPattern( pattern );
    
              buffer = form.format(x);
           }
           else
           {
              java.math.BigDecimal foo = new java.math.BigDecimal(x);
    
              foo = foo.movePointLeft(f);
              foo = foo.setScale(0,BigDecimal.ROUND_HALF_UP);
              foo = foo.movePointRight(f);
    
              f = f-1;
              pattern = "0";
    
              if ( f > 0 )
                 pattern += ".";
    
              for ( int i = 0; i < f; i++ )
                 pattern = pattern + "0";
    
              pattern = pattern + "E0";
              form.applyPattern( pattern );
    
              buffer = form.format(foo.doubleValue());
              buffer = convertExponentialFormat(buffer);
           }
        }
    

    Also, add this method to the ECMAObject class (in COM/Nombas/jse/libraries/ECMAObject.jsrc):

        static private String convertExponentialFormat(String format)
        {
          StringBuffer temp = new StringBuffer();
    
          /* Convert the 'E' to 'e+' or 'e-' */
          for( int i=0, len = format.length(); i<len; i++ )
          {
             char c = format.charAt(i);
             if ( c == 'E' )
             {
                temp.append("e");
    
                if ( format.charAt(i+1) != '-' )
                {
                   temp.append("+");
                }
             }
             else
             {
                temp.append(c);
             }
          }
    
          return temp.toString();
    
        }

  • discrepencies using delete on global variables
    (for ISDK/Java 5.00e)
  • Bug: When delete is used on global variables that were not created with the var keyword, the variables are not being deleted or the wrong boolean is being returned.

    Fix: In COM/Nombas/jse/Isdk/SECompile.jsrc, method operatorExpression() under case seTokDelete:, replace this else block at about line 2916:

        else { /* not a reference, return 'true', 11.4.1 */ ... } 

    with this code:

        else if( this.expr.type==SEExpression.GLOBAL )
        {
           this.addItem(sePushGlobalObject);
           this.addItem(seDeleteMember,this.expr.name);
        }
        else
        {
           /* not a reference, return 'true', 11.4.1 */
           this.discard();
           this.addItem(sePushTrue);
        } 

    Then in COM/Nombas/jse/Isdk/Call.jsrc, function(), find this comment:

        /* no need to set the attributes directly, the variable object
         * cannot be referenced by the script, which makes it
         * effectively 'DontDelete'.
         */

    which is no longer true. Replace it with:

        SEVAR_GET_REFBASE(wLoc).setAttributes(this, (int)wLoc.num_val,
                                             (byte)SE.DONTDELETE);
    
    
     

    and in COM/Nombas/jse/Isdk/_SEObject.jsrc, method deleteMember(), at about line 1502 the case with the comment

        /* member doesn't exist; don't delete what does not exist */
    
    
    should be changed to return true;

  • string replace, if no matches found, is not returning the initial string
    (for ISDK/Java 5.00e)
  • Bug: If String.prototype.replace() is called and no replacement is made, then the original string should be returned.

    Fix: In COM/Nombas/jse/libraries/ECMAString.jsrc, function string_which_search_helper(), at about line 1116 is a comment "...could be no match..." After the seAssignConvert() call just below that comment this function should return. With the return statement that block becomes:

       /* could be no match, if replace, return the string from thisVar */
       if( se.seGetType(SE.RETURN,SE.VALUE) == SE.TYPE_NULL &&
           mode == SE_REPLACE_MODE )
       {
          se.seAssignConvert(SE.RETURN,SE.VALUE,SE.THIS,SE.VALUE,SE.TOSTRING);
          return;
       }

for 5.00d -- (may apply to earlier version)

  • seCreateFiber reinitializes function libraries
    (for ISDK/Java 5.00d)

Problem: seCreateFiber is reinitializing the function libraries, when they should be shared. Because it reinitialized them in the same global, it just overwrote the existing libraries resulting in a performance decrease to 'redo' already-done work.

Fix: in COM/Nombas/jse/Isdk/Call.jsrc, the function seCreateFiber, find this line at about 5791:

   call.CallSettings = SE.EXIT_LEVEL|SE.NEW_DEFINES|SE.NO_INHERIT;

and replace with this:

   call.CallSettings = SE.EXIT_LEVEL|SE.NEW_DEFINES|SE.NO_INHERIT|SE.NO_LIBRARIES;

and in src/core/call.c, function callDelete(), at at about line 1906, replace this block:

   if( (((call.CallSettings & SE.NO_INHERIT) != 0) &&
        ((call.CallSettings & SE.NO_LIBRARIES) == 0)) ||
       call.prev == null )

with this

   if( (((call.CallSettings & SE.NO_INHERIT) != 0) &&
        ((call.CallSettings & SE.NO_LIBRARIES) == 0)) ||
       (call.prev == null
#      if JSE_TASK_SCHEDULER==1
       && fiberSibling==null
#      endif
        ) )

  • Errors with extremely large Date values
    (for ISDK/Java 5.00d)

Problem: Date values larger than the maximum allowable to new Date() can cause nearly-infinite loops.

Fix: In COM/Nombas/jse/Isdk/SEDate.jsrc, method do_date_construction(), near line 895 find this block:

   else
   {
      value = se.seGetNumber(SE.ARGS,SE.INDEX(0));
   }

and replace with this:

   else
   {
      value = se.seGetNumber(SE.ARGS,SE.INDEX(0));
      value = TimeClip(value);
   }

  • virtual-stack growth if retrieving values after an exception
    (for ISDK/Java 5.00d)

Problem: If an exception is generated during a call to the SE API, items may be left on the script stack. This is not likely to cause a problem in a run-time system, but in debug mode will cause the SE_API_RETURN() macro to emit a "stack growth" assertion.

Fix: In COM/Nombas/jse/Isdk/_SEVar.jh, in the macros for SEVAR_DEREFERENCE, are two lines (lines 399 419) like this::

   if( !CALL_QUIT(c) ) STACK_POP(c);                 \

in both cases the CALL_QUIT() test should be removed, so they both become:

   STACK_POP(c);                                     \

  • dynamic get is not being called if SEHasPropCallback not implemented
    (for ISDK/Java 5.00d)

Problem: If an object has dynamic callbacks via seSetCallbacks, but does not implement a hasProp callback, then the get callback should be called to determine if the object has the given property. This is not happening in 5.00d.

Fix: in src/core/varutil.c, the function seobjHasProperty, near the top (at about line 1296) is:

   if( SEOBJ_IS_DYNAMIC_PROP(call,this,SEHasPropCallback) )

replace with:

   if( SEOBJ_IS_DYNAMIC_PROP(call,this,SEHasPropCallback)
       || SEOBJ_IS_DYNAMIC_PROP(call,this,SEGetCallback) )

and then a few lines down (at about line 1305) immediately after this comment:

   /* Make sure that we initialize it in case GC happens */

add these lines:

   if ( !SEOBJ_IS_DYNAMIC_PROP(call,this,SEHasPropCallback) )
   {
      handled = false;
   }

  • string.split() incorrect if regular expression used as separator
    (for ISDK/Java 5.00d)

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 COM/Nombas/jse/Isdk/ECMAString.jsrc, function Ecma_String_split(), at about line 498(just after the second call to SplitMatch) this statement:

   if( z!=null );

should be changed to:

   if( z!=null && ((R==null) || se.seGetLong(z,SE.STOCK(JseStrID.index))==0) )

  • seDestroyContext cannot be called within seEval
    (for ISDK/Java 5.00d)

Problem: seDestroyContext was written with the assumption that no seEvals would be currently executing inside it when called. Since people want to be able to just abort and cleanup the context, the function has been changed to support this.

Fix: COM/Nombas/jse/Isdk/Call.jsrc, replace the existing seDestroyContext with this new version:

   public void seDestroyContext()
   {
      SE_CALL call;
      boolean again;

      do
      {
         call = CALL_FROM_JSECONTEXT(this);
         assert_is_context(call);
         again = (call.prev != null);
         Call.delete(call);
      }
      while( again );
   }

  • crash with eval() in nested function
    (for ISDK/Java 5.00d)

Bug: Crash in eval() inside nested function calls. This bug applies to any wrapper function trying to call seEval().

Fix: COM/Nombas/jse/Isdk/Call.jsrc, function createVariableObject(), at about line 1661 find:

   while( !FUNCTION_IS_LOCAL(func_orig) \
       || (lookfunc!=null && lookfunc!=func_orig) || depth-->0 )
   {

and replace with

   while( !FUNCTION_IS_LOCAL(func_orig) \
       || (lookfunc!=null && lookfunc!=func_orig) || depth>0 )
   {
      if( depth ) depth--;


  • STACK_INFO crashes within nested seEval()
    (for ISDK/Java 5.00d)

Problem: Using STACK_INFO within nested interprets can crash.

Fix: COM/Nombas/jse/Isdk/Call.jsrc in the seGetMember function, find this block at about line 1214:

   save = init_call.save;

   in_prev_call:
      while(true)
      {

and change it to:

   in_prev_call:
      while(true)
      {
         save = scall.save;      

     
  • stock objects passed to seEval with SE.FUNC will not work
    (for ISDK/Java 5.00d)

Bug: When calling seEval() with stock objects and the SE.FUNC flag (e.g. seEval(...,SE.THIS,...,SE.FUNC,...)) the stock object will not be recognized. This is most likely to show up when the object is SE.NOWHERE as a result of an invalid call to seGetObject().

Fix: In COM/Nombas/jse/Isdk/Call.jsrc, method seEvalFunc(), add this to the local variable declarations at the top

   SE_OBJECT realobj = seobjectTohSEObject(func_obj);

and about 20 lines further down in the same function, just before the statement "pushes += 2;", replace this line:

   SEVAR_INIT_OBJECT(func_var,func_obj.obj);

with this:

   SEVAR_INIT_OBJECT(func_var,realobj);
                                 

  • assert() or memory leak from seEval(...SE_FUNC..) if run-time error in script function
    (for ISDK/Java 5.00d)

Problem: When using seEval() to call a function, errors in the function could trigger assertions. In release builds, this would result in a slight memory leak.

Fix: In COM/Nombas/jse/Isdk/Call.jsrc, function callFunctionFully(), at about line 2700, replace this line:

   if( !callMayIContinue(this) )

with this:

   if( !CALL_ERROR(this) && !callMayIContinue(this) )

and 5 lines further down remove the following 3 statements:

      _SEVar ret = STACK_PUSH(this);
      SEVAR_INIT_UNDEFINED(ret);
      this.error(TextCore.MAYICONTINUE);
                                                             
  • SE_NEW_GLOBALS flag for seEval() doesn't work
    (for ISDK/Java 5.00d)

Problem: Specifying a new global in calls to seEval using the seEval parameters structure can fail to take effect.

Fix: COM/Nombas/jse/Isdk/Call.jsrc, function seEval(), at about line 9933, replace this line:

   HowToInterpret &= ~SE.NEW_GLOBALS;

with this:

   settings &= ~SE.NEW_GLOBALS

  • Function.prototype.apply() not accepting null for thisObj parameter
    (for ISDK/Java 5.00d)

Problem: Function.prototype.apply() should accept null or undefined as the first parameter, using the global object for these cases. Instead an error message is generated.

Fix: In COM/Nombas/jse/libraries/ECMAObject.jsrc, function Ecma_Function_apply, at about line 468replace this conditional:

   if( argc > 0 )

with this:

   if( argc > 0
    && SE.TYPE_NULL < se.seGetType(SE.ARGS,SE.INDEX(0)) )

                                 

  • seEval(...SE_FUNC...) does not generate exception if object is not a function
    (for ISDK/Java 5.00d)

Problem: Calling seEval() with a function (the SE.FUNC flag) will return false but will not generate an exception and will not call the seAttErrorFunc or sePrintErrorFunc. Instead, this will call the internal API function. In other words, calling seEval() with an invalid function object is viewed as an API error instead of a scripting error.

Fix: The underlying API philosophy is the seEval() should behave much like the script eval() function, and so using a non-function object as an API error is wrong. In COM/Nombas/jse/Isdk/Call.jsrc function seEvalFunc(), at about line 9367 changine this line:

   this.seAPIError("Object passed as a function to seEval is not really a function.");

to this

   this.quit(TextCore.NOT_FUNCTION_VARIABLE,"");                           
   

Home | Scripting | Products | Purchase | Download | Support | Company

Copyright ©2001, Nombas, Inc. All Rights Reserved.
Questions? Visit
http://support.nombas.com/