Changin IdFunction/IdFunctionMaster iteraction:

1. execMethod and methodArity in IdFunctionMaster do not receive methodId explicitly but rather through the IdFunction instance. To ensure fastest access to method id it is made pubic final field.

2. IdFunction allows to associate an internal tag with itself that allows not to worry about id clashes and simply check for object tag before doing method dispatch.
This commit is contained in:
igor%mir2.org 2004-06-08 14:23:35 +00:00
parent 593684a98a
commit 8f28fc868a
18 changed files with 236 additions and 226 deletions

View File

@ -155,10 +155,10 @@ public class BaseFunction extends IdScriptable implements Function {
super.deleteIdValue(id);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 1;
case Id_toSource: return 1;
@ -166,16 +166,14 @@ public class BaseFunction extends IdScriptable implements Function {
case Id_call: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod(int methodId, IdFunction f, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor:
return jsConstructor(cx, scope, args);
@ -202,11 +200,11 @@ public class BaseFunction extends IdScriptable implements Function {
case Id_apply:
case Id_call:
return applyOrCall(methodId == Id_apply, cx, scope,
return applyOrCall(f.methodId == Id_apply, cx, scope,
thisObj, args);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private BaseFunction realFunction(Scriptable thisObj, IdFunction f)

View File

@ -42,10 +42,24 @@ public class IdFunction extends BaseFunction
public IdFunction(IdFunctionMaster master, String name, int id)
{
this.functionName = name;
this.tag = null;
this.master = master;
this.methodId = id;
}
public IdFunction(Object tag, IdFunctionMaster master, String name, int id)
{
this.tag = tag;
this.functionName = name;
this.master = master;
this.methodId = id;
}
public final boolean hasTag(Object tag)
{
return this.tag == tag;
}
public static void define(Scriptable scope, String name,
IdFunctionMaster master, int id)
{
@ -61,23 +75,32 @@ public class IdFunction extends BaseFunction
public static void define(Scriptable scope, String name,
IdFunctionMaster master, int id,
int attributes, boolean sealed)
int attributes, boolean seal)
{
IdFunction f = new IdFunction(master, name, id);
f.setParentScope(scope);
if (sealed) { f.sealObject(); }
ScriptableObject.defineProperty(scope, name, f, attributes);
f.defineAsScopeProperty(scope, attributes, seal);
}
public static void defineConstructor(Scriptable scope, String name,
IdFunctionMaster master, int id,
int attributes, boolean sealed)
int attributes, boolean seal)
{
IdFunction f = new IdFunction(master, name, id);
f.setParentScope(scope);
f.useCallAsConstructor = true;
if (sealed) { f.sealObject(); }
ScriptableObject.defineProperty(scope, name, f, attributes);
f.defineAsScopeProperty(scope, attributes, seal);
}
public final void defineAsScopeProperty(Scriptable scope, boolean seal)
{
defineAsScopeProperty(scope, ScriptableObject.DONTENUM, seal);
}
public void defineAsScopeProperty(Scriptable scope, int attributes,
boolean seal)
{
setParentScope(scope);
if (seal) { sealObject(); }
ScriptableObject.defineProperty(scope, functionName, this, attributes);
}
public final int getMethodId()
@ -101,7 +124,7 @@ public class IdFunction extends BaseFunction
Object[] args)
throws JavaScriptException
{
return master.execMethod(methodId, this, cx, scope, thisObj, args);
return master.execMethod(this, cx, scope, thisObj, args);
}
public Scriptable createObject(Context cx, Scriptable scope)
@ -140,11 +163,7 @@ public class IdFunction extends BaseFunction
public int getArity()
{
int arity = master.methodArity(methodId);
if (arity < 0) {
throw onBadMethodId(master, methodId);
}
return arity;
return master.methodArity(this);
}
public int getLength() { return getArity(); }
@ -160,14 +179,15 @@ public class IdFunction extends BaseFunction
setImmunePrototypeProperty(prototype);
}
static RuntimeException onBadMethodId(IdFunctionMaster master, int id)
public final RuntimeException unknown()
{
// It is program error to call id-like methods for unknown or
// non-function id
return new RuntimeException("BAD FUNCTION ID="+id+" MASTER="+master);
return new RuntimeException("BAD FUNCTION ID="+methodId+" MASTER="+master);
}
IdFunctionMaster master;
private int methodId;
private final Object tag;
private final IdFunctionMaster master;
public final int methodId;
private boolean useCallAsConstructor;
}

View File

@ -35,20 +35,23 @@
package org.mozilla.javascript;
/** Master for id-based functions that knows their properties and how to
** execute them
/**
* Master for id-based functions that knows their properties and how to
* execute them.
*/
public interface IdFunctionMaster {
/** 'thisObj' will be null if invoked as constructor, in which case
** instance of Scriptable should be returned */
public Object execMethod(int methodId, IdFunction function,
Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
throws JavaScriptException;
public interface IdFunctionMaster
{
/**
* 'thisObj' will be null if invoked as constructor, in which case
* instance of Scriptable should be returned
*/
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args);
/** Get arity or defined argument count for method with given id.
** Should return -1 if methodId is not known or can not be used
** with execMethod call */
public int methodArity(int methodId);
/**
* Get arity or defined argument count for the given {@link IdFunction}
* instance.
*/
public int methodArity(IdFunction f);
}

View File

@ -371,20 +371,21 @@ public abstract class IdScriptable extends ScriptableObject
/** 'thisObj' will be null if invoked as constructor, in which case
** instance of Scriptable should be returned. */
public Object execMethod(int methodId, IdFunction function,
Context cx, Scriptable scope,
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
throws JavaScriptException
{
throw IdFunction.onBadMethodId(this, methodId);
throw f.unknown();
}
/** Get arity or defined argument count for method with given id.
** Should return -1 if methodId is not known or can not be used
** with execMethod call. */
public int methodArity(int methodId)
/**
* Get arity or defined argument count for the given {@link IdFunction}
* instance.
* If subclass overrides ths method, it should always calls
* <tt>super.methodArity(f)</tt> for unknown functions.
*/
public int methodArity(IdFunction f)
{
return -1;
throw f.unknown();
}
/** Get maximum id mapNameToId can generate */

View File

@ -168,24 +168,29 @@ public final class JavaAdapter implements IdFunctionMaster
public static void init(Context cx, Scriptable scope, boolean sealed)
{
JavaAdapter obj = new JavaAdapter();
IdFunction.defineConstructor(scope, "JavaAdapter", obj, Id_JavaAdapter,
ScriptableObject.DONTENUM, sealed);
new IdFunction(FTAG, obj, "JavaAdapter", Id_JavaAdapter)
.defineAsScopeProperty(scope, sealed);
}
public Object execMethod(int methodId, IdFunction function, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (methodId == Id_JavaAdapter) {
return js_createAdpter(cx, scope, args);
if (f.hasTag(FTAG)) {
if (f.methodId == Id_JavaAdapter) {
return js_createAdpter(cx, scope, args);
}
}
throw IdFunction.onBadMethodId(this, methodId);
throw f.unknown();
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (methodId == Id_JavaAdapter) { return 1; }
throw IdFunction.onBadMethodId(this, methodId);
if (f.hasTag(FTAG)) {
if (f.methodId == Id_JavaAdapter) {
return 1;
}
}
throw f.unknown();
}
public static Object convertResult(Object result, Class c)
@ -1226,5 +1231,6 @@ public final class JavaAdapter implements IdFunctionMaster
return array;
}
private static final Object FTAG = new Object();
private static final int Id_JavaAdapter = 1;
}

View File

@ -125,10 +125,10 @@ public class NativeArray extends IdScriptable {
super.setIdValue(id, value);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toLocaleString: return 1;
@ -145,16 +145,14 @@ public class NativeArray extends IdScriptable {
case Id_slice: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor:
return jsConstructor(cx, scope, args, f, thisObj == null);
@ -200,7 +198,7 @@ public class NativeArray extends IdScriptable {
return js_slice(cx, thisObj, args);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
public Object get(int index, Scriptable start)

View File

@ -66,23 +66,25 @@ final class NativeBoolean extends IdScriptable {
return super.getDefaultValue(typeHint);
}
public int methodArity(int methodId) {
if (prototypeFlag) {
if (methodId == Id_constructor) return 1;
if (methodId == Id_toString) return 0;
if (methodId == Id_toSource) return 0;
if (methodId == Id_valueOf) return 0;
}
return super.methodArity(methodId);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
if (methodId == Id_constructor) {
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toSource: return 0;
case Id_valueOf: return 0;
}
}
return super.methodArity(f);
}
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (f.methodId) {
case Id_constructor: {
boolean b = ScriptRuntime.toBoolean(args, 0);
if (thisObj == null) {
// new Boolean(val) creates a new boolean object.
@ -90,22 +92,23 @@ final class NativeBoolean extends IdScriptable {
}
// Boolean(val) converts val to a boolean.
return wrap_boolean(b);
}
} else if (methodId == Id_toString) {
case Id_toString:
return realThisBoolean(thisObj, f) ? "true" : "false";
} else if (methodId == Id_toSource) {
case Id_toSource:
if (realThisBoolean(thisObj, f))
return "(new Boolean(true))";
else
return "(new Boolean(false))";
} else if (methodId == Id_valueOf) {
case Id_valueOf:
return wrap_boolean(realThisBoolean(thisObj, f));
}
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static boolean realThisBoolean(Scriptable thisObj, IdFunction f)
@ -117,10 +120,12 @@ final class NativeBoolean extends IdScriptable {
protected String getIdName(int id) {
if (prototypeFlag) {
if (id == Id_constructor) return "constructor";
if (id == Id_toString) return "toString";
if (id == Id_toSource) return "toSource";
if (id == Id_valueOf) return "valueOf";
switch (id) {
case Id_constructor: return "constructor";
case Id_toString: return "toString";
case Id_toSource: return "toSource";
case Id_valueOf: return "valueOf";
}
}
return null;
}

View File

@ -147,18 +147,16 @@ final class NativeCallPrototype extends IdScriptable
return "Call";
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (methodId == Id_constructor) return 1;
return super.methodArity(methodId);
if (f.methodId == Id_constructor) return 1;
return super.methodArity(f);
}
public Object execMethod(int methodId, IdFunction f,
Context cx, Scriptable scope,
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
throws JavaScriptException
{
if (methodId == Id_constructor) {
if (f.methodId == Id_constructor) {
if (thisObj != null) {
throw Context.reportRuntimeError1("msg.only.from.new", "Call");
}
@ -167,7 +165,7 @@ final class NativeCallPrototype extends IdScriptable
result.setPrototype(getObjectPrototype(scope));
return result;
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
protected String getIdName(int id)

View File

@ -97,10 +97,10 @@ final class NativeDate extends IdScriptable
super.fillConstructorProperties(cx, ctor, sealed);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case ConstructorId_now: return 0;
case ConstructorId_parse: return 1;
case ConstructorId_UTC: return 1;
@ -151,15 +151,14 @@ final class NativeDate extends IdScriptable
case Id_setYear: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
int methodId = f.methodId;
switch (methodId) {
case ConstructorId_now:
return wrap_double(now());
@ -349,7 +348,7 @@ final class NativeDate extends IdScriptable
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static NativeDate realThis(Scriptable thisObj, IdFunction f)

View File

@ -81,33 +81,34 @@ final class NativeError extends IdScriptable
return obj;
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
if (methodId == Id_constructor) return 1;
if (methodId == Id_toString) return 0;
if (methodId == Id_toSource) return 0;
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toSource: return 0;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
if (methodId == Id_constructor) {
switch (f.methodId) {
case Id_constructor:
return make(cx, scope, f, args);
} else if (methodId == Id_toString) {
case Id_toString:
return js_toString(thisObj);
} else if (methodId == Id_toSource) {
case Id_toSource:
return js_toSource(cx, scope, thisObj);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static String js_toString(Scriptable thisObj)

View File

@ -54,7 +54,6 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeGlobal obj = new NativeGlobal();
obj.scopeSlaveFlag = true;
for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) {
String name;
@ -74,8 +73,8 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
default:
Kit.codeBug(); name = null;
}
IdFunction.define(scope, name, obj, id,
ScriptableObject.DONTENUM, sealed);
IdFunction f = new IdFunction(FTAG, obj, name, id);
f.defineAsScopeProperty(scope, sealed);
}
ScriptableObject.defineProperty(scope, "NaN",
@ -110,7 +109,8 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
newObject(cx, scope, "Error",
ScriptRuntime.emptyArgs);
errorProto.put("name", errorProto, name);
IdFunction ctor = new IdFunction(obj, name, Id_new_CommonError);
IdFunction ctor = new IdFunction(FTAG, obj, name,
Id_new_CommonError);
ctor.initAsConstructor(scope, errorProto);
if (sealed) {
ctor.sealObject();
@ -124,23 +124,21 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
}
}
public Object execMethod(int methodId, IdFunction function, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (scopeSlaveFlag) {
switch (methodId) {
if (f.hasTag(FTAG)) {
switch (f.methodId) {
case Id_decodeURI:
case Id_decodeURIComponent: {
String str = ScriptRuntime.toString(args, 0);
return decode(cx, str, methodId == Id_decodeURI);
return decode(cx, str, f.methodId == Id_decodeURI);
}
case Id_encodeURI:
case Id_encodeURIComponent: {
String str = ScriptRuntime.toString(args, 0);
return encode(cx, str, methodId == Id_encodeURI);
return encode(cx, str, f.methodId == Id_encodeURI);
}
case Id_escape:
@ -185,16 +183,16 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
case Id_new_CommonError:
// The implementation of all the ECMA error constructors
// (SyntaxError, TypeError, etc.)
return NativeError.make(cx, scope, function, args);
return NativeError.make(cx, scope, f, args);
}
}
throw IdFunction.onBadMethodId(this, methodId);
throw f.unknown();
}
public int methodArity(int methodId) {
if (scopeSlaveFlag) {
switch (methodId) {
public int methodArity(IdFunction f)
{
if (f.hasTag(FTAG)) {
switch (f.methodId) {
case Id_decodeURI: return 1;
case Id_decodeURIComponent: return 1;
case Id_encodeURI: return 1;
@ -211,7 +209,7 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
case Id_new_CommonError: return 1;
}
}
return -1;
throw f.unknown();
}
/**
@ -474,9 +472,7 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
{
if (functionObj instanceof IdFunction) {
IdFunction function = (IdFunction)functionObj;
if (function.master instanceof NativeGlobal
&& function.getMethodId() == Id_eval)
{
if (function.hasTag(FTAG) && function.methodId == Id_eval) {
return true;
}
}
@ -729,6 +725,8 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
return utf8Length;
}
private static final Object FTAG = new Object();
private static final int
Id_decodeURI = 1,
Id_decodeURIComponent = 2,
@ -746,7 +744,4 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
LAST_SCOPE_FUNCTION_ID = 12,
Id_new_CommonError = 13;
private boolean scopeSlaveFlag;
}

View File

@ -84,9 +84,9 @@ final class NativeMath extends IdScriptable
return super.getIdValue(id);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
switch (methodId) {
switch (f.methodId) {
case Id_toSource: return 0;
case Id_abs: return 1;
case Id_acos: return 1;
@ -107,16 +107,14 @@ final class NativeMath extends IdScriptable
case Id_sqrt: return 1;
case Id_tan: return 1;
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
double x;
switch (methodId) {
switch (f.methodId) {
case Id_toSource:
return "Math";
@ -130,7 +128,7 @@ final class NativeMath extends IdScriptable
case Id_asin:
x = ScriptRuntime.toNumber(args, 0);
if (x == x && -1.0 <= x && x <= 1.0) {
x = (methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
x = (f.methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
} else {
x = Double.NaN;
}
@ -178,7 +176,7 @@ final class NativeMath extends IdScriptable
case Id_max:
case Id_min:
x = (methodId == Id_max)
x = (f.methodId == Id_max)
? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
for (int i = 0; i != args.length; ++i) {
double d = ScriptRuntime.toNumber(args[i]);
@ -186,7 +184,7 @@ final class NativeMath extends IdScriptable
x = d; // NaN
break;
}
if (methodId == Id_max) {
if (f.methodId == Id_max) {
// if (x < d) x = d; does not work due to -0.0 >= +0.0
x = Math.max(x, d);
} else {
@ -242,7 +240,7 @@ final class NativeMath extends IdScriptable
break;
default:
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
return wrap_double(x);
}

View File

@ -86,9 +86,9 @@ final class NativeNumber extends IdScriptable {
super.fillConstructorProperties(cx, ctor, sealed);
}
public int methodArity(int methodId) {
public int methodArity(IdFunction f) {
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 1;
case Id_toLocaleString: return 1;
@ -99,16 +99,14 @@ final class NativeNumber extends IdScriptable {
case Id_toPrecision: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_constructor: {
double val = (args.length >= 1)
? ScriptRuntime.toNumber(args[0]) : 0.0;
@ -154,7 +152,7 @@ final class NativeNumber extends IdScriptable {
1, 0);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static double realThisValue(Scriptable thisObj, IdFunction f)

View File

@ -72,9 +72,9 @@ final class NativeObjectPrototype extends NativeObject
addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
switch (methodId) {
switch (f.methodId) {
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_toLocaleString: return 0;
@ -84,15 +84,13 @@ final class NativeObjectPrototype extends NativeObject
case Id_isPrototypeOf: return 1;
case Id_toSource: return 0;
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
switch (methodId) {
switch (f.methodId) {
case Id_constructor: {
if (thisObj != null) {
// BaseFunction.construct will set up parent, proto
@ -164,7 +162,7 @@ final class NativeObjectPrototype extends NativeObject
case Id_toSource:
return toSource(cx, scope, thisObj, args);
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static String toSource(Context cx, Scriptable scope,

View File

@ -126,26 +126,24 @@ class NativeScript extends NativeFunction implements Script
return script == null ? Undefined.instance : script.exec(cx, scope);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (0 <= prototypeIdShift) {
switch (methodId - prototypeIdShift) {
switch (f.methodId - prototypeIdShift) {
case Id_constructor: return 1;
case Id_toString: return 0;
case Id_exec: return 0;
case Id_compile: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod(int methodId, IdFunction f, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (0 <= prototypeIdShift) {
switch (methodId - prototypeIdShift) {
switch (f.methodId - prototypeIdShift) {
case Id_constructor: {
String source = (args.length == 0)
? ""
@ -176,7 +174,7 @@ class NativeScript extends NativeFunction implements Script
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static NativeScript realThis(Scriptable thisObj, IdFunction f)

View File

@ -88,10 +88,10 @@ final class NativeString extends IdScriptable {
return super.getIdValue(id);
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case ConstructorId_fromCharCode: return 1;
case Id_constructor: return 1;
@ -129,16 +129,14 @@ final class NativeString extends IdScriptable {
case Id_replace: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod
(int methodId, IdFunction f,
Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case ConstructorId_fromCharCode: {
int N = args.length;
if (N < 1)
@ -178,11 +176,11 @@ final class NativeString extends IdScriptable {
String target = ScriptRuntime.toString(thisObj);
double pos = ScriptRuntime.toInteger(args, 0);
if (pos < 0 || pos >= target.length()) {
if (methodId == Id_charAt) return "";
if (f.methodId == Id_charAt) return "";
else return ScriptRuntime.NaNobj;
}
char c = target.charAt((int)pos);
if (methodId == Id_charAt) return String.valueOf(c);
if (f.methodId == Id_charAt) return String.valueOf(c);
else return wrap_int(c);
}
@ -262,7 +260,7 @@ final class NativeString extends IdScriptable {
case Id_equalsIgnoreCase: {
String s1 = ScriptRuntime.toString(thisObj);
String s2 = ScriptRuntime.toString(args, 0);
return wrap_boolean(methodId == Id_equals
return wrap_boolean(f.methodId == Id_equals
? s1.equals(s2) : s1.equalsIgnoreCase(s2));
}
@ -279,7 +277,7 @@ final class NativeString extends IdScriptable {
replace(cx, scope, thisObj, args);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static NativeString realThis(Scriptable thisObj, IdFunction f)

View File

@ -49,7 +49,8 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
NativeWith obj = new NativeWith();
obj.prototypeFlag = true;
IdFunction ctor = new IdFunction(obj, "constructor", Id_constructor);
IdFunction ctor = new IdFunction(FTAG, obj, "constructor",
Id_constructor);
ctor.initAsConstructor(scope, obj);
if (sealed) { ctor.sealObject(); }
@ -144,36 +145,31 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
return prototype.hasInstance(value);
}
public Object execMethod(int methodId, IdFunction function, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
if (methodId == Id_constructor) {
if (f.hasTag(FTAG)) {
if (f.methodId == Id_constructor) {
throw Context.reportRuntimeError1
("msg.cant.call.indirect", "With");
}
}
throw IdFunction.onBadMethodId(this, methodId);
throw f.unknown();
}
public int methodArity(int methodId) {
if (prototypeFlag) {
if (methodId == Id_constructor) { return 0; }
public int methodArity(IdFunction f)
{
if (f.hasTag(FTAG)) {
if (f.methodId == Id_constructor) { return 0; }
}
return -1;
throw f.unknown();
}
static boolean isWithFunction(Object functionObj)
{
if (functionObj instanceof IdFunction) {
IdFunction function = (IdFunction)functionObj;
if (function.master instanceof NativeWith
&& function.getMethodId() == Id_constructor)
{
return true;
}
IdFunction f = (IdFunction)functionObj;
return f.hasTag(FTAG) && f.methodId == Id_constructor;
}
return false;
}
@ -191,6 +187,8 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
return thisObj;
}
private static final Object FTAG = new Object();
private static final int
Id_constructor = 1;

View File

@ -2621,10 +2621,10 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
lastIndex = value;
}
public int methodArity(int methodId)
public int methodArity(IdFunction f)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_compile: return 1;
case Id_toString: return 0;
case Id_toSource: return 0;
@ -2633,16 +2633,14 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
case Id_prefix: return 1;
}
}
return super.methodArity(methodId);
return super.methodArity(f);
}
public Object execMethod(int methodId, IdFunction f, Context cx,
Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (prototypeFlag) {
switch (methodId) {
switch (f.methodId) {
case Id_compile:
return realThis(thisObj, f).compile(cx, scope, args);
@ -2662,7 +2660,7 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
return realThis(thisObj, f).execSub(cx, scope, args, PREFIX);
}
}
return super.execMethod(methodId, f, cx, scope, thisObj, args);
return super.execMethod(f, cx, scope, thisObj, args);
}
private static NativeRegExp realThis(Scriptable thisObj, IdFunction f)