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
This commit is contained in:
nboyd%atg.com 2001-05-16 00:24:37 +00:00
Родитель 227f854124
Коммит 937f24e4f6
14 изменённых файлов: 114 добавлений и 116 удалений

Просмотреть файл

@ -636,7 +636,7 @@ public class Context {
if (scope == null)
scope = new NativeObject();
ScriptableObject.defineClass(scope, NativeFunction.class, sealed);
(new NativeObject()).scopeInit(this, scope, sealed);
NativeObject.init(this, scope, sealed);
Scriptable objectProto = ScriptableObject.
getObjectPrototype(scope);
@ -651,16 +651,16 @@ public class Context {
scope.setPrototype(objectProto);
// must precede NativeGlobal since it's needed therein
(new NativeError()).scopeInit(this, scope, sealed);
(new NativeGlobal()).scopeInit(this, scope, sealed);
NativeError.init(this, scope, sealed);
NativeGlobal.init(this, scope, sealed);
(new NativeArray()).scopeInit(this, scope, sealed);
(new NativeString()).scopeInit(this, scope, sealed);
(new NativeBoolean()).scopeInit(this, scope, sealed);
(new NativeNumber()).scopeInit(this, scope, sealed);
(new NativeDate()).scopeInit(this, scope, sealed);
(new NativeMath()).scopeInit(this, scope, sealed);
(new NativeWith()).scopeInit(this, scope, sealed);
NativeArray.init(this, scope, sealed);
NativeString.init(this, scope, sealed);
NativeBoolean.init(this, scope, sealed);
NativeNumber.init(this, scope, sealed);
NativeDate.init(this, scope, sealed);
NativeMath.init(this, scope, sealed);
NativeWith.init(this, scope, sealed);
String[] classes = { "NativeCall", "Call",
"regexp.NativeRegExp", "RegExp",

Просмотреть файл

@ -56,7 +56,7 @@ may override scopeInit or fillConstructorProperties methods.
*/
public abstract class IdScriptable extends ScriptableObject
implements IdFunctionMaster, ScopeInitializer
implements IdFunctionMaster
{
public boolean has(String name, Scriptable start) {
if (maxId != 0) {
@ -320,7 +320,7 @@ public abstract class IdScriptable extends ScriptableObject
** constructor with name getClassName in scope and makes its prototype
** property to point to this object.
*/
public void scopeInit(Context cx, Scriptable scope, boolean sealed) {
public void addAsPrototype(Context cx, Scriptable scope, boolean sealed) {
activateIdMap(cx, sealed);

Просмотреть файл

@ -61,6 +61,11 @@ public class NativeArray extends IdScriptable {
* always gets at least an object back, even when Array == null.
*/
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeArray obj = new NativeArray();
obj.addAsPrototype(cx, scope, sealed);
}
/**
* Zero-parameter constructor: just used to create Array.prototype
*/

Просмотреть файл

@ -44,6 +44,11 @@ package org.mozilla.javascript;
*/
public class NativeBoolean extends IdScriptable {
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeBoolean obj = new NativeBoolean();
obj.addAsPrototype(cx, scope, sealed);
}
/**
* Zero-parameter constructor: just used to create Boolean.prototype
*/

Просмотреть файл

@ -50,20 +50,7 @@ import java.text.SimpleDateFormat;
*/
public class NativeDate extends IdScriptable {
public String getClassName() {
return "Date";
}
public Object getDefaultValue(Class typeHint) {
if (typeHint == null)
typeHint = ScriptRuntime.StringClass;
return super.getDefaultValue(typeHint);
}
public void scopeInit(Context cx, Scriptable scope, boolean sealed) {
// Set the value of the prototype Date to NaN ('invalid date');
date = ScriptRuntime.NaN;
public static void init(Context cx, Scriptable scope, boolean sealed) {
if (thisTimeZone == null) {
// j.u.TimeZone is synchronized, so setting class statics from it
@ -72,7 +59,22 @@ public class NativeDate extends IdScriptable {
LocalTZA = thisTimeZone.getRawOffset();
}
super.scopeInit(cx, scope, sealed);
NativeDate obj = new NativeDate();
// Set the value of the prototype Date to NaN ('invalid date');
obj.date = ScriptRuntime.NaN;
obj.addAsPrototype(cx, scope, sealed);
}
public String getClassName() {
return "Date";
}
public Object getDefaultValue(Class typeHint) {
if (typeHint == null)
typeHint = ScriptRuntime.StringClass;
return super.getDefaultValue(typeHint);
}
protected void fillConstructorProperties

Просмотреть файл

@ -45,10 +45,11 @@ package org.mozilla.javascript;
*/
public class NativeError extends IdScriptable {
public void scopeInit(Context cx, Scriptable scope, boolean sealed) {
defineProperty("message", "", ScriptableObject.EMPTY);
defineProperty("name", "Error", ScriptableObject.EMPTY);
super.scopeInit(cx, scope, sealed);
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeError obj = new NativeError();
obj.defineProperty("message", "", ScriptableObject.EMPTY);
obj.defineProperty("name", "Error", ScriptableObject.EMPTY);
obj.addAsPrototype(cx, scope, sealed);
}
public int methodArity(int methodId) {

Просмотреть файл

@ -50,9 +50,13 @@ import java.lang.reflect.Method;
* @author Mike Shaver
*/
public class NativeGlobal implements ScopeInitializer, IdFunctionMaster {
public class NativeGlobal implements IdFunctionMaster {
public void scopeInit(Context cx, Scriptable scope, boolean sealed) {
public static void init(Context cx, Scriptable scope, boolean sealed) {
(new NativeGlobal()).scopeInit(cx, scope, sealed);
}
private void scopeInit(Context cx, Scriptable scope, boolean sealed) {
for (int id = 1; id <= MAX_ID; ++id) {
String name = getMethodName(id);

Просмотреть файл

@ -44,19 +44,18 @@ package org.mozilla.javascript;
public class NativeMath extends IdScriptable
{
public String getClassName() { return "Math"; }
public void scopeInit(Context cx, Scriptable scope, boolean sealed) {
activateIdMap(cx, sealed);
setPrototype(getObjectPrototype(scope));
setParentScope(scope);
if (sealed) {
sealObject();
}
ScriptableObject.defineProperty
(scope, "Math", this, ScriptableObject.DONTENUM);
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeMath obj = new NativeMath();
obj.activateIdMap(cx, sealed);
obj.setPrototype(getObjectPrototype(scope));
obj.setParentScope(scope);
if (sealed) { obj.sealObject(); }
ScriptableObject.defineProperty(scope, "Math", obj,
ScriptableObject.DONTENUM);
}
public String getClassName() { return "Math"; }
protected int getIdDefaultAttributes(int id) {
if (id > LAST_METHOD_ID) {
return DONTENUM | READONLY | PERMANENT;

Просмотреть файл

@ -48,6 +48,11 @@ public class NativeNumber extends IdScriptable {
private static final int MAX_PRECISION = 100;
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeNumber obj = new NativeNumber();
obj.addAsPrototype(cx, scope, sealed);
}
/**
* Zero-parameter constructor: just used to create Number.prototype
*/

Просмотреть файл

@ -45,6 +45,11 @@ import java.util.Hashtable;
*/
public class NativeObject extends IdScriptable {
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeObject obj = new NativeObject();
obj.addAsPrototype(cx, scope, sealed);
}
public String getClassName() {
return "Object";
}

Просмотреть файл

@ -54,6 +54,11 @@ import java.util.Vector;
*/
public class NativeString extends IdScriptable {
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeString obj = new NativeString();
obj.addAsPrototype(cx, scope, sealed);
}
/**
* Zero-parameter constructor: just used to create String.prototype
*/

Просмотреть файл

@ -43,9 +43,21 @@ import java.lang.reflect.Method;
* It simply delegates every action to its prototype except
* for operations on its parent.
*/
public class NativeWith
implements Scriptable, IdFunctionMaster, ScopeInitializer
public class NativeWith implements Scriptable, IdFunctionMaster
{
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeWith obj = new NativeWith();
IdFunction ctor = new IdFunction(obj, "constructor", Id_constructor);
ctor.initAsConstructor(scope, obj);
if (sealed) { ctor.sealObject(); }
obj.setParentScope(ctor);
obj.setPrototype(ScriptableObject.getObjectPrototype(scope));
ScriptableObject.defineProperty(scope, "With", obj,
ScriptableObject.DONTENUM);
}
public NativeWith() {
}

Просмотреть файл

@ -1,51 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript;
/**
* Indicate that implementation instance performs initializations for scope
*/
public interface ScopeInitializer {
/**
* Initialize scope.
* If sealed is true, seal any script object added to scope directly
* or as a property of some other object.
*/
public void scopeInit(Context cx, Scriptable scope, boolean sealed);
}

Просмотреть файл

@ -606,12 +606,12 @@ public abstract class ScriptableObject implements Scriptable {
/**
* Defines JavaScript objects from a Java class that implements Scriptable.
*
* If the given class implements the <code>ScopeInitializer</code>
* interface, then its instance is constructed and <code>scopeInit</code>
* is called upon it and no further initialization is done.
*
* If the given class has a method
* <pre>
* static void init(Context cx, Scriptable scope, boolean sealed);</pre>
*
* or its compatibility form
* <pre>
* static void init(Scriptable scope);</pre>
*
* then it is invoked and no further initialization is done.<p>
@ -740,26 +740,32 @@ public abstract class ScriptableObject implements Scriptable {
InvocationTargetException, ClassDefinitionException,
PropertyException
{
if (ScopeInitializerClass.isAssignableFrom(clazz)) {
ScopeInitializer setup = (ScopeInitializer)clazz.newInstance();
Context cx = Context.getContext();
setup.scopeInit(cx, scope, sealed);
return;
}
Method[] methods = FunctionObject.getMethodList(clazz);
for (int i=0; i < methods.length; i++) {
if (!methods[i].getName().equals("init"))
Method method = methods[i];
if (!method.getName().equals("init"))
continue;
Class[] parmTypes = methods[i].getParameterTypes();
if (parmTypes.length == 1 &&
parmTypes[0] == ScriptRuntime.ScriptableClass &&
Modifier.isStatic(methods[i].getModifiers()))
Class[] parmTypes = method.getParameterTypes();
if (parmTypes.length == 3 &&
parmTypes[0] == ContextClass &&
parmTypes[1] == ScriptRuntime.ScriptableClass &&
parmTypes[2] == Boolean.TYPE &&
Modifier.isStatic(method.getModifiers()))
{
Object args[] = { scope };
methods[i].invoke(null, args);
Object args[] = { Context.getContext(), scope,
sealed ? Boolean.TRUE : Boolean.FALSE };
method.invoke(null, args);
return;
}
if (parmTypes.length == 1 &&
parmTypes[0] == ScriptRuntime.ScriptableClass &&
Modifier.isStatic(method.getModifiers()))
{
Object args[] = { scope };
method.invoke(null, args);
return;
}
}
// If we got here, there isn't an "init" method with the right
@ -1797,5 +1803,5 @@ public abstract class ScriptableObject implements Scriptable {
boolean setterReturnsValue;
}
private static final Class ScopeInitializerClass = ScopeInitializer.class;
private static final Class ContextClass = Context.class;
}