зеркало из https://github.com/mozilla/gecko-dev.git
2 additional issues:
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:
Родитель
227f854124
Коммит
937f24e4f6
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче