1. In that patch I forgot to remove "import org.mozilla.classfile.*" and
simply catch Exception in newInvokerMaster which is not a good practice.
The attached patch FunctionObject_patch fixes that and removes other
unused imports.
2. In org.mozilla.classfile.DefiningClassLoader defineClass method first
tries to call via ClassManager the defineClass method in a class loader
that loaded DefiningClassLoader itself. But this would define new
classes in that class loader so they would not be subject of the garbage
collection until a classloader that loads DefiningClassLoader would go
away even if a DefiningClassLoader instance is gone. The
DefiningClassLoader_patch removes that and simply calls super.defineClass.
The patch also change the order of class search in loadClass so the
loader first looks for a class among its defined classes and only after
that in parent loaders.
Regards, Igor
1. In that patch I forgot to remove "import org.mozilla.classfile.*" and
simply catch Exception in newInvokerMaster which is not a good practice.
The attached patch FunctionObject_patch fixes that and removes other
unused imports.
2. In org.mozilla.classfile.DefiningClassLoader defineClass method first
tries to call via ClassManager the defineClass method in a class loader
that loaded DefiningClassLoader itself. But this would define new
classes in that class loader so they would not be subject of the garbage
collection until a classloader that loads DefiningClassLoader would go
away even if a DefiningClassLoader instance is gone. The
DefiningClassLoader_patch removes that and simply calls super.defineClass.
The patch also change the order of class search in loadClass so the
loader first looks for a class among its defined classes and only after
that in parent loaders.
Regards, Igor
> Igor Bukanov wrote:
>
>
>>Norris Boyd wrote:
>>
>>
>>>The intention was to keep classfile and JavaAdapter optional. Those
>>>dependencies crept in. We can use Invoker optionally--perhaps I should do
>>>some performance numbers to see if it's worth it.
>>>
>>I implemented that patch, it splits Invoker.java into Invoker.java and
>>its implementation in optimizer/InvokerImpl.java The reason to put it
>>into optimizer package is that Invoker is very similar in spirit to
>>NativeScript: it generates classes to speed up access and in this way
>>there is no need to have separated option not to use: one can simply
>>remove optimizer all together.
>>
>
> Yes, that sounds great.
>
>
>>
>>I noticed during implementation that JavaAdapter.DefiningClassLoader and
>>optimizer/JavaScriptClassLoader contains the same code, so maybe they
>>can be moved to org.mozilla.classfile package under one name?
>>
>
> Yes, that sounds like a good change too. Thanks for noticing that.
The update is pretty messy: it touches FunctionObject which I changed to
remove the special treatment of NativeWith in the previous patch, and it
also add/removes files.
Here is a description:
DefiningClassLoader.java should go to org/mozilla/classfile. It is the
same code that was in omj/optimizer/JavaScriptClassLoader.java with
class rename and adding public attribute and correspondingly
omj.optimizer/JavaScriptClassLoader.java should be removed. I guess it
would be nice to preserve logs/history in CVS during the move.
InvokerImpl.java should go to omj/optimizer. It is mostly what
omj.Invoker was.
invoker_changes_patch was generated via
cvs diff -u Invoker.java JavaAdapter.java optimizer/Codegen.java
and contains changes against the current CVS
FunctionObject_invoker_patch was generated via
diff -u ../../mozilla.1/javascript/FunctionObject.java FunctionObject.java
and contains changes against that With patch.
Igor
constructor, removes the special treatment of the With object from
IdScriptable and FunctionObject, adds to IdFunction the
initAsConstructor method similar in spirit to
FunctionObject.addAsConstructor (it is called now from IdScriptable and
NativeWith) and replaces in Context.java lazy initialization of
NativeWith by direct call of NativeWith.scopeInit.
The attached patch moves the IdFunction.Master interface to the
separated file IdFunctionMaster and eliminates getParentScope from the
interface: it is simpler to set scope explicitly.
The patch assumes the changes in IdFunction.java from the previous patch
and were produced via:
diff -uP javascript.2000-05-10 javascript
Regards, Igor
The attached patch allows subclasses of IdScriptable to override
hasIdValur/deleteIdValue and uses lazy initialization for idMapData
array to avoid its creation when an IdScriptable descendant does not
have any functions. The patch also touches NativeMath.java to replace in
its scopeInit method
super.scopeInit(cx, scope, sealed);
by
activateIdMap(cx, sealed);
This is the only reason NativeMath needs to call
IdScriptable.scopeInit() which is intended for creation
constructor/prototype pair.
Regards, Igor
Rhino: optimization for NativeFunction.java
Date:
Mon, 07 May 2001 14:19:59 +0200
From:
Igor Bukanov <igor.bukanov@windriver.com>
Organization:
Wind River
To:
Norris Boyd <nboyd@atg.com>
Hi, Norris!
This is the first of 3 patches that are completly independent from each
other.
Currently in NativeFunction its name stored as the first element in the
names array. But this lead to creation of a single element array for
each FunctionObject and for each script function that does not have
arguments or variables. The attached patch splits NativeFunction names
into simple functionName and argNames arrays and adjust code elsewhere
accordingly. This patch can increase memory footprint for anonymous
script functions without arguments because it adds additional field to
each NativeFunction, but I do not think this is a case to worry about.
Regards, Igor
Date: Mon, 07 May 2001 14:25:34 +0200
From: Igor Bukanov <igor.bukanov@windriver.com>
Organization: Wind River
To: Norris Boyd <nboyd@atg.com>
The current code that implements execMethod/methodArity for IdFunction
support returns an arbitrary value for id that is not known. This is not
very good behavior because it may hide bugs in the id support and it
also does not allow to distinguish ids that are used for function from
ids used for properties like String.length.
To fix this I changed semantic of the methodArity method to return -1
for an unknown/non-method id and added code to throw an exception for
bad ids. This change requires to adjust all NativeSomething objects that
use IdScriptabl and after a release all such interface changes would be
no go, but is not a release yet, right?
I also eliminated the "IdFunction f" argument from
IdFunction.Master.methodArity and the tagId field from IdFunction. When
I wrote the initial code for IdFunction.java, I added that just to be
able to use same id number in a class that implements IdFunction.Master
and its descendants via checking idTag. But that does not work in
general because IdScriptable can use id for non-function fields as well
so to avoid id clashes another way should be used. For example, if
someone would like to extend NativeMath to support more functionality,
he can use:
class Math2: extends NativeMath {
private static idBase;
{
if (idBase == 0) idBase = super.getMaximumId();
}
public int methodArity(int methodId) {
switch (methodId - idBase) {
case Id_foo: return 2;
case Id_bar: return 3;
}
return super.methodArity(methodId);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
{
switch (methodId - idBase) {
case Id_foo: return ...;
case Id_bar: return ...;
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
}
protected int getMaximumId() { return idBase + MAX_ID; }
protected String getIdName(int id) {
switch (id - idBase) {
case Id_foo: return "for";
case Id_bar: return "bar";
}
return super.getIdName(id);
}
...
private static final int
Id_foo = 1,
Id_bar = 2,
MAX_ID = 2;
etc.
Note that a simpler solution to make MAX_ID field public in NativeMath
and write in Math2:
private static final int
Id_foo = NativeMath.MAX_ID + 1,
Id_bar = NativeMath.MAX_ID + 2,
MAX_ID = NativeMath.MAX_ID + 2;
does not work because in this way adding any new id to NativeMath would
break binary compatibility with Math2.
Rhino: fix for race conditions in listeners code in Context.java
Date:
Mon, 07 May 2001 14:22:57 +0200
From:
Igor Bukanov <igor.bukanov@windriver.com>
Organization:
Wind River
To:
Norris Boyd <nboyd@atg.com>
The current code for listeners and contextListeners in Context.java is
not race condition free. If contextListeners Vector would be modified
during context event firing loops, the code can produce
index-out-of-bounds exception. The problem with listeners array is more
subbtle and comes from the fact that ListenerCollection.java uses code like:
for(Enumeration enum = getAllListeners();enum.hasMoreElements();) {
Object listener = enum.nextElement();
if(iface.isInstance(listener)) {
array.addElement(listener);
}
}
where getAllListeners() uses Vector.elements to get element enumeration.
But to work with such enumeration in a thread safe way, one has to
synchronized against Vector, otherwise between enum.hasMoreElements()
and enum.nextElement() the last element can be removed.
Initially I thought to fix ListenerCollection and use it for
contextListeners as well, but then I realized that in its current form
ListenerCollection is very inefficient (it produces too many objects
just to get simple array to fire events), so I wrote ListenerArray.java
and use it in Context.java. It makes life simpler and shrinks code as well.
js_SetProtoOrParent should always have used a condvar in addition to a lock.
- Fix bug 79129, assert-botch in js_AllocSlot (r/sr=jband, sr=shaver)
JS_INITIAL_NSLOTS is the minimum number of slots, js_FreeSlot guarantees it.
Subject:
rhino bug(s)
Date:
Mon, 30 Apr 2001 23:07:00 -0700
From:
Mike Dixon <MDixon@placeware.com>
To:
nboyd@atg.com
hi. i'm a happy rhino user, and just stumbled across what looks like a
pretty basic bug in the property stuff on ScriptableObject... (i'm running
1.5, but it looks like this code hasn't changed in CVS.) since it looks
like you're actively developing (even though it's been a while since
1.5...) i figured you might be interested -- apologies if i missed a more
formal bug reporting process...
the symptom was that i got a "Hashtable internal error" thrown from
getSlotToSet. reading the code, here's what i think could happen:
- create a new object (slots.length is initially 5)
- add 3 properties
- delete those 3 properties
(now count == 0, and slots[i] == REMOVED for 3 values of i)
- add 2 more properties
now assume that you're unlucky, and that these two hash to different values
than the first three; now you have 2 elements of slots[] containing real
slots, and the other three containing REMOVED.
now what happens when you try to create another slot? getSlotToSet is only
willing to put something in a null slot[], and you haven't got one, so you
get the internal error.
writing this message encouraged me to try to write a test case to reproduce
it, and in fact it's trivial:
js> x={}; x.a=x.b=x.c=1; delete x.a; delete x.b; delete x.c; x.d=x.e=1
1
js> x.whatever=1
(boom)
by the way, while reading the code i also noticed what looks like another,
less consequential bug: addSlot increments count before deciding to grow
the table, which is done with a recursive call, which will cause count to
be incremented again -- right? as far as i can tell, setting count too big
will only cause it to grow the table a little early next time, so it
doesn't really matter, but it looks wrong.
.mike.
remove jsdIContext and jsdIThreadstate interfaces
add TYPE_BOOLEAN to jsdIValue
update callback signatures to reflect the removal of jsdIContext and jsdIThreadstate
add errorHook and throwHook attributes to jsdIDebuggerService
remove jsdThreadState and jsdContext objects.
consolidate ExecutionHook and BreakpointHook callbacks
remove return value checking from all methods (xpconnect does this for us.)
validate integrity of jsdScript data to guard against calling into a destroyed script.
queue up script deletes that happen during the JS GC cycle, call them when GC finishes (bug 76979.)
don't NS_IF_ADDREF objects that we get using *::FromPtr()
add jsdScript::Invalidate()
move from pc as a ulong to pc as an object wrapped around a uword (jsdIPC)
rename init() to on() on jsdIService
move lineToPc and pcToLine from jsdIThreadState to jsdIScript (where they belong)
add setBreakpoint(), clearBreakpoint(), and clearAllBreakpoints() to jsdIScript
add off(), clearAllBreakpoints(), and breakpointHook attribute to jsdIService
add creatorURL, creatorLine, constructorURL, constructorLine, and value attribut
es to jsdIObject
move from pc as a ulong to pc as an object wrapped around a uword
relocate jsdService constructor to jsd_xpp.cpp in order to initialize the global
service
add global service for the breakpoint callback
add breakpoint callback
move c callbacks to top of source
add creatorURL, creatorLine, constructorURL, constructorLine, and value attribut
es to jsdObject
move from pc as a ulong to pc as an object wrapped around a uword
move lineToPc and pcToLine from ThreadState to Script (where it belongs)
add setBreakpoint(), clearBreakpoint(), and clearAllBreakpoints() to jsdScript
relocate jsdService constructor from jsd_xpp.h in order to initialize the global
service
rename init() to on() on jsdService
add off(), clearAllBreakpoints(), and breakpointHook attribute to jsdService
patch from peterv. We can't use js_* in this module because they're libjs' private stash. I got away with it on Linux somehow, but not on mac, and probably not on windows. jsd_EvaluateScriptInStackFrame now uses JS_EvaluateInStackFrame, instead of doing the inflation itself and calling JS_EvaluateUCInStackFrame.
mozilla/js/rhino/org is now distributed between
mozilla/js/rhino/src and mozilla/js/rhino/toolsrc.
The build.xml has been split in three.
Docs now live in the project directory.
These changes mean that the cvs directories mirror the distribution and thus a distribution
will build the same way as a cvs build.
15.3.4.2 Function.prototype.toString ( )
An implementation-dependent representation of the function is returned. This representation has the syntax of a
FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons
within the representation string is implementation-dependent.
add line attribute to jsdIStackFrame
remove isFuction from jsdIValue
add TYPE_UNKNOWN to jsType "enumeration" so we don't fail hard if we can't figure out the type.
add hook type "enumeration" to jsdIExecutionHook
add line attribute to jsdStackFrame
add pcToLine and lineToPc methods to jsdStackFrame
remove isFunction attribute from jsdValue (already covered by jsType attribute)
add propertyCount attribute to jsdValue so you can get the property cound without forcing a bunch of property wrappers to be created (as in GetProperties())
basic methods for jsdIObject and jsdIProperty
tweak string params
most methods for jsdIScript jsdIStackFrame, jsdIThreadState, and jsdIValue
add hack methods enterNestedEventLoop and exitNestedEventLoop. These should be moved to another interface before long.