aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java')
-rw-r--r--trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java311
1 files changed, 311 insertions, 0 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
new file mode 100644
index 0000000..954b078
--- /dev/null
+++ b/trunk/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
@@ -0,0 +1,311 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla 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/MPL/
+ *
+ * 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 the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (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
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * 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 MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the "arguments" object.
+ *
+ * See ECMA 10.1.8
+ *
+ * @see org.mozilla.javascript.NativeCall
+ * @author Norris Boyd
+ */
+final class Arguments extends IdScriptableObject
+{
+ static final long serialVersionUID = 4275508002492040609L;
+
+ public Arguments(NativeCall activation)
+ {
+ this.activation = activation;
+
+ Scriptable parent = activation.getParentScope();
+ setParentScope(parent);
+ setPrototype(ScriptableObject.getObjectPrototype(parent));
+
+ args = activation.originalArgs;
+ lengthObj = new Integer(args.length);
+
+ NativeFunction f = activation.function;
+ calleeObj = f;
+
+ int version = f.getLanguageVersion();
+ if (version <= Context.VERSION_1_3
+ && version != Context.VERSION_DEFAULT)
+ {
+ callerObj = null;
+ } else {
+ callerObj = NOT_FOUND;
+ }
+ }
+
+ public String getClassName()
+ {
+ return "Object";
+ }
+
+ public boolean has(int index, Scriptable start)
+ {
+ if (0 <= index && index < args.length) {
+ if (args[index] != NOT_FOUND) {
+ return true;
+ }
+ }
+ return super.has(index, start);
+ }
+
+ public Object get(int index, Scriptable start)
+ {
+ if (0 <= index && index < args.length) {
+ Object value = args[index];
+ if (value != NOT_FOUND) {
+ if (sharedWithActivation(index)) {
+ NativeFunction f = activation.function;
+ String argName = f.getParamOrVarName(index);
+ value = activation.get(argName, activation);
+ if (value == NOT_FOUND) Kit.codeBug();
+ }
+ return value;
+ }
+ }
+ return super.get(index, start);
+ }
+
+ private boolean sharedWithActivation(int index)
+ {
+ NativeFunction f = activation.function;
+ int definedCount = f.getParamCount();
+ if (index < definedCount) {
+ // Check if argument is not hidden by later argument with the same
+ // name as hidden arguments are not shared with activation
+ if (index < definedCount - 1) {
+ String argName = f.getParamOrVarName(index);
+ for (int i = index + 1; i < definedCount; i++) {
+ if (argName.equals(f.getParamOrVarName(i))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void put(int index, Scriptable start, Object value)
+ {
+ if (0 <= index && index < args.length) {
+ if (args[index] != NOT_FOUND) {
+ if (sharedWithActivation(index)) {
+ String argName;
+ argName = activation.function.getParamOrVarName(index);
+ activation.put(argName, activation, value);
+ return;
+ }
+ synchronized (this) {
+ if (args[index] != NOT_FOUND) {
+ if (args == activation.originalArgs) {
+ args = args.clone();
+ }
+ args[index] = value;
+ return;
+ }
+ }
+ }
+ }
+ super.put(index, start, value);
+ }
+
+ public void delete(int index)
+ {
+ if (0 <= index && index < args.length) {
+ synchronized (this) {
+ if (args[index] != NOT_FOUND) {
+ if (args == activation.originalArgs) {
+ args = args.clone();
+ }
+ args[index] = NOT_FOUND;
+ return;
+ }
+ }
+ }
+ super.delete(index);
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_callee = 1,
+ Id_length = 2,
+ Id_caller = 3,
+
+ MAX_INSTANCE_ID = 3;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:04 EDT
+ 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;
+ break L0;
+ }
+// #/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);
+ }
+
+// #/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;
+ case Id_length: return lengthObj;
+ case Id_caller: {
+ Object value = callerObj;
+ if (value == UniqueTag.NULL_VALUE) { value = null; }
+ else if (value == null) {
+ NativeCall caller = activation.parentActivationCall;
+ if (caller != null) {
+ value = caller.get("arguments", caller);
+ }
+ }
+ return value;
+ }
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ switch (id) {
+ case Id_callee: calleeObj = value; return;
+ case Id_length: lengthObj = value; return;
+ case Id_caller:
+ callerObj = (value != null) ? value : UniqueTag.NULL_VALUE;
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+ Object[] getIds(boolean getAll)
+ {
+ Object[] ids = super.getIds(getAll);
+ if (getAll && args.length != 0) {
+ boolean[] present = null;
+ int extraCount = args.length;
+ for (int i = 0; i != ids.length; ++i) {
+ Object id = ids[i];
+ if (id instanceof Integer) {
+ int index = ((Integer)id).intValue();
+ if (0 <= index && index < args.length) {
+ if (present == null) {
+ present = new boolean[args.length];
+ }
+ if (!present[index]) {
+ present[index] = true;
+ extraCount--;
+ }
+ }
+ }
+ }
+ if (extraCount != 0) {
+ Object[] tmp = new Object[extraCount + ids.length];
+ System.arraycopy(ids, 0, tmp, extraCount, ids.length);
+ ids = tmp;
+ int offset = 0;
+ for (int i = 0; i != args.length; ++i) {
+ if (present == null || !present[i]) {
+ ids[offset] = new Integer(i);
+ ++offset;
+ }
+ }
+ if (offset != extraCount) Kit.codeBug();
+ }
+ }
+ return ids;
+ }
+
+// 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
+// initial callerObj == null means access to caller arguments available
+// only in JS <= 1.3 scripts
+ private Object callerObj;
+ private Object calleeObj;
+ private Object lengthObj;
+
+ private NativeCall activation;
+
+// Initially args holds activation.getOriginalArgs(), but any modification
+// of its elements triggers creation of a copy. If its element holds NOT_FOUND,
+// it indicates deleted index, in which case super class is queried.
+ private Object[] args;
+}