зеркало из https://github.com/mozilla/pjs.git
Redesigning IdScriptable implementation.
The new logic introduces 2 independent id namespaces, instance ids and prototype ids. Typically there are very few instance properties and instance ids corresponds exactly to them. The prototype ids allows to define functions and other constant objects that typically found in prototype objects. The new implementation takes advantage of this difference to provide very different API to implement fast mapping both for instance and prototype ids.
This commit is contained in:
Родитель
26e2f979e9
Коммит
02ca5d7471
|
@ -152,28 +152,61 @@ class Arguments extends IdScriptable {
|
|||
super.delete(index);
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_callee = 1,
|
||||
Id_length = 2,
|
||||
Id_caller = 3,
|
||||
|
||||
MAX_INSTANCE_ID = 3;
|
||||
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee:
|
||||
case Id_caller:
|
||||
case Id_length:
|
||||
return DONTENUM;
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
setMaxInstanceId(0, MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected boolean hasIdValue(int id)
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return calleeObj != NOT_FOUND;
|
||||
case Id_length: return lengthObj != NOT_FOUND;
|
||||
case Id_caller: return callerObj != NOT_FOUND;
|
||||
int id;
|
||||
// #generated# Last update: 2002-04-09 20:46:33 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
if (s.length()==6) {
|
||||
c=s.charAt(5);
|
||||
if (c=='e') { X="callee";id=Id_callee; }
|
||||
else if (c=='h') { X="length";id=Id_length; }
|
||||
else if (c=='r') { X="caller";id=Id_caller; }
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
return super.hasIdValue(id);
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_callee:
|
||||
case Id_caller:
|
||||
case Id_length:
|
||||
attr = DONTENUM;
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, id);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
// #/string_id_map#
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return "callee";
|
||||
case Id_length: return "length";
|
||||
case Id_caller: return "caller";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return calleeObj;
|
||||
|
@ -185,17 +218,17 @@ class Arguments extends IdScriptable {
|
|||
NativeCall caller = activation.caller;
|
||||
if (caller == null) {
|
||||
value = null;
|
||||
}else {
|
||||
} else {
|
||||
value = caller.get("arguments", caller);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setIdValue(int id, Object value)
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: calleeObj = value; return;
|
||||
|
@ -204,27 +237,7 @@ class Arguments extends IdScriptable {
|
|||
callerObj = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
return;
|
||||
}
|
||||
super.setIdValue(id, value);
|
||||
}
|
||||
|
||||
protected void deleteIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: calleeObj = NOT_FOUND; return;
|
||||
case Id_length: lengthObj = NOT_FOUND; return;
|
||||
case Id_caller: callerObj = NOT_FOUND; return;
|
||||
}
|
||||
super.deleteIdValue(id);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_callee: return "callee";
|
||||
case Id_length: return "length";
|
||||
case Id_caller: return "caller";
|
||||
}
|
||||
return null;
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
Object[] getIds(boolean getAll)
|
||||
|
@ -265,37 +278,6 @@ class Arguments extends IdScriptable {
|
|||
return ids;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_callee = 1,
|
||||
Id_length = 2,
|
||||
Id_caller = 3,
|
||||
|
||||
MAX_INSTANCE_ID = 3;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2002-04-09 20:46:33 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
if (s.length()==6) {
|
||||
c=s.charAt(5);
|
||||
if (c=='e') { X="callee";id=Id_callee; }
|
||||
else if (c=='h') { X="length";id=Id_length; }
|
||||
else if (c=='r') { X="caller";id=Id_caller; }
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
return id;
|
||||
}
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
|
||||
// Fields to hold caller, callee and length properties,
|
||||
// where NOT_FOUND value tags deleted properties.
|
||||
// In addition if callerObj == NULL_VALUE, it tags null for scripts, as
|
||||
|
|
|
@ -45,20 +45,14 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
public class BaseFunction extends IdScriptable implements Function {
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed) {
|
||||
private static final Object FUNCTION_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
BaseFunction obj = new BaseFunction();
|
||||
obj.prototypeFlag = true;
|
||||
obj.functionName = "";
|
||||
obj.isPrototypePropertyImmune = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor, boolean sealed)
|
||||
{
|
||||
// Fix up bootstrapping problem: getPrototype of the IdFunction
|
||||
// can not return Function.prototype because Function object is not
|
||||
// yet defined.
|
||||
ctor.setPrototype(this);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
|
@ -90,107 +84,166 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
functionName);
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
Id_arity = 2,
|
||||
Id_name = 3,
|
||||
Id_prototype = 4,
|
||||
Id_arguments = 5,
|
||||
|
||||
MAX_INSTANCE_ID = 5;
|
||||
|
||||
{
|
||||
setMaxInstanceId(0, MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2001-05-20 00:12:12 GMT+02:00
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 4: X="name";id=Id_name; break L;
|
||||
case 5: X="arity";id=Id_arity; break L;
|
||||
case 6: X="length";id=Id_length; break L;
|
||||
case 9: c=s.charAt(0);
|
||||
if (c=='a') { X="arguments";id=Id_arguments; }
|
||||
else if (c=='p') { X="prototype";id=Id_prototype; }
|
||||
break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
// #/string_id_map#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_length:
|
||||
case Id_arity:
|
||||
case Id_name:
|
||||
attr = DONTENUM | READONLY | PERMANENT;
|
||||
break;
|
||||
case Id_prototype:
|
||||
attr = (isPrototypePropertyImmune)
|
||||
? DONTENUM | READONLY | PERMANENT
|
||||
: DONTENUM;
|
||||
break;
|
||||
case Id_arguments:
|
||||
if (argumentsProperty == null) {
|
||||
attr = DONTENUM;
|
||||
} else {
|
||||
attr = EMPTY;
|
||||
}
|
||||
break;
|
||||
default: throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, id);
|
||||
}
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_length:
|
||||
case Id_arity:
|
||||
case Id_name:
|
||||
return DONTENUM | READONLY | PERMANENT;
|
||||
case Id_prototype:
|
||||
return isPrototypePropertyImmune
|
||||
? DONTENUM | READONLY | PERMANENT
|
||||
: DONTENUM;
|
||||
case Id_arguments:
|
||||
return EMPTY;
|
||||
case Id_length: return "length";
|
||||
case Id_arity: return "arity";
|
||||
case Id_name: return "name";
|
||||
case Id_prototype: return "prototype";
|
||||
case Id_arguments: return "arguments";
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected boolean hasIdValue(int id)
|
||||
{
|
||||
if (id == Id_prototype) {
|
||||
return prototypeProperty != NOT_FOUND;
|
||||
}
|
||||
else if (id == Id_arguments) {
|
||||
// Should after delete Function.arguments its activation still
|
||||
// be available during Function call?
|
||||
// This code assumes it should not: after default set/deleteIdValue
|
||||
// hasIdValue/getIdValue would not be called again
|
||||
// To handle the opposite case, set/deleteIdValue should be
|
||||
// overwritten as well
|
||||
return null != getActivation(Context.getContext());
|
||||
}
|
||||
return super.hasIdValue(id);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_length: return wrap_int(getLength());
|
||||
case Id_arity: return wrap_int(getArity());
|
||||
case Id_name: return getFunctionName();
|
||||
case Id_prototype: return getPrototypeProperty();
|
||||
case Id_arguments: return getArguments();
|
||||
case Id_length: return wrap_int(getLength());
|
||||
case Id_arity: return wrap_int(getArity());
|
||||
case Id_name: return getFunctionName();
|
||||
case Id_prototype: return getPrototypeProperty();
|
||||
case Id_arguments: return getArguments();
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setIdValue(int id, Object value)
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
if (id == Id_prototype) {
|
||||
prototypeProperty = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
if (!isPrototypePropertyImmune) {
|
||||
prototypeProperty = (value != null)
|
||||
? value : UniqueTag.NULL_VALUE;
|
||||
}
|
||||
return;
|
||||
} else if (id == Id_arguments) {
|
||||
argumentsProperty = (value != null)
|
||||
? value : UniqueTag.NULL_VALUE;
|
||||
}
|
||||
super.setIdValue(id, value);
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
protected void deleteIdValue(int id)
|
||||
protected void fillConstructorProperties(IdFunction ctor)
|
||||
{
|
||||
if (id == Id_prototype) {
|
||||
prototypeProperty = NOT_FOUND;
|
||||
return;
|
||||
// Fix up bootstrapping problem: getPrototype of the IdFunction
|
||||
// can not return Function.prototype because Function object is not
|
||||
// yet defined.
|
||||
ctor.setPrototype(this);
|
||||
super.fillConstructorProperties(ctor);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=1; s="toString"; break;
|
||||
case Id_toSource: arity=1; s="toSource"; break;
|
||||
case Id_apply: arity=2; s="apply"; break;
|
||||
case Id_call: arity=1; s="call"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
super.deleteIdValue(id);
|
||||
initPrototypeMethod(FUNCTION_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
int methodId = f.methodId();
|
||||
switch (methodId) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, scope, args);
|
||||
|
||||
case Id_toString: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = ScriptRuntime.toInt32(args, 0);
|
||||
return realf.decompile(indent, 0);
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = 0;
|
||||
int flags = Decompiler.TO_SOURCE_FLAG;
|
||||
if (args.length != 0) {
|
||||
indent = ScriptRuntime.toInt32(args[0]);
|
||||
if (indent >= 0) {
|
||||
flags = 0;
|
||||
} else {
|
||||
indent = 0;
|
||||
}
|
||||
}
|
||||
return realf.decompile(indent, flags);
|
||||
}
|
||||
|
||||
case Id_apply:
|
||||
case Id_call:
|
||||
return applyOrCall(methodId == Id_apply, cx, scope,
|
||||
thisObj, args);
|
||||
}
|
||||
if (!f.hasTag(FUNCTION_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, scope, args);
|
||||
|
||||
case Id_toString: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = ScriptRuntime.toInt32(args, 0);
|
||||
return realf.decompile(indent, 0);
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
BaseFunction realf = realFunction(thisObj, f);
|
||||
int indent = 0;
|
||||
int flags = Decompiler.TO_SOURCE_FLAG;
|
||||
if (args.length != 0) {
|
||||
indent = ScriptRuntime.toInt32(args[0]);
|
||||
if (indent >= 0) {
|
||||
flags = 0;
|
||||
} else {
|
||||
indent = 0;
|
||||
}
|
||||
}
|
||||
return realf.decompile(indent, flags);
|
||||
}
|
||||
|
||||
case Id_apply:
|
||||
case Id_call:
|
||||
return applyOrCall(id, cx, scope, thisObj, args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private BaseFunction realFunction(Scriptable thisObj, IdFunction f)
|
||||
|
@ -208,6 +261,9 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
*/
|
||||
public void setImmunePrototypeProperty(Object value)
|
||||
{
|
||||
if (isPrototypePropertyImmune) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
prototypeProperty = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
isPrototypePropertyImmune = true;
|
||||
}
|
||||
|
@ -326,7 +382,7 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
return functionName;
|
||||
}
|
||||
|
||||
Object getPrototypeProperty() {
|
||||
final Object getPrototypeProperty() {
|
||||
Object result = prototypeProperty;
|
||||
if (result == null) {
|
||||
synchronized (this) {
|
||||
|
@ -361,13 +417,21 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
|
||||
private Object getArguments()
|
||||
{
|
||||
// <Function name>.arguments is deprecated, so we use a slow
|
||||
// way of getting it that doesn't add to the invocation cost.
|
||||
// TODO: add warning, error based on version
|
||||
NativeCall activation = getActivation(Context.getContext());
|
||||
return activation == null
|
||||
? null
|
||||
: activation.get("arguments", activation);
|
||||
// <Function name>.arguments is deprecated, so we use a slow
|
||||
// way of getting it that doesn't add to the invocation cost.
|
||||
// TODO: add warning, error based on version
|
||||
Object value = argumentsProperty;
|
||||
if (value != null) {
|
||||
// Should after changing <Function name>.arguments its
|
||||
// activation still be available during Function call?
|
||||
// This code assumes it should not: argumentsProperty != null
|
||||
// means assigned or delete arguments
|
||||
return (value == UniqueTag.NULL_VALUE) ? null : value;
|
||||
}
|
||||
NativeCall activation = getActivation(Context.getContext());
|
||||
return (activation == null)
|
||||
? null
|
||||
: activation.get("arguments", activation);
|
||||
}
|
||||
|
||||
NativeCall getActivation(Context cx)
|
||||
|
@ -449,7 +513,7 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
*
|
||||
* See Ecma 15.3.4.[34]
|
||||
*/
|
||||
private static Object applyOrCall(boolean isApply,
|
||||
private static Object applyOrCall(int id,
|
||||
Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
throws JavaScriptException
|
||||
|
@ -465,7 +529,7 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
}
|
||||
|
||||
Object[] callArgs;
|
||||
if (isApply) {
|
||||
if (id == Id_apply) {
|
||||
// Follow Ecma 15.3.4.3
|
||||
if (L <= 1) {
|
||||
callArgs = ScriptRuntime.emptyArgs;
|
||||
|
@ -494,76 +558,9 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
return ScriptRuntime.call(cx, function, callThis, callArgs, scope);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_length: return "length";
|
||||
case Id_arity: return "arity";
|
||||
case Id_name: return "name";
|
||||
case Id_prototype: return "prototype";
|
||||
case Id_arguments: return "arguments";
|
||||
}
|
||||
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_apply: return "apply";
|
||||
case Id_call: return "call";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 1;
|
||||
case Id_toSource: return 1;
|
||||
case Id_apply: return 2;
|
||||
case Id_call: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
Id_arity = 2,
|
||||
Id_name = 3,
|
||||
Id_prototype = 4,
|
||||
Id_arguments = 5,
|
||||
|
||||
MAX_INSTANCE_ID = 5;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2001-05-20 00:12:12 GMT+02:00
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
case 4: X="name";id=Id_name; break L;
|
||||
case 5: X="arity";id=Id_arity; break L;
|
||||
case 6: X="length";id=Id_length; break L;
|
||||
case 9: c=s.charAt(0);
|
||||
if (c=='a') { X="arguments";id=Id_arguments; }
|
||||
else if (c=='p') { X="prototype";id=Id_prototype; }
|
||||
break L;
|
||||
}
|
||||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
// #/string_id_map#
|
||||
|
||||
if (id != 0 || !prototypeFlag) { return id; }
|
||||
|
||||
// #string_id_map#
|
||||
// #generated# Last update: 2004-03-17 13:23:22 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -583,13 +580,13 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = MAX_INSTANCE_ID + 1,
|
||||
Id_toString = MAX_INSTANCE_ID + 2,
|
||||
Id_toSource = MAX_INSTANCE_ID + 3,
|
||||
Id_apply = MAX_INSTANCE_ID + 4,
|
||||
Id_call = MAX_INSTANCE_ID + 5,
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
Id_apply = 4,
|
||||
Id_call = 5,
|
||||
|
||||
MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 5;
|
||||
MAX_PROTOTYPE_ID = 5;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
|
@ -597,6 +594,6 @@ public class BaseFunction extends IdScriptable implements Function {
|
|||
|
||||
private Object prototypeProperty;
|
||||
private boolean isPrototypePropertyImmune;
|
||||
private boolean prototypeFlag;
|
||||
private Object argumentsProperty;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,159 +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 or
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// API class
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
public class IdFunction extends BaseFunction
|
||||
{
|
||||
public IdFunction(IdFunctionMaster master, Object tag, int id,
|
||||
String name, int arity, Scriptable scope)
|
||||
{
|
||||
if (scope == null) throw new IllegalArgumentException();
|
||||
this.functionName = name;
|
||||
this.master = master;
|
||||
this.tag = tag;
|
||||
this.methodId = id;
|
||||
this.arity = arity;
|
||||
setParentScope(scope);
|
||||
}
|
||||
|
||||
public final boolean hasTag(Object tag)
|
||||
{
|
||||
return this.tag == tag;
|
||||
}
|
||||
|
||||
public final int methodId()
|
||||
{
|
||||
return methodId;
|
||||
}
|
||||
|
||||
public final void markAsConstructor(Scriptable prototypeProperty)
|
||||
{
|
||||
useCallAsConstructor = true;
|
||||
setImmunePrototypeProperty(prototypeProperty);
|
||||
}
|
||||
|
||||
public final void addAsProperty(Scriptable target)
|
||||
{
|
||||
addAsProperty(target, false);
|
||||
}
|
||||
|
||||
public final void addAsProperty(Scriptable target, boolean seal)
|
||||
{
|
||||
if (seal) { sealObject(); }
|
||||
ScriptableObject.defineProperty(target, functionName, this,
|
||||
ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
||||
public void exportAsScopeProperty(boolean seal)
|
||||
{
|
||||
addAsProperty(getParentScope(), seal);
|
||||
}
|
||||
|
||||
public Scriptable getPrototype()
|
||||
{
|
||||
// Lazy initialization of prototype: for native functions this
|
||||
// may not be called at all
|
||||
Scriptable proto = super.getPrototype();
|
||||
if (proto == null) {
|
||||
proto = getFunctionPrototype(getParentScope());
|
||||
setPrototype(proto);
|
||||
}
|
||||
return proto;
|
||||
}
|
||||
|
||||
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
|
||||
Object[] args)
|
||||
throws JavaScriptException
|
||||
{
|
||||
return master.execMethod(this, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
public Scriptable createObject(Context cx, Scriptable scope)
|
||||
{
|
||||
if (useCallAsConstructor) {
|
||||
return null;
|
||||
}
|
||||
// Throw error if not explicitly coded to be used as constructor,
|
||||
// to satisfy ECMAScript standard (see bugzilla 202019).
|
||||
// To follow current (2003-05-01) SpiderMonkey behavior, change it to:
|
||||
// return super.createObject(cx, scope);
|
||||
throw ScriptRuntime.typeError1("msg.not.ctor", functionName);
|
||||
}
|
||||
|
||||
String decompile(int indent, int flags)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
|
||||
if (!justbody) {
|
||||
sb.append("function ");
|
||||
sb.append(getFunctionName());
|
||||
sb.append("() { ");
|
||||
}
|
||||
sb.append("[native code for ");
|
||||
if (master instanceof Scriptable) {
|
||||
Scriptable smaster = (Scriptable)master;
|
||||
sb.append(smaster.getClassName());
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(getFunctionName());
|
||||
sb.append(", arity=");
|
||||
sb.append(getArity());
|
||||
sb.append(justbody ? "]\n" : "] }\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int getArity()
|
||||
{
|
||||
return arity;
|
||||
}
|
||||
|
||||
public int getLength() { return getArity(); }
|
||||
|
||||
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="+methodId+" MASTER="+master);
|
||||
}
|
||||
|
||||
private final IdFunctionMaster master;
|
||||
private final Object tag;
|
||||
private final int methodId;
|
||||
private int arity;
|
||||
private boolean useCallAsConstructor;
|
||||
}
|
|
@ -35,22 +35,22 @@
|
|||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
Base class for native object implementation that uses IdFunction to export its methods to script via <class-name>.prototype object.
|
||||
|
||||
Any descendant should implement at least the following methods:
|
||||
mapNameToId
|
||||
getIdName
|
||||
findInstanceIdInfo
|
||||
getInstanceIdName
|
||||
execMethod
|
||||
methodArity
|
||||
|
||||
To define non-function properties, the descendant should override
|
||||
getIdValue
|
||||
setIdValue
|
||||
getIdAttributes
|
||||
getInstanceIdValue
|
||||
setInstanceIdValue
|
||||
to get/set property value and provide its default attributes.
|
||||
|
||||
During initialization descendant should call setMaxId directly or via calling addAsPrototype.
|
||||
|
||||
To customize initializition of constructor and protype objects, descendant
|
||||
may override scopeInit or fillConstructorProperties methods.
|
||||
|
@ -59,12 +59,288 @@ may override scopeInit or fillConstructorProperties methods.
|
|||
public abstract class IdScriptable extends ScriptableObject
|
||||
implements IdFunctionMaster
|
||||
{
|
||||
private static final class PrototypeValues implements Serializable
|
||||
{
|
||||
private static final int VALUE_SLOT = 0;
|
||||
private static final int NAME_SLOT = 1;
|
||||
private static final int SLOT_SPAN = 2;
|
||||
|
||||
private IdScriptable obj;
|
||||
private Object tag;
|
||||
private int maxId;
|
||||
private volatile Object[] valueArray;
|
||||
private volatile short[] attributeArray;
|
||||
private volatile int lastFoundId = 1;
|
||||
|
||||
// The following helps to avoid creation of valueArray during runtime
|
||||
// initialization for common case of "constructor" property
|
||||
int constructorId;
|
||||
private IdFunction constructor;
|
||||
private short constructorAttrs;
|
||||
|
||||
PrototypeValues(IdScriptable obj, int maxId)
|
||||
{
|
||||
if (obj == null) throw new IllegalArgumentException();
|
||||
if (maxId < 1) throw new IllegalArgumentException();
|
||||
this.obj = obj;
|
||||
this.maxId = maxId;
|
||||
}
|
||||
|
||||
final void initValue(int id, String name, Object value, int attributes)
|
||||
{
|
||||
if (!(1 <= id && id <= maxId))
|
||||
throw new IllegalArgumentException();
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (value == NOT_FOUND)
|
||||
throw new IllegalArgumentException();
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
if (obj.findPrototypeId(name) != id)
|
||||
throw new IllegalArgumentException(name);
|
||||
|
||||
if (id == constructorId) {
|
||||
if (!(value instanceof IdFunction)) {
|
||||
throw new IllegalArgumentException(
|
||||
"consructor should be initialized with IdFunction");
|
||||
}
|
||||
constructor = (IdFunction)value;
|
||||
constructorAttrs = (short)attributes;
|
||||
return;
|
||||
}
|
||||
|
||||
initSlot(id, name, value, attributes);
|
||||
}
|
||||
|
||||
private void initSlot(int id, String name, Object value,
|
||||
int attributes)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null)
|
||||
throw new IllegalStateException();
|
||||
|
||||
if (value == null) {
|
||||
value = UniqueTag.NULL_VALUE;
|
||||
}
|
||||
int index = (id - 1) * SLOT_SPAN;
|
||||
synchronized (this) {
|
||||
Object value2 = array[index + VALUE_SLOT];
|
||||
if (value2 == null) {
|
||||
array[index + VALUE_SLOT] = value;
|
||||
array[index + NAME_SLOT] = name;
|
||||
attributeArray[id - 1] = (short)attributes;
|
||||
} else {
|
||||
if (!name.equals(array[index + NAME_SLOT]))
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final IdFunction createPrecachedConstructor()
|
||||
{
|
||||
if (constructorId != 0) throw new IllegalStateException();
|
||||
constructorId = obj.findPrototypeId("constructor");
|
||||
if (constructorId == 0) {
|
||||
throw new IllegalStateException(
|
||||
"No id for constructor property");
|
||||
}
|
||||
obj.initPrototypeId(constructorId);
|
||||
if (constructor == null) {
|
||||
throw new IllegalStateException(
|
||||
obj.getClass().getName()+".initPrototypeId() did not "
|
||||
+"initialize id="+constructorId);
|
||||
}
|
||||
constructor.initFunction(obj.getClassName(),
|
||||
ScriptableObject.getTopLevelScope(obj));
|
||||
constructor.markAsConstructor(obj);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
final int findId(String name)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
return obj.findPrototypeId(name);
|
||||
}
|
||||
int id = lastFoundId;
|
||||
if (name == array[(id - 1) * SLOT_SPAN + NAME_SLOT]) {
|
||||
return id;
|
||||
}
|
||||
id = obj.findPrototypeId(name);
|
||||
if (id != 0) {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
// Make cache to work!
|
||||
array[nameSlot] = name;
|
||||
lastFoundId = id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
final boolean has(int id)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
// Not yet initialized, assume all exists
|
||||
return true;
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
Object value = array[valueSlot];
|
||||
if (value == null) {
|
||||
// The particular entry has not been yet initialized
|
||||
return true;
|
||||
}
|
||||
return value != NOT_FOUND;
|
||||
}
|
||||
|
||||
final Object get(int id)
|
||||
{
|
||||
Object value = ensureId(id);
|
||||
if (value == UniqueTag.NULL_VALUE) {
|
||||
value = null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
final void set(int id, Scriptable start, Object value)
|
||||
{
|
||||
if (value == NOT_FOUND) throw new IllegalArgumentException();
|
||||
ensureId(id);
|
||||
int attr = attributeArray[id - 1];
|
||||
if ((attr & READONLY) == 0) {
|
||||
if (start == obj) {
|
||||
if (value == null) {
|
||||
value = UniqueTag.NULL_VALUE;
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
synchronized (this) {
|
||||
valueArray[valueSlot] = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
String name = (String)valueArray[nameSlot];
|
||||
start.put(name, start, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final void delete(int id)
|
||||
{
|
||||
ensureId(id);
|
||||
int attr = attributeArray[id - 1];
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
synchronized (this) {
|
||||
valueArray[valueSlot] = NOT_FOUND;
|
||||
attributeArray[id - 1] = EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int getAttributes(int id)
|
||||
{
|
||||
ensureId(id);
|
||||
return attributeArray[id - 1];
|
||||
}
|
||||
|
||||
final void setAttributes(int id, int attributes)
|
||||
{
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
ensureId(id);
|
||||
synchronized (this) {
|
||||
attributeArray[id - 1] = (short)attributes;
|
||||
}
|
||||
}
|
||||
|
||||
final Object[] getNames(boolean getAll, Object[] extraEntries)
|
||||
{
|
||||
Object[] names = null;
|
||||
int count = 0;
|
||||
for (int id = 1; id <= maxId; ++id) {
|
||||
Object value = ensureId(id);
|
||||
if (getAll || (attributeArray[id - 1] & DONTENUM) == 0) {
|
||||
if (value != NOT_FOUND) {
|
||||
int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
|
||||
String name = (String)valueArray[nameSlot];
|
||||
if (names == null) {
|
||||
names = new Object[maxId - 1];
|
||||
}
|
||||
names[count++] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
return extraEntries;
|
||||
} else if (extraEntries == null || extraEntries.length == 0) {
|
||||
if (count != names.length) {
|
||||
Object[] tmp = new Object[count];
|
||||
System.arraycopy(names, 0, tmp, 0, count);
|
||||
names = tmp;
|
||||
}
|
||||
return names;
|
||||
} else {
|
||||
int extra = extraEntries.length;
|
||||
Object[] tmp = new Object[extra + count];
|
||||
System.arraycopy(extraEntries, 0, tmp, 0, extra);
|
||||
System.arraycopy(names, 0, tmp, extra, count);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
private Object ensureId(int id)
|
||||
{
|
||||
Object[] array = valueArray;
|
||||
if (array == null) {
|
||||
synchronized (this) {
|
||||
array = valueArray;
|
||||
if (array == null) {
|
||||
array = new Object[maxId * SLOT_SPAN];
|
||||
valueArray = array;
|
||||
attributeArray = new short[maxId];
|
||||
}
|
||||
}
|
||||
}
|
||||
int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
|
||||
Object value = array[valueSlot];
|
||||
if (value == null) {
|
||||
if (id == constructorId) {
|
||||
initSlot(constructorId, "constructor",
|
||||
constructor, constructorAttrs);
|
||||
constructor = null; // no need to refer it any longer
|
||||
} else {
|
||||
obj.initPrototypeId(id);
|
||||
}
|
||||
value = array[valueSlot];
|
||||
if (value == null) {
|
||||
throw new IllegalStateException(
|
||||
obj.getClass().getName()+".initPrototypeId(int id) "
|
||||
+"did not initialize id="+id);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public IdScriptable()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean has(String name, Scriptable start)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId_writeCached(name);
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) != 0) {
|
||||
return true;
|
||||
}
|
||||
int id = (info & 0xFFFF);
|
||||
return NOT_FOUND != getInstanceIdValue(id);
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
return hasValue(id);
|
||||
return prototypeValues.has(id);
|
||||
}
|
||||
}
|
||||
return super.has(name, start);
|
||||
|
@ -72,23 +348,17 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
|
||||
public Object get(String name, Scriptable start)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId_writeCached(name);
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int id = (info & 0xFFFF);
|
||||
return getInstanceIdValue(id);
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
Object[] data = idMapData;
|
||||
if (data == null) {
|
||||
return getIdValue(id);
|
||||
}
|
||||
else {
|
||||
Object value = data[id - 1];
|
||||
if (value == null) {
|
||||
value = getIdValue(id);
|
||||
}
|
||||
else if (value == UniqueTag.NULL_VALUE) {
|
||||
value = null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return prototypeValues.get(id);
|
||||
}
|
||||
}
|
||||
return super.get(name, start);
|
||||
|
@ -96,17 +366,18 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
|
||||
public void put(String name, Scriptable start, Object value)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId_cached(name);
|
||||
if (id != 0) {
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
if (start == this && isSealed()) {
|
||||
throw Context.reportRuntimeError1("msg.modify.sealed",
|
||||
name);
|
||||
}
|
||||
int attr = getIdAttributes(id);
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & READONLY) == 0) {
|
||||
if (start == this) {
|
||||
setIdValue(id, value);
|
||||
int id = (info & 0xFFFF);
|
||||
setInstanceIdValue(id, value);
|
||||
}
|
||||
else {
|
||||
start.put(name, start, value);
|
||||
|
@ -115,36 +386,61 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
if (start == this && isSealed()) {
|
||||
throw Context.reportRuntimeError1("msg.modify.sealed",
|
||||
name);
|
||||
}
|
||||
prototypeValues.set(id, start, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.put(name, start, value);
|
||||
}
|
||||
|
||||
public void delete(String name)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId(name);
|
||||
if (id != 0) {
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
// Let the super class to throw exceptions for sealed objects
|
||||
if (!isSealed()) {
|
||||
int attr = getIdAttributes(id);
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
deleteIdValue(id);
|
||||
int id = (info & 0xFFFF);
|
||||
setInstanceIdValue(id, NOT_FOUND);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
if (!isSealed()) {
|
||||
prototypeValues.delete(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.delete(name);
|
||||
}
|
||||
|
||||
public int getAttributes(String name)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId(name);
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
if (hasValue(id)) {
|
||||
return getIdAttributes(id);
|
||||
}
|
||||
// For ids with deleted values super will throw exceptions
|
||||
return prototypeValues.getAttributes(id);
|
||||
}
|
||||
}
|
||||
return super.getAttributes(name);
|
||||
|
@ -152,64 +448,56 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
|
||||
public void setAttributes(String name, int attributes)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId(name);
|
||||
if (id != 0) {
|
||||
synchronized (this) {
|
||||
if (hasValue(id)) {
|
||||
setIdAttributes(id, attributes);
|
||||
return;
|
||||
}
|
||||
ScriptableObject.checkValidAttributes(attributes);
|
||||
if (maxInstanceId != 0) {
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int currentAttributes = (info >>> 16);
|
||||
if (attributes != currentAttributes) {
|
||||
throw new RuntimeException(
|
||||
"Change of attributes for this id is not supported");
|
||||
}
|
||||
// For ids with deleted values super will throw exceptions
|
||||
}
|
||||
}
|
||||
super.setAttributes(name, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redefine ScriptableObject.defineProperty to allow changing
|
||||
* values/attributes of id-based properties unless
|
||||
* getIdAttributes contains the READONLY attribute.
|
||||
* @see #getIdAttributes
|
||||
* @see org.mozilla.javascript.ScriptableObject#defineProperty
|
||||
*/
|
||||
public void defineProperty(String propertyName, Object value,
|
||||
int attributes)
|
||||
{
|
||||
if (maxId != 0) {
|
||||
int id = mapNameToId(propertyName);
|
||||
if (id != 0) {
|
||||
int current_attributes = getIdAttributes(id);
|
||||
if ((current_attributes & READONLY) != 0) {
|
||||
// It is a bug to redefine id with readonly attributes
|
||||
throw new RuntimeException
|
||||
("Attempt to redefine read-only id " + propertyName);
|
||||
}
|
||||
setIdAttributes(id, attributes);
|
||||
setIdValue(id, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.defineProperty(propertyName, value, attributes);
|
||||
if (prototypeValues != null) {
|
||||
int id = prototypeValues.findId(name);
|
||||
if (id != 0) {
|
||||
prototypeValues.setAttributes(id, attributes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.setAttributes(name, attributes);
|
||||
}
|
||||
|
||||
Object[] getIds(boolean getAll)
|
||||
{
|
||||
Object[] result = super.getIds(getAll);
|
||||
|
||||
if (maxId != 0) {
|
||||
if (prototypeValues != null) {
|
||||
result = prototypeValues.getNames(getAll, result);
|
||||
}
|
||||
|
||||
if (maxInstanceId != 0) {
|
||||
Object[] ids = null;
|
||||
int count = 0;
|
||||
|
||||
for (int id = maxId; id != 0; --id) {
|
||||
if (hasValue(id)) {
|
||||
if (getAll || (getIdAttributes(id) & DONTENUM) == 0) {
|
||||
for (int id = maxInstanceId; id != 0; --id) {
|
||||
String name = getInstanceIdName(id);
|
||||
int info = findInstanceIdInfo(name);
|
||||
if (info != 0) {
|
||||
int attr = (info >>> 16);
|
||||
if ((attr & PERMANENT) == 0) {
|
||||
if (NOT_FOUND == getInstanceIdValue(id)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (getAll || (attr & DONTENUM) == 0) {
|
||||
if (count == 0) {
|
||||
// Need extra room for no more then [1..id] names
|
||||
ids = new Object[id];
|
||||
}
|
||||
ids[count++] = getIdName(id);
|
||||
ids[count++] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,148 +516,72 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
return result;
|
||||
}
|
||||
|
||||
// Try to avoid calls to mapNameToId by quering name cache
|
||||
private int mapNameToId_cached(String name)
|
||||
/** Get maximum id findInstanceIdInfo can generate */
|
||||
protected final int getMaxInstanceId()
|
||||
{
|
||||
if (CACHE_NAMES) {
|
||||
Object[] data = idMapData;
|
||||
if (data != null) {
|
||||
int id = lastIdCache;
|
||||
if (data[id - 1 + maxId] == name) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapNameToId(name);
|
||||
}
|
||||
|
||||
// Same as mapNameToId_cached but put to cache id found by mapNameToId
|
||||
private int mapNameToId_writeCached(String name) {
|
||||
if (CACHE_NAMES) {
|
||||
Object[] data = idMapData;
|
||||
if (data != null) {
|
||||
int id = lastIdCache;
|
||||
if (data[id - 1 + maxId] == name) {
|
||||
return id;
|
||||
}
|
||||
id = mapNameToId(name);
|
||||
if (id != 0) {
|
||||
data[id - 1 + maxId] = name;
|
||||
lastIdCache = id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return mapNameToId(name);
|
||||
return maxInstanceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map name to id of prototype or instance property.
|
||||
* Should return 0 if not found
|
||||
* Set maximum id findInstanceIdInfo can generate.
|
||||
*
|
||||
* @param maxInstanceId new value of maximum id.
|
||||
* @param prevMaxId the current result of {@link #getMaxInstanceId()}.
|
||||
* It is used for consitency checks.
|
||||
*/
|
||||
protected abstract int mapNameToId(String name);
|
||||
protected final void setMaxInstanceId(int prevMaxId, int maxInstanceId)
|
||||
{
|
||||
if (prevMaxId != this.maxInstanceId) {
|
||||
// Consitency check
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (this.maxInstanceId >= maxInstanceId) {
|
||||
// maxInstanceId can only go up
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.maxInstanceId = maxInstanceId;
|
||||
}
|
||||
|
||||
protected static int instanceIdInfo(int attributes, int id)
|
||||
{
|
||||
return (attributes << 16) | id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map name to id of instance property.
|
||||
* Should return 0 if not found or the result of
|
||||
* {@link #instanceIdInfo(int, int)}.
|
||||
*/
|
||||
protected int findInstanceIdInfo(String name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Map id back to property name it defines.
|
||||
*/
|
||||
protected String getIdName(int id)
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/** Get attributes for id.
|
||||
** Default implementation return DONTENUM that is the standard attribute
|
||||
** for core EcmaScript function. Typically descendants need to overwrite
|
||||
** this for non-function attributes like length to return
|
||||
** DONTENUM | READONLY | PERMANENT or DONTENUM | PERMANENT
|
||||
*/
|
||||
protected int getIdAttributes(int id)
|
||||
{
|
||||
return DONTENUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attributes for id.
|
||||
* Descendants should override the default implementation if they want to
|
||||
* allow to change id attributes since the default implementation throw an
|
||||
* exception unless new attributes eqaul the result of
|
||||
* <tt>getIdAttributes(id)</tt>.
|
||||
*/
|
||||
protected void setIdAttributes(int id, int attributes)
|
||||
{
|
||||
int current = getIdAttributes(id);
|
||||
if (attributes != current) {
|
||||
throw new RuntimeException(
|
||||
"Change of attributes for this id is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if id value exists.
|
||||
** Default implementation always returns true */
|
||||
protected boolean hasIdValue(int id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Get id value.
|
||||
** If id value is constant, descendant can call cacheIdValue to store
|
||||
** value in the permanent cache.
|
||||
** Default implementation creates IdFunction instance for given id
|
||||
** and cache its value
|
||||
*/
|
||||
protected Object getIdValue(int id)
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(this);
|
||||
IdFunction f = newIdFunction(id, scope);
|
||||
return cacheIdValue(id, f);
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id value.
|
||||
* IdScriptable never calls this method if result of
|
||||
* <code>getIdAttributes(id)</code> contains READONLY attribute.
|
||||
* Descendants can overwrite this method to provide custom handler for
|
||||
* property assignments.
|
||||
* Set or delete id value. If value == NOT_FOUND , the implementation
|
||||
* should make sure that the following getInstanceIdValue return NOT_FOUND.
|
||||
*/
|
||||
protected void setIdValue(int id, Object value)
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
synchronized (this) {
|
||||
Object[] data = ensureIdData();
|
||||
data[id - 1] = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store value in permanent cache unless value was already assigned to id.
|
||||
* After this call IdScriptable never calls hasIdValue and getIdValue
|
||||
* for the given id.
|
||||
*/
|
||||
protected Object cacheIdValue(int id, Object value)
|
||||
{
|
||||
synchronized (this) {
|
||||
Object[] data = ensureIdData();
|
||||
Object curValue = data[id - 1];
|
||||
if (curValue == null) {
|
||||
data[id - 1] = (value != null) ? value : UniqueTag.NULL_VALUE;
|
||||
}
|
||||
else {
|
||||
value = curValue;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete value represented by id so hasIdValue return false.
|
||||
* IdScriptable never calls this method if result of
|
||||
* <code>getIdAttributes(id)</code> contains PERMANENT attribute.
|
||||
* Descendants can overwrite this method to provide custom handler for
|
||||
* property delete.
|
||||
*/
|
||||
protected void deleteIdValue(int id)
|
||||
{
|
||||
synchronized (this) {
|
||||
ensureIdData()[id - 1] = NOT_FOUND;
|
||||
}
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
/** 'thisObj' will be null if invoked as constructor, in which case
|
||||
|
@ -380,42 +592,9 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
throw f.unknown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arity or defined argument count for the given function id.
|
||||
* If subclass overrides ths method, it should always calls
|
||||
* <tt>super.methodArity(id)</tt> for unknown functions.
|
||||
*/
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
throw new IllegalArgumentException(String.valueOf(methodId));
|
||||
}
|
||||
|
||||
/** Get maximum id mapNameToId can generate */
|
||||
protected final int getMaxId()
|
||||
{
|
||||
return maxId;
|
||||
}
|
||||
|
||||
/** Set maximum id mapNameToId can generate */
|
||||
protected final void setMaxId(int maxId)
|
||||
{
|
||||
// maxId can only go up
|
||||
if (maxId < this.maxId) Kit.codeBug();
|
||||
this.maxId = maxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare this object to serve as the prototype property of constructor
|
||||
* object with name <code>getClassName()<code> defined in
|
||||
* <code>scope</code>.
|
||||
* @param maxId maximum id available in prototype object
|
||||
* @param cx current context
|
||||
* @param scope object to define constructor in.
|
||||
* @param sealed indicates whether object and all its properties should
|
||||
* be sealed
|
||||
*/
|
||||
public void addAsPrototype(int maxId, Context cx, Scriptable scope,
|
||||
boolean sealed)
|
||||
public final IdFunction exportAsJSClass(int maxPrototypeId,
|
||||
Scriptable scope,
|
||||
boolean sealed)
|
||||
{
|
||||
// Set scope and prototype unless IdScriptable is top level scope itself
|
||||
if (scope != this && scope != null) {
|
||||
|
@ -423,24 +602,79 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
setPrototype(getObjectPrototype(scope));
|
||||
}
|
||||
|
||||
setMaxId(maxId);
|
||||
IdFunction ctor = newConstructor(scope);
|
||||
ctor.markAsConstructor(this);
|
||||
fillConstructorProperties(ctor, sealed);
|
||||
cacheIdValue(ctor.methodId(), ctor);
|
||||
ctor.exportAsScopeProperty(sealed);
|
||||
activatePrototypeMap(maxPrototypeId);
|
||||
IdFunction ctor = prototypeValues.createPrecachedConstructor();
|
||||
if (sealed) {
|
||||
sealObject();
|
||||
}
|
||||
fillConstructorProperties(ctor);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
return ctor;
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor, boolean sealed)
|
||||
public final boolean hasPrototypeMap()
|
||||
{
|
||||
return prototypeValues != null;
|
||||
}
|
||||
|
||||
public final void activatePrototypeMap(int maxPrototypeId)
|
||||
{
|
||||
PrototypeValues values = new PrototypeValues(this, maxPrototypeId);
|
||||
synchronized (this) {
|
||||
if (prototypeValues != null)
|
||||
throw new IllegalStateException();
|
||||
prototypeValues = values;
|
||||
}
|
||||
}
|
||||
|
||||
public final void initPrototypeMethod(Object tag, int id, String name,
|
||||
int arity)
|
||||
{
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(this);
|
||||
IdFunction f = newIdFunction(tag, id, name, arity, scope);
|
||||
prototypeValues.initValue(id, name, f, DONTENUM);
|
||||
}
|
||||
|
||||
public final void initPrototypeConstructor(IdFunction f)
|
||||
{
|
||||
int id = prototypeValues.constructorId;
|
||||
if (id == 0)
|
||||
throw new IllegalStateException();
|
||||
if (f.methodId() != id)
|
||||
throw new IllegalArgumentException();
|
||||
if (isSealed()) { f.sealObject(); }
|
||||
prototypeValues.initValue(id, "constructor", f, DONTENUM);
|
||||
}
|
||||
|
||||
public final void initPrototypeValue(int id, String name, Object value,
|
||||
int attributes)
|
||||
{
|
||||
prototypeValues.initValue(id, name, value, attributes);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
|
||||
protected int findPrototypeId(String name)
|
||||
{
|
||||
throw new IllegalStateException(name);
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor)
|
||||
{
|
||||
}
|
||||
|
||||
protected void addIdFunctionProperty
|
||||
(Scriptable obj, int id, boolean sealed)
|
||||
protected void addIdFunctionProperty(Scriptable obj, Object tag, int id,
|
||||
String name, int arity)
|
||||
{
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(obj);
|
||||
IdFunction f = newIdFunction(id, scope);
|
||||
f.addAsProperty(obj, sealed);
|
||||
IdFunction f = newIdFunction(tag, id, name, arity, scope);
|
||||
f.addAsProperty(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,28 +704,15 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
f.getFunctionName());
|
||||
}
|
||||
|
||||
protected IdFunction newIdFunction(int id, Scriptable scope)
|
||||
private IdFunction newIdFunction(Object tag, int id, String name,
|
||||
int arity, Scriptable scope)
|
||||
{
|
||||
return newIdFunction(getIdName(id), id, scope);
|
||||
}
|
||||
|
||||
protected IdFunction newIdFunction(String name, int id, Scriptable scope)
|
||||
{
|
||||
IdFunction f = new IdFunction(this, null, id, name, methodArity(id),
|
||||
IdFunction f = new IdFunction(this, tag, id, name, arity,
|
||||
scope);
|
||||
if (isSealed()) { f.sealObject(); }
|
||||
return f;
|
||||
}
|
||||
|
||||
protected IdFunction newConstructor(Scriptable scope)
|
||||
{
|
||||
int constructorId = mapNameToId("constructor");
|
||||
if (constructorId == 0) {
|
||||
throw new IllegalStateException("No id for constructor property");
|
||||
}
|
||||
return newIdFunction(getClassName(), constructorId, scope);
|
||||
}
|
||||
|
||||
protected final Object wrap_double(double x)
|
||||
{
|
||||
return (x == x) ? new Double(x) : ScriptRuntime.NaNobj;
|
||||
|
@ -514,32 +735,7 @@ public abstract class IdScriptable extends ScriptableObject
|
|||
return x ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
private boolean hasValue(int id)
|
||||
{
|
||||
Object value;
|
||||
Object[] data = idMapData;
|
||||
if (data == null || (value = data[id - 1]) == null) {
|
||||
return hasIdValue(id);
|
||||
}
|
||||
else {
|
||||
return value != NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
// Must be called only from synchronized (this)
|
||||
private Object[] ensureIdData()
|
||||
{
|
||||
Object[] data = idMapData;
|
||||
if (data == null) {
|
||||
idMapData = data = new Object[CACHE_NAMES ? maxId * 2 : maxId];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private int maxId;
|
||||
private Object[] idMapData;
|
||||
|
||||
private static final boolean CACHE_NAMES = true;
|
||||
private int lastIdCache;
|
||||
private int maxInstanceId;
|
||||
private volatile PrototypeValues prototypeValues;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ import java.io.Serializable;
|
|||
*/
|
||||
public class ImporterTopLevel extends IdScriptable
|
||||
{
|
||||
private static final Object IMPORTER_TAG = new Object();
|
||||
|
||||
public ImporterTopLevel() { }
|
||||
|
||||
public ImporterTopLevel(Context cx) {
|
||||
|
@ -92,24 +94,26 @@ public class ImporterTopLevel extends IdScriptable
|
|||
public static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
ImporterTopLevel obj = new ImporterTopLevel();
|
||||
obj.prototypeFlag = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public void initStandardObjects(Context cx, boolean sealed)
|
||||
{
|
||||
// Assume that Context.initStandardObjects initialize JavaImporter
|
||||
// property lazily so the above init call is not yet called
|
||||
cx.initStandardObjects(this, sealed);
|
||||
prototypeFlag = true;
|
||||
topScopeFlag = true;
|
||||
// topScopeFlag hides constructor property so constructor name
|
||||
// would refer to constructor property in the prototype of the scope
|
||||
// If seal is true then exportAsJSClass(cx, seal) would seal
|
||||
// this obj. Since this is scope as well, it would not allow
|
||||
// to add variables.
|
||||
IdFunction ctor = exportAsJSClass(MAX_PROTOTYPE_ID, this, false);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
// delete "constructor" defined by exportAsJSClass so "constructor"
|
||||
// name would refer to Object.constructor
|
||||
// and not to JavaImporter.prototype.constructor.
|
||||
// For this reason addAsPrototype can not be used to replace
|
||||
// the following 4 lines as it requires to have id for "constructor".
|
||||
setMaxId(MAX_PROTOTYPE_ID);
|
||||
IdFunction ctor = newIdFunction("JavaImporter", Id_constructor, this);
|
||||
ctor.markAsConstructor(this);
|
||||
ctor.exportAsScopeProperty(sealed);
|
||||
delete("constructor");
|
||||
}
|
||||
|
||||
public boolean has(String name, Scriptable start) {
|
||||
|
@ -170,7 +174,7 @@ public class ImporterTopLevel extends IdScriptable
|
|||
}
|
||||
}
|
||||
// set explicitly prototype and scope
|
||||
// as otherwise in topScopeFlag mode BaseFunction.construct
|
||||
// as otherwise in top scope mode BaseFunction.construct
|
||||
// would keep them set to null. It also allow to use
|
||||
// JavaImporter without new and still get properly
|
||||
// initialized object.
|
||||
|
@ -232,22 +236,37 @@ public class ImporterTopLevel extends IdScriptable
|
|||
put(n, this, cl);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=0; s="constructor"; break;
|
||||
case Id_importClass: arity=1; s="importClass"; break;
|
||||
case Id_importPackage: arity=1; s="importPackage"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(IMPORTER_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (f.methodId()) {
|
||||
case Id_constructor:
|
||||
return js_construct(scope, args);
|
||||
|
||||
case Id_importClass:
|
||||
return realThis(thisObj, f).js_importClass(args);
|
||||
|
||||
case Id_importPackage:
|
||||
return realThis(thisObj, f).js_importPackage(args);
|
||||
}
|
||||
if (!f.hasTag(IMPORTER_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return js_construct(scope, args);
|
||||
|
||||
case Id_importClass:
|
||||
return realThis(thisObj, f).js_importClass(args);
|
||||
|
||||
case Id_importPackage:
|
||||
return realThis(thisObj, f).js_importPackage(args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static ImporterTopLevel realThis(Scriptable thisObj, IdFunction f)
|
||||
|
@ -257,33 +276,10 @@ public class ImporterTopLevel extends IdScriptable
|
|||
return (ImporterTopLevel)thisObj;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_importClass: return "importClass";
|
||||
case Id_importPackage: return "importPackage";
|
||||
}
|
||||
}
|
||||
return super.getIdName(id);
|
||||
}
|
||||
|
||||
public int methodArity(int methodId) {
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 0;
|
||||
case Id_importClass: return 1;
|
||||
case Id_importPackage: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s) {
|
||||
if (!prototypeFlag) { return 0; }
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-06-08 02:03:11 CEST
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -297,11 +293,6 @@ public class ImporterTopLevel extends IdScriptable
|
|||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == Id_constructor && topScopeFlag) {
|
||||
// see comments in initStandardObjects
|
||||
id = 0;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -314,7 +305,5 @@ public class ImporterTopLevel extends IdScriptable
|
|||
// #/string_id_map#
|
||||
|
||||
private ObjArray importedPackages = new ObjArray();
|
||||
|
||||
private boolean prototypeFlag;
|
||||
private boolean topScopeFlag;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,10 @@ public final class JavaAdapter implements IdFunctionMaster
|
|||
IdFunction ctor = new IdFunction(obj, FTAG, Id_JavaAdapter,
|
||||
"JavaAdapter", 1, scope);
|
||||
ctor.markAsConstructor(null);
|
||||
ctor.exportAsScopeProperty(sealed);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
|
|
|
@ -61,11 +61,12 @@ public class NativeArray extends IdScriptable {
|
|||
* always gets at least an object back, even when Array == null.
|
||||
*/
|
||||
|
||||
private static final Object ARRAY_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeArray obj = new NativeArray();
|
||||
obj.prototypeFlag = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,81 +102,120 @@ public class NativeArray extends IdScriptable {
|
|||
return "Array";
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
MAX_INSTANCE_ID = 1;
|
||||
|
||||
{
|
||||
if (id == Id_length) {
|
||||
return DONTENUM | PERMANENT;
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
setMaxInstanceId(0, MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
if (s.equals("length")) {
|
||||
return instanceIdInfo(DONTENUM | PERMANENT, Id_length);
|
||||
}
|
||||
return super.findInstanceIdInfo(s);
|
||||
}
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
if (id == Id_length) { return "length"; }
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
if (id == Id_length) {
|
||||
return wrap_double(length);
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setIdValue(int id, Object value)
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
if (id == Id_length) {
|
||||
setLength(value); return;
|
||||
}
|
||||
super.setIdValue(id, value);
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toLocaleString: arity=1; s="toLocaleString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_join: arity=1; s="join"; break;
|
||||
case Id_reverse: arity=0; s="reverse"; break;
|
||||
case Id_sort: arity=1; s="sort"; break;
|
||||
case Id_push: arity=1; s="push"; break;
|
||||
case Id_pop: arity=1; s="pop"; break;
|
||||
case Id_shift: arity=1; s="shift"; break;
|
||||
case Id_unshift: arity=1; s="unshift"; break;
|
||||
case Id_splice: arity=1; s="splice"; break;
|
||||
case Id_concat: arity=1; s="concat"; break;
|
||||
case Id_slice: arity=1; s="slice"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(ARRAY_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (f.methodId()) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, scope, args, f, thisObj == null);
|
||||
|
||||
case Id_toString:
|
||||
return toStringHelper(cx, scope, thisObj,
|
||||
cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE),
|
||||
false);
|
||||
|
||||
case Id_toLocaleString:
|
||||
return toStringHelper(cx, scope, thisObj, false, true);
|
||||
|
||||
case Id_toSource:
|
||||
return toStringHelper(cx, scope, thisObj, true, false);
|
||||
|
||||
case Id_join:
|
||||
return js_join(cx, thisObj, args);
|
||||
|
||||
case Id_reverse:
|
||||
return js_reverse(cx, thisObj, args);
|
||||
|
||||
case Id_sort:
|
||||
return js_sort(cx, scope, thisObj, args);
|
||||
|
||||
case Id_push:
|
||||
return js_push(cx, thisObj, args);
|
||||
|
||||
case Id_pop:
|
||||
return js_pop(cx, thisObj, args);
|
||||
|
||||
case Id_shift:
|
||||
return js_shift(cx, thisObj, args);
|
||||
|
||||
case Id_unshift:
|
||||
return js_unshift(cx, thisObj, args);
|
||||
|
||||
case Id_splice:
|
||||
return js_splice(cx, scope, thisObj, args);
|
||||
|
||||
case Id_concat:
|
||||
return js_concat(cx, scope, thisObj, args);
|
||||
|
||||
case Id_slice:
|
||||
return js_slice(cx, thisObj, args);
|
||||
}
|
||||
if (!f.hasTag(ARRAY_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return jsConstructor(cx, scope, args, f, thisObj == null);
|
||||
|
||||
case Id_toString:
|
||||
return toStringHelper(cx, scope, thisObj,
|
||||
cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE), false);
|
||||
|
||||
case Id_toLocaleString:
|
||||
return toStringHelper(cx, scope, thisObj, false, true);
|
||||
|
||||
case Id_toSource:
|
||||
return toStringHelper(cx, scope, thisObj, true, false);
|
||||
|
||||
case Id_join:
|
||||
return js_join(cx, thisObj, args);
|
||||
|
||||
case Id_reverse:
|
||||
return js_reverse(cx, thisObj, args);
|
||||
|
||||
case Id_sort:
|
||||
return js_sort(cx, scope, thisObj, args);
|
||||
|
||||
case Id_push:
|
||||
return js_push(cx, thisObj, args);
|
||||
|
||||
case Id_pop:
|
||||
return js_pop(cx, thisObj, args);
|
||||
|
||||
case Id_shift:
|
||||
return js_shift(cx, thisObj, args);
|
||||
|
||||
case Id_unshift:
|
||||
return js_unshift(cx, thisObj, args);
|
||||
|
||||
case Id_splice:
|
||||
return js_splice(cx, scope, thisObj, args);
|
||||
|
||||
case Id_concat:
|
||||
return js_concat(cx, scope, thisObj, args);
|
||||
|
||||
case Id_slice:
|
||||
return js_slice(cx, thisObj, args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
public Object get(int index, Scriptable start)
|
||||
|
@ -642,12 +682,10 @@ public class NativeArray extends IdScriptable {
|
|||
Object cmp, Object[] cmpBuf)
|
||||
throws JavaScriptException
|
||||
{
|
||||
if (check) {
|
||||
if (cmp == null) {
|
||||
if (cmpBuf != null) Kit.codeBug();
|
||||
} else {
|
||||
if (cmpBuf == null || cmpBuf.length != 2) Kit.codeBug();
|
||||
}
|
||||
if (cmp == null) {
|
||||
if (cmpBuf != null) Kit.codeBug();
|
||||
} else {
|
||||
if (cmpBuf == null || cmpBuf.length != 2) Kit.codeBug();
|
||||
}
|
||||
|
||||
Object undef = Undefined.instance;
|
||||
|
@ -692,7 +730,7 @@ public class NativeArray extends IdScriptable {
|
|||
Object cmp, Object[] cmpBuf)
|
||||
throws JavaScriptException
|
||||
{
|
||||
if (check && length <= 1) Kit.codeBug();
|
||||
if (length <= 1) Kit.codeBug();
|
||||
|
||||
// Build heap
|
||||
for (int i = length / 2; i != 0;) {
|
||||
|
@ -747,7 +785,7 @@ public class NativeArray extends IdScriptable {
|
|||
Object cmp, Object[] cmpBuf)
|
||||
throws JavaScriptException
|
||||
{
|
||||
if (check && length <= 1) Kit.codeBug();
|
||||
if (length <= 1) Kit.codeBug();
|
||||
|
||||
// Build heap
|
||||
for (long i = length / 2; i != 0;) {
|
||||
|
@ -1088,72 +1126,10 @@ public class NativeArray extends IdScriptable {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (id == Id_length) { return "length"; }
|
||||
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toLocaleString: return "toLocaleString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_join: return "join";
|
||||
case Id_reverse: return "reverse";
|
||||
case Id_sort: return "sort";
|
||||
case Id_push: return "push";
|
||||
case Id_pop: return "pop";
|
||||
case Id_shift: return "shift";
|
||||
case Id_unshift: return "unshift";
|
||||
case Id_splice: return "splice";
|
||||
case Id_concat: return "concat";
|
||||
case Id_slice: return "slice";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toLocaleString: return 1;
|
||||
case Id_toSource: return 0;
|
||||
case Id_join: return 1;
|
||||
case Id_reverse: return 0;
|
||||
case Id_sort: return 1;
|
||||
case Id_push: return 1;
|
||||
case Id_pop: return 1;
|
||||
case Id_shift: return 1;
|
||||
case Id_unshift: return 1;
|
||||
case Id_splice: return 1;
|
||||
case Id_concat: return 1;
|
||||
case Id_slice: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
MAX_INSTANCE_ID = 1;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
{
|
||||
if (s.equals("length")) { return Id_length; }
|
||||
else if (prototypeFlag) {
|
||||
return toPrototypeId(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static int toPrototypeId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:17:02 CET
|
||||
|
@ -1191,30 +1167,26 @@ public class NativeArray extends IdScriptable {
|
|||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = MAX_INSTANCE_ID + 1,
|
||||
Id_toString = MAX_INSTANCE_ID + 2,
|
||||
Id_toLocaleString = MAX_INSTANCE_ID + 3,
|
||||
Id_toSource = MAX_INSTANCE_ID + 4,
|
||||
Id_join = MAX_INSTANCE_ID + 5,
|
||||
Id_reverse = MAX_INSTANCE_ID + 6,
|
||||
Id_sort = MAX_INSTANCE_ID + 7,
|
||||
Id_push = MAX_INSTANCE_ID + 8,
|
||||
Id_pop = MAX_INSTANCE_ID + 9,
|
||||
Id_shift = MAX_INSTANCE_ID + 10,
|
||||
Id_unshift = MAX_INSTANCE_ID + 11,
|
||||
Id_splice = MAX_INSTANCE_ID + 12,
|
||||
Id_concat = MAX_INSTANCE_ID + 13,
|
||||
Id_slice = MAX_INSTANCE_ID + 14,
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toLocaleString = 3,
|
||||
Id_toSource = 4,
|
||||
Id_join = 5,
|
||||
Id_reverse = 6,
|
||||
Id_sort = 7,
|
||||
Id_push = 8,
|
||||
Id_pop = 9,
|
||||
Id_shift = 10,
|
||||
Id_unshift = 11,
|
||||
Id_splice = 12,
|
||||
Id_concat = 13,
|
||||
Id_slice = 14,
|
||||
|
||||
MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 14;
|
||||
MAX_PROTOTYPE_ID = 14;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private long length;
|
||||
private Object[] dense;
|
||||
private static final int maximumDenseLength = 10000;
|
||||
|
||||
private boolean prototypeFlag;
|
||||
|
||||
private static final boolean check = true && Context.check;
|
||||
}
|
||||
|
|
|
@ -42,19 +42,23 @@ package org.mozilla.javascript;
|
|||
* See ECMA 15.6.
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
final class NativeBoolean extends IdScriptable {
|
||||
final class NativeBoolean extends IdScriptable
|
||||
{
|
||||
private static final Object BOOLEAN_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed) {
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeBoolean obj = new NativeBoolean(false);
|
||||
obj.prototypeFlag = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
private NativeBoolean(boolean b) {
|
||||
private NativeBoolean(boolean b)
|
||||
{
|
||||
booleanValue = b;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
public String getClassName()
|
||||
{
|
||||
return "Boolean";
|
||||
}
|
||||
|
||||
|
@ -66,36 +70,51 @@ final class NativeBoolean extends IdScriptable {
|
|||
return super.getDefaultValue(typeHint);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(BOOLEAN_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
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.
|
||||
return new NativeBoolean(b);
|
||||
}
|
||||
// Boolean(val) converts val to a boolean.
|
||||
return wrap_boolean(b);
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
return realThisBoolean(thisObj, f) ? "true" : "false";
|
||||
|
||||
case Id_toSource:
|
||||
if (realThisBoolean(thisObj, f))
|
||||
return "(new Boolean(true))";
|
||||
else
|
||||
return "(new Boolean(false))";
|
||||
|
||||
case Id_valueOf:
|
||||
return wrap_boolean(realThisBoolean(thisObj, f));
|
||||
}
|
||||
if (!f.hasTag(BOOLEAN_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor: {
|
||||
boolean b = ScriptRuntime.toBoolean(args, 0);
|
||||
if (thisObj == null) {
|
||||
// new Boolean(val) creates a new boolean object.
|
||||
return new NativeBoolean(b);
|
||||
}
|
||||
// Boolean(val) converts val to a boolean.
|
||||
return wrap_boolean(b);
|
||||
}
|
||||
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
case Id_toString:
|
||||
return realThisBoolean(thisObj, f) ? "true" : "false";
|
||||
|
||||
case Id_toSource:
|
||||
if (realThisBoolean(thisObj, f))
|
||||
return "(new Boolean(true))";
|
||||
else
|
||||
return "(new Boolean(false))";
|
||||
|
||||
case Id_valueOf:
|
||||
return wrap_boolean(realThisBoolean(thisObj, f));
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static boolean realThisBoolean(Scriptable thisObj, IdFunction f)
|
||||
|
@ -105,35 +124,10 @@ final class NativeBoolean extends IdScriptable {
|
|||
return ((NativeBoolean)thisObj).booleanValue;
|
||||
}
|
||||
|
||||
protected String getIdName(int id) {
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_valueOf: return "valueOf";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toSource: return 0;
|
||||
case Id_valueOf: return 0;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s) {
|
||||
if (!prototypeFlag) { return 0; }
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:28:00 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -161,6 +155,4 @@ final class NativeBoolean extends IdScriptable {
|
|||
// #/string_id_map#
|
||||
|
||||
private boolean booleanValue;
|
||||
|
||||
private boolean prototypeFlag;
|
||||
}
|
||||
|
|
|
@ -43,11 +43,14 @@ package org.mozilla.javascript;
|
|||
* @see org.mozilla.javascript.Arguments
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
public final class NativeCall extends ScriptableObject
|
||||
public final class NativeCall extends IdScriptable
|
||||
{
|
||||
private static final Object CALL_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
new NativeCallPrototype(cx, scope, sealed);
|
||||
NativeCall obj = new NativeCall();
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
NativeCall() { }
|
||||
|
@ -129,28 +132,26 @@ public final class NativeCall extends ScriptableObject
|
|||
return thisObj;
|
||||
}
|
||||
|
||||
NativeCall caller;
|
||||
NativeFunction funObj;
|
||||
Scriptable thisObj;
|
||||
private Object[] originalArgs;
|
||||
}
|
||||
|
||||
final class NativeCallPrototype extends IdScriptable
|
||||
{
|
||||
NativeCallPrototype(Context cx, Scriptable scope, boolean sealed)
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
}
|
||||
|
||||
public String getClassName()
|
||||
{
|
||||
return "Call";
|
||||
String s;
|
||||
int arity;
|
||||
if (id == Id_constructor) {
|
||||
arity=1; s="constructor";
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(CALL_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (f.methodId() == Id_constructor) {
|
||||
if (!f.hasTag(CALL_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
if (id == Id_constructor) {
|
||||
if (thisObj != null) {
|
||||
throw Context.reportRuntimeError1("msg.only.from.new", "Call");
|
||||
}
|
||||
|
@ -159,22 +160,10 @@ final class NativeCallPrototype extends IdScriptable
|
|||
result.setPrototype(getObjectPrototype(scope));
|
||||
return result;
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (id == Id_constructor) return "constructor";
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (methodId == Id_constructor) return 1;
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
return s.equals("constructor") ? Id_constructor : 0;
|
||||
}
|
||||
|
@ -182,4 +171,11 @@ final class NativeCallPrototype extends IdScriptable
|
|||
private static final int
|
||||
Id_constructor = 1,
|
||||
MAX_PROTOTYPE_ID = 1;
|
||||
|
||||
|
||||
NativeCall caller;
|
||||
NativeFunction funObj;
|
||||
Scriptable thisObj;
|
||||
private Object[] originalArgs;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,15 +50,14 @@ import java.text.SimpleDateFormat;
|
|||
*/
|
||||
final class NativeDate extends IdScriptable
|
||||
{
|
||||
private static final Object DATE_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeDate obj = new NativeDate();
|
||||
obj.prototypeFlag = true;
|
||||
|
||||
// Set the value of the prototype Date to NaN ('invalid date');
|
||||
obj.date = ScriptRuntime.NaN;
|
||||
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
private NativeDate()
|
||||
|
@ -88,209 +87,254 @@ final class NativeDate extends IdScriptable
|
|||
return date;
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor, boolean sealed)
|
||||
protected void fillConstructorProperties(IdFunction ctor)
|
||||
{
|
||||
addIdFunctionProperty(ctor, ConstructorId_now, sealed);
|
||||
addIdFunctionProperty(ctor, ConstructorId_parse, sealed);
|
||||
addIdFunctionProperty(ctor, ConstructorId_UTC, sealed);
|
||||
super.fillConstructorProperties(ctor, sealed);
|
||||
addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_now,
|
||||
"now", 0);
|
||||
addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_parse,
|
||||
"parse", 1);
|
||||
addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_UTC,
|
||||
"UTC", 1);
|
||||
super.fillConstructorProperties(ctor);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toTimeString: arity=0; s="toTimeString"; break;
|
||||
case Id_toDateString: arity=0; s="toDateString"; break;
|
||||
case Id_toLocaleString: arity=0; s="toLocaleString"; break;
|
||||
case Id_toLocaleTimeString: arity=0; s="toLocaleTimeString"; break;
|
||||
case Id_toLocaleDateString: arity=0; s="toLocaleDateString"; break;
|
||||
case Id_toUTCString: arity=0; s="toUTCString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
case Id_getTime: arity=0; s="getTime"; break;
|
||||
case Id_getYear: arity=0; s="getYear"; break;
|
||||
case Id_getFullYear: arity=0; s="getFullYear"; break;
|
||||
case Id_getUTCFullYear: arity=0; s="getUTCFullYear"; break;
|
||||
case Id_getMonth: arity=0; s="getMonth"; break;
|
||||
case Id_getUTCMonth: arity=0; s="getUTCMonth"; break;
|
||||
case Id_getDate: arity=0; s="getDate"; break;
|
||||
case Id_getUTCDate: arity=0; s="getUTCDate"; break;
|
||||
case Id_getDay: arity=0; s="getDay"; break;
|
||||
case Id_getUTCDay: arity=0; s="getUTCDay"; break;
|
||||
case Id_getHours: arity=0; s="getHours"; break;
|
||||
case Id_getUTCHours: arity=0; s="getUTCHours"; break;
|
||||
case Id_getMinutes: arity=0; s="getMinutes"; break;
|
||||
case Id_getUTCMinutes: arity=0; s="getUTCMinutes"; break;
|
||||
case Id_getSeconds: arity=0; s="getSeconds"; break;
|
||||
case Id_getUTCSeconds: arity=0; s="getUTCSeconds"; break;
|
||||
case Id_getMilliseconds: arity=0; s="getMilliseconds"; break;
|
||||
case Id_getUTCMilliseconds: arity=0; s="getUTCMilliseconds"; break;
|
||||
case Id_getTimezoneOffset: arity=0; s="getTimezoneOffset"; break;
|
||||
case Id_setTime: arity=1; s="setTime"; break;
|
||||
case Id_setMilliseconds: arity=1; s="setMilliseconds"; break;
|
||||
case Id_setUTCMilliseconds: arity=1; s="setUTCMilliseconds"; break;
|
||||
case Id_setSeconds: arity=2; s="setSeconds"; break;
|
||||
case Id_setUTCSeconds: arity=2; s="setUTCSeconds"; break;
|
||||
case Id_setMinutes: arity=3; s="setMinutes"; break;
|
||||
case Id_setUTCMinutes: arity=3; s="setUTCMinutes"; break;
|
||||
case Id_setHours: arity=4; s="setHours"; break;
|
||||
case Id_setUTCHours: arity=4; s="setUTCHours"; break;
|
||||
case Id_setDate: arity=1; s="setDate"; break;
|
||||
case Id_setUTCDate: arity=1; s="setUTCDate"; break;
|
||||
case Id_setMonth: arity=2; s="setMonth"; break;
|
||||
case Id_setUTCMonth: arity=2; s="setUTCMonth"; break;
|
||||
case Id_setFullYear: arity=3; s="setFullYear"; break;
|
||||
case Id_setUTCFullYear: arity=3; s="setUTCFullYear"; break;
|
||||
case Id_setYear: arity=1; s="setYear"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(DATE_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
case ConstructorId_parse:
|
||||
return wrap_double(date_parseString
|
||||
(ScriptRuntime.toString(args, 0)));
|
||||
|
||||
case ConstructorId_UTC:
|
||||
return wrap_double(jsStaticFunction_UTC(args));
|
||||
|
||||
case Id_constructor: {
|
||||
// if called as a function, just return a string
|
||||
// representing the current time.
|
||||
if (thisObj != null)
|
||||
return date_format(now(), Id_toString);
|
||||
return jsConstructor(args);
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_toTimeString:
|
||||
case Id_toDateString: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
return date_format(t, methodId);
|
||||
}
|
||||
|
||||
case Id_toLocaleString:
|
||||
case Id_toLocaleTimeString:
|
||||
case Id_toLocaleDateString: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
return toLocale_helper(t, methodId);
|
||||
}
|
||||
|
||||
case Id_toUTCString: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) { return js_toUTCString(t); }
|
||||
return js_NaN_date_str;
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
return "(new Date("+ScriptRuntime.toString(t)+"))";
|
||||
}
|
||||
|
||||
case Id_valueOf:
|
||||
case Id_getTime:
|
||||
return wrap_double(realThis(thisObj, f).date);
|
||||
|
||||
case Id_getYear:
|
||||
case Id_getFullYear:
|
||||
case Id_getUTCFullYear: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId != Id_getUTCFullYear)
|
||||
t = LocalTime(t);
|
||||
t = YearFromTime(t);
|
||||
if (methodId == Id_getYear) {
|
||||
if (cx.hasFeature(
|
||||
Context.FEATURE_NON_ECMA_GET_YEAR))
|
||||
{
|
||||
if (1900 <= t && t < 2000) {
|
||||
t -= 1900;
|
||||
}
|
||||
} else {
|
||||
t -= 1900;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMonth:
|
||||
case Id_getUTCMonth: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getMonth)
|
||||
t = LocalTime(t);
|
||||
t = MonthFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getDate:
|
||||
case Id_getUTCDate: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getDate)
|
||||
t = LocalTime(t);
|
||||
t = DateFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getDay:
|
||||
case Id_getUTCDay: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getDay)
|
||||
t = LocalTime(t);
|
||||
t = WeekDay(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getHours:
|
||||
case Id_getUTCHours: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getHours)
|
||||
t = LocalTime(t);
|
||||
t = HourFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMinutes:
|
||||
case Id_getUTCMinutes: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getMinutes)
|
||||
t = LocalTime(t);
|
||||
t = MinFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getSeconds:
|
||||
case Id_getUTCSeconds: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getSeconds)
|
||||
t = LocalTime(t);
|
||||
t = SecFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMilliseconds:
|
||||
case Id_getUTCMilliseconds: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (methodId == Id_getMilliseconds)
|
||||
t = LocalTime(t);
|
||||
t = msFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getTimezoneOffset: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
t = (t - LocalTime(t)) / msPerMinute;
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_setTime: {
|
||||
NativeDate real = realThis(thisObj, f);
|
||||
double t = ScriptRuntime.toNumber(args, 0);
|
||||
real.date = TimeClip(t);
|
||||
return wrap_double(real.date);
|
||||
}
|
||||
|
||||
case Id_setMilliseconds:
|
||||
case Id_setUTCMilliseconds:
|
||||
case Id_setSeconds:
|
||||
case Id_setUTCSeconds:
|
||||
case Id_setMinutes:
|
||||
case Id_setUTCMinutes:
|
||||
case Id_setHours:
|
||||
case Id_setUTCHours:
|
||||
return wrap_double(
|
||||
realThis(thisObj, f).makeTime(args, methodId));
|
||||
|
||||
case Id_setDate:
|
||||
case Id_setUTCDate:
|
||||
case Id_setMonth:
|
||||
case Id_setUTCMonth:
|
||||
case Id_setFullYear:
|
||||
case Id_setUTCFullYear:
|
||||
return wrap_double(
|
||||
realThis(thisObj, f).makeDate(args, methodId));
|
||||
|
||||
case Id_setYear:
|
||||
return wrap_double(realThis(thisObj, f).
|
||||
js_setYear(ScriptRuntime.toNumber(args, 0)));
|
||||
}
|
||||
if (!f.hasTag(DATE_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case ConstructorId_now:
|
||||
return wrap_double(now());
|
||||
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
case ConstructorId_parse: {
|
||||
String dataStr = ScriptRuntime.toString(args, 0);
|
||||
return wrap_double(date_parseString(dataStr));
|
||||
}
|
||||
|
||||
case ConstructorId_UTC:
|
||||
return wrap_double(jsStaticFunction_UTC(args));
|
||||
|
||||
case Id_constructor: {
|
||||
// if called as a function, just return a string
|
||||
// representing the current time.
|
||||
if (thisObj != null)
|
||||
return date_format(now(), Id_toString);
|
||||
return jsConstructor(args);
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_toTimeString:
|
||||
case Id_toDateString:
|
||||
return date_format(realThis(thisObj, f).date, id);
|
||||
|
||||
case Id_toLocaleString:
|
||||
case Id_toLocaleTimeString:
|
||||
case Id_toLocaleDateString:
|
||||
return toLocale_helper(realThis(thisObj, f).date, id);
|
||||
|
||||
case Id_toUTCString: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) { return js_toUTCString(t); }
|
||||
return js_NaN_date_str;
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
return "(new Date("+ScriptRuntime.toString(t)+"))";
|
||||
}
|
||||
|
||||
case Id_valueOf:
|
||||
case Id_getTime:
|
||||
return wrap_double(realThis(thisObj, f).date);
|
||||
|
||||
case Id_getYear:
|
||||
case Id_getFullYear:
|
||||
case Id_getUTCFullYear: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id != Id_getUTCFullYear) t = LocalTime(t);
|
||||
t = YearFromTime(t);
|
||||
if (id == Id_getYear) {
|
||||
if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) {
|
||||
if (1900 <= t && t < 2000) {
|
||||
t -= 1900;
|
||||
}
|
||||
} else {
|
||||
t -= 1900;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMonth:
|
||||
case Id_getUTCMonth: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getMonth) t = LocalTime(t);
|
||||
t = MonthFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getDate:
|
||||
case Id_getUTCDate: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getDate) t = LocalTime(t);
|
||||
t = DateFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getDay:
|
||||
case Id_getUTCDay: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getDay) t = LocalTime(t);
|
||||
t = WeekDay(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getHours:
|
||||
case Id_getUTCHours: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getHours) t = LocalTime(t);
|
||||
t = HourFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMinutes:
|
||||
case Id_getUTCMinutes: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getMinutes) t = LocalTime(t);
|
||||
t = MinFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getSeconds:
|
||||
case Id_getUTCSeconds: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getSeconds) t = LocalTime(t);
|
||||
t = SecFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getMilliseconds:
|
||||
case Id_getUTCMilliseconds: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
if (id == Id_getMilliseconds) t = LocalTime(t);
|
||||
t = msFromTime(t);
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_getTimezoneOffset: {
|
||||
double t = realThis(thisObj, f).date;
|
||||
if (t == t) {
|
||||
t = (t - LocalTime(t)) / msPerMinute;
|
||||
}
|
||||
return wrap_double(t);
|
||||
}
|
||||
|
||||
case Id_setTime: {
|
||||
NativeDate real = realThis(thisObj, f);
|
||||
double t = ScriptRuntime.toNumber(args, 0);
|
||||
real.date = TimeClip(t);
|
||||
return wrap_double(real.date);
|
||||
}
|
||||
|
||||
case Id_setMilliseconds:
|
||||
case Id_setUTCMilliseconds:
|
||||
case Id_setSeconds:
|
||||
case Id_setUTCSeconds:
|
||||
case Id_setMinutes:
|
||||
case Id_setUTCMinutes:
|
||||
case Id_setHours:
|
||||
case Id_setUTCHours:
|
||||
return wrap_double(realThis(thisObj, f).makeTime(args, id));
|
||||
|
||||
case Id_setDate:
|
||||
case Id_setUTCDate:
|
||||
case Id_setMonth:
|
||||
case Id_setUTCMonth:
|
||||
case Id_setFullYear:
|
||||
case Id_setUTCFullYear:
|
||||
return wrap_double(realThis(thisObj, f).makeDate(args, id));
|
||||
|
||||
case Id_setYear: {
|
||||
double year = ScriptRuntime.toNumber(args, 0);
|
||||
return wrap_double(realThis(thisObj, f).js_setYear(year));
|
||||
}
|
||||
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
}
|
||||
|
||||
private static NativeDate realThis(Scriptable thisObj, IdFunction f)
|
||||
|
@ -1418,125 +1462,10 @@ final class NativeDate extends IdScriptable
|
|||
return this.date;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case ConstructorId_now: return "now";
|
||||
case ConstructorId_parse: return "parse";
|
||||
case ConstructorId_UTC: return "UTC";
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toTimeString: return "toTimeString";
|
||||
case Id_toDateString: return "toDateString";
|
||||
case Id_toLocaleString: return "toLocaleString";
|
||||
case Id_toLocaleTimeString: return "toLocaleTimeString";
|
||||
case Id_toLocaleDateString: return "toLocaleDateString";
|
||||
case Id_toUTCString: return "toUTCString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_valueOf: return "valueOf";
|
||||
case Id_getTime: return "getTime";
|
||||
case Id_getYear: return "getYear";
|
||||
case Id_getFullYear: return "getFullYear";
|
||||
case Id_getUTCFullYear: return "getUTCFullYear";
|
||||
case Id_getMonth: return "getMonth";
|
||||
case Id_getUTCMonth: return "getUTCMonth";
|
||||
case Id_getDate: return "getDate";
|
||||
case Id_getUTCDate: return "getUTCDate";
|
||||
case Id_getDay: return "getDay";
|
||||
case Id_getUTCDay: return "getUTCDay";
|
||||
case Id_getHours: return "getHours";
|
||||
case Id_getUTCHours: return "getUTCHours";
|
||||
case Id_getMinutes: return "getMinutes";
|
||||
case Id_getUTCMinutes: return "getUTCMinutes";
|
||||
case Id_getSeconds: return "getSeconds";
|
||||
case Id_getUTCSeconds: return "getUTCSeconds";
|
||||
case Id_getMilliseconds: return "getMilliseconds";
|
||||
case Id_getUTCMilliseconds: return "getUTCMilliseconds";
|
||||
case Id_getTimezoneOffset: return "getTimezoneOffset";
|
||||
case Id_setTime: return "setTime";
|
||||
case Id_setMilliseconds: return "setMilliseconds";
|
||||
case Id_setUTCMilliseconds: return "setUTCMilliseconds";
|
||||
case Id_setSeconds: return "setSeconds";
|
||||
case Id_setUTCSeconds: return "setUTCSeconds";
|
||||
case Id_setMinutes: return "setMinutes";
|
||||
case Id_setUTCMinutes: return "setUTCMinutes";
|
||||
case Id_setHours: return "setHours";
|
||||
case Id_setUTCHours: return "setUTCHours";
|
||||
case Id_setDate: return "setDate";
|
||||
case Id_setUTCDate: return "setUTCDate";
|
||||
case Id_setMonth: return "setMonth";
|
||||
case Id_setUTCMonth: return "setUTCMonth";
|
||||
case Id_setFullYear: return "setFullYear";
|
||||
case Id_setUTCFullYear: return "setUTCFullYear";
|
||||
case Id_setYear: return "setYear";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case ConstructorId_now: return 0;
|
||||
case ConstructorId_parse: return 1;
|
||||
case ConstructorId_UTC: return 1;
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toTimeString: return 0;
|
||||
case Id_toDateString: return 0;
|
||||
case Id_toLocaleString: return 0;
|
||||
case Id_toLocaleTimeString: return 0;
|
||||
case Id_toLocaleDateString: return 0;
|
||||
case Id_toUTCString: return 0;
|
||||
case Id_toSource: return 0;
|
||||
case Id_valueOf: return 0;
|
||||
case Id_getTime: return 0;
|
||||
case Id_getYear: return 0;
|
||||
case Id_getFullYear: return 0;
|
||||
case Id_getUTCFullYear: return 0;
|
||||
case Id_getMonth: return 0;
|
||||
case Id_getUTCMonth: return 0;
|
||||
case Id_getDate: return 0;
|
||||
case Id_getUTCDate: return 0;
|
||||
case Id_getDay: return 0;
|
||||
case Id_getUTCDay: return 0;
|
||||
case Id_getHours: return 0;
|
||||
case Id_getUTCHours: return 0;
|
||||
case Id_getMinutes: return 0;
|
||||
case Id_getUTCMinutes: return 0;
|
||||
case Id_getSeconds: return 0;
|
||||
case Id_getUTCSeconds: return 0;
|
||||
case Id_getMilliseconds: return 0;
|
||||
case Id_getUTCMilliseconds: return 0;
|
||||
case Id_getTimezoneOffset: return 0;
|
||||
case Id_setTime: return 1;
|
||||
case Id_setMilliseconds: return 1;
|
||||
case Id_setUTCMilliseconds: return 1;
|
||||
case Id_setSeconds: return 2;
|
||||
case Id_setUTCSeconds: return 2;
|
||||
case Id_setMinutes: return 3;
|
||||
case Id_setUTCMinutes: return 3;
|
||||
case Id_setHours: return 4;
|
||||
case Id_setUTCHours: return 4;
|
||||
case Id_setDate: return 1;
|
||||
case Id_setUTCDate: return 1;
|
||||
case Id_setMonth: return 2;
|
||||
case Id_setUTCMonth: return 2;
|
||||
case Id_setFullYear: return 3;
|
||||
case Id_setUTCFullYear: return 3;
|
||||
case Id_setYear: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
if (!prototypeFlag) { return 0; }
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:33:23 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -1716,8 +1645,6 @@ final class NativeDate extends IdScriptable
|
|||
private static java.text.DateFormat localeTimeFormatter;
|
||||
|
||||
private double date;
|
||||
|
||||
private boolean prototypeFlag;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,16 +45,16 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
final class NativeError extends IdScriptable
|
||||
{
|
||||
private static final Object ERROR_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeError obj = new NativeError();
|
||||
obj.prototypeFlag = true;
|
||||
ScriptableObject.putProperty(obj, "name", "Error");
|
||||
ScriptableObject.putProperty(obj, "message", "");
|
||||
ScriptableObject.putProperty(obj, "fileName", "");
|
||||
ScriptableObject.putProperty(obj, "lineNumber", new Integer(0));
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
static NativeError make(Context cx, Scriptable scope, IdFunction ctorObj,
|
||||
|
@ -81,22 +81,47 @@ final class NativeError extends IdScriptable
|
|||
return obj;
|
||||
}
|
||||
|
||||
public String getClassName()
|
||||
{
|
||||
return "Error";
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return js_toString(this);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(ERROR_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (f.methodId()) {
|
||||
case Id_constructor:
|
||||
return make(cx, scope, f, args);
|
||||
|
||||
case Id_toString:
|
||||
return js_toString(thisObj);
|
||||
|
||||
case Id_toSource:
|
||||
return js_toSource(cx, scope, thisObj);
|
||||
}
|
||||
if (!f.hasTag(ERROR_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor:
|
||||
return make(cx, scope, f, args);
|
||||
|
||||
case Id_toString:
|
||||
return js_toString(thisObj);
|
||||
|
||||
case Id_toSource:
|
||||
return js_toSource(cx, scope, thisObj);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static String js_toString(Scriptable thisObj)
|
||||
|
@ -148,16 +173,6 @@ final class NativeError extends IdScriptable
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getClassName()
|
||||
{
|
||||
return "Error";
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return js_toString(this);
|
||||
}
|
||||
|
||||
private static String getString(Scriptable obj, String id)
|
||||
{
|
||||
Object value = ScriptableObject.getProperty(obj, id);
|
||||
|
@ -165,35 +180,9 @@ final class NativeError extends IdScriptable
|
|||
return ScriptRuntime.toString(value);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toSource: return "toSource";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toSource: return 0;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
if (!prototypeFlag) { return 0; }
|
||||
|
||||
// #string_id_map#
|
||||
// #generated# Last update: 2004-03-17 13:35:15 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -218,6 +207,4 @@ final class NativeError extends IdScriptable
|
|||
MAX_PROTOTYPE_ID = 3;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private boolean prototypeFlag;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,10 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
throw Kit.codeBug();
|
||||
}
|
||||
IdFunction f = new IdFunction(obj, FTAG, id, name, arity, scope);
|
||||
f.exportAsScopeProperty(sealed);
|
||||
if (sealed) {
|
||||
f.sealObject();
|
||||
}
|
||||
f.exportAsScopeProperty();
|
||||
}
|
||||
|
||||
ScriptableObject.defineProperty(scope, "NaN",
|
||||
|
@ -143,7 +146,10 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
IdFunction ctor = new IdFunction(obj, FTAG, Id_new_CommonError,
|
||||
name, 1, scope);
|
||||
ctor.markAsConstructor(errorProto);
|
||||
ctor.exportAsScopeProperty(sealed);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,10 @@ public class NativeJavaTopPackage
|
|||
// a ScriptableObject.
|
||||
ScriptableObject global = (ScriptableObject) scope;
|
||||
|
||||
getClass.exportAsScopeProperty(sealed);
|
||||
if (sealed) {
|
||||
getClass.sealObject();
|
||||
}
|
||||
getClass.exportAsScopeProperty();
|
||||
global.defineProperty("Packages", top, ScriptableObject.DONTENUM);
|
||||
global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
|
|
@ -44,9 +44,12 @@ package org.mozilla.javascript;
|
|||
|
||||
final class NativeMath extends IdScriptable
|
||||
{
|
||||
private static final Object MATH_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeMath obj = new NativeMath();
|
||||
obj.activatePrototypeMap(MAX_ID);
|
||||
obj.setPrototype(getObjectPrototype(scope));
|
||||
obj.setParentScope(scope);
|
||||
if (sealed) { obj.sealObject(); }
|
||||
|
@ -54,39 +57,65 @@ final class NativeMath extends IdScriptable
|
|||
ScriptableObject.DONTENUM);
|
||||
}
|
||||
|
||||
public String getClassName() { return "Math"; }
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
private NativeMath()
|
||||
{
|
||||
if (id > LAST_METHOD_ID) {
|
||||
return DONTENUM | READONLY | PERMANENT;
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
public String getClassName() { return "Math"; }
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
if (id > LAST_METHOD_ID) {
|
||||
if (id <= LAST_METHOD_ID) {
|
||||
String name;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_toSource: arity = 0; name = "toSource"; break;
|
||||
case Id_abs: arity = 1; name = "abs"; break;
|
||||
case Id_acos: arity = 1; name = "acos"; break;
|
||||
case Id_asin: arity = 1; name = "asin"; break;
|
||||
case Id_atan: arity = 1; name = "atan"; break;
|
||||
case Id_atan2: arity = 2; name = "atan2"; break;
|
||||
case Id_ceil: arity = 1; name = "ceil"; break;
|
||||
case Id_cos: arity = 1; name = "cos"; break;
|
||||
case Id_exp: arity = 1; name = "exp"; break;
|
||||
case Id_floor: arity = 1; name = "floor"; break;
|
||||
case Id_log: arity = 1; name = "log"; break;
|
||||
case Id_max: arity = 2; name = "max"; break;
|
||||
case Id_min: arity = 2; name = "min"; break;
|
||||
case Id_pow: arity = 2; name = "pow"; break;
|
||||
case Id_random: arity = 0; name = "random"; break;
|
||||
case Id_round: arity = 1; name = "round"; break;
|
||||
case Id_sin: arity = 1; name = "sin"; break;
|
||||
case Id_sqrt: arity = 1; name = "sqrt"; break;
|
||||
case Id_tan: arity = 1; name = "tan"; break;
|
||||
default: throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(MATH_TAG, id, name, arity);
|
||||
} else {
|
||||
String name;
|
||||
double x;
|
||||
switch (id) {
|
||||
case Id_E: x = Math.E; break;
|
||||
case Id_PI: x = Math.PI; break;
|
||||
case Id_LN10: x = 2.302585092994046; break;
|
||||
case Id_LN2: x = 0.6931471805599453; break;
|
||||
case Id_LOG2E: x = 1.4426950408889634; break;
|
||||
case Id_LOG10E: x = 0.4342944819032518; break;
|
||||
case Id_SQRT1_2: x = 0.7071067811865476; break;
|
||||
case Id_SQRT2: x = 1.4142135623730951; break;
|
||||
default: /* Unreachable */ x = 0;
|
||||
case Id_E: x = Math.E; name = "E"; break;
|
||||
case Id_PI: x = Math.PI; name = "PI"; break;
|
||||
case Id_LN10: x = 2.302585092994046; name = "LN10"; break;
|
||||
case Id_LN2: x = 0.6931471805599453; name = "LN2"; break;
|
||||
case Id_LOG2E: x = 1.4426950408889634; name = "LOG2E"; break;
|
||||
case Id_LOG10E: x = 0.4342944819032518; name = "LOG10E"; break;
|
||||
case Id_SQRT1_2: x = 0.7071067811865476; name = "SQRT1_2"; break;
|
||||
case Id_SQRT2: x = 1.4142135623730951; name = "SQRT2"; break;
|
||||
default: throw new IllegalStateException(String.valueOf(id));
|
||||
}
|
||||
return cacheIdValue(id, wrap_double(x));
|
||||
initPrototypeValue(id, name, wrap_double(x),
|
||||
DONTENUM | READONLY | PERMANENT);
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(MATH_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
double x;
|
||||
int methodId = f.methodId();
|
||||
switch (methodId) {
|
||||
|
@ -214,8 +243,7 @@ final class NativeMath extends IdScriptable
|
|||
x = Math.tan(x);
|
||||
break;
|
||||
|
||||
default:
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
default: throw new IllegalStateException(String.valueOf(methodId));
|
||||
}
|
||||
return wrap_double(x);
|
||||
}
|
||||
|
@ -275,70 +303,9 @@ final class NativeMath extends IdScriptable
|
|||
return result;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_abs: return "abs";
|
||||
case Id_acos: return "acos";
|
||||
case Id_asin: return "asin";
|
||||
case Id_atan: return "atan";
|
||||
case Id_atan2: return "atan2";
|
||||
case Id_ceil: return "ceil";
|
||||
case Id_cos: return "cos";
|
||||
case Id_exp: return "exp";
|
||||
case Id_floor: return "floor";
|
||||
case Id_log: return "log";
|
||||
case Id_max: return "max";
|
||||
case Id_min: return "min";
|
||||
case Id_pow: return "pow";
|
||||
case Id_random: return "random";
|
||||
case Id_round: return "round";
|
||||
case Id_sin: return "sin";
|
||||
case Id_sqrt: return "sqrt";
|
||||
case Id_tan: return "tan";
|
||||
|
||||
case Id_E: return "E";
|
||||
case Id_PI: return "PI";
|
||||
case Id_LN10: return "LN10";
|
||||
case Id_LN2: return "LN2";
|
||||
case Id_LOG2E: return "LOG2E";
|
||||
case Id_LOG10E: return "LOG10E";
|
||||
case Id_SQRT1_2: return "SQRT1_2";
|
||||
case Id_SQRT2: return "SQRT2";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
switch (methodId) {
|
||||
case Id_toSource: return 0;
|
||||
case Id_abs: return 1;
|
||||
case Id_acos: return 1;
|
||||
case Id_asin: return 1;
|
||||
case Id_atan: return 1;
|
||||
case Id_atan2: return 2;
|
||||
case Id_ceil: return 1;
|
||||
case Id_cos: return 1;
|
||||
case Id_exp: return 1;
|
||||
case Id_floor: return 1;
|
||||
case Id_log: return 1;
|
||||
case Id_max: return 2;
|
||||
case Id_min: return 2;
|
||||
case Id_pow: return 2;
|
||||
case Id_random: return 0;
|
||||
case Id_round: return 1;
|
||||
case Id_sin: return 1;
|
||||
case Id_sqrt: return 1;
|
||||
case Id_tan: return 1;
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:51:32 CET
|
||||
|
@ -421,9 +388,7 @@ final class NativeMath extends IdScriptable
|
|||
Id_SQRT1_2 = LAST_METHOD_ID + 7,
|
||||
Id_SQRT2 = LAST_METHOD_ID + 8,
|
||||
|
||||
MAX_INSTANCE_ID = LAST_METHOD_ID + 8;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
MAX_ID = LAST_METHOD_ID + 8;
|
||||
|
||||
// #/string_id_map#
|
||||
}
|
||||
|
|
|
@ -44,31 +44,29 @@ package org.mozilla.javascript;
|
|||
*
|
||||
* @author Norris Boyd
|
||||
*/
|
||||
final class NativeNumber extends IdScriptable {
|
||||
final class NativeNumber extends IdScriptable
|
||||
{
|
||||
private static final Object NUMBER_TAG = new Object();
|
||||
|
||||
private static final int MAX_PRECISION = 100;
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed) {
|
||||
NativeNumber obj = new NativeNumber();
|
||||
obj.prototypeFlag = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeNumber obj = new NativeNumber(0.0);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-parameter constructor: just used to create Number.prototype
|
||||
*/
|
||||
private NativeNumber() {
|
||||
}
|
||||
|
||||
private NativeNumber(double number) {
|
||||
private NativeNumber(double number)
|
||||
{
|
||||
doubleValue = number;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
public String getClassName()
|
||||
{
|
||||
return "Number";
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor, boolean sealed)
|
||||
protected void fillConstructorProperties(IdFunction ctor)
|
||||
{
|
||||
final int attr = ScriptableObject.DONTENUM |
|
||||
ScriptableObject.PERMANENT |
|
||||
|
@ -82,60 +80,77 @@ final class NativeNumber extends IdScriptable {
|
|||
ctor.defineProperty("MAX_VALUE", wrap_double(Double.MAX_VALUE), attr);
|
||||
ctor.defineProperty("MIN_VALUE", wrap_double(Double.MIN_VALUE), attr);
|
||||
|
||||
super.fillConstructorProperties(ctor, sealed);
|
||||
super.fillConstructorProperties(ctor);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=1; s="toString"; break;
|
||||
case Id_toLocaleString: arity=1; s="toLocaleString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
case Id_toFixed: arity=1; s="toFixed"; break;
|
||||
case Id_toExponential: arity=1; s="toExponential"; break;
|
||||
case Id_toPrecision: arity=1; s="toPrecision"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(NUMBER_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (f.methodId()) {
|
||||
case Id_constructor: {
|
||||
double val = (args.length >= 1)
|
||||
? ScriptRuntime.toNumber(args[0]) : 0.0;
|
||||
if (thisObj == null) {
|
||||
// new Number(val) creates a new Number object.
|
||||
return new NativeNumber(val);
|
||||
}
|
||||
// Number(val) converts val to a number value.
|
||||
return wrap_double(val);
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_toLocaleString: {
|
||||
// toLocaleString is just an alias for toString for now
|
||||
double val = realThisValue(thisObj, f);
|
||||
int base = (args.length == 0)
|
||||
? 10 : ScriptRuntime.toInt32(args[0]);
|
||||
return ScriptRuntime.numberToString(val, base);
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
double val = realThisValue(thisObj, f);
|
||||
return "(new Number("+ScriptRuntime.toString(val)+"))";
|
||||
}
|
||||
|
||||
case Id_valueOf:
|
||||
return wrap_double(realThisValue(thisObj, f));
|
||||
|
||||
case Id_toFixed:
|
||||
return num_to(f, thisObj, args,
|
||||
DToA.DTOSTR_FIXED, DToA.DTOSTR_FIXED,
|
||||
-20, 0);
|
||||
|
||||
case Id_toExponential:
|
||||
return num_to(f, thisObj, args,
|
||||
DToA.DTOSTR_STANDARD_EXPONENTIAL,
|
||||
DToA.DTOSTR_EXPONENTIAL,
|
||||
0, 1);
|
||||
|
||||
case Id_toPrecision:
|
||||
return num_to(f, thisObj, args,
|
||||
DToA.DTOSTR_STANDARD, DToA.DTOSTR_PRECISION,
|
||||
1, 0);
|
||||
}
|
||||
if (!f.hasTag(NUMBER_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor: {
|
||||
double val = (args.length >= 1)
|
||||
? ScriptRuntime.toNumber(args[0]) : 0.0;
|
||||
if (thisObj == null) {
|
||||
// new Number(val) creates a new Number object.
|
||||
return new NativeNumber(val);
|
||||
}
|
||||
// Number(val) converts val to a number value.
|
||||
return wrap_double(val);
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_toLocaleString: {
|
||||
// toLocaleString is just an alias for toString for now
|
||||
double val = realThisValue(thisObj, f);
|
||||
int base = (args.length == 0)
|
||||
? 10 : ScriptRuntime.toInt32(args[0]);
|
||||
return ScriptRuntime.numberToString(val, base);
|
||||
}
|
||||
|
||||
case Id_toSource: {
|
||||
double val = realThisValue(thisObj, f);
|
||||
return "(new Number("+ScriptRuntime.toString(val)+"))";
|
||||
}
|
||||
|
||||
case Id_valueOf:
|
||||
return wrap_double(realThisValue(thisObj, f));
|
||||
|
||||
case Id_toFixed:
|
||||
return num_to(f, thisObj, args, DToA.DTOSTR_FIXED,
|
||||
DToA.DTOSTR_FIXED, -20, 0);
|
||||
|
||||
case Id_toExponential:
|
||||
return num_to(f, thisObj, args, DToA.DTOSTR_STANDARD_EXPONENTIAL,
|
||||
DToA.DTOSTR_EXPONENTIAL, 0, 1);
|
||||
|
||||
case Id_toPrecision:
|
||||
return num_to(f, thisObj, args, DToA.DTOSTR_STANDARD,
|
||||
DToA.DTOSTR_PRECISION, 1, 0);
|
||||
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
private static double realThisValue(Scriptable thisObj, IdFunction f)
|
||||
|
@ -174,42 +189,10 @@ final class NativeNumber extends IdScriptable {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
protected String getIdName(int id) {
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toLocaleString: return "toLocaleString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_valueOf: return "valueOf";
|
||||
case Id_toFixed: return "toFixed";
|
||||
case Id_toExponential: return "toExponential";
|
||||
case Id_toPrecision: return "toPrecision";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId) {
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 1;
|
||||
case Id_toLocaleString: return 1;
|
||||
case Id_toSource: return 0;
|
||||
case Id_valueOf: return 0;
|
||||
case Id_toFixed: return 1;
|
||||
case Id_toExponential: return 1;
|
||||
case Id_toPrecision: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s) {
|
||||
if (!prototypeFlag) { return 0; }
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:41:35 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -249,6 +232,4 @@ final class NativeNumber extends IdScriptable {
|
|||
// #/string_id_map#
|
||||
|
||||
private double doubleValue;
|
||||
|
||||
private boolean prototypeFlag;
|
||||
}
|
||||
|
|
|
@ -44,9 +44,12 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
public class NativeObject extends IdScriptable
|
||||
{
|
||||
private static final Object OBJECT_TAG = new Object();
|
||||
|
||||
public static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
new NativeObjectPrototype(cx, scope, sealed);
|
||||
NativeObject obj = new NativeObject();
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
public String getClassName()
|
||||
|
@ -59,133 +62,111 @@ public class NativeObject extends IdScriptable
|
|||
return ScriptRuntime.defaultObjectToString(this);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s) { return 0; }
|
||||
|
||||
protected String getIdName(int id) { return null; }
|
||||
|
||||
}
|
||||
|
||||
final class NativeObjectPrototype extends NativeObject
|
||||
{
|
||||
NativeObjectPrototype(Context cx, Scriptable scope, boolean sealed)
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toLocaleString: arity=0; s="toLocaleString"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
|
||||
case Id_propertyIsEnumerable:
|
||||
arity=1; s="propertyIsEnumerable"; break;
|
||||
case Id_isPrototypeOf: arity=1; s="isPrototypeOf"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(OBJECT_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
switch (f.methodId()) {
|
||||
case Id_constructor: {
|
||||
if (thisObj != null) {
|
||||
// BaseFunction.construct will set up parent, proto
|
||||
return f.construct(cx, scope, args);
|
||||
}
|
||||
if (args.length == 0 || args[0] == null
|
||||
|| args[0] == Undefined.instance)
|
||||
{
|
||||
return new NativeObject();
|
||||
}
|
||||
return ScriptRuntime.toObject(cx, scope, args[0]);
|
||||
if (!f.hasTag(OBJECT_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor: {
|
||||
if (thisObj != null) {
|
||||
// BaseFunction.construct will set up parent, proto
|
||||
return f.construct(cx, scope, args);
|
||||
}
|
||||
|
||||
case Id_toLocaleString: // For now just alias toString
|
||||
case Id_toString: {
|
||||
if (cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE)) {
|
||||
String s = ScriptRuntime.defaultObjectToSource(cx, scope,
|
||||
thisObj,
|
||||
args);
|
||||
int L = s.length();
|
||||
if (L != 0 && s.charAt(0) == '(' && s.charAt(L - 1) == ')')
|
||||
{
|
||||
// Strip () that surrounds toSource
|
||||
s = s.substring(1, L - 1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
return ScriptRuntime.defaultObjectToString(thisObj);
|
||||
if (args.length == 0 || args[0] == null
|
||||
|| args[0] == Undefined.instance)
|
||||
{
|
||||
return new NativeObject();
|
||||
}
|
||||
return ScriptRuntime.toObject(cx, scope, args[0]);
|
||||
}
|
||||
|
||||
case Id_valueOf:
|
||||
return thisObj;
|
||||
|
||||
case Id_hasOwnProperty: {
|
||||
if (args.length != 0) {
|
||||
String property = ScriptRuntime.toString(args[0]);
|
||||
if (thisObj.has(property, thisObj))
|
||||
return Boolean.TRUE;
|
||||
case Id_toLocaleString: // For now just alias toString
|
||||
case Id_toString: {
|
||||
if (cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE)) {
|
||||
String s = ScriptRuntime.defaultObjectToSource(cx, scope,
|
||||
thisObj, args);
|
||||
int L = s.length();
|
||||
if (L != 0 && s.charAt(0) == '(' && s.charAt(L - 1) == ')') {
|
||||
// Strip () that surrounds toSource
|
||||
s = s.substring(1, L - 1);
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
return s;
|
||||
}
|
||||
return ScriptRuntime.defaultObjectToString(thisObj);
|
||||
}
|
||||
|
||||
case Id_propertyIsEnumerable: {
|
||||
if (args.length != 0) {
|
||||
String name = ScriptRuntime.toString(args[0]);
|
||||
if (thisObj.has(name, thisObj)) {
|
||||
if (thisObj instanceof ScriptableObject) {
|
||||
ScriptableObject so = (ScriptableObject)thisObj;
|
||||
int a = so.getAttributes(name);
|
||||
if ((a & ScriptableObject.DONTENUM) == 0) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
case Id_valueOf:
|
||||
return thisObj;
|
||||
|
||||
case Id_hasOwnProperty: {
|
||||
if (args.length != 0) {
|
||||
String property = ScriptRuntime.toString(args[0]);
|
||||
if (thisObj.has(property, thisObj))
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
case Id_propertyIsEnumerable: {
|
||||
if (args.length != 0) {
|
||||
String name = ScriptRuntime.toString(args[0]);
|
||||
if (thisObj.has(name, thisObj)) {
|
||||
if (thisObj instanceof ScriptableObject) {
|
||||
ScriptableObject so = (ScriptableObject)thisObj;
|
||||
int a = so.getAttributes(name);
|
||||
if ((a & ScriptableObject.DONTENUM) == 0) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
case Id_isPrototypeOf: {
|
||||
if (args.length != 0 && args[0] instanceof Scriptable) {
|
||||
Scriptable v = (Scriptable) args[0];
|
||||
do {
|
||||
v = v.getPrototype();
|
||||
if (v == thisObj)
|
||||
return Boolean.TRUE;
|
||||
} while (v != null);
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
case Id_isPrototypeOf: {
|
||||
if (args.length != 0 && args[0] instanceof Scriptable) {
|
||||
Scriptable v = (Scriptable) args[0];
|
||||
do {
|
||||
v = v.getPrototype();
|
||||
if (v == thisObj)
|
||||
return Boolean.TRUE;
|
||||
} while (v != null);
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
case Id_toSource:
|
||||
return ScriptRuntime.defaultObjectToSource(cx, scope, thisObj,
|
||||
args);
|
||||
case Id_toSource:
|
||||
return ScriptRuntime.defaultObjectToSource(cx, scope, thisObj,
|
||||
args);
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toLocaleString: return "toLocaleString";
|
||||
case Id_valueOf: return "valueOf";
|
||||
case Id_hasOwnProperty: return "hasOwnProperty";
|
||||
case Id_propertyIsEnumerable: return "propertyIsEnumerable";
|
||||
case Id_isPrototypeOf: return "isPrototypeOf";
|
||||
case Id_toSource: return "toSource";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
switch (methodId) {
|
||||
case Id_constructor: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toLocaleString: return 0;
|
||||
case Id_valueOf: return 0;
|
||||
case Id_hasOwnProperty: return 1;
|
||||
case Id_propertyIsEnumerable: return 1;
|
||||
case Id_isPrototypeOf: return 1;
|
||||
case Id_toSource: return 0;
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2003-11-11 01:51:40 CET
|
||||
|
|
|
@ -57,13 +57,12 @@ import java.io.IOException;
|
|||
|
||||
class NativeScript extends NativeFunction implements Script
|
||||
{
|
||||
private static final Object SCRIPT_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeScript obj = new NativeScript(null);
|
||||
obj.prototypeIdShift = obj.getMaxId();
|
||||
obj.addAsPrototype(obj.prototypeIdShift + MAX_PROTOTYPE_ID,
|
||||
cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
private NativeScript(Script script)
|
||||
|
@ -126,42 +125,60 @@ class NativeScript extends NativeFunction implements Script
|
|||
return script == null ? Undefined.instance : script.exec(cx, scope);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_exec: arity=0; s="exec"; break;
|
||||
case Id_compile: arity=1; s="compile"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(SCRIPT_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (0 <= prototypeIdShift) {
|
||||
switch (f.methodId() - prototypeIdShift) {
|
||||
case Id_constructor: {
|
||||
String source = (args.length == 0)
|
||||
? ""
|
||||
: ScriptRuntime.toString(args[0]);
|
||||
Script script = compile(cx, source);
|
||||
NativeScript nscript = new NativeScript(script);
|
||||
nscript.setParentScope(scope);
|
||||
nscript.setPrototype(getClassPrototype(scope, "Script"));
|
||||
return nscript;
|
||||
}
|
||||
case Id_toString: {
|
||||
NativeScript real = realThis(thisObj, f);
|
||||
Script realScript = real.script;
|
||||
if (realScript == null) { realScript = real; }
|
||||
return cx.decompileScript(realScript,
|
||||
getTopLevelScope(scope), 0);
|
||||
}
|
||||
case Id_exec: {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.cant.call.indirect", "exec");
|
||||
}
|
||||
case Id_compile: {
|
||||
NativeScript real = realThis(thisObj, f);
|
||||
String source = ScriptRuntime.toString(args, 0);
|
||||
real.script = compile(cx, source);
|
||||
return real;
|
||||
}
|
||||
}
|
||||
if (!f.hasTag(SCRIPT_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_constructor: {
|
||||
String source = (args.length == 0)
|
||||
? ""
|
||||
: ScriptRuntime.toString(args[0]);
|
||||
Script script = compile(cx, source);
|
||||
NativeScript nscript = new NativeScript(script);
|
||||
nscript.setParentScope(scope);
|
||||
nscript.setPrototype(getClassPrototype(scope, "Script"));
|
||||
return nscript;
|
||||
}
|
||||
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
case Id_toString: {
|
||||
NativeScript real = realThis(thisObj, f);
|
||||
Script realScript = real.script;
|
||||
if (realScript == null) { realScript = real; }
|
||||
return cx.decompileScript(realScript,
|
||||
getTopLevelScope(scope), 0);
|
||||
}
|
||||
|
||||
case Id_exec: {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.cant.call.indirect", "exec");
|
||||
}
|
||||
|
||||
case Id_compile: {
|
||||
NativeScript real = realThis(thisObj, f);
|
||||
String source = ScriptRuntime.toString(args, 0);
|
||||
real.script = compile(cx, source);
|
||||
return real;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static NativeScript realThis(Scriptable thisObj, IdFunction f)
|
||||
|
@ -182,49 +199,9 @@ class NativeScript extends NativeFunction implements Script
|
|||
return cx.compileString(source, filename, linep[0], null);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (0 <= prototypeIdShift) {
|
||||
switch (id - prototypeIdShift) {
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_exec: return "exec";
|
||||
case Id_compile: return "compile";
|
||||
}
|
||||
}
|
||||
return super.getIdName(id);
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (0 <= prototypeIdShift) {
|
||||
switch (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);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
{
|
||||
if (0 <= prototypeIdShift) {
|
||||
int id = toPrototypeId(s);
|
||||
if (id != 0) {
|
||||
// Shift [1, MAX_PROTOTYPE_ID] to
|
||||
// [NativeFunction.getMaxId() + 1,
|
||||
// NativeFunction.getMaxId() + MAX_PROTOTYPE_ID]
|
||||
return prototypeIdShift + id;
|
||||
}
|
||||
}
|
||||
return super.mapNameToId(s);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static int toPrototypeId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2001-05-23 13:25:01 GMT+02:00
|
||||
|
@ -251,10 +228,5 @@ class NativeScript extends NativeFunction implements Script
|
|||
// #/string_id_map#
|
||||
|
||||
private Script script;
|
||||
|
||||
// "0 <= prototypeIdShift" serves as indicator of prototype instance
|
||||
// and as id offset to take into account ids present in each instance
|
||||
// of the base class NativeFunction.
|
||||
private int prototypeIdShift = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,10 +51,12 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
final class NativeString extends IdScriptable {
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed) {
|
||||
private static final Object STRING_TAG = new Object();
|
||||
|
||||
static void init(Context cx, Scriptable scope, boolean sealed)
|
||||
{
|
||||
NativeString obj = new NativeString("");
|
||||
obj.prototypeFlag = true;
|
||||
obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
|
||||
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
|
||||
}
|
||||
|
||||
private NativeString(String s) {
|
||||
|
@ -65,180 +67,236 @@ final class NativeString extends IdScriptable {
|
|||
return "String";
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor, boolean sealed)
|
||||
private static final int
|
||||
Id_length = 1,
|
||||
MAX_INSTANCE_ID = 1;
|
||||
|
||||
{
|
||||
addIdFunctionProperty(ctor, ConstructorId_fromCharCode, sealed);
|
||||
super.fillConstructorProperties(ctor, sealed);
|
||||
setMaxInstanceId(0, MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
if (id == Id_length) {
|
||||
return DONTENUM | READONLY | PERMANENT;
|
||||
if (s.equals("length")) {
|
||||
return instanceIdInfo(DONTENUM | READONLY | PERMANENT, Id_length);
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
return super.findInstanceIdInfo(s);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
if (id == Id_length) { return "length"; }
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
if (id == Id_length) {
|
||||
return wrap_int(string.length());
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void fillConstructorProperties(IdFunction ctor)
|
||||
{
|
||||
addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCharCode,
|
||||
"fromCharCode", 1);
|
||||
super.fillConstructorProperties(ctor);
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_constructor: arity=1; s="constructor"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_valueOf: arity=0; s="valueOf"; break;
|
||||
case Id_charAt: arity=1; s="charAt"; break;
|
||||
case Id_charCodeAt: arity=1; s="charCodeAt"; break;
|
||||
case Id_indexOf: arity=1; s="indexOf"; break;
|
||||
case Id_lastIndexOf: arity=1; s="lastIndexOf"; break;
|
||||
case Id_split: arity=2; s="split"; break;
|
||||
case Id_substring: arity=2; s="substring"; break;
|
||||
case Id_toLowerCase: arity=0; s="toLowerCase"; break;
|
||||
case Id_toUpperCase: arity=0; s="toUpperCase"; break;
|
||||
case Id_substr: arity=2; s="substr"; break;
|
||||
case Id_concat: arity=1; s="concat"; break;
|
||||
case Id_slice: arity=2; s="slice"; break;
|
||||
case Id_bold: arity=0; s="bold"; break;
|
||||
case Id_italics: arity=0; s="italics"; break;
|
||||
case Id_fixed: arity=0; s="fixed"; break;
|
||||
case Id_strike: arity=0; s="strike"; break;
|
||||
case Id_small: arity=0; s="small"; break;
|
||||
case Id_big: arity=0; s="big"; break;
|
||||
case Id_blink: arity=0; s="blink"; break;
|
||||
case Id_sup: arity=0; s="sup"; break;
|
||||
case Id_sub: arity=0; s="sub"; break;
|
||||
case Id_fontsize: arity=0; s="fontsize"; break;
|
||||
case Id_fontcolor: arity=0; s="fontcolor"; break;
|
||||
case Id_link: arity=0; s="link"; break;
|
||||
case Id_anchor: arity=0; s="anchor"; break;
|
||||
case Id_equals: arity=1; s="equals"; break;
|
||||
case Id_equalsIgnoreCase: arity=1; s="equalsIgnoreCase"; break;
|
||||
case Id_match: arity=1; s="match"; break;
|
||||
case Id_search: arity=1; s="search"; break;
|
||||
case Id_replace: arity=1; s="replace"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(STRING_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
int methodId = f.methodId();
|
||||
switch (methodId) {
|
||||
case ConstructorId_fromCharCode: {
|
||||
int N = args.length;
|
||||
if (N < 1)
|
||||
return "";
|
||||
StringBuffer sb = new StringBuffer(N);
|
||||
for (int i = 0; i != N; ++i) {
|
||||
sb.append(ScriptRuntime.toUint16(args[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
case Id_constructor: {
|
||||
String s = (args.length >= 1)
|
||||
? ScriptRuntime.toString(args[0]) : "";
|
||||
if (thisObj == null) {
|
||||
// new String(val) creates a new String object.
|
||||
return new NativeString(s);
|
||||
}
|
||||
// String(val) converts val to a string value.
|
||||
return s;
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_valueOf:
|
||||
// ECMA 15.5.4.2: 'the toString function is not generic.
|
||||
return realThis(thisObj, f).string;
|
||||
|
||||
case Id_toSource: {
|
||||
String s = realThis(thisObj, f).string;
|
||||
return "(new String(\""+ScriptRuntime.escapeString(s)
|
||||
+"\"))";
|
||||
}
|
||||
|
||||
case Id_charAt:
|
||||
case Id_charCodeAt: {
|
||||
// See ECMA 15.5.4.[4,5]
|
||||
String target = ScriptRuntime.toString(thisObj);
|
||||
double pos = ScriptRuntime.toInteger(args, 0);
|
||||
if (pos < 0 || pos >= target.length()) {
|
||||
if (methodId == Id_charAt) return "";
|
||||
else return ScriptRuntime.NaNobj;
|
||||
}
|
||||
char c = target.charAt((int)pos);
|
||||
if (methodId == Id_charAt) return String.valueOf(c);
|
||||
else return wrap_int(c);
|
||||
}
|
||||
|
||||
case Id_indexOf:
|
||||
return wrap_int(js_indexOf
|
||||
(ScriptRuntime.toString(thisObj), args));
|
||||
|
||||
case Id_lastIndexOf:
|
||||
return wrap_int(js_lastIndexOf
|
||||
(ScriptRuntime.toString(thisObj), args));
|
||||
|
||||
case Id_split:
|
||||
return js_split
|
||||
(cx, scope, ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_substring:
|
||||
return js_substring
|
||||
(cx, ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_toLowerCase:
|
||||
// See ECMA 15.5.4.11
|
||||
return ScriptRuntime.toString(thisObj).toLowerCase();
|
||||
|
||||
case Id_toUpperCase:
|
||||
// See ECMA 15.5.4.12
|
||||
return ScriptRuntime.toString(thisObj).toUpperCase();
|
||||
|
||||
case Id_substr:
|
||||
return js_substr(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_concat:
|
||||
return js_concat(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_slice:
|
||||
return js_slice(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_bold:
|
||||
return tagify(thisObj, "b", null, null);
|
||||
|
||||
case Id_italics:
|
||||
return tagify(thisObj, "i", null, null);
|
||||
|
||||
case Id_fixed:
|
||||
return tagify(thisObj, "tt", null, null);
|
||||
|
||||
case Id_strike:
|
||||
return tagify(thisObj, "strike", null, null);
|
||||
|
||||
case Id_small:
|
||||
return tagify(thisObj, "small", null, null);
|
||||
|
||||
case Id_big:
|
||||
return tagify(thisObj, "big", null, null);
|
||||
|
||||
case Id_blink:
|
||||
return tagify(thisObj, "blink", null, null);
|
||||
|
||||
case Id_sup:
|
||||
return tagify(thisObj, "sup", null, null);
|
||||
|
||||
case Id_sub:
|
||||
return tagify(thisObj, "sub", null, null);
|
||||
|
||||
case Id_fontsize:
|
||||
return tagify(thisObj, "font", "size", args);
|
||||
|
||||
case Id_fontcolor:
|
||||
return tagify(thisObj, "font", "color", args);
|
||||
|
||||
case Id_link:
|
||||
return tagify(thisObj, "a", "href", args);
|
||||
|
||||
case Id_anchor:
|
||||
return tagify(thisObj, "a", "name", args);
|
||||
|
||||
case Id_equals:
|
||||
case Id_equalsIgnoreCase: {
|
||||
String s1 = ScriptRuntime.toString(thisObj);
|
||||
String s2 = ScriptRuntime.toString(args, 0);
|
||||
return wrap_boolean(methodId == Id_equals
|
||||
? s1.equals(s2) : s1.equalsIgnoreCase(s2));
|
||||
}
|
||||
|
||||
case Id_match:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
match(cx, scope, thisObj, args);
|
||||
|
||||
case Id_search:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
search(cx, scope, thisObj, args);
|
||||
|
||||
case Id_replace:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
replace(cx, scope, thisObj, args);
|
||||
}
|
||||
if (!f.hasTag(STRING_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case ConstructorId_fromCharCode: {
|
||||
int N = args.length;
|
||||
if (N < 1)
|
||||
return "";
|
||||
StringBuffer sb = new StringBuffer(N);
|
||||
for (int i = 0; i != N; ++i) {
|
||||
sb.append(ScriptRuntime.toUint16(args[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
case Id_constructor: {
|
||||
String s = (args.length >= 1)
|
||||
? ScriptRuntime.toString(args[0]) : "";
|
||||
if (thisObj == null) {
|
||||
// new String(val) creates a new String object.
|
||||
return new NativeString(s);
|
||||
}
|
||||
// String(val) converts val to a string value.
|
||||
return s;
|
||||
}
|
||||
|
||||
case Id_toString:
|
||||
case Id_valueOf:
|
||||
// ECMA 15.5.4.2: 'the toString function is not generic.
|
||||
return realThis(thisObj, f).string;
|
||||
|
||||
case Id_toSource: {
|
||||
String s = realThis(thisObj, f).string;
|
||||
return "(new String(\""+ScriptRuntime.escapeString(s)+"\"))";
|
||||
}
|
||||
|
||||
case Id_charAt:
|
||||
case Id_charCodeAt: {
|
||||
// See ECMA 15.5.4.[4,5]
|
||||
String target = ScriptRuntime.toString(thisObj);
|
||||
double pos = ScriptRuntime.toInteger(args, 0);
|
||||
if (pos < 0 || pos >= target.length()) {
|
||||
if (id == Id_charAt) return "";
|
||||
else return ScriptRuntime.NaNobj;
|
||||
}
|
||||
char c = target.charAt((int)pos);
|
||||
if (id == Id_charAt) return String.valueOf(c);
|
||||
else return wrap_int(c);
|
||||
}
|
||||
|
||||
case Id_indexOf:
|
||||
return wrap_int(js_indexOf(
|
||||
ScriptRuntime.toString(thisObj), args));
|
||||
|
||||
case Id_lastIndexOf:
|
||||
return wrap_int(js_lastIndexOf(
|
||||
ScriptRuntime.toString(thisObj), args));
|
||||
|
||||
case Id_split:
|
||||
return js_split(cx, scope, ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_substring:
|
||||
return js_substring(cx, ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_toLowerCase:
|
||||
// See ECMA 15.5.4.11
|
||||
return ScriptRuntime.toString(thisObj).toLowerCase();
|
||||
|
||||
case Id_toUpperCase:
|
||||
// See ECMA 15.5.4.12
|
||||
return ScriptRuntime.toString(thisObj).toUpperCase();
|
||||
|
||||
case Id_substr:
|
||||
return js_substr(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_concat:
|
||||
return js_concat(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_slice:
|
||||
return js_slice(ScriptRuntime.toString(thisObj), args);
|
||||
|
||||
case Id_bold:
|
||||
return tagify(thisObj, "b", null, null);
|
||||
|
||||
case Id_italics:
|
||||
return tagify(thisObj, "i", null, null);
|
||||
|
||||
case Id_fixed:
|
||||
return tagify(thisObj, "tt", null, null);
|
||||
|
||||
case Id_strike:
|
||||
return tagify(thisObj, "strike", null, null);
|
||||
|
||||
case Id_small:
|
||||
return tagify(thisObj, "small", null, null);
|
||||
|
||||
case Id_big:
|
||||
return tagify(thisObj, "big", null, null);
|
||||
|
||||
case Id_blink:
|
||||
return tagify(thisObj, "blink", null, null);
|
||||
|
||||
case Id_sup:
|
||||
return tagify(thisObj, "sup", null, null);
|
||||
|
||||
case Id_sub:
|
||||
return tagify(thisObj, "sub", null, null);
|
||||
|
||||
case Id_fontsize:
|
||||
return tagify(thisObj, "font", "size", args);
|
||||
|
||||
case Id_fontcolor:
|
||||
return tagify(thisObj, "font", "color", args);
|
||||
|
||||
case Id_link:
|
||||
return tagify(thisObj, "a", "href", args);
|
||||
|
||||
case Id_anchor:
|
||||
return tagify(thisObj, "a", "name", args);
|
||||
|
||||
case Id_equals:
|
||||
case Id_equalsIgnoreCase: {
|
||||
String s1 = ScriptRuntime.toString(thisObj);
|
||||
String s2 = ScriptRuntime.toString(args, 0);
|
||||
return wrap_boolean(id == Id_equals
|
||||
? s1.equals(s2) : s1.equalsIgnoreCase(s2));
|
||||
}
|
||||
|
||||
case Id_match:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
match(cx, scope, thisObj, args);
|
||||
|
||||
case Id_search:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
search(cx, scope, thisObj, args);
|
||||
|
||||
case Id_replace:
|
||||
return ScriptRuntime.checkRegExpProxy(cx).
|
||||
replace(cx, scope, thisObj, args);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static NativeString realThis(Scriptable thisObj, IdFunction f)
|
||||
{
|
||||
if (!(thisObj instanceof NativeString))
|
||||
if (!(thisObj instanceof NativeString))
|
||||
throw incompatibleCallError(f);
|
||||
return (NativeString)thisObj;
|
||||
}
|
||||
|
@ -681,115 +739,9 @@ final class NativeString extends IdScriptable {
|
|||
return target;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
if (id == Id_length) { return "length"; }
|
||||
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case ConstructorId_fromCharCode: return "fromCharCode";
|
||||
|
||||
case Id_constructor: return "constructor";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_valueOf: return "valueOf";
|
||||
case Id_charAt: return "charAt";
|
||||
case Id_charCodeAt: return "charCodeAt";
|
||||
case Id_indexOf: return "indexOf";
|
||||
case Id_lastIndexOf: return "lastIndexOf";
|
||||
case Id_split: return "split";
|
||||
case Id_substring: return "substring";
|
||||
case Id_toLowerCase: return "toLowerCase";
|
||||
case Id_toUpperCase: return "toUpperCase";
|
||||
case Id_substr: return "substr";
|
||||
case Id_concat: return "concat";
|
||||
case Id_slice: return "slice";
|
||||
case Id_bold: return "bold";
|
||||
case Id_italics: return "italics";
|
||||
case Id_fixed: return "fixed";
|
||||
case Id_strike: return "strike";
|
||||
case Id_small: return "small";
|
||||
case Id_big: return "big";
|
||||
case Id_blink: return "blink";
|
||||
case Id_sup: return "sup";
|
||||
case Id_sub: return "sub";
|
||||
case Id_fontsize: return "fontsize";
|
||||
case Id_fontcolor: return "fontcolor";
|
||||
case Id_link: return "link";
|
||||
case Id_anchor: return "anchor";
|
||||
case Id_equals: return "equals";
|
||||
case Id_equalsIgnoreCase: return "equalsIgnoreCase";
|
||||
case Id_match: return "match";
|
||||
case Id_search: return "search";
|
||||
case Id_replace: return "replace";
|
||||
}
|
||||
}
|
||||
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,
|
||||
MAX_INSTANCE_ID = 1;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
{
|
||||
if (s.equals("length")) { return Id_length; }
|
||||
else if (prototypeFlag) {
|
||||
return toPrototypeId(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static int toPrototypeId(String s)
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:44:29 CET
|
||||
|
@ -852,46 +804,46 @@ final class NativeString extends IdScriptable {
|
|||
}
|
||||
|
||||
private static final int
|
||||
Id_constructor = MAX_INSTANCE_ID + 1,
|
||||
Id_toString = MAX_INSTANCE_ID + 2,
|
||||
Id_toSource = MAX_INSTANCE_ID + 3,
|
||||
Id_valueOf = MAX_INSTANCE_ID + 4,
|
||||
Id_charAt = MAX_INSTANCE_ID + 5,
|
||||
Id_charCodeAt = MAX_INSTANCE_ID + 6,
|
||||
Id_indexOf = MAX_INSTANCE_ID + 7,
|
||||
Id_lastIndexOf = MAX_INSTANCE_ID + 8,
|
||||
Id_split = MAX_INSTANCE_ID + 9,
|
||||
Id_substring = MAX_INSTANCE_ID + 10,
|
||||
Id_toLowerCase = MAX_INSTANCE_ID + 11,
|
||||
Id_toUpperCase = MAX_INSTANCE_ID + 12,
|
||||
Id_substr = MAX_INSTANCE_ID + 13,
|
||||
Id_concat = MAX_INSTANCE_ID + 14,
|
||||
Id_slice = MAX_INSTANCE_ID + 15,
|
||||
Id_bold = MAX_INSTANCE_ID + 16,
|
||||
Id_italics = MAX_INSTANCE_ID + 17,
|
||||
Id_fixed = MAX_INSTANCE_ID + 18,
|
||||
Id_strike = MAX_INSTANCE_ID + 19,
|
||||
Id_small = MAX_INSTANCE_ID + 20,
|
||||
Id_big = MAX_INSTANCE_ID + 21,
|
||||
Id_blink = MAX_INSTANCE_ID + 22,
|
||||
Id_sup = MAX_INSTANCE_ID + 23,
|
||||
Id_sub = MAX_INSTANCE_ID + 24,
|
||||
Id_fontsize = MAX_INSTANCE_ID + 25,
|
||||
Id_fontcolor = MAX_INSTANCE_ID + 26,
|
||||
Id_link = MAX_INSTANCE_ID + 27,
|
||||
Id_anchor = MAX_INSTANCE_ID + 28,
|
||||
Id_equals = MAX_INSTANCE_ID + 29,
|
||||
Id_equalsIgnoreCase = MAX_INSTANCE_ID + 30,
|
||||
Id_match = MAX_INSTANCE_ID + 31,
|
||||
Id_search = MAX_INSTANCE_ID + 32,
|
||||
Id_replace = MAX_INSTANCE_ID + 33,
|
||||
ConstructorId_fromCharCode = -1,
|
||||
|
||||
MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 33;
|
||||
Id_constructor = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
Id_valueOf = 4,
|
||||
Id_charAt = 5,
|
||||
Id_charCodeAt = 6,
|
||||
Id_indexOf = 7,
|
||||
Id_lastIndexOf = 8,
|
||||
Id_split = 9,
|
||||
Id_substring = 10,
|
||||
Id_toLowerCase = 11,
|
||||
Id_toUpperCase = 12,
|
||||
Id_substr = 13,
|
||||
Id_concat = 14,
|
||||
Id_slice = 15,
|
||||
Id_bold = 16,
|
||||
Id_italics = 17,
|
||||
Id_fixed = 18,
|
||||
Id_strike = 19,
|
||||
Id_small = 20,
|
||||
Id_big = 21,
|
||||
Id_blink = 22,
|
||||
Id_sup = 23,
|
||||
Id_sub = 24,
|
||||
Id_fontsize = 25,
|
||||
Id_fontcolor = 26,
|
||||
Id_link = 27,
|
||||
Id_anchor = 28,
|
||||
Id_equals = 29,
|
||||
Id_equalsIgnoreCase = 30,
|
||||
Id_match = 31,
|
||||
Id_search = 32,
|
||||
Id_replace = 33,
|
||||
|
||||
MAX_PROTOTYPE_ID = 33;
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
private String string;
|
||||
|
||||
private boolean prototypeFlag;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,10 @@ public class NativeWith implements Scriptable, IdFunctionMaster {
|
|||
IdFunction ctor = new IdFunction(obj, FTAG, Id_constructor,
|
||||
"With", 0, scope);
|
||||
ctor.markAsConstructor(obj);
|
||||
ctor.exportAsScopeProperty(sealed);
|
||||
if (sealed) {
|
||||
ctor.sealObject();
|
||||
}
|
||||
ctor.exportAsScopeProperty();
|
||||
}
|
||||
|
||||
private NativeWith() {
|
||||
|
|
|
@ -59,7 +59,9 @@ import org.mozilla.javascript.*;
|
|||
|
||||
|
||||
|
||||
public class NativeRegExp extends IdScriptable implements Function {
|
||||
public class NativeRegExp extends IdScriptable implements Function
|
||||
{
|
||||
private static final Object REGEXP_TAG = new Object();
|
||||
|
||||
public static final int JSREG_GLOB = 0x1; // 'g' flag: global
|
||||
public static final int JSREG_FOLD = 0x2; // 'i' flag: fold
|
||||
|
@ -133,8 +135,7 @@ public class NativeRegExp extends IdScriptable implements Function {
|
|||
|
||||
NativeRegExp proto = new NativeRegExp();
|
||||
proto.re = (RECompiled)compileRE("", null, false);
|
||||
proto.prototypeFlag = true;
|
||||
proto.setMaxId(MAX_PROTOTYPE_ID);
|
||||
proto.activatePrototypeMap(MAX_PROTOTYPE_ID);
|
||||
proto.setParentScope(scope);
|
||||
proto.setPrototype(getObjectPrototype(scope));
|
||||
|
||||
|
@ -2575,124 +2576,6 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
|
|||
throw ScriptRuntime.constructError("SyntaxError", msg);
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_lastIndex:
|
||||
return ScriptableObject.PERMANENT | ScriptableObject.DONTENUM;
|
||||
case Id_source:
|
||||
case Id_global:
|
||||
case Id_ignoreCase:
|
||||
case Id_multiline:
|
||||
return ScriptableObject.PERMANENT | ScriptableObject.READONLY
|
||||
| ScriptableObject.DONTENUM;
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_lastIndex:
|
||||
return wrap_double(lastIndex);
|
||||
case Id_source:
|
||||
return new String(re.source);
|
||||
case Id_global:
|
||||
return wrap_boolean((re.flags & JSREG_GLOB) != 0);
|
||||
case Id_ignoreCase:
|
||||
return wrap_boolean((re.flags & JSREG_FOLD) != 0);
|
||||
case Id_multiline:
|
||||
return wrap_boolean((re.flags & JSREG_MULTILINE) != 0);
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
}
|
||||
|
||||
protected void setIdValue(int id, Object value)
|
||||
{
|
||||
if (id == Id_lastIndex) {
|
||||
setLastIndex(ScriptRuntime.toNumber(value));
|
||||
return;
|
||||
}
|
||||
super.setIdValue(id, value);
|
||||
}
|
||||
|
||||
void setLastIndex(double value)
|
||||
{
|
||||
lastIndex = value;
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (f.methodId()) {
|
||||
case Id_compile:
|
||||
return realThis(thisObj, f).compile(cx, scope, args);
|
||||
|
||||
case Id_toString:
|
||||
case Id_toSource:
|
||||
return realThis(thisObj, f).toString();
|
||||
|
||||
case Id_exec:
|
||||
return realThis(thisObj, f).execSub(cx, scope, args, MATCH);
|
||||
|
||||
case Id_test: {
|
||||
Object x = realThis(thisObj, f).execSub(cx, scope, args, TEST);
|
||||
return Boolean.TRUE.equals(x) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
case Id_prefix:
|
||||
return realThis(thisObj, f).execSub(cx, scope, args, PREFIX);
|
||||
}
|
||||
}
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
private static NativeRegExp realThis(Scriptable thisObj, IdFunction f)
|
||||
{
|
||||
if (!(thisObj instanceof NativeRegExp))
|
||||
throw incompatibleCallError(f);
|
||||
return (NativeRegExp)thisObj;
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_lastIndex: return "lastIndex";
|
||||
case Id_source: return "source";
|
||||
case Id_global: return "global";
|
||||
case Id_ignoreCase: return "ignoreCase";
|
||||
case Id_multiline: return "multiline";
|
||||
}
|
||||
|
||||
if (prototypeFlag) {
|
||||
switch (id) {
|
||||
case Id_compile: return "compile";
|
||||
case Id_toString: return "toString";
|
||||
case Id_toSource: return "toSource";
|
||||
case Id_exec: return "exec";
|
||||
case Id_test: return "test";
|
||||
case Id_prefix: return "prefix";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int methodArity(int methodId)
|
||||
{
|
||||
if (prototypeFlag) {
|
||||
switch (methodId) {
|
||||
case Id_compile: return 1;
|
||||
case Id_toString: return 0;
|
||||
case Id_toSource: return 0;
|
||||
case Id_exec: return 1;
|
||||
case Id_test: return 1;
|
||||
case Id_prefix: return 1;
|
||||
}
|
||||
}
|
||||
return super.methodArity(methodId);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
|
@ -2704,9 +2587,11 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
|
|||
|
||||
MAX_INSTANCE_ID = 5;
|
||||
|
||||
{ setMaxId(MAX_INSTANCE_ID); }
|
||||
{
|
||||
setMaxInstanceId(0, MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s)
|
||||
protected int findInstanceIdInfo(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2001-05-24 12:01:22 GMT+02:00
|
||||
|
@ -2728,9 +2613,124 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
|
|||
// #/generated#
|
||||
// #/string_id_map#
|
||||
|
||||
if (id != 0 || !prototypeFlag) { return id; }
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_lastIndex:
|
||||
attr = PERMANENT | DONTENUM;
|
||||
break;
|
||||
case Id_source:
|
||||
case Id_global:
|
||||
case Id_ignoreCase:
|
||||
case Id_multiline:
|
||||
attr = PERMANENT | READONLY | DONTENUM;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return instanceIdInfo(attr, id);
|
||||
}
|
||||
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_lastIndex: return "lastIndex";
|
||||
case Id_source: return "source";
|
||||
case Id_global: return "global";
|
||||
case Id_ignoreCase: return "ignoreCase";
|
||||
case Id_multiline: return "multiline";
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case Id_lastIndex:
|
||||
return wrap_double(lastIndex);
|
||||
case Id_source:
|
||||
return new String(re.source);
|
||||
case Id_global:
|
||||
return wrap_boolean((re.flags & JSREG_GLOB) != 0);
|
||||
case Id_ignoreCase:
|
||||
return wrap_boolean((re.flags & JSREG_FOLD) != 0);
|
||||
case Id_multiline:
|
||||
return wrap_boolean((re.flags & JSREG_MULTILINE) != 0);
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
if (id == Id_lastIndex) {
|
||||
setLastIndex(ScriptRuntime.toNumber(value));
|
||||
return;
|
||||
}
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
void setLastIndex(double value)
|
||||
{
|
||||
lastIndex = value;
|
||||
}
|
||||
|
||||
protected void initPrototypeId(int id)
|
||||
{
|
||||
String s;
|
||||
int arity;
|
||||
switch (id) {
|
||||
case Id_compile: arity=1; s="compile"; break;
|
||||
case Id_toString: arity=0; s="toString"; break;
|
||||
case Id_toSource: arity=0; s="toSource"; break;
|
||||
case Id_exec: arity=1; s="exec"; break;
|
||||
case Id_test: arity=1; s="test"; break;
|
||||
case Id_prefix: arity=1; s="prefix"; break;
|
||||
default: throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
initPrototypeMethod(REGEXP_TAG, id, s, arity);
|
||||
}
|
||||
|
||||
public Object execMethod(IdFunction f, Context cx, Scriptable scope,
|
||||
Scriptable thisObj, Object[] args)
|
||||
{
|
||||
if (!f.hasTag(REGEXP_TAG)) {
|
||||
return super.execMethod(f, cx, scope, thisObj, args);
|
||||
}
|
||||
int id = f.methodId();
|
||||
switch (id) {
|
||||
case Id_compile:
|
||||
return realThis(thisObj, f).compile(cx, scope, args);
|
||||
|
||||
case Id_toString:
|
||||
case Id_toSource:
|
||||
return realThis(thisObj, f).toString();
|
||||
|
||||
case Id_exec:
|
||||
return realThis(thisObj, f).execSub(cx, scope, args, MATCH);
|
||||
|
||||
case Id_test: {
|
||||
Object x = realThis(thisObj, f).execSub(cx, scope, args, TEST);
|
||||
return Boolean.TRUE.equals(x) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
case Id_prefix:
|
||||
return realThis(thisObj, f).execSub(cx, scope, args, PREFIX);
|
||||
}
|
||||
throw new IllegalArgumentException(String.valueOf(id));
|
||||
}
|
||||
|
||||
private static NativeRegExp realThis(Scriptable thisObj, IdFunction f)
|
||||
{
|
||||
if (!(thisObj instanceof NativeRegExp))
|
||||
throw incompatibleCallError(f);
|
||||
return (NativeRegExp)thisObj;
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
protected int findPrototypeId(String s)
|
||||
{
|
||||
int id;
|
||||
// #generated# Last update: 2004-03-17 13:54:21 CET
|
||||
L0: { id = 0; String X = null; int c;
|
||||
L: switch (s.length()) {
|
||||
|
@ -2752,17 +2752,16 @@ System.out.println("Testing at " + x.cp + ", op = " + op);
|
|||
}
|
||||
|
||||
private static final int
|
||||
Id_compile = MAX_INSTANCE_ID + 1,
|
||||
Id_toString = MAX_INSTANCE_ID + 2,
|
||||
Id_toSource = MAX_INSTANCE_ID + 3,
|
||||
Id_exec = MAX_INSTANCE_ID + 4,
|
||||
Id_test = MAX_INSTANCE_ID + 5,
|
||||
Id_prefix = MAX_INSTANCE_ID + 6,
|
||||
Id_compile = 1,
|
||||
Id_toString = 2,
|
||||
Id_toSource = 3,
|
||||
Id_exec = 4,
|
||||
Id_test = 5,
|
||||
Id_prefix = 6,
|
||||
|
||||
MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 6;
|
||||
MAX_PROTOTYPE_ID = 6;
|
||||
|
||||
// #/string_id_map#
|
||||
private boolean prototypeFlag;
|
||||
|
||||
RECompiled re;
|
||||
private double lastIndex; /* index after last match, for //g iterator */
|
||||
|
|
|
@ -86,111 +86,11 @@ public class NativeRegExpCtor extends NativeFunction {
|
|||
return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
|
||||
}
|
||||
|
||||
protected int getIdAttributes(int id)
|
||||
{
|
||||
int shifted = id - idBase;
|
||||
if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
|
||||
switch (shifted) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
return PERMANENT;
|
||||
}
|
||||
return PERMANENT | READONLY;
|
||||
}
|
||||
return super.getIdAttributes(id);
|
||||
}
|
||||
|
||||
private static String stringResult(Object obj)
|
||||
{
|
||||
return (obj == null) ? "" : obj.toString();
|
||||
}
|
||||
|
||||
protected Object getIdValue(int id)
|
||||
{
|
||||
int shifted = id - idBase;
|
||||
if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
|
||||
RegExpImpl impl = getImpl();
|
||||
switch (shifted) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
return wrap_boolean(impl.multiline);
|
||||
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
return stringResult(impl.input);
|
||||
|
||||
case Id_lastMatch:
|
||||
case Id_AMPERSAND:
|
||||
return stringResult(impl.lastMatch);
|
||||
|
||||
case Id_lastParen:
|
||||
case Id_PLUS:
|
||||
return stringResult(impl.lastParen);
|
||||
|
||||
case Id_leftContext:
|
||||
case Id_BACK_QUOTE:
|
||||
return stringResult(impl.leftContext);
|
||||
|
||||
case Id_rightContext:
|
||||
case Id_QUOTE:
|
||||
return stringResult(impl.rightContext);
|
||||
}
|
||||
// Must be one of $1..$9, convert to 0..8
|
||||
int substring_number = shifted - DOLLAR_ID_BASE - 1;
|
||||
return impl.getParenSubString(substring_number).toString();
|
||||
}
|
||||
return super.getIdValue(id);
|
||||
}
|
||||
|
||||
protected void setIdValue(int id, Object value)
|
||||
{
|
||||
switch (id - idBase) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
getImpl().multiline = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
getImpl().input = ScriptRuntime.toString(value);
|
||||
return;
|
||||
}
|
||||
super.setIdValue(id, value);
|
||||
}
|
||||
|
||||
protected String getIdName(int id)
|
||||
{
|
||||
int shifted = id - idBase;
|
||||
if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
|
||||
switch (shifted) {
|
||||
case Id_multiline: return "multiline";
|
||||
case Id_STAR: return "$*";
|
||||
|
||||
case Id_input: return "input";
|
||||
case Id_UNDERSCORE: return "$_";
|
||||
|
||||
case Id_lastMatch: return "lastMatch";
|
||||
case Id_AMPERSAND: return "$&";
|
||||
|
||||
case Id_lastParen: return "lastParen";
|
||||
case Id_PLUS: return "$+";
|
||||
|
||||
case Id_leftContext: return "leftContext";
|
||||
case Id_BACK_QUOTE: return "$`";
|
||||
|
||||
case Id_rightContext: return "rightContext";
|
||||
case Id_QUOTE: return "$'";
|
||||
}
|
||||
// Must be one of $1..$9, convert to 0..8
|
||||
int substring_number = shifted - DOLLAR_ID_BASE - 1;
|
||||
char[] buf = { '$', (char)('1' + substring_number) };
|
||||
return new String(buf);
|
||||
}
|
||||
return super.getIdName(id);
|
||||
}
|
||||
|
||||
// #string_id_map#
|
||||
|
||||
private static final int
|
||||
|
@ -228,14 +128,14 @@ public class NativeRegExpCtor extends NativeFunction {
|
|||
MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;
|
||||
|
||||
// maxId for superclass
|
||||
private int idBase;
|
||||
private static int idBase = -1;
|
||||
|
||||
{
|
||||
idBase = getMaxId();
|
||||
setMaxId(idBase + MAX_INSTANCE_ID);
|
||||
if (idBase < 0) idBase = getMaxInstanceId();
|
||||
setMaxInstanceId(idBase, idBase + MAX_INSTANCE_ID);
|
||||
}
|
||||
|
||||
protected int mapNameToId(String s) {
|
||||
protected int findInstanceIdInfo(String s) {
|
||||
int id;
|
||||
// #generated# Last update: 2001-05-24 16:09:31 GMT+02:00
|
||||
L0: { id = 0; String X = null; int c;
|
||||
|
@ -269,8 +169,109 @@ public class NativeRegExpCtor extends NativeFunction {
|
|||
if (X!=null && X!=s && !X.equals(s)) id = 0;
|
||||
}
|
||||
// #/generated#
|
||||
|
||||
if (id == 0) return super.findInstanceIdInfo(s);
|
||||
|
||||
int attr;
|
||||
switch (id) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
attr = PERMANENT;
|
||||
break;
|
||||
default:
|
||||
attr = PERMANENT | READONLY;
|
||||
break;
|
||||
}
|
||||
|
||||
return instanceIdInfo(attr, idBase + id);
|
||||
}
|
||||
|
||||
// #/string_id_map#
|
||||
|
||||
return (id != 0) ? idBase + id : super.mapNameToId(s);
|
||||
protected String getInstanceIdName(int id)
|
||||
{
|
||||
int shifted = id - idBase;
|
||||
if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
|
||||
switch (shifted) {
|
||||
case Id_multiline: return "multiline";
|
||||
case Id_STAR: return "$*";
|
||||
|
||||
case Id_input: return "input";
|
||||
case Id_UNDERSCORE: return "$_";
|
||||
|
||||
case Id_lastMatch: return "lastMatch";
|
||||
case Id_AMPERSAND: return "$&";
|
||||
|
||||
case Id_lastParen: return "lastParen";
|
||||
case Id_PLUS: return "$+";
|
||||
|
||||
case Id_leftContext: return "leftContext";
|
||||
case Id_BACK_QUOTE: return "$`";
|
||||
|
||||
case Id_rightContext: return "rightContext";
|
||||
case Id_QUOTE: return "$'";
|
||||
}
|
||||
// Must be one of $1..$9, convert to 0..8
|
||||
int substring_number = shifted - DOLLAR_ID_BASE - 1;
|
||||
char[] buf = { '$', (char)('1' + substring_number) };
|
||||
return new String(buf);
|
||||
}
|
||||
return super.getInstanceIdName(id);
|
||||
}
|
||||
|
||||
protected Object getInstanceIdValue(int id)
|
||||
{
|
||||
int shifted = id - idBase;
|
||||
if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
|
||||
RegExpImpl impl = getImpl();
|
||||
switch (shifted) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
return wrap_boolean(impl.multiline);
|
||||
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
return stringResult(impl.input);
|
||||
|
||||
case Id_lastMatch:
|
||||
case Id_AMPERSAND:
|
||||
return stringResult(impl.lastMatch);
|
||||
|
||||
case Id_lastParen:
|
||||
case Id_PLUS:
|
||||
return stringResult(impl.lastParen);
|
||||
|
||||
case Id_leftContext:
|
||||
case Id_BACK_QUOTE:
|
||||
return stringResult(impl.leftContext);
|
||||
|
||||
case Id_rightContext:
|
||||
case Id_QUOTE:
|
||||
return stringResult(impl.rightContext);
|
||||
}
|
||||
// Must be one of $1..$9, convert to 0..8
|
||||
int substring_number = shifted - DOLLAR_ID_BASE - 1;
|
||||
return impl.getParenSubString(substring_number).toString();
|
||||
}
|
||||
return super.getInstanceIdValue(id);
|
||||
}
|
||||
|
||||
protected void setInstanceIdValue(int id, Object value)
|
||||
{
|
||||
switch (id - idBase) {
|
||||
case Id_multiline:
|
||||
case Id_STAR:
|
||||
getImpl().multiline = ScriptRuntime.toBoolean(value);
|
||||
return;
|
||||
|
||||
case Id_input:
|
||||
case Id_UNDERSCORE:
|
||||
getImpl().input = ScriptRuntime.toString(value);
|
||||
return;
|
||||
}
|
||||
super.setInstanceIdValue(id, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче