1. IdFunction.methodId is no longer public as some old Java compilers have troubles with it and accessor method has to be used instead.

2. IdFunction constructor now takes scope argument as well to prevent initialization bugs.
This commit is contained in:
igor%mir2.org 2004-06-09 12:54:04 +00:00
Родитель 0c1a037f66
Коммит a8ca02b455
20 изменённых файлов: 115 добавлений и 137 удалений

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

@ -159,7 +159,8 @@ public class BaseFunction extends IdScriptable implements Function {
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
int methodId = f.methodId();
switch (methodId) {
case Id_constructor:
return jsConstructor(cx, scope, args);
@ -186,7 +187,7 @@ public class BaseFunction extends IdScriptable implements Function {
case Id_apply:
case Id_call:
return applyOrCall(f.methodId == Id_apply, cx, scope,
return applyOrCall(methodId == Id_apply, cx, scope,
thisObj, args);
}
}

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

@ -40,13 +40,14 @@ package org.mozilla.javascript;
public class IdFunction extends BaseFunction
{
public IdFunction(IdFunctionMaster master, Object tag, int id,
String name, int arity)
String name, int arity, Scriptable scope)
{
this.functionName = name;
this.master = master;
this.tag = tag;
this.methodId = id;
this.arity = arity;
setParentScope(scope);
}
public final boolean hasTag(Object tag)
@ -54,27 +55,27 @@ public class IdFunction extends BaseFunction
return this.tag == tag;
}
public final int getMethodId()
public final int methodId()
{
return methodId;
}
public final void enableConstructorUsage()
public final void markAsConstructor(Scriptable prototypeProperty)
{
useCallAsConstructor = true;
setImmunePrototypeProperty(prototypeProperty);
}
public final void defineAsScopeProperty(Scriptable scope, boolean seal)
public final void exportAsScopeProperty(boolean seal)
{
defineAsScopeProperty(scope, ScriptableObject.DONTENUM, seal);
exportAsScopeProperty(ScriptableObject.DONTENUM, seal);
}
public void defineAsScopeProperty(Scriptable scope, int attributes,
boolean seal)
public void exportAsScopeProperty(int attributes, boolean seal)
{
setParentScope(scope);
if (seal) { sealObject(); }
ScriptableObject.defineProperty(scope, functionName, this, attributes);
ScriptableObject.defineProperty(getParentScope(), functionName, this,
attributes);
}
public Scriptable getPrototype()
@ -137,17 +138,6 @@ public class IdFunction extends BaseFunction
public int getLength() { return getArity(); }
/** Prepare to be used as constructor .
** @param scope constructor scope
** @param prototype DontEnum, DontDelete, ReadOnly prototype property
** of the constructor */
public void initAsConstructor(Scriptable scope, Scriptable prototype)
{
useCallAsConstructor = true;
setParentScope(scope);
setImmunePrototypeProperty(prototype);
}
public final RuntimeException unknown()
{
// It is program error to call id-like methods for unknown or
@ -157,7 +147,7 @@ public class IdFunction extends BaseFunction
private final IdFunctionMaster master;
private final Object tag;
public final int methodId;
private final int methodId;
private int arity;
private boolean useCallAsConstructor;
}

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

@ -318,8 +318,7 @@ public abstract class IdScriptable extends ScriptableObject
*/
protected Object getIdValue(int id)
{
IdFunction f = newIdFunction(id);
f.setParentScope(getParentScope());
IdFunction f = newIdFunction(id, getParentScope());
return cacheIdValue(id, f);
}
@ -431,21 +430,12 @@ public abstract class IdScriptable extends ScriptableObject
setPrototype(getObjectPrototype(scope));
}
String name = getClassName();
IdFunction ctor = newIdFunction(name, constructorId);
ctor.initAsConstructor(scope, this);
IdFunction ctor = newIdFunction(getClassName(), constructorId, scope);
ctor.markAsConstructor(this);
fillConstructorProperties(cx, ctor, sealed);
if (sealed) {
ctor.sealObject();
}
cacheIdValue(constructorId, ctor);
if (sealed) {
sealObject();
}
defineProperty(scope, name, ctor, ScriptableObject.DONTENUM);
ctor.exportAsScopeProperty(sealed);
}
protected void fillConstructorProperties
@ -456,8 +446,7 @@ public abstract class IdScriptable extends ScriptableObject
protected void addIdFunctionProperty
(Scriptable obj, int id, boolean sealed)
{
IdFunction f = newIdFunction(id);
f.setParentScope(getParentScope());
IdFunction f = newIdFunction(id, getParentScope());
if (sealed) { f.sealObject(); }
defineProperty(obj, getIdName(id), f, DONTENUM);
}
@ -487,14 +476,15 @@ public abstract class IdScriptable extends ScriptableObject
f.getFunctionName());
}
protected IdFunction newIdFunction(int id)
protected IdFunction newIdFunction(int id, Scriptable scope)
{
return newIdFunction(getIdName(id), id);
return newIdFunction(getIdName(id), id, scope);
}
protected IdFunction newIdFunction(String name, int id)
protected IdFunction newIdFunction(String name, int id, Scriptable scope)
{
IdFunction f = new IdFunction(this, null, id, name, methodArity(id));
IdFunction f = new IdFunction(this, null, id, name, methodArity(id),
scope);
if (isSealed()) { f.sealObject(); }
return f;
}

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

@ -227,10 +227,10 @@ public class ImporterTopLevel extends IdScriptable
}
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor:
return js_construct(scope, args);

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

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

@ -168,17 +168,17 @@ public final class JavaAdapter implements IdFunctionMaster
public static void init(Context cx, Scriptable scope, boolean sealed)
{
JavaAdapter obj = new JavaAdapter();
IdFunction f = new IdFunction(obj, FTAG, Id_JavaAdapter,
"JavaAdapter", 1);
f.enableConstructorUsage();
f.defineAsScopeProperty(scope, sealed);
IdFunction ctor = new IdFunction(obj, FTAG, Id_JavaAdapter,
"JavaAdapter", 1, scope);
ctor.markAsConstructor(null);
ctor.exportAsScopeProperty(sealed);
}
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (f.hasTag(FTAG)) {
if (f.methodId == Id_JavaAdapter) {
if (f.methodId() == Id_JavaAdapter) {
return js_createAdpter(cx, scope, args);
}
}

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

@ -129,7 +129,7 @@ public class NativeArray extends IdScriptable {
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor:
return jsConstructor(cx, scope, args, f, thisObj == null);

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

@ -70,7 +70,7 @@ final class NativeBoolean extends IdScriptable {
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor: {
boolean b = ScriptRuntime.toBoolean(args, 0);
if (thisObj == null) {

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

@ -150,7 +150,7 @@ final class NativeCallPrototype extends IdScriptable
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (f.methodId == Id_constructor) {
if (f.methodId() == Id_constructor) {
if (thisObj != null) {
throw Context.reportRuntimeError1("msg.only.from.new", "Call");
}

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

@ -101,7 +101,7 @@ final class NativeDate extends IdScriptable
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
int methodId = f.methodId;
int methodId = f.methodId();
switch (methodId) {
case ConstructorId_now:
return wrap_double(now());

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

@ -85,7 +85,7 @@ final class NativeError extends IdScriptable
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor:
return make(cx, scope, f, args);

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

@ -99,8 +99,8 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
default:
throw Kit.codeBug();
}
IdFunction f = new IdFunction(obj, FTAG, id, name, arity);
f.defineAsScopeProperty(scope, sealed);
IdFunction f = new IdFunction(obj, FTAG, id, name, arity, scope);
f.exportAsScopeProperty(sealed);
}
ScriptableObject.defineProperty(scope, "NaN",
@ -135,18 +135,15 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
newObject(cx, scope, "Error",
ScriptRuntime.emptyArgs);
errorProto.put("name", errorProto, name);
IdFunction ctor = new IdFunction(obj, FTAG, Id_new_CommonError,
name, 1);
ctor.initAsConstructor(scope, errorProto);
if (sealed) {
ctor.sealObject();
if (errorProto instanceof ScriptableObject) {
((ScriptableObject)errorProto).sealObject();
}
}
ScriptableObject.defineProperty(scope, name, ctor,
ScriptableObject.DONTENUM);
IdFunction ctor = new IdFunction(obj, FTAG, Id_new_CommonError,
name, 1, scope);
ctor.markAsConstructor(errorProto);
ctor.exportAsScopeProperty(sealed);
}
}
@ -154,17 +151,18 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
Scriptable thisObj, Object[] args)
{
if (f.hasTag(FTAG)) {
switch (f.methodId) {
int methodId = f.methodId();
switch (methodId) {
case Id_decodeURI:
case Id_decodeURIComponent: {
String str = ScriptRuntime.toString(args, 0);
return decode(cx, str, f.methodId == Id_decodeURI);
return decode(cx, str, methodId == Id_decodeURI);
}
case Id_encodeURI:
case Id_encodeURIComponent: {
String str = ScriptRuntime.toString(args, 0);
return encode(cx, str, f.methodId == Id_encodeURI);
return encode(cx, str, methodId == Id_encodeURI);
}
case Id_escape:
@ -475,7 +473,7 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
{
if (functionObj instanceof IdFunction) {
IdFunction function = (IdFunction)functionObj;
if (function.hasTag(FTAG) && function.methodId == Id_eval) {
if (function.hasTag(FTAG) && function.methodId() == Id_eval) {
return true;
}
}

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

@ -118,7 +118,7 @@ public class NativeJavaTopPackage
// getClass implementation
IdFunction getClass = new IdFunction(top, FTAG, Id_getClass,
"getClass", 1);
"getClass", 1, scope);
// We want to get a real alias, and not a distinct JavaPackage
// with the same packageName, so that we share classes and top
@ -129,7 +129,7 @@ public class NativeJavaTopPackage
// a ScriptableObject.
ScriptableObject global = (ScriptableObject) scope;
getClass.defineAsScopeProperty(global, sealed);
getClass.exportAsScopeProperty(sealed);
global.defineProperty("Packages", top, ScriptableObject.DONTENUM);
global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM);
}
@ -138,7 +138,7 @@ public class NativeJavaTopPackage
Scriptable thisObj, Object[] args)
{
if (f.hasTag(FTAG)) {
if (f.methodId == Id_getClass) {
if (f.methodId() == Id_getClass) {
return js_getClass(cx, scope, args);
}
}

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

@ -88,7 +88,8 @@ final class NativeMath extends IdScriptable
Scriptable thisObj, Object[] args)
{
double x;
switch (f.methodId) {
int methodId = f.methodId();
switch (methodId) {
case Id_toSource:
return "Math";
@ -102,7 +103,7 @@ final class NativeMath extends IdScriptable
case Id_asin:
x = ScriptRuntime.toNumber(args, 0);
if (x == x && -1.0 <= x && x <= 1.0) {
x = (f.methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
x = (methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
} else {
x = Double.NaN;
}
@ -150,7 +151,7 @@ final class NativeMath extends IdScriptable
case Id_max:
case Id_min:
x = (f.methodId == Id_max)
x = (methodId == Id_max)
? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
for (int i = 0; i != args.length; ++i) {
double d = ScriptRuntime.toNumber(args[i]);
@ -158,7 +159,7 @@ final class NativeMath extends IdScriptable
x = d; // NaN
break;
}
if (f.methodId == Id_max) {
if (methodId == Id_max) {
// if (x < d) x = d; does not work due to -0.0 >= +0.0
x = Math.max(x, d);
} else {

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

@ -90,7 +90,7 @@ final class NativeNumber extends IdScriptable {
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor: {
double val = (args.length >= 1)
? ScriptRuntime.toNumber(args[0]) : 0.0;

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

@ -75,7 +75,7 @@ final class NativeObjectPrototype extends NativeObject
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
switch (f.methodId) {
switch (f.methodId()) {
case Id_constructor: {
if (thisObj != null) {
// BaseFunction.construct will set up parent, proto

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

@ -130,7 +130,7 @@ class NativeScript extends NativeFunction implements Script
Scriptable thisObj, Object[] args)
{
if (0 <= prototypeIdShift) {
switch (f.methodId - prototypeIdShift) {
switch (f.methodId() - prototypeIdShift) {
case Id_constructor: {
String source = (args.length == 0)
? ""

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

@ -88,55 +88,12 @@ final class NativeString extends IdScriptable {
return super.getIdValue(id);
}
protected int methodArity(int methodId)
{
if (prototypeFlag) {
switch (methodId) {
case ConstructorId_fromCharCode: return 1;
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toSource: return 0;
case Id_valueOf: return 0;
case Id_charAt: return 1;
case Id_charCodeAt: return 1;
case Id_indexOf: return 1;
case Id_lastIndexOf: return 1;
case Id_split: return 2;
case Id_substring: return 2;
case Id_toLowerCase: return 0;
case Id_toUpperCase: return 0;
case Id_substr: return 2;
case Id_concat: return 1;
case Id_slice: return 2;
case Id_bold: return 0;
case Id_italics: return 0;
case Id_fixed: return 0;
case Id_strike: return 0;
case Id_small: return 0;
case Id_big: return 0;
case Id_blink: return 0;
case Id_sup: return 0;
case Id_sub: return 0;
case Id_fontsize: return 0;
case Id_fontcolor: return 0;
case Id_link: return 0;
case Id_anchor: return 0;
case Id_equals: return 1;
case Id_equalsIgnoreCase: return 1;
case Id_match: return 1;
case Id_search: return 1;
case Id_replace: return 1;
}
}
return super.methodArity(methodId);
}
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
int methodId = f.methodId();
switch (methodId) {
case ConstructorId_fromCharCode: {
int N = args.length;
if (N < 1)
@ -176,11 +133,11 @@ final class NativeString extends IdScriptable {
String target = ScriptRuntime.toString(thisObj);
double pos = ScriptRuntime.toInteger(args, 0);
if (pos < 0 || pos >= target.length()) {
if (f.methodId == Id_charAt) return "";
if (methodId == Id_charAt) return "";
else return ScriptRuntime.NaNobj;
}
char c = target.charAt((int)pos);
if (f.methodId == Id_charAt) return String.valueOf(c);
if (methodId == Id_charAt) return String.valueOf(c);
else return wrap_int(c);
}
@ -260,7 +217,7 @@ final class NativeString extends IdScriptable {
case Id_equalsIgnoreCase: {
String s1 = ScriptRuntime.toString(thisObj);
String s2 = ScriptRuntime.toString(args, 0);
return wrap_boolean(f.methodId == Id_equals
return wrap_boolean(methodId == Id_equals
? s1.equals(s2) : s1.equalsIgnoreCase(s2));
}
@ -771,6 +728,50 @@ final class NativeString extends IdScriptable {
return null;
}
protected int methodArity(int methodId)
{
if (prototypeFlag) {
switch (methodId) {
case ConstructorId_fromCharCode: return 1;
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toSource: return 0;
case Id_valueOf: return 0;
case Id_charAt: return 1;
case Id_charCodeAt: return 1;
case Id_indexOf: return 1;
case Id_lastIndexOf: return 1;
case Id_split: return 2;
case Id_substring: return 2;
case Id_toLowerCase: return 0;
case Id_toUpperCase: return 0;
case Id_substr: return 2;
case Id_concat: return 1;
case Id_slice: return 2;
case Id_bold: return 0;
case Id_italics: return 0;
case Id_fixed: return 0;
case Id_strike: return 0;
case Id_small: return 0;
case Id_big: return 0;
case Id_blink: return 0;
case Id_sup: return 0;
case Id_sub: return 0;
case Id_fontsize: return 0;
case Id_fontcolor: return 0;
case Id_link: return 0;
case Id_anchor: return 0;
case Id_equals: return 1;
case Id_equalsIgnoreCase: return 1;
case Id_match: return 1;
case Id_search: return 1;
case Id_replace: return 1;
}
}
return super.methodArity(methodId);
}
private static final int
ConstructorId_fromCharCode = -1,
Id_length = 1,

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

@ -49,16 +49,13 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
NativeWith obj = new NativeWith();
obj.prototypeFlag = true;
IdFunction ctor = new IdFunction(obj, FTAG, Id_constructor,
"constructor", 0);
ctor.initAsConstructor(scope, obj);
if (sealed) { ctor.sealObject(); }
obj.setParentScope(ctor);
obj.setParentScope(scope);
obj.setPrototype(ScriptableObject.getObjectPrototype(scope));
ScriptableObject.defineProperty(scope, "With", ctor,
ScriptableObject.DONTENUM);
IdFunction ctor = new IdFunction(obj, FTAG, Id_constructor,
"With", 0, scope);
ctor.markAsConstructor(obj);
ctor.exportAsScopeProperty(sealed);
}
private NativeWith() {
@ -149,7 +146,7 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
Scriptable thisObj, Object[] args)
{
if (f.hasTag(FTAG)) {
if (f.methodId == Id_constructor) {
if (f.methodId() == Id_constructor) {
throw Context.reportRuntimeError1("msg.cant.call.indirect", "With");
}
}
@ -160,7 +157,7 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
{
if (functionObj instanceof IdFunction) {
IdFunction f = (IdFunction)functionObj;
return f.hasTag(FTAG) && f.methodId == Id_constructor;
return f.hasTag(FTAG) && f.methodId() == Id_constructor;
}
return false;
}

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

@ -2625,7 +2625,7 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
switch (f.methodId()) {
case Id_compile:
return realThis(thisObj, f).compile(cx, scope, args);