|
Java
Integration SDK 4.30x Errata
Fixes Affecting Users of the ScriptEase
Java ISDKs
- 4.30e
API - lastest update: February 26, 2002
API
Errata, version 4.30e (may apply to earlier
versions)
New, February 26, 2002
API Errata, version 4.30d (may apply to earlier
versions)
New, October 4, 2001
API Errata, version 4.30a (may apply to
earlier versions)
New, August 30, 2001
The
Details
for
4.30e --
- String
replace may skip matches if replacement string
is null-string (i.e. "")
(for ISDK/Java 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/ECMAlib.jsrc, 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/jstring_search_helper.txt
- parseInt("0")
throws exception
(for ISDK/Java 4.30e)
Bug: Calling parseInt("0") results in the engine
throwing an IndexOutOfBounds exception
Fix: In ECMAlib.java around line 202 in
the parseInt() wrapper function, find this line:
if( 'X' == Character.toUpperCase( str.charAt(idx+1) ) )
and
change it to this:
if( str.length() > 1 && 'X' == Character.toUpperCase( str.charAt(idx+1) ) )
also,
find this line (around line 213 in the same
function):
if ( '0' == str.charAt(idx) && 'X' == Character.toUpperCase(str.charAt(idx+1)) )
and
change it to this:
if ( '0' == str.charAt(idx) && str.length() > 1 && 'X' == Character.toUpperCase(str.charAt(idx+1)) )
- Math.round()
returns -0 instead of +0 from -0.5 to -0
(for ISDK/Java 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 Libs/SEMath.java, in the Ecma_Math_round
wrapper function, the "if" statement and block
should be changed to:
if ( Jselib.jseIsFinite(val) && !Jselib.jseIsZero(val) )
{
double half = (jseOne/2);
/* exception to standard math if between -0.5 and -0, inclusive */
if (val < Jselib.jseZero && -half <= val)
val = Jselib.jseNegZero;
else
val = Math.floor(val+half);
}
- Math.min(+0,-0)
wrongly returns +0
(for ISDK/Java 4.30e)
Bug: Math.min() is not returning -0 when comparing
-0 against +0.
Fix: in Libs/SEMath.java, in the Ecma_Math_min
wrapper function, at about line 483 change the
comparison from:
if( current < minval )
to:
if( (current < minval) || (Jselib.jseIsNegZero(current) && Jselib.jseIsZero(minval)) )
- Invalid
date computation on negative month
(for ISDK/Java 4.30e)
Bug: Date calculations are incorrect 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 Libs/SEdate.java, function MakeDay(), insert
code between lines 475 and 479 add code so those
lines become:
r6 = m%12; if ( r6 < 0 ) { r6 += 12; r5--; } t = TimeFromYear(r5);
- Stack
overflow if reporting invalid data type while
generating an error message
(for ISDK/Java 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 cause a stack overflow.
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 Call.jsrc, method errorVPrintf(), replace
this code: (around line 2591)
if ( Global.inErrorVPrintf )
return;
with
this:
if ( Global.inErrorVPrintf )
{
SET_ERROR( FlowError );
return;
}
SET_ERROR(FlowError);
Also
in Call.jsrc, method errorVPrintf(), just before
the comment that reads:
/* If possible find line number information and add that */
add
this statement:
Global.inErrorVPrintf = true;
- Pre-compiled
scripts with function calls cause NullPointerException
(for ISKD/Java 4.30e)
Problem:
When interpreting a pre-compiled script that
makes functions calls, the engine throws a NullPointerException
Fix:
Around line 607 of Token.jsrc, in the readVar()
method, find this block:
byte type = readByte();
if ( type == NEW_FUNCTION )
{
/* a function variable */
localTokenRead( call, var );
}
right
before the comment, insert the following line:
INIT_BLANK_OBJECT(call,var);
The
block should now look like this:
byte type = readByte();
if ( type == NEW_FUNCTION )
{
INIT_BLANK_OBJECT(call,var);
/* a function variable */
localTokenRead( call, var );
}
- Compiling
large scripts slow
(for ISDK/Java 4.30e)
Problem: Compiling large scripts takes an extremely
long time.
Fix: Around line 153 in Loclfunc.jsrc,
in the nextToken() method, find this line:
tok_alloced += 50;
and change it to
tok_alloced *= 2;
- Excessive
memory usage while interpreting a script
(for ISDK/Java 4.30e)
Problem: While interpreting some scripts, the
engine may unnecessarily use a large amount
of memory.
Fix: Around line 369 in seVar.jsrc,
in the createAllocatedString() method, find
this line:
ret.data = mem;
and
change it to this:
ret.data = String.copyValueOf(mem.toCharArray(), 0, len);
- stack
variable overwrite when mayIContinue() method
returns false
(for ISDK/Java 4.30e)
Bug:
When you mayIContinue() callback return 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 Call.jsrc, method jseInterpret(), at about
line 3931, replace this line:
seVar tmp = Global.stack[ ++stackptr ];
with
this:
seVar tmp = ((Call)newc).Global.stack[ ++((Call)newc).stackptr ];
- terminating
execution from within a "try" block can cause
memory leaks
(for ISDK/Java 4.30e)
Bug: If execution is terminated while a script
is within a try block, such as if the mayIContinue()
callback function returns False or by calling
jseLibSetExitFlag(), then some allocated memory
will not be released.
Fix: in Call.jsrc, in method delete()
of the Call class, add this line to the end
of the method (just before the 'call = null;'
line) at around line 3396:
call.tries = null;
and
in Secode.jsrc, about 19 lines into the method
handleFinally() of the Secode class, replace
these lines (at about line 6365):
if ( call.QUIT() ) call.stackptr = call.tries.sptr;
with
these:
if ( call.state == FlowError ) call.stackptr = call.tries.sptr;
- RegExp.prototype._class
wrong
(for ISDK/Java 4.30e)
Bug:
RegExp.prototype._class should be defined as
"RegExp" but is instead defined as the number
NaN.
Fix:
In Libs/ECMAlib.java at about line 941, replace
this line:
Jselib.JSE_VARSTRING( PROTOCLASS_PROPERTIES, REGEXP_PROPERTY, jseDontEnum),
with
this:
Jselib.JSE_VARSTRING( PROTOCLASS_PROPERTIES, "\"RegExp\"", jseDontEnum),
for
4.30d --
convert(call,tmp,jseToPrimitive);
to:
convertToPrimitive(call,tmp,VNumber);
- ToNumber()
returns incorrect values for "+" and "-"
(for
ISDK/Java 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 VarUtil.jsrc, method convertStringToNumber,
around line 1404, change this line of code:
if ( lenParsed == lenStr )
to:
if ( lenParsed == lenStr && lenStr != 1 )
- toString(radix)
not returing correct value for 0
(for ISDK/Java 4.30d)
The
following simple script should return "0", but
does is not:
var z = (0).toString(10);
Fix:
In ECMAlib.java, at the beginning of the method
EcmaNumberToStringWithRadix(), insert the following
code:
if( val == 0 )
{
buf[0] = "0";
return;
}
- toString
on functions concatenates some indentifiers
(for ISDK/Java 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:
Many changes are required to fix this and related
problems. Upgrade to 4.30.
- eval
does not propogate the "this" of its caller
(for ISDK/Java 4.30d)
Problem:
eval() does not propogate the 'this' of its
caller.
Fix:
In ECMAlib.java, in the method eval(), change
the reference to JSE_INTERPRET_KEEPTHIS in the
call to jseInterpret() to JSE_INTERPRET_PARENTTHIS.
In
JseInterpretMethod.jsrc, add these lines:
/* Use the 'this' variable from the calling function */
public static final int JSE_INTERPRET_PARENTTHIS = 0x100;
In
Call.jsrc, near line 3122, there is a call to
RunCompiledCode(), change it to this:
{
seObject this_obj = null; if ( (HowToInterpret&JSE_INTERPRET_KEEPTHIS)!=0 &&
frameptr != -1 )
{ this_obj = GET_OBJECT(Global.stack[frameptr-(THIS_OFFSET+num_args)]);
} if ( this_obj==null &&
(HowToInterpret&JSE_INTERPRET_PARENTTHIS)!=0 )
{
if( frameptr!=-1 )
{
int old_frame;
int old_num_args;
old_num_args = GET_STORAGE_LONG(OLD_ARGS(this));
old_frame = GET_STORAGE_LONG(OLD_FRAME(this)); if( old_frame != -1 )
{
this_obj = GET_OBJECT(Global.stack[old_frame-(THIS_OFFSET+old_num_args)]);
}
}
} if( this_obj==null )
{
this_obj = InterpretCall.GLOBAL();
}
InterpretCall.RunCompiledCode( argc, argv, CallMain,this_obj,
HowToInterpret); }
- static
Array initializer is not instanceof Object
(for ISDK/Java 4.30d)
Bug:
When an Array object is initialized with a static
Array Initialiser, as in this code:
var foo = [ 1, 2, 3 ];
it
is recognized as "instanceof Array" but is not
recognized as "instanceof Object".
Fix:
In Secode.jsrc, method interpret(), "case seCodeVal.instanceOf:",
at about line 5797 is this comment:
/* at any rate, this is the last chance. */
to
fix this bug, insert the following code ahead
of the comment, so it reads:
/* finally. all objects inherit from Object */ else if (call.ObjectPrototype == functionPrototype.obj_val) result = true; /* at any rate, this is the last chance. */
- empty
Object initializer creates an Array object;
should be an Object object
(for ISDK/Java 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 Secode.jsrc, class secompile, method Object(),
at about line 3646, change this line:
if ( t[0].type != ':' )
to
this:
if ( t[0].type != ':' && token.type != '}' )
- "continue"
within "switch" statement jumps to wrong condition
(for
ISDK/Java 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 Secode.jsrc, around line 682, add this to
the "loopTracker" class:
boolean is_switch;
at
line 3172, in the secompile class, find the
newLoop() method, and change its signature to
this:
void newLoop( gotoItem label, boolean is_switch )
in
Secode.jsrc, all calls to newLoop() get a second
false parameter, except for the one in the Switch()
method of the secompile class. That ones get
true for its second parameter.
Then,
in Secode.jsrc, change the newLoop() method's
body to look like this:
void newLoop( gotoItem label, boolean is_switch ) { loopTracker t = new loopTracker(); t.next = loopTrack; loopTrack = t; t.is_switch = is_switch; if ( label != null ) label.loop = t; }
and
at line 725 of Secode.jsrc, in the loopTracker
class, change the method addContinue to this:
void addContinue( int addr ) { if ( continuesUsed >= continuesAlloced ) { continuesAlloced += 10; int[] tmp = new int[continuesAlloced]; if( continues != null ) System.arraycopy( continues, 0, tmp, 0, continues.length ); continues = tmp; }
continues[continuesUsed++] = addr; }
and
finally, in Secode.jsrc, in the Statement()
method of the secompile class, within the "case
seTokVal.seTokContinue:", around line 1911,
change this code:
it = this.gotoTrack.labels[x].loop;
if ( it == null )
to:
it = this.gotoTrack.labels[x].loop;
if ( it == null || (it.is_switch && !isbreak) )
- Floating
point numbers not written correctly in jseCreateCodeTokenBuffer
(for ISDK/Java 4.30d)
Problem:
When creating tokens with jseCreateCodeTokenBuffer,
floating point numbers are written incorrectly.
Fix:
In Token.jsrc, function writeNumber(), at
line 248 change this line:
if ( (double)n == n )
to:
if ( (double)n32 = n )
- Floating
point numbers not read correctly when interpreting
from token buffer
(for ISDK/Java 4.30d)
Problem:
When interpreting from a precompiled token
buffer, floating point numbers will not be
read correctly.
Fix:
In Token.jsrc, function readNumber_fromNumber(),
at line 516 change this line:
return (double)val;
to:
return Double.longBitsToDouble(val);
- Scripts
interpreted from a token buffer may display
erratic behavior
(for ISDK/Java 4.30d)
Problem:
When interpreting from a token buffer, goto
labels may become all messed up.
Fix:
In Token.jsrc, function AbsoluteGotoFromRelative(),
at line 464 change this line:
for ( c = 0; 0 != opcodes[RelativeGoto--]; c++ )
to:
for ( c = 0; 0 != RelativeGoto--; c++ )
- Some
characters not read correctly when interpreting
from a token buffer
(for ISDK/Java 4.30d)
Problem:
When interpreting from a token buffer, some
characters may be read back incorrectly.
Fix:
In Token.jsrc, function readString(), at line
556 change this block of code:
for ( i = 0; i < len; i++ )
{
char c;
c = (char)(readByte() | (readByte()<<8));
str.append( c );
}
to:
for ( i = 0; i < len; i++ )
{
char c;
byte b1 = readByte();
byte b2 = readByte();
byte[] tmp = { b1, b2 };
c = new String(tmp,0,2).charAt(0);
str.append( c );
}
for
4.30a --
- Continue
statement in do/while skips while
(for ISDK/Java 4.30a)
Problem:
continue used in a do/while loop not doing
the while condition test, always going to
top of loop
Fix:
In srccore/Secode.java function Do(), at the
top of the function (about line 2028 ) add
this new local variable:
int cont_addr;
In the middle of the function, right before
this existing line (line 2051):
addItem( seCodeVal.seContinueFunc, prevLineNumber );
add:
cont_addr = currentItem();
finally, at the bottom of the function, change
this line (line 2068):
endLoop( currentItem(), top_of_loop, label );
to:
endLoop( currentItem(), cont_addr, label );
- Variables
not being popped off of the stack properly
(for ISDK/Java 4.30a)
Problem:
When compiling functions, some variables were
not being popped off of the stack properly.
Fix:
In srccore/Secode.java, function function()
around line 2815, find the following code:
/* Create a constant for it. */
newfunc = new LocalFunction( call, name, cfunction, var );
i = locfunc.createConstant( call, var );
if ( !literal )
{
j = locfunc.addLocal( call, name );
locfunc.VarFunc[j] = i;
}
call.STACK_POP();
and remove the call to STACK_POP(); At the
end of the same function, find the following
code (around line 2890):
return success;
and replace it with:
call.STACK_POP();
return success;
- Error
when subtracting C-Strings
(for ISDK/Java 4.30a)
Problem:
A NullPointer Exception occurs when subtracting
C-strings
Fix:
In srccore/Secode.java in the case statement
for seCodeVal.seSubtract (around line 5785),
change this line:
if ( lhs2.GET_OBJECT() != rhs.GET_OBJECT() )
to:
if ( lhs2.GET_STRING() != rhs.GET_STRING() )
- jseSetSharedData()
not adding data correctly
(for ISDK/Java 4.30a)
Problem:
After the first call to jseSetSharedData(),
subsequent calls write over previous data.
Fix:
In srccore/Call.java in jseSetSharedData,
find the following section of code (around
line 5349):
newNode = new sharedDataNode();
newNode.next = Global.sharedDataList;
newNode = new sharedDataNode();
and remove the second call to sharedDataNode's
constructor.
- NullPointer
exception when using jseCallStackInfo()
(for ISDK/Java 4.30a)
Problem:
A NullPointer exception is thrown when using
jseCallStackInfo()
Fix:
In srccore/Call.java function jseCallStackInfo()
(around line 5140), find the following line:
num_args = Global.stack[fptr - ARGS_OFFSET].GET_STORAGE_LONG();
and replace it with this line:
nargs = Global.stack[fptr - ARGS_OFFSET].GET_STORAGE_LONG();
- Error
when moving backwards in C-string
(for ISDK/Java 4.30a)
Problem:
An ArrayIndexOutOfBounds Exception is thrown
when attempting to move back in a C-string
Fix:
In srccore/seVar.java there is a function
getValue with the following signture: final
boolean getValue( Call call, int mem, seVar
dest ). Near the end of this function, find
this section of code (around line 990):
String data = getData( call );
/* will go back, but we've verified there is enough stuff to read from */
INIT_NUMBER(dest, (double)data.charAt( loc ) );
change this section to this:
int off = getDataOffset( call );
seString data = GET_STRING();
INIT_NUMBER(dest, (double)data.data.charAt( off+loc ) );
You
will also have to add the function getDataOffset
to the seVar class. The source can be found
at ftp://ftp.nombas.com/pub/isdkeval/se430/dataOffset.txt.
|